OLD | NEW |
1 //===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===// | 1 //===-- X86MCInstLower.cpp - Convert X86 MachineInstr to an MCInst --------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file contains code to lower X86 MachineInstrs to their corresponding | 10 // This file contains code to lower X86 MachineInstrs to their corresponding |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering, | 682 void X86AsmPrinter::LowerTlsAddr(X86MCInstLower &MCInstLowering, |
683 const MachineInstr &MI) { | 683 const MachineInstr &MI) { |
684 | 684 |
685 bool is64Bits = MI.getOpcode() == X86::TLS_addr64 || | 685 bool is64Bits = MI.getOpcode() == X86::TLS_addr64 || |
686 MI.getOpcode() == X86::TLS_base_addr64; | 686 MI.getOpcode() == X86::TLS_base_addr64; |
687 | 687 |
688 bool needsPadding = MI.getOpcode() == X86::TLS_addr64; | 688 bool needsPadding = MI.getOpcode() == X86::TLS_addr64; |
689 | 689 |
690 MCContext &context = OutStreamer.getContext(); | 690 MCContext &context = OutStreamer.getContext(); |
691 | 691 |
| 692 // @LOCALMOD-START |
| 693 // TODO(dschuff): Instead of testing the target OS we should add (upstream) a |
| 694 // method to one of the MC classes to test whether bundle alignment is enabled |
| 695 // (currently only the AsmBackend has this, which can't be used when emitting |
| 696 // asm files). That facility should be used here and in MCAsmStreamer.cpp |
| 697 // (this should be done once we are unblocked from switching to gas by |
| 698 // default, so we know exactly where we need it). |
| 699 Triple TT(getSubtargetInfo().getTargetTriple()); |
| 700 const bool needsBundleLock = TT.getOS() == Triple::NaCl; |
| 701 if (needsBundleLock) |
| 702 OutStreamer.EmitBundleLock(false); |
| 703 // @LOCALMOD-END |
692 if (needsPadding) | 704 if (needsPadding) |
693 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX)); | 705 EmitAndCountInstruction(MCInstBuilder(X86::DATA16_PREFIX)); |
694 | 706 |
695 MCSymbolRefExpr::VariantKind SRVK; | 707 MCSymbolRefExpr::VariantKind SRVK; |
696 switch (MI.getOpcode()) { | 708 switch (MI.getOpcode()) { |
697 case X86::TLS_addr32: | 709 case X86::TLS_addr32: |
698 case X86::TLS_addr64: | 710 case X86::TLS_addr64: |
699 SRVK = MCSymbolRefExpr::VK_TLSGD; | 711 SRVK = MCSymbolRefExpr::VK_TLSGD; |
700 break; | 712 break; |
701 case X86::TLS_base_addr32: | 713 case X86::TLS_base_addr32: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr"; | 760 StringRef name = is64Bits ? "__tls_get_addr" : "___tls_get_addr"; |
749 MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name); | 761 MCSymbol *tlsGetAddr = context.GetOrCreateSymbol(name); |
750 const MCSymbolRefExpr *tlsRef = | 762 const MCSymbolRefExpr *tlsRef = |
751 MCSymbolRefExpr::Create(tlsGetAddr, | 763 MCSymbolRefExpr::Create(tlsGetAddr, |
752 MCSymbolRefExpr::VK_PLT, | 764 MCSymbolRefExpr::VK_PLT, |
753 context); | 765 context); |
754 | 766 |
755 EmitAndCountInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32 | 767 EmitAndCountInstruction(MCInstBuilder(is64Bits ? X86::CALL64pcrel32 |
756 : X86::CALLpcrel32) | 768 : X86::CALLpcrel32) |
757 .addExpr(tlsRef)); | 769 .addExpr(tlsRef)); |
| 770 // @LOCALMOD-START |
| 771 if (needsBundleLock) |
| 772 OutStreamer.EmitBundleUnlock(); |
| 773 // @LOCALMOD-END |
758 } | 774 } |
759 | 775 |
760 /// \brief Emit the optimal amount of multi-byte nops on X86. | 776 /// \brief Emit the optimal amount of multi-byte nops on X86. |
761 static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit, const MCSu
btargetInfo &STI) { | 777 static void EmitNops(MCStreamer &OS, unsigned NumBytes, bool Is64Bit, const MCSu
btargetInfo &STI) { |
762 // This works only for 64bit. For 32bit we have to do additional checking if | 778 // This works only for 64bit. For 32bit we have to do additional checking if |
763 // the CPU supports multi-byte nops. | 779 // the CPU supports multi-byte nops. |
764 assert(Is64Bit && "EmitNops only supports X86-64"); | 780 assert(Is64Bit && "EmitNops only supports X86-64"); |
765 while (NumBytes) { | 781 while (NumBytes) { |
766 unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg; | 782 unsigned Opc, BaseReg, ScaleVal, IndexReg, Displacement, SegmentReg; |
767 Opc = IndexReg = Displacement = SegmentReg = 0; | 783 Opc = IndexReg = Displacement = SegmentReg = 0; |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) | 1080 if (MI->getOperand(2).getTargetFlags() != X86II::MO_GOT_ABSOLUTE_ADDRESS) |
1065 break; | 1081 break; |
1066 | 1082 |
1067 // Okay, we have something like: | 1083 // Okay, we have something like: |
1068 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL) | 1084 // EAX = ADD32ri EAX, MO_GOT_ABSOLUTE_ADDRESS(@MYGLOBAL) |
1069 | 1085 |
1070 // For this, we want to print something like: | 1086 // For this, we want to print something like: |
1071 // MYGLOBAL + (. - PICBASE) | 1087 // MYGLOBAL + (. - PICBASE) |
1072 // However, we can't generate a ".", so just emit a new label here and refer | 1088 // However, we can't generate a ".", so just emit a new label here and refer |
1073 // to it. | 1089 // to it. |
| 1090 |
| 1091 // @LOCALMOD-START |
| 1092 // When using the gas assembler, emitting a new label and then using it in |
| 1093 // the difference expression gives the wrong value when the instruction |
| 1094 // following the label gets bundle padding added to it. (The label will |
| 1095 // point to the nop padding instead of the instruction, which works when |
| 1096 // jumping to the label, but not when calculating GOT addresses. See |
| 1097 // https://code.google.com/p/nativeclient/issues/detail?id=3982) For this |
| 1098 // case, just emit the instruction using the "." directly rather than going |
| 1099 // through all the MC layers. The LLVM assembler is smart enough to make the |
| 1100 // label point to the actual instruction rather than the nop, so this hack |
| 1101 // isn't necessary. |
| 1102 if (Subtarget->isTargetNaCl32() && |
| 1103 OutStreamer.hasRawTextSupport()) { |
| 1104 std::string OS; |
| 1105 raw_string_ostream ROS(OS); |
| 1106 ROS << "\taddl\t$_GLOBAL_OFFSET_TABLE_+(.-" << *MF->getPICBaseSymbol() |
| 1107 << "), %" |
| 1108 << X86ATTInstPrinter::getRegisterName(MI->getOperand(0).getReg()); |
| 1109 OutStreamer.EmitRawText(ROS.str()); |
| 1110 return; |
| 1111 } |
| 1112 // @LOCALMOD-END |
1074 MCSymbol *DotSym = OutContext.CreateTempSymbol(); | 1113 MCSymbol *DotSym = OutContext.CreateTempSymbol(); |
1075 OutStreamer.EmitLabel(DotSym); | 1114 OutStreamer.EmitLabel(DotSym); |
1076 | 1115 |
1077 // Now that we have emitted the label, lower the complex operand expression. | 1116 // Now that we have emitted the label, lower the complex operand expression. |
1078 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2)); | 1117 MCSymbol *OpSym = MCInstLowering.GetSymbolFromOperand(MI->getOperand(2)); |
1079 | 1118 |
1080 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); | 1119 const MCExpr *DotExpr = MCSymbolRefExpr::Create(DotSym, OutContext); |
1081 const MCExpr *PICBase = | 1120 const MCExpr *PICBase = |
1082 MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), OutContext); | 1121 MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), OutContext); |
1083 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext); | 1122 DotExpr = MCBinaryExpr::CreateSub(DotExpr, PICBase, OutContext); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 // Then flush the shadow so that we fill with nops before the call, not | 1322 // Then flush the shadow so that we fill with nops before the call, not |
1284 // after it. | 1323 // after it. |
1285 SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); | 1324 SMShadowTracker.emitShadowPadding(OutStreamer, getSubtargetInfo()); |
1286 // Then emit the call | 1325 // Then emit the call |
1287 OutStreamer.EmitInstruction(TmpInst, getSubtargetInfo()); | 1326 OutStreamer.EmitInstruction(TmpInst, getSubtargetInfo()); |
1288 return; | 1327 return; |
1289 } | 1328 } |
1290 | 1329 |
1291 EmitAndCountInstruction(TmpInst); | 1330 EmitAndCountInstruction(TmpInst); |
1292 } | 1331 } |
OLD | NEW |