[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