asb created this revision.
asb added reviewers: reames, craig.topper, kito-cheng.
Herald added subscribers: jobnoorman, luke, wingo, pmatos, VincentWu, vkmr, 
frasercrmck, jdoerfert, evandro, luismarques, apazos, sameer.abuasal, 
s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, 
rogfer01, edward-jones, zzheng, jrtc27, shiva0217, niosHD, sabuasal, simoncook, 
johnrusso, rbar, hiraditya, arichardson.
Herald added a project: All.
asb requested review of this revision.
Herald added subscribers: cfe-commits, pcwang-thead, eopXD, MaskRay.
Herald added projects: clang, LLVM.

This implements the v0.1 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. My reasoning is that this 
validation is easy to implement and review, while ensuring the register class 
is correct as described isn't so easy without testing that is only added when 
codegen is implemented. Admittedly, the need to check for the aq/rl/aqrl opcode 
variants makes the validateInstruction
logic a bit uglier. Happy to switch approach if preferred by reviewers.

It's not a pre-requisite for this patch, but we likely want to have an asm 
constraint for even registers. I've filed an issue here 
https://github.com/riscv-non-isa/riscv-c-api-doc/issues/37


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D149248

Files:
  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
  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

Index: llvm/test/MC/RISCV/rv64zacas-valid.s
===================================================================
--- /dev/null
+++ 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)
Index: llvm/test/MC/RISCV/rv64zacas-invalid.s
===================================================================
--- /dev/null
+++ 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.
Index: llvm/test/MC/RISCV/rv32zacas-valid.s
===================================================================
--- /dev/null
+++ 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)
Index: llvm/test/MC/RISCV/rv32zacas-invalid.s
===================================================================
--- /dev/null
+++ 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{{$}}
Index: llvm/test/MC/RISCV/attribute-arch.s
===================================================================
--- llvm/test/MC/RISCV/attribute-arch.s
+++ llvm/test/MC/RISCV/attribute-arch.s
@@ -251,3 +251,6 @@
 
 .attribute arch, "rv32izicond1p0"
 # CHECK: attribute      5, "rv32i2p1_zicond1p0"
+
+.attribute arch, "rv32izacas0p1"
+# CHECK: attribute      5, "rv32i2p1_a2p1_zacas0p1"
Index: llvm/test/CodeGen/RISCV/attributes.ll
===================================================================
--- llvm/test/CodeGen/RISCV/attributes.ll
+++ llvm/test/CodeGen/RISCV/attributes.ll
@@ -69,6 +69,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvksh %s -o - | FileCheck --check-prefix=RV32ZVKSH %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zve32x -mattr=+experimental-zvkt %s -o - | FileCheck --check-prefix=RV32ZVKT %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV32ZICOND %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
@@ -145,6 +146,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+zve32x -mattr=+experimental-zvksh %s -o - | FileCheck --check-prefix=RV64ZVKSH %s
 ; RUN: llc -mtriple=riscv64 -mattr=+zve32x -mattr=+experimental-zvkt %s -o - | FileCheck --check-prefix=RV64ZVKT %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV64ZICOND %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
 
 ; CHECK: .attribute 4, 16
 
@@ -216,6 +218,7 @@
 ; RV32ZVKSH: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvksh0p5_zvl32b1p0"
 ; RV32ZVKT: .attribute 5, "rv32i2p1_zicsr2p0_zve32x1p0_zvkt0p5_zvl32b1p0"
 ; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0"
+; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas0p1"
 
 ; RV64M: .attribute 5, "rv64i2p1_m2p0"
 ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -291,6 +294,7 @@
 ; RV64ZVKSH: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvksh0p5_zvl32b1p0"
 ; RV64ZVKT: .attribute 5, "rv64i2p1_zicsr2p0_zve32x1p0_zvkt0p5_zvl32b1p0"
 ; RV64ZICOND: .attribute 5, "rv64i2p1_zicond1p0"
+; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas0p1"
 
 define i32 @addi(i32 %a) {
   %1 = add i32 %a, 1
Index: llvm/lib/Target/RISCV/RISCVInstrInfoA.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfoA.td
+++ 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 @@
                   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
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/RISCV/RISCVFeatures.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVFeatures.td
+++ llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -566,6 +566,13 @@
                                 AssemblerPredicate<(all_of FeatureStdExtZicond),
                                 "'Zicond' (Integer Conditional Operations)">;
 
+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
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2940,6 +2940,25 @@
     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 == 1) {
+      SMLoc Loc = Operands[1]->getStartLoc();
+      return Error(Loc, "The destination register must be even.");
+    }
+    if (Rs2 % 2 == 1) {
+      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;
Index: llvm/lib/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -135,6 +135,8 @@
 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"zihintntl", RISCVExtensionVersion{0, 2}},
 
+    {"zacas", RISCVExtensionVersion{0, 1}},
+
     {"zca", RISCVExtensionVersion{1, 0}},
     {"zcb", RISCVExtensionVersion{1, 0}},
     {"zcd", RISCVExtensionVersion{1, 0}},
@@ -915,6 +917,7 @@
 static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"};
 static const char *ImpliedExtsXTHeadVdot[] = {"v"};
 static const char *ImpliedExtsXsfvcp[] = {"zve32x"};
+static const char *ImpliedExtsZacas[] = {"a"};
 static const char *ImpliedExtsZcb[] = {"zca"};
 static const char *ImpliedExtsZdinx[] = {"zfinx"};
 static const char *ImpliedExtsZfa[] = {"f"};
@@ -970,6 +973,7 @@
     {{"v"}, {ImpliedExtsV}},
     {{"xsfvcp"}, {ImpliedExtsXsfvcp}},
     {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
+    {{"zacas"}, {ImpliedExtsZacas}},
     {{"zcb"}, {ImpliedExtsZcb}},
     {{"zdinx"}, {ImpliedExtsZdinx}},
     {{"zfa"}, {ImpliedExtsZfa}},
Index: llvm/docs/ReleaseNotes.rst
===================================================================
--- llvm/docs/ReleaseNotes.rst
+++ llvm/docs/ReleaseNotes.rst
@@ -169,6 +169,8 @@
 * Added support for Zfa extension version 0.2.
 * Updated support experimental vector crypto extensions to version 0.5.1 of
   the specification.
+* Added assembler/disassembler support for the experimental Zacas (atomic
+  compare-and-swap) extension.
 
 Changes to the WebAssembly Backend
 ----------------------------------
Index: llvm/docs/RISCVUsage.rst
===================================================================
--- llvm/docs/RISCVUsage.rst
+++ llvm/docs/RISCVUsage.rst
@@ -205,6 +205,9 @@
 ``experimental-zvbb``, ``experimental-zvbc``, ``experimental-zvkg``, ``experimental-zvkn``, ``experimental-zvkng``, ``experimental-zvknha``, ``experimental-zvknhb``, ``experimental-zvkns``, ``experimental-zvks``, ``experimental-zvksed``, ``experimental-zvksg``, ``experimental-zvksh``, ``experimental-zvkt``
   LLVM implements the `0.5 draft specification <https://github.com/riscv/riscv-crypto/releases/download/v20230407/riscv-crypto-spec-vector.pdf>`__. Note that current vector crypto extension version can be found in: <https://github.com/riscv/riscv-crypto>.
 
+``experimental-zacas``
+  LLVM implements the `0.1 draft specification <https://github.com/riscv/riscv-zacas/blob/ac15dbdb636963371a646eab63ed4b42257db571/riscv-zacas.pdf>`_.
+
 To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using.  To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`.  Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
 
 Vendor Extensions
Index: clang/test/Preprocessor/riscv-target-features.c
===================================================================
--- clang/test/Preprocessor/riscv-target-features.c
+++ clang/test/Preprocessor/riscv-target-features.c
@@ -63,6 +63,7 @@
 // CHECK-NOT: __riscv_zvksh {{.*$}}
 // CHECK-NOT: __riscv_zvkt {{.*$}}
 // CHECK-NOT: __riscv_zicond {{.*$}}
+// CHECK-NOT: __riscv_zacas {{.*$}}
 
 // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \
 // RUN: -o - | FileCheck %s
@@ -640,3 +641,11 @@
 // RUN: -march=rv64i_zicond1p0 -x c -E -dM %s \
 // RUN: -o - | FileCheck --check-prefix=CHECK-ZICOND-EXT %s
 // CHECK-ZICOND-EXT: __riscv_zicond  1000000{{$}}
+
+// RUN: %clang -target riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zacas0p1 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// RUN: %clang -target riscv64 -menable-experimental-extensions \
+// RUN: -march=rv64i_zacas0p1 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
+// CHECK-ZACAS-EXT: __riscv_zacas  1000{{$}}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to