[llvm] f1246e9 - [SPARC][IAS] Add support for the full set of CAS instructions

Brad Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 5 01:51:28 PDT 2023


Author: Koakuma
Date: 2023-09-05T04:40:04-04:00
New Revision: f1246e90c023007e2f388787160dbe9234b203fc

URL: https://github.com/llvm/llvm-project/commit/f1246e90c023007e2f388787160dbe9234b203fc
DIFF: https://github.com/llvm/llvm-project/commit/f1246e90c023007e2f388787160dbe9234b203fc.diff

LOG: [SPARC][IAS] Add support for the full set of CAS instructions

This completes the support for the CAS instructions.

Besides the base CASA and CASXA forms, on v9 the aliases CAS, CASX, CASL, and
CASXL are also available.

Reviewed By: barannikov88

Differential Revision: https://reviews.llvm.org/D157234

Added: 
    llvm/test/MC/Disassembler/Sparc/sparc-atomics.txt
    llvm/test/MC/Sparc/sparc-cas-instructions.s

Modified: 
    llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
    llvm/lib/Target/Sparc/SparcInstr64Bit.td
    llvm/lib/Target/Sparc/SparcInstrFormats.td
    llvm/lib/Target/Sparc/SparcInstrInfo.td
    llvm/test/MC/Sparc/leon-instructions.s
    llvm/test/MC/Sparc/sparcv9-atomic-instructions.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 69476129abbff5e..adeebf535be95f0 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -1175,7 +1175,8 @@ SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
                                                  Parser.getTok().getLoc()));
     Parser.Lex(); // Eat the [
 
-    if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
+    if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||
+        Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {
       SMLoc S = Parser.getTok().getLoc();
       if (getLexer().getKind() != AsmToken::Percent)
         return MatchOperand_NoMatch;

diff  --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td
index 4b8793d1e7132f9..6ddb1cc3afb0da8 100644
--- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td
+++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td
@@ -475,14 +475,34 @@ def SETHIXi : F2_1<0b100,
 }
 
 // ATOMICS.
-let Predicates = [Is64Bit], Constraints = "$swap = $rd", asi = 0b10000000 in {
-  def CASXrr: F3_1_asi<3, 0b111110,
+let Predicates = [Is64Bit, HasV9], Constraints = "$swap = $rd" in {
+  let asi = 0b10000000 in
+    def CASXrr: F3_1_asi<3, 0b111110,
                 (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
                                      I64Regs:$swap),
                  "casx [$rs1], $rs2, $rd",
                  [(set i64:$rd,
                      (atomic_cmp_swap_64 i64:$rs1, i64:$rs2, i64:$swap))]>;
 
+  let asi = 0b10001000 in
+    def CASXLrr: F3_1_asi<3, 0b111110,
+                (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
+                                     I64Regs:$swap),
+                 "casxl [$rs1], $rs2, $rd",
+                 []>;
+
+  def CASXArr: F3_1_asi<3, 0b111110,
+                (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
+                                     I64Regs:$swap, ASITag:$asi),
+                 "casxa [$rs1] $asi, $rs2, $rd",
+                 []>;
+
+  let Uses = [ASR3] in
+    def CASXAri: F3_1_cas_asi<3, 0b111110,
+                (outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
+                                     I64Regs:$swap),
+                 "casxa [$rs1] %asi, $rs2, $rd",
+                 []>;
 } // Predicates = [Is64Bit], Constraints = ...
 
 let Predicates = [Is64Bit] in {

diff  --git a/llvm/lib/Target/Sparc/SparcInstrFormats.td b/llvm/lib/Target/Sparc/SparcInstrFormats.td
index c67b591ab98ac9e..3939f4ed942763c 100644
--- a/llvm/lib/Target/Sparc/SparcInstrFormats.td
+++ b/llvm/lib/Target/Sparc/SparcInstrFormats.td
@@ -135,6 +135,14 @@ class F3_1_asi<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
   let Inst{4-0}  = rs2;
 }
 
+// CAS instructions does not use an immediate even when i=1
+class F3_1_cas_asi<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
+           string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
+   : F3_1_asi<opVal, op3val, outs, ins, asmstr, pattern, itin> {
+  let asi = 0;
+  let Inst{13}   = 1;     // i field = 1
+}
+
 class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins, string asmstr,
        list<dag> pattern, InstrItinClass itin = IIC_iu_instr>
   : F3_1_asi<opVal, op3val, outs, ins, asmstr, pattern, itin> {

diff  --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 6940a2a0266450d..1d625b608a2b5e2 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -51,10 +51,14 @@ def HasVIS3 : Predicate<"Subtarget->isVIS3()">,
 // point instructions.
 def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
 
-// HasLeonCASA - This is true when the target processor supports the CASA
-// instruction
+// HasLeonCASA - This is true when the target processor supports the Leon CASA
+// instruction.
 def HasLeonCASA : Predicate<"Subtarget->hasLeonCasa()">;
 
+// HasCASA - This is true when the target processor supports CASA instruction.
+def HasCASA : Predicate<"Subtarget->hasLeonCasa() || Subtarget->isV9()">,
+              AssemblerPredicate<(any_of LeonCASA, FeatureV9)>;
+
 // HasPWRPSR - This is true when the target processor supports partial
 // writes to the PSR register that only affects the ET field.
 def HasPWRPSR : Predicate<"Subtarget->hasPWRPSR()">,
@@ -1700,16 +1704,26 @@ let Predicates = [HasV9], rd = 15, rs1 = 0b00000 in
                  "sir $simm13", []>;
 
 // The CAS instruction, unlike other instructions, only comes in a
-// form which requires an ASI be provided. The ASI value hardcoded
-// here is ASI_PRIMARY, the default unprivileged ASI for SparcV9.
-let Predicates = [HasV9], Constraints = "$swap = $rd", asi = 0b10000000 in
-  def CASrr: F3_1_asi<3, 0b111100,
+// form which requires an ASI be provided.
+let Predicates = [HasV9], Constraints = "$swap = $rd" in {
+  // The ASI value hardcoded here is ASI_PRIMARY, the default
+  // unprivileged ASI for SparcV9.
+  let asi = 0b10000000 in
+    def CASrr: F3_1_asi<3, 0b111100,
                 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
                                      IntRegs:$swap),
                  "cas [$rs1], $rs2, $rd",
                  [(set i32:$rd,
                      (atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>;
 
+  // SparcV9 also specifies a CASL alias, which uses ASI_PRIMARY_LITTLE.
+  let asi = 0b10001000 in
+    def CASLrr: F3_1_asi<3, 0b111100,
+                (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
+                                     IntRegs:$swap),
+                 "casl [$rs1], $rs2, $rd",
+                 []>;
+}
 
 // CASA is supported as an instruction on some LEON3 and all LEON4 processors.
 // This version can be automatically lowered from C code, selecting ASI 10
@@ -1721,15 +1735,23 @@ let Predicates = [HasLeonCASA], Constraints = "$swap = $rd", asi = 0b00001010 in
                  [(set i32:$rd,
                      (atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>;
 
-// CASA supported on some LEON3 and all LEON4 processors. Same pattern as
-// CASrr, above, but with a 
diff erent ASI. This version is supported for
-// inline assembly lowering only.
-let Predicates = [HasLeonCASA], Constraints = "$swap = $rd" in
+// CASA supported on all V9, some LEON3 and all LEON4 processors.
+// Same pattern as CASrr above, but with a 
diff erent ASI.
+// This version is supported for inline assembly lowering only.
+let Predicates = [HasCASA], Constraints = "$swap = $rd" in
   def CASArr: F3_1_asi<3, 0b111100,
                 (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
                                      IntRegs:$swap, ASITag:$asi),
                  "casa [$rs1] $asi, $rs2, $rd", []>;
 
+// On the other hand, CASA that takes its ASI from a register
+// is only supported on V9 processors.
+let Predicates = [HasV9], Uses = [ASR3], Constraints = "$swap = $rd" in
+  def CASAri: F3_1_cas_asi<3, 0b111100,
+                (outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
+                                     IntRegs:$swap),
+                 "casa [$rs1] %asi, $rs2, $rd", []>;
+
 // TODO: Add DAG sequence to lower these instructions. Currently, only provided
 // as inline assembler-supported instructions.
 let Predicates = [HasUMAC_SMAC], Defs = [Y, ASR18], Uses = [Y, ASR18] in {

diff  --git a/llvm/test/MC/Disassembler/Sparc/sparc-atomics.txt b/llvm/test/MC/Disassembler/Sparc/sparc-atomics.txt
new file mode 100644
index 000000000000000..289eed0e83a1d1f
--- /dev/null
+++ b/llvm/test/MC/Disassembler/Sparc/sparc-atomics.txt
@@ -0,0 +1,25 @@
+# RUN: llvm-mc --disassemble %s -triple=sparcv9-unknown-linux | FileCheck %s
+
+# CHECK: cas [%i0], %l6, %o2
+0xd5,0xe6,0x10,0x16
+
+# CHECK: casl [%i0], %l6, %o2
+0xd5,0xe6,0x11,0x16
+
+# CHECK: casa [%i0] 255, %l6, %o2
+0xd5,0xe6,0x1f,0xf6
+
+# CHECK: casa [%i0] %asi, %l6, %o2
+0xd5,0xe6,0x20,0x16
+
+# CHECK: casx [%i0], %l6, %o2
+0xd5,0xf6,0x10,0x16
+
+# CHECK: casxl [%i0], %l6, %o2
+0xd5,0xf6,0x11,0x16
+
+# CHECK: casxa [%i0] 255, %l6, %o2
+0xd5,0xf6,0x1f,0xf6
+
+# CHECK: casxa [%i0] %asi, %l6, %o2
+0xd5,0xf6,0x20,0x16

diff  --git a/llvm/test/MC/Sparc/leon-instructions.s b/llvm/test/MC/Sparc/leon-instructions.s
index 78a6d750a87d452..210231a1a7d7edc 100644
--- a/llvm/test/MC/Sparc/leon-instructions.s
+++ b/llvm/test/MC/Sparc/leon-instructions.s
@@ -1,20 +1,11 @@
-! RUN: llvm-mc %s -arch=sparc -mcpu=leon3 -show-encoding | FileCheck %s -check-prefix=CHECK_NO_CASA
-! RUN: llvm-mc %s -arch=sparc -mcpu=ut699 -show-encoding | FileCheck %s -check-prefix=CHECK_NO_CASA
+! RUN: llvm-mc %s -arch=sparc -mcpu=leon3 -show-encoding | FileCheck %s
+! RUN: llvm-mc %s -arch=sparc -mcpu=ut699 -show-encoding | FileCheck %s
 ! RUN: llvm-mc %s -arch=sparc -mcpu=gr712rc -show-encoding | FileCheck %s
 ! RUN: llvm-mc %s -arch=sparc -mcpu=leon4 -show-encoding | FileCheck %s
 ! RUN: llvm-mc %s -arch=sparc -mcpu=gr740 -show-encoding | FileCheck %s
 
-
-        ! CHECK: casa [%i0] 10, %l6, %o2    ! encoding: [0xd5,0xe6,0x01,0x56]
-        casa [%i0] 10, %l6, %o2
-
-        ! CHECK: casa [%i0] 5, %l6, %o2    ! encoding: [0xd5,0xe6,0x00,0xb6]
-        casa [%i0] 5, %l6, %o2
-
         ! CHECK: umac %i0, %l6, %o2    ! encoding: [0x95,0xf6,0x00,0x16]
-        ! CHECK_NO_CASA: umac %i0, %l6, %o2    ! encoding: [0x95,0xf6,0x00,0x16]
         umac %i0, %l6, %o2
 
         ! CHECK: smac %i0, %l6, %o2    ! encoding: [0x95,0xfe,0x00,0x16]
-        ! CHECK_NO_CASA: smac %i0, %l6, %o2    ! encoding: [0x95,0xfe,0x00,0x16]
         smac %i0, %l6, %o2

diff  --git a/llvm/test/MC/Sparc/sparc-cas-instructions.s b/llvm/test/MC/Sparc/sparc-cas-instructions.s
new file mode 100644
index 000000000000000..8d062932d9a6438
--- /dev/null
+++ b/llvm/test/MC/Sparc/sparc-cas-instructions.s
@@ -0,0 +1,53 @@
+! RUN: not llvm-mc %s -arch=sparc -show-encoding 2>&1 | FileCheck %s --check-prefix=V8
+! RUN: not llvm-mc %s -arch=sparc -mattr=+hasleoncasa -show-encoding 2>&1 | FileCheck %s --check-prefix=LEON
+! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s --check-prefix=V9
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: cas [%i0], %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
+! LEON: error: instruction requires a CPU feature not currently enabled
+cas [%i0], %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casl [%i0], %l6, %o2   ! encoding: [0xd5,0xe6,0x11,0x16]
+! LEON: error: instruction requires a CPU feature not currently enabled
+casl [%i0], %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casx [%i0], %l6, %o2  ! encoding: [0xd5,0xf6,0x10,0x16]
+! LEON: error: instruction requires a CPU feature not currently enabled
+casx [%i0], %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casxl [%i0], %l6, %o2  ! encoding: [0xd5,0xf6,0x11,0x16]
+! LEON: error: instruction requires a CPU feature not currently enabled
+casxl [%i0], %l6, %o2
+
+! V8: error: malformed ASI tag, must be a constant integer expression
+! V9: casxa [%i0] %asi, %l6, %o2   ! encoding: [0xd5,0xf6,0x20,0x16]
+! LEON: error: malformed ASI tag, must be a constant integer expression
+casxa [%i0] %asi, %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casxa [%i0] 128, %l6, %o2   ! encoding: [0xd5,0xf6,0x10,0x16]
+! LEON: error: instruction requires a CPU feature not currently enabled
+casxa [%i0] 0x80, %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casxa [%i0] 128, %l6, %o2   ! encoding: [0xd5,0xf6,0x10,0x16]
+! LEON: error: instruction requires a CPU feature not currently enabled
+casxa [%i0] (0x40+0x40), %l6, %o2
+
+! V8: error: malformed ASI tag, must be a constant integer expression
+! V9: casa [%i0] %asi, %l6, %o2   ! encoding: [0xd5,0xe6,0x20,0x16]
+! LEON: error: malformed ASI tag, must be a constant integer expression
+casa [%i0] %asi, %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casa [%i0] 128, %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
+! LEON: casa [%i0] 128, %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
+casa [%i0] 0x80, %l6, %o2
+
+! V8: error: instruction requires a CPU feature not currently enabled
+! V9: casa [%i0] 128, %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
+! LEON: casa [%i0] 128, %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
+casa [%i0] (0x40+0x40), %l6, %o2

diff  --git a/llvm/test/MC/Sparc/sparcv9-atomic-instructions.s b/llvm/test/MC/Sparc/sparcv9-atomic-instructions.s
index 14f685c5f0a1108..4d28907fb863bd9 100644
--- a/llvm/test/MC/Sparc/sparcv9-atomic-instructions.s
+++ b/llvm/test/MC/Sparc/sparcv9-atomic-instructions.s
@@ -17,9 +17,3 @@
 
         ! CHECK: ldstuba [%i0+2] %asi, %g1 ! encoding: [0xc2,0xee,0x20,0x02]
         ldstuba [%i0+2] %asi, %g1
-
-        ! CHECK: cas [%i0], %l6, %o2   ! encoding: [0xd5,0xe6,0x10,0x16]
-        cas [%i0], %l6, %o2
-
-        ! CHECK: casx [%i0], %l6, %o2  ! encoding: [0xd5,0xf6,0x10,0x16]
-        casx [%i0], %l6, %o2


        


More information about the llvm-commits mailing list