[llvm] c8c5f31 - [SPARC][IAS] Add SETX pseudoinstruction
Brad Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 22 09:49:43 PDT 2023
Author: Koakuma
Date: 2023-08-22T12:49:00-04:00
New Revision: c8c5f317e4617062dab61be650cecbda9adb407a
URL: https://github.com/llvm/llvm-project/commit/c8c5f317e4617062dab61be650cecbda9adb407a
DIFF: https://github.com/llvm/llvm-project/commit/c8c5f317e4617062dab61be650cecbda9adb407a.diff
LOG: [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
Added:
llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
Modified:
llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
llvm/lib/Target/Sparc/SparcInstrAliases.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 9bfee26db806d4..bfb62cdae8d449 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -15,6 +15,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
@@ -28,6 +29,7 @@
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
@@ -119,6 +121,9 @@ class SparcAsmParser : public MCTargetAsmParser {
bool expandSET(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions);
+ bool expandSETX(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions);
+
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
public:
@@ -643,6 +648,78 @@ bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
return false;
}
+bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
+ SmallVectorImpl<MCInst> &Instructions) {
+ MCOperand MCRegOp = Inst.getOperand(0);
+ MCOperand MCValOp = Inst.getOperand(1);
+ MCOperand MCTmpOp = Inst.getOperand(2);
+ assert(MCRegOp.isReg() && MCTmpOp.isReg());
+ assert(MCValOp.isImm() || MCValOp.isExpr());
+
+ // the imm operand can be either an expression or an immediate.
+ bool IsImm = MCValOp.isImm();
+ int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
+
+ const MCExpr *ValExpr = IsImm ? MCConstantExpr::create(ImmValue, getContext())
+ : MCValOp.getExpr();
+
+ // Very small immediates can be expressed directly as a single `or`.
+ if (IsImm && isInt<13>(ImmValue)) {
+ // or rd, val, rd
+ Instructions.push_back(MCInstBuilder(SP::ORri)
+ .addReg(MCRegOp.getReg())
+ .addReg(Sparc::G0)
+ .addExpr(ValExpr));
+ return false;
+ }
+
+ // Otherwise, first we set the lower half of the register.
+
+ // sethi %hi(val), rd
+ Instructions.push_back(
+ MCInstBuilder(SP::SETHIi)
+ .addReg(MCRegOp.getReg())
+ .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr)));
+ // or rd, %lo(val), rd
+ Instructions.push_back(
+ MCInstBuilder(SP::ORri)
+ .addReg(MCRegOp.getReg())
+ .addReg(MCRegOp.getReg())
+ .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr)));
+
+ // Small positive immediates can be expressed as a single `sethi`+`or`
+ // combination, so we can just return here.
+ if (IsImm && isUInt<32>(ImmValue))
+ return false;
+
+ // For bigger immediates, we need to generate the upper half, then shift and
+ // merge it with the lower half that has just been generated above.
+
+ // sethi %hh(val), tmp
+ Instructions.push_back(
+ MCInstBuilder(SP::SETHIi)
+ .addReg(MCTmpOp.getReg())
+ .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HH, ValExpr)));
+ // or tmp, %hm(val), tmp
+ Instructions.push_back(
+ MCInstBuilder(SP::ORri)
+ .addReg(MCTmpOp.getReg())
+ .addReg(MCTmpOp.getReg())
+ .addExpr(adjustPICRelocation(SparcMCExpr::VK_Sparc_HM, ValExpr)));
+ // sllx tmp, 32, tmp
+ Instructions.push_back(MCInstBuilder(SP::SLLXri)
+ .addReg(MCTmpOp.getReg())
+ .addReg(MCTmpOp.getReg())
+ .addImm(32));
+ // or tmp, rd, rd
+ Instructions.push_back(MCInstBuilder(SP::ORrr)
+ .addReg(MCRegOp.getReg())
+ .addReg(MCTmpOp.getReg())
+ .addReg(MCRegOp.getReg()));
+
+ return false;
+}
+
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
OperandVector &Operands,
MCStreamer &Out,
@@ -663,6 +740,10 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
if (expandSET(Inst, IDLoc, Instructions))
return true;
break;
+ case SP::SETX:
+ if (expandSETX(Inst, IDLoc, Instructions))
+ return true;
+ break;
}
for (const MCInst &I : Instructions) {
diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index 01c3696cc7bca6..b2a22eb0bd45b9 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -443,6 +443,13 @@ 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">;
+// setx value, tmp, rd
+// (turns into a sequence of sethi+or+shift, depending on the value)
+def SETX : AsmPseudoInst<(outs I64Regs:$rd),
+ (ins i64imm:$val, I64Regs:$tmp),
+ "setx $val, $tmp, $rd">,
+ Requires<[Is64Bit, HasV9]>;
+
// not rd -> xnor rd, %g0, rd
def : InstAlias<"not $rd", (XNORrr IntRegs:$rd, IntRegs:$rd, G0), 0>;
diff --git a/llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s b/llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
new file mode 100644
index 00000000000000..dfaab3fc9b15fb
--- /dev/null
+++ b/llvm/test/MC/Sparc/sparcv9-synthetic-instructions.s
@@ -0,0 +1,80 @@
+! RUN: not llvm-mc %s -arch=sparc -show-encoding 2>&1 | FileCheck %s --check-prefix=V8
+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s --check-prefix=V9
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx 1, %g1, %o1
+! V9: mov 1, %o1 ! encoding: [0x92,0x10,0x20,0x01]
+setx 1, %g1, %o1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx (0+1), %g1, %o1
+! V9: mov 1, %o1 ! encoding: [0x92,0x10,0x20,0x01]
+setx (0+1), %g1, %o1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx -1, %g1, %o1
+! V9: mov -1, %o1 ! encoding: [0x92,0x10,0x3f,0xff]
+setx -1, %g1, %o1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx (0-1), %g1, %o1
+! V9: mov -1, %o1 ! encoding: [0x92,0x10,0x3f,0xff]
+setx (0-1), %g1, %o1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx 0xffffffff, %g1, %o1
+! V9: sethi %hi(4294967295), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(4294967295), kind: fixup_sparc_hi22
+! V9: or %o1, %lo(4294967295), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(4294967295), kind: fixup_sparc_lo10
+setx 0xffffffff, %g1, %o1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx (0xffff0000+0x0000ffff), %g1, %o1
+! V9: sethi %hi(4294967295), %o1 ! encoding: [0x13,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(4294967295), kind: fixup_sparc_hi22
+! V9: or %o1, %lo(4294967295), %o1 ! encoding: [0x92,0x12,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(4294967295), kind: fixup_sparc_lo10
+setx (0xffff0000+0x0000ffff), %g1, %o1
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx 0x0123456789abcdef, %g1, %o0
+! V9: sethi %hi(81985529216486895), %o0 ! encoding: [0x11,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(81985529216486895), kind: fixup_sparc_hi22
+! V9: or %o0, %lo(81985529216486895), %o0 ! encoding: [0x90,0x12,0b001000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(81985529216486895), kind: fixup_sparc_lo10
+! V9: sethi %hh(81985529216486895), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hh(81985529216486895), kind: fixup_sparc_hh
+! V9: or %g1, %hm(81985529216486895), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %hm(81985529216486895), kind: fixup_sparc_hm
+! V9: sllx %g1, 32, %g1 ! encoding: [0x83,0x28,0x70,0x20]
+! V9: or %g1, %o0, %o0 ! encoding: [0x90,0x10,0x40,0x08]
+setx 0x0123456789abcdef, %g1, %o0
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx (0x0123456700000000+0x0000000089abcdef), %g1, %o0
+! V9: sethi %hi(81985529216486895), %o0 ! encoding: [0x11,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(81985529216486895), kind: fixup_sparc_hi22
+! V9: or %o0, %lo(81985529216486895), %o0 ! encoding: [0x90,0x12,0b001000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(81985529216486895), kind: fixup_sparc_lo10
+! V9: sethi %hh(81985529216486895), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hh(81985529216486895), kind: fixup_sparc_hh
+! V9: or %g1, %hm(81985529216486895), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %hm(81985529216486895), kind: fixup_sparc_hm
+! V9: sllx %g1, 32, %g1 ! encoding: [0x83,0x28,0x70,0x20]
+! V9: or %g1, %o0, %o0 ! encoding: [0x90,0x10,0x40,0x08]
+setx (0x0123456700000000+0x0000000089abcdef), %g1, %o0
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V8-NEXT: setx (.BB1-.BB0), %g1, %o0
+! V9: sethi %hi(.BB1-.BB0), %o0 ! encoding: [0x11,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hi(.BB1-.BB0), kind: fixup_sparc_hi22
+! V9: or %o0, %lo(.BB1-.BB0), %o0 ! encoding: [0x90,0x12,0b001000AA,A]
+! V9: ! fixup A - offset: 0, value: %lo(.BB1-.BB0), kind: fixup_sparc_lo10
+! V9: sethi %hh(.BB1-.BB0), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
+! V9: ! fixup A - offset: 0, value: %hh(.BB1-.BB0), kind: fixup_sparc_hh
+! V9: or %g1, %hm(.BB1-.BB0), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
+! V9: ! fixup A - offset: 0, value: %hm(.BB1-.BB0), kind: fixup_sparc_hm
+! V9: sllx %g1, 32, %g1 ! encoding: [0x83,0x28,0x70,0x20]
+! V9: or %g1, %o0, %o0 ! encoding: [0x90,0x10,0x40,0x08]
+setx (.BB1-.BB0), %g1, %o0
More information about the llvm-commits
mailing list