Skip to content

Commit a0d3d69

Browse files
authored
[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: #125150
1 parent 7b5e90b commit a0d3d69

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed

llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ class SparcAsmParser : public MCTargetAsmParser {
130130
bool expandSET(MCInst &Inst, SMLoc IDLoc,
131131
SmallVectorImpl<MCInst> &Instructions);
132132

133+
bool expandSETSW(MCInst &Inst, SMLoc IDLoc,
134+
SmallVectorImpl<MCInst> &Instructions);
135+
133136
bool expandSETX(MCInst &Inst, SMLoc IDLoc,
134137
SmallVectorImpl<MCInst> &Instructions);
135138

@@ -734,6 +737,69 @@ bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
734737
return false;
735738
}
736739

740+
bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
741+
SmallVectorImpl<MCInst> &Instructions) {
742+
MCOperand MCRegOp = Inst.getOperand(0);
743+
MCOperand MCValOp = Inst.getOperand(1);
744+
assert(MCRegOp.isReg());
745+
assert(MCValOp.isImm() || MCValOp.isExpr());
746+
747+
// The imm operand can be either an expression or an immediate.
748+
bool IsImm = Inst.getOperand(1).isImm();
749+
int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
750+
const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())
751+
: MCValOp.getExpr();
752+
753+
bool IsSmallImm = IsImm && isInt<13>(ImmValue);
754+
bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
755+
756+
MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
757+
758+
if (!isInt<32>(ImmValue)) {
759+
return Error(IDLoc,
760+
"set: argument must be between -2147483648 and 2147483647");
761+
}
762+
763+
// Very small immediates can be expressed without emitting a sethi.
764+
if (!IsSmallImm) {
765+
// sethi %hi(val), rd
766+
Instructions.push_back(
767+
MCInstBuilder(SP::SETHIi)
768+
.addReg(MCRegOp.getReg())
769+
.addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr)));
770+
771+
PrevReg = MCRegOp;
772+
}
773+
774+
// If the immediate has the lower bits set or is small, we need to emit an or.
775+
if (!NoLowBitsImm || IsSmallImm) {
776+
const MCExpr *Expr =
777+
IsSmallImm ? ValExpr
778+
: adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
779+
780+
// or rd, %lo(val), rd
781+
Instructions.push_back(MCInstBuilder(SP::ORri)
782+
.addReg(MCRegOp.getReg())
783+
.addReg(PrevReg.getReg())
784+
.addExpr(Expr));
785+
786+
// If it's a small immediate there's nothing more to do.
787+
if (IsSmallImm)
788+
return false;
789+
}
790+
791+
// Large negative or non-immediate expressions would need an sra.
792+
if (!IsImm || ImmValue < 0) {
793+
// sra rd, %g0, rd
794+
Instructions.push_back(MCInstBuilder(SP::SRArr)
795+
.addReg(MCRegOp.getReg())
796+
.addReg(MCRegOp.getReg())
797+
.addReg(Sparc::G0));
798+
}
799+
800+
return false;
801+
}
802+
737803
bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
738804
SmallVectorImpl<MCInst> &Instructions) {
739805
MCOperand MCRegOp = Inst.getOperand(0);
@@ -826,6 +892,10 @@ bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
826892
if (expandSET(Inst, IDLoc, Instructions))
827893
return true;
828894
break;
895+
case SP::SETSW:
896+
if (expandSETSW(Inst, IDLoc, Instructions))
897+
return true;
898+
break;
829899
case SP::SETX:
830900
if (expandSETX(Inst, IDLoc, Instructions))
831901
return true;

llvm/lib/Target/Sparc/SparcInstrAliases.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,10 @@ def : InstAlias<"save", (SAVErr G0, G0, G0)>;
450450
// def : InstAlias<"set $val, $rd", (ORri IntRegs:$rd, (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
451451
def SET : AsmPseudoInst<(outs IntRegs:$rd), (ins i32imm:$val), "set $val, $rd">;
452452

453+
// setsw value, rd
454+
// (turns into a sequence of sethi+or+sra, depending on the value)
455+
def SETSW : AsmPseudoInst<(outs IntRegs:$rd), (ins i32imm:$val), "setsw $val, $rd">, Requires<[HasV9]>;
456+
453457
// setx value, tmp, rd
454458
// (turns into a sequence of sethi+or+shift, depending on the value)
455459
def SETX : AsmPseudoInst<(outs I64Regs:$rd),

llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,39 @@ setx (.BB1-.BB0), %g1, %o0
8686
setuw 32768, %g1
8787
! V9: mov 1, %g1 ! encoding: [0x82,0x10,0x20,0x01]
8888
setuw 1, %g1
89+
90+
! V8: error: instruction requires a CPU feature not currently enabled
91+
! V9: mov 4095, %g1 ! encoding: [0x82,0x10,0x2f,0xff]
92+
setsw 4095, %g1
93+
! V8: error: instruction requires a CPU feature not currently enabled
94+
! V9: mov -4096, %g1 ! encoding: [0x82,0x10,0x30,0x00]
95+
setsw -4096, %g1
96+
! V8: error: instruction requires a CPU feature not currently enabled
97+
! V9: sethi %hi(4096), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
98+
! V9: ! fixup A - offset: 0, value: %hi(4096), kind: fixup_sparc_hi22
99+
setsw 4096, %g1
100+
! V8: error: instruction requires a CPU feature not currently enabled
101+
! V9: sethi %hi(-4097), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
102+
! V9: ! fixup A - offset: 0, value: %hi(-4097), kind: fixup_sparc_hi22
103+
! V9: sra %g1, %g0, %g1 ! encoding: [0x83,0x38,0x40,0x00]
104+
setsw -4097, %g1
105+
! V8: error: instruction requires a CPU feature not currently enabled
106+
! V9: sethi %hi(2147483647), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
107+
! V9: ! fixup A - offset: 0, value: %hi(2147483647), kind: fixup_sparc_hi22
108+
! V9: or %o1, %lo(2147483647), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
109+
! V9: ! fixup A - offset: 0, value: %lo(2147483647), kind: fixup_sparc_lo10
110+
setsw 2147483647, %o1
111+
! V8: error: instruction requires a CPU feature not currently enabled
112+
! V9: sethi %hi(-2147483647), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
113+
! V9: ! fixup A - offset: 0, value: %hi(-2147483647), kind: fixup_sparc_hi22
114+
! V9: or %o1, %lo(-2147483647), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
115+
! V9: ! fixup A - offset: 0, value: %lo(-2147483647), kind: fixup_sparc_lo10
116+
! V9: sra %o1, %g0, %o1 ! encoding: [0x93,0x3a,0x40,0x00]
117+
setsw -2147483647, %o1
118+
! V8: error: instruction requires a CPU feature not currently enabled
119+
! V9: sethi %hi(.Ltmp0), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
120+
! V9: ! fixup A - offset: 0, value: %hi(.Ltmp0), kind: fixup_sparc_hi22
121+
! V9: or %o1, %lo(.Ltmp0), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
122+
! V9: ! fixup A - offset: 0, value: %lo(.Ltmp0), kind: fixup_sparc_lo10
123+
! V9: sra %o1, %g0, %o1 ! encoding: [0x93,0x3a,0x40,0x00]
124+
setsw ., %o1

0 commit comments

Comments
 (0)