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" 12263508Sdim#include "llvm/ADT/StringSwitch.h" 13234353Sdim#include "llvm/MC/MCAsmBackend.h" 14226584Sdim#include "llvm/MC/MCAssembler.h" 15226584Sdim#include "llvm/MC/MCELFObjectWriter.h" 16226584Sdim#include "llvm/MC/MCExpr.h" 17226584Sdim#include "llvm/MC/MCFixupKindInfo.h" 18226584Sdim#include "llvm/MC/MCMachObjectWriter.h" 19226584Sdim#include "llvm/MC/MCObjectWriter.h" 20226584Sdim#include "llvm/MC/MCSectionCOFF.h" 21226584Sdim#include "llvm/MC/MCSectionELF.h" 22226584Sdim#include "llvm/MC/MCSectionMachO.h" 23226584Sdim#include "llvm/Support/CommandLine.h" 24226584Sdim#include "llvm/Support/ELF.h" 25226584Sdim#include "llvm/Support/ErrorHandling.h" 26263508Sdim#include "llvm/Support/MachO.h" 27226584Sdim#include "llvm/Support/TargetRegistry.h" 28226584Sdim#include "llvm/Support/raw_ostream.h" 29226584Sdimusing namespace llvm; 30226584Sdim 31226584Sdim// Option to allow disabling arithmetic relaxation to workaround PR9807, which 32226584Sdim// is useful when running bitwise comparison experiments on Darwin. We should be 33226584Sdim// able to remove this once PR9807 is resolved. 34226584Sdimstatic cl::opt<bool> 35226584SdimMCDisableArithRelaxation("mc-x86-disable-arith-relaxation", 36226584Sdim cl::desc("Disable relaxation of arithmetic instruction for X86")); 37226584Sdim 38226584Sdimstatic unsigned getFixupKindLog2Size(unsigned Kind) { 39226584Sdim switch (Kind) { 40234353Sdim default: llvm_unreachable("invalid fixup kind!"); 41226584Sdim case FK_PCRel_1: 42234353Sdim case FK_SecRel_1: 43226584Sdim case FK_Data_1: return 0; 44226584Sdim case FK_PCRel_2: 45234353Sdim case FK_SecRel_2: 46226584Sdim case FK_Data_2: return 1; 47226584Sdim case FK_PCRel_4: 48226584Sdim case X86::reloc_riprel_4byte: 49226584Sdim case X86::reloc_riprel_4byte_movq_load: 50226584Sdim case X86::reloc_signed_4byte: 51226584Sdim case X86::reloc_global_offset_table: 52234353Sdim case FK_SecRel_4: 53226584Sdim case FK_Data_4: return 2; 54226584Sdim case FK_PCRel_8: 55234353Sdim case FK_SecRel_8: 56226584Sdim case FK_Data_8: return 3; 57226584Sdim } 58226584Sdim} 59226584Sdim 60226584Sdimnamespace { 61226584Sdim 62226584Sdimclass X86ELFObjectWriter : public MCELFObjectTargetWriter { 63226584Sdimpublic: 64234353Sdim X86ELFObjectWriter(bool is64Bit, uint8_t OSABI, uint16_t EMachine, 65234353Sdim bool HasRelocationAddend, bool foobar) 66234353Sdim : MCELFObjectTargetWriter(is64Bit, OSABI, EMachine, HasRelocationAddend) {} 67226584Sdim}; 68226584Sdim 69226584Sdimclass X86AsmBackend : public MCAsmBackend { 70241430Sdim StringRef CPU; 71263508Sdim bool HasNopl; 72226584Sdimpublic: 73241430Sdim X86AsmBackend(const Target &T, StringRef _CPU) 74263508Sdim : MCAsmBackend(), CPU(_CPU) { 75263508Sdim HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" && 76263508Sdim CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" && 77263508Sdim CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" && 78263508Sdim CPU != "geode" && CPU != "winchip-c6" && CPU != "winchip2" && 79263508Sdim CPU != "c3" && CPU != "c3-2"; 80263508Sdim } 81226584Sdim 82226584Sdim unsigned getNumFixupKinds() const { 83226584Sdim return X86::NumTargetFixupKinds; 84226584Sdim } 85226584Sdim 86226584Sdim const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { 87226584Sdim const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = { 88226584Sdim { "reloc_riprel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, 89226584Sdim { "reloc_riprel_4byte_movq_load", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel}, 90226584Sdim { "reloc_signed_4byte", 0, 4 * 8, 0}, 91226584Sdim { "reloc_global_offset_table", 0, 4 * 8, 0} 92226584Sdim }; 93226584Sdim 94226584Sdim if (Kind < FirstTargetFixupKind) 95226584Sdim return MCAsmBackend::getFixupKindInfo(Kind); 96226584Sdim 97226584Sdim assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() && 98226584Sdim "Invalid kind!"); 99226584Sdim return Infos[Kind - FirstTargetFixupKind]; 100226584Sdim } 101226584Sdim 102234353Sdim void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, 103226584Sdim uint64_t Value) const { 104226584Sdim unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); 105226584Sdim 106226584Sdim assert(Fixup.getOffset() + Size <= DataSize && 107226584Sdim "Invalid fixup offset!"); 108226584Sdim 109226584Sdim // Check that uppper bits are either all zeros or all ones. 110226584Sdim // Specifically ignore overflow/underflow as long as the leakage is 111226584Sdim // limited to the lower bits. This is to remain compatible with 112226584Sdim // other assemblers. 113226584Sdim assert(isIntN(Size * 8 + 1, Value) && 114226584Sdim "Value does not fit in the Fixup field"); 115226584Sdim 116226584Sdim for (unsigned i = 0; i != Size; ++i) 117226584Sdim Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8)); 118226584Sdim } 119226584Sdim 120234353Sdim bool mayNeedRelaxation(const MCInst &Inst) const; 121226584Sdim 122234353Sdim bool fixupNeedsRelaxation(const MCFixup &Fixup, 123234353Sdim uint64_t Value, 124249423Sdim const MCRelaxableFragment *DF, 125234353Sdim const MCAsmLayout &Layout) const; 126226584Sdim 127234353Sdim void relaxInstruction(const MCInst &Inst, MCInst &Res) const; 128234353Sdim 129234353Sdim bool writeNopData(uint64_t Count, MCObjectWriter *OW) const; 130226584Sdim}; 131226584Sdim} // end anonymous namespace 132226584Sdim 133226584Sdimstatic unsigned getRelaxedOpcodeBranch(unsigned Op) { 134226584Sdim switch (Op) { 135226584Sdim default: 136226584Sdim return Op; 137226584Sdim 138226584Sdim case X86::JAE_1: return X86::JAE_4; 139226584Sdim case X86::JA_1: return X86::JA_4; 140226584Sdim case X86::JBE_1: return X86::JBE_4; 141226584Sdim case X86::JB_1: return X86::JB_4; 142226584Sdim case X86::JE_1: return X86::JE_4; 143226584Sdim case X86::JGE_1: return X86::JGE_4; 144226584Sdim case X86::JG_1: return X86::JG_4; 145226584Sdim case X86::JLE_1: return X86::JLE_4; 146226584Sdim case X86::JL_1: return X86::JL_4; 147226584Sdim case X86::JMP_1: return X86::JMP_4; 148226584Sdim case X86::JNE_1: return X86::JNE_4; 149226584Sdim case X86::JNO_1: return X86::JNO_4; 150226584Sdim case X86::JNP_1: return X86::JNP_4; 151226584Sdim case X86::JNS_1: return X86::JNS_4; 152226584Sdim case X86::JO_1: return X86::JO_4; 153226584Sdim case X86::JP_1: return X86::JP_4; 154226584Sdim case X86::JS_1: return X86::JS_4; 155226584Sdim } 156226584Sdim} 157226584Sdim 158226584Sdimstatic unsigned getRelaxedOpcodeArith(unsigned Op) { 159226584Sdim switch (Op) { 160226584Sdim default: 161226584Sdim return Op; 162226584Sdim 163226584Sdim // IMUL 164226584Sdim case X86::IMUL16rri8: return X86::IMUL16rri; 165226584Sdim case X86::IMUL16rmi8: return X86::IMUL16rmi; 166226584Sdim case X86::IMUL32rri8: return X86::IMUL32rri; 167226584Sdim case X86::IMUL32rmi8: return X86::IMUL32rmi; 168226584Sdim case X86::IMUL64rri8: return X86::IMUL64rri32; 169226584Sdim case X86::IMUL64rmi8: return X86::IMUL64rmi32; 170226584Sdim 171226584Sdim // AND 172226584Sdim case X86::AND16ri8: return X86::AND16ri; 173226584Sdim case X86::AND16mi8: return X86::AND16mi; 174226584Sdim case X86::AND32ri8: return X86::AND32ri; 175226584Sdim case X86::AND32mi8: return X86::AND32mi; 176226584Sdim case X86::AND64ri8: return X86::AND64ri32; 177226584Sdim case X86::AND64mi8: return X86::AND64mi32; 178226584Sdim 179226584Sdim // OR 180226584Sdim case X86::OR16ri8: return X86::OR16ri; 181226584Sdim case X86::OR16mi8: return X86::OR16mi; 182226584Sdim case X86::OR32ri8: return X86::OR32ri; 183226584Sdim case X86::OR32mi8: return X86::OR32mi; 184226584Sdim case X86::OR64ri8: return X86::OR64ri32; 185226584Sdim case X86::OR64mi8: return X86::OR64mi32; 186226584Sdim 187226584Sdim // XOR 188226584Sdim case X86::XOR16ri8: return X86::XOR16ri; 189226584Sdim case X86::XOR16mi8: return X86::XOR16mi; 190226584Sdim case X86::XOR32ri8: return X86::XOR32ri; 191226584Sdim case X86::XOR32mi8: return X86::XOR32mi; 192226584Sdim case X86::XOR64ri8: return X86::XOR64ri32; 193226584Sdim case X86::XOR64mi8: return X86::XOR64mi32; 194226584Sdim 195226584Sdim // ADD 196226584Sdim case X86::ADD16ri8: return X86::ADD16ri; 197226584Sdim case X86::ADD16mi8: return X86::ADD16mi; 198226584Sdim case X86::ADD32ri8: return X86::ADD32ri; 199226584Sdim case X86::ADD32mi8: return X86::ADD32mi; 200226584Sdim case X86::ADD64ri8: return X86::ADD64ri32; 201226584Sdim case X86::ADD64mi8: return X86::ADD64mi32; 202226584Sdim 203226584Sdim // SUB 204226584Sdim case X86::SUB16ri8: return X86::SUB16ri; 205226584Sdim case X86::SUB16mi8: return X86::SUB16mi; 206226584Sdim case X86::SUB32ri8: return X86::SUB32ri; 207226584Sdim case X86::SUB32mi8: return X86::SUB32mi; 208226584Sdim case X86::SUB64ri8: return X86::SUB64ri32; 209226584Sdim case X86::SUB64mi8: return X86::SUB64mi32; 210226584Sdim 211226584Sdim // CMP 212226584Sdim case X86::CMP16ri8: return X86::CMP16ri; 213226584Sdim case X86::CMP16mi8: return X86::CMP16mi; 214226584Sdim case X86::CMP32ri8: return X86::CMP32ri; 215226584Sdim case X86::CMP32mi8: return X86::CMP32mi; 216226584Sdim case X86::CMP64ri8: return X86::CMP64ri32; 217226584Sdim case X86::CMP64mi8: return X86::CMP64mi32; 218226584Sdim 219226584Sdim // PUSH 220226584Sdim case X86::PUSHi8: return X86::PUSHi32; 221226584Sdim case X86::PUSHi16: return X86::PUSHi32; 222226584Sdim case X86::PUSH64i8: return X86::PUSH64i32; 223226584Sdim case X86::PUSH64i16: return X86::PUSH64i32; 224226584Sdim } 225226584Sdim} 226226584Sdim 227226584Sdimstatic unsigned getRelaxedOpcode(unsigned Op) { 228226584Sdim unsigned R = getRelaxedOpcodeArith(Op); 229226584Sdim if (R != Op) 230226584Sdim return R; 231226584Sdim return getRelaxedOpcodeBranch(Op); 232226584Sdim} 233226584Sdim 234234353Sdimbool X86AsmBackend::mayNeedRelaxation(const MCInst &Inst) const { 235226584Sdim // Branches can always be relaxed. 236226584Sdim if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode()) 237226584Sdim return true; 238226584Sdim 239226584Sdim if (MCDisableArithRelaxation) 240226584Sdim return false; 241226584Sdim 242226584Sdim // Check if this instruction is ever relaxable. 243226584Sdim if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode()) 244226584Sdim return false; 245226584Sdim 246226584Sdim 247226584Sdim // Check if it has an expression and is not RIP relative. 248226584Sdim bool hasExp = false; 249226584Sdim bool hasRIP = false; 250226584Sdim for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { 251226584Sdim const MCOperand &Op = Inst.getOperand(i); 252226584Sdim if (Op.isExpr()) 253226584Sdim hasExp = true; 254226584Sdim 255226584Sdim if (Op.isReg() && Op.getReg() == X86::RIP) 256226584Sdim hasRIP = true; 257226584Sdim } 258226584Sdim 259226584Sdim // FIXME: Why exactly do we need the !hasRIP? Is it just a limitation on 260226584Sdim // how we do relaxations? 261226584Sdim return hasExp && !hasRIP; 262226584Sdim} 263226584Sdim 264234353Sdimbool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, 265234353Sdim uint64_t Value, 266249423Sdim const MCRelaxableFragment *DF, 267234353Sdim const MCAsmLayout &Layout) const { 268234353Sdim // Relax if the value is too big for a (signed) i8. 269234353Sdim return int64_t(Value) != int64_t(int8_t(Value)); 270234353Sdim} 271234353Sdim 272226584Sdim// FIXME: Can tblgen help at all here to verify there aren't other instructions 273226584Sdim// we can relax? 274234353Sdimvoid X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { 275226584Sdim // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel. 276226584Sdim unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode()); 277226584Sdim 278226584Sdim if (RelaxedOp == Inst.getOpcode()) { 279226584Sdim SmallString<256> Tmp; 280226584Sdim raw_svector_ostream OS(Tmp); 281226584Sdim Inst.dump_pretty(OS); 282226584Sdim OS << "\n"; 283226584Sdim report_fatal_error("unexpected instruction to relax: " + OS.str()); 284226584Sdim } 285226584Sdim 286226584Sdim Res = Inst; 287226584Sdim Res.setOpcode(RelaxedOp); 288226584Sdim} 289226584Sdim 290249423Sdim/// \brief Write a sequence of optimal nops to the output, covering \p Count 291249423Sdim/// bytes. 292249423Sdim/// \return - true on success, false on failure 293234353Sdimbool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const { 294226584Sdim static const uint8_t Nops[10][10] = { 295226584Sdim // nop 296226584Sdim {0x90}, 297226584Sdim // xchg %ax,%ax 298226584Sdim {0x66, 0x90}, 299226584Sdim // nopl (%[re]ax) 300226584Sdim {0x0f, 0x1f, 0x00}, 301226584Sdim // nopl 0(%[re]ax) 302226584Sdim {0x0f, 0x1f, 0x40, 0x00}, 303226584Sdim // nopl 0(%[re]ax,%[re]ax,1) 304226584Sdim {0x0f, 0x1f, 0x44, 0x00, 0x00}, 305226584Sdim // nopw 0(%[re]ax,%[re]ax,1) 306226584Sdim {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00}, 307226584Sdim // nopl 0L(%[re]ax) 308226584Sdim {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00}, 309226584Sdim // nopl 0L(%[re]ax,%[re]ax,1) 310226584Sdim {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 311226584Sdim // nopw 0L(%[re]ax,%[re]ax,1) 312226584Sdim {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 313226584Sdim // nopw %cs:0L(%[re]ax,%[re]ax,1) 314226584Sdim {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, 315226584Sdim }; 316226584Sdim 317241430Sdim // This CPU doesnt support long nops. If needed add more. 318241895Sdim // FIXME: Can we get this from the subtarget somehow? 319261225Sdim // FIXME: We could generated something better than plain 0x90. 320263508Sdim if (!HasNopl) { 321241430Sdim for (uint64_t i = 0; i < Count; ++i) 322241430Sdim OW->Write8(0x90); 323241430Sdim return true; 324241430Sdim } 325241430Sdim 326249423Sdim // 15 is the longest single nop instruction. Emit as many 15-byte nops as 327249423Sdim // needed, then emit a nop of the remaining length. 328249423Sdim do { 329249423Sdim const uint8_t ThisNopLength = (uint8_t) std::min(Count, (uint64_t) 15); 330249423Sdim const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10; 331249423Sdim for (uint8_t i = 0; i < Prefixes; i++) 332249423Sdim OW->Write8(0x66); 333249423Sdim const uint8_t Rest = ThisNopLength - Prefixes; 334249423Sdim for (uint8_t i = 0; i < Rest; i++) 335249423Sdim OW->Write8(Nops[Rest - 1][i]); 336249423Sdim Count -= ThisNopLength; 337249423Sdim } while (Count != 0); 338226584Sdim 339226584Sdim return true; 340226584Sdim} 341226584Sdim 342226584Sdim/* *** */ 343226584Sdim 344226584Sdimnamespace { 345263508Sdim 346226584Sdimclass ELFX86AsmBackend : public X86AsmBackend { 347226584Sdimpublic: 348234353Sdim uint8_t OSABI; 349241430Sdim ELFX86AsmBackend(const Target &T, uint8_t _OSABI, StringRef CPU) 350241430Sdim : X86AsmBackend(T, CPU), OSABI(_OSABI) { 351226584Sdim HasReliableSymbolDifference = true; 352226584Sdim } 353226584Sdim 354226584Sdim virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 355226584Sdim const MCSectionELF &ES = static_cast<const MCSectionELF&>(Section); 356226584Sdim return ES.getFlags() & ELF::SHF_MERGE; 357226584Sdim } 358226584Sdim}; 359226584Sdim 360226584Sdimclass ELFX86_32AsmBackend : public ELFX86AsmBackend { 361226584Sdimpublic: 362241430Sdim ELFX86_32AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 363241430Sdim : ELFX86AsmBackend(T, OSABI, CPU) {} 364226584Sdim 365226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 366243830Sdim return createX86ELFObjectWriter(OS, /*IsELF64*/ false, OSABI, ELF::EM_386); 367226584Sdim } 368226584Sdim}; 369226584Sdim 370226584Sdimclass ELFX86_64AsmBackend : public ELFX86AsmBackend { 371226584Sdimpublic: 372241430Sdim ELFX86_64AsmBackend(const Target &T, uint8_t OSABI, StringRef CPU) 373241430Sdim : ELFX86AsmBackend(T, OSABI, CPU) {} 374226584Sdim 375226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 376243830Sdim return createX86ELFObjectWriter(OS, /*IsELF64*/ true, OSABI, ELF::EM_X86_64); 377226584Sdim } 378226584Sdim}; 379226584Sdim 380226584Sdimclass WindowsX86AsmBackend : public X86AsmBackend { 381226584Sdim bool Is64Bit; 382226584Sdim 383226584Sdimpublic: 384241430Sdim WindowsX86AsmBackend(const Target &T, bool is64Bit, StringRef CPU) 385241430Sdim : X86AsmBackend(T, CPU) 386226584Sdim , Is64Bit(is64Bit) { 387226584Sdim } 388226584Sdim 389226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 390234353Sdim return createX86WinCOFFObjectWriter(OS, Is64Bit); 391226584Sdim } 392226584Sdim}; 393226584Sdim 394263508Sdimnamespace CU { 395263508Sdim 396263508Sdim /// Compact unwind encoding values. 397263508Sdim enum CompactUnwindEncodings { 398263508Sdim /// [RE]BP based frame where [RE]BP is pused on the stack immediately after 399263508Sdim /// the return address, then [RE]SP is moved to [RE]BP. 400263508Sdim UNWIND_MODE_BP_FRAME = 0x01000000, 401263508Sdim 402263508Sdim /// A frameless function with a small constant stack size. 403263508Sdim UNWIND_MODE_STACK_IMMD = 0x02000000, 404263508Sdim 405263508Sdim /// A frameless function with a large constant stack size. 406263508Sdim UNWIND_MODE_STACK_IND = 0x03000000, 407263508Sdim 408263508Sdim /// No compact unwind encoding is available. 409263508Sdim UNWIND_MODE_DWARF = 0x04000000, 410263508Sdim 411263508Sdim /// Mask for encoding the frame registers. 412263508Sdim UNWIND_BP_FRAME_REGISTERS = 0x00007FFF, 413263508Sdim 414263508Sdim /// Mask for encoding the frameless registers. 415263508Sdim UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF 416263508Sdim }; 417263508Sdim 418263508Sdim} // end CU namespace 419263508Sdim 420226584Sdimclass DarwinX86AsmBackend : public X86AsmBackend { 421263508Sdim const MCRegisterInfo &MRI; 422263508Sdim 423263508Sdim /// \brief Number of registers that can be saved in a compact unwind encoding. 424263508Sdim enum { CU_NUM_SAVED_REGS = 6 }; 425263508Sdim 426263508Sdim mutable unsigned SavedRegs[CU_NUM_SAVED_REGS]; 427263508Sdim bool Is64Bit; 428263508Sdim 429263508Sdim unsigned OffsetSize; ///< Offset of a "push" instruction. 430263508Sdim unsigned PushInstrSize; ///< Size of a "push" instruction. 431263508Sdim unsigned MoveInstrSize; ///< Size of a "move" instruction. 432263508Sdim unsigned StackDivide; ///< Amount to adjust stack stize by. 433263508Sdimprotected: 434263508Sdim /// \brief Implementation of algorithm to generate the compact unwind encoding 435263508Sdim /// for the CFI instructions. 436263508Sdim uint32_t 437263508Sdim generateCompactUnwindEncodingImpl(ArrayRef<MCCFIInstruction> Instrs) const { 438263508Sdim if (Instrs.empty()) return 0; 439263508Sdim 440263508Sdim // Reset the saved registers. 441263508Sdim unsigned SavedRegIdx = 0; 442263508Sdim memset(SavedRegs, 0, sizeof(SavedRegs)); 443263508Sdim 444263508Sdim bool HasFP = false; 445263508Sdim 446263508Sdim // Encode that we are using EBP/RBP as the frame pointer. 447263508Sdim uint32_t CompactUnwindEncoding = 0; 448263508Sdim 449263508Sdim unsigned SubtractInstrIdx = Is64Bit ? 3 : 2; 450263508Sdim unsigned InstrOffset = 0; 451263508Sdim unsigned StackAdjust = 0; 452263508Sdim unsigned StackSize = 0; 453263508Sdim unsigned PrevStackSize = 0; 454263508Sdim unsigned NumDefCFAOffsets = 0; 455263508Sdim 456263508Sdim for (unsigned i = 0, e = Instrs.size(); i != e; ++i) { 457263508Sdim const MCCFIInstruction &Inst = Instrs[i]; 458263508Sdim 459263508Sdim switch (Inst.getOperation()) { 460263508Sdim default: 461263508Sdim // Any other CFI directives indicate a frame that we aren't prepared 462263508Sdim // to represent via compact unwind, so just bail out. 463263508Sdim return 0; 464263508Sdim case MCCFIInstruction::OpDefCfaRegister: { 465263508Sdim // Defines a frame pointer. E.g. 466263508Sdim // 467263508Sdim // movq %rsp, %rbp 468263508Sdim // L0: 469263508Sdim // .cfi_def_cfa_register %rbp 470263508Sdim // 471263508Sdim HasFP = true; 472263508Sdim assert(MRI.getLLVMRegNum(Inst.getRegister(), true) == 473263508Sdim (Is64Bit ? X86::RBP : X86::EBP) && "Invalid frame pointer!"); 474263508Sdim 475263508Sdim // Reset the counts. 476263508Sdim memset(SavedRegs, 0, sizeof(SavedRegs)); 477263508Sdim StackAdjust = 0; 478263508Sdim SavedRegIdx = 0; 479263508Sdim InstrOffset += MoveInstrSize; 480263508Sdim break; 481263508Sdim } 482263508Sdim case MCCFIInstruction::OpDefCfaOffset: { 483263508Sdim // Defines a new offset for the CFA. E.g. 484263508Sdim // 485263508Sdim // With frame: 486263508Sdim // 487263508Sdim // pushq %rbp 488263508Sdim // L0: 489263508Sdim // .cfi_def_cfa_offset 16 490263508Sdim // 491263508Sdim // Without frame: 492263508Sdim // 493263508Sdim // subq $72, %rsp 494263508Sdim // L0: 495263508Sdim // .cfi_def_cfa_offset 80 496263508Sdim // 497263508Sdim PrevStackSize = StackSize; 498263508Sdim StackSize = std::abs(Inst.getOffset()) / StackDivide; 499263508Sdim ++NumDefCFAOffsets; 500263508Sdim break; 501263508Sdim } 502263508Sdim case MCCFIInstruction::OpOffset: { 503263508Sdim // Defines a "push" of a callee-saved register. E.g. 504263508Sdim // 505263508Sdim // pushq %r15 506263508Sdim // pushq %r14 507263508Sdim // pushq %rbx 508263508Sdim // L0: 509263508Sdim // subq $120, %rsp 510263508Sdim // L1: 511263508Sdim // .cfi_offset %rbx, -40 512263508Sdim // .cfi_offset %r14, -32 513263508Sdim // .cfi_offset %r15, -24 514263508Sdim // 515263508Sdim if (SavedRegIdx == CU_NUM_SAVED_REGS) 516263508Sdim // If there are too many saved registers, we cannot use a compact 517263508Sdim // unwind encoding. 518263508Sdim return CU::UNWIND_MODE_DWARF; 519263508Sdim 520263508Sdim unsigned Reg = MRI.getLLVMRegNum(Inst.getRegister(), true); 521263508Sdim SavedRegs[SavedRegIdx++] = Reg; 522263508Sdim StackAdjust += OffsetSize; 523263508Sdim InstrOffset += PushInstrSize; 524263508Sdim break; 525263508Sdim } 526263508Sdim } 527263508Sdim } 528263508Sdim 529263508Sdim StackAdjust /= StackDivide; 530263508Sdim 531263508Sdim if (HasFP) { 532263508Sdim if ((StackAdjust & 0xFF) != StackAdjust) 533263508Sdim // Offset was too big for a compact unwind encoding. 534263508Sdim return CU::UNWIND_MODE_DWARF; 535263508Sdim 536263508Sdim // Get the encoding of the saved registers when we have a frame pointer. 537263508Sdim uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(); 538263508Sdim if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; 539263508Sdim 540263508Sdim CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME; 541263508Sdim CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16; 542263508Sdim CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS; 543263508Sdim } else { 544263508Sdim // If the amount of the stack allocation is the size of a register, then 545263508Sdim // we "push" the RAX/EAX register onto the stack instead of adjusting the 546263508Sdim // stack pointer with a SUB instruction. We don't support the push of the 547263508Sdim // RAX/EAX register with compact unwind. So we check for that situation 548263508Sdim // here. 549263508Sdim if ((NumDefCFAOffsets == SavedRegIdx + 1 && 550263508Sdim StackSize - PrevStackSize == 1) || 551263508Sdim (Instrs.size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2)) 552263508Sdim return CU::UNWIND_MODE_DWARF; 553263508Sdim 554263508Sdim SubtractInstrIdx += InstrOffset; 555263508Sdim ++StackAdjust; 556263508Sdim 557263508Sdim if ((StackSize & 0xFF) == StackSize) { 558263508Sdim // Frameless stack with a small stack size. 559263508Sdim CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD; 560263508Sdim 561263508Sdim // Encode the stack size. 562263508Sdim CompactUnwindEncoding |= (StackSize & 0xFF) << 16; 563263508Sdim } else { 564263508Sdim if ((StackAdjust & 0x7) != StackAdjust) 565263508Sdim // The extra stack adjustments are too big for us to handle. 566263508Sdim return CU::UNWIND_MODE_DWARF; 567263508Sdim 568263508Sdim // Frameless stack with an offset too large for us to encode compactly. 569263508Sdim CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND; 570263508Sdim 571263508Sdim // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP' 572263508Sdim // instruction. 573263508Sdim CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16; 574263508Sdim 575263508Sdim // Encode any extra stack stack adjustments (done via push 576263508Sdim // instructions). 577263508Sdim CompactUnwindEncoding |= (StackAdjust & 0x7) << 13; 578263508Sdim } 579263508Sdim 580263508Sdim // Encode the number of registers saved. (Reverse the list first.) 581263508Sdim std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]); 582263508Sdim CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10; 583263508Sdim 584263508Sdim // Get the encoding of the saved registers when we don't have a frame 585263508Sdim // pointer. 586263508Sdim uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx); 587263508Sdim if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF; 588263508Sdim 589263508Sdim // Encode the register encoding. 590263508Sdim CompactUnwindEncoding |= 591263508Sdim RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION; 592263508Sdim } 593263508Sdim 594263508Sdim return CompactUnwindEncoding; 595263508Sdim } 596263508Sdim 597263508Sdimprivate: 598263508Sdim /// \brief Get the compact unwind number for a given register. The number 599263508Sdim /// corresponds to the enum lists in compact_unwind_encoding.h. 600263508Sdim int getCompactUnwindRegNum(unsigned Reg) const { 601263508Sdim static const uint16_t CU32BitRegs[7] = { 602263508Sdim X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0 603263508Sdim }; 604263508Sdim static const uint16_t CU64BitRegs[] = { 605263508Sdim X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 606263508Sdim }; 607263508Sdim const uint16_t *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs; 608263508Sdim for (int Idx = 1; *CURegs; ++CURegs, ++Idx) 609263508Sdim if (*CURegs == Reg) 610263508Sdim return Idx; 611263508Sdim 612263508Sdim return -1; 613263508Sdim } 614263508Sdim 615263508Sdim /// \brief Return the registers encoded for a compact encoding with a frame 616263508Sdim /// pointer. 617263508Sdim uint32_t encodeCompactUnwindRegistersWithFrame() const { 618263508Sdim // Encode the registers in the order they were saved --- 3-bits per 619263508Sdim // register. The list of saved registers is assumed to be in reverse 620263508Sdim // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS. 621263508Sdim uint32_t RegEnc = 0; 622263508Sdim for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) { 623263508Sdim unsigned Reg = SavedRegs[i]; 624263508Sdim if (Reg == 0) break; 625263508Sdim 626263508Sdim int CURegNum = getCompactUnwindRegNum(Reg); 627263508Sdim if (CURegNum == -1) return ~0U; 628263508Sdim 629263508Sdim // Encode the 3-bit register number in order, skipping over 3-bits for 630263508Sdim // each register. 631263508Sdim RegEnc |= (CURegNum & 0x7) << (Idx++ * 3); 632263508Sdim } 633263508Sdim 634263508Sdim assert((RegEnc & 0x3FFFF) == RegEnc && 635263508Sdim "Invalid compact register encoding!"); 636263508Sdim return RegEnc; 637263508Sdim } 638263508Sdim 639263508Sdim /// \brief Create the permutation encoding used with frameless stacks. It is 640263508Sdim /// passed the number of registers to be saved and an array of the registers 641263508Sdim /// saved. 642263508Sdim uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const { 643263508Sdim // The saved registers are numbered from 1 to 6. In order to encode the 644263508Sdim // order in which they were saved, we re-number them according to their 645263508Sdim // place in the register order. The re-numbering is relative to the last 646263508Sdim // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in 647263508Sdim // that order: 648263508Sdim // 649263508Sdim // Orig Re-Num 650263508Sdim // ---- ------ 651263508Sdim // 6 6 652263508Sdim // 2 2 653263508Sdim // 4 3 654263508Sdim // 5 3 655263508Sdim // 656263508Sdim for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) { 657263508Sdim int CUReg = getCompactUnwindRegNum(SavedRegs[i]); 658263508Sdim if (CUReg == -1) return ~0U; 659263508Sdim SavedRegs[i] = CUReg; 660263508Sdim } 661263508Sdim 662263508Sdim // Reverse the list. 663263508Sdim std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]); 664263508Sdim 665263508Sdim uint32_t RenumRegs[CU_NUM_SAVED_REGS]; 666263508Sdim for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){ 667263508Sdim unsigned Countless = 0; 668263508Sdim for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j) 669263508Sdim if (SavedRegs[j] < SavedRegs[i]) 670263508Sdim ++Countless; 671263508Sdim 672263508Sdim RenumRegs[i] = SavedRegs[i] - Countless - 1; 673263508Sdim } 674263508Sdim 675263508Sdim // Take the renumbered values and encode them into a 10-bit number. 676263508Sdim uint32_t permutationEncoding = 0; 677263508Sdim switch (RegCount) { 678263508Sdim case 6: 679263508Sdim permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1] 680263508Sdim + 6 * RenumRegs[2] + 2 * RenumRegs[3] 681263508Sdim + RenumRegs[4]; 682263508Sdim break; 683263508Sdim case 5: 684263508Sdim permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2] 685263508Sdim + 6 * RenumRegs[3] + 2 * RenumRegs[4] 686263508Sdim + RenumRegs[5]; 687263508Sdim break; 688263508Sdim case 4: 689263508Sdim permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3] 690263508Sdim + 3 * RenumRegs[4] + RenumRegs[5]; 691263508Sdim break; 692263508Sdim case 3: 693263508Sdim permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4] 694263508Sdim + RenumRegs[5]; 695263508Sdim break; 696263508Sdim case 2: 697263508Sdim permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5]; 698263508Sdim break; 699263508Sdim case 1: 700263508Sdim permutationEncoding |= RenumRegs[5]; 701263508Sdim break; 702263508Sdim } 703263508Sdim 704263508Sdim assert((permutationEncoding & 0x3FF) == permutationEncoding && 705263508Sdim "Invalid compact register encoding!"); 706263508Sdim return permutationEncoding; 707263508Sdim } 708263508Sdim 709226584Sdimpublic: 710263508Sdim DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef CPU, 711263508Sdim bool Is64Bit) 712263508Sdim : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) { 713263508Sdim memset(SavedRegs, 0, sizeof(SavedRegs)); 714263508Sdim OffsetSize = Is64Bit ? 8 : 4; 715263508Sdim MoveInstrSize = Is64Bit ? 3 : 2; 716263508Sdim StackDivide = Is64Bit ? 8 : 4; 717263508Sdim PushInstrSize = 1; 718263508Sdim } 719226584Sdim}; 720226584Sdim 721226584Sdimclass DarwinX86_32AsmBackend : public DarwinX86AsmBackend { 722263508Sdim bool SupportsCU; 723226584Sdimpublic: 724263508Sdim DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI, 725263508Sdim StringRef CPU, bool SupportsCU) 726263508Sdim : DarwinX86AsmBackend(T, MRI, CPU, false), SupportsCU(SupportsCU) {} 727226584Sdim 728226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 729226584Sdim return createX86MachObjectWriter(OS, /*Is64Bit=*/false, 730263508Sdim MachO::CPU_TYPE_I386, 731263508Sdim MachO::CPU_SUBTYPE_I386_ALL); 732226584Sdim } 733263508Sdim 734263508Sdim /// \brief Generate the compact unwind encoding for the CFI instructions. 735263508Sdim virtual uint32_t 736263508Sdim generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const { 737263508Sdim return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0; 738263508Sdim } 739226584Sdim}; 740226584Sdim 741226584Sdimclass DarwinX86_64AsmBackend : public DarwinX86AsmBackend { 742263508Sdim bool SupportsCU; 743263508Sdim const MachO::CPUSubTypeX86 Subtype; 744226584Sdimpublic: 745263508Sdim DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI, 746263508Sdim StringRef CPU, bool SupportsCU, 747263508Sdim MachO::CPUSubTypeX86 st) 748263508Sdim : DarwinX86AsmBackend(T, MRI, CPU, true), SupportsCU(SupportsCU), 749263508Sdim Subtype(st) { 750226584Sdim HasReliableSymbolDifference = true; 751226584Sdim } 752226584Sdim 753226584Sdim MCObjectWriter *createObjectWriter(raw_ostream &OS) const { 754226584Sdim return createX86MachObjectWriter(OS, /*Is64Bit=*/true, 755263508Sdim MachO::CPU_TYPE_X86_64, Subtype); 756226584Sdim } 757226584Sdim 758226584Sdim virtual bool doesSectionRequireSymbols(const MCSection &Section) const { 759226584Sdim // Temporary labels in the string literals sections require symbols. The 760226584Sdim // issue is that the x86_64 relocation format does not allow symbol + 761226584Sdim // offset, and so the linker does not have enough information to resolve the 762226584Sdim // access to the appropriate atom unless an external relocation is used. For 763226584Sdim // non-cstring sections, we expect the compiler to use a non-temporary label 764226584Sdim // for anything that could have an addend pointing outside the symbol. 765226584Sdim // 766226584Sdim // See <rdar://problem/4765733>. 767226584Sdim const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 768226584Sdim return SMO.getType() == MCSectionMachO::S_CSTRING_LITERALS; 769226584Sdim } 770226584Sdim 771226584Sdim virtual bool isSectionAtomizable(const MCSection &Section) const { 772226584Sdim const MCSectionMachO &SMO = static_cast<const MCSectionMachO&>(Section); 773226584Sdim // Fixed sized data sections are uniqued, they cannot be diced into atoms. 774226584Sdim switch (SMO.getType()) { 775226584Sdim default: 776226584Sdim return true; 777226584Sdim 778226584Sdim case MCSectionMachO::S_4BYTE_LITERALS: 779226584Sdim case MCSectionMachO::S_8BYTE_LITERALS: 780226584Sdim case MCSectionMachO::S_16BYTE_LITERALS: 781226584Sdim case MCSectionMachO::S_LITERAL_POINTERS: 782226584Sdim case MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS: 783226584Sdim case MCSectionMachO::S_LAZY_SYMBOL_POINTERS: 784226584Sdim case MCSectionMachO::S_MOD_INIT_FUNC_POINTERS: 785226584Sdim case MCSectionMachO::S_MOD_TERM_FUNC_POINTERS: 786226584Sdim case MCSectionMachO::S_INTERPOSING: 787226584Sdim return false; 788226584Sdim } 789226584Sdim } 790263508Sdim 791263508Sdim /// \brief Generate the compact unwind encoding for the CFI instructions. 792263508Sdim virtual uint32_t 793263508Sdim generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const { 794263508Sdim return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0; 795263508Sdim } 796226584Sdim}; 797226584Sdim 798226584Sdim} // end anonymous namespace 799226584Sdim 800263508SdimMCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, 801263508Sdim const MCRegisterInfo &MRI, 802263508Sdim StringRef TT, 803263508Sdim StringRef CPU) { 804226584Sdim Triple TheTriple(TT); 805226584Sdim 806226584Sdim if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) 807263508Sdim return new DarwinX86_32AsmBackend(T, MRI, CPU, 808263508Sdim TheTriple.isMacOSX() && 809263508Sdim !TheTriple.isMacOSXVersionLT(10, 7)); 810226584Sdim 811243830Sdim if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF) 812241430Sdim return new WindowsX86AsmBackend(T, false, CPU); 813226584Sdim 814234353Sdim uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 815241430Sdim return new ELFX86_32AsmBackend(T, OSABI, CPU); 816226584Sdim} 817226584Sdim 818263508SdimMCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, 819263508Sdim const MCRegisterInfo &MRI, 820263508Sdim StringRef TT, 821263508Sdim StringRef CPU) { 822226584Sdim Triple TheTriple(TT); 823226584Sdim 824263508Sdim if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) { 825263508Sdim MachO::CPUSubTypeX86 CS = 826263508Sdim StringSwitch<MachO::CPUSubTypeX86>(TheTriple.getArchName()) 827263508Sdim .Case("x86_64h", MachO::CPU_SUBTYPE_X86_64_H) 828263508Sdim .Default(MachO::CPU_SUBTYPE_X86_64_ALL); 829263508Sdim return new DarwinX86_64AsmBackend(T, MRI, CPU, 830263508Sdim TheTriple.isMacOSX() && 831263508Sdim !TheTriple.isMacOSXVersionLT(10, 7), CS); 832263508Sdim } 833226584Sdim 834243830Sdim if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF) 835241430Sdim return new WindowsX86AsmBackend(T, true, CPU); 836226584Sdim 837234353Sdim uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS()); 838241430Sdim return new ELFX86_64AsmBackend(T, OSABI, CPU); 839226584Sdim} 840