aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp78
1 files changed, 56 insertions, 22 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index 95012a148d83..83f3614ded1a 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -680,12 +680,21 @@ Optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const {
#define ELF_RELOC(X, Y) .Case(#X, Y)
#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
#undef ELF_RELOC
+ .Case("BFD_RELOC_NONE", ELF::R_X86_64_NONE)
+ .Case("BFD_RELOC_8", ELF::R_X86_64_8)
+ .Case("BFD_RELOC_16", ELF::R_X86_64_16)
+ .Case("BFD_RELOC_32", ELF::R_X86_64_32)
+ .Case("BFD_RELOC_64", ELF::R_X86_64_64)
.Default(-1u);
} else {
Type = llvm::StringSwitch<unsigned>(Name)
#define ELF_RELOC(X, Y) .Case(#X, Y)
#include "llvm/BinaryFormat/ELFRelocs/i386.def"
#undef ELF_RELOC
+ .Case("BFD_RELOC_NONE", ELF::R_386_NONE)
+ .Case("BFD_RELOC_8", ELF::R_386_8)
+ .Case("BFD_RELOC_16", ELF::R_386_16)
+ .Case("BFD_RELOC_32", ELF::R_386_32)
.Default(-1u);
}
if (Type == -1u)
@@ -1073,6 +1082,8 @@ void X86AsmBackend::finishLayout(MCAssembler const &Asm,
}
unsigned X86AsmBackend::getMaximumNopSize() const {
+ if (STI.hasFeature(X86::Mode16Bit))
+ return 4;
if (!STI.hasFeature(X86::FeatureNOPL) && !STI.hasFeature(X86::Mode64Bit))
return 1;
if (STI.getFeatureBits()[X86::FeatureFast7ByteNOP])
@@ -1091,29 +1102,44 @@ unsigned X86AsmBackend::getMaximumNopSize() const {
/// bytes.
/// \return - true on success, false on failure
bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
- static const char Nops[10][11] = {
- // nop
- "\x90",
- // xchg %ax,%ax
- "\x66\x90",
- // nopl (%[re]ax)
- "\x0f\x1f\x00",
- // nopl 0(%[re]ax)
- "\x0f\x1f\x40\x00",
- // nopl 0(%[re]ax,%[re]ax,1)
- "\x0f\x1f\x44\x00\x00",
- // nopw 0(%[re]ax,%[re]ax,1)
- "\x66\x0f\x1f\x44\x00\x00",
- // nopl 0L(%[re]ax)
- "\x0f\x1f\x80\x00\x00\x00\x00",
- // nopl 0L(%[re]ax,%[re]ax,1)
- "\x0f\x1f\x84\x00\x00\x00\x00\x00",
- // nopw 0L(%[re]ax,%[re]ax,1)
- "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
- // nopw %cs:0L(%[re]ax,%[re]ax,1)
- "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
+ static const char Nops32Bit[10][11] = {
+ // nop
+ "\x90",
+ // xchg %ax,%ax
+ "\x66\x90",
+ // nopl (%[re]ax)
+ "\x0f\x1f\x00",
+ // nopl 0(%[re]ax)
+ "\x0f\x1f\x40\x00",
+ // nopl 0(%[re]ax,%[re]ax,1)
+ "\x0f\x1f\x44\x00\x00",
+ // nopw 0(%[re]ax,%[re]ax,1)
+ "\x66\x0f\x1f\x44\x00\x00",
+ // nopl 0L(%[re]ax)
+ "\x0f\x1f\x80\x00\x00\x00\x00",
+ // nopl 0L(%[re]ax,%[re]ax,1)
+ "\x0f\x1f\x84\x00\x00\x00\x00\x00",
+ // nopw 0L(%[re]ax,%[re]ax,1)
+ "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
+ // nopw %cs:0L(%[re]ax,%[re]ax,1)
+ "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
+ };
+
+ // 16-bit mode uses different nop patterns than 32-bit.
+ static const char Nops16Bit[4][11] = {
+ // nop
+ "\x90",
+ // xchg %eax,%eax
+ "\x66\x90",
+ // lea 0(%si),%si
+ "\x8d\x74\x00",
+ // lea 0w(%si),%si
+ "\x8d\xb4\x00\x00",
};
+ const char(*Nops)[11] =
+ STI.getFeatureBits()[X86::Mode16Bit] ? Nops16Bit : Nops32Bit;
+
uint64_t MaxNopLength = (uint64_t)getMaximumNopSize();
// Emit as many MaxNopLength NOPs as needed, then emit a NOP of the remaining
@@ -1428,6 +1454,7 @@ public:
unsigned StackAdjust = 0;
unsigned StackSize = 0;
unsigned NumDefCFAOffsets = 0;
+ int MinAbsOffset = std::numeric_limits<int>::max();
for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
const MCCFIInstruction &Inst = Instrs[i];
@@ -1456,6 +1483,7 @@ public:
memset(SavedRegs, 0, sizeof(SavedRegs));
StackAdjust = 0;
SavedRegIdx = 0;
+ MinAbsOffset = std::numeric_limits<int>::max();
InstrOffset += MoveInstrSize;
break;
}
@@ -1499,6 +1527,7 @@ public:
unsigned Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true);
SavedRegs[SavedRegIdx++] = Reg;
StackAdjust += OffsetSize;
+ MinAbsOffset = std::min(MinAbsOffset, abs(Inst.getOffset()));
InstrOffset += PushInstrSize(Reg);
break;
}
@@ -1512,6 +1541,11 @@ public:
// Offset was too big for a compact unwind encoding.
return CU::UNWIND_MODE_DWARF;
+ // We don't attempt to track a real StackAdjust, so if the saved registers
+ // aren't adjacent to rbp we can't cope.
+ if (SavedRegIdx != 0 && MinAbsOffset != 3 * (int)OffsetSize)
+ return CU::UNWIND_MODE_DWARF;
+
// Get the encoding of the saved registers when we have a frame pointer.
uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
@@ -1597,7 +1631,7 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
- if (TheTriple.getEnvironment() == Triple::GNUX32)
+ if (TheTriple.isX32())
return new ELFX86_X32AsmBackend(T, OSABI, STI);
return new ELFX86_64AsmBackend(T, OSABI, STI);
}