Skip to content

Commit c8c5f31

Browse files
koachanbrad0
authored andcommitted
[SPARC][IAS] Add SETX pseudoinstruction
This adds the v9 SETX pseudoinstruction for convenient loading of 64-bit values. Reviewed By: barannikov88 Differential Revision: https://reviews.llvm.org/D157230
1 parent 9fee2ac commit c8c5f31

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

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

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "llvm/MC/MCContext.h"
1616
#include "llvm/MC/MCExpr.h"
1717
#include "llvm/MC/MCInst.h"
18+
#include "llvm/MC/MCInstBuilder.h"
1819
#include "llvm/MC/MCInstrInfo.h"
1920
#include "llvm/MC/MCObjectFileInfo.h"
2021
#include "llvm/MC/MCParser/MCAsmLexer.h"
@@ -28,6 +29,7 @@
2829
#include "llvm/MC/TargetRegistry.h"
2930
#include "llvm/Support/Casting.h"
3031
#include "llvm/Support/ErrorHandling.h"
32+
#include "llvm/Support/MathExtras.h"
3133
#include "llvm/Support/SMLoc.h"
3234
#include "llvm/Support/raw_ostream.h"
3335
#include "llvm/TargetParser/Triple.h"
@@ -119,6 +121,9 @@ class SparcAsmParser : public MCTargetAsmParser {
119121
bool expandSET(MCInst &Inst, SMLoc IDLoc,
120122
SmallVectorImpl<MCInst> &Instructions);
121123

124+
bool expandSETX(MCInst &Inst, SMLoc IDLoc,
125+
SmallVectorImpl<MCInst> &Instructions);
126+
122127
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
123128

124129
public:
@@ -643,6 +648,78 @@ bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
643648
return false;
644649
}
645650

651+
bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
652+
SmallVectorImpl<MCInst> &Instructions) {
653+
MCOperand MCRegOp = Inst.getOperand(0);
654+
MCOperand MCValOp = Inst.getOperand(1);
655+
MCOperand MCTmpOp = Inst.getOperand(2);
656+
assert(MCRegOp.isReg() && MCTmpOp.isReg());
657+
assert(MCValOp.isImm() || MCValOp.isExpr());
658+
659+
// the imm operand can be either an expression or an immediate.
660+
bool IsImm = MCValOp.isImm();
661+
int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
662+
663+
const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())
664+
: MCValOp.getExpr();
665+
666+
// Very small immediates can be expressed directly as a single `or`.
667+
if (IsImm && isInt<13>(ImmValue)) {
668+
// or rd, val, rd
669+
Instructions.push_back(MCInstBuilder(SP::ORri)
670+
.addReg(MCRegOp.getReg())
671+
.addReg(Sparc::G0)
672+
.addExpr(ValExpr));
673+
return false;
674+
}
675+
676+
// Otherwise, first we set the lower half of the register.
677+
678+
// sethi %hi(val), rd
679+
Instructions.push_back(
680+
MCInstBuilder(SP::SETHIi)
681+
.addReg(MCRegOp.getReg())
682+
.addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr)));
683+
// or rd, %lo(val), rd
684+
Instructions.push_back(
685+
MCInstBuilder(SP::ORri)
686+
.addReg(MCRegOp.getReg())
687+
.addReg(MCRegOp.getReg())
688+
.addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr)));
689+
690+
// Small positive immediates can be expressed as a single `sethi`+`or`
691+
// combination, so we can just return here.
692+
if (IsImm && isUInt<32>(ImmValue))
693+
return false;
694+
695+
// For bigger immediates, we need to generate the upper half, then shift and
696+
// merge it with the lower half that has just been generated above.
697+
698+
// sethi %hh(val), tmp
699+
Instructions.push_back(
700+
MCInstBuilder(SP::SETHIi)
701+
.addReg(MCTmpOp.getReg())
702+
.addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HH, ValExpr)));
703+
// or tmp, %hm(val), tmp
704+
Instructions.push_back(
705+
MCInstBuilder(SP::ORri)
706+
.addReg(MCTmpOp.getReg())
707+
.addReg(MCTmpOp.getReg())
708+
.addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HM, ValExpr)));
709+
// sllx tmp, 32, tmp
710+
Instructions.push_back(MCInstBuilder(SP::SLLXri)
711+
.addReg(MCTmpOp.getReg())
712+
.addReg(MCTmpOp.getReg())
713+
.addImm(32));
714+
// or tmp, rd, rd
715+
Instructions.push_back(MCInstBuilder(SP::ORrr)
716+
.addReg(MCRegOp.getReg())
717+
.addReg(MCTmpOp.getReg())
718+
.addReg(MCRegOp.getReg()));
719+
720+
return false;
721+
}
722+
646723
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
647724
OperandVector &Operands,
648725
MCStreamer &Out,
@@ -663,6 +740,10 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
663740
if (expandSET(Inst, IDLoc, Instructions))
664741
return true;
665742
break;
743+
case SP::SETX:
744+
if (expandSETX(Inst, IDLoc, Instructions))
745+
return true;
746+
break;
666747
}
667748

668749
for (const MCInst &I : Instructions) {

llvm/lib/Target/Sparc/SparcInstrAliases.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,13 @@ def : InstAlias<"save", (SAVErr G0, G0, G0)>;
443443
// def : InstAlias<"set $val, $rd", (ORri IntRegs:$rd, (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
444444
def SET : AsmPseudoInst<(outs IntRegs:$rd), (ins i32imm:$val), "set $val, $rd">;
445445

446+
// setx value, tmp, rd
447+
// (turns into a sequence of sethi+or+shift, depending on the value)
448+
def SETX : AsmPseudoInst<(outs I64Regs:$rd),
449+
(ins i64imm:$val, I64Regs:$tmp),
450+
"setx $val, $tmp, $rd">,
451+
Requires<[Is64Bit, HasV9]>;
452+
446453
// not rd -> xnor rd, %g0, rd
447454
def : InstAlias<"not $rd", (XNORrr IntRegs:$rd, IntRegs:$rd, G0), 0>;
448455

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
! RUN: not llvm-mc %s -arch=sparc -show-encoding 2>&1 | FileCheck %s --check-prefix=V8
2+
! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s --check-prefix=V9
3+
4+
! V8: error: instruction requires a CPU feature not currently enabled
5+
! V8-NEXT: setx 1, %g1, %o1
6+
! V9: mov 1, %o1 ! encoding: [0x92,0x10,0x20,0x01]
7+
setx 1, %g1, %o1
8+
9+
! V8: error: instruction requires a CPU feature not currently enabled
10+
! V8-NEXT: setx (0+1), %g1, %o1
11+
! V9: mov 1, %o1 ! encoding: [0x92,0x10,0x20,0x01]
12+
setx (0+1), %g1, %o1
13+
14+
! V8: error: instruction requires a CPU feature not currently enabled
15+
! V8-NEXT: setx -1, %g1, %o1
16+
! V9: mov -1, %o1 ! encoding: [0x92,0x10,0x3f,0xff]
17+
setx -1, %g1, %o1
18+
19+
! V8: error: instruction requires a CPU feature not currently enabled
20+
! V8-NEXT: setx (0-1), %g1, %o1
21+
! V9: mov -1, %o1 ! encoding: [0x92,0x10,0x3f,0xff]
22+
setx (0-1), %g1, %o1
23+
24+
! V8: error: instruction requires a CPU feature not currently enabled
25+
! V8-NEXT: setx 0xffffffff, %g1, %o1
26+
! V9: sethi %hi(4294967295), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
27+
! V9: ! fixup A - offset: 0, value: %hi(4294967295), kind: fixup_sparc_hi22
28+
! V9: or %o1, %lo(4294967295), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
29+
! V9: ! fixup A - offset: 0, value: %lo(4294967295), kind: fixup_sparc_lo10
30+
setx 0xffffffff, %g1, %o1
31+
32+
! V8: error: instruction requires a CPU feature not currently enabled
33+
! V8-NEXT: setx (0xffff0000+0x0000ffff), %g1, %o1
34+
! V9: sethi %hi(4294967295), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
35+
! V9: ! fixup A - offset: 0, value: %hi(4294967295), kind: fixup_sparc_hi22
36+
! V9: or %o1, %lo(4294967295), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
37+
! V9: ! fixup A - offset: 0, value: %lo(4294967295), kind: fixup_sparc_lo10
38+
setx (0xffff0000+0x0000ffff), %g1, %o1
39+
40+
! V8: error: instruction requires a CPU feature not currently enabled
41+
! V8-NEXT: setx 0x0123456789abcdef, %g1, %o0
42+
! V9: sethi %hi(81985529216486895), %o0 ! encoding: [0x11,0b00AAAAAA,A,A]
43+
! V9: ! fixup A - offset: 0, value: %hi(81985529216486895), kind: fixup_sparc_hi22
44+
! V9: or %o0, %lo(81985529216486895), %o0 ! encoding: [0x90,0x12,0b001000AA,A]
45+
! V9: ! fixup A - offset: 0, value: %lo(81985529216486895), kind: fixup_sparc_lo10
46+
! V9: sethi %hh(81985529216486895), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
47+
! V9: ! fixup A - offset: 0, value: %hh(81985529216486895), kind: fixup_sparc_hh
48+
! V9: or %g1, %hm(81985529216486895), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
49+
! V9: ! fixup A - offset: 0, value: %hm(81985529216486895), kind: fixup_sparc_hm
50+
! V9: sllx %g1, 32, %g1 ! encoding: [0x83,0x28,0x70,0x20]
51+
! V9: or %g1, %o0, %o0 ! encoding: [0x90,0x10,0x40,0x08]
52+
setx 0x0123456789abcdef, %g1, %o0
53+
54+
! V8: error: instruction requires a CPU feature not currently enabled
55+
! V8-NEXT: setx (0x0123456700000000+0x0000000089abcdef), %g1, %o0
56+
! V9: sethi %hi(81985529216486895), %o0 ! encoding: [0x11,0b00AAAAAA,A,A]
57+
! V9: ! fixup A - offset: 0, value: %hi(81985529216486895), kind: fixup_sparc_hi22
58+
! V9: or %o0, %lo(81985529216486895), %o0 ! encoding: [0x90,0x12,0b001000AA,A]
59+
! V9: ! fixup A - offset: 0, value: %lo(81985529216486895), kind: fixup_sparc_lo10
60+
! V9: sethi %hh(81985529216486895), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
61+
! V9: ! fixup A - offset: 0, value: %hh(81985529216486895), kind: fixup_sparc_hh
62+
! V9: or %g1, %hm(81985529216486895), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
63+
! V9: ! fixup A - offset: 0, value: %hm(81985529216486895), kind: fixup_sparc_hm
64+
! V9: sllx %g1, 32, %g1 ! encoding: [0x83,0x28,0x70,0x20]
65+
! V9: or %g1, %o0, %o0 ! encoding: [0x90,0x10,0x40,0x08]
66+
setx (0x0123456700000000+0x0000000089abcdef), %g1, %o0
67+
68+
! V8: error: instruction requires a CPU feature not currently enabled
69+
! V8-NEXT: setx (.BB1-.BB0), %g1, %o0
70+
! V9: sethi %hi(.BB1-.BB0), %o0 ! encoding: [0x11,0b00AAAAAA,A,A]
71+
! V9: ! fixup A - offset: 0, value: %hi(.BB1-.BB0), kind: fixup_sparc_hi22
72+
! V9: or %o0, %lo(.BB1-.BB0), %o0 ! encoding: [0x90,0x12,0b001000AA,A]
73+
! V9: ! fixup A - offset: 0, value: %lo(.BB1-.BB0), kind: fixup_sparc_lo10
74+
! V9: sethi %hh(.BB1-.BB0), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
75+
! V9: ! fixup A - offset: 0, value: %hh(.BB1-.BB0), kind: fixup_sparc_hh
76+
! V9: or %g1, %hm(.BB1-.BB0), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
77+
! V9: ! fixup A - offset: 0, value: %hm(.BB1-.BB0), kind: fixup_sparc_hm
78+
! V9: sllx %g1, 32, %g1 ! encoding: [0x83,0x28,0x70,0x20]
79+
! V9: or %g1, %o0, %o0 ! encoding: [0x90,0x10,0x40,0x08]
80+
setx (.BB1-.BB0), %g1, %o0

0 commit comments

Comments
 (0)