diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -72,6 +72,7 @@ // CHECK-NOT: __riscv_zfbfmin {{.*$}} // CHECK-NOT: __riscv_zvfbfmin {{.*$}} // CHECK-NOT: __riscv_zvfbfwma {{.*$}} +// CHECK-NOT: __riscv_zacas {{.*$}} // RUN: %clang -target riscv32-unknown-linux-gnu -march=rv32i -x c -E -dM %s \ // RUN: -o - | FileCheck %s @@ -771,3 +772,11 @@ // RUN: | FileCheck --check-prefix=CHECK-COMBINE-INTO-ZVKSG %s // CHECK-COMBINE-INTO-ZVKSG: __riscv_zvks 1000000{{$}} // CHECK-COMBINE-INTO-ZVKSG: __riscv_zvksg 1000000{{$}} + +// RUN: %clang -target riscv32 -menable-experimental-extensions \ +// RUN: -march=rv32i_zacas1p0 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s +// RUN: %clang -target riscv64 -menable-experimental-extensions \ +// RUN: -march=rv64i_zacas1p0 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s +// CHECK-ZACAS-EXT: __riscv_zacas 1000000{{$}} diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -191,6 +191,9 @@ ``experimental-ssaia`` LLVM implements the `Ratification candidate 3 `_. +``experimental-zacas`` + LLVM implements the `1.0-rc1 draft specification `_. + ``experimental-zfa`` LLVM implements the `0.2 draft specification `__. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -253,6 +253,8 @@ * Assembly support was added for the experimental Zfbfmin (scalar BF16 conversions), Zvfbfmin (vector BF16 conversions), and Zvfbfwma (vector BF16 widening mul-add) extensions. +* Added assembler/disassembler support for the experimental Zacas (atomic + compare-and-swap) extension. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -153,6 +153,8 @@ {"smaia", RISCVExtensionVersion{1, 0}}, {"ssaia", RISCVExtensionVersion{1, 0}}, + {"zacas", RISCVExtensionVersion{1, 0}}, + {"zfa", RISCVExtensionVersion{0, 2}}, {"zfbfmin", RISCVExtensionVersion{0, 6}}, @@ -944,6 +946,7 @@ static const char *ImpliedExtsV[] = {"zvl128b", "zve64d"}; static const char *ImpliedExtsXTHeadVdot[] = {"v"}; static const char *ImpliedExtsXsfvcp[] = {"zve32x"}; +static const char *ImpliedExtsZacas[] = {"a"}; static const char *ImpliedExtsZcb[] = {"zca"}; static const char *ImpliedExtsZcmp[] = {"zca"}; static const char *ImpliedExtsZcmt[] = {"zca"}; @@ -1006,6 +1009,7 @@ {{"v"}, {ImpliedExtsV}}, {{"xsfvcp"}, {ImpliedExtsXsfvcp}}, {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}}, + {{"zacas"}, {ImpliedExtsZacas}}, {{"zcb"}, {ImpliedExtsZcb}}, {{"zcmp"}, {ImpliedExtsZcmp}}, {{"zcmt"}, {ImpliedExtsZcmt}}, diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -3276,6 +3276,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 != 0) { + SMLoc Loc = Operands[1]->getStartLoc(); + return Error(Loc, "The destination register must be even."); + } + if (Rs2 % 2 != 0) { + SMLoc Loc = Operands[2]->getStartLoc(); + return Error(Loc, "The source register must be even."); + } + } + const MCInstrDesc &MCID = MII.get(Opcode); if (!(MCID.TSFlags & RISCVII::ConstraintMask)) return false; diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -656,6 +656,13 @@ "'Zfbfmin' (Scalar BF16 Converts) or " "'Zvfbfwma' (Vector BF16 widening mul-add)">; +def FeatureStdExtZacas + : SubtargetFeature<"experimental-zacas", "HasStdExtZacas", "true", + "'Zacas' (Atomic Compare-And-Swap Instructions)">; +def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">, + AssemblerPredicate<(all_of FeatureStdExtZacas), + "'Zacas' (Atomic Compare-And-Swap Instructions)">; + //===----------------------------------------------------------------------===// // Vendor extensions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td @@ -7,7 +7,8 @@ //===----------------------------------------------------------------------===// // // This file describes the RISC-V instructions from the standard 'A', Atomic -// Instructions extension. +// Instructions extension as well as the experimental 'Zacas' (Atomic +// Compare-and-Swap) extension. // //===----------------------------------------------------------------------===// @@ -101,6 +102,15 @@ Sched<[WriteAtomicD, ReadAtomicDA, ReadAtomicDD]>; } // Predicates = [HasStdExtA, IsRV64] +let Predicates = [HasStdExtZacas] in { +defm AMOCAS_W : AMO_rr_aq_rl<0b00101, 0b010, "amocas.w">; +defm AMOCAS_D : AMO_rr_aq_rl<0b00101, 0b011, "amocas.d">; +} // Predicates = [HasStdExtZacas] + +let Predicates = [HasStdExtZacas, IsRV64] in { +defm AMOCAS_Q : AMO_rr_aq_rl<0b00101, 0b100, "amocas.q">; +} // Predicates = [HasStdExtZacas, IsRV64] + //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -80,6 +80,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV32ZFBFMIN %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBFMIN %s ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBFWMA %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %s ; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s @@ -167,6 +168,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV64ZFBFMIN %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBFMIN %s ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBFWMA %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s ; CHECK: .attribute 4, 16 @@ -249,6 +251,7 @@ ; RV32ZFBFMIN: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfbfmin0p6" ; RV32ZVFBFMIN: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin0p6_zvl32b1p0" ; RV32ZVFBFWMA: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfwma0p6_zvl32b1p0" +; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0" ; RV64M: .attribute 5, "rv64i2p1_m2p0" ; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0" @@ -335,6 +338,7 @@ ; RV64ZFBFMIN: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfbfmin0p6" ; RV64ZVFBFMIN: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfmin0p6_zvl32b1p0" ; RV64ZVFBFWMA: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zve32f1p0_zve32x1p0_zvfbfwma0p6_zvl32b1p0" +; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0" define i32 @addi(i32 %a) { %1 = add i32 %a, 1 diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -281,3 +281,6 @@ .attribute arch, "rv64i_xsfcie" # CHECK: attribute 5, "rv64i2p1_xsfcie1p0" + +.attribute arch, "rv32izacas1p0" +# CHECK: attribute 5, "rv32i2p1_a2p1_zacas1p0" diff --git a/llvm/test/MC/RISCV/rv32zacas-invalid.s b/llvm/test/MC/RISCV/rv32zacas-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zacas-invalid.s @@ -0,0 +1,18 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zacas < %s 2>&1 | FileCheck %s + +# Non-zero offsets not supported for the third operand (rs1). +amocas.w a1, a3, 1(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amocas.d a1, a3, 2(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 + +# First and second operands (rd and rs2) of amocas.d must be even for RV32. +amocas.d a1, a2, (a1) # CHECK: :[[@LINE]]:10: error: The destination register must be even. +amocas.d a0, a1, (a1) # CHECK: :[[@LINE]]:14: error: The source register must be even. +amocas.d.aq a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even. +amocas.d.aq a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even. +amocas.d.rl a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even. +amocas.d.rl a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even. +amocas.d.aqrl a1, a2, (a1) # CHECK: :[[@LINE]]:15: error: The destination register must be even. +amocas.d.aqrl a0, a1, (a1) # CHECK: :[[@LINE]]:19: error: The source register must be even. + +# amocas.q is not supported for RV32. +amocas.q a1, a1, (a1) # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} diff --git a/llvm/test/MC/RISCV/rv32zacas-valid.s b/llvm/test/MC/RISCV/rv32zacas-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zacas-valid.s @@ -0,0 +1,64 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zacas -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zacas -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zacas < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zacas -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zacas < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zacas -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: not llvm-mc -triple=riscv32 -mattr=+a -show-encoding %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR +# RUN: not llvm-mc -triple=riscv64 -mattr=+a -show-encoding %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR + +# CHECK-ASM-AND-OBJ: amocas.w a1, a3, (a5) +# CHECK-ASM: encoding: [0xaf,0xa5,0xd7,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.w a1, a3, (a5) +# CHECK-ASM-AND-OBJ: amocas.w a1, a3, (a5) +# CHECK-ASM: encoding: [0xaf,0xa5,0xd7,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.w a1, a3, 0(a5) +# CHECK-ASM-AND-OBJ: amocas.w zero, zero, (a5) +# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.w zero, zero, (a5) +# CHECK-ASM-AND-OBJ: amocas.w.aq zero, zero, (a5) +# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x2c] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.w.aq zero, zero, (a5) +# CHECK-ASM-AND-OBJ: amocas.w.rl zero, zero, (a5) +# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x2a] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.w.rl zero, zero, (a5) +# CHECK-ASM-AND-OBJ: amocas.w.aqrl zero, zero, (a5) +# CHECK-ASM: encoding: [0x2f,0xa0,0x07,0x2e] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.w.aqrl zero, zero, (a5) + +# CHECK-ASM-AND-OBJ: amocas.d a0, a2, (a1) +# CHECK-ASM: encoding: [0x2f,0xb5,0xc5,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d a0, a2, (a1) +# CHECK-ASM-AND-OBJ: amocas.d a0, a2, (a1) +# CHECK-ASM: encoding: [0x2f,0xb5,0xc5,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d a0, a2, 0(a1) +# CHECK-ASM-AND-OBJ: amocas.d zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d zero, zero, (a1) +# CHECK-ASM-AND-OBJ: amocas.d.aq zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x2c] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d.aq zero, zero, (a1) +# CHECK-ASM-AND-OBJ: amocas.d.rl zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x2a] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d.rl zero, zero, (a1) +# CHECK-ASM-AND-OBJ: amocas.d.aqrl zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xb0,0x05,0x2e] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d.aqrl zero, zero, (a1) diff --git a/llvm/test/MC/RISCV/rv64zacas-invalid.s b/llvm/test/MC/RISCV/rv64zacas-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zacas-invalid.s @@ -0,0 +1,16 @@ +# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zacas < %s 2>&1 | FileCheck %s + +# Non-zero offsets not supported for the third operand (rs1). +amocas.w a1, a3, 1(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amocas.d a1, a3, 2(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 +amocas.q a1, a3, 3(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0 + +# First and second operands (rd and rs2) of amocas.q must be even. +amocas.q a1, a2, (a1) # CHECK: :[[@LINE]]:10: error: The destination register must be even. +amocas.q a0, a1, (a1) # CHECK: :[[@LINE]]:14: error: The source register must be even. +amocas.q.aq a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even. +amocas.q.aq a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even. +amocas.q.rl a1, a2, (a1) # CHECK: :[[@LINE]]:13: error: The destination register must be even. +amocas.q.rl a0, a1, (a1) # CHECK: :[[@LINE]]:17: error: The source register must be even. +amocas.q.aqrl a1, a2, (a1) # CHECK: :[[@LINE]]:15: error: The destination register must be even. +amocas.q.aqrl a0, a1, (a1) # CHECK: :[[@LINE]]:19: error: The source register must be even. diff --git a/llvm/test/MC/RISCV/rv64zacas-valid.s b/llvm/test/MC/RISCV/rv64zacas-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zacas-valid.s @@ -0,0 +1,51 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zacas -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zacas < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zacas -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: not llvm-mc -triple=riscv64 -mattr=+a -show-encoding %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR + +# Odd register numbers for rd and rs2 are allowed for amocas.d on RV64. + +# CHECK-ASM-AND-OBJ: amocas.d a1, a3, (a5) +# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d a1, a3, (a5) +# CHECK-ASM-AND-OBJ: amocas.d.aq a1, a3, (a5) +# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x2c] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d.aq a1, a3, (a5) +# CHECK-ASM-AND-OBJ: amocas.d.rl a1, a3, (a5) +# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x2a] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d.rl a1, a3, (a5) +# CHECK-ASM-AND-OBJ: amocas.d.aqrl a1, a3, (a5) +# CHECK-ASM: encoding: [0xaf,0xb5,0xd7,0x2e] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.d.aqrl a1, a3, (a5) + +# CHECK-ASM-AND-OBJ: amocas.q a0, a2, (a1) +# CHECK-ASM: encoding: [0x2f,0xc5,0xc5,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.q a0, a2, (a1) +# CHECK-ASM-AND-OBJ: amocas.q a0, a2, (a1) +# CHECK-ASM: encoding: [0x2f,0xc5,0xc5,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.q a0, a2, 0(a1) +# CHECK-ASM-AND-OBJ: amocas.q zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x28] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.q zero, zero, (a1) +# CHECK-ASM-AND-OBJ: amocas.q.aq zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x2c] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.q.aq zero, zero, (a1) +# CHECK-ASM-AND-OBJ: amocas.q.rl zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x2a] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.q.rl zero, zero, (a1) +# CHECK-ASM-AND-OBJ: amocas.q.aqrl zero, zero, (a1) +# CHECK-ASM: encoding: [0x2f,0xc0,0x05,0x2e] +# CHECK-ERROR: instruction requires the following: 'Zacas' (Atomic Compare-And-Swap Instructions){{$}} +amocas.q.aqrl zero, zero, (a1)