]> granicus.if.org Git - llvm/commitdiff
MC: Introduce the ABS8 symbol modifier.
authorPeter Collingbourne <peter@pcc.me.uk>
Tue, 31 Jan 2017 18:28:44 +0000 (18:28 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Tue, 31 Jan 2017 18:28:44 +0000 (18:28 +0000)
@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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293667 91177308-0d34-0410-b5e6-96231b3b80d8

docs/Extensions.rst
include/llvm/MC/MCExpr.h
lib/MC/MCAssembler.cpp
lib/MC/MCExpr.cpp
lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp
test/MC/X86/abs8.s [new file with mode: 0644]

index 2b12123cdf6889ba18e0e5a976490281d65b7abc..56bb279305963a0acfd7c7b99c7ec2e59425030b 100644 (file)
@@ -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
 --------------
 
index 50f4d7597dea3cfdad31f04ae9e8625c36f6dae3..8e40d268005aa74f8d5dbde32714d5df9926af55 100644 (file)
@@ -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,
index 17a0edcc95450a4f5551aed5c5e00bb7db844995..9019d11b611f5bc4af8a87ccb6e3ba3045ceff93 100644 (file)
@@ -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);
 }
index f312b463d2efdca10242ac7c232150a14c605e91..17ab97f67687d03cba9214b0da98ea8cc29fe753 100644 (file)
@@ -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)
index da69da51df1085df93ff28a1f63a329bcae24d5a..8958f35e85f298f66a4974fef9e427d98686ceda 100644 (file)
@@ -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 (file)
index 0000000..1172fb0
--- /dev/null
@@ -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