Index: clang/test/Preprocessor/riscv-target-features.c =================================================================== --- clang/test/Preprocessor/riscv-target-features.c +++ clang/test/Preprocessor/riscv-target-features.c @@ -67,6 +67,7 @@ // CHECK-NOT: __riscv_zicond {{.*$}} // CHECK-NOT: __riscv_smaia {{.*$}} // CHECK-NOT: __riscv_ssaia {{.*$}} +// CHECK-NOT: __riscv_zacas {{.*$}} // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \ // RUN: -o - | FileCheck %s @@ -674,3 +675,11 @@ // RUN: -march=rv64issaia1p0 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-SSAIA-EXT %s // CHECK-SSAIA-EXT: __riscv_ssaia 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{{$}} Index: llvm/docs/RISCVUsage.rst =================================================================== --- llvm/docs/RISCVUsage.rst +++ llvm/docs/RISCVUsage.rst @@ -219,6 +219,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 `__. Note that current vector crypto extension version can be found in: . +``experimental-zacas`` + LLVM implements the `0.1 draft specification `_. + 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: llvm/docs/ReleaseNotes.rst =================================================================== --- llvm/docs/ReleaseNotes.rst +++ llvm/docs/ReleaseNotes.rst @@ -185,6 +185,8 @@ * Add sifive-x280 processor. * Zve32f is no longer allowed with Zfinx. Zve64d is no longer allowed with Zdinx. +* Added assembler/disassembler support for the experimental Zacas (atomic + compare-and-swap) extension. Changes to the WebAssembly Backend ---------------------------------- Index: llvm/lib/Support/RISCVISAInfo.cpp =================================================================== --- llvm/lib/Support/RISCVISAInfo.cpp +++ llvm/lib/Support/RISCVISAInfo.cpp @@ -140,6 +140,8 @@ {"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"}; 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"}; @@ -974,6 +977,7 @@ {{"v"}, {ImpliedExtsV}}, {{"xsfvcp"}, {ImpliedExtsXsfvcp}}, {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}}, + {{"zacas"}, {ImpliedExtsZacas}}, {{"zcb"}, {ImpliedExtsZcb}}, {{"zcmp"}, {ImpliedExtsZcmp}}, {{"zcmt"}, {ImpliedExtsZcmt}}, Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -3172,6 +3172,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/Target/RISCV/RISCVFeatures.td =================================================================== --- llvm/lib/Target/RISCV/RISCVFeatures.td +++ llvm/lib/Target/RISCV/RISCVFeatures.td @@ -611,6 +611,13 @@ "excluding the machine-level CSRs and behavior not " "directly visible to supervisor level.)", []>; +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/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/test/CodeGen/RISCV/attributes.ll =================================================================== --- llvm/test/CodeGen/RISCV/attributes.ll +++ llvm/test/CodeGen/RISCV/attributes.ll @@ -74,6 +74,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV32ZICOND %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-smaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SMAIA %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SSAIA %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 @@ -155,6 +156,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV64ZICOND %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-smaia %s -o - | FileCheck --check-prefixes=CHECK,RV64SMAIA %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV64SSAIA %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s ; CHECK: .attribute 4, 16 @@ -231,6 +233,7 @@ ; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0" ; RV32SMAIA: .attribute 5, "rv32i2p1_smaia1p0" ; RV32SSAIA: .attribute 5, "rv32i2p1_ssaia1p0" +; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas0p1" ; RV64M: .attribute 5, "rv64i2p1_m2p0" ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0" @@ -311,6 +314,7 @@ ; RV64ZICOND: .attribute 5, "rv64i2p1_zicond1p0" ; RV64SMAIA: .attribute 5, "rv64i2p1_smaia1p0" ; RV64SSAIA: .attribute 5, "rv64i2p1_ssaia1p0" +; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas0p1" define i32 @addi(i32 %a) { %1 = add i32 %a, 1 Index: llvm/test/MC/RISCV/attribute-arch.s =================================================================== --- llvm/test/MC/RISCV/attribute-arch.s +++ llvm/test/MC/RISCV/attribute-arch.s @@ -263,3 +263,6 @@ .attribute arch, "rv32i_ssaia1p0" # CHECK: attribute 5, "rv32i2p1_ssaia1p0" + +.attribute arch, "rv32izacas0p1" +# CHECK: attribute 5, "rv32i2p1_a2p1_zacas0p1" 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/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/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/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)