[llvm] a65557d - [LoongArch] Fixup value adjustment in applyFixup

Weining Lu via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 15 06:01:10 PDT 2022


Author: wanglei
Date: 2022-09-15T21:00:22+08:00
New Revision: a65557d4b3b43bd06d443957cff2079f242f60f1

URL: https://github.com/llvm/llvm-project/commit/a65557d4b3b43bd06d443957cff2079f242f60f1
DIFF: https://github.com/llvm/llvm-project/commit/a65557d4b3b43bd06d443957cff2079f242f60f1.diff

LOG: [LoongArch] Fixup value adjustment in applyFixup

A complete implementation of `applyFixup` for D132323.

Makes `LoongArchAsmBackend::shouldForceRelocation` to determine
if the relocation types must be forced.

This patch also adds range and alignment checks for `b*` instructions'
operands, at which point the offset to a label is known.

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

Added: 
    llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s
    llvm/test/MC/LoongArch/Relocations/fixups-invalid.s
    llvm/test/MC/LoongArch/Relocations/fixups.s

Modified: 
    llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
    llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 6d9c93bedd7f0..4a5edd82ade86 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -11,10 +11,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "LoongArchAsmBackend.h"
+#include "LoongArchFixupKinds.h"
 #include "llvm/MC/MCAsmLayout.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/MC/MCValue.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/EndianStream.h"
 
@@ -75,6 +77,52 @@ LoongArchAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
   return Infos[Kind - FirstTargetFixupKind];
 }
 
+static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
+                                 MCContext &Ctx) {
+  switch (Fixup.getTargetKind()) {
+  default:
+    llvm_unreachable("Unknown fixup kind");
+  case FK_Data_1:
+  case FK_Data_2:
+  case FK_Data_4:
+  case FK_Data_8:
+    return Value;
+  case LoongArch::fixup_loongarch_b16: {
+    if (!isInt<18>(Value))
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+    if (Value % 4)
+      Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
+    return (Value >> 2) & 0xffff;
+  }
+  case LoongArch::fixup_loongarch_b21: {
+    if (!isInt<23>(Value))
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+    if (Value % 4)
+      Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
+    return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x1f);
+  }
+  case LoongArch::fixup_loongarch_b26: {
+    if (!isInt<28>(Value))
+      Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
+    if (Value % 4)
+      Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
+    return ((Value & 0x3fffc) << 8) | ((Value >> 18) & 0x3ff);
+  }
+  case LoongArch::fixup_loongarch_abs_hi20:
+  case LoongArch::fixup_loongarch_tls_le_hi20:
+    return (Value >> 12) & 0xfffff;
+  case LoongArch::fixup_loongarch_abs_lo12:
+  case LoongArch::fixup_loongarch_tls_le_lo12:
+    return Value & 0xfff;
+  case LoongArch::fixup_loongarch_abs64_lo20:
+  case LoongArch::fixup_loongarch_tls_le64_lo20:
+    return (Value >> 32) & 0xfffff;
+  case LoongArch::fixup_loongarch_abs64_hi12:
+  case LoongArch::fixup_loongarch_tls_le64_hi12:
+    return (Value >> 52) & 0xfff;
+  }
+}
+
 void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
                                      const MCFixup &Fixup,
                                      const MCValue &Target,
@@ -88,7 +136,10 @@ void LoongArchAsmBackend::applyFixup(const MCAssembler &Asm,
   if (Kind >= FirstLiteralRelocationKind)
     return;
   MCFixupKindInfo Info = getFixupKindInfo(Kind);
-  // TODO: Apply any target-specific value adjustments.
+  MCContext &Ctx = Asm.getContext();
+
+  // Apply any target-specific value adjustments.
+  Value = adjustFixupValue(Fixup, Value, Ctx);
 
   // Shift the value into position.
   Value <<= Info.TargetOffset;
@@ -109,9 +160,15 @@ bool LoongArchAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
                                                 const MCValue &Target) {
   if (Fixup.getKind() >= FirstLiteralRelocationKind)
     return true;
-  // TODO: Determine which relocation require special processing at linking
-  // time.
-  return false;
+  switch (Fixup.getTargetKind()) {
+  default:
+    return false;
+  case FK_Data_1:
+  case FK_Data_2:
+  case FK_Data_4:
+  case FK_Data_8:
+    return !Target.isAbsolute();
+  }
 }
 
 bool LoongArchAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,

diff  --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
index e44bcd715b696..5f3c1053537fc 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchMCCodeEmitter.cpp
@@ -263,6 +263,9 @@ LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
     case LoongArch::BCNEZ:
       FixupKind = LoongArch::fixup_loongarch_b21;
       break;
+    case LoongArch::B:
+      FixupKind = LoongArch::fixup_loongarch_b26;
+      break;
     }
   }
 

diff  --git a/llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s b/llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s
new file mode 100644
index 0000000000000..0fa389953cecf
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/fixups-diagnostics.s
@@ -0,0 +1,29 @@
+# RUN: not llvm-mc --triple=loongarch64 --filetype=obj %s -o /dev/null 2>&1 | FileCheck %s
+
+  beq $a0, $a1, far_distant # CHECK: :[[#@LINE]]:3: error: fixup value out of range
+  bne $a0, $a1, unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned
+
+  bnez $a0, unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned
+  beqz $a0, far_distant_bz # CHECK: :[[#@LINE]]:3: error: fixup value out of range
+
+  b unaligned # CHECK: :[[#@LINE]]:3: error: fixup value must be 4-byte aligned
+
+  .byte 0
+unaligned:
+  .byte 0
+  .byte 0
+  .byte 0
+
+  .space 1<<16
+distant:
+  .space 1<<18
+far_distant:
+
+  .byte 0
+unaligned_bz:
+  .byte 0
+  .byte 0
+  .byte 0
+distant_bz:
+  .space 1<<23
+far_distant_bz:

diff  --git a/llvm/test/MC/LoongArch/Relocations/fixups-invalid.s b/llvm/test/MC/LoongArch/Relocations/fixups-invalid.s
new file mode 100644
index 0000000000000..8251a71d74d71
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/fixups-invalid.s
@@ -0,0 +1,7 @@
+# RUN: not llvm-mc --filetype=obj %s --triple=loongarch32 -o /dev/null 2>&1 \
+# RUN:     | FileCheck %s
+# RUN: not llvm-mc --filetype=obj %s --triple=loongarch64 -o /dev/null 2>&1 \
+# RUN:     | FileCheck %s
+
+.byte foo   # CHECK: [[#@LINE]]:7: error: 1-byte data relocations not supported
+.2byte foo  # CHECK: [[#@LINE]]:8: error: 2-byte data relocations not supported

diff  --git a/llvm/test/MC/LoongArch/Relocations/fixups.s b/llvm/test/MC/LoongArch/Relocations/fixups.s
new file mode 100644
index 0000000000000..cdb38c09d4c0c
--- /dev/null
+++ b/llvm/test/MC/LoongArch/Relocations/fixups.s
@@ -0,0 +1,67 @@
+# RUN: llvm-mc --triple=loongarch64 %s --show-encoding \
+# RUN:     | FileCheck --check-prefix=CHECK-FIXUP %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \
+# RUN:     | llvm-objdump -d - | FileCheck --check-prefix=CHECK-INSTR %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s \
+# RUN:     | llvm-readobj -r - | FileCheck --check-prefix=CHECK-REL %s
+
+## Checks that fixups that can be resolved within the same object file are
+## applied correctly.
+
+.LBB0:
+lu12i.w $t1, %abs_hi20(val)
+# CHECK-FIXUP: fixup A - offset: 0, value: %abs_hi20(val), kind: fixup_loongarch_abs_hi20
+# CHECK-INSTR: lu12i.w $t1, 74565
+
+ori $t1, $t1, %abs_lo12(val)
+# CHECK-FIXUP: fixup A - offset: 0, value: %abs_lo12(val), kind: fixup_loongarch_abs_lo12
+# CHECK-INSTR: ori $t1, $t1, 1656
+
+b .LBB0
+# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b26
+# CHECK-INSTR: b -8
+b .LBB2
+# CHECK-FIXUP: fixup A - offset: 0, value: .LBB2, kind: fixup_loongarch_b26
+# CHECK-INSTR: b 331004
+beq $a0, $a1, .LBB0
+# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b16
+# CHECK-INSTR: beq $a0, $a1, -16
+blt $a0, $a1, .LBB1
+# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_loongarch_b16
+# CHECK-INSTR: blt $a0, $a1, 1116
+beqz $a0, .LBB0
+# CHECK-FIXUP: fixup A - offset: 0, value: .LBB0, kind: fixup_loongarch_b21
+# CHECK-INSTR: beqz $a0, -24
+bnez $a0, .LBB1
+# CHECK-FIXUP: fixup A - offset: 0, value: .LBB1, kind: fixup_loongarch_b21
+# CHECK-INSTR: bnez $a0, 1108
+
+.fill 1104
+
+.LBB1:
+
+.fill 329876
+nop
+.LBB2:
+
+.set val, 0x12345678
+
+# CHECK-REL-NOT: R_LARCH
+
+## Testing the function call offset could resolved by assembler
+## when the function and the callsite within the same compile unit.
+func:
+.fill 100
+bl func
+# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26
+# CHECK-INSTR: bl -100
+
+.fill 10000
+bl func
+# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26
+# CHECK-INSTR: bl -10104
+
+.fill 20888
+bl func
+# CHECK-FIXUP: fixup A - offset: 0, value: func, kind: fixup_loongarch_b26
+# CHECK-INSTR: bl -30996


        


More information about the llvm-commits mailing list