[CSKY] Fix the adjustFixupValue of fixup_csky_pcrel_uimm7_scale4
authorZi Xuan Wu (Zeson) <zixuan.wu@linux.alibaba.com>
Mon, 31 Oct 2022 10:07:37 +0000 (18:07 +0800)
committerZi Xuan Wu <zixuan.wu@linux.alibaba.com>
Wed, 2 Nov 2022 06:18:35 +0000 (14:18 +0800)
The logic to calculate the offset of lrw16 is complex and the Value
before adjustFixupValue should in range of 0 <= (Value >> 2) <= 0xfe.

It also influences the relax condition.

llvm/lib/Target/CSKY/MCTargetDesc/CSKYAsmBackend.cpp
llvm/test/MC/CSKY/const-pool.s [new file with mode: 0644]

index b5dfdfa..4171a97 100644 (file)
@@ -150,24 +150,24 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
 
     return (Value >> 1) & 0x3ff;
   case CSKY::fixup_csky_pcrel_uimm7_scale4:
-    if (!isUIntN(9, Value))
+    if ((Value >> 2) > 0xfe)
       Ctx.reportError(Fixup.getLoc(), "out of range pc-relative fixup value.");
     if (Value & 0x3)
       Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned.");
 
-    if ((Value & 0xff) <= 0b111111100) {
+    if ((Value >> 2) <= 0x7f) {
       unsigned IMM5L = (Value >> 2) & 0x1f;
       unsigned IMM2H = (Value >> 7) & 0x3;
 
       Value = (1 << 12) | (IMM2H << 8) | IMM5L;
     } else {
-      unsigned IMM5L = (!Value >> 2) & 0x1f;
-      unsigned IMM2H = (!Value >> 7) & 0x3;
+      unsigned IMM5L = (~Value >> 2) & 0x1f;
+      unsigned IMM2H = (~Value >> 7) & 0x3;
 
       Value = (IMM2H << 8) | IMM5L;
     }
 
-    return Value & 0xffff;
+    return Value;
   }
 }
 
@@ -194,7 +194,7 @@ bool CSKYAsmBackend::fixupNeedsRelaxationAdvanced(const MCFixup &Fixup,
   case CSKY::fixup_csky_pcrel_imm26_scale2:
     return !isShiftedInt<26, 1>(Offset);
   case CSKY::fixup_csky_pcrel_uimm7_scale4:
-    return !isShiftedUInt<8, 2>(Offset);
+    return ((Value >> 2) > 0xfe) || (Value & 0x3);
   }
 }
 
diff --git a/llvm/test/MC/CSKY/const-pool.s b/llvm/test/MC/CSKY/const-pool.s
new file mode 100644 (file)
index 0000000..3225a91
--- /dev/null
@@ -0,0 +1,18 @@
+# RUN: llvm-mc -filetype=obj -triple=csky -mattr=+e2 -mattr=+high-registers < %s \
+# RUN:     | llvm-objdump --mattr=+e2  --no-show-raw-insn -M no-aliases -d -r - | FileCheck %s
+
+
+lrw a3, [.LCPI1_1]
+.zero 0x3ea
+.LCPI1_1:
+    .long   symA@GOTOFF
+
+lrw a3, [.LCPI1_2]
+.zero 0x3ec
+.LCPI1_2:
+    .long   symA@GOTOFF
+
+
+# CHECK:        0:             lrw16   r3, 0x3ec
+# CHECK:      3f0:              lrw32  r3, 0x7e0
+