Skip to content

[Mips] Allow expressions in some immediate operands #127581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

MaskRay
Copy link
Member

@MaskRay MaskRay commented Feb 18, 2025

e.g.
addiu $t2, $t3, .Lend-.Lstart-4
used by libdragon/boot/boot_trampoline.S

To make this work, update a few places:

  • AsmParser: When matching a isSImm/isUImm, consider an expression
    that does not evaluate to an assemble-time constant an immediate.
  • MCCodeEmitter: If this is an I-type instruction and the expression
    does not evaluate to an assemble-time constant, append a
    fixup_Mips_AnyImm16.
    TODO: in MipsInstrInfo.td, more Operand should switch from the
    default getMachineOpValue to getImmOpValue like RISCV.
  • AsmBackend: If the expression does not evaluate to a constant
    with assembler layout information, report "unknown relocation type"
    like X86. If the result is not within [-32768,65535] (the bound gas
    uses when parsing a constant integer for ADDIU)

Fix #126531

Created using spr 1.3.5-bogner
@llvmbot llvmbot added the mc Machine (object) code label Feb 18, 2025
@MaskRay MaskRay requested review from wzssyqa and brad0 February 18, 2025 07:03
@llvmbot
Copy link
Member

llvmbot commented Feb 18, 2025

@llvm/pr-subscribers-mc

Author: Fangrui Song (MaskRay)

Changes

e.g.
addiu $t2, $t3, .Lend-.Lstart-4
used by libdragon/boot/boot_trampoline.S

To make this work, update a few places:

  • AsmParser: When matching a isSImm/isUImm, consider an expression
    that does not evaluate to an assemble-time constant an immediate.
  • MCCodeEmitter: If this is an I-type instruction and the expression
    does not evaluate to an assemble-time constant, append a
    fixup_Mips_AnyImm16.
    TODO: in MipsInstrInfo.td, more Operand should switch from the
    default getMachineOpValue to getImmOpValue like RISCV.
  • AsmBackend: If the expression does not evaluate to a constant
    with assembler layout information, report "unknown relocation type"
    like X86. If the result is not within [-32768,65535] (the bound gas
    uses when parsing a constant integer for ADDIU)

Fix #126531


Full diff: https://github.com/llvm/llvm-project/pull/127581.diff

10 Files Affected:

  • (modified) llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (+12-2)
  • (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp (+19-10)
  • (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h (+14-8)
  • (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp (+2-1)
  • (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h (+13-8)
  • (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (+24-20)
  • (modified) llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h (+3)
  • (added) llvm/test/MC/Mips/fixup-expr.s (+37)
  • (added) llvm/test/MC/Mips/fixup-out-of-range.s (+13)
  • (modified) llvm/test/MC/Mips/imm-operand-err.s (+4-6)
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 8c328d5ed7234..82fff1dad697f 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -1311,11 +1311,21 @@ class MipsOperand : public MCParsedAsmOperand {
   }
 
   template <unsigned Bits> bool isSImm() const {
-    return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
+    if (!isImm())
+      return false;
+    int64_t Res;
+    if (getImm()->evaluateAsAbsolute(Res))
+      return isInt<Bits>(Res);
+    return true;
   }
 
   template <unsigned Bits> bool isUImm() const {
-    return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
+    if (!isImm())
+      return false;
+    int64_t Res;
+    if (getImm()->evaluateAsAbsolute(Res))
+      return isUInt<Bits>(Res);
+    return true;
   }
 
   template <unsigned Bits> bool isAnyImm() const {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index 4af6768b13cc9..49df6a5e7fca6 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -60,6 +60,11 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
   case Mips::fixup_MIPS_PCLO16:
     Value &= 0xffff;
     break;
+  case Mips::fixup_Mips_AnyImm16:
+    if (!isInt<16>(Value) && !isUInt<16>(Value))
+      Ctx.reportError(Fixup.getLoc(),
+                      "fixup value out of range [-32768, 65535]");
+    break;
   case FK_DTPRel_4:
   case FK_DTPRel_8:
   case FK_TPRel_4:
@@ -351,16 +356,18 @@ std::optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
 const MCFixupKindInfo &MipsAsmBackend::
 getFixupKindInfo(MCFixupKind Kind) const {
   const static MCFixupKindInfo LittleEndianInfos[] = {
-    // This table *must* be in same the order of fixup_* kinds in
-    // MipsFixupKinds.h.
-    //
-    // name                    offset  bits  flags
+      // This table *must* be in same the order of fixup_* kinds in
+      // MipsFixupKinds.h.
+      //
+      // name                    offset  bits  flags
+      // clang-format off
     { "fixup_Mips_16",           0,     16,   0 },
     { "fixup_Mips_32",           0,     32,   0 },
     { "fixup_Mips_REL32",        0,     32,   0 },
     { "fixup_Mips_26",           0,     26,   0 },
     { "fixup_Mips_HI16",         0,     16,   0 },
     { "fixup_Mips_LO16",         0,     16,   0 },
+    { "fixup_Mips_AnyImm16",     0,     16,   0 },
     { "fixup_Mips_GPREL16",      0,     16,   0 },
     { "fixup_Mips_LITERAL",      0,     16,   0 },
     { "fixup_Mips_GOT",          0,     16,   0 },
@@ -424,22 +431,24 @@ getFixupKindInfo(MCFixupKind Kind) const {
     { "fixup_Mips_SUB",                  0,     64,   0 },
     { "fixup_MICROMIPS_SUB",             0,     64,   0 },
     { "fixup_Mips_JALR",                 0,     32,   0 },
-    { "fixup_MICROMIPS_JALR",            0,     32,   0 }
+    { "fixup_MICROMIPS_JALR",            0,     32,   0 } // clang-format on
   };
   static_assert(std::size(LittleEndianInfos) == Mips::NumTargetFixupKinds,
                 "Not all MIPS little endian fixup kinds added!");
 
   const static MCFixupKindInfo BigEndianInfos[] = {
-    // This table *must* be in same the order of fixup_* kinds in
-    // MipsFixupKinds.h.
-    //
-    // name                    offset  bits  flags
+      // This table *must* be in same the order of fixup_* kinds in
+      // MipsFixupKinds.h.
+      //
+      // name                    offset  bits  flags
+      // clang-format off
     { "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_AnyImm16",    16,     16,   0 },
     { "fixup_Mips_GPREL16",     16,     16,   0 },
     { "fixup_Mips_LITERAL",     16,     16,   0 },
     { "fixup_Mips_GOT",         16,     16,   0 },
@@ -503,7 +512,7 @@ getFixupKindInfo(MCFixupKind Kind) const {
     { "fixup_Mips_SUB",                   0,     64,   0 },
     { "fixup_MICROMIPS_SUB",              0,     64,   0 },
     { "fixup_Mips_JALR",                  0,     32,   0 },
-    { "fixup_MICROMIPS_JALR",             0,     32,   0 }
+    { "fixup_MICROMIPS_JALR",             0,     32,   0 } // clang-format on
   };
   static_assert(std::size(BigEndianInfos) == Mips::NumTargetFixupKinds,
                 "Not all MIPS big endian fixup kinds added!");
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
index bd4c5d35ddfbe..b0c5aea9bddab 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h
@@ -26,7 +26,8 @@ namespace llvm {
 /// instruction info tracks.
 ///
 namespace MipsII {
-  /// Target Operand Flag enum.
+/// Target Operand Flag enum.
+// clang-format off
   enum TOF {
     //===------------------------------------------------------------------===//
     // Mips Specific MachineOperand flags.
@@ -100,7 +101,7 @@ namespace MipsII {
     MO_DLLIMPORT = 0x20,
   };
 
-  enum {
+enum {
     //===------------------------------------------------------------------===//
     // Instruction encodings.  These are the standard/most common forms for
     // Mips instructions.
@@ -132,13 +133,18 @@ namespace MipsII {
     /// HasFCCRegOperand - Instruction uses an $fcc<x> register.
     HasFCCRegOperand = 1 << 6
 
-  };
+};
+// clang-format on
 
-  enum OperandType : unsigned {
-    OPERAND_FIRST_MIPS_MEM_IMM = MCOI::OPERAND_FIRST_TARGET,
-    OPERAND_MEM_SIMM9 = OPERAND_FIRST_MIPS_MEM_IMM,
-    OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
-  };
+enum OperandType : unsigned {
+  OPERAND_FIRST_MIPS_MEM_IMM = MCOI::OPERAND_FIRST_TARGET,
+  OPERAND_MEM_SIMM9 = OPERAND_FIRST_MIPS_MEM_IMM,
+  OPERAND_LAST_MIPS_MEM_IMM = OPERAND_MEM_SIMM9
+};
+
+static inline unsigned getFormat(uint64_t TSFlags) {
+  return TSFlags & FormMask;
+}
 }
 
 inline static MCRegister getMSARegFromFReg(MCRegister Reg) {
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index f2d4a6a5bf263..b60b336422ed5 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -328,7 +328,8 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
     return ELF::R_MICROMIPS_JALR;
   }
 
-  llvm_unreachable("invalid fixup kind!");
+  Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
+  return ELF::R_MIPS_NONE;
 }
 
 /// Sort relocation table entries by offset except where another order is
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
index b83d822bd8d03..1c8b59396ad8f 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
@@ -13,14 +13,15 @@
 
 namespace llvm {
 namespace Mips {
-  // Although most of the current fixup types reflect a unique relocation
-  // one can have multiple fixup types for a given relocation and thus need
-  // to be uniquely named.
-  //
-  // This table *must* be in the same order of
-  // MCFixupKindInfo Infos[Mips::NumTargetFixupKinds]
-  // in MipsAsmBackend.cpp.
-  //
+// Although most of the current fixup types reflect a unique relocation
+// one can have multiple fixup types for a given relocation and thus need
+// to be uniquely named.
+//
+// This table *must* be in the same order of
+// MCFixupKindInfo Infos[Mips::NumTargetFixupKinds]
+// in MipsAsmBackend.cpp.
+//
+// clang-format off
   enum Fixups {
     // Branch fixups resulting in R_MIPS_16.
     fixup_Mips_16 = FirstTargetFixupKind,
@@ -40,6 +41,9 @@ namespace Mips {
     // Pure lower 16 bit fixup resulting in - R_MIPS_LO16.
     fixup_Mips_LO16,
 
+    // 16-bit fixup that must be resolved.
+    fixup_Mips_AnyImm16,
+
     // 16 bit fixup for GP offest resulting in - R_MIPS_GPREL16.
     fixup_Mips_GPREL16,
 
@@ -226,6 +230,7 @@ namespace Mips {
     LastTargetFixupKind,
     NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
   };
+// clang-format on
 } // namespace Mips
 } // namespace llvm
 
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 097b3cf8aa723..23e8ea53f5142 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MipsMCCodeEmitter.h"
+#include "MCTargetDesc/MipsBaseInfo.h"
 #include "MCTargetDesc/MipsFixupKinds.h"
 #include "MCTargetDesc/MipsMCExpr.h"
 #include "MCTargetDesc/MipsMCTargetDesc.h"
@@ -578,23 +579,7 @@ getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
 unsigned MipsMCCodeEmitter::
 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
                const MCSubtargetInfo &STI) const {
-  int64_t Res;
-
-  if (Expr->evaluateAsAbsolute(Res))
-    return Res;
-
   MCExpr::ExprKind Kind = Expr->getKind();
-  if (Kind == MCExpr::Constant) {
-    return cast<MCConstantExpr>(Expr)->getValue();
-  }
-
-  if (Kind == MCExpr::Binary) {
-    unsigned Res =
-        getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
-    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
-    return Res;
-  }
-
   if (Kind == MCExpr::Target) {
     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
 
@@ -712,8 +697,7 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
     return 0;
   }
 
-  if (Kind == MCExpr::SymbolRef)
-    Ctx.reportError(Expr->getLoc(), "expected an immediate");
+  Ctx.reportError(Expr->getLoc(), "expected an immediate");
   return 0;
 }
 
@@ -732,9 +716,29 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   } else if (MO.isDFPImm()) {
     return static_cast<unsigned>(bit_cast<double>(MO.getDFPImm()));
   }
-  // MO must be an Expr.
+  // TODO: Set EncoderMethod to "getImmOpValue" for imm Operand so that
+  // getMachineOpValue will not be called for isExpr code paths.
   assert(MO.isExpr());
-  return getExprOpValue(MO.getExpr(),Fixups, STI);
+  return getImmOpValue(MI, MO, Fixups, STI);
+}
+
+unsigned MipsMCCodeEmitter::getImmOpValue(const MCInst &MI, const MCOperand &MO,
+                                          SmallVectorImpl<MCFixup> &Fixups,
+                                          const MCSubtargetInfo &STI) const {
+  if (MO.isImm())
+    return MO.getImm();
+  assert(MO.isExpr() && "getImmOpValue expects only expressions or immediates");
+  const MCExpr *Expr = MO.getExpr();
+  int64_t Res;
+  if (Expr->evaluateAsAbsolute(Res))
+    return Res;
+  unsigned MIFrm = MipsII::getFormat(MCII.get(MI.getOpcode()).TSFlags);
+  if (!isa<MCTargetExpr>(Expr) && MIFrm == MipsII::FrmI) {
+    Fixups.push_back(MCFixup::create(
+        0, Expr, MCFixupKind(Mips::fixup_Mips_AnyImm16), MI.getLoc()));
+    return 0;
+  }
+  return getExprOpValue(Expr, Fixups, STI);
 }
 
 /// Return binary encoding of memory related operand.
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index 871afd9eb9584..497b3e64df533 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -177,6 +177,9 @@ class MipsMCCodeEmitter : public MCCodeEmitter {
   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
+  unsigned getImmOpValue(const MCInst &MI, const MCOperand &MO,
+                         SmallVectorImpl<MCFixup> &Fixups,
+                         const MCSubtargetInfo &STI) const;
 
   unsigned getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups,
diff --git a/llvm/test/MC/Mips/fixup-expr.s b/llvm/test/MC/Mips/fixup-expr.s
new file mode 100644
index 0000000000000..85a855e1a83c0
--- /dev/null
+++ b/llvm/test/MC/Mips/fixup-expr.s
@@ -0,0 +1,37 @@
+# RUN: llvm-mc -filetype=obj -triple=mips64 %s -o %t.be
+# RUN: llvm-objdump -d %t.be | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=mips64el %s -o %t.le
+# RUN: llvm-objdump -d %t.le | FileCheck %s
+
+# RUN: not llvm-mc -filetype=obj -triple=mips64el --defsym ERR=1 %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+# CHECK:      addiu $4, $5, -0x8000
+# CHECK-NEXT: addiu $4, $5, -0x1
+# CHECK-NEXT: addiu $4, $5, -0x8000
+# CHECK-NEXT: addiu $4, $5, 0x7fff
+# CHECK-NEXT: addiu $4, $5, -0x1
+addiu $4, $5, v_32769+1
+addiu $4, $5, v65535
+addiu $4, $5, .L0-.L1
+addiu $4, $5, .L2-.L1
+addiu $4, $5, .L2-.L0+0
+
+.ifdef ERR
+# ERR: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $4, $5, v_32769
+# ERR: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $4, $5, v65535+1
+
+# ERR: [[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $4, $5, .L2-.L0+1
+.endif
+
+v_32769 = -32769
+v65535 = 65535
+
+.section .rodata,"a"
+.L0:
+.space 32768
+.L1:
+.space 32767
+.L2:
diff --git a/llvm/test/MC/Mips/fixup-out-of-range.s b/llvm/test/MC/Mips/fixup-out-of-range.s
new file mode 100644
index 0000000000000..08744c8b2320d
--- /dev/null
+++ b/llvm/test/MC/Mips/fixup-out-of-range.s
@@ -0,0 +1,13 @@
+# RUN: not llvm-mc -triple mips64 -filetype obj %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
+
+# CHECK: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $t2, $t3, v_32769
+addiu $t2, $t3, v_32768
+addiu $t2, $t3, v65535
+# CHECK: :[[#@LINE+1]]:1: error: fixup value out of range [-32768, 65535]
+addiu $t2, $t3, v65536
+
+v_32769 = -32769
+v_32768 = -32768
+v65535 = 65535
+v65536 = 65536
diff --git a/llvm/test/MC/Mips/imm-operand-err.s b/llvm/test/MC/Mips/imm-operand-err.s
index 8ded4a21b4807..278ba0cacda96 100644
--- a/llvm/test/MC/Mips/imm-operand-err.s
+++ b/llvm/test/MC/Mips/imm-operand-err.s
@@ -1,15 +1,13 @@
 ## Print an error if a non-immediate operand is used while an immediate is expected
-# RUN: not llvm-mc -filetype=obj -triple=mips -o /dev/null %s 2>&1 | FileCheck %s
-# RUN: not llvm-mc -filetype=obj -triple=mips64 -o /dev/null %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -filetype=obj -triple=mips -o /dev/null %s 2>&1 | FileCheck %s --implicit-check-not=error:
+# RUN: not llvm-mc -filetype=obj -triple=mips64 -o /dev/null %s 2>&1 | FileCheck %s --implicit-check-not=error:
 
-# CHECK: [[#@LINE+1]]:16: error: expected an immediate
+# CHECK: [[#@LINE+1]]:3: error: unsupported relocation type
   ori  $4, $4, start
-# CHECK: [[#@LINE+1]]:17: error: expected an immediate
   ori  $4, $4, (start - .)
 
-# CHECK: [[#@LINE+1]]:18: error: expected an immediate
+# CHECK: [[#@LINE+1]]:3: error: unsupported relocation type
   addiu  $4, $4, start
-# CHECK: [[#@LINE+1]]:19: error: expected an immediate
   addiu  $4, $4, (start - .)
 
 start:

@MaskRay MaskRay requested a review from yingopq February 18, 2025 07:03
Copy link

github-actions bot commented Feb 18, 2025

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff b356a3085be43fda14a9f34f9e81bdf36b73e915 a97bbe611a80c10626321aba3be165704bed018a --extensions cpp,h -- llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp llvm/lib/Target/Mips/MCTargetDesc/MipsBaseInfo.h llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
View the diff from clang-format here.
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index d53ee15168..892fbc6db7 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -576,9 +576,9 @@ getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
   return 0;
 }
 
-unsigned MipsMCCodeEmitter::
-getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
-               const MCSubtargetInfo &STI) const {
+unsigned MipsMCCodeEmitter::getExprOpValue(const MCExpr *Expr,
+                                           SmallVectorImpl<MCFixup> &Fixups,
+                                           const MCSubtargetInfo &STI) const {
   MCExpr::ExprKind Kind = Expr->getKind();
   if (Kind == MCExpr::Target) {
     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);

Created using spr 1.3.5-bogner
@MaskRay
Copy link
Member Author

MaskRay commented Feb 21, 2025

Ping:)

@wzssyqa
Copy link
Contributor

wzssyqa commented Feb 27, 2025

LGTM for the code.
But there is some code format warning.

@MaskRay
Copy link
Member Author

MaskRay commented Feb 27, 2025

LGTM for the code. But there is some code format warning.

Thanks. I prefer to ignore the formatting warning. I do not touch these lines and do not want to format them (unneeded diff).

unsigned MipsMCCodeEmitter::
getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
               const MCSubtargetInfo &STI) const {

MaskRay added a commit that referenced this pull request Mar 1, 2025
Created using spr 1.3.5-bogner
@MaskRay MaskRay merged commit b65e094 into main Mar 1, 2025
5 of 11 checks passed
@MaskRay MaskRay deleted the users/MaskRay/spr/mips-allow-expressions-in-some-immediate-operands branch March 1, 2025 18:26
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Mar 1, 2025
e.g.
`addiu   $t2, $t3, .Lend-.Lstart-4`
used by libdragon/boot/boot_trampoline.S

To make this work, update a few places:

* AsmParser: When matching a isSImm/isUImm, consider an expression
  that does not evaluate to an assemble-time constant an immediate.
* MCCodeEmitter: If this is an I-type instruction and the expression
  does not evaluate to an assemble-time constant, append a
  `fixup_Mips_AnyImm16`.
  TODO: in MipsInstrInfo.td, more `Operand` should switch from the
  default `getMachineOpValue` to `getImmOpValue` like RISCV.
* AsmBackend: If the expression does not evaluate to a constant
  with assembler layout information, report "unknown relocation type"
  like X86. If the result is not within [-32768,65535] (the bound gas
  uses when parsing a constant integer for ADDIU)

Fix #126531

Pull Request: llvm/llvm-project#127581
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
jph-13 pushed a commit to jph-13/llvm-project that referenced this pull request Mar 21, 2025
e.g.
`addiu   $t2, $t3, .Lend-.Lstart-4`
used by libdragon/boot/boot_trampoline.S

To make this work, update a few places:

* AsmParser: When matching a isSImm/isUImm, consider an expression
  that does not evaluate to an assemble-time constant an immediate.
* MCCodeEmitter: If this is an I-type instruction and the expression
  does not evaluate to an assemble-time constant, append a
  `fixup_Mips_AnyImm16`.
  TODO: in MipsInstrInfo.td, more `Operand` should switch from the
  default `getMachineOpValue` to `getImmOpValue` like RISCV.
* AsmBackend: If the expression does not evaluate to a constant
  with assembler layout information, report "unknown relocation type"
  like X86. If the result is not within [-32768,65535] (the bound gas
  uses when parsing a constant integer for ADDIU)

Fix llvm#126531

Pull Request: llvm#127581
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MIPS assembler cannot resolve local label arithmetic in immediate expression (GNU as parity issue)
3 participants