[mips] Work around inconsistency in llvm-mc's placement of fixup markers
authorDaniel Sanders <daniel.sanders@imgtec.com>
Fri, 23 May 2014 13:35:24 +0000 (13:35 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Fri, 23 May 2014 13:35:24 +0000 (13:35 +0000)
Summary:
Add a second fixup table to MipsAsmBackend::getFixupKindInfo() to correctly
position llvm-mc's fixup placeholders for big-endian.

See PR19836 for full details of the issue. To summarize, the fixup placeholders
do not account for endianness properly and the implementations of
getFixupKindInfo() for each target are measuring MCFixupKindInfo.TargetOffset
from different ends of the instruction encoding to compensate.

Reviewers: jkolek, zoran.jovanovic, vmedic

Reviewed By: vmedic

Differential Revision: http://reviews.llvm.org/D3889

llvm-svn: 209514

llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
llvm/test/MC/Mips/llvm-mc-fixup-endianness.s [new file with mode: 0644]
llvm/test/MC/Mips/mips_directives.s
llvm/test/MC/Mips/mips_gprel16.s
llvm/test/MC/Mips/msa/test_cbranch.s

index 153974e..332f7ea 100644 (file)
@@ -189,7 +189,7 @@ void MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
 
 const MCFixupKindInfo &MipsAsmBackend::
 getFixupKindInfo(MCFixupKind Kind) const {
-  const static MCFixupKindInfo Infos[Mips::NumTargetFixupKinds] = {
+  const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = {
     // This table *must* be in same the order of fixup_* kinds in
     // MipsFixupKinds.h.
     //
@@ -246,12 +246,72 @@ getFixupKindInfo(MCFixupKind Kind) const {
     { "fixup_MICROMIPS_TLS_TPREL_LO16",  0,     16,   0 }
   };
 
+  const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = {
+    // This table *must* be in same the order of fixup_* kinds in
+    // MipsFixupKinds.h.
+    //
+    // name                    offset  bits  flags
+    { "fixup_Mips_16",          16,     16,   0 },
+    { "fixup_Mips_32",           0,     32,   0 },
+    { "fixup_Mips_REL32",        0,     32,   0 },
+    { "fixup_Mips_26",           6,     26,   0 },
+    { "fixup_Mips_HI16",        16,     16,   0 },
+    { "fixup_Mips_LO16",        16,     16,   0 },
+    { "fixup_Mips_GPREL16",     16,     16,   0 },
+    { "fixup_Mips_LITERAL",     16,     16,   0 },
+    { "fixup_Mips_GOT_Global",  16,     16,   0 },
+    { "fixup_Mips_GOT_Local",   16,     16,   0 },
+    { "fixup_Mips_PC16",        16,     16,  MCFixupKindInfo::FKF_IsPCRel },
+    { "fixup_Mips_CALL16",      16,     16,   0 },
+    { "fixup_Mips_GPREL32",      0,     32,   0 },
+    { "fixup_Mips_SHIFT5",      21,      5,   0 },
+    { "fixup_Mips_SHIFT6",      21,      5,   0 },
+    { "fixup_Mips_64",           0,     64,   0 },
+    { "fixup_Mips_TLSGD",       16,     16,   0 },
+    { "fixup_Mips_GOTTPREL",    16,     16,   0 },
+    { "fixup_Mips_TPREL_HI",    16,     16,   0 },
+    { "fixup_Mips_TPREL_LO",    16,     16,   0 },
+    { "fixup_Mips_TLSLDM",      16,     16,   0 },
+    { "fixup_Mips_DTPREL_HI",   16,     16,   0 },
+    { "fixup_Mips_DTPREL_LO",   16,     16,   0 },
+    { "fixup_Mips_Branch_PCRel",16,     16,  MCFixupKindInfo::FKF_IsPCRel },
+    { "fixup_Mips_GPOFF_HI",    16,     16,   0 },
+    { "fixup_Mips_GPOFF_LO",    16,     16,   0 },
+    { "fixup_Mips_GOT_PAGE",    16,     16,   0 },
+    { "fixup_Mips_GOT_OFST",    16,     16,   0 },
+    { "fixup_Mips_GOT_DISP",    16,     16,   0 },
+    { "fixup_Mips_HIGHER",      16,     16,   0 },
+    { "fixup_Mips_HIGHEST",     16,     16,   0 },
+    { "fixup_Mips_GOT_HI16",    16,     16,   0 },
+    { "fixup_Mips_GOT_LO16",    16,     16,   0 },
+    { "fixup_Mips_CALL_HI16",   16,     16,   0 },
+    { "fixup_Mips_CALL_LO16",   16,     16,   0 },
+    { "fixup_MICROMIPS_26_S1",   6,     26,   0 },
+    { "fixup_MICROMIPS_HI16",   16,     16,   0 },
+    { "fixup_MICROMIPS_LO16",   16,     16,   0 },
+    { "fixup_MICROMIPS_GOT16",  16,     16,   0 },
+    { "fixup_MICROMIPS_PC16_S1",16,     16,   MCFixupKindInfo::FKF_IsPCRel },
+    { "fixup_MICROMIPS_CALL16", 16,     16,   0 },
+    { "fixup_MICROMIPS_GOT_DISP",        16,     16,   0 },
+    { "fixup_MICROMIPS_GOT_PAGE",        16,     16,   0 },
+    { "fixup_MICROMIPS_GOT_OFST",        16,     16,   0 },
+    { "fixup_MICROMIPS_TLS_GD",          16,     16,   0 },
+    { "fixup_MICROMIPS_TLS_LDM",         16,     16,   0 },
+    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16,     16,   0 },
+    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16,     16,   0 },
+    { "fixup_MICROMIPS_TLS_TPREL_HI16",  16,     16,   0 },
+    { "fixup_MICROMIPS_TLS_TPREL_LO16",  16,     16,   0 }
+  };
+
   if (Kind < FirstTargetFixupKind)
     return MCAsmBackend::getFixupKindInfo(Kind);
 
   assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
           "Invalid kind!");
-  return Infos[Kind - FirstTargetFixupKind];
+
+  if (IsLittle)
+    return LittleEndianInfos[Kind - FirstTargetFixupKind];
+  return BigEndianInfos[Kind - FirstTargetFixupKind];
 }
 
 /// WriteNopData - Write an (optimal) nop sequence of Count bytes
diff --git a/llvm/test/MC/Mips/llvm-mc-fixup-endianness.s b/llvm/test/MC/Mips/llvm-mc-fixup-endianness.s
new file mode 100644 (file)
index 0000000..bc6a5d9
--- /dev/null
@@ -0,0 +1,6 @@
+# RUN: llvm-mc -show-encoding -mcpu=mips32 -triple mips-unknown-unknown %s | FileCheck -check-prefix=BE %s
+# RUN: llvm-mc -show-encoding -mcpu=mips32 -triple mipsel-unknown-unknown %s | FileCheck -check-prefix=LE %s
+#
+        .text
+        b foo # BE: b foo # encoding: [0x10,0x00,A,A]
+              # LE: b foo # encoding: [A,A,0x00,0x10]
index 6780dd0..1a7d61f 100644 (file)
@@ -51,7 +51,7 @@ $BB0_4:
     .set  $tmp7, $BB0_4-$BB0_2
     .set f6,$f6
 # CHECK:    abs.s   $f6, $f7           # encoding: [0x46,0x00,0x39,0x85]
-# CHECK:    lui     $1, %hi($tmp7)     # encoding: [0x3c'A',0x01'A',0x00,0x00]
+# CHECK:    lui     $1, %hi($tmp7)     # encoding: [0x3c,0x01,A,A]
 # CHECK:                               #   fixup A - offset: 0, value: ($tmp7)@ABS_HI, kind: fixup_Mips_HI16
     abs.s  f6,FPU_MASK
     lui $1, %hi($tmp7)
index 716c75e..9dd3fa3 100644 (file)
@@ -6,6 +6,9 @@
 // RUN: llvm-mc -mcpu=mips32r2 -triple=mipsel-pc-linux -filetype=obj -relocation-model=static %s -o - \
 // RUN: | llvm-objdump -disassemble -mattr +mips32r2 - \
 // RUN: | FileCheck %s
+// RUN: llvm-mc -mcpu=mips32r2 -triple=mips-pc-linux -filetype=obj -relocation-model=static %s -o - \
+// RUN: | llvm-objdump -disassemble -mattr +mips32r2 - \
+// RUN: | FileCheck %s
 
        .text
        .abicalls
index 37b8872..aa6779b 100644 (file)
@@ -7,22 +7,22 @@
 #CHECK:      bnz.w        $w2, 128      # encoding: [0x47,0xc2,0x00,0x20]
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
 #CHECK:      bnz.d        $w3, -128     # encoding: [0x47,0xe3,0xff,0xe0]
-#CHECK:      bnz.b        $w0, SYMBOL0  # encoding: [0x47'A',0x80'A',0x00,0x00]
+#CHECK:      bnz.b        $w0, SYMBOL0  # encoding: [0x47,0x80,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bnz.h        $w1, SYMBOL1  # encoding: [0x47'A',0xa1'A',0x00,0x00]
+#CHECK:      bnz.h        $w1, SYMBOL1  # encoding: [0x47,0xa1,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL1, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bnz.w        $w2, SYMBOL2  # encoding: [0x47'A',0xc2'A',0x00,0x00]
+#CHECK:      bnz.w        $w2, SYMBOL2  # encoding: [0x47,0xc2,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL2, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bnz.d        $w3, SYMBOL3  # encoding: [0x47'A',0xe3'A',0x00,0x00]
+#CHECK:      bnz.d        $w3, SYMBOL3  # encoding: [0x47,0xe3,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL3, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
 
 #CHECK:      bnz.v        $w0, 4        # encoding: [0x45,0xe0,0x00,0x01]
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bnz.v        $w0, SYMBOL0  # encoding: [0x45'A',0xe0'A',0x00,0x00]
+#CHECK:      bnz.v        $w0, SYMBOL0  # encoding: [0x45,0xe0,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
 
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
 #CHECK:      bz.d         $w3, -1024    # encoding: [0x47,0x63,0xff,0x00]
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bz.b         $w0, SYMBOL0  # encoding: [0x47'A',A,0x00,0x00]
+#CHECK:      bz.b         $w0, SYMBOL0  # encoding: [0x47,0x00,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bz.h         $w1, SYMBOL1  # encoding: [0x47'A',0x21'A',0x00,0x00]
+#CHECK:      bz.h         $w1, SYMBOL1  # encoding: [0x47,0x21,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL1, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bz.w         $w2, SYMBOL2  # encoding: [0x47'A',0x42'A',0x00,0x00]
+#CHECK:      bz.w         $w2, SYMBOL2  # encoding: [0x47,0x42,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL2, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bz.d         $w3, SYMBOL3  # encoding: [0x47'A',0x63'A',0x00,0x00]
+#CHECK:      bz.d         $w3, SYMBOL3  # encoding: [0x47,0x63,A,A]
                                         #   fixup A - offset: 0, value: SYMBOL3, kind: fixup_Mips_PC16
 #CHECK:      nop                        # encoding: [0x00,0x00,0x00,0x00]
 
 #CHECK:      bz.v        $w0, 4        # encoding: [0x45,0x60,0x00,0x01]
 #CHECK:      nop                       # encoding: [0x00,0x00,0x00,0x00]
-#CHECK:      bz.v        $w0, SYMBOL0  # encoding: [0x45'A',0x60'A',0x00,0x00]
+#CHECK:      bz.v        $w0, SYMBOL0  # encoding: [0x45,0x60,A,A]
                                        #   fixup A - offset: 0, value: SYMBOL0, kind: fixup_Mips_PC16
 #CHECK:      nop                       # encoding: [0x00,0x00,0x00,0x00]