| 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 |