[mips] Expand 'lw/sw' instructions for 32-bit GOT
authorSimon Atanasyan <simon@atanasyan.com>
Wed, 18 Sep 2019 19:19:47 +0000 (19:19 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Wed, 18 Sep 2019 19:19:47 +0000 (19:19 +0000)
In case of using 32-bit GOT access to the table requires two instructions
with attached %got_hi and %got_lo relocations. This patch implements
correct expansion of 'lw/sw' instructions in that case.

Differential Revision: https://reviews.llvm.org/D67705

llvm-svn: 372251

llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/test/MC/Mips/mips-expansions.s
llvm/test/MC/Mips/mips64-expansions.s

index a938740..8ab8bfe 100644 (file)
@@ -2871,7 +2871,6 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
                                             bool Is32BitSym, SMLoc IDLoc,
                                             MCStreamer &Out,
                                             const MCSubtargetInfo *STI) {
-  // FIXME: These expansions do not respect -mxgot.
   MipsTargetStreamer &TOut = getTargetStreamer();
   bool UseSrcReg = SrcReg != Mips::NoRegister && SrcReg != Mips::ZERO &&
                    SrcReg != Mips::ZERO_64;
@@ -2895,6 +2894,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
         (Res.getSymA()->getSymbol().isELF() &&
          cast<MCSymbolELF>(Res.getSymA()->getSymbol()).getBinding() ==
              ELF::STB_LOCAL);
+    bool UseXGOT = STI->getFeatureBits()[Mips::FeatureXGOT] && !IsLocalSym;
 
     // The case where the result register is $25 is somewhat special. If the
     // symbol in the final relocation is external and not modified with a
@@ -2902,10 +2902,69 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
     // or R_MIPS_CALL16 instead of R_MIPS_GOT_DISP in 64-bit case.
     if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
         Res.getConstant() == 0 && !IsLocalSym) {
-      const MCExpr *CallExpr =
-          MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
-      TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
-                   MCOperand::createExpr(CallExpr), IDLoc, STI);
+      if (UseXGOT) {
+        const MCExpr *CallHiExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_HI16,
+                                                      SymExpr, getContext());
+        const MCExpr *CallLoExpr = MipsMCExpr::create(MipsMCExpr::MEK_CALL_LO16,
+                                                      SymExpr, getContext());
+        TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(CallHiExpr), IDLoc,
+                    STI);
+        TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, DstReg, GPReg,
+                     IDLoc, STI);
+        TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, DstReg,
+                     MCOperand::createExpr(CallLoExpr), IDLoc, STI);
+      } else {
+        const MCExpr *CallExpr =
+            MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
+        TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, DstReg, GPReg,
+                     MCOperand::createExpr(CallExpr), IDLoc, STI);
+      }
+      return false;
+    }
+
+    unsigned TmpReg = DstReg;
+    if (UseSrcReg &&
+        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
+                                                               SrcReg)) {
+      // If $rs is the same as $rd, we need to use AT.
+      // If it is not available we exit.
+      unsigned ATReg = getATReg(IDLoc);
+      if (!ATReg)
+        return true;
+      TmpReg = ATReg;
+    }
+
+    if (UseXGOT) {
+      // Loading address from XGOT
+      //   External GOT: lui $tmp, %got_hi(symbol)($gp)
+      //                 addu $tmp, $tmp, $gp
+      //                 lw $tmp, %got_lo(symbol)($tmp)
+      //                >addiu $tmp, $tmp, offset
+      //                >addiu $rd, $tmp, $rs
+      // The addiu's marked with a '>' may be omitted if they are redundant. If
+      // this happens then the last instruction must use $rd as the result
+      // register.
+      const MCExpr *CallHiExpr =
+          MipsMCExpr::create(MipsMCExpr::MEK_GOT_HI16, SymExpr, getContext());
+      const MCExpr *CallLoExpr = MipsMCExpr::create(
+          MipsMCExpr::MEK_GOT_LO16, Res.getSymA(), getContext());
+
+      TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(CallHiExpr), IDLoc,
+                  STI);
+      TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, TmpReg, TmpReg, GPReg,
+                   IDLoc, STI);
+      TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, TmpReg,
+                   MCOperand::createExpr(CallLoExpr), IDLoc, STI);
+
+      if (Res.getConstant() != 0)
+        TOut.emitRRX(IsPtr64 ? Mips::DADDiu : Mips::ADDiu, TmpReg, TmpReg,
+                     MCOperand::createExpr(MCConstantExpr::create(
+                         Res.getConstant(), getContext())),
+                     IDLoc, STI);
+
+      if (UseSrcReg)
+        TOut.emitRRR(IsPtr64 ? Mips::DADDu : Mips::ADDu, DstReg, TmpReg, SrcReg,
+                     IDLoc, STI);
       return false;
     }
 
@@ -2961,18 +3020,6 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
       }
     }
 
-    unsigned TmpReg = DstReg;
-    if (UseSrcReg &&
-        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
-                                                               SrcReg)) {
-      // If $rs is the same as $rd, we need to use AT.
-      // If it is not available we exit.
-      unsigned ATReg = getATReg(IDLoc);
-      if (!ATReg)
-        return true;
-      TmpReg = ATReg;
-    }
-
     TOut.emitRRX(IsPtr64 ? Mips::LD : Mips::LW, TmpReg, GPReg,
                  MCOperand::createExpr(GotExpr), IDLoc, STI);
 
index b5a91cb..09b45c3 100644 (file)
@@ -1,5 +1,7 @@
-# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 \
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=-xgot \
 # RUN:            -show-encoding | FileCheck %s --check-prefixes=CHECK,CHECK-LE,GOT
+# RUN: llvm-mc %s -triple=mipsel-unknown-linux -mcpu=mips32r2 -mattr=+xgot \
+# RUN:            -show-encoding | FileCheck %s --check-prefixes=CHECK,CHECK-LE,XGOT
 # RUN: llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 \
 # RUN:            -show-encoding | FileCheck %s --check-prefixes=CHECK,CHECK-BE
 
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # GOT-NEXT: addu    $10, $10, $4            # encoding: [0x21,0x50,0x44,0x01]
 # GOT-NEXT: lw      $10, 0($10)             # encoding: [0x00,0x00,0x4a,0x8d]
+
+# XGOT:      lui    $10, %got_hi(symbol)     # encoding: [A,A,0x0a,0x3c]
+# XGOT-NEXT:                                 #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: addu   $10, $10, $gp            # encoding: [0x21,0x50,0x5c,0x01]
+# XGOT-NEXT: lw     $10, %got_lo(symbol)($10) # encoding: [A,A,0x4a,0x8d]
+# XGOT-NEXT:                                 #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: addu   $10, $10, $4             # encoding: [0x21,0x50,0x44,0x01]
+# XGOT-NEXT: lw     $10, 0($10)              # encoding: [0x00,0x00,0x4a,0x8d]
   .set at
   sw $10, symbol($9)
 # GOT:      lw      $1, %got(symbol)($gp)   # encoding: [A,A,0x81,0x8f]
 # GOT-NEXT: addu    $1, $1, $9              # encoding: [0x21,0x08,0x29,0x00]
 # GOT-NEXT: sw      $10, 0($1)              # encoding: [0x00,0x00,0x2a,0xac]
 
+# XGOT:      lui    $1, %got_hi(symbol)     # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: addu   $1, $1, $gp             # encoding: [0x21,0x08,0x3c,0x00]
+# XGOT-NEXT: lw     $1, %got_lo(symbol)($1) # encoding: [A,A,0x21,0x8c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: addu   $1, $1, $9              # encoding: [0x21,0x08,0x29,0x00]
+# XGOT-NEXT: sw     $10, 0($1)              # encoding: [0x00,0x00,0x2a,0xac]
+
   lw $8, 1f+8
 # GOT:      lw      $8, %got($tmp0)($gp)    # encoding: [A,A,0x88,0x8f]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
 # GOT-NEXT: addiu   $8, $8, %lo($tmp0)      # encoding: [A,A,0x08,0x25]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
 # GOT-NEXT: lw      $8, 8($8)               # encoding: [0x08,0x00,0x08,0x8d]
+
+# XGOT:      lw     $8, %got($tmp0)($gp)    # encoding: [A,A,0x88,0x8f]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
+# XGOT-NEXT: addiu  $8, $8, %lo($tmp0)      # encoding: [A,A,0x08,0x25]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
+# XGOT-NEXT: lw     $8, 8($8)               # encoding: [0x08,0x00,0x08,0x8d]
   sw $8, 1f+8
 # GOT:      lw      $1, %got($tmp0)($gp)    # encoding: [A,A,0x81,0x8f]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
 # GOT-NEXT: sw      $8, 8($1)               # encoding: [0x08,0x00,0x28,0xac]
 
+# XGOT:      lw     $1, %got($tmp0)($gp)    # encoding: [A,A,0x81,0x8f]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
+# XGOT-NEXT: addiu  $1, $1, %lo($tmp0)      # encoding: [A,A,0x21,0x24]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
+# XGOT-NEXT: sw     $8, 8($1)               # encoding: [0x08,0x00,0x28,0xac]
+
   lw $10, 655483($4)
 # GOT:      lui     $10, 10                 # encoding: [0x0a,0x00,0x0a,0x3c]
 # GOT-NEXT: addu    $10, $10, $4            # encoding: [0x21,0x50,0x44,0x01]
 # GOT-NEXT: lw      $10, 123($10)           # encoding: [0x7b,0x00,0x4a,0x8d]
+
+# XGOT:      lui    $10, 10                 # encoding: [0x0a,0x00,0x0a,0x3c]
+# XGOT-NEXT: addu   $10, $10, $4            # encoding: [0x21,0x50,0x44,0x01]
+# XGOT-NEXT: lw     $10, 123($10)           # encoding: [0x7b,0x00,0x4a,0x8d]
   sw $10, 123456($9)
 # GOT:      lui     $1, 2                   # encoding: [0x02,0x00,0x01,0x3c]
 # GOT-NEXT: addu    $1, $1, $9              # encoding: [0x21,0x08,0x29,0x00]
 # GOT-NEXT: sw      $10, -7616($1)          # encoding: [0x40,0xe2,0x2a,0xac]
 
+# XGOT:      lui    $1, 2                   # encoding: [0x02,0x00,0x01,0x3c]
+# XGOT-NEXT: addu   $1, $1, $9              # encoding: [0x21,0x08,0x29,0x00]
+# XGOT-NEXT: sw     $10, -7616($1)          # encoding: [0x40,0xe2,0x2a,0xac]
+
   lw $8, symbol+8
 # GOT:      lw      $8, %got(symbol)($gp)   # encoding: [A,A,0x88,0x8f]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # GOT-NEXT: lw      $8, 8($8)               # encoding: [0x08,0x00,0x08,0x8d]
+
+# XGOT:      lui    $8, %got_hi(symbol)     # encoding: [A,A,0x08,0x3c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: addu   $8, $8, $gp             # encoding: [0x21,0x40,0x1c,0x01]
+# XGOT-NEXT: lw     $8, %got_lo(symbol)($8) # encoding: [A,A,0x08,0x8d]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: lw     $8, 8($8)               # encoding: [0x08,0x00,0x08,0x8d]
   sw $8, symbol+8
 # GOT:      lw      $1, %got(symbol)($gp)   # encoding: [A,A,0x81,0x8f]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # GOT-NEXT: sw $8, 8($1)                    # encoding: [0x08,0x00,0x28,0xac]
 
+# XGOT:      lui    $1, %got_hi(symbol)     # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: addu   $1, $1, $gp             # encoding: [0x21,0x08,0x3c,0x00]
+# XGOT-NEXT: lw     $1, %got_lo(symbol)($1) # encoding: [A,A,0x21,0x8c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: sw     $8, 8($1)               # encoding: [0x08,0x00,0x28,0xac]
+
   ldc1 $f0, symbol
 # GOT:      lw      $1, %got(symbol)($gp)   # encoding: [A,A,0x81,0x8f]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # GOT-NEXT: ldc1    $f0, 0($1)              # encoding: [0x00,0x00,0x20,0xd4]
+
+# XGOT:      lui    $1, %got_hi(symbol)     # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: addu   $1, $1, $gp             # encoding: [0x21,0x08,0x3c,0x00]
+# XGOT-NEXT: lw     $1, %got_lo(symbol)($1) # encoding: [A,A,0x21,0x8c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: ldc1   $f0, 0($1)              # encoding: [0x00,0x00,0x20,0xd4]
   sdc1 $f0, symbol
 # GOT:      lw      $1, %got(symbol)($gp)   # encoding: [A,A,0x81,0x8f]
 # GOT-NEXT:                                 #   fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
 # GOT-NEXT: sdc1    $f0, 0($1)              # encoding: [0x00,0x00,0x20,0xf4]
+
+# XGOT:      lui    $1, %got_hi(symbol)     # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: addu   $1, $1, $gp             # encoding: [0x21,0x08,0x3c,0x00]
+# XGOT-NEXT: lw     $1, %got_lo(symbol)($1) # encoding: [A,A,0x21,0x8c]
+# XGOT-NEXT:                                #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: sdc1   $f0, 0($1)              # encoding: [0x00,0x00,0x20,0xf4]
   .option pic0
 
 # Test BNE with an immediate as the 2nd operand.
index 25ee898..c586c81 100644 (file)
@@ -1,5 +1,7 @@
-# RUN: llvm-mc %s -triple=mips64el-unknown-linux -mcpu=mips64r2 \
+# RUN: llvm-mc %s -triple=mips64el-unknown-linux -mcpu=mips64r2 -mattr=-xgot \
 # RUN:            -show-encoding | FileCheck --check-prefixes=CHECK,GOT %s
+# RUN: llvm-mc %s -triple=mips64el-unknown-linux -mcpu=mips64r2 -mattr=+xgot \
+# RUN:            -show-encoding | FileCheck --check-prefixes=CHECK,XGOT %s
 
 # Check that signed negative 32-bit immediates are loaded correctly:
   li $10, ~(0x101010)
@@ -475,44 +477,108 @@ sym:
 # GOT-NEXT:                                     #   fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: daddu   $10, $10, $4                # encoding: [0x2d,0x50,0x44,0x01]
 # GOT-NEXT: lw      $10, 0($10)                 # encoding: [0x00,0x00,0x4a,0x8d]
+
+# XGOT:      lui    $10, %got_hi(symbol)        # encoding: [A,A,0x0a,0x3c]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: daddu  $10, $10, $gp               # encoding: [0x2d,0x50,0x5c,0x01]
+# XGOT-NEXT: ld     $10, %got_lo(symbol)($10)   # encoding: [A,A,0x4a,0xdd]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: daddu  $10, $10, $4                # encoding: [0x2d,0x50,0x44,0x01]
+# XGOT-NEXT: lw     $10, 0($10)                 # encoding: [0x00,0x00,0x4a,0x8d]
+
   sw $10, symbol($9)
 # GOT:      ld      $1, %got_disp(symbol)($gp)  # encoding: [A,A,0x81,0xdf]
 # GOT-NEXT:                                     #   fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: daddu   $1, $1, $9                  # encoding: [0x2d,0x08,0x29,0x00]
 # GOT-NEXT: sw      $10, 0($1)                  # encoding: [0x00,0x00,0x2a,0xac]
 
+# XGOT:      lui    $1, %got_hi(symbol)         # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: daddu  $1, $1, $gp                 # encoding: [0x2d,0x08,0x3c,0x00]
+# XGOT-NEXT: ld     $1, %got_lo(symbol)($1)     # encoding: [A,A,0x21,0xdc]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: daddu  $1, $1, $9                  # encoding: [0x2d,0x08,0x29,0x00]
+# XGOT-NEXT: sw     $10, 0($1)                  # encoding: [0x00,0x00,0x2a,0xac]
+
   lw $8, sym+8
 # GOT:      ld      $8, %got_disp(sym)($gp)     # encoding: [A,A,0x88,0xdf]
 # GOT-NEXT:                                     #   fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: lw      $8, 8($8)                   # encoding: [0x08,0x00,0x08,0x8d]
+
+# XGOT:      ld     $8, %got_disp(sym)($gp)     # encoding: [A,A,0x88,0xdf]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
+# XGOT-NEXT: lw     $8, 8($8)                   # encoding: [0x08,0x00,0x08,0x8d]
+
   sw $8, sym+8
 # GOT:      ld      $1, %got_disp(sym)($gp)     # encoding: [A,A,0x81,0xdf]
 # GOT-NEXT:                                     #   fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: sw      $8, 8($1)                   # encoding: [0x08,0x00,0x28,0xac]
 
+# XGOT:      ld     $1, %got_disp(sym)($gp)     # encoding: [A,A,0x81,0xdf]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_disp(sym), kind: fixup_Mips_GOT_DISP
+# XGOT-NEXT: sw     $8, 8($1)                   # encoding: [0x08,0x00,0x28,0xac]
+
   lw $10, 655483($4)
 # GOT:      lui     $10, 10                     # encoding: [0x0a,0x00,0x0a,0x3c]
 # GOT-NEXT: daddu   $10, $10, $4                # encoding: [0x2d,0x50,0x44,0x01]
 # GOT-NEXT: lw      $10, 123($10)               # encoding: [0x7b,0x00,0x4a,0x8d]
+
+# XGOT:      lui    $10, 10                     # encoding: [0x0a,0x00,0x0a,0x3c]
+# XGOT-NEXT: daddu  $10, $10, $4                # encoding: [0x2d,0x50,0x44,0x01]
+# XGOT-NEXT: lw     $10, 123($10)               # encoding: [0x7b,0x00,0x4a,0x8d]
   sw $10, 123456($9)
 # GOT:      lui     $1, 2                       # encoding: [0x02,0x00,0x01,0x3c]
 # GOT-NEXT: daddu   $1, $1, $9                  # encoding: [0x2d,0x08,0x29,0x00]
 # GOT-NEXT: sw      $10, -7616($1)              # encoding: [0x40,0xe2,0x2a,0xac]
 
+# XGOT:      lui    $1, 2                       # encoding: [0x02,0x00,0x01,0x3c]
+# XGOT-NEXT: daddu  $1, $1, $9                  # encoding: [0x2d,0x08,0x29,0x00]
+# XGOT-NEXT: sw     $10, -7616($1)              # encoding: [0x40,0xe2,0x2a,0xac]
+
   lw $8, symbol+8
 # GOT:      ld      $8, %got_disp(symbol)($gp)  # encoding: [A,A,0x88,0xdf]
 # GOT-NEXT:                                     #   fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: lw      $8, 8($8)                   # encoding: [0x08,0x00,0x08,0x8d]
+
+# XGOT:      lui    $8, %got_hi(symbol)         # encoding: [A,A,0x08,0x3c]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: daddu  $8, $8, $gp                 # encoding: [0x2d,0x40,0x1c,0x01]
+# XGOT-NEXT: ld     $8, %got_lo(symbol)($8)     # encoding: [A,A,0x08,0xdd]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: lw     $8, 8($8)                   # encoding: [0x08,0x00,0x08,0x8d]
+
   sw $8, symbol+8
 # GOT:      ld      $1, %got_disp(symbol)($gp)  # encoding: [A,A,0x81,0xdf]
 # GOT-NEXT:                                     #   fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: sw $8, 8($1)                        # encoding: [0x08,0x00,0x28,0xac]
 
+# XGOT:      lui    $1, %got_hi(symbol)         # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: daddu  $1, $1, $gp                 # encoding: [0x2d,0x08,0x3c,0x00]
+# XGOT-NEXT: ld     $1, %got_lo(symbol)($1)     # encoding: [A,A,0x21,0xdc]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: sw     $8, 8($1)                   # encoding: [0x08,0x00,0x28,0xac]
+
   ldc1 $f0, symbol
 # GOT:      ld      $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
 # GOT-NEXT:                                    #   fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: ldc1    $f0, 0($1)                 # encoding: [0x00,0x00,0x20,0xd4]
+
+# XGOT:      lui    $1, %got_hi(symbol)         # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: daddu  $1, $1, $gp                 # encoding: [0x2d,0x08,0x3c,0x00]
+# XGOT-NEXT: ld     $1, %got_lo(symbol)($1)     # encoding: [A,A,0x21,0xdc]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: ldc1   $f0, 0($1)                  # encoding: [0x00,0x00,0x20,0xd4]
+
   sdc1 $f0, symbol
 # GOT:      ld      $1, %got_disp(symbol)($gp) # encoding: [A,A,0x81,0xdf]
 # GOT-NEXT:                                    #   fixup A - offset: 0, value: %got_disp(symbol), kind: fixup_Mips_GOT_DISP
 # GOT-NEXT: sdc1    $f0, 0($1)                 # encoding: [0x00,0x00,0x20,0xf4]
+
+# XGOT:      lui    $1, %got_hi(symbol)         # encoding: [A,A,0x01,0x3c]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_hi(symbol), kind: fixup_Mips_GOT_HI16
+# XGOT-NEXT: daddu  $1, $1, $gp                 # encoding: [0x2d,0x08,0x3c,0x00]
+# XGOT-NEXT: ld     $1, %got_lo(symbol)($1)     # encoding: [A,A,0x21,0xdc]
+# XGOT-NEXT:                                    #   fixup A - offset: 0, value: %got_lo(symbol), kind: fixup_Mips_GOT_LO16
+# XGOT-NEXT: sdc1   $f0, 0($1)                  # encoding: [0x00,0x00,0x20,0xf4]