Skip to content

Commit 0c5fd5a

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.4
2 parents 0bbfd96 + 249bf21 commit 0c5fd5a

File tree

5 files changed

+204
-0
lines changed

5 files changed

+204
-0
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
25932593
bool UseNoExecStack = false;
25942594
bool Msa = false;
25952595
const char *MipsTargetFeature = nullptr;
2596+
llvm::SmallVector<const char *> SparcTargetFeatures;
25962597
StringRef ImplicitIt;
25972598
for (const Arg *A :
25982599
Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler,
@@ -2738,6 +2739,31 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
27382739
if (MipsTargetFeature)
27392740
continue;
27402741
break;
2742+
2743+
case llvm::Triple::sparc:
2744+
case llvm::Triple::sparcel:
2745+
case llvm::Triple::sparcv9:
2746+
if (Value == "--undeclared-regs") {
2747+
// LLVM already allows undeclared use of G registers, so this option
2748+
// becomes a no-op. This solely exists for GNU compatibility.
2749+
// TODO implement --no-undeclared-regs
2750+
continue;
2751+
}
2752+
SparcTargetFeatures =
2753+
llvm::StringSwitch<llvm::SmallVector<const char *>>(Value)
2754+
.Case("-Av8", {"-v8plus"})
2755+
.Case("-Av8plus", {"+v8plus", "+v9"})
2756+
.Case("-Av8plusa", {"+v8plus", "+v9", "+vis"})
2757+
.Case("-Av8plusb", {"+v8plus", "+v9", "+vis", "+vis2"})
2758+
.Case("-Av8plusd", {"+v8plus", "+v9", "+vis", "+vis2", "+vis3"})
2759+
.Case("-Av9", {"+v9"})
2760+
.Case("-Av9a", {"+v9", "+vis"})
2761+
.Case("-Av9b", {"+v9", "+vis", "+vis2"})
2762+
.Case("-Av9d", {"+v9", "+vis", "+vis2", "+vis3"})
2763+
.Default({});
2764+
if (!SparcTargetFeatures.empty())
2765+
continue;
2766+
break;
27412767
}
27422768

27432769
if (Value == "-force_cpusubtype_ALL") {
@@ -2842,6 +2868,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
28422868
CmdArgs.push_back("-target-feature");
28432869
CmdArgs.push_back(MipsTargetFeature);
28442870
}
2871+
if (!SparcTargetFeatures.empty()) {
2872+
for (const char *Feature : SparcTargetFeatures) {
2873+
CmdArgs.push_back("-target-feature");
2874+
CmdArgs.push_back(Feature);
2875+
}
2876+
}
28452877

28462878
// forward -fembed-bitcode to assmebler
28472879
if (C.getDriver().embedBitcodeEnabled() ||

clang/test/Driver/sparc-ias-Wa.s

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8 2>&1 | \
2+
// RUN: FileCheck -check-prefix=V8 %s
3+
// V8: -cc1as
4+
// V8: "-target-feature" "-v8plus"
5+
6+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plus 2>&1 | \
7+
// RUN: FileCheck -check-prefix=V8PLUS %s
8+
// V8PLUS: -cc1as
9+
// V8PLUS: "-target-feature" "+v8plus"
10+
// V8PLUS: "-target-feature" "+v9"
11+
12+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plusa 2>&1 | \
13+
// RUN: FileCheck -check-prefix=V8PLUSA %s
14+
// V8PLUSA: -cc1as
15+
// V8PLUSA: "-target-feature" "+v8plus"
16+
// V8PLUSA: "-target-feature" "+v9"
17+
// V8PLUSA: "-target-feature" "+vis"
18+
19+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plusb 2>&1 | \
20+
// RUN: FileCheck -check-prefix=V8PLUSB %s
21+
// V8PLUSB: -cc1as
22+
// V8PLUSB: "-target-feature" "+v8plus"
23+
// V8PLUSB: "-target-feature" "+v9"
24+
// V8PLUSB: "-target-feature" "+vis"
25+
// V8PLUSB: "-target-feature" "+vis2"
26+
27+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plusd 2>&1 | \
28+
// RUN: FileCheck -check-prefix=V8PLUSD %s
29+
// V8PLUSD: -cc1as
30+
// V8PLUSD: "-target-feature" "+v8plus"
31+
// V8PLUSD: "-target-feature" "+v9"
32+
// V8PLUSD: "-target-feature" "+vis"
33+
// V8PLUSD: "-target-feature" "+vis2"
34+
// V8PLUSD: "-target-feature" "+vis3"
35+
36+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9 2>&1 | \
37+
// RUN: FileCheck -check-prefix=V9 %s
38+
// V9: -cc1as
39+
// V9: "-target-feature" "+v9"
40+
41+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9a 2>&1 | \
42+
// RUN: FileCheck -check-prefix=V9A %s
43+
// V9A: -cc1as
44+
// V9A: "-target-feature" "+v9"
45+
// V9A: "-target-feature" "+vis"
46+
47+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9b 2>&1 | \
48+
// RUN: FileCheck -check-prefix=V9B %s
49+
// V9B: -cc1as
50+
// V9B: "-target-feature" "+v9"
51+
// V9B: "-target-feature" "+vis"
52+
// V9B: "-target-feature" "+vis2"
53+
54+
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9d 2>&1 | \
55+
// RUN: FileCheck -check-prefix=V9D %s
56+
// V9D: -cc1as
57+
// V9D: "-target-feature" "+v9"
58+
// V9D: "-target-feature" "+vis"
59+
// V9D: "-target-feature" "+vis2"
60+
// V9D: "-target-feature" "+vis3"

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: 6 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">;
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),
@@ -605,6 +609,8 @@ def : InstAlias<"unimp", (UNIMP 0), 0>;
605609
// interchangeable with `unimp` all the time.
606610
def : MnemonicAlias<"illtrap", "unimp">;
607611

612+
def : MnemonicAlias<"setuw", "set">;
613+
608614
def : MnemonicAlias<"iflush", "flush">;
609615

610616
def : MnemonicAlias<"stub", "stb">;

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

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,42 @@
5454
! CHECK: ! fixup A - offset: 0, value: %lo(2147483647), kind: fixup_sparc_lo10
5555
set 2147483647, %o1
5656

57+
!! setuw is a mnemonic alias for set.
58+
! CHECK: sethi %hi(32768), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
59+
! CHECK: ! fixup A - offset: 0, value: %hi(32768), kind: fixup_sparc_hi22
60+
setuw 32768, %g1
61+
! CHECK: mov 1, %g1 ! encoding: [0x82,0x10,0x20,0x01]
62+
setuw 1, %g1
63+
64+
! CHECK: sethi %hi(32768), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
65+
! CHECK: ! fixup A - offset: 0, value: %hi(32768), kind: fixup_sparc_hi22
66+
setsw 32768, %g1
67+
! CHECK: mov 1, %g1 ! encoding: [0x82,0x10,0x20,0x01]
68+
setsw 1, %g1
69+
! CHECK: mov -1, %g1 ! encoding: [0x82,0x10,0x3f,0xff]
70+
setsw -1, %g1
71+
! CHECK: sethi %hi(-32768), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
72+
! CHECK: ! fixup A - offset: 0, value: %hi(-32768), kind: fixup_sparc_hi22
73+
! CHECK: sra %g1, %g0, %g1 ! encoding: [0x83,0x38,0x40,0x00]
74+
setsw -32768, %g1
75+
! CHECK: sethi %hi(2147483647), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
76+
! CHECK: ! fixup A - offset: 0, value: %hi(2147483647), kind: fixup_sparc_hi22
77+
! CHECK: or %o1, %lo(2147483647), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
78+
! CHECK: ! fixup A - offset: 0, value: %lo(2147483647), kind: fixup_sparc_lo10
79+
setsw 2147483647, %o1
80+
! CHECK: sethi %hi(-2147483647), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
81+
! CHECK: ! fixup A - offset: 0, value: %hi(-2147483647), kind: fixup_sparc_hi22
82+
! CHECK: or %o1, %lo(-2147483647), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
83+
! CHECK: ! fixup A - offset: 0, value: %lo(-2147483647), kind: fixup_sparc_lo10
84+
! CHECK: sra %o1, %g0, %o1 ! encoding: [0x93,0x3a,0x40,0x00]
85+
setsw -2147483647, %o1
86+
! CHECK: sethi %hi(.Ltmp0), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
87+
! CHECK: ! fixup A - offset: 0, value: %hi(.Ltmp0), kind: fixup_sparc_hi22
88+
! CHECK: or %o1, %lo(.Ltmp0), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
89+
! CHECK: ! fixup A - offset: 0, value: %lo(.Ltmp0), kind: fixup_sparc_lo10
90+
! CHECK: sra %o1, %g0, %o1 ! encoding: [0x93,0x3a,0x40,0x00]
91+
setsw ., %o1
92+
5793
! CHECK: xnor %g1, %g0, %g2 ! encoding: [0x84,0x38,0x40,0x00]
5894
not %g1, %g2
5995
! CHECK: xnor %g1, %g0, %g1 ! encoding: [0x82,0x38,0x40,0x00]

0 commit comments

Comments
 (0)