Skip to content

Commit

Permalink
[𝘀𝗽𝗿] initial version
Browse files Browse the repository at this point in the history
Created using spr 1.3.4
  • Loading branch information
koachan committed Jan 31, 2025
2 parents 0bbfd96 + 249bf21 commit 0c5fd5a
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 0 deletions.
32 changes: 32 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2593,6 +2593,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
bool UseNoExecStack = false;
bool Msa = false;
const char *MipsTargetFeature = nullptr;
llvm::SmallVector<const char *> SparcTargetFeatures;
StringRef ImplicitIt;
for (const Arg *A :
Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler,
Expand Down Expand Up @@ -2738,6 +2739,31 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
if (MipsTargetFeature)
continue;
break;

case llvm::Triple::sparc:
case llvm::Triple::sparcel:
case llvm::Triple::sparcv9:
if (Value == "--undeclared-regs") {
// LLVM already allows undeclared use of G registers, so this option
// becomes a no-op. This solely exists for GNU compatibility.
// TODO implement --no-undeclared-regs
continue;
}
SparcTargetFeatures =
llvm::StringSwitch<llvm::SmallVector<const char *>>(Value)
.Case("-Av8", {"-v8plus"})
.Case("-Av8plus", {"+v8plus", "+v9"})
.Case("-Av8plusa", {"+v8plus", "+v9", "+vis"})
.Case("-Av8plusb", {"+v8plus", "+v9", "+vis", "+vis2"})
.Case("-Av8plusd", {"+v8plus", "+v9", "+vis", "+vis2", "+vis3"})
.Case("-Av9", {"+v9"})
.Case("-Av9a", {"+v9", "+vis"})
.Case("-Av9b", {"+v9", "+vis", "+vis2"})
.Case("-Av9d", {"+v9", "+vis", "+vis2", "+vis3"})
.Default({});
if (!SparcTargetFeatures.empty())
continue;
break;
}

if (Value == "-force_cpusubtype_ALL") {
Expand Down Expand Up @@ -2842,6 +2868,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back("-target-feature");
CmdArgs.push_back(MipsTargetFeature);
}
if (!SparcTargetFeatures.empty()) {
for (const char *Feature : SparcTargetFeatures) {
CmdArgs.push_back("-target-feature");
CmdArgs.push_back(Feature);
}
}

// forward -fembed-bitcode to assmebler
if (C.getDriver().embedBitcodeEnabled() ||
Expand Down
60 changes: 60 additions & 0 deletions clang/test/Driver/sparc-ias-Wa.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8 2>&1 | \
// RUN: FileCheck -check-prefix=V8 %s
// V8: -cc1as
// V8: "-target-feature" "-v8plus"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plus 2>&1 | \
// RUN: FileCheck -check-prefix=V8PLUS %s
// V8PLUS: -cc1as
// V8PLUS: "-target-feature" "+v8plus"
// V8PLUS: "-target-feature" "+v9"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plusa 2>&1 | \
// RUN: FileCheck -check-prefix=V8PLUSA %s
// V8PLUSA: -cc1as
// V8PLUSA: "-target-feature" "+v8plus"
// V8PLUSA: "-target-feature" "+v9"
// V8PLUSA: "-target-feature" "+vis"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plusb 2>&1 | \
// RUN: FileCheck -check-prefix=V8PLUSB %s
// V8PLUSB: -cc1as
// V8PLUSB: "-target-feature" "+v8plus"
// V8PLUSB: "-target-feature" "+v9"
// V8PLUSB: "-target-feature" "+vis"
// V8PLUSB: "-target-feature" "+vis2"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av8plusd 2>&1 | \
// RUN: FileCheck -check-prefix=V8PLUSD %s
// V8PLUSD: -cc1as
// V8PLUSD: "-target-feature" "+v8plus"
// V8PLUSD: "-target-feature" "+v9"
// V8PLUSD: "-target-feature" "+vis"
// V8PLUSD: "-target-feature" "+vis2"
// V8PLUSD: "-target-feature" "+vis3"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9 2>&1 | \
// RUN: FileCheck -check-prefix=V9 %s
// V9: -cc1as
// V9: "-target-feature" "+v9"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9a 2>&1 | \
// RUN: FileCheck -check-prefix=V9A %s
// V9A: -cc1as
// V9A: "-target-feature" "+v9"
// V9A: "-target-feature" "+vis"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9b 2>&1 | \
// RUN: FileCheck -check-prefix=V9B %s
// V9B: -cc1as
// V9B: "-target-feature" "+v9"
// V9B: "-target-feature" "+vis"
// V9B: "-target-feature" "+vis2"

// RUN: %clang --target=sparc-linux-gnu -### -fintegrated-as -c %s -Wa,-Av9d 2>&1 | \
// RUN: FileCheck -check-prefix=V9D %s
// V9D: -cc1as
// V9D: "-target-feature" "+v9"
// V9D: "-target-feature" "+vis"
// V9D: "-target-feature" "+vis2"
// V9D: "-target-feature" "+vis3"
70 changes: 70 additions & 0 deletions llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrAliases.td
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -605,6 +609,8 @@ def : InstAlias<"unimp", (UNIMP 0), 0>;
// interchangeable with `unimp` all the time.
def : MnemonicAlias<"illtrap", "unimp">;

def : MnemonicAlias<"setuw", "set">;

def : MnemonicAlias<"iflush", "flush">;

def : MnemonicAlias<"stub", "stb">;
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/MC/Sparc/sparc-synthetic-instructions.s
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,42 @@
! CHECK: ! fixup A - offset: 0, value: %lo(2147483647), kind: fixup_sparc_lo10
set 2147483647, %o1

!! setuw is a mnemonic alias for set.
! CHECK: sethi %hi(32768), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
! CHECK: ! fixup A - offset: 0, value: %hi(32768), kind: fixup_sparc_hi22
setuw 32768, %g1
! 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]
Expand Down

0 comments on commit 0c5fd5a

Please sign in to comment.