[llvm-branch-commits] [SPARC][IAS] Add definitions for OSA 2011 instructions (PR #138403)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat May 3 06:52:25 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: Koakuma (koachan)

<details>
<summary>Changes</summary>



---

Patch is 56.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138403.diff


15 Files Affected:

- (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def (+1) 
- (modified) llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (+9) 
- (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp (+15) 
- (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp (+2) 
- (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h (+5-1) 
- (modified) llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp (+39) 
- (modified) llvm/lib/Target/Sparc/Sparc.td (+4-1) 
- (modified) llvm/lib/Target/Sparc/SparcInstrAliases.td (+65) 
- (modified) llvm/lib/Target/Sparc/SparcInstrFormats.td (+43) 
- (modified) llvm/lib/Target/Sparc/SparcInstrInfo.td (+16) 
- (modified) llvm/lib/Target/Sparc/SparcInstrUAOSA.td (+105-1) 
- (modified) llvm/test/MC/Disassembler/Sparc/sparc-ua-osa.txt (+176-1) 
- (added) llvm/test/MC/Sparc/sparc-osa2011.s (+274) 
- (removed) llvm/test/MC/Sparc/sparc64-bpr-offset.s (-31) 
- (added) llvm/test/MC/Sparc/sparc64-branch-offset.s (+267) 


``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
index 7e01a4a8a0a06..b87949ab199b5 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
@@ -87,3 +87,4 @@ ELF_RELOC(R_SPARC_GOTDATA_LOX10,  81)
 ELF_RELOC(R_SPARC_GOTDATA_OP_HIX22,  82)
 ELF_RELOC(R_SPARC_GOTDATA_OP_LOX10,  83)
 ELF_RELOC(R_SPARC_GOTDATA_OP,     84)
+ELF_RELOC(R_SPARC_WDISP10, 88)
diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
index 828d638723587..c42e173379a39 100644
--- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
@@ -261,6 +261,8 @@ DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
 
 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,
                                const MCDisassembler *Decoder);
+static DecodeStatus DecodeSIMM5(MCInst &Inst, unsigned insn, uint64_t Address,
+                                const MCDisassembler *Decoder);
 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,
                                  const MCDisassembler *Decoder);
 
@@ -340,6 +342,13 @@ static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeSIMM5(MCInst &MI, unsigned insn, uint64_t Address,
+                                const MCDisassembler *Decoder) {
+  assert(isUInt<5>(insn));
+  MI.addOperand(MCOperand::createImm(SignExtend64<5>(insn)));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,
                                  const MCDisassembler *Decoder) {
   assert(isUInt<13>(insn));
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index cc8b86e6135b5..d37724699be5d 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -50,6 +50,15 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
     return (d16hi << 20) | d16lo;
   }
 
+  case Sparc::fixup_sparc_br10: {
+    // 7.17 Compare and Branch
+    // Inst{20-19} = d10hi;
+    // Inst{12-5}  = d10lo;
+    unsigned d10hi = (Value >> 10) & 0x3;
+    unsigned d10lo = (Value >> 2) & 0xff;
+    return (d10hi << 19) | (d10lo << 5);
+  }
+
   case Sparc::fixup_sparc_hix22:
     return (~Value >> 10) & 0x3fffff;
 
@@ -162,11 +171,13 @@ namespace {
 
     MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {
       const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
+          // clang-format off
         // name                    offset bits  flags
         { "fixup_sparc_call30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_br22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_br19",      13,     19,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_br16",       0,     32,  MCFixupKindInfo::FKF_IsPCRel },
+        { "fixup_sparc_br10",       0,     32,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_13",        19,     13,  0 },
         { "fixup_sparc_hi22",      10,     22,  0 },
         { "fixup_sparc_lo10",      22,     10,  0 },
@@ -205,14 +216,17 @@ namespace {
         { "fixup_sparc_gotdata_hix22",  0,  0,  0 },
         { "fixup_sparc_gotdata_lox10",  0,  0,  0 },
         { "fixup_sparc_gotdata_op",     0,  0,  0 },
+          // clang-format on
       };
 
       const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
+          // clang-format off
         // name                    offset bits  flags
         { "fixup_sparc_call30",     0,     30,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_br22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_br16",      32,      0,  MCFixupKindInfo::FKF_IsPCRel },
+        { "fixup_sparc_br10",      32,      0,  MCFixupKindInfo::FKF_IsPCRel },
         { "fixup_sparc_13",         0,     13,  0 },
         { "fixup_sparc_hi22",       0,     22,  0 },
         { "fixup_sparc_lo10",       0,     10,  0 },
@@ -251,6 +265,7 @@ namespace {
         { "fixup_sparc_gotdata_hix22",  0,  0,  0 },
         { "fixup_sparc_gotdata_lox10",  0,  0,  0 },
         { "fixup_sparc_gotdata_op",     0,  0,  0 },
+          // clang-format on
       };
 
       // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index f95e5ac1664e6..6b6d352c7736b 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -84,6 +84,8 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
     case Sparc::fixup_sparc_br19:    return ELF::R_SPARC_WDISP19;
     case Sparc::fixup_sparc_br16:
       return ELF::R_SPARC_WDISP16;
+    case Sparc::fixup_sparc_br10:
+      return ELF::R_SPARC_WDISP10;
     case Sparc::fixup_sparc_pc22:    return ELF::R_SPARC_PC22;
     case Sparc::fixup_sparc_pc10:    return ELF::R_SPARC_PC10;
     case Sparc::fixup_sparc_wplt30:  return ELF::R_SPARC_WPLT30;
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
index 3b91326589894..ec8f78cd63812 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -11,6 +11,7 @@
 
 #include "llvm/MC/MCFixup.h"
 
+// clang-format off
 namespace llvm {
   namespace Sparc {
     enum Fixups {
@@ -28,6 +29,9 @@ namespace llvm {
       /// fixup_sparc_bpr  - 16-bit fixup for bpr
       fixup_sparc_br16,
 
+      /// fixup_sparc_br10  - 10-bit fixup for cbcond
+      fixup_sparc_br10,
+
       /// fixup_sparc_13 - 13-bit fixup
       fixup_sparc_13,
 
@@ -112,5 +116,5 @@ namespace llvm {
     };
   }
 }
-
+// clang-format on
 #endif
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index 0c9ba6a8a297c..06721db60cdd6 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -71,6 +71,9 @@ class SparcMCCodeEmitter : public MCCodeEmitter {
   unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
+  unsigned getSImm5OpValue(const MCInst &MI, unsigned OpNo,
+                           SmallVectorImpl<MCFixup> &Fixups,
+                           const MCSubtargetInfo &STI) const;
   unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;
@@ -80,6 +83,9 @@ class SparcMCCodeEmitter : public MCCodeEmitter {
   unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const;
+  unsigned getCompareAndBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
+                                            SmallVectorImpl<MCFixup> &Fixups,
+                                            const MCSubtargetInfo &STI) const;
 };
 
 } // end anonymous namespace
@@ -141,6 +147,26 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   return 0;
 }
 
+unsigned SparcMCCodeEmitter::getSImm5OpValue(const MCInst &MI, unsigned OpNo,
+                                             SmallVectorImpl<MCFixup> &Fixups,
+                                             const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+
+  if (MO.isImm())
+    return MO.getImm();
+
+  assert(MO.isExpr() &&
+         "getSImm5OpValue expects only expressions or an immediate");
+
+  const MCExpr *Expr = MO.getExpr();
+
+  // Constant value, no fixup is needed
+  if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
+    return CE->getValue();
+
+  llvm_unreachable("simm5 operands can only be used with constants!");
+}
+
 unsigned
 SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
                                      SmallVectorImpl<MCFixup> &Fixups,
@@ -239,6 +265,19 @@ getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
   return 0;
 }
 
+unsigned SparcMCCodeEmitter::getCompareAndBranchTargetOpValue(
+    const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
+    const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  if (MO.isReg() || MO.isImm())
+    return getMachineOpValue(MI, MO, Fixups, STI);
+
+  Fixups.push_back(
+      MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br10));
+
+  return 0;
+}
+
 #include "SparcGenMCCodeEmitter.inc"
 
 MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 93c3098bd89fe..6e6c887e60e12 100644
--- a/llvm/lib/Target/Sparc/Sparc.td
+++ b/llvm/lib/Target/Sparc/Sparc.td
@@ -55,6 +55,9 @@ def FeatureUA2005
 def FeatureUA2007
   : SubtargetFeature<"ua2007", "IsUA2007", "true",
                      "Enable UltraSPARC Architecture 2007 extensions">;
+def FeatureOSA2011
+  : SubtargetFeature<"osa2011", "IsOSA2011", "true",
+                     "Enable Oracle SPARC Architecture 2011 extensions">;
 def FeatureLeon
   : SubtargetFeature<"leon", "IsLeon", "true",
                      "Enable LEON extensions">;
@@ -166,7 +169,7 @@ def : Proc<"niagara3",        [FeatureV9, FeatureV8Deprecated, UsePopc,
                                FeatureUA2005, FeatureUA2007]>;
 def : Proc<"niagara4",        [FeatureV9, FeatureV8Deprecated, UsePopc,
                                FeatureVIS, FeatureVIS2, FeatureVIS3,
-                               FeatureUA2005, FeatureUA2007]>;
+                               FeatureUA2005, FeatureUA2007, FeatureOSA2011]>;
 
 // LEON 2 FT generic
 def : Processor<"leon2", LEON2Itineraries,
diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index 590395c16965b..fa2c62101d30e 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -331,6 +331,25 @@ multiclass reg_cond_alias<string rcond, int condVal> {
                             Requires<[Is64Bit]>;
 }
 
+// Instruction aliases for compare-and-branch.
+multiclass cwb_cond_alias<string cond, int condVal> {
+  def : InstAlias<!strconcat(!strconcat("cwb", cond), " $rs1, $rs2, $imm"),
+                  (CWBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
+                  Requires<[HasOSA2011]>;
+  def : InstAlias<!strconcat(!strconcat("cwb", cond), " $rs1, $simm5, $imm"),
+                  (CWBCONDri cbtarget:$imm, condVal, IntRegs:$rs1, simm5Op:$simm5)>,
+                  Requires<[HasOSA2011]>;
+}
+
+multiclass cxb_cond_alias<string cond, int condVal> {
+  def : InstAlias<!strconcat(!strconcat("cxb", cond), " $rs1, $rs2, $imm"),
+                  (CXBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
+                  Requires<[HasOSA2011]>;
+  def : InstAlias<!strconcat(!strconcat("cxb", cond), " $rs1, $simm5, $imm"),
+                  (CXBCONDri cbtarget:$imm, condVal, IntRegs:$rs1, simm5Op:$simm5)>,
+                  Requires<[HasOSA2011]>;
+}
+
 defm : int_cond_alias<"a",    0b1000>;
 defm : int_cond_alias<"n",    0b0000>;
 defm : int_cond_alias<"ne",   0b1001>;
@@ -408,6 +427,46 @@ defm : reg_cond_alias<"ne",   0b101>;
 defm : reg_cond_alias<"gz",   0b110>;
 defm : reg_cond_alias<"gez",  0b111>;
 
+defm : cwb_cond_alias<"ne",   0b1001>;
+defm : cwb_cond_alias<"e",    0b0001>;
+defm : cwb_cond_alias<"g",    0b1010>;
+defm : cwb_cond_alias<"le",   0b0010>;
+defm : cwb_cond_alias<"ge",   0b1011>;
+defm : cwb_cond_alias<"l",    0b0011>;
+defm : cwb_cond_alias<"gu",   0b1100>;
+defm : cwb_cond_alias<"leu",  0b0100>;
+defm : cwb_cond_alias<"cc",   0b1101>;
+defm : cwb_cond_alias<"cs",   0b0101>;
+defm : cwb_cond_alias<"pos",  0b1110>;
+defm : cwb_cond_alias<"neg",  0b0110>;
+defm : cwb_cond_alias<"vc",   0b1111>;
+defm : cwb_cond_alias<"vs",   0b0111>;
+let EmitPriority = 0 in
+{
+  defm : cwb_cond_alias<"geu",  0b1101>; // same as cc
+  defm : cwb_cond_alias<"lu",   0b0101>; // same as cs
+}
+
+defm : cxb_cond_alias<"ne",   0b1001>;
+defm : cxb_cond_alias<"e",    0b0001>;
+defm : cxb_cond_alias<"g",    0b1010>;
+defm : cxb_cond_alias<"le",   0b0010>;
+defm : cxb_cond_alias<"ge",   0b1011>;
+defm : cxb_cond_alias<"l",    0b0011>;
+defm : cxb_cond_alias<"gu",   0b1100>;
+defm : cxb_cond_alias<"leu",  0b0100>;
+defm : cxb_cond_alias<"cc",   0b1101>;
+defm : cxb_cond_alias<"cs",   0b0101>;
+defm : cxb_cond_alias<"pos",  0b1110>;
+defm : cxb_cond_alias<"neg",  0b0110>;
+defm : cxb_cond_alias<"vc",   0b1111>;
+defm : cxb_cond_alias<"vs",   0b0111>;
+let EmitPriority = 0 in
+{
+  defm : cxb_cond_alias<"geu",  0b1101>; // same as cc
+  defm : cxb_cond_alias<"lu",   0b0101>; // same as cs
+}
+
 // Section A.3 Synthetic Instructions
 
 // Most are marked as Emit=0, so that they are not used for disassembly. This is
@@ -665,3 +724,9 @@ def : InstAlias<"signx $rs1, $rd", (SRArr IntRegs:$rd, IntRegs:$rs1, G0), 0>, Re
 
 // sir -> sir 0
 def : InstAlias<"sir", (SIR 0), 0>;
+
+// pause reg_or_imm -> wrasr %g0, reg_or_imm, %asr27
+let Predicates = [HasOSA2011] in {
+def : InstAlias<"pause $rs2", (WRASRrr ASR27, G0, IntRegs:$rs2), 1>;
+def : InstAlias<"pause $simm13", (WRASRri ASR27, G0, simm13Op:$simm13), 1>;
+} // Predicates = [HasOSA2011]
diff --git a/llvm/lib/Target/Sparc/SparcInstrFormats.td b/llvm/lib/Target/Sparc/SparcInstrFormats.td
index 2998f53ef2dbc..fe10bb443348a 100644
--- a/llvm/lib/Target/Sparc/SparcInstrFormats.td
+++ b/llvm/lib/Target/Sparc/SparcInstrFormats.td
@@ -102,6 +102,49 @@ class F2_4<bit annul, bit pred, dag outs, dag ins,
   let Inst{13-0}  = imm16{13-0};
 }
 
+class F2_5<bit cc, dag outs, dag ins, string asmstr,
+           list<dag> pattern = [], InstrItinClass itin = NoItinerary>
+   : InstSP<outs, ins, asmstr, pattern, itin> {
+  bits<10> imm10;
+  bits<5>  rs1;
+  bits<5>  rs2;
+  bits<4>  cond;
+
+  let op          = 0; // op = 0
+
+  let Inst{29}    = cond{3};
+  let Inst{28}    = 1;
+  let Inst{27-25} = cond{2-0};
+  let Inst{24-22} = 0b011;
+  let Inst{21}    = cc;
+  let Inst{20-19} = imm10{9-8};
+  let Inst{18-14} = rs1;
+  let Inst{13}    = 0; // i = 0
+  let Inst{12-5}  = imm10{7-0};
+  let Inst{4-0}   = rs2;
+}
+
+class F2_6<bit cc, dag outs, dag ins, string asmstr,
+           list<dag> pattern = [], InstrItinClass itin = NoItinerary>
+   : InstSP<outs, ins, asmstr, pattern, itin> {
+  bits<10> imm10;
+  bits<5>  rs1;
+  bits<5>  simm5;
+  bits<4>  cond;
+
+  let op          = 0; // op = 0
+
+  let Inst{29}    = cond{3};
+  let Inst{28}    = 1;
+  let Inst{27-25} = cond{2-0};
+  let Inst{24-22} = 0b011;
+  let Inst{21}    = cc;
+  let Inst{20-19} = imm10{9-8};
+  let Inst{18-14} = rs1;
+  let Inst{13}    = 1; // i = 1
+  let Inst{12-5}  = imm10{7-0};
+  let Inst{4-0}   = simm5;
+}
 
 //===----------------------------------------------------------------------===//
 // Format #3 instruction classes in the Sparc
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 057eafd734e71..c14d72b33c08c 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -55,6 +55,10 @@ def HasUA2005 : Predicate<"Subtarget->isUA2005()">,
 def HasUA2007 : Predicate<"Subtarget->isUA2007()">,
                 AssemblerPredicate<(all_of FeatureUA2007)>;
 
+// HasOSA2011 - This is true when the target processor has OSA 2011 extensions.
+def HasOSA2011 : Predicate<"Subtarget->isOSA2011()">,
+                AssemblerPredicate<(all_of FeatureOSA2011)>;
+
 // HasHardQuad - This is true when the target processor supports quad floating
 // point instructions.
 def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
@@ -93,6 +97,8 @@ def UseDeprecatedInsts : Predicate<"Subtarget->useV8DeprecatedInsts()">;
 // FIXME these should have AsmOperandClass.
 def uimm3 : PatLeaf<(imm), [{ return isUInt<3>(N->getZExtValue()); }]>;
 
+def simm5  : PatLeaf<(imm), [{ return isInt<5>(N->getSExtValue()); }]>;
+
 def simm10  : PatLeaf<(imm), [{ return isInt<10>(N->getSExtValue()); }]>;
 
 def simm11  : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>;
@@ -231,6 +237,10 @@ def bprtarget16 : Operand<OtherVT> {
   let EncoderMethod = "getBranchOnRegTargetOpValue";
 }
 
+def cbtarget : Operand<OtherVT> {
+  let EncoderMethod = "getCompareAndBranchTargetOpValue";
+}
+
 def SparcCallTargetAsmOperand : AsmOperandClass {
   let Name = "CallTarget";
   let ParserMethod = "parseCallTarget";
@@ -242,6 +252,12 @@ def calltarget : Operand<i32> {
   let ParserMatchClass = SparcCallTargetAsmOperand;
 }
 
+def simm5Op : Operand<iPTR> {
+  let OperandType = "OPERAND_IMMEDIATE";
+  let DecoderMethod = "DecodeSIMM5";
+  let EncoderMethod = "getSImm5OpValue";
+}
+
 def simm13Op : Operand<iPTR> {
   let OperandType = "OPERAND_IMMEDIATE";
   let DecoderMethod = "DecodeSIMM13";
diff --git a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
index a1bfcc3dbb652..4da489d23fe43 100644
--- a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
+++ b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This file contains instruction formats, definitions and patterns needed for
-// UA 2005 and UA 2007 instructions on SPARC.
+// UA 2005, UA 2007, and OSA 2011 instructions on SPARC.
 //===----------------------------------------------------------------------===//
 
 // Convenience template for 4-operand instructions
@@ -16,6 +16,21 @@ class FourOp<string OpcStr, bits<6> op3val, bits<4> op5val,
       : F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, RC:$rs3),
         !strconcat(OpcStr, " $rs1, $rs2, $rs3, $rd")>;
 
+class FourOpImm<string OpcStr, bits<6> op3val, bits<4> op5val,
+        RegisterClass RC>
+      : F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, simm5Op:$rs3),
+        !strconcat(OpcStr, " $rs1, $rs2, $rs3, $rd")>;
+
+/// F2_56 multiclass - Define a F2_5/F2_6 pattern in one shot.
+multiclass F2_56<string OpcStr, bits<1> cc> {
+  def rr  : F2_5<cc, (outs),
+                 (ins cbtarget:$imm10, CCOp:$cond, IntRegs:$rs1, IntRegs:$rs2),
+                 !strconcat(OpcStr, "$cond $rs1, $rs2, $imm10")>;
+  def ri  : F2_6<cc, (outs),
+                 (ins cbtarget:$imm10, CCOp:$cond, IntRegs:$rs1, simm5Op:$simm5),
+                 !strconcat(OpcStr, "$cond $rs1, $simm5, $imm10")>;
+}
+
 // UltraSPARC Architecture 2005 Instructions
 let Predicates = [HasUA2005] in {
 let hasSideEffects = 1 in
@@ -38,3 +53,92 @@ def FNMADDD : FourOp<"fnmaddd", 0b110111, 0b1110, DFPRegs>;
 def FNMSUBS : FourOp<"fnmsubs", 0b110111, 0b1001, FPRegs>;
 def FNMSUBD : FourOp<"fnmsubd", 0b110111, 0b1010, DFPRegs>;
 } // Predicates = [HasUA2007]
+
+// Oracle SPARC Architecture 2011 Instructions
+let Predicates = [HasOSA2011] in {
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in {
+defm CWBCOND : F2_56<"cwb", 0>;
+defm CXBCOND : F2_56<"cxb", 1>;
+}
+
+def FPMADDX   : FourOp<"fpmaddx", 0b110111, 0b0000, DFPRegs>;
+def FPMADDXHI : FourOp<"fpmaddxhi", 0b110111, 0b0100, DFPRegs>;
+
+def AES_EROUND01 : FourOp<"aes_eround01", 0b011001, 0b0000, DFPRegs>;
+def AES_EROUND23 : FourOp<"aes_eround23", 0b011001, 0b0001, DFPRegs>;
+def AES_DROUND01 : FourOp<"aes_dround01", 0b011001, 0b0010, DFPRegs>;
+def AES_DROUND23 : FourOp<"aes_dround23", 0b011001, 0b0011, DFPRegs>;
+def AES_EROUND01_LAST : FourOp<"aes_eround01_l", 0b011001, 0b0100, DFPRegs>;
+def AES_EROUND23_LAST : FourOp<"aes_eround23_l", 0b011001, 0b0101, DFPRegs>;
+def AES_DROUND01_LAST : FourOp<"aes_dround01_l", 0b011001, 0b0110, D...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/138403


More information about the llvm-branch-commits mailing list