[llvm] 29f630a - [RISCV][MC] MC layer support for the experimental zacas extension

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 10 00:27:06 PDT 2023


Author: Alex Bradbury
Date: 2023-07-10T08:26:31+01:00
New Revision: 29f630a1ddcbb03caa31b5002f0cbc105ff3a869

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

LOG: [RISCV][MC] MC layer support for the experimental zacas extension

This implements the v1.0-rc1 draft extension.

amocas.d on RV32 and amocas.q have the restriction that rd and rs2 must
be even registers. I've opted to implement this restriction in
RISCVAsmParser::validateInstruction even though for codegen we'll need a
new register class and can then remove this validation. This also
sidesteps, for now, the issue of amocas.d being different on rv32 vs
rv64.

See <https://github.com/riscv-non-isa/riscv-c-api-doc/issues/37> for the
issue of needing an agreed asm register constraint for register pairs.

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

Added: 
    llvm/test/MC/RISCV/rv32zacas-invalid.s
    llvm/test/MC/RISCV/rv32zacas-valid.s
    llvm/test/MC/RISCV/rv64zacas-invalid.s
    llvm/test/MC/RISCV/rv64zacas-valid.s

Modified: 
    clang/test/Preprocessor/riscv-target-features.c
    llvm/docs/RISCVUsage.rst
    llvm/docs/ReleaseNotes.rst
    llvm/lib/Support/RISCVISAInfo.cpp
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/RISCVFeatures.td
    llvm/lib/Target/RISCV/RISCVInstrInfoA.td
    llvm/test/CodeGen/RISCV/attributes.ll
    llvm/test/MC/RISCV/attribute-arch.s

Removed: 
    


################################################################################
diff  --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 9de44408b74f5c..27c089494de177 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -72,6 +72,7 @@
 // CHECK-NOT: __riscv_zfbfmin {{.*$}}
 // CHECK-NOT: __riscv_zvfbfmin {{.*$}}
 // CHECK-NOT: __riscv_zvfbfwma {{.*$}}
+// CHECK-NOT: __riscv_zacas {{.*$}}
 
 // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \
 // RUN: -o - | FileCheck %s
@@ -771,3 +772,11 @@
 // RUN: | FileCheck --check-prefix=CHECK-COMBINE-INTO-ZVKSG %s
 // CHECK-COMBINE-INTO-ZVKSG: __riscv_zvks 1000000{{$}}
 // CHECK-COMBINE-INTO-ZVKSG: __riscv_zvksg 1000000{{$}}
+
+// RUN: %clang -target riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zacas1p0 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// RUN: %clang -target riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zacas1p0 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// CHECK-ZACAS-EXT: __riscv_zacas 1000000{{$}}

diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 2f1942d75058ac..be71a9e028acd7 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -191,6 +191,9 @@ The primary goal of experimental support is to assist in the process of ratifica
 ``experimental-ssaia``
   LLVM implements the `Ratification candidate 3 <https://github.com/riscv/riscv-aia/releases/tag/1.0-RC3>`_.
 
+``experimental-zacas``
+  LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.
+
 ``experimental-zfa``
   LLVM implements the `0.2 draft specification <https://github.com/riscv/riscv-isa-manual/releases/download/draft-20230131-c0b298a/zfa-20230414.pdf>`__.
 

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 4016e1badcbcc6..606adc92f910d6 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -253,6 +253,8 @@ Changes to the RISC-V Backend
 * Assembly support was added for the experimental Zfbfmin (scalar BF16
   conversions), Zvfbfmin (vector BF16 conversions), and Zvfbfwma (vector BF16
   widening mul-add) extensions.
+* Added assembler/disassembler support for the experimental Zacas (atomic
+  compare-and-swap) extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------

diff  --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 720ed06ecf7f65..3cd1ff4c02e3f4 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -153,6 +153,8 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"smaia", RISCVExtensionVersion{1, 0}},
     {"ssaia", RISCVExtensionVersion{1, 0}},
 
+    {"zacas", RISCVExtensionVersion{1, 0}},
+
     {"zfa", RISCVExtensionVersion{0, 2}},
     {"zfbfmin", RISCVExtensionVersion{0, 6}},
 
@@ -944,6 +946,7 @@ static const char *ImpliedExtsF[] = {"zicsr"};
 static const char *ImpliedExtsV[] = {"zvl128b", "zve64d"};
 static const char *ImpliedExtsXTHeadVdot[] = {"v"};
 static const char *ImpliedExtsXsfvcp[] = {"zve32x"};
+static const char *ImpliedExtsZacas[] = {"a"};
 static const char *ImpliedExtsZcb[] = {"zca"};
 static const char *ImpliedExtsZcmp[] = {"zca"};
 static const char *ImpliedExtsZcmt[] = {"zca"};
@@ -1006,6 +1009,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
     {{"v"}, {ImpliedExtsV}},
     {{"xsfvcp"}, {ImpliedExtsXsfvcp}},
     {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
+    {{"zacas"}, {ImpliedExtsZacas}},
     {{"zcb"}, {ImpliedExtsZcb}},
     {{"zcmp"}, {ImpliedExtsZcmp}},
     {{"zcmt"}, {ImpliedExtsZcmt}},

diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index ac9f18c8fd2fbb..dc1ce01d958f96 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -3276,6 +3276,25 @@ bool RISCVAsmParser::validateInstruction(MCInst &Inst,
     return Error(Loc, "Operand must be constant 4.");
   }
 
+  bool IsAMOCAS_D = Opcode == RISCV::AMOCAS_D || Opcode == RISCV::AMOCAS_D_AQ ||
+                    Opcode == RISCV::AMOCAS_D_RL ||
+                    Opcode == RISCV::AMOCAS_D_AQ_RL;
+  bool IsAMOCAS_Q = Opcode == RISCV::AMOCAS_Q || Opcode == RISCV::AMOCAS_Q_AQ ||
+                    Opcode == RISCV::AMOCAS_Q_RL ||
+                    Opcode == RISCV::AMOCAS_Q_AQ_RL;
+  if ((!isRV64() && IsAMOCAS_D) || IsAMOCAS_Q) {
+    unsigned Rd = Inst.getOperand(0).getReg();
+    unsigned Rs2 = Inst.getOperand(2).getReg();
+    if (Rd % 2 != 0) {
+      SMLoc Loc = Operands[1]->getStartLoc();
+      return Error(Loc, "The destination register must be even.");
+    }
+    if (Rs2 % 2 != 0) {
+      SMLoc Loc = Operands[2]->getStartLoc();
+      return Error(Loc, "The source register must be even.");
+    }
+  }
+
   const MCInstrDesc &MCID = MII.get(Opcode);
   if (!(MCID.TSFlags & RISCVII::ConstraintMask))
     return false;

diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 806268e7baf49e..0157bfc162ff5e 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -656,6 +656,13 @@ def HasHalfFPLoadStoreMove
                                     "'Zfbfmin' (Scalar BF16 Converts) or "
                                     "'Zvfbfwma' (Vector BF16 widening mul-add)">;
 
+def FeatureStdExtZacas
+    : SubtargetFeature<"experimental-zacas", "HasStdExtZacas", "true",
+                       "'Zacas' (Atomic Compare-And-Swap Instructions)">;
+def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZacas),
+                               "'Zacas' (Atomic Compare-And-Swap Instructions)">;
+
 //===----------------------------------------------------------------------===//
 // Vendor extensions
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
index b388168386408e..8421109b85147e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
@@ -7,7 +7,8 @@
 //===----------------------------------------------------------------------===//
 //
 // This file describes the RISC-V instructions from the standard 'A', Atomic
-// Instructions extension.
+// Instructions extension as well as the experimental 'Zacas' (Atomic
+// Compare-and-Swap) extension.
 //
 //===----------------------------------------------------------------------===//
 
@@ -101,6 +102,15 @@ defm AMOMAXU_D  : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">,
                   Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>;
 } // Predicates = [HasStdExtA, IsRV64]
 
+let Predicates = [HasStdExtZacas] in {
+defm AMOCAS_W : AMO_rr_aq_rl<0b00101, 0b010, "amocas.w">;
+defm AMOCAS_D : AMO_rr_aq_rl<0b00101, 0b011, "amocas.d">;
+} // Predicates = [HasStdExtZacas]
+
+let Predicates = [HasStdExtZacas, IsRV64] in {
+defm AMOCAS_Q : AMO_rr_aq_rl<0b00101, 0b100, "amocas.q">;
+} // Predicates = [HasStdExtZacas, IsRV64]
+
 //===----------------------------------------------------------------------===//
 // Pseudo-instructions and codegen patterns
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index fad90b30ab3e49..1e7c5be18f381d 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -80,6 +80,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV32ZFBFMIN %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBFMIN %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBFWMA %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %s
 
 ; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
 ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s
@@ -167,6 +168,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV64ZFBFMIN %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBFMIN %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBFWMA %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
 
 ; CHECK: .attribute 4, 16
 
@@ -249,6 +251,7 @@
 ; RV32ZFBFMIN: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfbfmin0p6"
 ; RV32ZVFBFMIN: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin0p6_zvl32b1p0"
 ; RV32ZVFBFWMA: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfwma0p6_zvl32b1p0"
+; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0"
 
 ; RV64M: .attribute 5, "rv64i2p1_m2p0"
 ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -335,6 +338,7 @@
 ; RV64ZFBFMIN: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfbfmin0p6"
 ; RV64ZVFBFMIN: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin0p6_zvl32b1p0"
 ; RV64ZVFBFWMA: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfwma0p6_zvl32b1p0"
+; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
 
 define i32 @addi(i32 %a) {
   %1 = add i32 %a, 1

diff  --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index aee5c7cdc651a8..2d4885ab15b43d 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -281,3 +281,6 @@
 
 .attribute arch, "rv64i_xsfcie"
 # CHECK: attribute      5, "rv64i2p1_xsfcie1p0"
+
+.attribute arch, "rv32izacas1p0"
+# CHECK: attribute      5, "rv32i2p1_a2p1_zacas1p0"

diff  --git a/llvm/test/MC/RISCV/rv32zacas-invalid.s b/llvm/test/MC/RISCV/rv32zacas-invalid.s
new file mode 100644
index 00000000000000..f6a5858d9b3ee9
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zacas-invalid.s
@@ -0,0 +1,18 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zacas < %s 2>&1 | FileCheck %s
+
+# Non-zero offsets not supported for the third operand (rs1).
+amocas.w a1, a3, 1(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+amocas.d a1, a3, 2(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+
+# First and second operands (rd and rs2) of amocas.d must be even for RV32.
+amocas.d a1, a2, (a1) # CHECK: :[[@LINE]]:10: error: The destination register must be even.
+amocas.d a0, a1, (a1) # CHECK: :[[@LINE]]:14: error: The source register must be even.
+amocas.d.aq a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even.
+amocas.d.aq a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even.
+amocas.d.rl a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even.
+amocas.d.rl a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even.
+amocas.d.aqrl a1, a2, (a1) # CHECK: :[[@LINE]]:15: error: The destination register must be even.
+amocas.d.aqrl a0, a1, (a1) # CHECK: :[[@LINE]]:19: error: The source register must be even.
+
+# amocas.q is not supported for RV32.
+amocas.q a1, a1, (a1) # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}}

diff  --git a/llvm/test/MC/RISCV/rv32zacas-valid.s b/llvm/test/MC/RISCV/rv32zacas-valid.s
new file mode 100644
index 00000000000000..d80b963f0a0477
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zacas-valid.s
@@ -0,0 +1,64 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zacas -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zacas -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zacas < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zacas -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zacas < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zacas -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: not llvm-mc -triple=riscv32 -mattr=+a -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 -mattr=+a -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ASM-AND-OBJ: amocas.w a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0xa5,0xd7,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.w a1, a3, (a5)
+# CHECK-ASM-AND-OBJ: amocas.w a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0xa5,0xd7,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.w a1, a3, 0(a5)
+# CHECK-ASM-AND-OBJ: amocas.w zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.w zero, zero, (a5)
+# CHECK-ASM-AND-OBJ: amocas.w.aq zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x2c]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.w.aq zero, zero, (a5)
+# CHECK-ASM-AND-OBJ: amocas.w.rl zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x2a]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.w.rl zero, zero, (a5)
+# CHECK-ASM-AND-OBJ: amocas.w.aqrl zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x2e]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.w.aqrl zero, zero, (a5)
+
+# CHECK-ASM-AND-OBJ: amocas.d a0, a2, (a1)
+# CHECK-ASM: encoding: [0x2f,0xb5,0xc5,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d a0, a2, (a1)
+# CHECK-ASM-AND-OBJ: amocas.d a0, a2, (a1)
+# CHECK-ASM: encoding: [0x2f,0xb5,0xc5,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d a0, a2, 0(a1)
+# CHECK-ASM-AND-OBJ: amocas.d zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.d.aq zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x2c]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d.aq zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.d.rl zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x2a]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d.rl zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.d.aqrl zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x2e]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d.aqrl zero, zero, (a1)

diff  --git a/llvm/test/MC/RISCV/rv64zacas-invalid.s b/llvm/test/MC/RISCV/rv64zacas-invalid.s
new file mode 100644
index 00000000000000..feb570a2952784
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zacas-invalid.s
@@ -0,0 +1,16 @@
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zacas < %s 2>&1 | FileCheck %s
+
+# Non-zero offsets not supported for the third operand (rs1).
+amocas.w a1, a3, 1(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+amocas.d a1, a3, 2(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+amocas.q a1, a3, 3(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+
+# First and second operands (rd and rs2) of amocas.q must be even.
+amocas.q a1, a2, (a1) # CHECK: :[[@LINE]]:10: error: The destination register must be even.
+amocas.q a0, a1, (a1) # CHECK: :[[@LINE]]:14: error: The source register must be even.
+amocas.q.aq a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even.
+amocas.q.aq a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even.
+amocas.q.rl a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even.
+amocas.q.rl a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even.
+amocas.q.aqrl a1, a2, (a1) # CHECK: :[[@LINE]]:15: error: The destination register must be even.
+amocas.q.aqrl a0, a1, (a1) # CHECK: :[[@LINE]]:19: error: The source register must be even.

diff  --git a/llvm/test/MC/RISCV/rv64zacas-valid.s b/llvm/test/MC/RISCV/rv64zacas-valid.s
new file mode 100644
index 00000000000000..843401b50871af
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zacas-valid.s
@@ -0,0 +1,51 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zacas -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zacas < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zacas -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: not llvm-mc -triple=riscv64 -mattr=+a -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# Odd register numbers for rd and rs2 are allowed for amocas.d on RV64.
+
+# CHECK-ASM-AND-OBJ: amocas.d a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d a1, a3, (a5)
+# CHECK-ASM-AND-OBJ: amocas.d.aq a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x2c]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d.aq a1, a3, (a5)
+# CHECK-ASM-AND-OBJ: amocas.d.rl a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x2a]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d.rl a1, a3, (a5)
+# CHECK-ASM-AND-OBJ: amocas.d.aqrl a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x2e]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.d.aqrl a1, a3, (a5)
+
+# CHECK-ASM-AND-OBJ: amocas.q a0, a2, (a1)
+# CHECK-ASM: encoding: [0x2f,0xc5,0xc5,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.q a0, a2, (a1)
+# CHECK-ASM-AND-OBJ: amocas.q a0, a2, (a1)
+# CHECK-ASM: encoding: [0x2f,0xc5,0xc5,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.q a0, a2, 0(a1)
+# CHECK-ASM-AND-OBJ: amocas.q zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.q zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.q.aq zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x2c]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.q.aq zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.q.rl zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x2a]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.q.rl zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.q.aqrl zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x2e]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.q.aqrl zero, zero, (a1)


        


More information about the llvm-commits mailing list