65 X86ELFObjectWriter(
bool is64Bit, uint8_t OSABI, uint16_t EMachine,
66 bool HasRelocationAddend,
bool foobar)
76 unsigned getNumFixupKinds()
const override {
86 {
"reloc_signed_4byte", 0, 32, 0},
87 {
"reloc_signed_4byte_relax", 0, 32, 0},
88 {
"reloc_global_offset_table", 0, 32, 0},
89 {
"reloc_global_offset_table8", 0, 64, 0},
104 uint64_t
Value,
bool IsResolved,
115 "Value does not fit in the Fixup field");
117 for (
unsigned i = 0; i !=
Size; ++i)
118 Data[Fixup.
getOffset() + i] = uint8_t(Value >> (i * 8));
121 bool mayNeedRelaxation(
const MCInst &Inst,
124 bool fixupNeedsRelaxation(
const MCFixup &Fixup, uint64_t Value,
129 MCInst &Res)
const override;
131 bool writeNopData(
raw_ostream &OS, uint64_t Count)
const override;
141 return (is16BitMode) ? X86::JAE_2 : X86::JAE_4;
143 return (is16BitMode) ? X86::JA_2 : X86::JA_4;
145 return (is16BitMode) ? X86::JBE_2 : X86::JBE_4;
147 return (is16BitMode) ? X86::JB_2 : X86::JB_4;
149 return (is16BitMode) ? X86::JE_2 : X86::JE_4;
151 return (is16BitMode) ? X86::JGE_2 : X86::JGE_4;
153 return (is16BitMode) ? X86::JG_2 : X86::JG_4;
155 return (is16BitMode) ? X86::JLE_2 : X86::JLE_4;
157 return (is16BitMode) ? X86::JL_2 : X86::JL_4;
159 return (is16BitMode) ? X86::JMP_2 : X86::JMP_4;
161 return (is16BitMode) ? X86::JNE_2 : X86::JNE_4;
163 return (is16BitMode) ? X86::JNO_2 : X86::JNO_4;
165 return (is16BitMode) ? X86::JNP_2 : X86::JNP_4;
167 return (is16BitMode) ? X86::JNS_2 : X86::JNS_4;
169 return (is16BitMode) ? X86::JO_2 : X86::JO_4;
171 return (is16BitMode) ? X86::JP_2 : X86::JP_4;
173 return (is16BitMode) ? X86::JS_2 : X86::JS_4;
184 case X86::IMUL16rri8:
return X86::IMUL16rri;
185 case X86::IMUL16rmi8:
return X86::IMUL16rmi;
186 case X86::IMUL32rri8:
return X86::IMUL32rri;
187 case X86::IMUL32rmi8:
return X86::IMUL32rmi;
188 case X86::IMUL64rri8:
return X86::IMUL64rri32;
189 case X86::IMUL64rmi8:
return X86::IMUL64rmi32;
192 case X86::AND16ri8:
return X86::AND16ri;
193 case X86::AND16mi8:
return X86::AND16mi;
194 case X86::AND32ri8:
return X86::AND32ri;
195 case X86::AND32mi8:
return X86::AND32mi;
196 case X86::AND64ri8:
return X86::AND64ri32;
197 case X86::AND64mi8:
return X86::AND64mi32;
200 case X86::OR16ri8:
return X86::OR16ri;
201 case X86::OR16mi8:
return X86::OR16mi;
202 case X86::OR32ri8:
return X86::OR32ri;
203 case X86::OR32mi8:
return X86::OR32mi;
204 case X86::OR64ri8:
return X86::OR64ri32;
205 case X86::OR64mi8:
return X86::OR64mi32;
208 case X86::XOR16ri8:
return X86::XOR16ri;
209 case X86::XOR16mi8:
return X86::XOR16mi;
210 case X86::XOR32ri8:
return X86::XOR32ri;
211 case X86::XOR32mi8:
return X86::XOR32mi;
212 case X86::XOR64ri8:
return X86::XOR64ri32;
213 case X86::XOR64mi8:
return X86::XOR64mi32;
216 case X86::ADD16ri8:
return X86::ADD16ri;
217 case X86::ADD16mi8:
return X86::ADD16mi;
218 case X86::ADD32ri8:
return X86::ADD32ri;
219 case X86::ADD32mi8:
return X86::ADD32mi;
220 case X86::ADD64ri8:
return X86::ADD64ri32;
221 case X86::ADD64mi8:
return X86::ADD64mi32;
224 case X86::ADC16ri8:
return X86::ADC16ri;
225 case X86::ADC16mi8:
return X86::ADC16mi;
226 case X86::ADC32ri8:
return X86::ADC32ri;
227 case X86::ADC32mi8:
return X86::ADC32mi;
228 case X86::ADC64ri8:
return X86::ADC64ri32;
229 case X86::ADC64mi8:
return X86::ADC64mi32;
232 case X86::SUB16ri8:
return X86::SUB16ri;
233 case X86::SUB16mi8:
return X86::SUB16mi;
234 case X86::SUB32ri8:
return X86::SUB32ri;
235 case X86::SUB32mi8:
return X86::SUB32mi;
236 case X86::SUB64ri8:
return X86::SUB64ri32;
237 case X86::SUB64mi8:
return X86::SUB64mi32;
240 case X86::SBB16ri8:
return X86::SBB16ri;
241 case X86::SBB16mi8:
return X86::SBB16mi;
242 case X86::SBB32ri8:
return X86::SBB32ri;
243 case X86::SBB32mi8:
return X86::SBB32mi;
244 case X86::SBB64ri8:
return X86::SBB64ri32;
245 case X86::SBB64mi8:
return X86::SBB64mi32;
248 case X86::CMP16ri8:
return X86::CMP16ri;
249 case X86::CMP16mi8:
return X86::CMP16mi;
250 case X86::CMP32ri8:
return X86::CMP32ri;
251 case X86::CMP32mi8:
return X86::CMP32mi;
252 case X86::CMP64ri8:
return X86::CMP64ri32;
253 case X86::CMP64mi8:
return X86::CMP64mi32;
256 case X86::PUSH32i8:
return X86::PUSHi32;
257 case X86::PUSH16i8:
return X86::PUSHi16;
258 case X86::PUSH64i8:
return X86::PUSH64i32;
269 bool X86AsmBackend::mayNeedRelaxation(
const MCInst &Inst,
289 bool X86AsmBackend::fixupNeedsRelaxation(
const MCFixup &
Fixup,
294 return int64_t(
Value) != int64_t(int8_t(
Value));
299 void X86AsmBackend::relaxInstruction(
const MCInst &Inst,
321 bool X86AsmBackend::writeNopData(
raw_ostream &OS, uint64_t Count)
const {
322 static const char Nops[10][11] = {
332 "\x0f\x1f\x44\x00\x00",
334 "\x66\x0f\x1f\x44\x00\x00",
336 "\x0f\x1f\x80\x00\x00\x00\x00",
338 "\x0f\x1f\x84\x00\x00\x00\x00\x00",
340 "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
342 "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
348 for (uint64_t i = 0; i < Count; ++i)
355 uint64_t MaxNopLength = 10;
366 const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength);
367 const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
368 for (uint8_t i = 0; i < Prefixes; i++)
370 const uint8_t Rest = ThisNopLength - Prefixes;
372 OS.
write(Nops[Rest - 1], Rest);
373 Count -= ThisNopLength;
374 }
while (Count != 0);
383 class ELFX86AsmBackend :
public X86AsmBackend {
387 : X86AsmBackend(T, STI), OSABI(OSABI) {}
390 class ELFX86_32AsmBackend :
public ELFX86AsmBackend {
392 ELFX86_32AsmBackend(
const Target &
T, uint8_t OSABI,
394 : ELFX86AsmBackend(T, OSABI, STI) {}
396 std::unique_ptr<MCObjectTargetWriter>
397 createObjectTargetWriter()
const override {
402 class ELFX86_X32AsmBackend :
public ELFX86AsmBackend {
404 ELFX86_X32AsmBackend(
const Target &
T, uint8_t OSABI,
406 : ELFX86AsmBackend(T, OSABI, STI) {}
408 std::unique_ptr<MCObjectTargetWriter>
409 createObjectTargetWriter()
const override {
415 class ELFX86_IAMCUAsmBackend :
public ELFX86AsmBackend {
417 ELFX86_IAMCUAsmBackend(
const Target &
T, uint8_t OSABI,
419 : ELFX86AsmBackend(T, OSABI, STI) {}
421 std::unique_ptr<MCObjectTargetWriter>
422 createObjectTargetWriter()
const override {
428 class ELFX86_64AsmBackend :
public ELFX86AsmBackend {
430 ELFX86_64AsmBackend(
const Target &
T, uint8_t OSABI,
432 : ELFX86AsmBackend(T, OSABI, STI) {}
434 std::unique_ptr<MCObjectTargetWriter>
435 createObjectTargetWriter()
const override {
440 class WindowsX86AsmBackend :
public X86AsmBackend {
446 : X86AsmBackend(T, STI)
458 std::unique_ptr<MCObjectTargetWriter>
459 createObjectTargetWriter()
const override {
470 UNWIND_MODE_BP_FRAME = 0x01000000,
473 UNWIND_MODE_STACK_IMMD = 0x02000000,
476 UNWIND_MODE_STACK_IND = 0x03000000,
479 UNWIND_MODE_DWARF = 0x04000000,
482 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
485 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
490 class DarwinX86AsmBackend :
public X86AsmBackend {
494 enum { CU_NUM_SAVED_REGS = 6 };
496 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
500 unsigned MoveInstrSize;
501 unsigned StackDivide;
504 unsigned PushInstrSize(
unsigned Reg)
const {
528 if (Instrs.
empty())
return 0;
531 unsigned SavedRegIdx = 0;
532 memset(SavedRegs, 0,
sizeof(SavedRegs));
539 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
540 unsigned InstrOffset = 0;
541 unsigned StackAdjust = 0;
542 unsigned StackSize = 0;
543 unsigned NumDefCFAOffsets = 0;
545 for (
unsigned i = 0, e = Instrs.
size(); i != e; ++i) {
565 (Is64Bit ? X86::RBP : X86::EBP))
569 memset(SavedRegs, 0,
sizeof(SavedRegs));
572 InstrOffset += MoveInstrSize;
607 if (SavedRegIdx == CU_NUM_SAVED_REGS)
610 return CU::UNWIND_MODE_DWARF;
613 SavedRegs[SavedRegIdx++] =
Reg;
614 StackAdjust += OffsetSize;
615 InstrOffset += PushInstrSize(Reg);
621 StackAdjust /= StackDivide;
624 if ((StackAdjust & 0xFF) != StackAdjust)
626 return CU::UNWIND_MODE_DWARF;
629 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
630 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
632 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
633 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
634 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
636 SubtractInstrIdx += InstrOffset;
639 if ((StackSize & 0xFF) == StackSize) {
641 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
644 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
646 if ((StackAdjust & 0x7) != StackAdjust)
648 return CU::UNWIND_MODE_DWARF;
651 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
655 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
658 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
663 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
667 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
668 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
671 CompactUnwindEncoding |=
672 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
675 return CompactUnwindEncoding;
681 int getCompactUnwindRegNum(
unsigned Reg)
const {
682 static const MCPhysReg CU32BitRegs[7] = {
686 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
688 const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
689 for (
int Idx = 1; *CURegs; ++CURegs, ++Idx)
698 uint32_t encodeCompactUnwindRegistersWithFrame()
const {
703 for (
int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
704 unsigned Reg = SavedRegs[i];
707 int CURegNum = getCompactUnwindRegNum(Reg);
708 if (CURegNum == -1)
return ~0U;
712 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
715 assert((RegEnc & 0x3FFFF) == RegEnc &&
716 "Invalid compact register encoding!");
723 uint32_t encodeCompactUnwindRegistersWithoutFrame(
unsigned RegCount)
const {
737 for (
unsigned i = 0; i < RegCount; ++i) {
738 int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
739 if (CUReg == -1)
return ~0U;
740 SavedRegs[i] = CUReg;
744 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
746 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
747 for (
unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
748 unsigned Countless = 0;
749 for (
unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
750 if (SavedRegs[j] < SavedRegs[i])
753 RenumRegs[i] = SavedRegs[i] - Countless - 1;
760 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
761 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
765 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
766 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
770 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
771 + 3 * RenumRegs[4] + RenumRegs[5];
774 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
778 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
781 permutationEncoding |= RenumRegs[5];
785 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
786 "Invalid compact register encoding!");
787 return permutationEncoding;
793 : X86AsmBackend(T, STI),
MRI(MRI), Is64Bit(Is64Bit) {
794 memset(SavedRegs, 0,
sizeof(SavedRegs));
795 OffsetSize = Is64Bit ? 8 : 4;
796 MoveInstrSize = Is64Bit ? 3 : 2;
797 StackDivide = Is64Bit ? 8 : 4;
801 class DarwinX86_32AsmBackend :
public DarwinX86AsmBackend {
805 : DarwinX86AsmBackend(T, MRI, STI,
false) {}
807 std::unique_ptr<MCObjectTargetWriter>
808 createObjectTargetWriter()
const override {
815 uint32_t generateCompactUnwindEncoding(
817 return generateCompactUnwindEncodingImpl(Instrs);
821 class DarwinX86_64AsmBackend :
public DarwinX86AsmBackend {
826 : DarwinX86AsmBackend(T, MRI, STI,
true), Subtype(st) {}
828 std::unique_ptr<MCObjectTargetWriter>
829 createObjectTargetWriter()
const override {
835 uint32_t generateCompactUnwindEncoding(
837 return generateCompactUnwindEncodingImpl(Instrs);
849 return new DarwinX86_32AsmBackend(T, MRI, STI);
852 return new WindowsX86AsmBackend(T,
false, STI);
857 return new ELFX86_IAMCUAsmBackend(T, OSABI, STI);
859 return new ELFX86_32AsmBackend(T, OSABI, STI);
872 return new DarwinX86_64AsmBackend(T, MRI, STI, CS);
876 return new WindowsX86AsmBackend(T,
true, STI);
881 return new ELFX86_X32AsmBackend(T, OSABI, STI);
882 return new ELFX86_64AsmBackend(T, OSABI, STI);
A eight-byte pc relative fixup.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
This represents an "assembler immediate".
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
std::unique_ptr< MCObjectTargetWriter > createX86MachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
Construct an X86 Mach-O object writer.
A raw_ostream that writes to an SmallVector or SmallString.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const Triple & getTargetTriple() const
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
A one-byte pc relative fixup.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
MCAsmBackend * createX86_32AsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
const FeatureBitset & getFeatureBits() const
Encapsulates the layout of an assembly file at a particular point in time.
MCAsmBackend * createX86_64AsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
A four-byte section relative fixup.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
A two-byte section relative fixup.
CompactUnwindEncodings
Compact unwind encoding values.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Instances of this class represent a single low-level machine instruction.
std::unique_ptr< MCObjectTargetWriter > createX86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine)
Construct an X86 ELF object writer.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
std::unique_ptr< MCObjectTargetWriter > createX86WinCOFFObjectWriter(bool Is64Bit)
Construct an X86 Win COFF object writer.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isOSWindows() const
Tests whether the OS is Windows.
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
A switch()-like statement whose cases are string literals.
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
size_t size() const
size - Get the array size.
static bool is64Bit(const char *name)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
OpType getOperation() const
unsigned getNumOperands() const
uint32_t getOffset() const
static unsigned getFixupKindLog2Size(unsigned Kind)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
static unsigned getRelaxedOpcodeArith(const MCInst &Inst)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
raw_ostream & write(unsigned char C)
PowerPC TLS Dynamic Call Fixup
unsigned getRegister() const
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
void setOpcode(unsigned Op)
A two-byte pc relative fixup.
A four-byte pc relative fixup.
const MCOperand & getOperand(unsigned i) const
virtual Optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
EnvironmentType getEnvironment() const
getEnvironment - Get the parsed environment type of this triple.
StringRef str()
Return a StringRef for the vector contents.
static unsigned getRelaxedOpcodeBranch(const MCInst &Inst, bool is16BitMode)
Target - Wrapper for Target specific information.
A one-byte section relative fixup.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
static unsigned getRelaxedOpcode(const MCInst &Inst, bool is16BitMode)
A eight-byte section relative fixup.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Generic base class for all target subtargets.
Target independent information on a fixup kind.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Generic interface to target specific assembler backends.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
unsigned getOpcode() const
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
MCFixupKind getKind() const
bool empty() const
empty - Check if the array is empty.