[llvm-branch-commits] [SPARC][IAS] Add support for `setsw` pseudoinstruction (PR #125150)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Jan 30 18:07:49 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-sparc

Author: Koakuma (koachan)

<details>
<summary>Changes</summary>

Implement `setsw` pseudoinstruction for setting a 32-bit signed imm.


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


3 Files Affected:

- (modified) llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp (+70) 
- (modified) llvm/lib/Target/Sparc/SparcInstrAliases.td (+4) 
- (modified) llvm/test/MC/Sparc/sparc-synthetic-instructions.s (+29) 


``````````diff
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index bc239480baa891..879f2ed8849618 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -130,6 +130,9 @@ class SparcAsmParser : public MCTargetAsmParser {
   bool expandSET(MCInst &Inst, SMLoc IDLoc,
                  SmallVectorImpl<MCInst> &Instructions);
 
+  bool expandSETSW(MCInst &Inst, SMLoc IDLoc,
+                   SmallVectorImpl<MCInst> &Instructions);
+
   bool expandSETX(MCInst &Inst, SMLoc IDLoc,
                   SmallVectorImpl<MCInst> &Instructions);
 
@@ -734,6 +737,69 @@ bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
   return false;
 }
 
+bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
+                                 SmallVectorImpl<MCInst> &Instructions) {
+  MCOperand MCRegOp = Inst.getOperand(0);
+  MCOperand MCValOp = Inst.getOperand(1);
+  assert(MCRegOp.isReg());
+  assert(MCValOp.isImm() || MCValOp.isExpr());
+
+  // the imm operand can be either an expression or an immediate.
+  bool IsImm = Inst.getOperand(1).isImm();
+  int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
+  const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())
+                                : MCValOp.getExpr();
+
+  bool IsSmallImm = IsImm && isInt<13>(ImmValue);
+  bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
+
+  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
+
+  if (!isInt<32>(ImmValue)) {
+    return Error(IDLoc,
+                 "set: argument must be between -2147483648 and 2147483647");
+  }
+
+  // Very small immediates can be expressed without emitting a sethi.
+  if (!IsSmallImm) {
+    // sethi %hi(val), rd
+    Instructions.push_back(
+        MCInstBuilder(SP::SETHIi)
+            .addReg(MCRegOp.getReg())
+            .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr)));
+
+    PrevReg = MCRegOp;
+  }
+
+  // If the immediate has the lower bits set or is small, we need to emit an or.
+  if (!NoLowBitsImm || IsSmallImm) {
+    const MCExpr *Expr =
+        IsSmallImm ? ValExpr
+                   : adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
+
+    // or    rd, %lo(val), rd
+    Instructions.push_back(MCInstBuilder(SP::ORri)
+                               .addReg(MCRegOp.getReg())
+                               .addReg(PrevReg.getReg())
+                               .addExpr(Expr));
+
+    // If it's a small immediate there's nothing more to do.
+    if (IsSmallImm)
+      return false;
+  }
+
+  // Large negative or non-immediate expressions would need an sra.
+  if (!IsImm || ImmValue < 0) {
+    // sra    rd, %g0, rd
+    Instructions.push_back(MCInstBuilder(SP::SRArr)
+                               .addReg(MCRegOp.getReg())
+                               .addReg(MCRegOp.getReg())
+                               .addReg(Sparc::G0));
+  }
+
+  return false;
+}
+
 bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
                                 SmallVectorImpl<MCInst> &Instructions) {
   MCOperand MCRegOp = Inst.getOperand(0);
@@ -826,6 +892,10 @@ bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
       if (expandSET(Inst, IDLoc, Instructions))
         return true;
       break;
+    case SP::SETSW:
+      if (expandSETSW(Inst, IDLoc, Instructions))
+        return true;
+      break;
     case SP::SETX:
       if (expandSETX(Inst, IDLoc, Instructions))
         return true;
diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index cfc0b4735c91c4..b7232cc066165e 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -450,6 +450,10 @@ def : InstAlias<"save", (SAVErr G0, G0, G0)>;
 // def : InstAlias<"set $val, $rd", (ORri IntRegs:$rd, (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
 def SET : AsmPseudoInst<(outs IntRegs:$rd), (ins i32imm:$val), "set $val, $rd">;
 
+// setsw value, rd
+// (turns into a sequence of sethi+or+sra, depending on the value)
+def SETSW : AsmPseudoInst<(outs IntRegs:$rd), (ins i32imm:$val), "setsw $val, $rd">;
+
 // setx value, tmp, rd
 // (turns into a sequence of sethi+or+shift, depending on the value)
 def SETX : AsmPseudoInst<(outs I64Regs:$rd),
diff --git a/llvm/test/MC/Sparc/sparc-synthetic-instructions.s b/llvm/test/MC/Sparc/sparc-synthetic-instructions.s
index 9c6db2836af176..f679ee72baf536 100644
--- a/llvm/test/MC/Sparc/sparc-synthetic-instructions.s
+++ b/llvm/test/MC/Sparc/sparc-synthetic-instructions.s
@@ -61,6 +61,35 @@
         ! CHECK: mov 1, %g1 ! encoding: [0x82,0x10,0x20,0x01]
         setuw 1, %g1
 
+        ! CHECK: sethi %hi(32768), %g1           ! encoding: [0x03,0b00AAAAAA,A,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %hi(32768), kind: fixup_sparc_hi22
+        setsw 32768, %g1
+        ! CHECK: mov 1, %g1                      ! encoding: [0x82,0x10,0x20,0x01]
+        setsw 1, %g1
+        ! CHECK: mov -1, %g1                     ! encoding: [0x82,0x10,0x3f,0xff]
+        setsw -1, %g1
+        ! CHECK: sethi %hi(-32768), %g1          ! encoding: [0x03,0b00AAAAAA,A,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %hi(-32768), kind: fixup_sparc_hi22
+        ! CHECK: sra %g1, %g0, %g1               ! encoding: [0x83,0x38,0x40,0x00]
+        setsw -32768, %g1
+        ! CHECK: sethi %hi(2147483647), %o1      ! encoding: [0x13,0b00AAAAAA,A,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %hi(2147483647), kind: fixup_sparc_hi22
+        ! CHECK: or %o1, %lo(2147483647), %o1    ! encoding: [0x92,0x12,0b011000AA,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %lo(2147483647), kind: fixup_sparc_lo10
+        setsw 2147483647, %o1
+        ! CHECK: sethi %hi(-2147483647), %o1     ! encoding: [0x13,0b00AAAAAA,A,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %hi(-2147483647), kind: fixup_sparc_hi22
+        ! CHECK: or %o1, %lo(-2147483647), %o1   ! encoding: [0x92,0x12,0b011000AA,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %lo(-2147483647), kind: fixup_sparc_lo10
+        ! CHECK: sra %o1, %g0, %o1               ! encoding: [0x93,0x3a,0x40,0x00]
+        setsw -2147483647, %o1
+        ! CHECK: sethi %hi(.Ltmp0), %o1          ! encoding: [0x13,0b00AAAAAA,A,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %hi(.Ltmp0), kind: fixup_sparc_hi22
+        ! CHECK: or %o1, %lo(.Ltmp0), %o1        ! encoding: [0x92,0x12,0b011000AA,A]
+        ! CHECK:                                 !   fixup A - offset: 0, value: %lo(.Ltmp0), kind: fixup_sparc_lo10
+        ! CHECK: sra %o1, %g0, %o1               ! encoding: [0x93,0x3a,0x40,0x00]
+        setsw ., %o1
+
         ! CHECK: xnor %g1, %g0, %g2               ! encoding: [0x84,0x38,0x40,0x00]
         not %g1, %g2
         ! CHECK: xnor %g1, %g0, %g1               ! encoding: [0x82,0x38,0x40,0x00]

``````````

</details>


https://github.com/llvm/llvm-project/pull/125150


More information about the llvm-branch-commits mailing list