1226584Sdim//===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim 10226584Sdim#include "MCTargetDesc/X86BaseInfo.h" 11226584Sdim#include "MCTargetDesc/X86FixupKinds.h" 12234353Sdim#include "llvm/MC/MCAsmBackend.h" 13226584Sdim#include "llvm/MC/MCAssembler.h" 14226584Sdim#include "llvm/MC/MCELFObjectWriter.h" 15226584Sdim#include "llvm/MC/MCExpr.h" 16226584Sdim#include "llvm/MC/MCFixupKindInfo.h" 17226584Sdim#include "llvm/MC/MCMachObjectWriter.h" 18226584Sdim#include "llvm/MC/MCObjectWriter.h" 19226584Sdim#include "llvm/MC/MCSectionCOFF.h" 20226584Sdim#include "llvm/MC/MCSectionELF.h" 21226584Sdim#include "llvm/MC/MCSectionMachO.h" 22226584Sdim#include "llvm/Object/MachOFormat.h" 23226584Sdim#include "llvm/Support/CommandLine.h" 24226584Sdim#include "llvm/Support/ELF.h" 25226584Sdim#include "llvm/Support/ErrorHandling.h" 26226584Sdim#include "llvm/Support/TargetRegistry.h" 27226584Sdim#include "llvm/Support/raw_ostream.h" 28226584Sdimusing namespace llvm; 29226584Sdim 30226584Sdim// Option to allow disabling arithmetic relaxation to workaround PR9807, which 31226584Sdim// is useful when running bitwise comparison experiments on Darwin. We should be 32226584Sdim// able to remove this once PR9807 is resolved. 33226584Sdimstatic cl::opt<bool> 34226584SdimMCDisableArithRelaxation("mc-x86-disable-arith-relaxation", 35226584Sdim cl::desc("Disable relaxation of arithmetic instruction for X86")); 36226584Sdim 37226584Sdimstatic unsigned getFixupKindLog2Size(unsigned Kind) { 38226584Sdim switch (Kind) { 39234353Sdim default: llvm_unreachable("invalid fixup kind!"); 40226584Sdim case FK_PCRel_1: 41234353Sdim case FK_SecRel_1: 42226584Sdim case FK_Data_1: return 0; 43226584Sdim case FK_PCRel_2: 44234353Sdim case FK_SecRel_2: 45226584Sdim case FK_Data_2: return 1; 46226584Sdim case FK_PCRel_4: 47226584Sdim case X86::reloc_riprel_4byte: 48226584Sdim case X86::reloc_riprel_4byte_movq_load: 49226584Sdim case X86::reloc_signed_4byte: 50226584Sdim case X86::reloc_global_offset_table: 51234353Sdim case FK_SecRel_4: 52226584Sdim case FK_Data_4: return 2; 53226584Sdim case FK_PCRel_8: 54234353Sdim case FK_SecRel_8: 55226584Sdim case FK_Data_8: return 3; 56226584Sdim } 57226584Sdim} 58226584Sdim 59226584Sdimnamespace { 60226584Sdim 61226584Sdimclass X86ELFObjectWriter : public MCELFObjectTargetWriter { 62226584Sdimpublic: 63234353Sdim X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine, 64234353Sdim bool HasRelocationAddend, bool foobar) 65234353Sdim : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {} 66226584Sdim}; 67226584Sdim 68226584Sdimclass X86AsmBackend : public MCAsmBackend { 69241430Sdim StringRef CPU; 70226584Sdimpublic: 71241430Sdim X86AsmBackend(const Target &T, StringRef _CPU) 72241430Sdim : MCAsmBackend(), CPU(_CPU) {} 73226584Sdim 74226584Sdim unsigned getNumFixupKinds() const { 75226584Sdim return X86::NumTargetFixupKinds; 76226584Sdim } 77226584Sdim 78226584Sdim const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { 79226584Sdim const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { 80226584Sdim { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, 81226584Sdim { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel}, 82226584Sdim { "reloc_signed_4byte", 0, 4 * 8, 0}, 83226584Sdim { "reloc_global_offset_table", 0, 4 * 8, 0} 84226584Sdim }; 85226584Sdim 86226584Sdim if (Kind < FirstTargetFixupKind) 87226584Sdim return MCAsmBackend::getFixupKindInfo(Kind); 88226584Sdim 89226584Sdim assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 90226584Sdim "Invalid kind!"); 91226584Sdim return Infos[Kind - FirstTargetFixupKind]; 92226584Sdim } 93226584Sdim 94234353Sdim void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 95226584Sdim uint64_t Value) const { 96226584Sdim unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); 97226584Sdim 98226584Sdim assert(Fixup.getOffset() + Size <= DataSize && 99226584Sdim "Invalid fixup offset!"); 100226584Sdim 101226584Sdim // Check that uppper bits are either all zeros or all ones. 102226584Sdim // Specifically ignore overflow/underflow as long as the leakage is 103226584Sdim // limited to the lower bits. This is to remain compatible with 104226584Sdim // other assemblers. 105226584Sdim assert(isIntN(Size * 8 + 1, Value) && 106226584Sdim "Value does not fit in the Fixup field"); 107226584Sdim 108226584Sdim for (unsigned i = 0; i != Size; ++i) 109226584Sdim Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); 110226584Sdim } 111226584Sdim 112234353Sdim bool mayNeedRelaxation(const MCInst &Inst) const; 113226584Sdim 114234353Sdim bool fixupNeedsRelaxation(const MCFixup &Fixup, 115234353Sdim uint64_t Value, 116249423Sdim const MCRelaxableFragment *DF, 117234353Sdim const MCAsmLayout &Layout) const; 118226584Sdim 119234353Sdim void relaxInstruction(const MCInst &Inst, MCInst &Res) const; 120234353Sdim 121234353Sdim bool writeNopData(uint64_t Count, MCObjectWriter *OW) const; 122226584Sdim}; 123226584Sdim} // end anonymous namespace 124226584Sdim 125226584Sdimstatic unsigned getRelaxedOpcodeBranch(unsigned Op) { 126226584Sdim switch (Op) { 127226584Sdim default: 128226584Sdim return Op; 129226584Sdim 130226584Sdim case X86::JAE_1: return X86::JAE_4; 131226584Sdim case X86::JA_1: return X86::JA_4; 132226584Sdim case X86::JBE_1: return X86::JBE_4; 133226584Sdim case X86::JB_1: return X86::JB_4; 134226584Sdim case X86::JE_1: return X86::JE_4; 135226584Sdim case X86::JGE_1: return X86::JGE_4; 136226584Sdim case X86::JG_1: return X86::JG_4; 137226584Sdim case X86::JLE_1: return X86::JLE_4; 138226584Sdim case X86::JL_1: return X86::JL_4; 139226584Sdim case X86::JMP_1: return X86::JMP_4; 140226584Sdim case X86::JNE_1: return X86::JNE_4; 141226584Sdim case X86::JNO_1: return X86::JNO_4; 142226584Sdim case X86::JNP_1: return X86::JNP_4; 143226584Sdim case X86::JNS_1: return X86::JNS_4; 144226584Sdim case X86::JO_1: return X86::JO_4; 145226584Sdim case X86::JP_1: return X86::JP_4; 146226584Sdim case X86::JS_1: return X86::JS_4; 147226584Sdim } 148226584Sdim} 149226584Sdim 150226584Sdimstatic unsigned getRelaxedOpcodeArith(unsigned Op) { 151226584Sdim switch (Op) { 152226584Sdim default: 153226584Sdim return Op; 154226584Sdim 155226584Sdim // IMUL 156226584Sdim case X86::IMUL16rri8: return X86::IMUL16rri; 157226584Sdim case X86::IMUL16rmi8: return X86::IMUL16rmi; 158226584Sdim case X86::IMUL32rri8: return X86::IMUL32rri; 159226584Sdim case X86::IMUL32rmi8: return X86::IMUL32rmi; 160226584Sdim case X86::IMUL64rri8: return X86::IMUL64rri32; 161226584Sdim case X86::IMUL64rmi8: return X86::IMUL64rmi32; 162226584Sdim 163226584Sdim // AND 164226584Sdim case X86::AND16ri8: return X86::AND16ri; 165226584Sdim case X86::AND16mi8: return X86::AND16mi; 166226584Sdim case X86::AND32ri8: return X86::AND32ri; 167226584Sdim case X86::AND32mi8: return X86::AND32mi; 168226584Sdim case X86::AND64ri8: return X86::AND64ri32; 169226584Sdim case X86::AND64mi8: return X86::AND64mi32; 170226584Sdim 171226584Sdim // OR 172226584Sdim case X86::OR16ri8: return X86::OR16ri; 173226584Sdim case X86::OR16mi8: return X86::OR16mi; 174226584Sdim case X86::OR32ri8: return X86::OR32ri; 175226584Sdim case X86::OR32mi8: return X86::OR32mi; 176226584Sdim case X86::OR64ri8: return X86::OR64ri32; 177226584Sdim case X86::OR64mi8: return X86::OR64mi32; 178226584Sdim 179226584Sdim // XOR 180226584Sdim case X86::XOR16ri8: return X86::XOR16ri; 181226584Sdim case X86::XOR16mi8: return X86::XOR16mi; 182226584Sdim case X86::XOR32ri8: return X86::XOR32ri; 183226584Sdim case X86::XOR32mi8: return X86::XOR32mi; 184226584Sdim case X86::XOR64ri8: return X86::XOR64ri32; 185226584Sdim case X86::XOR64mi8: return X86::XOR64mi32; 186226584Sdim 187226584Sdim // ADD 188226584Sdim case X86::ADD16ri8: return X86::ADD16ri; 189226584Sdim case X86::ADD16mi8: return X86::ADD16mi; 190226584Sdim case X86::ADD32ri8: return X86::ADD32ri; 191226584Sdim case X86::ADD32mi8: return X86::ADD32mi; 192226584Sdim case X86::ADD64ri8: return X86::ADD64ri32; 193226584Sdim case X86::ADD64mi8: return X86::ADD64mi32; 194226584Sdim 195226584Sdim // SUB 196226584Sdim case X86::SUB16ri8: return X86::SUB16ri; 197226584Sdim case X86::SUB16mi8: return X86::SUB16mi; 198226584Sdim case X86::SUB32ri8: return X86::SUB32ri; 199226584Sdim case X86::SUB32mi8: return X86::SUB32mi; 200226584Sdim case X86::SUB64ri8: return X86::SUB64ri32; 201226584Sdim case X86::SUB64mi8: return X86::SUB64mi32; 202226584Sdim 203226584Sdim // CMP 204226584Sdim case X86::CMP16ri8: return X86::CMP16ri; 205226584Sdim case X86::CMP16mi8: return X86::CMP16mi; 206226584Sdim case X86::CMP32ri8: return X86::CMP32ri; 207226584Sdim case X86::CMP32mi8: return X86::CMP32mi; 208226584Sdim case X86::CMP64ri8: return X86::CMP64ri32; 209226584Sdim case X86::CMP64mi8: return X86::CMP64mi32; 210226584Sdim 211226584Sdim // PUSH 212226584Sdim case X86::PUSHi8: return X86::PUSHi32; 213226584Sdim case X86::PUSHi16: return X86::PUSHi32; 214226584Sdim case X86::PUSH64i8: return X86::PUSH64i32; 215226584Sdim case X86::PUSH64i16: return X86::PUSH64i32; 216226584Sdim } 217226584Sdim} 218226584Sdim 219226584Sdimstatic unsigned getRelaxedOpcode(unsigned Op) { 220226584Sdim unsigned R = getRelaxedOpcodeArith(Op); 221226584Sdim if (R != Op) 222226584Sdim return R; 223226584Sdim return getRelaxedOpcodeBranch(Op); 224226584Sdim} 225226584Sdim 226234353Sdimbool X86AsmBackend::mayNeedRelaxation(const MCInst &Inst) const { 227226584Sdim // Branches can always be relaxed. 228226584Sdim if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode()) 229226584Sdim return true; 230226584Sdim 231226584Sdim if (MCDisableArithRelaxation) 232226584Sdim return false; 233226584Sdim 234226584Sdim // Check if this instruction is ever relaxable. 235226584Sdim if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode()) 236226584Sdim return false; 237226584Sdim 238226584Sdim 239226584Sdim // Check if it has an expression and is not RIP relative. 240226584Sdim bool hasExp = false; 241226584Sdim bool hasRIP = false; 242226584Sdim for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { 243226584Sdim const MCOperand &Op = Inst.getOperand(i); 244226584Sdim if (Op.isExpr()) 245226584Sdim hasExp = true; 246226584Sdim 247226584Sdim if (Op.isReg() && Op.getReg() == X86::RIP) 248226584Sdim hasRIP = true; 249226584Sdim } 250226584Sdim 251226584Sdim // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on 252226584Sdim // how we do relaxations? 253226584Sdim return hasExp && !hasRIP; 254226584Sdim} 255226584Sdim 256234353Sdimbool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, 257234353Sdim uint64_t Value, 258249423Sdim const MCRelaxableFragment *DF, 259234353Sdim const MCAsmLayout &Layout) const { 260234353Sdim // Relax if the value is too big for a (signed) i8. 261234353Sdim return int64_t(Value) != int64_t(int8_t(Value)); 262234353Sdim} 263234353Sdim 264226584Sdim// FIXME: Can tblgen help at all here to verify there aren't other instructions 265226584Sdim// we can relax? 266234353Sdimvoid X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { 267226584Sdim // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. 268226584Sdim unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); 269226584Sdim 270226584Sdim if (RelaxedOp == Inst.getOpcode()) { 271226584Sdim SmallString<256> Tmp; 272226584Sdim raw_svector_ostream OS(Tmp); 273226584Sdim Inst.dump_pretty(OS); 274226584Sdim OS << "\n"; 275226584Sdim report_fatal_error("unexpected instruction to relax: " + OS.str()); 276226584Sdim } 277226584Sdim 278226584Sdim Res = Inst; 279226584Sdim Res.setOpcode(RelaxedOp); 280226584Sdim} 281226584Sdim 282249423Sdim/// \brief Write a sequence of optimal nops to the output, covering \p Count 283249423Sdim/// bytes. 284249423Sdim/// \return - true on success, false on failure 285234353Sdimbool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { 286226584Sdim static const uint8_t Nops[10][10] = { 287226584Sdim // nop 288226584Sdim {0x90}, 289226584Sdim // xchg %ax,%ax 290226584Sdim {0x66, 0x90}, 291226584Sdim // nopl (%[re]ax) 292226584Sdim {0x0f, 0x1f, 0x00}, 293226584Sdim // nopl 0(%[re]ax) 294226584Sdim {0x0f, 0x1f, 0x40, 0x00}, 295226584Sdim // nopl 0(%[re]ax,%[re]ax,1) 296226584Sdim {0x0f, 0x1f, 0x44, 0x00, 0x00}, 297226584Sdim // nopw 0(%[re]ax,%[re]ax,1) 298226584Sdim {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 299226584Sdim // nopl 0L(%[re]ax) 300226584Sdim {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 301226584Sdim // nopl 0L(%[re]ax,%[re]ax,1) 302226584Sdim {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 303226584Sdim // nopw 0L(%[re]ax,%[re]ax,1) 304226584Sdim {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 305226584Sdim // nopw %cs:0L(%[re]ax,%[re]ax,1) 306226584Sdim {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 307226584Sdim }; 308226584Sdim 309241430Sdim // This CPU doesnt support long nops. If needed add more. 310241895Sdim // FIXME: Can we get this from the subtarget somehow? 311241895Sdim if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" || 312241895Sdim CPU == "pentium" || CPU == "pentium-mmx" || CPU == "geode") { 313241430Sdim for (uint64_t i = 0; i < Count; ++i) 314241430Sdim OW->Write8(0x90); 315241430Sdim return true; 316241430Sdim } 317241430Sdim 318249423Sdim // 15 is the longest single nop instruction. Emit as many 15-byte nops as 319249423Sdim // needed, then emit a nop of the remaining length. 320249423Sdim do { 321249423Sdim const uint8_t ThisNopLength = (uint8_t) std::min(Count, (uint64_t) 15); 322249423Sdim const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10; 323249423Sdim for (uint8_t i = 0; i < Prefixes; i++) 324249423Sdim OW->Write8(0x66); 325249423Sdim const uint8_t Rest = ThisNopLength - Prefixes; 326249423Sdim for (uint8_t i = 0; i < Rest; i++) 327249423Sdim OW->Write8(Nops[Rest - 1][i]); 328249423Sdim Count -= ThisNopLength; 329249423Sdim } while (Count != 0); 330226584Sdim 331226584Sdim return true; 332226584Sdim} 333226584Sdim 334226584Sdim/* *** */ 335226584Sdim 336226584Sdimnamespace { 337226584Sdimclass ELFX86AsmBackend : public X86AsmBackend { 338226584Sdimpublic: 339234353Sdim uint8_t OSABI; 340241430Sdim ELFX86AsmBackend(const Target &T, uint8_t _OSABI, StringRef CPU) 341241430Sdim : X86AsmBackend(T, CPU), OSABI(_OSABI) { 342226584Sdim HasReliableSymbolDifference = true; 343226584Sdim } 344226584Sdim 345226584Sdim virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 346226584Sdim const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section); 347226584Sdim return ES.getFlags() & ELF::SHF_MERGE; 348226584Sdim } 349226584Sdim}; 350226584Sdim 351226584Sdimclass ELFX86_32AsmBackend : public ELFX86AsmBackend { 352226584Sdimpublic: 353241430Sdim ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 354241430Sdim : ELFX86AsmBackend(T, OSABI, CPU) {} 355226584Sdim 356226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 357243830Sdim return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, ELF::EM_386); 358226584Sdim } 359226584Sdim}; 360226584Sdim 361226584Sdimclass ELFX86_64AsmBackend : public ELFX86AsmBackend { 362226584Sdimpublic: 363241430Sdim ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 364241430Sdim : ELFX86AsmBackend(T, OSABI, CPU) {} 365226584Sdim 366226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 367243830Sdim return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64); 368226584Sdim } 369226584Sdim}; 370226584Sdim 371226584Sdimclass WindowsX86AsmBackend : public X86AsmBackend { 372226584Sdim bool Is64Bit; 373226584Sdim 374226584Sdimpublic: 375241430Sdim WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU) 376241430Sdim : X86AsmBackend(T, CPU) 377226584Sdim , Is64Bit(is64Bit) { 378226584Sdim } 379226584Sdim 380226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 381234353Sdim return createX86WinCOFFObjectWriter(OS, Is64Bit); 382226584Sdim } 383226584Sdim}; 384226584Sdim 385226584Sdimclass DarwinX86AsmBackend : public X86AsmBackend { 386226584Sdimpublic: 387241430Sdim DarwinX86AsmBackend(const Target &T, StringRef CPU) 388241430Sdim : X86AsmBackend(T, CPU) { } 389226584Sdim}; 390226584Sdim 391226584Sdimclass DarwinX86_32AsmBackend : public DarwinX86AsmBackend { 392226584Sdimpublic: 393241430Sdim DarwinX86_32AsmBackend(const Target &T, StringRef CPU) 394241430Sdim : DarwinX86AsmBackend(T, CPU) {} 395226584Sdim 396226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 397226584Sdim return createX86MachObjectWriter(OS, /*Is64Bit=*/false, 398226584Sdim object::mach::CTM_i386, 399226584Sdim object::mach::CSX86_ALL); 400226584Sdim } 401226584Sdim}; 402226584Sdim 403226584Sdimclass DarwinX86_64AsmBackend : public DarwinX86AsmBackend { 404226584Sdimpublic: 405241430Sdim DarwinX86_64AsmBackend(const Target &T, StringRef CPU) 406241430Sdim : DarwinX86AsmBackend(T, CPU) { 407226584Sdim HasReliableSymbolDifference = true; 408226584Sdim } 409226584Sdim 410226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 411226584Sdim return createX86MachObjectWriter(OS, /*Is64Bit=*/true, 412226584Sdim object::mach::CTM_x86_64, 413226584Sdim object::mach::CSX86_ALL); 414226584Sdim } 415226584Sdim 416226584Sdim virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 417226584Sdim // Temporary labels in the string literals sections require symbols. The 418226584Sdim // issue is that the x86_64 relocation format does not allow symbol + 419226584Sdim // offset, and so the linker does not have enough information to resolve the 420226584Sdim // access to the appropriate atom unless an external relocation is used. For 421226584Sdim // non-cstring sections, we expect the compiler to use a non-temporary label 422226584Sdim // for anything that could have an addend pointing outside the symbol. 423226584Sdim // 424226584Sdim // See <rdar://problem/4765733>. 425226584Sdim const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 426226584Sdim return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS; 427226584Sdim } 428226584Sdim 429226584Sdim virtual bool isSectionAtomizable(const MCSection &Section) const { 430226584Sdim const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 431226584Sdim // Fixed sized data sections are uniqued, they cannot be diced into atoms. 432226584Sdim switch (SMO.getType()) { 433226584Sdim default: 434226584Sdim return true; 435226584Sdim 436226584Sdim case MCSectionMachO::S_4BYTE_LITERALS: 437226584Sdim case MCSectionMachO::S_8BYTE_LITERALS: 438226584Sdim case MCSectionMachO::S_16BYTE_LITERALS: 439226584Sdim case MCSectionMachO::S_LITERAL_POINTERS: 440226584Sdim case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS: 441226584Sdim case MCSectionMachO::S_LAZY_SYMBOL_POINTERS: 442226584Sdim case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS: 443226584Sdim case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS: 444226584Sdim case MCSectionMachO::S_INTERPOSING: 445226584Sdim return false; 446226584Sdim } 447226584Sdim } 448226584Sdim}; 449226584Sdim 450226584Sdim} // end anonymous namespace 451226584Sdim 452241430SdimMCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT, StringRef CPU) { 453226584Sdim Triple TheTriple(TT); 454226584Sdim 455226584Sdim if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) 456241430Sdim return new DarwinX86_32AsmBackend(T, CPU); 457226584Sdim 458243830Sdim if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF) 459241430Sdim return new WindowsX86AsmBackend(T, false, CPU); 460226584Sdim 461234353Sdim uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 462241430Sdim return new ELFX86_32AsmBackend(T, OSABI, CPU); 463226584Sdim} 464226584Sdim 465241430SdimMCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT, StringRef CPU) { 466226584Sdim Triple TheTriple(TT); 467226584Sdim 468226584Sdim if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) 469241430Sdim return new DarwinX86_64AsmBackend(T, CPU); 470226584Sdim 471243830Sdim if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF) 472241430Sdim return new WindowsX86AsmBackend(T, true, CPU); 473226584Sdim 474234353Sdim uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 475241430Sdim return new ELFX86_64AsmBackend(T, OSABI, CPU); 476226584Sdim} 477