[mips][ias] Expand on r238751 to cover as many relocs as possible.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Tue, 16 Jun 2015 13:46:26 +0000 (13:46 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Tue, 16 Jun 2015 13:46:26 +0000 (13:46 +0000)
Summary:
Relocs that can be converted from absolute to PC-relative now do so if IsPCRel
is true. Relocs that require PC-relative now call llvm_unreachable() if IsPCRel
is false and similarly those that require absolute assert that IsPCRel is false.

Note that while it looks like some relocs (e.g. R_MIPS_26) can be converted into
the MIPS32r6/MIPS64r6 relocs (R_MIPS_PC*_S2), it isn't actually valid to do so.

Placeholders have been left in the testcase for unsupported relocs and relocs
that cannot be generated at the moment.

Reviewers: vkalintiris

Reviewed By: vkalintiris

Subscribers: llvm-commits, rafael

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

llvm-svn: 239817

llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
llvm/test/MC/Mips/mips-relocations.s [deleted file]
llvm/test/MC/Mips/relocation.s

index 982a7f5..9b29527 100644 (file)
@@ -64,13 +64,47 @@ MipsELFObjectWriter::~MipsELFObjectWriter() {}
 unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
                                            const MCFixup &Fixup,
                                            bool IsPCRel) const {
-  // determine the type of the relocation
+  // Determine the type of the relocation.
   unsigned Kind = (unsigned)Fixup.getKind();
 
   switch (Kind) {
+  case Mips::fixup_Mips_16:
+  case FK_Data_2:
+    return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16;
   case Mips::fixup_Mips_32:
   case FK_Data_4:
     return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32;
+  }
+
+  if (IsPCRel) {
+    switch (Kind) {
+    case Mips::fixup_Mips_Branch_PCRel:
+    case Mips::fixup_Mips_PC16:
+      return ELF::R_MIPS_PC16;
+    case Mips::fixup_MICROMIPS_PC7_S1:
+      return ELF::R_MICROMIPS_PC7_S1;
+    case Mips::fixup_MICROMIPS_PC10_S1:
+      return ELF::R_MICROMIPS_PC10_S1;
+    case Mips::fixup_MICROMIPS_PC16_S1:
+      return ELF::R_MICROMIPS_PC16_S1;
+    case Mips::fixup_MIPS_PC19_S2:
+      return ELF::R_MIPS_PC19_S2;
+    case Mips::fixup_MIPS_PC18_S3:
+      return ELF::R_MIPS_PC18_S3;
+    case Mips::fixup_MIPS_PC21_S2:
+      return ELF::R_MIPS_PC21_S2;
+    case Mips::fixup_MIPS_PC26_S2:
+      return ELF::R_MIPS_PC26_S2;
+    case Mips::fixup_MIPS_PCHI16:
+      return ELF::R_MIPS_PCHI16;
+    case Mips::fixup_MIPS_PCLO16:
+      return ELF::R_MIPS_PCLO16;
+    }
+
+    llvm_unreachable("invalid PC-relative fixup kind!");
+  }
+
+  switch (Kind) {
   case Mips::fixup_Mips_64:
   case FK_Data_8:
     return ELF::R_MIPS_64;
@@ -110,9 +144,6 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
     return ELF::R_MIPS_TLS_DTPREL_HI16;
   case Mips::fixup_Mips_DTPREL_LO:
     return ELF::R_MIPS_TLS_DTPREL_LO16;
-  case Mips::fixup_Mips_Branch_PCRel:
-  case Mips::fixup_Mips_PC16:
-    return ELF::R_MIPS_PC16;
   case Mips::fixup_Mips_GOT_PAGE:
     return ELF::R_MIPS_GOT_PAGE;
   case Mips::fixup_Mips_GOT_OFST:
@@ -153,12 +184,6 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
     return ELF::R_MICROMIPS_LO16;
   case Mips::fixup_MICROMIPS_GOT16:
     return ELF::R_MICROMIPS_GOT16;
-  case Mips::fixup_MICROMIPS_PC7_S1:
-    return ELF::R_MICROMIPS_PC7_S1;
-  case Mips::fixup_MICROMIPS_PC10_S1:
-    return ELF::R_MICROMIPS_PC10_S1;
-  case Mips::fixup_MICROMIPS_PC16_S1:
-    return ELF::R_MICROMIPS_PC16_S1;
   case Mips::fixup_MICROMIPS_CALL16:
     return ELF::R_MICROMIPS_CALL16;
   case Mips::fixup_MICROMIPS_GOT_DISP:
@@ -179,19 +204,8 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
     return ELF::R_MICROMIPS_TLS_TPREL_HI16;
   case Mips::fixup_MICROMIPS_TLS_TPREL_LO16:
     return ELF::R_MICROMIPS_TLS_TPREL_LO16;
-  case Mips::fixup_MIPS_PC19_S2:
-    return ELF::R_MIPS_PC19_S2;
-  case Mips::fixup_MIPS_PC18_S3:
-    return ELF::R_MIPS_PC18_S3;
-  case Mips::fixup_MIPS_PC21_S2:
-    return ELF::R_MIPS_PC21_S2;
-  case Mips::fixup_MIPS_PC26_S2:
-    return ELF::R_MIPS_PC26_S2;
-  case Mips::fixup_MIPS_PCHI16:
-    return ELF::R_MIPS_PCHI16;
-  case Mips::fixup_MIPS_PCLO16:
-    return ELF::R_MIPS_PCLO16;
   }
+
   llvm_unreachable("invalid fixup kind!");
 }
 
diff --git a/llvm/test/MC/Mips/mips-relocations.s b/llvm/test/MC/Mips/mips-relocations.s
deleted file mode 100644 (file)
index 13cea2f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 | FileCheck %s
-# Check that the assembler can handle the documented syntax
-# for relocations.
-# CHECK:  lui   $2, %hi(_gp_disp)     # encoding: [A,A,0x02,0x3c]
-# CHECK:                              #   fixup A - offset: 0, value: _gp_disp@ABS_HI, kind: fixup_Mips_HI16
-# CHECK:  addiu $2, $2, %lo(_gp_disp) # encoding: [A,A,0x42,0x24]
-# CHECK:                              #   fixup A - offset: 0, value: _gp_disp@ABS_LO, kind: fixup_Mips_LO16
-# CHECK:  lw    $25, %call16(strchr)($gp)   # encoding: [A,A,0x99,0x8f]
-# CHECK:                                    #   fixup A - offset: 0, value: strchr@GOT_CALL, kind: fixup_Mips_CALL16
-# CHECK:  lw      $3, %got(loop_1)($2)    # encoding: [A,A,0x43,0x8c]
-# CHECK:                                  #   fixup A - offset: 0, value: loop_1@GOT, kind: fixup_Mips_GOT_Local
-# CHECK:  lui     $2, %dtprel_hi(_gp_disp) # encoding: [A,A,0x02,0x3c]
-# CHECK:                                        #   fixup A - offset: 0, value: _gp_disp@DTPREL_HI, kind: fixup_Mips_DTPREL_HI
-# CHECK:  addiu   $2, $2, %dtprel_lo(_gp_disp) # encoding: [A,A,0x42,0x24]
-# CHECK:                                  #   fixup A - offset: 0, value: _gp_disp@DTPREL_LO, kind: fixup_Mips_DTPREL_LO
-# CHECK:  lw      $3, %got(loop_1)($2)      # encoding: [A,A,0x43,0x8c]
-# CHECK:                                    #   fixup A - offset: 0, value: loop_1@GOT, kind: fixup_Mips_GOT_Local
-# CHECK:  lw      $4, %got_disp(loop_2)($3) # encoding: [A,A,0x64,0x8c]
-# CHECK:                                    #   fixup A - offset: 0, value: loop_2@GOT_DISP, kind: fixup_Mips_GOT_DISP
-# CHECK:  lw      $5, %got_page(loop_3)($4) # encoding: [A,A,0x85,0x8c]
-# CHECK:                                    #   fixup A - offset: 0, value: loop_3@GOT_PAGE, kind: fixup_Mips_GOT_PAGE
-# CHECK:  lw      $6, %got_ofst(loop_4)($5) # encoding: [A,A,0xa6,0x8c]
-# CHECK:                                    #   fixup A - offset: 0, value: loop_4@GOT_OFST, kind: fixup_Mips_GOT_OFST
-# CHECK:  lui     $2, %tprel_hi(_gp_disp)   # encoding: [A,A,0x02,0x3c]
-# CHECK:                                    #   fixup A - offset: 0, value: _gp_disp@TPREL_HI, kind: fixup_Mips_TPREL_HI
-# CHECK:  addiu   $2, $2, %tprel_lo(_gp_disp) # encoding: [A,A,0x42,0x24]
-# CHECK:                                      #   fixup A - offset: 0, value: _gp_disp@TPREL_LO, kind: fixup_Mips_TPREL_LO
-
-    lui $2, %hi(_gp_disp)
-    addiu $2, $2, %lo(_gp_disp)
-    lw $25, %call16(strchr)($gp)
-    lw      $3, %got(loop_1)($2)
-    lui $2, %dtprel_hi(_gp_disp)
-    addiu $2, $2, %dtprel_lo(_gp_disp)
-    lw $3, %got(loop_1)($2)
-    lw $4, %got_disp(loop_2)($3)
-    lw $5, %got_page(loop_3)($4)
-    lw $6, %got_ofst(loop_4)($5)
-    lui $2, %tprel_hi(_gp_disp)
-    addiu $2, $2, %tprel_lo(_gp_disp)
index 642b409..3a5f5a9 100644 (file)
-// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux < %s | llvm-readobj -r | FileCheck  %s
+// RUN: llvm-mc -triple mips-unknown-linux < %s -show-encoding \
+// RUN:     | FileCheck -check-prefix=ENCBE -check-prefix=FIXUP %s
+// RUN: llvm-mc -triple mipsel-unknown-linux < %s -show-encoding \
+// RUN:     | FileCheck -check-prefix=ENCLE -check-prefix=FIXUP %s
+// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux < %s \
+// RUN:     | llvm-readobj -r | FileCheck -check-prefix=RELOC %s
 
 // Test that we produce the correct relocation.
 // FIXME: move more relocation only tests here.
 
-        .long foo
-// CHECK: R_MIPS_32 foo
+// Check prefixes:
+// RELOC - Check the relocation in the object.
+// FIXUP - Check the fixup on the instruction.
+// ENCBE - Check the big-endian encoding on the instruction.
+// ENCLE - Check the little-endian encoding on the instruction.
+// ????? - Placeholder. Relocation is defined but the way of generating it is
+//         unknown.
+// FIXME - Placeholder. Generation method is known but doesn't work.
 
-        .long foo-.
-// CHECK: R_MIPS_PC32 foo
+        .short foo                         // RELOC: R_MIPS_16 foo
+
+        .long foo                          // RELOC: R_MIPS_32 foo
+
+                                           // ?????: R_MIPS_REL32 foo
+
+        jal foo                            // RELOC: R_MIPS_26 foo
+                                           // ENCBE: jal foo # encoding: [0b000011AA,A,A,A]
+                                           // ENCLE: jal foo # encoding: [A,A,A,0b000011AA]
+                                           // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_Mips_26
+
+        addiu $2, $3, %hi(foo)             // RELOC: R_MIPS_HI16 foo
+                                           // ENCBE: addiu $2, $3, %hi(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %hi(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@ABS_HI, kind: fixup_Mips_HI16
+
+        addiu $2, $3, %lo(foo)             // RELOC: R_MIPS_LO16 foo
+                                           // ENCBE: addiu $2, $3, %lo(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %lo(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@ABS_LO, kind: fixup_Mips_LO16
+
+        addiu $2, $3, %gp_rel(foo)         // RELOC: R_MIPS_GPREL16 foo
+                                           // ENCBE: addiu $2, $3, %gp_rel(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %gp_rel(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GPREL, kind: fixup_Mips_GPREL
+
+                                           // ?????: R_MIPS_LITERAL foo
+
+        addiu $2, $3, %got(foo)            // RELOC: R_MIPS_GOT16 foo
+                                           // ENCBE: addiu $2, $3, %got(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT, kind: fixup_Mips_GOT_Local
+
+        .short foo-.                       // RELOC: R_MIPS_PC16 foo
+
+        addiu $2, $3, %call16(foo)         // RELOC: R_MIPS_CALL16 foo
+                                           // ENCBE: addiu $2, $3, %call16(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %call16(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT_CALL, kind: fixup_Mips_CALL16
+
+        .quad foo                          // RELOC: R_MIPS_64 foo
+
+                                           // ?????: R_MIPS_GPREL32 foo
+                                           // ?????: R_MIPS_UNUSED1 foo
+                                           // ?????: R_MIPS_UNUSED2 foo
+                                           // ?????: R_MIPS_UNUSED3 foo
+                                           // ?????: R_MIPS_SHIFT5 foo
+                                           // ?????: R_MIPS_SHIFT6 foo
+
+        addiu $2, $3, %got_disp(foo)       // RELOC: R_MIPS_GOT_DISP foo
+                                           // ENCBE: addiu $2, $3, %got_disp(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got_disp(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT_DISP, kind: fixup_Mips_GOT_DISP
+
+        addiu $2, $3, %got_page(foo)       // RELOC: R_MIPS_GOT_PAGE foo
+                                           // ENCBE: addiu $2, $3, %got_page(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got_page(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT_PAGE, kind: fixup_Mips_GOT_PAGE
+
+        addiu $2, $3, %got_ofst(foo)       // RELOC: R_MIPS_GOT_OFST foo
+                                           // ENCBE: addiu $2, $3, %got_ofst(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got_ofst(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT_OFST, kind: fixup_Mips_GOT_OFST
+
+        addiu $2, $3, %got_hi(foo)         // RELOC: R_MIPS_GOT_HI16 foo
+                                           // ENCBE: addiu $2, $3, %got_hi(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got_hi(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT_HI16, kind: fixup_Mips_GOT_HI16
+
+        addiu $2, $3, %got_lo(foo)         // RELOC: R_MIPS_GOT_LO16 foo
+                                           // ENCBE: addiu $2, $3, %got_lo(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got_lo(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOT_LO16, kind: fixup_Mips_GOT_LO16
+
+//      addiu $2, $3, %neg(foo)            // FIXME: R_MIPS_SUB foo
+                                           // ?????: R_MIPS_INSERT_A
+                                           // ?????: R_MIPS_INSERT_B
+                                           // ?????: R_MIPS_DELETE
+
+        .set mips64
+        daddiu $2, $3, %higher(foo)        // RELOC: R_MIPS_HIGHER foo
+                                           // ENCBE: daddiu $2, $3, %higher(foo) # encoding: [0x64,0x62,A,A]
+                                           // ENCLE: daddiu $2, $3, %higher(foo) # encoding: [A,A,0x62,0x64]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@HIGHER, kind: fixup_Mips_HIGHER
+
+        daddiu $2, $3, %highest(foo)       // RELOC: R_MIPS_HIGHEST foo
+                                           // ENCBE: daddiu $2, $3, %highest(foo) # encoding: [0x64,0x62,A,A]
+                                           // ENCLE: daddiu $2, $3, %highest(foo) # encoding: [A,A,0x62,0x64]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@HIGHEST, kind: fixup_Mips_HIGHEST
+
+        .set mips0
+        addiu $2, $3, %call_hi(foo)        // RELOC: R_MIPS_CALL_HI16 foo
+                                           // ENCBE: addiu $2, $3, %call_hi(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %call_hi(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@CALL_HI16, kind: fixup_Mips_CALL_HI16
+
+        addiu $2, $3, %call_lo(foo)        // RELOC: R_MIPS_CALL_LO16 foo
+                                           // ENCBE: addiu $2, $3, %call_lo(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %call_lo(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@CALL_LO16, kind: fixup_Mips_CALL_LO16
+
+                                           // ?????: R_MIPS_SCN_DISP foo
+                                           // ?????: R_MIPS_REL16 foo
+                                           // ?????: R_MIPS_ADD_IMMEDIATE foo
+                                           // ?????: R_MIPS_PJUMP foo
+                                           // ?????: R_MIPS_RELGOT foo
+//      jalr $25                           // ?????: R_MIPS_JALR foo
+
+                                           // ?????: R_MIPS_TLS_DTPMOD32 foo
+//      .dtprelword foo                    // FIXME: R_MIPS_TLS_DTPREL32 foo
+                                           // ?????: R_MIPS_TLS_DTPMOD64 foo
+//      .dtpreldword foo                   // FIXME: R_MIPS_TLS_DTPREL64 foo
+        addiu $2, $3, %tlsgd(foo)          // RELOC: R_MIPS_TLS_GD foo
+                                           // ENCBE: addiu $2, $3, %tlsgd(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %tlsgd(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@TLSGD, kind: fixup_Mips_TLSGD
+
+        addiu $2, $3, %tlsldm(foo)         // RELOC: R_MIPS_TLS_LDM foo
+                                           // ENCBE: addiu $2, $3, %tlsldm(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %tlsldm(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@TLSLDM, kind: fixup_Mips_TLSLDM
+
+        addiu $2, $3, %dtprel_hi(foo)      // RELOC: R_MIPS_TLS_DTPREL_HI16 foo
+                                           // ENCBE: addiu $2, $3, %dtprel_hi(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %dtprel_hi(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@DTPREL_HI, kind: fixup_Mips_DTPREL_HI
+
+        addiu $2, $3, %dtprel_lo(foo)      // RELOC: R_MIPS_TLS_DTPREL_LO16 foo
+                                           // ENCBE: addiu $2, $3, %dtprel_lo(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %dtprel_lo(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@DTPREL_LO, kind: fixup_Mips_DTPREL_LO
+
+        addiu $2, $3, %gottprel(foo)       // RELOC: R_MIPS_TLS_GOTTPREL foo
+                                           // ENCBE: addiu $2, $3, %gottprel(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %gottprel(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@GOTTPREL, kind: fixup_Mips_GOTTPREL
+
+//      .tprelword foo                     // FIXME: R_MIPS_TLS_TPREL32 foo
+//      .tpreldword foo                    // FIXME: R_MIPS_TLS_TPREL64 foo
+        addiu $2, $3, %tprel_hi(foo)       // RELOC: R_MIPS_TLS_TPREL_HI16 foo
+                                           // ENCBE: addiu $2, $3, %tprel_hi(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %tprel_hi(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@TPREL_HI, kind: fixup_Mips_TPREL_HI
+
+        addiu $2, $3, %tprel_lo(foo)       // RELOC: R_MIPS_TLS_TPREL_LO16 foo
+                                           // ENCBE: addiu $2, $3, %tprel_lo(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %tprel_lo(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@TPREL_LO, kind: fixup_Mips_TPREL_LO
+
+                                           // ?????: R_MIPS_GLOB_DAT foo
+        .set mips32r6
+        beqzc $2, foo                      // RELOC: R_MIPS_PC21_S2 foo
+                                           // ENCBE: beqzc $2, foo # encoding: [0xd8,0b010AAAAA,A,A]
+                                           // ENCLE: beqzc $2, foo # encoding: [A,A,0b010AAAAA,0xd8]
+                                           // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_MIPS_PC21_S2
+
+        bc foo                             // RELOC: R_MIPS_PC26_S2 foo
+                                           // ENCBE: bc foo # encoding: [0b110010AA,A,A,A]
+                                           // ENCLE: bc foo # encoding: [A,A,A,0b110010AA]
+                                           // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_MIPS_PC26_S2
+
+        .set mips64r6
+        ldpc $2, foo                       // RELOC: R_MIPS_PC18_S3 foo
+                                           // ENCBE: ldpc $2, foo # encoding: [0xec,0b010110AA,A,A]
+                                           // ENCLE: ldpc $2, foo # encoding: [A,A,0b010110AA,0xec]
+                                           // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_Mips_PC18_S3
+
+        .set mips32r6
+        lwpc $2, foo                       // RELOC: R_MIPS_PC19_S2 foo
+                                           // ENCBE: lwpc $2, foo # encoding: [0xec,0b01001AAA,A,A]
+                                           // ENCLE: lwpc $2, foo # encoding: [A,A,0b01001AAA,0xec]
+                                           // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_MIPS_PC19_S2
+
+        addiu $2, $3, %pcrel_hi(foo)       // RELOC: R_MIPS_PCHI16 foo
+                                           // ENCBE: addiu $2, $3, %pcrel_hi(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %pcrel_hi(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@PCREL_HI16, kind: fixup_MIPS_PCHI16
+
+        addiu $2, $3, %pcrel_lo(foo)       // RELOC: R_MIPS_PCLO16 foo
+                                           // ENCBE: addiu $2, $3, %pcrel_lo(foo) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %pcrel_lo(foo) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: foo@PCREL_LO16, kind: fixup_MIPS_PCLO16
+
+        .set mips0
+                                           // FIXME: R_MIPS16_*
+                                           // ?????: R_MIPS_COPY foo
+                                           // ?????: R_MIPS_JUMP_SLOT foo
+                                           // FIXME: R_MICROMIPS_*
+        .long foo-.                        // RELOC: R_MIPS_PC32 foo
+//      .ehword foo                        // FIXME: R_MIPS_EH foo