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

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 30 07:17:47 PST 2024


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/80005

>From 1f29db80606dff676f25d5b7a6a985628e82b03b Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 30 Jan 2024 21:57:13 +0800
Subject: [PATCH 1/2] [RISCV][MC] Add MC layer support for the experimental
 zabha extension

---
 llvm/docs/RISCVUsage.rst                      |   3 +
 llvm/docs/ReleaseNotes.rst                    |   1 +
 llvm/lib/Support/RISCVISAInfo.cpp             |   3 +
 llvm/lib/Target/RISCV/RISCVFeatures.td        |   7 +
 llvm/lib/Target/RISCV/RISCVInstrInfoZa.td     |  51 ++++
 llvm/lib/Target/RISCV/RISCVSchedRocket.td     |   1 +
 llvm/lib/Target/RISCV/RISCVSchedSiFive7.td    |   1 +
 llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td |   1 +
 .../Target/RISCV/RISCVSchedSyntacoreSCR1.td   |   1 +
 llvm/lib/Target/RISCV/RISCVSchedule.td        |  18 ++
 llvm/test/CodeGen/RISCV/attributes.ll         |   4 +
 llvm/test/MC/RISCV/rvzabha-invalid.s          |  16 ++
 llvm/test/MC/RISCV/rvzabha-valid.s            | 235 ++++++++++++++++++
 llvm/test/MC/RISCV/rvzabha-zacas-valid.s      |  64 +++++
 llvm/unittests/Support/RISCVISAInfoTest.cpp   |   1 +
 15 files changed, 407 insertions(+)
 create mode 100644 llvm/test/MC/RISCV/rvzabha-invalid.s
 create mode 100644 llvm/test/MC/RISCV/rvzabha-valid.s
 create mode 100644 llvm/test/MC/RISCV/rvzabha-zacas-valid.s

diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 06292f05b90b8..c5e4939223099 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 `1.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 c46d76da962c6..5f5247c647f76 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -194,6 +194,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
 // clang-format off
 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"zaamo", {0, 2}},
+    {"zabha", {1, 0}},
     {"zacas", {1, 0}},
     {"zalrsc", {0, 2}},
 
@@ -1006,6 +1007,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"};
@@ -1080,6 +1082,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 f03ccecfae799..57225320f6706 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -792,6 +792,7 @@ Experimental extensions
     zicfiss             0.4
     zimop               0.1
     zaamo               0.2
+    zabha               1.0
     zacas               1.0
     zalrsc              0.2
     zfbfmin             1.0

>From dde24f6f4aae49006fb0855b17e3b24e0ba428bf Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 30 Jan 2024 23:17:17 +0800
Subject: [PATCH 2/2] fixup! [RISCV][MC] Add MC layer support for the
 experimental zabha extension

Fix docs.
---
 llvm/docs/RISCVUsage.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index c5e4939223099..5caf2fee197f2 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -227,7 +227,7 @@ 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 `1.0-rc1 draft specification <https://github.com/riscv/riscv-zabha/tree/v1.0-rc1>`_.
+  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>`_.



More information about the llvm-commits mailing list