From aa7dd32bfad109b4933bfcb10b1d3e3f1f59a2b5 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 31 Jan 2017 18:28:44 +0000 Subject: [PATCH] MC: Introduce the ABS8 symbol modifier. @ABS8 can be applied to symbols which appear as immediate operands to instructions that have a 8-bit immediate form for that operand. It causes the assembler to use the 8-bit form and an 8-bit relocation (e.g. R_386_8 or R_X86_64_8) for the symbol. Differential Revision: https://reviews.llvm.org/D28688 llvm-svn: 293667 --- docs/Extensions.rst | 22 +++++++++++++++++++ include/llvm/MC/MCExpr.h | 2 ++ lib/MC/MCAssembler.cpp | 4 ++++ lib/MC/MCExpr.cpp | 2 ++ .../X86/MCTargetDesc/X86ELFObjectWriter.cpp | 2 ++ test/MC/X86/abs8.s | 8 +++++++ 6 files changed, 40 insertions(+) create mode 100644 test/MC/X86/abs8.s diff --git a/docs/Extensions.rst b/docs/Extensions.rst index 2b12123cdf6..56bb2793059 100644 --- a/docs/Extensions.rst +++ b/docs/Extensions.rst @@ -207,6 +207,28 @@ in the assembler to differentiate the sections. Target Specific Behaviour ========================= +X86 +--- + +Relocations +^^^^^^^^^^^ + +``@ABS8`` can be applied to symbols which appear as immediate operands to +instructions that have an 8-bit immediate form for that operand. It causes +the assembler to use the 8-bit form and an 8-bit relocation (e.g. ``R_386_8`` +or ``R_X86_64_8``) for the symbol. + +For example: + +.. code-block:: gas + + cmpq $foo@ABS8, %rdi + +This causes the assembler to select the form of the 64-bit ``cmpq`` instruction +that takes an 8-bit immediate operand that is sign extended to 64 bits, as +opposed to ``cmpq $foo, %rdi`` which takes a 32-bit immediate operand. This +is also not the same as ``cmpb $foo, %dil``, which is an 8-bit comparison. + Windows on ARM -------------- diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 50f4d7597de..8e40d268005 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -194,6 +194,8 @@ public: VK_SIZE, // symbol@SIZE VK_WEAKREF, // The link between the symbols in .weakref foo, bar + VK_X86_ABS8, + VK_ARM_NONE, VK_ARM_GOT_PREL, VK_ARM_TARGET1, diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 17a0edcc954..9019d11b611 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -747,6 +747,10 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, MCValue Target; uint64_t Value; bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value); + if (Target.getSymA() && + Target.getSymA()->getKind() == MCSymbolRefExpr::VK_X86_ABS8 && + Fixup.getKind() == FK_Data_1) + return false; return getBackend().fixupNeedsRelaxationAdvanced(Fixup, Resolved, Value, DF, Layout); } diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index f312b463d2e..17ab97f6768 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -208,6 +208,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { case VK_SECREL: return "SECREL32"; case VK_SIZE: return "SIZE"; case VK_WEAKREF: return "WEAKREF"; + case VK_X86_ABS8: return "ABS8"; case VK_ARM_NONE: return "none"; case VK_ARM_GOT_PREL: return "GOT_PREL"; case VK_ARM_TARGET1: return "target1"; @@ -317,6 +318,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) { .Case("imgrel", VK_COFF_IMGREL32) .Case("secrel32", VK_SECREL) .Case("size", VK_SIZE) + .Case("abs8", VK_X86_ABS8) .Case("l", VK_PPC_LO) .Case("h", VK_PPC_HI) .Case("ha", VK_PPC_HA) diff --git a/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp b/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp index da69da51df1..8958f35e85f 100644 --- a/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -96,6 +96,7 @@ static unsigned getRelocType64(MCContext &Ctx, SMLoc Loc, default: llvm_unreachable("Unimplemented"); case MCSymbolRefExpr::VK_None: + case MCSymbolRefExpr::VK_X86_ABS8: switch (Type) { case RT64_64: return IsPCRel ? ELF::R_X86_64_PC64 : ELF::R_X86_64_64; @@ -219,6 +220,7 @@ static unsigned getRelocType32(MCContext &Ctx, default: llvm_unreachable("Unimplemented"); case MCSymbolRefExpr::VK_None: + case MCSymbolRefExpr::VK_X86_ABS8: switch (Type) { case RT32_32: return IsPCRel ? ELF::R_386_PC32 : ELF::R_386_32; diff --git a/test/MC/X86/abs8.s b/test/MC/X86/abs8.s new file mode 100644 index 00000000000..1172fb08d4e --- /dev/null +++ b/test/MC/X86/abs8.s @@ -0,0 +1,8 @@ +// RUN: llvm-mc -filetype=obj %s -o - -triple i686-pc-linux | llvm-objdump -d -r - | FileCheck --check-prefix=32 %s +// RUN: llvm-mc -filetype=obj %s -o - -triple x86_64-pc-linux | llvm-objdump -d -r - | FileCheck --check-prefix=64 %s + +// 32: 0: 83 ff 00 cmpl $0, %edi +// 32: 00000002: R_386_8 foo +// 64: 0: 83 ff 00 cmpl $0, %edi +// 64: 0000000000000002: R_X86_64_8 foo+0 +cmp $foo@ABS8, %edi