[llvm] a0d3d69 - [SPARC][IAS] Add support for `setsw` pseudoinstruction
via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 5 08:05:40 PST 2025
Author: Koakuma
Date: 2025-02-05T23:05:35+07:00
New Revision: a0d3d690a23a3aa54cd576dc8f4ea1b22c20d189
URL: https://github.com/llvm/llvm-project/commit/a0d3d690a23a3aa54cd576dc8f4ea1b22c20d189
DIFF: https://github.com/llvm/llvm-project/commit/a0d3d690a23a3aa54cd576dc8f4ea1b22c20d189.diff
LOG: [SPARC][IAS] Add support for `setsw` pseudoinstruction
Implement `setsw` pseudoinstruction for setting a 32-bit signed imm.
Reviewers: brad0, s-barannikov, rorth
Reviewed By: s-barannikov
Pull Request: https://github.com/llvm/llvm-project/pull/125150
Added:
Modified:
llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
llvm/lib/Target/Sparc/SparcInstrAliases.td
llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index bc239480baa891..3e9fc31d7bfc22 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 906f51bb8d10b2..bc57ddbb5682fa 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">, Requires<[HasV9]>;
+
// 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/sparcv9-synthetic-instructions.s b/llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
index f8a99cd1bdf5eb..0d14ff558b314a 100644
--- a/llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
+++ b/llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
@@ -86,3 +86,39 @@ setx (.BB1-.BB0), %g1, %o0
setuw 32768, %g1
! V9: mov 1, %g1 ! encoding: [0x82,0x10,0x20,0x01]
setuw 1, %g1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: mov 4095, %g1 ! encoding: [0x82,0x10,0x2f,0xff]
+setsw 4095, %g1
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: mov -4096, %g1 ! encoding: [0x82,0x10,0x30,0x00]
+setsw -4096, %g1
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: sethi %hi(4096), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(4096), kind: fixup_sparc_hi22
+setsw 4096, %g1
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: sethi %hi(-4097), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(-4097), kind: fixup_sparc_hi22
+! V9: sra %g1, %g0, %g1 ! encoding: [0x83,0x38,0x40,0x00]
+setsw -4097, %g1
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: sethi %hi(2147483647), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(2147483647), kind: fixup_sparc_hi22
+! V9: or %o1, %lo(2147483647), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(2147483647), kind: fixup_sparc_lo10
+setsw 2147483647, %o1
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: sethi %hi(-2147483647), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(-2147483647), kind: fixup_sparc_hi22
+! V9: or %o1, %lo(-2147483647), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(-2147483647), kind: fixup_sparc_lo10
+! V9: sra %o1, %g0, %o1 ! encoding: [0x93,0x3a,0x40,0x00]
+setsw -2147483647, %o1
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: sethi %hi(.Ltmp0), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(.Ltmp0), kind: fixup_sparc_hi22
+! V9: or %o1, %lo(.Ltmp0), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(.Ltmp0), kind: fixup_sparc_lo10
+! V9: sra %o1, %g0, %o1 ! encoding: [0x93,0x3a,0x40,0x00]
+setsw ., %o1
More information about the llvm-commits
mailing list