[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