LLVM API Documentation

X86AsmBackend.cpp
Go to the documentation of this file.
00001 //===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "MCTargetDesc/X86BaseInfo.h"
00011 #include "MCTargetDesc/X86FixupKinds.h"
00012 #include "llvm/MC/MCAsmBackend.h"
00013 #include "llvm/MC/MCAssembler.h"
00014 #include "llvm/MC/MCELFObjectWriter.h"
00015 #include "llvm/MC/MCExpr.h"
00016 #include "llvm/MC/MCFixupKindInfo.h"
00017 #include "llvm/MC/MCMachObjectWriter.h"
00018 #include "llvm/MC/MCObjectWriter.h"
00019 #include "llvm/MC/MCSectionCOFF.h"
00020 #include "llvm/MC/MCSectionELF.h"
00021 #include "llvm/MC/MCSectionMachO.h"
00022 #include "llvm/Object/MachOFormat.h"
00023 #include "llvm/Support/CommandLine.h"
00024 #include "llvm/Support/ELF.h"
00025 #include "llvm/Support/ErrorHandling.h"
00026 #include "llvm/Support/TargetRegistry.h"
00027 #include "llvm/Support/raw_ostream.h"
00028 using namespace llvm;
00029 
00030 // Option to allow disabling arithmetic relaxation to workaround PR9807, which
00031 // is useful when running bitwise comparison experiments on Darwin. We should be
00032 // able to remove this once PR9807 is resolved.
00033 static cl::opt<bool>
00034 MCDisableArithRelaxation("mc-x86-disable-arith-relaxation",
00035          cl::desc("Disable relaxation of arithmetic instruction for X86"));
00036 
00037 static unsigned getFixupKindLog2Size(unsigned Kind) {
00038   switch (Kind) {
00039   default: llvm_unreachable("invalid fixup kind!");
00040   case FK_PCRel_1:
00041   case FK_SecRel_1:
00042   case FK_Data_1: return 0;
00043   case FK_PCRel_2:
00044   case FK_SecRel_2:
00045   case FK_Data_2: return 1;
00046   case FK_PCRel_4:
00047   case X86::reloc_riprel_4byte:
00048   case X86::reloc_riprel_4byte_movq_load:
00049   case X86::reloc_signed_4byte:
00050   case X86::reloc_global_offset_table:
00051   case FK_SecRel_4:
00052   case FK_Data_4: return 2;
00053   case FK_PCRel_8:
00054   case FK_SecRel_8:
00055   case FK_Data_8: return 3;
00056   }
00057 }
00058 
00059 namespace {
00060 
00061 class X86ELFObjectWriter : public MCELFObjectTargetWriter {
00062 public:
00063   X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine,
00064                      bool HasRelocationAddend, bool foobar)
00065     : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {}
00066 };
00067 
00068 class X86AsmBackend : public MCAsmBackend {
00069   StringRef CPU;
00070 public:
00071   X86AsmBackend(const Target &T, StringRef _CPU)
00072     : MCAsmBackend(), CPU(_CPU) {}
00073 
00074   unsigned getNumFixupKinds() const {
00075     return X86::NumTargetFixupKinds;
00076   }
00077 
00078   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
00079     const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
00080       { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel },
00081       { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel},
00082       { "reloc_signed_4byte", 0, 4 * 8, 0},
00083       { "reloc_global_offset_table", 0, 4 * 8, 0}
00084     };
00085 
00086     if (Kind < FirstTargetFixupKind)
00087       return MCAsmBackend::getFixupKindInfo(Kind);
00088 
00089     assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
00090            "Invalid kind!");
00091     return Infos[Kind - FirstTargetFixupKind];
00092   }
00093 
00094   void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
00095                   uint64_t Value) const {
00096     unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
00097 
00098     assert(Fixup.getOffset() + Size <= DataSize &&
00099            "Invalid fixup offset!");
00100 
00101     // Check that uppper bits are either all zeros or all ones.
00102     // Specifically ignore overflow/underflow as long as the leakage is
00103     // limited to the lower bits. This is to remain compatible with
00104     // other assemblers.
00105     assert(isIntN(Size * 8 + 1, Value) &&
00106            "Value does not fit in the Fixup field");
00107 
00108     for (unsigned i = 0; i != Size; ++i)
00109       Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8));
00110   }
00111 
00112   bool mayNeedRelaxation(const MCInst &Inst) const;
00113 
00114   bool fixupNeedsRelaxation(const MCFixup &Fixup,
00115                             uint64_t Value,
00116                             const MCRelaxableFragment *DF,
00117                             const MCAsmLayout &Layout) const;
00118 
00119   void relaxInstruction(const MCInst &Inst, MCInst &Res) const;
00120 
00121   bool writeNopData(uint64_t Count, MCObjectWriter *OW) const;
00122 };
00123 } // end anonymous namespace
00124 
00125 static unsigned getRelaxedOpcodeBranch(unsigned Op) {
00126   switch (Op) {
00127   default:
00128     return Op;
00129 
00130   case X86::JAE_1: return X86::JAE_4;
00131   case X86::JA_1:  return X86::JA_4;
00132   case X86::JBE_1: return X86::JBE_4;
00133   case X86::JB_1:  return X86::JB_4;
00134   case X86::JE_1:  return X86::JE_4;
00135   case X86::JGE_1: return X86::JGE_4;
00136   case X86::JG_1:  return X86::JG_4;
00137   case X86::JLE_1: return X86::JLE_4;
00138   case X86::JL_1:  return X86::JL_4;
00139   case X86::JMP_1: return X86::JMP_4;
00140   case X86::JNE_1: return X86::JNE_4;
00141   case X86::JNO_1: return X86::JNO_4;
00142   case X86::JNP_1: return X86::JNP_4;
00143   case X86::JNS_1: return X86::JNS_4;
00144   case X86::JO_1:  return X86::JO_4;
00145   case X86::JP_1:  return X86::JP_4;
00146   case X86::JS_1:  return X86::JS_4;
00147   }
00148 }
00149 
00150 static unsigned getRelaxedOpcodeArith(unsigned Op) {
00151   switch (Op) {
00152   default:
00153     return Op;
00154 
00155     // IMUL
00156   case X86::IMUL16rri8: return X86::IMUL16rri;
00157   case X86::IMUL16rmi8: return X86::IMUL16rmi;
00158   case X86::IMUL32rri8: return X86::IMUL32rri;
00159   case X86::IMUL32rmi8: return X86::IMUL32rmi;
00160   case X86::IMUL64rri8: return X86::IMUL64rri32;
00161   case X86::IMUL64rmi8: return X86::IMUL64rmi32;
00162 
00163     // AND
00164   case X86::AND16ri8: return X86::AND16ri;
00165   case X86::AND16mi8: return X86::AND16mi;
00166   case X86::AND32ri8: return X86::AND32ri;
00167   case X86::AND32mi8: return X86::AND32mi;
00168   case X86::AND64ri8: return X86::AND64ri32;
00169   case X86::AND64mi8: return X86::AND64mi32;
00170 
00171     // OR
00172   case X86::OR16ri8: return X86::OR16ri;
00173   case X86::OR16mi8: return X86::OR16mi;
00174   case X86::OR32ri8: return X86::OR32ri;
00175   case X86::OR32mi8: return X86::OR32mi;
00176   case X86::OR64ri8: return X86::OR64ri32;
00177   case X86::OR64mi8: return X86::OR64mi32;
00178 
00179     // XOR
00180   case X86::XOR16ri8: return X86::XOR16ri;
00181   case X86::XOR16mi8: return X86::XOR16mi;
00182   case X86::XOR32ri8: return X86::XOR32ri;
00183   case X86::XOR32mi8: return X86::XOR32mi;
00184   case X86::XOR64ri8: return X86::XOR64ri32;
00185   case X86::XOR64mi8: return X86::XOR64mi32;
00186 
00187     // ADD
00188   case X86::ADD16ri8: return X86::ADD16ri;
00189   case X86::ADD16mi8: return X86::ADD16mi;
00190   case X86::ADD32ri8: return X86::ADD32ri;
00191   case X86::ADD32mi8: return X86::ADD32mi;
00192   case X86::ADD64ri8: return X86::ADD64ri32;
00193   case X86::ADD64mi8: return X86::ADD64mi32;
00194 
00195     // SUB
00196   case X86::SUB16ri8: return X86::SUB16ri;
00197   case X86::SUB16mi8: return X86::SUB16mi;
00198   case X86::SUB32ri8: return X86::SUB32ri;
00199   case X86::SUB32mi8: return X86::SUB32mi;
00200   case X86::SUB64ri8: return X86::SUB64ri32;
00201   case X86::SUB64mi8: return X86::SUB64mi32;
00202 
00203     // CMP
00204   case X86::CMP16ri8: return X86::CMP16ri;
00205   case X86::CMP16mi8: return X86::CMP16mi;
00206   case X86::CMP32ri8: return X86::CMP32ri;
00207   case X86::CMP32mi8: return X86::CMP32mi;
00208   case X86::CMP64ri8: return X86::CMP64ri32;
00209   case X86::CMP64mi8: return X86::CMP64mi32;
00210 
00211     // PUSH
00212   case X86::PUSHi8: return X86::PUSHi32;
00213   case X86::PUSHi16: return X86::PUSHi32;
00214   case X86::PUSH64i8: return X86::PUSH64i32;
00215   case X86::PUSH64i16: return X86::PUSH64i32;
00216   }
00217 }
00218 
00219 static unsigned getRelaxedOpcode(unsigned Op) {
00220   unsigned R = getRelaxedOpcodeArith(Op);
00221   if (R != Op)
00222     return R;
00223   return getRelaxedOpcodeBranch(Op);
00224 }
00225 
00226 bool X86AsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
00227   // Branches can always be relaxed.
00228   if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode())
00229     return true;
00230 
00231   if (MCDisableArithRelaxation)
00232     return false;
00233 
00234   // Check if this instruction is ever relaxable.
00235   if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode())
00236     return false;
00237 
00238 
00239   // Check if it has an expression and is not RIP relative.
00240   bool hasExp = false;
00241   bool hasRIP = false;
00242   for (unsigned i = 0; i < Inst.getNumOperands(); ++i) {
00243     const MCOperand &Op = Inst.getOperand(i);
00244     if (Op.isExpr())
00245       hasExp = true;
00246 
00247     if (Op.isReg() && Op.getReg() == X86::RIP)
00248       hasRIP = true;
00249   }
00250 
00251   // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on
00252   // how we do relaxations?
00253   return hasExp && !hasRIP;
00254 }
00255 
00256 bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
00257                                          uint64_t Value,
00258                                          const MCRelaxableFragment *DF,
00259                                          const MCAsmLayout &Layout) const {
00260   // Relax if the value is too big for a (signed) i8.
00261   return int64_t(Value) != int64_t(int8_t(Value));
00262 }
00263 
00264 // FIXME: Can tblgen help at all here to verify there aren't other instructions
00265 // we can relax?
00266 void X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
00267   // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel.
00268   unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
00269 
00270   if (RelaxedOp == Inst.getOpcode()) {
00271     SmallString<256> Tmp;
00272     raw_svector_ostream OS(Tmp);
00273     Inst.dump_pretty(OS);
00274     OS << "\n";
00275     report_fatal_error("unexpected instruction to relax: " + OS.str());
00276   }
00277 
00278   Res = Inst;
00279   Res.setOpcode(RelaxedOp);
00280 }
00281 
00282 /// \brief Write a sequence of optimal nops to the output, covering \p Count
00283 /// bytes.
00284 /// \return - true on success, false on failure
00285 bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
00286   static const uint8_t Nops[10][10] = {
00287     // nop
00288     {0x90},
00289     // xchg %ax,%ax
00290     {0x66, 0x90},
00291     // nopl (%[re]ax)
00292     {0x0f, 0x1f, 0x00},
00293     // nopl 0(%[re]ax)
00294     {0x0f, 0x1f, 0x40, 0x00},
00295     // nopl 0(%[re]ax,%[re]ax,1)
00296     {0x0f, 0x1f, 0x44, 0x00, 0x00},
00297     // nopw 0(%[re]ax,%[re]ax,1)
00298     {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
00299     // nopl 0L(%[re]ax)
00300     {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
00301     // nopl 0L(%[re]ax,%[re]ax,1)
00302     {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
00303     // nopw 0L(%[re]ax,%[re]ax,1)
00304     {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
00305     // nopw %cs:0L(%[re]ax,%[re]ax,1)
00306     {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
00307   };
00308 
00309   // This CPU doesnt support long nops. If needed add more.
00310   // FIXME: Can we get this from the subtarget somehow?
00311   if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
00312       CPU == "pentium" || CPU == "pentium-mmx" || CPU == "geode") {
00313     for (uint64_t i = 0; i < Count; ++i)
00314       OW->Write8(0x90);
00315     return true;
00316   }
00317 
00318   // 15 is the longest single nop instruction.  Emit as many 15-byte nops as
00319   // needed, then emit a nop of the remaining length.
00320   do {
00321     const uint8_t ThisNopLength = (uint8_t) std::min(Count, (uint64_t) 15);
00322     const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
00323     for (uint8_t i = 0; i < Prefixes; i++)
00324       OW->Write8(0x66);
00325     const uint8_t Rest = ThisNopLength - Prefixes;
00326     for (uint8_t i = 0; i < Rest; i++)
00327       OW->Write8(Nops[Rest - 1][i]);
00328     Count -= ThisNopLength;
00329   } while (Count != 0);
00330 
00331   return true;
00332 }
00333 
00334 /* *** */
00335 
00336 namespace {
00337 class ELFX86AsmBackend : public X86AsmBackend {
00338 public:
00339   uint8_t OSABI;
00340   ELFX86AsmBackend(const Target &T, uint8_t _OSABI, StringRef CPU)
00341     : X86AsmBackend(T, CPU), OSABI(_OSABI) {
00342     HasReliableSymbolDifference = true;
00343   }
00344 
00345   virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
00346     const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section);
00347     return ES.getFlags() & ELF::SHF_MERGE;
00348   }
00349 };
00350 
00351 class ELFX86_32AsmBackend : public ELFX86AsmBackend {
00352 public:
00353   ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU)
00354     : ELFX86AsmBackend(T, OSABI, CPU) {}
00355 
00356   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
00357     return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, ELF::EM_386);
00358   }
00359 };
00360 
00361 class ELFX86_64AsmBackend : public ELFX86AsmBackend {
00362 public:
00363   ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU)
00364     : ELFX86AsmBackend(T, OSABI, CPU) {}
00365 
00366   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
00367     return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64);
00368   }
00369 };
00370 
00371 class WindowsX86AsmBackend : public X86AsmBackend {
00372   bool Is64Bit;
00373 
00374 public:
00375   WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU)
00376     : X86AsmBackend(T, CPU)
00377     , Is64Bit(is64Bit) {
00378   }
00379 
00380   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
00381     return createX86WinCOFFObjectWriter(OS, Is64Bit);
00382   }
00383 };
00384 
00385 class DarwinX86AsmBackend : public X86AsmBackend {
00386 public:
00387   DarwinX86AsmBackend(const Target &T, StringRef CPU)
00388     : X86AsmBackend(T, CPU) { }
00389 };
00390 
00391 class DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
00392 public:
00393   DarwinX86_32AsmBackend(const Target &T, StringRef CPU)
00394     : DarwinX86AsmBackend(T, CPU) {}
00395 
00396   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
00397     return createX86MachObjectWriter(OS, /*Is64Bit=*/false,
00398                                      object::mach::CTM_i386,
00399                                      object::mach::CSX86_ALL);
00400   }
00401 };
00402 
00403 class DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
00404 public:
00405   DarwinX86_64AsmBackend(const Target &T, StringRef CPU)
00406     : DarwinX86AsmBackend(T, CPU) {
00407     HasReliableSymbolDifference = true;
00408   }
00409 
00410   MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
00411     return createX86MachObjectWriter(OS, /*Is64Bit=*/true,
00412                                      object::mach::CTM_x86_64,
00413                                      object::mach::CSX86_ALL);
00414   }
00415 
00416   virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
00417     // Temporary labels in the string literals sections require symbols. The
00418     // issue is that the x86_64 relocation format does not allow symbol +
00419     // offset, and so the linker does not have enough information to resolve the
00420     // access to the appropriate atom unless an external relocation is used. For
00421     // non-cstring sections, we expect the compiler to use a non-temporary label
00422     // for anything that could have an addend pointing outside the symbol.
00423     //
00424     // See <rdar://problem/4765733>.
00425     const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
00426     return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS;
00427   }
00428 
00429   virtual bool isSectionAtomizable(const MCSection &Section) const {
00430     const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section);
00431     // Fixed sized data sections are uniqued, they cannot be diced into atoms.
00432     switch (SMO.getType()) {
00433     default:
00434       return true;
00435 
00436     case MCSectionMachO::S_4BYTE_LITERALS:
00437     case MCSectionMachO::S_8BYTE_LITERALS:
00438     case MCSectionMachO::S_16BYTE_LITERALS:
00439     case MCSectionMachO::S_LITERAL_POINTERS:
00440     case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS:
00441     case MCSectionMachO::S_LAZY_SYMBOL_POINTERS:
00442     case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS:
00443     case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS:
00444     case MCSectionMachO::S_INTERPOSING:
00445       return false;
00446     }
00447   }
00448 };
00449 
00450 } // end anonymous namespace
00451 
00452 MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
00453   Triple TheTriple(TT);
00454 
00455   if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
00456     return new DarwinX86_32AsmBackend(T, CPU);
00457 
00458   if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
00459     return new WindowsX86AsmBackend(T, false, CPU);
00460 
00461   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
00462   return new ELFX86_32AsmBackend(T, OSABI, CPU);
00463 }
00464 
00465 MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
00466   Triple TheTriple(TT);
00467 
00468   if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
00469     return new DarwinX86_64AsmBackend(T, CPU);
00470 
00471   if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
00472     return new WindowsX86AsmBackend(T, true, CPU);
00473 
00474   uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
00475   return new ELFX86_64AsmBackend(T, OSABI, CPU);
00476 }