[llvm] 89f87c3 - [RISCV][MC] Add MC layer support for the experimental zabha extension (#80005)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 31 01:06:47 PST 2024


Author: Yingwei Zheng
Date: 2024-01-31T17:06:43+08:00
New Revision: 89f87c387627150d342722b79c78cea2311cddf7

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

LOG: [RISCV][MC] Add MC layer support for the experimental zabha extension (#80005)

This patch implements the zabha (Byte and Halfword Atomic Memory
Operations) v1.0-rc1 extension.
See also https://github.com/riscv/riscv-zabha/blob/v1.0-rc1/zabha.adoc.

Added: 
    llvm/test/MC/RISCV/rvzabha-invalid.s
    llvm/test/MC/RISCV/rvzabha-valid.s
    llvm/test/MC/RISCV/rvzabha-zacas-valid.s

Modified: 
    llvm/docs/RISCVUsage.rst
    llvm/docs/ReleaseNotes.rst
    llvm/lib/Support/RISCVISAInfo.cpp
    llvm/lib/Target/RISCV/RISCVFeatures.td
    llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
    llvm/lib/Target/RISCV/RISCVSchedRocket.td
    llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
    llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td
    llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR1.td
    llvm/lib/Target/RISCV/RISCVSchedule.td
    llvm/test/CodeGen/RISCV/attributes.ll
    llvm/unittests/Support/RISCVISAInfoTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 06292f05b90b8..5caf2fee197f2 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -226,6 +226,9 @@ LLVM supports (to various degrees) a number of experimental extensions.  All exp
 
 The primary goal of experimental support is to assist in the process of ratification by providing an existence proof of an implementation, and simplifying efforts to validate the value of a proposed extension against large code bases.  Experimental extensions are expected to either transition to ratified status, or be eventually removed.  The decision on whether to accept an experimental extension is currently done on an entirely case by case basis; if you want to propose one, attending the bi-weekly RISC-V sync-up call is strongly advised.
 
+``experimental-zabha``
+  LLVM implements assembler support for the `v1.0-rc1 draft specification <https://github.com/riscv/riscv-zabha/tree/v1.0-rc1>`_.
+
 ``experimental-zacas``
   LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.
 

diff  --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 15eb2408310a5..ad5b2ec1219e0 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -93,6 +93,7 @@ Changes to the RISC-V Backend
 -----------------------------
 
 * Support for the Zicond extension is no longer experimental.
+* Added assembler/disassembler support for the experimental Zabha (Byte and Halfword Atomic Memory Operations) extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------

diff  --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 2745a42352047..0ae1fc01e4ffc 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -195,6 +195,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
 // clang-format off
 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"zaamo", {0, 2}},
+    {"zabha", {1, 0}},
     {"zacas", {1, 0}},
     {"zalrsc", {0, 2}},
 
@@ -1017,6 +1018,7 @@ static const char *ImpliedExtsXSfvfnrclipxfqf[] = {"zve32f"};
 static const char *ImpliedExtsXSfvfwmaccqqq[] = {"zvfbfmin"};
 static const char *ImpliedExtsXSfvqmaccdod[] = {"zve32x"};
 static const char *ImpliedExtsXSfvqmaccqoq[] = {"zve32x"};
+static const char *ImpliedExtsZabha[] = {"a"};
 static const char *ImpliedExtsZacas[] = {"a"};
 static const char *ImpliedExtsZcb[] = {"zca"};
 static const char *ImpliedExtsZcd[] = {"d", "zca"};
@@ -1091,6 +1093,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
     {{"xsfvqmaccdod"}, {ImpliedExtsXSfvqmaccdod}},
     {{"xsfvqmaccqoq"}, {ImpliedExtsXSfvqmaccqoq}},
     {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
+    {{"zabha"}, {ImpliedExtsZabha}},
     {{"zacas"}, {ImpliedExtsZacas}},
     {{"zcb"}, {ImpliedExtsZcb}},
     {{"zcd"}, {ImpliedExtsZcd}},

diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 58bf5e8fdefbd..6b7bf4886c263 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -177,6 +177,13 @@ def HasStdExtAOrZaamo
                          "'A' (Atomic Instructions) or "
                          "'Zaamo' (Atomic Memory Operations)">;
 
+def FeatureStdExtZabha
+    : SubtargetFeature<"experimental-zabha", "HasStdExtZabha", "true",
+                       "'Zabha' (Byte and Halfword Atomic Memory Operations)">;
+def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">,
+                     AssemblerPredicate<(all_of FeatureStdExtZabha),
+                         "'Zabha' (Byte and Halfword Atomic Memory Operations)">;
+
 def FeatureStdExtZacas
     : SubtargetFeature<"experimental-zacas", "HasStdExtZacas", "true",
                        "'Zacas' (Atomic Compare-And-Swap Instructions)">;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
index 6b7f31d465e20..fa918d90ad160 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZa.td
@@ -10,6 +10,7 @@
 // extensions:
 //   - Zawrs (v1.0) : Wait-on-Reservation-Set.
 //   - Zacas (v1.0-rc1) : Atomic Compare-and-Swap.
+//   - Zabha (v1.0-rc1) : Byte and Halfword Atomic Memory Operations.
 //
 //===----------------------------------------------------------------------===//
 
@@ -134,3 +135,53 @@ let Predicates = [HasStdExtZawrs] in {
 def WRS_NTO : WRSInst<0b000000001101, "wrs.nto">, Sched<[]>;
 def WRS_STO : WRSInst<0b000000011101, "wrs.sto">, Sched<[]>;
 } // Predicates = [HasStdExtZawrs]
+
+//===----------------------------------------------------------------------===//
+// Zabha (Byte and Halfword Atomic Memory Operations)
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtZabha] in {
+defm AMOSWAP_B  : AMO_rr_aq_rl<0b00001, 0b000, "amoswap.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOADD_B   : AMO_rr_aq_rl<0b00000, 0b000, "amoadd.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOXOR_B   : AMO_rr_aq_rl<0b00100, 0b000, "amoxor.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOAND_B   : AMO_rr_aq_rl<0b01100, 0b000, "amoand.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOOR_B    : AMO_rr_aq_rl<0b01000, 0b000, "amoor.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOMIN_B   : AMO_rr_aq_rl<0b10000, 0b000, "amomin.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOMAX_B   : AMO_rr_aq_rl<0b10100, 0b000, "amomax.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOMINU_B  : AMO_rr_aq_rl<0b11000, 0b000, "amominu.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+defm AMOMAXU_B  : AMO_rr_aq_rl<0b11100, 0b000, "amomaxu.b">,
+                  Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
+
+defm AMOSWAP_H  : AMO_rr_aq_rl<0b00001, 0b001, "amoswap.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOADD_H   : AMO_rr_aq_rl<0b00000, 0b001, "amoadd.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOXOR_H   : AMO_rr_aq_rl<0b00100, 0b001, "amoxor.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOAND_H   : AMO_rr_aq_rl<0b01100, 0b001, "amoand.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOOR_H    : AMO_rr_aq_rl<0b01000, 0b001, "amoor.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOMIN_H   : AMO_rr_aq_rl<0b10000, 0b001, "amomin.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOMAX_H   : AMO_rr_aq_rl<0b10100, 0b001, "amomax.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOMINU_H  : AMO_rr_aq_rl<0b11000, 0b001, "amominu.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+defm AMOMAXU_H  : AMO_rr_aq_rl<0b11100, 0b001, "amomaxu.h">,
+                  Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
+}
+
+// If Zacas extension is also implemented, Zabha further provides AMOCAS.[B|H].
+let Predicates = [HasStdExtZabha, HasStdExtZacas] in {
+defm AMOCAS_B : AMO_cas_aq_rl<0b00101, 0b000, "amocas.b", GPR>;
+defm AMOCAS_H : AMO_cas_aq_rl<0b00101, 0b001, "amocas.h", GPR>;
+}

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td
index bb9dfe5d01240..60fa1a848306d 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedRocket.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td
@@ -239,6 +239,7 @@ def : ReadAdvance<ReadFClass64, 0>;
 //===----------------------------------------------------------------------===//
 // Unsupported extensions
 defm : UnsupportedSchedV;
+defm : UnsupportedSchedZabha;
 defm : UnsupportedSchedZba;
 defm : UnsupportedSchedZbb;
 defm : UnsupportedSchedZbc;

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
index f531ab2fac8f9..976b88250e45e 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
@@ -1209,6 +1209,7 @@ foreach mx = SchedMxList in {
 
 //===----------------------------------------------------------------------===//
 // Unsupported extensions
+defm : UnsupportedSchedZabha;
 defm : UnsupportedSchedZbc;
 defm : UnsupportedSchedZbkb;
 defm : UnsupportedSchedZbkx;

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td b/llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td
index 02fff5b52bbc0..01398dea14a3b 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td
@@ -345,6 +345,7 @@ def : ReadAdvance<ReadSingleBitImm, 0>;
 
 //===----------------------------------------------------------------------===//
 // Unsupported extensions
+defm : UnsupportedSchedZabha;
 defm : UnsupportedSchedZbc;
 defm : UnsupportedSchedZbkb;
 defm : UnsupportedSchedZbkx;

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR1.td b/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR1.td
index 06ad2075b0736..f2c07810867bd 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR1.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR1.td
@@ -199,6 +199,7 @@ def : ReadAdvance<ReadSFBALU, 0>;
 //===----------------------------------------------------------------------===//
 // Unsupported extensions
 defm : UnsupportedSchedV;
+defm : UnsupportedSchedZabha;
 defm : UnsupportedSchedZba;
 defm : UnsupportedSchedZbb;
 defm : UnsupportedSchedZbc;

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedule.td b/llvm/lib/Target/RISCV/RISCVSchedule.td
index f6c1b096ad90c..593921bfcc67a 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedule.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedule.td
@@ -30,6 +30,8 @@ def WriteSTB        : SchedWrite;    // Store byte
 def WriteSTH        : SchedWrite;    // Store half-word
 def WriteSTW        : SchedWrite;    // Store word
 def WriteSTD        : SchedWrite;    // Store double-word
+def WriteAtomicB    : SchedWrite;    //Atomic memory operation byte size
+def WriteAtomicH    : SchedWrite;    //Atomic memory operation halfword size
 def WriteAtomicW    : SchedWrite;    //Atomic memory operation word size
 def WriteAtomicD    : SchedWrite;    //Atomic memory operation double word size
 def WriteAtomicLDW  : SchedWrite;    // Atomic load word
@@ -135,6 +137,10 @@ def ReadIDiv        : SchedRead;
 def ReadIDiv32      : SchedRead;
 def ReadIMul        : SchedRead;
 def ReadIMul32      : SchedRead;
+def ReadAtomicBA    : SchedRead;
+def ReadAtomicBD    : SchedRead;
+def ReadAtomicHA    : SchedRead;
+def ReadAtomicHD    : SchedRead;
 def ReadAtomicWA    : SchedRead;
 def ReadAtomicWD    : SchedRead;
 def ReadAtomicDA    : SchedRead;
@@ -271,6 +277,18 @@ def : ReadAdvance<ReadFRoundF16, 0>;
 } // Unsupported = true
 }
 
+multiclass UnsupportedSchedZabha {
+let Unsupported = true in {
+def : WriteRes<WriteAtomicB, []>;
+def : WriteRes<WriteAtomicH, []>;
+
+def : ReadAdvance<ReadAtomicBA, 0>;
+def : ReadAdvance<ReadAtomicBD, 0>;
+def : ReadAdvance<ReadAtomicHA, 0>;
+def : ReadAdvance<ReadAtomicHD, 0>;
+} // Unsupported = true
+}
+
 // Include the scheduler resources for other instruction extensions.
 include "RISCVScheduleZb.td"
 include "RISCVScheduleV.td"

diff  --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index b64db86ddf6c7..8c5d33d03aa44 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -97,6 +97,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV32ZICFILP %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zabha %s -o - | FileCheck --check-prefix=RV32ZABHA %s
 
 ; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
 ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s
@@ -201,6 +202,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV64ZALRSC %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV64ZICFILP %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zabha %s -o - | FileCheck --check-prefix=RV64ZABHA %s
 
 ; CHECK: .attribute 4, 16
 
@@ -300,6 +302,7 @@
 ; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0"
 ; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc0p2"
 ; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p4"
+; RV32ZABHA: .attribute 5, "rv32i2p1_a2p1_zabha1p0"
 
 ; RV64M: .attribute 5, "rv64i2p1_m2p0"
 ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -403,6 +406,7 @@
 ; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
 ; RV64ZALRSC: .attribute 5, "rv64i2p1_zalrsc0p2"
 ; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"
+; RV64ZABHA: .attribute 5, "rv64i2p1_a2p1_zabha1p0"
 
 define i32 @addi(i32 %a) {
   %1 = add i32 %a, 1

diff  --git a/llvm/test/MC/RISCV/rvzabha-invalid.s b/llvm/test/MC/RISCV/rvzabha-invalid.s
new file mode 100644
index 0000000000000..091f7e59ae184
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvzabha-invalid.s
@@ -0,0 +1,16 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zabha < %s 2>&1 | FileCheck %s
+# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zabha < %s 2>&1 | FileCheck %s
+
+# Final operand must have parentheses
+amoswap.b a1, a2, a3 # CHECK: :[[@LINE]]:19: error: expected '(' or optional integer offset
+amomin.b a1, a2, 1 # CHECK: :[[@LINE]]:20: error: expected '(' after optional integer offset
+amomin.b a1, a2, 1(a3) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+
+# Only .aq, .rl, and .aqrl suffixes are valid
+amoxor.b.rlqa a2, a3, (a4) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
+amoor.b.aq.rl a4, a5, (a6) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
+amoor.b. a4, a5, (a6) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
+
+# Non-zero offsets not supported for the third operand (rs1).
+amocas.b a1, a3, 1(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
+amocas.h a0, a2, 2(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0

diff  --git a/llvm/test/MC/RISCV/rvzabha-valid.s b/llvm/test/MC/RISCV/rvzabha-valid.s
new file mode 100644
index 0000000000000..c1f7f44a04ddd
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvzabha-valid.s
@@ -0,0 +1,235 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zabha -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zabha -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-zabha < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zabha -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zabha < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zabha -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: amoswap.b a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x07,0x14,0x08]
+amoswap.b a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.b a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x85,0xc6,0x00]
+amoadd.b a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.b a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x06,0xd7,0x20]
+amoxor.b a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.b a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x86,0xe7,0x60]
+amoand.b a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.b a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x07,0xf8,0x40]
+amoor.b a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.b a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x87,0x08,0x81]
+amomin.b a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.b s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x8b,0x6a,0xa1]
+amomax.b s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.b s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x0b,0x5a,0xc1]
+amominu.b s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.b s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x8a,0x49,0xe1]
+amomaxu.b s5, s4, (s3)
+
+# CHECK-ASM-AND-OBJ: amoswap.b.aq a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x07,0x14,0x0c]
+amoswap.b.aq a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.b.aq a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x85,0xc6,0x04]
+amoadd.b.aq a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.b.aq a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x06,0xd7,0x24]
+amoxor.b.aq a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.b.aq a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x86,0xe7,0x64]
+amoand.b.aq a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.b.aq a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x07,0xf8,0x44]
+amoor.b.aq a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.b.aq a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x87,0x08,0x85]
+amomin.b.aq a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.b.aq s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x8b,0x6a,0xa5]
+amomax.b.aq s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.b.aq s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x0b,0x5a,0xc5]
+amominu.b.aq s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.b.aq s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x8a,0x49,0xe5]
+amomaxu.b.aq s5, s4, (s3)
+
+# CHECK-ASM-AND-OBJ: amoswap.b.rl a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x07,0x14,0x0a]
+amoswap.b.rl a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.b.rl a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x85,0xc6,0x02]
+amoadd.b.rl a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.b.rl a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x06,0xd7,0x22]
+amoxor.b.rl a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.b.rl a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x86,0xe7,0x62]
+amoand.b.rl a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.b.rl a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x07,0xf8,0x42]
+amoor.b.rl a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.b.rl a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x87,0x08,0x83]
+amomin.b.rl a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.b.rl s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x8b,0x6a,0xa3]
+amomax.b.rl s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.b.rl s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x0b,0x5a,0xc3]
+amominu.b.rl s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.b.rl s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x8a,0x49,0xe3]
+amomaxu.b.rl s5, s4, (s3)
+
+# CHECK-ASM-AND-OBJ: amoswap.b.aqrl a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x07,0x14,0x0e]
+amoswap.b.aqrl a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.b.aqrl a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x85,0xc6,0x06]
+amoadd.b.aqrl a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.b.aqrl a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x06,0xd7,0x26]
+amoxor.b.aqrl a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.b.aqrl a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x86,0xe7,0x66]
+amoand.b.aqrl a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.b.aqrl a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x07,0xf8,0x46]
+amoor.b.aqrl a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.b.aqrl a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x87,0x08,0x87]
+amomin.b.aqrl a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.b.aqrl s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x8b,0x6a,0xa7]
+amomax.b.aqrl s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.b.aqrl s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x0b,0x5a,0xc7]
+amominu.b.aqrl s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.b.aqrl s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x8a,0x49,0xe7]
+amomaxu.b.aqrl s5, s4, (s3)
+
+
+# CHECK-ASM-AND-OBJ: amoswap.h a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x17,0x14,0x08]
+amoswap.h a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.h a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x95,0xc6,0x00]
+amoadd.h a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.h a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x16,0xd7,0x20]
+amoxor.h a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.h a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x96,0xe7,0x60]
+amoand.h a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.h a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x17,0xf8,0x40]
+amoor.h a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.h a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x97,0x08,0x81]
+amomin.h a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.h s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x9b,0x6a,0xa1]
+amomax.h s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.h s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x1b,0x5a,0xc1]
+amominu.h s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.h s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x9a,0x49,0xe1]
+amomaxu.h s5, s4, (s3)
+
+# CHECK-ASM-AND-OBJ: amoswap.h.aq a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x17,0x14,0x0c]
+amoswap.h.aq a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.h.aq a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x95,0xc6,0x04]
+amoadd.h.aq a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.h.aq a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x16,0xd7,0x24]
+amoxor.h.aq a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.h.aq a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x96,0xe7,0x64]
+amoand.h.aq a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.h.aq a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x17,0xf8,0x44]
+amoor.h.aq a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.h.aq a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x97,0x08,0x85]
+amomin.h.aq a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.h.aq s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x9b,0x6a,0xa5]
+amomax.h.aq s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.h.aq s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x1b,0x5a,0xc5]
+amominu.h.aq s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.h.aq s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x9a,0x49,0xe5]
+amomaxu.h.aq s5, s4, (s3)
+
+# CHECK-ASM-AND-OBJ: amoswap.h.rl a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x17,0x14,0x0a]
+amoswap.h.rl a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.h.rl a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x95,0xc6,0x02]
+amoadd.h.rl a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.h.rl a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x16,0xd7,0x22]
+amoxor.h.rl a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.h.rl a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x96,0xe7,0x62]
+amoand.h.rl a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.h.rl a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x17,0xf8,0x42]
+amoor.h.rl a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.h.rl a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x97,0x08,0x83]
+amomin.h.rl a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.h.rl s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x9b,0x6a,0xa3]
+amomax.h.rl s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.h.rl s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x1b,0x5a,0xc3]
+amominu.h.rl s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.h.rl s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x9a,0x49,0xe3]
+amomaxu.h.rl s5, s4, (s3)
+
+# CHECK-ASM-AND-OBJ: amoswap.h.aqrl a4, ra, (s0)
+# CHECK-ASM: encoding: [0x2f,0x17,0x14,0x0e]
+amoswap.h.aqrl a4, ra, (s0)
+# CHECK-ASM-AND-OBJ: amoadd.h.aqrl a1, a2, (a3)
+# CHECK-ASM: encoding: [0xaf,0x95,0xc6,0x06]
+amoadd.h.aqrl a1, a2, (a3)
+# CHECK-ASM-AND-OBJ: amoxor.h.aqrl a2, a3, (a4)
+# CHECK-ASM: encoding: [0x2f,0x16,0xd7,0x26]
+amoxor.h.aqrl a2, a3, (a4)
+# CHECK-ASM-AND-OBJ: amoand.h.aqrl a3, a4, (a5)
+# CHECK-ASM: encoding: [0xaf,0x96,0xe7,0x66]
+amoand.h.aqrl a3, a4, (a5)
+# CHECK-ASM-AND-OBJ: amoor.h.aqrl a4, a5, (a6)
+# CHECK-ASM: encoding: [0x2f,0x17,0xf8,0x46]
+amoor.h.aqrl a4, a5, (a6)
+# CHECK-ASM-AND-OBJ: amomin.h.aqrl a5, a6, (a7)
+# CHECK-ASM: encoding: [0xaf,0x97,0x08,0x87]
+amomin.h.aqrl a5, a6, (a7)
+# CHECK-ASM-AND-OBJ: amomax.h.aqrl s7, s6, (s5)
+# CHECK-ASM: encoding: [0xaf,0x9b,0x6a,0xa7]
+amomax.h.aqrl s7, s6, (s5)
+# CHECK-ASM-AND-OBJ: amominu.h.aqrl s6, s5, (s4)
+# CHECK-ASM: encoding: [0x2f,0x1b,0x5a,0xc7]
+amominu.h.aqrl s6, s5, (s4)
+# CHECK-ASM-AND-OBJ: amomaxu.h.aqrl s5, s4, (s3)
+# CHECK-ASM: encoding: [0xaf,0x9a,0x49,0xe7]
+amomaxu.h.aqrl s5, s4, (s3)

diff  --git a/llvm/test/MC/RISCV/rvzabha-zacas-valid.s b/llvm/test/MC/RISCV/rvzabha-zacas-valid.s
new file mode 100644
index 0000000000000..8ad2f99d3feba
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvzabha-zacas-valid.s
@@ -0,0 +1,64 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zabha,+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-zabha,+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-zabha,+experimental-zacas < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zabha,+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-zabha,+experimental-zacas < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zabha,+experimental-zacas -M no-aliases -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: not llvm-mc -triple=riscv32 -mattr=+experimental-zabha -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+# RUN: not llvm-mc -triple=riscv64 -mattr=+experimental-zabha -show-encoding %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ASM-AND-OBJ: amocas.b a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0x85,0xd7,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.b a1, a3, (a5)
+# CHECK-ASM-AND-OBJ: amocas.b a1, a3, (a5)
+# CHECK-ASM: encoding: [0xaf,0x85,0xd7,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.b a1, a3, 0(a5)
+# CHECK-ASM-AND-OBJ: amocas.b zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0x80,0x07,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.b zero, zero, (a5)
+# CHECK-ASM-AND-OBJ: amocas.b.aq zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0x80,0x07,0x2c]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.b.aq zero, zero, (a5)
+# CHECK-ASM-AND-OBJ: amocas.b.rl zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0x80,0x07,0x2a]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.b.rl zero, zero, (a5)
+# CHECK-ASM-AND-OBJ: amocas.b.aqrl zero, zero, (a5)
+# CHECK-ASM: encoding: [0x2f,0x80,0x07,0x2e]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.b.aqrl zero, zero, (a5)
+
+# CHECK-ASM-AND-OBJ: amocas.h a0, a2, (a1)
+# CHECK-ASM: encoding: [0x2f,0x95,0xc5,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.h a0, a2, (a1)
+# CHECK-ASM-AND-OBJ: amocas.h a0, a2, (a1)
+# CHECK-ASM: encoding: [0x2f,0x95,0xc5,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.h a0, a2, 0(a1)
+# CHECK-ASM-AND-OBJ: amocas.h zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0x90,0x05,0x28]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.h zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.h.aq zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0x90,0x05,0x2c]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.h.aq zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.h.rl zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0x90,0x05,0x2a]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.h.rl zero, zero, (a1)
+# CHECK-ASM-AND-OBJ: amocas.h.aqrl zero, zero, (a1)
+# CHECK-ASM: encoding: [0x2f,0x90,0x05,0x2e]
+# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}}
+amocas.h.aqrl zero, zero, (a1)

diff  --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp
index f739c26b6880c..4cd957438acb6 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -855,6 +855,7 @@ Experimental extensions
     zicfiss             0.4
     zimop               0.1
     zaamo               0.2
+    zabha               1.0
     zacas               1.0
     zalrsc              0.2
     zfbfmin             1.0


        


More information about the llvm-commits mailing list