From 76750eaf6d9f3986c8e7f8612f2d8b12f29d887a Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 19 Aug 2024 16:43:16 -0700 Subject: [PATCH 01/11] [libunwind] Fix mismerge of https://reviews.llvm.org/D139368 Update the assembly directives to correctly compile. --- libunwind/src/UnwindRegistersRestore.S | 22 +++++++++++----------- libunwind/src/UnwindRegistersSave.S | 16 ++++++++-------- libunwind/src/assembly.h | 4 ++++ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S index 75dbee731575..f2b66dfbacc8 100644 --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -1300,19 +1300,19 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) #elif defined(__riscv) -.macro restore_fpr num +.macro restore_fpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - cfld f\num, (__SIZEOF_CHERI_CAPABILITY__ * 32 + 8 * \num)(ca0) + cfld f\num, (RISCV_FOFFSET + RISCV_FSIZE * \num)(c\ctxreg) #else - FLOAD f\num, (8 * 32 + 8 * \num)(a0) + FLOAD f\num, (RISCV_FOFFSET + RISCV_FSIZE * \num)(\ctxreg) #endif .endm -.macro restore_gpr num +.macro restore_gpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - clc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(ca0) + clc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(c\ctxreg) #else - ILOAD x\num, (8 * \num)(a0) + ILOAD x\num, (RISCV_ISIZE * \num)(\ctxreg) #endif .endm @@ -1326,24 +1326,24 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv) DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv) # if defined(__riscv_flen) .irp i,FROM_0_TO_31 - restore_fpr f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0) + restore_fpr \i, a0 .endr # endif #ifdef __CHERI_PURE_CAPABILITY__ clc c1, (__SIZEOF_CHERI_CAPABILITY__ * 0)(ca0) // restore pc into ra #else - ILOAD x1, (8 * 0)(a0) // restore pc into ra + ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra #endif // x0 is zero .irp i,2,3,4,5,6,7,8,9 - restore_gpr x\i, (RISCV_ISIZE * \i)(a0) + restore_gpr \i, a0 .endr // skip a0 for now .irp i,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 - restore_gpr x\i, (RISCV_ISIZE * \i)(a0) + restore_gpr \i, a0 .endr - restore_gpr x10, (RISCV_ISIZE * 10)(a0) // restore a0 + restore_gpr 10, a0 // restore a0 #ifdef __CHERI_PURE_CAPABILITY__ cret // jump to cra diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S index 5b2de4372b46..39cc33c7566d 100644 --- a/libunwind/src/UnwindRegistersSave.S +++ b/libunwind/src/UnwindRegistersSave.S @@ -1224,19 +1224,19 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) #elif defined(__riscv) -.macro save_fpr num +.macro save_fpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - cfsd f\num, (__SIZEOF_CHERI_CAPABILITY__ * 32 + 8 * \num)(ca0) + cfsd f\num, (__SIZEOF_CHERI_CAPABILITY__ * 32 + 8 * \num)(c\ctxreg) #else - FSTORE f\num, (8 * 32 + 8 * \num)(a0) + FSTORE f\num, (8 * 32 + 8 * \num)(\ctxreg) #endif .endm -.macro save_gpr num +.macro save_gpr num, ctxreg #ifdef __CHERI_PURE_CAPABILITY__ - csc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(ca0) + csc c\num, (__SIZEOF_CHERI_CAPABILITY__ * \num)(c\ctxreg) #else - ISTORE x\num, (8 * \num)(a0) + ISTORE x\num, (8 * \num)(\ctxreg) #endif .endm @@ -1253,12 +1253,12 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) ISTORE x1, (8 * 0)(a0) // store ra as pc #endif .irp i,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 - save_gpr x\i, (RISCV_ISIZE * \i)(a0) + save_gpr \i, a0 .endr # if defined(__riscv_flen) .irp i,FROM_0_TO_31 - save_fpr f\i, (RISCV_FOFFSET + RISCV_FSIZE * \i)(a0) + save_fpr \i, a0 .endr # endif diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h index 207b231770cf..8da72ce22c78 100644 --- a/libunwind/src/assembly.h +++ b/libunwind/src/assembly.h @@ -35,8 +35,12 @@ #elif defined(__APPLE__) && defined(__aarch64__) #define SEPARATOR %% #elif defined(__riscv) +#ifdef __CHERI_PURE_CAPABILITY__ +# define RISCV_FOFFSET (__SIZEOF_CHERI_CAPABILITY__ * 32) +#else # define RISCV_ISIZE (__riscv_xlen / 8) # define RISCV_FOFFSET (RISCV_ISIZE * 32) +#endif # if defined(__riscv_flen) # define RISCV_FSIZE (__riscv_flen / 8) # endif From 29286eaaabc3afd54f39567cec2f1d645d855846 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 19 Aug 2024 16:46:21 -0700 Subject: [PATCH 02/11] [libunwind] Use size_t when reading vlenb register This register is not a uintptr_t, and we want an XLEN integer instead. --- libunwind/src/Registers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp index 0752f5035297..49e7622e5271 100644 --- a/libunwind/src/Registers.hpp +++ b/libunwind/src/Registers.hpp @@ -4618,7 +4618,7 @@ inline reg_t Registers_riscv::getRegister(int regNum) const { if ((regNum > 0) && (regNum < 32)) return _registers[regNum]; if (regNum == UNW_RISCV_VLENB) { - reg_t vlenb; + size_t vlenb; __asm__("csrr %0, 0xC22" : "=r"(vlenb)); return vlenb; } From 923d3a76bd878f7975bdf2a01a961f6ee88fe579 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 19 Aug 2024 17:08:31 -0700 Subject: [PATCH 03/11] [libunwind] Fix running `ninja unwind-test-binaries` This is a local diff for CHERI LLVM but is rather helpful for debugging crashing test cases without having to intercept the lit infrastructure. --- libunwind/test/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libunwind/test/CMakeLists.txt b/libunwind/test/CMakeLists.txt index 7269870bf236..baf3f50cdd54 100644 --- a/libunwind/test/CMakeLists.txt +++ b/libunwind/test/CMakeLists.txt @@ -44,15 +44,15 @@ set(_LIBUNWIND_TEST_BINARIES) option(LIBUINWIND_BUILD_STATIC_TEST_BINARIES "build static test binaries" ON) foreach(_test_path ${_LIBUNWIND_TESTS}) get_filename_component(_test "${_test_path}" NAME_WE) - if ("${_test}" MATCHES ".*bad_unwind_info.*") + if ("${_test}" MATCHES ".*bad_unwind_info.*" OR "${_test}" MATCHES ".*scalable_vectors.*") continue() # Only works for a subset of architectures endif() string(REGEX MATCH ".*exceptions.*" _has_exceptions ${_test}) if (_has_exceptions) - set(_common_libs ${_cxx_abi_link_flag} -lpthread -lc -lpthread -ldl) + set(_common_libs unwind-headers ${_cxx_abi_link_flag} -lpthread -lc -lpthread -ldl) set(_common_flags -fexceptions) else() - set(_common_libs -lpthread -lc -lpthread -ldl) + set(_common_libs unwind-headers -lpthread -lc -lpthread -ldl) set(_common_flags -fno-exceptions) endif() foreach(_opt "" -O0 -O1 -O2 -O3) From 4f482f3d226edd2cec5a7f25bba29c5f4799095d Mon Sep 17 00:00:00 2001 From: Alexander Richardson Date: Mon, 18 Sep 2023 09:08:24 -0700 Subject: [PATCH 04/11] [libc++][lit] Atomically update the persistent cache (#66538) When running multiple shards in parallel, one shard might write to the cache while another one is reading this cache. Instead of updating the file in place, write to a temporary file and swap the cache file using os.replace(). This is an atomic operation and means shards will either see the old state or the new one. (cherry picked from commit 14882d6b7440e797d8d60cb1f8207fe332cae033) --- libcxx/utils/libcxx/test/dsl.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libcxx/utils/libcxx/test/dsl.py b/libcxx/utils/libcxx/test/dsl.py index 93c37126b908..a9e044cc1cff 100644 --- a/libcxx/utils/libcxx/test/dsl.py +++ b/libcxx/utils/libcxx/test/dsl.py @@ -63,8 +63,14 @@ def f(config, *args, **kwargs): if cacheKey not in cache: cache[cacheKey] = function(config, *args, **kwargs) # Update the persistent cache so it knows about the new key - with open(persistentCache, 'wb') as cacheFile: + # We write to a PID-suffixed file and rename the result to + # ensure that the cache is not corrupted when running the test + # suite with multiple shards. Since this file is in the same + # directory as the destination, os.replace() will be atomic. + unique_suffix = ".tmp." + str(os.getpid()) + with open(persistentCache + unique_suffix, "wb") as cacheFile: pickle.dump(cache, cacheFile) + os.replace(persistentCache + unique_suffix, persistentCache) return cache[cacheKey] return f return decorator From 630da04a8de9f087a5c85bde056a3f6545a74e52 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Sun, 25 Aug 2024 22:23:09 -0700 Subject: [PATCH 05/11] [CHERI-RISC-V] Add more MC tests for loads/stores We were not checking capability mode loads/stores, only compressed ones and atomics. --- .../cheri/rv32xcheri-cap-mode-only-valid.s | 15 +++++++ .../RISCV/cheri/rv32xcheri-cap-mode-valid.s | 39 +++++++++++++++++++ .../cheri/rv64xcheri-cap-mode-only-valid.s | 25 ++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s create mode 100644 llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s create mode 100644 llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s diff --git a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s new file mode 100644 index 000000000000..9f763e085bea --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s @@ -0,0 +1,15 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +# Capability load/store uses different encodings for RV32 vs RV64 + +# CHECK-ASM-AND-OBJ: clc ca2, 17(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x36,0x15,0x01] +clc ca2, 17(ca0) +# CHECK-ASM-AND-OBJ: csc ca5, 25(ca3) +# CHECK-ASM-SAME: encoding: [0xa3,0xbc,0xf6,0x00] +csc ca5, 25(ca3) + diff --git a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s new file mode 100644 index 000000000000..bd8f6105d5f5 --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s @@ -0,0 +1,39 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xcheri,+cap-mode < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: clb a2, 17(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x06,0x15,0x01] +clb a2, 17(ca0) +# CHECK-ASM-AND-OBJ: csb a5, 25(ca3) +# CHECK-ASM-SAME: encoding: [0xa3,0x8c,0xf6,0x00] +csb a5, 25(ca3) + +# CHECK-ASM-AND-OBJ: clh a2, 17(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x16,0x15,0x01] +clh a2, 17(ca0) +# CHECK-ASM-AND-OBJ: csh a5, 25(ca3) +# CHECK-ASM-SAME: encoding: [0xa3,0x9c,0xf6,0x00] +csh a5, 25(ca3) + +# CHECK-ASM-AND-OBJ: clw ra, 17(csp) +# CHECK-ASM-SAME: encoding: [0x83,0x20,0x11,0x01] +clw ra, 17(csp) +# CHECK-ASM-AND-OBJ: csw ra, 25(csp) +# CHECK-ASM-SAME: encoding: [0xa3,0x2c,0x11,0x00] +csw ra, 25(csp) + +# CHECK-ASM-AND-OBJ: clbu ra, 17(csp) +# CHECK-ASM-SAME: encoding: [0x83,0x40,0x11,0x01] +clbu ra, 17(csp) + +# CHECK-ASM-AND-OBJ: clhu ra, 17(csp) +# CHECK-ASM-SAME: encoding: [0x83,0x50,0x11,0x01] +clhu ra, 17(csp) diff --git a/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s new file mode 100644 index 000000000000..bfdd5e0dc057 --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s @@ -0,0 +1,25 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xcheri,+cap-mode < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +# Capability load/store uses different encodings for RV32 vs RV64 + +# CHECK-ASM-AND-OBJ: clc ca2, 17(ca0) +# CHECK-ASM-SAME: encoding: [0x0f,0x26,0x15,0x01] +clc ca2, 17(ca0) +# CHECK-ASM-AND-OBJ: csc ca5, 25(ca3) +# CHECK-ASM-SAME: encoding: [0xa3,0xcc,0xf6,0x00] +csc ca5, 25(ca3) + +# CHECK-ASM-AND-OBJ: cld a2, 17(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x36,0x15,0x01] +cld a2, 17(ca0) +# CHECK-ASM-AND-OBJ: csd a5, 25(ca3) +# CHECK-ASM-SAME: encoding: [0xa3,0xbc,0xf6,0x00] +csd a5, 25(ca3) + +# CHECK-ASM-AND-OBJ: clwu a2, 17(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x66,0x15,0x01] +clwu a2, 17(ca0) From 60b0070c024a5e6f3b20034b38da95460a591600 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Sun, 25 Aug 2024 22:59:24 -0700 Subject: [PATCH 06/11] [CHERI-RISC-V] Allow load/store mnemonics without the c prefix [1/n] Instead, make it depend on the type of the operand. This commit only touches the basic load/store instruction without the assembler aliases or compressed instructions. --- llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 65 ++++++++++++------- .../cheri/rv32xcheri-cap-mode-only-valid.s | 10 ++- .../RISCV/cheri/rv32xcheri-cap-mode-valid.s | 17 ++++- .../cheri/rv64xcheri-cap-mode-only-valid.s | 10 ++- llvm/test/MC/RISCV/rvi-pseudos-invalid.s | 2 +- 5 files changed, 75 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index 0d72ac2c4d57..4e69aa529295 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -214,16 +214,27 @@ multiclass AMO_C_rr_aq_rl funct5, bits<3> funct3, rdClass>; } -let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in -class CheriLoad_ri funct3, string opcodestr> - : RVInstI; - -let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in -class CheriStore_ri funct3, string opcodestr> - : RVInstS; +multiclass CheriLoad_ri funct3, string opcodestr> { + let hasSideEffects = 0, mayLoad = 1, mayStore = 0, + DecoderNamespace = "CapModeOnly_" in + def "" : RVInstI; + def : InstAlias(NAME) GPR:$rd, GPCR:$rs1, simm12:$imm12), + 0>; +} + +multiclass CheriStore_ri funct3, string opcodestr> { + let hasSideEffects = 0, mayLoad = 0, mayStore = 1, + DecoderNamespace = "CapModeOnly_" in + def "" : RVInstS; + def : InstAlias(NAME) GPR:$rs2, GPCR:$rs1, simm12:$imm12), + 0>; +} let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in class CLR_r funct3, string opcodestr> @@ -721,25 +732,23 @@ def : InstAlias<"cjalr $rs, $offset", (CJALR C1, GPCR:$rs, simm12:$of def : InstAlias<"cjalr $rd, $rs, $offset", (CJALR GPCR:$rd, GPCR:$rs, simm12:$offset), 0>; } // Predicates = [HasCheri, IsCapMode] -let DecoderNamespace = "CapModeOnly_" in { let Predicates = [HasCheri, IsCapMode] in { -def CLB : CheriLoad_ri<0b000, "clb">; -def CLH : CheriLoad_ri<0b001, "clh">; -def CLW : CheriLoad_ri<0b010, "clw">; -def CLBU : CheriLoad_ri<0b100, "clbu">; -def CLHU : CheriLoad_ri<0b101, "clhu">; - -def CSB : CheriStore_ri<0b000, "csb">; -def CSH : CheriStore_ri<0b001, "csh">; -def CSW : CheriStore_ri<0b010, "csw">; +defm CLB : CheriLoad_ri<0b000, "lb">; +defm CLH : CheriLoad_ri<0b001, "lh">; +defm CLW : CheriLoad_ri<0b010, "lw">; +defm CLBU : CheriLoad_ri<0b100, "lbu">; +defm CLHU : CheriLoad_ri<0b101, "lhu">; + +defm CSB : CheriStore_ri<0b000, "sb">; +defm CSH : CheriStore_ri<0b001, "sh">; +defm CSW : CheriStore_ri<0b010, "sw">; } // Predicates = [HasCheri, IsCapMode] let Predicates = [HasCheri, IsRV64, IsCapMode] in { -def CLWU : CheriLoad_ri<0b110, "clwu">; -def CLD : CheriLoad_ri<0b011, "cld">; -def CSD : CheriStore_ri<0b011, "csd">; +defm CLWU : CheriLoad_ri<0b110, "lwu">; +defm CLD : CheriLoad_ri<0b011, "ld">; +defm CSD : CheriStore_ri<0b011, "sd">; } // Predicates = [HasCheri, IsRV64, IsCapMode] -} // DecoderNameSpace = "CapModeOnly_" let Predicates = [HasCheri, IsRV32, IsCapMode] in { let DecoderNamespace = "RISCV32CapModeOnly_", @@ -747,12 +756,16 @@ let DecoderNamespace = "RISCV32CapModeOnly_", def CLC_64 : RVInstI<0x3, OPC_LOAD, (outs GPCR:$rd), (ins GPCR:$rs1, simm12:$imm12), "clc", "$rd, ${imm12}(${rs1})">; +def : InstAlias<"lc $rd, ${imm12}(${rs1})", + (CLC_64 GPCR:$rd, GPCR:$rs1, simm12:$imm12), 0>; let DecoderNamespace = "RISCV32CapModeOnly_", hasSideEffects = 0, mayLoad = 0, mayStore = 1 in def CSC_64 : RVInstS<0x3, OPC_STORE, (outs), (ins GPCR:$rs2, GPCR:$rs1, simm12:$imm12), "csc", "$rs2, ${imm12}(${rs1})">; +def : InstAlias<"sc $rs2, ${imm12}(${rs1})", + (CSC_64 GPCR:$rs2, GPCR:$rs1, simm12:$imm12), 0>; let EmitPriority = 0 in { def : InstAlias<"clc $rd, (${rs1})", @@ -768,12 +781,16 @@ let DecoderNamespace = "CapModeOnly_", def CLC_128 : RVInstI<0x2, OPC_MISC_MEM, (outs GPCR:$rd), (ins GPCR:$rs1, simm12:$imm12), "clc", "$rd, ${imm12}(${rs1})">; +def : InstAlias<"lc $rd, ${imm12}(${rs1})", + (CLC_128 GPCR:$rd, GPCR:$rs1, simm12:$imm12), 0>; let DecoderNamespace = "CapModeOnly_", hasSideEffects = 0, mayLoad = 0, mayStore = 1 in def CSC_128 : RVInstS<0x4, OPC_STORE, (outs), (ins GPCR:$rs2, GPCR:$rs1, simm12:$imm12), "csc", "$rs2, ${imm12}(${rs1})">; +def : InstAlias<"sc $rs2, ${imm12}(${rs1})", + (CSC_128 GPCR:$rs2, GPCR:$rs1, simm12:$imm12), 0>; let EmitPriority = 0 in { def : InstAlias<"clc $rd, (${rs1})", diff --git a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s index 9f763e085bea..78d3ad361095 100644 --- a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s @@ -1,9 +1,17 @@ -# RUN: llvm-mc %s -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode < %s \ # RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ # RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +## Same test again without the "c" prefix on all lines +# RUN: sed -e 's/^c//' < %s > %t.s +# RUN: llvm-mc -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %t.s \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + # Capability load/store uses different encodings for RV32 vs RV64 # CHECK-ASM-AND-OBJ: clc ca2, 17(ca0) diff --git a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s index bd8f6105d5f5..4660e37aed62 100644 --- a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s @@ -1,6 +1,6 @@ -# RUN: llvm-mc %s -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc %s -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s \ # RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode < %s \ # RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ @@ -9,6 +9,19 @@ # RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ # RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s +## Same test again without the "c" prefix on all lines +# RUN: sed -e 's/^c//' < %s > %t.s +# RUN: llvm-mc -triple=riscv32 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %t.s \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %t.s \ +# RUN: | FileCheck --check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck --check-prefixes=CHECK-ASM-AND-OBJ %s + # CHECK-ASM-AND-OBJ: clb a2, 17(ca0) # CHECK-ASM-SAME: encoding: [0x03,0x06,0x15,0x01] clb a2, 17(ca0) diff --git a/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s index bfdd5e0dc057..c28846a27284 100644 --- a/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s @@ -1,9 +1,17 @@ -# RUN: llvm-mc %s -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s\ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xcheri,+cap-mode < %s \ # RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ # RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +## Same test again without the "c" prefix on all lines +# RUN: sed -e 's/^c//' < %s > %t.s +# RUN: llvm-mc -triple=riscv64 -mattr=+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %t.s\ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + # Capability load/store uses different encodings for RV32 vs RV64 # CHECK-ASM-AND-OBJ: clc ca2, 17(ca0) diff --git a/llvm/test/MC/RISCV/rvi-pseudos-invalid.s b/llvm/test/MC/RISCV/rvi-pseudos-invalid.s index 9d9849ba0ac0..f0c45938a293 100644 --- a/llvm/test/MC/RISCV/rvi-pseudos-invalid.s +++ b/llvm/test/MC/RISCV/rvi-pseudos-invalid.s @@ -22,7 +22,7 @@ la x1, %hi(foo) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name la x1, %lo(foo) # CHECK: :[[@LINE]]:8: error: operand must be a bare symbol name sw a2, %hi(a_symbol), a3 # CHECK: :[[@LINE]]:8: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047] -sw a2, %lo(a_symbol), a3 # CHECK: :[[@LINE]]:23: error: invalid operand for instruction +sw a2, %lo(a_symbol), a3 # CHECK: :[[@LINE]]:23: error: operand must be a bare symbol name sw a2, %lo(a_symbol)(a4), a3 # CHECK: :[[@LINE]]:27: error: invalid operand for instruction # Too few operands must be rejected From 70cf4c64bc31c5b100e6902b8f521753abbe06f9 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Sun, 25 Aug 2024 23:14:42 -0700 Subject: [PATCH 07/11] [CHERI-RISC-V] Allow load/store mnemonics without the c prefix [2/n] As a follow-up to the last commit this includes the aliases without an immediate offset. --- llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 64 ++++++++----------- .../cheri/rv32xcheri-cap-mode-only-valid.s | 7 ++ .../RISCV/cheri/rv32xcheri-cap-mode-valid.s | 29 +++++++++ .../cheri/rv64xcheri-cap-mode-only-valid.s | 18 ++++++ 4 files changed, 81 insertions(+), 37 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index 4e69aa529295..b6231ff0c5c5 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -732,6 +732,13 @@ def : InstAlias<"cjalr $rs, $offset", (CJALR C1, GPCR:$rs, simm12:$of def : InstAlias<"cjalr $rd, $rs, $offset", (CJALR GPCR:$rd, GPCR:$rs, simm12:$offset), 0>; } // Predicates = [HasCheri, IsCapMode] +// Expands to an instruction alias with and without a c prefix for loads/stores +multiclass CPrefixedInstAlias { + def : InstAlias<"c" # Asm, Result, 0>; + def : InstAlias; +} + + let Predicates = [HasCheri, IsCapMode] in { defm CLB : CheriLoad_ri<0b000, "lb">; defm CLH : CheriLoad_ri<0b001, "lh">; @@ -767,12 +774,10 @@ def CSC_64 : RVInstS<0x3, OPC_STORE, (outs), def : InstAlias<"sc $rs2, ${imm12}(${rs1})", (CSC_64 GPCR:$rs2, GPCR:$rs1, simm12:$imm12), 0>; -let EmitPriority = 0 in { -def : InstAlias<"clc $rd, (${rs1})", - (CLC_64 GPCR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"csc $rs2, (${rs1})", - (CSC_64 GPCR:$rs2, GPCR:$rs1, 0)>; -} +defm : CPrefixedInstAlias<"lc $rd, (${rs1})", + (CLC_64 GPCR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"sc $rs2, (${rs1})", + (CSC_64 GPCR:$rs2, GPCR:$rs1, 0)>; } let Predicates = [HasCheri, IsRV64, IsCapMode] in { @@ -792,44 +797,29 @@ def CSC_128 : RVInstS<0x4, OPC_STORE, (outs), def : InstAlias<"sc $rs2, ${imm12}(${rs1})", (CSC_128 GPCR:$rs2, GPCR:$rs1, simm12:$imm12), 0>; -let EmitPriority = 0 in { -def : InstAlias<"clc $rd, (${rs1})", - (CLC_128 GPCR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"csc $rs2, (${rs1})", - (CSC_128 GPCR:$rs2, GPCR:$rs1, 0)>; -} +defm : CPrefixedInstAlias<"lc $rd, (${rs1})", + (CLC_128 GPCR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"sc $rs2, (${rs1})", + (CSC_128 GPCR:$rs2, GPCR:$rs1, 0)>; } -let EmitPriority = 0 in { let Predicates = [HasCheri, IsCapMode] in { -def : InstAlias<"clb $rd, (${rs1})", - (CLB GPR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"clh $rd, (${rs1})", - (CLH GPR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"clw $rd, (${rs1})", - (CLW GPR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"clbu $rd, (${rs1})", - (CLBU GPR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"clhu $rd, (${rs1})", - (CLHU GPR:$rd, GPCR:$rs1, 0)>; - -def : InstAlias<"csb $rs2, (${rs1})", - (CSB GPR:$rs2, GPCR:$rs1, 0)>; -def : InstAlias<"csh $rs2, (${rs1})", - (CSH GPR:$rs2, GPCR:$rs1, 0)>; -def : InstAlias<"csw $rs2, (${rs1})", - (CSW GPR:$rs2, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"lb $rd, (${rs1})", (CLB GPR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"lh $rd, (${rs1})", (CLH GPR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"lw $rd, (${rs1})", (CLW GPR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"lbu $rd, (${rs1})", (CLBU GPR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"lhu $rd, (${rs1})", (CLHU GPR:$rd, GPCR:$rs1, 0)>; + +defm : CPrefixedInstAlias<"sb $rs2, (${rs1})", (CSB GPR:$rs2, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"sh $rs2, (${rs1})", (CSH GPR:$rs2, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"sw $rs2, (${rs1})", (CSW GPR:$rs2, GPCR:$rs1, 0)>; } // Predicates = [HasCheri, IsCapMode] let Predicates = [HasCheri, IsRV64, IsCapMode] in { -def : InstAlias<"clwu $rd, (${rs1})", - (CLWU GPR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"cld $rd, (${rs1})", - (CLD GPR:$rd, GPCR:$rs1, 0)>; -def : InstAlias<"csd $rs2, (${rs1})", - (CSD GPR:$rs2, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"lwu $rd, (${rs1})", (CLWU GPR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"ld $rd, (${rs1})", (CLD GPR:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"sd $rs2, (${rs1})", (CSD GPR:$rs2, GPCR:$rs1, 0)>; } // Predicates = [HasCheri, IsRV64, IsCapMode] -} /// 'A' (Atomic Instructions) extension diff --git a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s index 78d3ad361095..f4418e7b19a5 100644 --- a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-only-valid.s @@ -21,3 +21,10 @@ clc ca2, 17(ca0) # CHECK-ASM-SAME: encoding: [0xa3,0xbc,0xf6,0x00] csc ca5, 25(ca3) + +# CHECK-ASM-AND-OBJ: clc ca2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x36,0x05,0x00] +clc ca2, (ca0) +# CHECK-ASM-AND-OBJ: csc ca5, 0(ca3) +# CHECK-ASM-SAME: encoding: [0x23,0xb0,0xf6,0x00] +csc ca5, (ca3) diff --git a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s index 4660e37aed62..aa1699f1e56e 100644 --- a/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32xcheri-cap-mode-valid.s @@ -50,3 +50,32 @@ clbu ra, 17(csp) # CHECK-ASM-AND-OBJ: clhu ra, 17(csp) # CHECK-ASM-SAME: encoding: [0x83,0x50,0x11,0x01] clhu ra, 17(csp) + +# CHECK-ASM-AND-OBJ: clb a2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x06,0x05,0x00] +clb a2, (ca0) +# CHECK-ASM-AND-OBJ: csb a5, 0(ca3) +# CHECK-ASM-SAME: encoding: [0x23,0x80,0xf6,0x00] +csb a5, (ca3) + +# CHECK-ASM-AND-OBJ: clh a2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x16,0x05,0x00] +clh a2, (ca0) +# CHECK-ASM-AND-OBJ: csh a5, 0(ca3) +# CHECK-ASM-SAME: encoding: [0x23,0x90,0xf6,0x00] +csh a5, (ca3) + +# CHECK-ASM-AND-OBJ: clw ra, 0(csp) +# CHECK-ASM-SAME: encoding: [0x83,0x20,0x01,0x00] +clw ra, (csp) +# CHECK-ASM-AND-OBJ: csw ra, 0(csp) +# CHECK-ASM-SAME: encoding: [0x23,0x20,0x11,0x00] +csw ra, (csp) + +# CHECK-ASM-AND-OBJ: clbu ra, 0(csp) +# CHECK-ASM-SAME: encoding: [0x83,0x40,0x01,0x00] +clbu ra, (csp) + +# CHECK-ASM-AND-OBJ: clhu ra, 0(csp) +# CHECK-ASM-SAME: encoding: [0x83,0x50,0x01,0x00] +clhu ra, (csp) diff --git a/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s index c28846a27284..aa9cf214b427 100644 --- a/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv64xcheri-cap-mode-only-valid.s @@ -31,3 +31,21 @@ csd a5, 25(ca3) # CHECK-ASM-AND-OBJ: clwu a2, 17(ca0) # CHECK-ASM-SAME: encoding: [0x03,0x66,0x15,0x01] clwu a2, 17(ca0) + +# CHECK-ASM-AND-OBJ: clc ca2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x0f,0x26,0x05,0x00] +clc ca2, (ca0) +# CHECK-ASM-AND-OBJ: csc ca5, 0(ca3) +# CHECK-ASM-SAME: encoding: [0x23,0xc0,0xf6,0x00] +csc ca5, (ca3) + +# CHECK-ASM-AND-OBJ: cld a2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x36,0x05,0x00] +cld a2, (ca0) +# CHECK-ASM-AND-OBJ: csd a5, 0(ca3) +# CHECK-ASM-SAME: encoding: [0x23,0xb0,0xf6,0x00] +csd a5, (ca3) + +# CHECK-ASM-AND-OBJ: clwu a2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x03,0x66,0x05,0x00] +clwu a2, (ca0) From 3d32b930bebda52ee163fb85fe9289373cedb8c2 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 26 Aug 2024 00:01:03 -0700 Subject: [PATCH 08/11] [CHERI-RISC-V] Allow load/store mnemonics without the c prefix [3/n] This adds the atomic operations --- llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 206 ++++++++++-------- .../cheri/rv32axcheri-cap-mode-invalid.s | 1 + .../cheri/rv32axcheri-cap-mode-only-valid.s | 10 +- .../RISCV/cheri/rv32axcheri-cap-mode-valid.s | 17 +- .../cheri/rv64axcheri-cap-mode-invalid.s | 1 + .../RISCV/cheri/rv64axcheri-cap-mode-valid.s | 11 +- 6 files changed, 153 insertions(+), 93 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index b6231ff0c5c5..ffd9a4ebbdac 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -236,65 +236,95 @@ multiclass CheriStore_ri funct3, string opcodestr> { 0>; } -let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in -class CLR_r funct3, string opcodestr> - : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO, - (outs GPR:$rd), (ins GPCRMemZeroOffset:$rs1), - opcodestr, "$rd, $rs1"> { - let rs2 = 0; -} -multiclass CLR_r_aq_rl funct3, string opcodestr> { - def "" : CLR_r<0, 0, funct3, opcodestr>; - def _AQ : CLR_r<1, 0, funct3, opcodestr # ".aq">; - def _RL : CLR_r<0, 1, funct3, opcodestr # ".rl">; - def _AQ_RL : CLR_r<1, 1, funct3, opcodestr # ".aqrl">; +multiclass CLR_r funct3, string opcodestr, + string Namespace> { + let hasSideEffects = 0, mayLoad = 1, mayStore = 0, + DecoderNamespace = Namespace in + def "" : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO, + (outs GPR:$rd), (ins GPCRMemZeroOffset:$rs1), + "c" # opcodestr, "$rd, $rs1"> { + let rs2 = 0; + } + def : InstAlias(NAME) GPR:$rd, GPCRMemZeroOffset:$rs1), + 0>; } -let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in -class CAMO_rr funct5, bit aq, bit rl, bits<3> funct3, string opcodestr> - : RVInstRAtomic; - -multiclass CAMO_rr_aq_rl funct5, bits<3> funct3, string opcodestr> { - def "" : CAMO_rr; - def _AQ : CAMO_rr; - def _RL : CAMO_rr; - def _AQ_RL : CAMO_rr; +multiclass CLR_r_aq_rl funct3, string opcodestr, + string Namespace = "CapModeOnly_"> { + defm "" : CLR_r<0, 0, funct3, opcodestr, Namespace>; + defm _AQ : CLR_r<1, 0, funct3, opcodestr # ".aq", Namespace>; + defm _RL : CLR_r<0, 1, funct3, opcodestr # ".rl", Namespace>; + defm _AQ_RL : CLR_r<1, 1, funct3, opcodestr # ".aqrl", Namespace>; +} + +multiclass CAMO_rr funct5, bit aq, bit rl, bits<3> funct3, + string opcodestr, string Namespace> { + let hasSideEffects = 0, mayLoad = 1, mayStore = 1, + DecoderNamespace = Namespace in + def "" : RVInstRAtomic; + def : InstAlias(NAME) GPR:$rd, GPCRMemZeroOffset:$rs1, + GPR:$rs2), 0>; +} + +multiclass CAMO_rr_aq_rl funct5, bits<3> funct3, string opcodestr, + string Namespace = "CapModeOnly_"> { + defm "" : CAMO_rr; + defm _AQ : CAMO_rr; + defm _RL : CAMO_rr; + defm _AQ_RL : CAMO_rr; +} + +multiclass CLR_C_r funct3, string opcodestr, + string Namespace> { +let hasSideEffects = 0, mayLoad = 1, mayStore = 0, + DecoderNamespace = Namespace in + def "" : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO, + (outs GPCR:$rd), (ins GPCRMemZeroOffset:$rs1), + "c" # opcodestr, "$rd, $rs1"> { + let rs2 = 0; + } + def : InstAlias(NAME) GPCR:$rd, GPCRMemZeroOffset:$rs1), + 0>; } -let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in -class CLR_C_r funct3, string opcodestr> - : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO, - (outs GPCR:$rd), (ins GPCRMemZeroOffset:$rs1), - opcodestr, "$rd, $rs1"> { - let rs2 = 0; +multiclass CLR_C_r_aq_rl funct3, string opcodestr, + string Namespace = "CapModeOnly_"> { + defm _ # clenstr : CLR_C_r<0, 0, funct3, opcodestr, Namespace>; + defm _AQ_ # clenstr : CLR_C_r<1, 0, funct3, opcodestr # ".aq", Namespace>; + defm _RL_ # clenstr : CLR_C_r<0, 1, funct3, opcodestr # ".rl", Namespace>; + defm _AQ_RL_ # clenstr : CLR_C_r<1, 1, funct3, opcodestr # ".aqrl", Namespace>; } -multiclass CLR_C_r_aq_rl funct3, string opcodestr> { - def _ # clenstr : CLR_C_r<0, 0, funct3, opcodestr>; - def _AQ_ # clenstr : CLR_C_r<1, 0, funct3, opcodestr # ".aq">; - def _RL_ # clenstr : CLR_C_r<0, 1, funct3, opcodestr # ".rl">; - def _AQ_RL_ # clenstr : CLR_C_r<1, 1, funct3, opcodestr # ".aqrl">; +multiclass CAMO_C_rr funct5, bit aq, bit rl, bits<3> funct3, + string opcodestr, RegisterClass rdClass, string Namespace> { + let hasSideEffects = 0, mayLoad = 1, mayStore = 1, + DecoderNamespace = Namespace in + def "" : RVInstRAtomic; + def : InstAlias(NAME) rdClass:$rd, GPCRMemZeroOffset:$rs1, + GPCR:$rs2), 0>; } -let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in -class CAMO_C_rr funct5, bit aq, bit rl, bits<3> funct3, - string opcodestr, RegisterClass rdClass> - : RVInstRAtomic; - multiclass CAMO_C_rr_aq_rl funct5, bits<3> funct3, - string opcodestr, RegisterClass rdClass> { - def _ # clenstr : CAMO_C_rr; - def _AQ_ # clenstr : CAMO_C_rr; - def _RL_ # clenstr : CAMO_C_rr; - def _AQ_RL_ # clenstr : CAMO_C_rr; + string opcodestr, RegisterClass rdClass, + string Namespace = "CapModeOnly_"> { + defm _ # clenstr : CAMO_C_rr; + defm _AQ_ # clenstr : CAMO_C_rr; + defm _RL_ # clenstr : CAMO_C_rr; + defm _AQ_RL_ # clenstr : CAMO_C_rr; } let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in @@ -823,54 +853,52 @@ defm : CPrefixedInstAlias<"sd $rs2, (${rs1})", (CSD GPR:$rs2, GPCR:$rs1, 0)>; /// 'A' (Atomic Instructions) extension -let DecoderNamespace = "CapModeOnly_" in { let Predicates = [HasCheri, HasStdExtA, IsCapMode] in { -defm CLR_B : CLR_r_aq_rl<0b000, "clr.b">; -defm CSC_B : CAMO_rr_aq_rl<0b00011, 0b000, "csc.b">; - -defm CLR_H : CLR_r_aq_rl<0b001, "clr.h">; -defm CSC_H : CAMO_rr_aq_rl<0b00011, 0b001, "csc.h">; - -defm CLR_W : CLR_r_aq_rl<0b010, "clr.w">; -defm CSC_W : CAMO_rr_aq_rl<0b00011, 0b010, "csc.w">; -defm CAMOSWAP_W : CAMO_rr_aq_rl<0b00001, 0b010, "camoswap.w">; -defm CAMOADD_W : CAMO_rr_aq_rl<0b00000, 0b010, "camoadd.w">; -defm CAMOXOR_W : CAMO_rr_aq_rl<0b00100, 0b010, "camoxor.w">; -defm CAMOAND_W : CAMO_rr_aq_rl<0b01100, 0b010, "camoand.w">; -defm CAMOOR_W : CAMO_rr_aq_rl<0b01000, 0b010, "camoor.w">; -defm CAMOMIN_W : CAMO_rr_aq_rl<0b10000, 0b010, "camomin.w">; -defm CAMOMAX_W : CAMO_rr_aq_rl<0b10100, 0b010, "camomax.w">; -defm CAMOMINU_W : CAMO_rr_aq_rl<0b11000, 0b010, "camominu.w">; -defm CAMOMAXU_W : CAMO_rr_aq_rl<0b11100, 0b010, "camomaxu.w">; +defm CLR_B : CLR_r_aq_rl<0b000, "lr.b">; +defm CSC_B : CAMO_rr_aq_rl<0b00011, 0b000, "sc.b">; + +defm CLR_H : CLR_r_aq_rl<0b001, "lr.h">; +defm CSC_H : CAMO_rr_aq_rl<0b00011, 0b001, "sc.h">; + +defm CLR_W : CLR_r_aq_rl<0b010, "lr.w">; +defm CSC_W : CAMO_rr_aq_rl<0b00011, 0b010, "sc.w">; +defm CAMOSWAP_W : CAMO_rr_aq_rl<0b00001, 0b010, "amoswap.w">; +defm CAMOADD_W : CAMO_rr_aq_rl<0b00000, 0b010, "amoadd.w">; +defm CAMOXOR_W : CAMO_rr_aq_rl<0b00100, 0b010, "amoxor.w">; +defm CAMOAND_W : CAMO_rr_aq_rl<0b01100, 0b010, "amoand.w">; +defm CAMOOR_W : CAMO_rr_aq_rl<0b01000, 0b010, "amoor.w">; +defm CAMOMIN_W : CAMO_rr_aq_rl<0b10000, 0b010, "amomin.w">; +defm CAMOMAX_W : CAMO_rr_aq_rl<0b10100, 0b010, "amomax.w">; +defm CAMOMINU_W : CAMO_rr_aq_rl<0b11000, 0b010, "amominu.w">; +defm CAMOMAXU_W : CAMO_rr_aq_rl<0b11100, 0b010, "amomaxu.w">; } // Predicates = [HasCheri, HasStdExtA, IsCapMode] let Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode] in { -defm CLR_D : CLR_r_aq_rl<0b011, "clr.d">; -defm CSC_D : CAMO_rr_aq_rl<0b00011, 0b011, "csc.d">; -defm CAMOSWAP_D : CAMO_rr_aq_rl<0b00001, 0b011, "camoswap.d">; -defm CAMOADD_D : CAMO_rr_aq_rl<0b00000, 0b011, "camoadd.d">; -defm CAMOXOR_D : CAMO_rr_aq_rl<0b00100, 0b011, "camoxor.d">; -defm CAMOAND_D : CAMO_rr_aq_rl<0b01100, 0b011, "camoand.d">; -defm CAMOOR_D : CAMO_rr_aq_rl<0b01000, 0b011, "camoor.d">; -defm CAMOMIN_D : CAMO_rr_aq_rl<0b10000, 0b011, "camomin.d">; -defm CAMOMAX_D : CAMO_rr_aq_rl<0b10100, 0b011, "camomax.d">; -defm CAMOMINU_D : CAMO_rr_aq_rl<0b11000, 0b011, "camominu.d">; -defm CAMOMAXU_D : CAMO_rr_aq_rl<0b11100, 0b011, "camomaxu.d">; +defm CLR_D : CLR_r_aq_rl<0b011, "lr.d">; +defm CSC_D : CAMO_rr_aq_rl<0b00011, 0b011, "sc.d">; +defm CAMOSWAP_D : CAMO_rr_aq_rl<0b00001, 0b011, "amoswap.d">; +defm CAMOADD_D : CAMO_rr_aq_rl<0b00000, 0b011, "amoadd.d">; +defm CAMOXOR_D : CAMO_rr_aq_rl<0b00100, 0b011, "amoxor.d">; +defm CAMOAND_D : CAMO_rr_aq_rl<0b01100, 0b011, "amoand.d">; +defm CAMOOR_D : CAMO_rr_aq_rl<0b01000, 0b011, "amoor.d">; +defm CAMOMIN_D : CAMO_rr_aq_rl<0b10000, 0b011, "amomin.d">; +defm CAMOMAX_D : CAMO_rr_aq_rl<0b10100, 0b011, "amomax.d">; +defm CAMOMINU_D : CAMO_rr_aq_rl<0b11000, 0b011, "amominu.d">; +defm CAMOMAXU_D : CAMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">; } // Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode] -} // DecoderNamespace = "CapModeOnly_" -let DecoderNamespace = "RISCV32CapModeOnly_", - Predicates = [HasCheri, HasStdExtA, IsRV32, IsCapMode] in { -defm CLR_C : CLR_C_r_aq_rl<"64", 0b011, "clr.c">; -defm CSC_C : CAMO_C_rr_aq_rl<"64", 0b00011, 0b011, "csc.c", GPR>; -defm CAMOSWAP_C : CAMO_C_rr_aq_rl<"64", 0b00001, 0b011, "camoswap.c", GPCR>; +let Predicates = [HasCheri, HasStdExtA, IsRV32, IsCapMode] in { +defm CLR_C : CLR_C_r_aq_rl<"64", 0b011, "lr.c", "RISCV32CapModeOnly_">; +defm CSC_C : CAMO_C_rr_aq_rl<"64", 0b00011, 0b011, "sc.c", GPR, + "RISCV32CapModeOnly_">; +defm CAMOSWAP_C : CAMO_C_rr_aq_rl<"64", 0b00001, 0b011, "amoswap.c", GPCR, + "RISCV32CapModeOnly_">; } -let DecoderNamespace = "CapModeOnly_", - Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode] in { -defm CLR_C : CLR_C_r_aq_rl<"128", 0b100, "clr.c">; -defm CSC_C : CAMO_C_rr_aq_rl<"128", 0b00011, 0b100, "csc.c", GPR>; -defm CAMOSWAP_C : CAMO_C_rr_aq_rl<"128", 0b00001, 0b100, "camoswap.c", GPCR>; +let Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode] in { +defm CLR_C : CLR_C_r_aq_rl<"128", 0b100, "lr.c">; +defm CSC_C : CAMO_C_rr_aq_rl<"128", 0b00011, 0b100, "sc.c", GPR>; +defm CAMOSWAP_C : CAMO_C_rr_aq_rl<"128", 0b00001, 0b100, "amoswap.c", GPCR>; } /// 'F' (Single-Precision Floating-Point) extension diff --git a/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-invalid.s b/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-invalid.s index a60e550c2bc2..5f49ac1ec185 100644 --- a/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-invalid.s +++ b/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-invalid.s @@ -5,6 +5,7 @@ camoswap.w a1, a2, c3 # CHECK: :[[@LINE]]:20: error: expected '(' or optional in camomin.w a1, a2, 1 # CHECK: :[[@LINE]]:21: error: expected '(' after optional integer offset camomin.w a1, a2, 1(c3) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 clr.w a4, c5 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset +clr.w a4, (a5) # CHECK: :[[@LINE]]:12: error: invalid operand for instruction # Only .aq, .rl, and .aqrl suffixes are valid camoxor.w.rlqa a2, a3, (c4) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic diff --git a/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-only-valid.s index 7faf0daad8b1..23275f2c9c4d 100644 --- a/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-only-valid.s @@ -1,9 +1,17 @@ -# RUN: llvm-mc %s -triple=riscv32 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv32 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+xcheri,+cap-mode < %s \ # RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ # RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +## Same test again without the "c" prefix on all lines +# RUN: sed -e 's/^c//' < %s > %t.s +# RUN: llvm-mc -triple=riscv32 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %t.s \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + # CHECK-ASM-AND-OBJ: clr.c ct0, (ct1) # CHECK-ASM: encoding: [0xaf,0x32,0x03,0x10] clr.c ct0, (ct1) diff --git a/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-valid.s index b51b177eaad2..9e6db9062e91 100644 --- a/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32axcheri-cap-mode-valid.s @@ -1,6 +1,6 @@ -# RUN: llvm-mc %s -triple=riscv32 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv32 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s\ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s -# RUN: llvm-mc %s -triple=riscv64 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv64 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s\ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+xcheri,+cap-mode < %s \ # RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ @@ -9,6 +9,19 @@ # RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ # RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +## Same test again without the "c" prefix on all lines +# RUN: sed -e 's/^c//' < %s > %t.s +# RUN: llvm-mc %t.s -triple=riscv32 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %t.s -triple=riscv64 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+a,+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + # CHECK-ASM-AND-OBJ: clr.b t0, (ct1) # CHECK-ASM: encoding: [0xaf,0x02,0x03,0x10] clr.b t0, (ct1) diff --git a/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-invalid.s b/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-invalid.s index e702401f5d68..731fdc5c5ff0 100644 --- a/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-invalid.s +++ b/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-invalid.s @@ -5,6 +5,7 @@ camoswap.d a1, a2, ca3 # CHECK: :[[@LINE]]:20: error: expected '(' or optional i camomin.d a1, a2, 1 # CHECK: :[[@LINE]]:21: error: expected '(' after optional integer offset camomin.d a1, a2, 1(ca3) # CHECK: :[[@LINE]]:19: error: optional integer offset must be 0 clr.d a4, a5 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset +clr.d a4, (a5) # CHECK: :[[@LINE]]:12: error: invalid operand for instruction # Only .aq, .rl, and .aqrl suffixes are valid camoxor.d.rlqa a2, a3, (ca4) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic diff --git a/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-valid.s index c1093498a99e..b61bbd13516e 100644 --- a/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv64axcheri-cap-mode-valid.s @@ -1,9 +1,18 @@ -# RUN: llvm-mc %s -triple=riscv64 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding \ +# RUN: llvm-mc -triple=riscv64 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %s \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+xcheri,+cap-mode < %s \ # RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ # RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +## Same test again without the "c" prefix on all lines +# RUN: sed -e 's/^c//' < %s > %t.s +# RUN: llvm-mc -triple=riscv64 -mattr=+a,+xcheri,+cap-mode -riscv-no-aliases -show-encoding < %t.s \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+a,+xcheri,+cap-mode < %t.s \ +# RUN: | llvm-objdump --mattr=+a,+xcheri,+cap-mode -M no-aliases -d -r - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + + # CHECK-ASM-AND-OBJ: clr.d t0, (ct1) # CHECK-ASM: encoding: [0xaf,0x32,0x03,0x10] clr.d t0, (ct1) From 3b58c004382b67f0934d77bf06270bee9e0f2f50 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 26 Aug 2024 23:14:50 -0700 Subject: [PATCH 09/11] [CHERI-RISC-V] Allow load/store mnemonics without the c prefix [4/n] This adds support for compressed instructions. Does not yet include Zcb or floating-point loads/stores. --- llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 14 ++++++++++ .../cheri/rv32cxcheri-cap-mode-invalid.s | 8 ++++++ .../cheri/rv32cxcheri-cap-mode-only-valid.s | 14 +++++++++- .../RISCV/cheri/rv32cxcheri-cap-mode-valid.s | 12 +++++++++ .../cheri/rv64cxcheri-cap-mode-only-valid.s | 26 ++++++++++++++++++- 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index ffd9a4ebbdac..378bf228d2d0 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -1135,7 +1135,21 @@ def : InstAlias<"c.cincoffsetimm4cspn $rd, $rs1, $imm", (C_CIncOffsetImm4CSPN GPCRC:$rd, CSP:$rs1, uimm10_lsb00nonzero:$imm), 0>; def : InstAlias<"c.cincoffsetimm16csp $rd, $imm", (C_CIncOffsetImm16CSP CSP:$rd, simm10_lsb0000nonzero:$imm), 0>; +def : MnemonicAlias<"c.lw", "c.clw">; +def : MnemonicAlias<"c.sw", "c.csw">; +def : MnemonicAlias<"c.sc", "c.csc">; +def : MnemonicAlias<"c.lc", "c.clc">; +def : MnemonicAlias<"c.lwsp", "c.clwcsp">; +def : MnemonicAlias<"c.swsp", "c.cswcsp">; +def : MnemonicAlias<"c.scsp", "c.csccsp">; +def : MnemonicAlias<"c.lcsp", "c.clccsp">; } // Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsCapMode] +let Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsRV64, IsCapMode] in { +def : MnemonicAlias<"c.ld", "c.cld">; +def : MnemonicAlias<"c.sd", "c.csd">; +def : MnemonicAlias<"c.ldsp", "c.cldcsp">; +def : MnemonicAlias<"c.sdsp", "c.csdcsp">; +} // Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsRV64, IsCapMode] //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns diff --git a/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-invalid.s b/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-invalid.s index 8887af28b32e..5907f9fd5f33 100644 --- a/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-invalid.s +++ b/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-invalid.s @@ -29,6 +29,14 @@ c.csw a5, 1(ca3) # TODO-RV64-NO-C: :[[#@LINE-5]]:11: error: instruction requires the following: 'C' (Compressed Instructions){{$}} # CHECK-RV64-NO-C: :[[#@LINE-6]]:11: error: invalid operand for instruction +c.csw a5, 4(a3) +# CHECK: :[[#@LINE-1]]:13: error: invalid operand for instruction +c.sw a5, 4(a3) +# CHECK-RV32-NO-C: :[[#@LINE-1]]:1: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores), Not Capability Mode +# CHECK-RV32-C: :[[#@LINE-2]]:12: error: invalid operand for instruction +# CHECK-RV64-NO-C: :[[#@LINE-3]]:1: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores), Not Capability Mode +# CHECK-RV64-C: :[[#@LINE-4]]:12: error: invalid operand for instruction + # Bad operands: c.cjalr a1 # CHECK: :[[#@LINE-1]]:9: error: invalid operand for instruction diff --git a/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-only-valid.s index 5c93926148d0..b4635582a53e 100644 --- a/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-only-valid.s @@ -9,18 +9,30 @@ # CHECK-ASM-AND-OBJ: c.clccsp cra, 40(csp) # CHECK-ASM-SAME: encoding: [0xa2,0x70] c.clccsp cra, 40(csp) +# CHECK-ASM-AND-OBJ: c.clccsp cra, 40(csp) +# CHECK-ASM-SAME: encoding: [0xa2,0x70] +c.lcsp cra, 40(csp) # CHECK-ASM-AND-OBJ: c.csccsp cra, 256(csp) # CHECK-ASM-SAME: encoding: [0x06,0xe2] c.csccsp cra, 256(csp) +# CHECK-ASM-AND-OBJ: c.csccsp cra, 256(csp) +# CHECK-ASM-SAME: encoding: [0x06,0xe2] +c.scsp cra, 256(csp) # CHECK-ASM-AND-OBJ: c.clc ca2, 16(ca0) # CHECK-ASM-SAME: encoding: [0x10,0x69] c.clc ca2, 16(ca0) +# CHECK-ASM-AND-OBJ: c.clc ca2, 16(ca0) +# CHECK-ASM-SAME: encoding: [0x10,0x69] +c.lc ca2, 16(ca0) # CHECK-ASM-AND-OBJ: c.csc ca5, 128(ca3) # CHECK-ASM-SAME: encoding: [0xdc,0xe2] c.csc ca5, 128(ca3) +# CHECK-ASM-AND-OBJ: c.csc ca5, 128(ca3) +# CHECK-ASM-SAME: encoding: [0xdc,0xe2] +c.sc ca5, 128(ca3) ## C.JAL is only defined for RV32C: -# CHECK-OBJ: c.cjal 0x806 +# CHECK-OBJ: c.cjal 0x80e # CHECK-ASM: c.cjal 2046 # CHECK-ASM-SAME: encoding: [0xfd,0x2f] c.cjal 2046 diff --git a/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-valid.s index be147c486930..6dc9db876c43 100644 --- a/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32cxcheri-cap-mode-valid.s @@ -12,15 +12,27 @@ # CHECK-ASM-AND-OBJ: c.clwcsp ra, 0(csp) # CHECK-ASM-SAME: encoding: [0x82,0x40] c.clwcsp ra, 0(csp) +# CHECK-ASM-AND-OBJ: c.clwcsp ra, 0(csp) +# CHECK-ASM-SAME: encoding: [0x82,0x40] +c.lwsp ra, 0(csp) # CHECK-ASM-AND-OBJ: c.cswcsp ra, 252(csp) # CHECK-ASM-SAME: encoding: [0x86,0xdf] c.cswcsp ra, 252(csp) +# CHECK-ASM-AND-OBJ: c.cswcsp ra, 252(csp) +# CHECK-ASM-SAME: encoding: [0x86,0xdf] +c.swsp ra, 252(csp) # CHECK-ASM-AND-OBJ: c.clw a2, 0(ca0) # CHECK-ASM-SAME: encoding: [0x10,0x41] c.clw a2, 0(ca0) +# CHECK-ASM-AND-OBJ: c.clw a2, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x10,0x41] +c.lw a2, 0(ca0) # CHECK-ASM-AND-OBJ: c.csw a5, 124(ca3) # CHECK-ASM-SAME: encoding: [0xfc,0xde] c.csw a5, 124(ca3) +# CHECK-ASM-AND-OBJ: c.csw a5, 124(ca3) +# CHECK-ASM-SAME: encoding: [0xfc,0xde] +c.sw a5, 124(ca3) # CHECK-ASM-AND-OBJ: c.cjr ca7 # CHECK-ASM-SAME: encoding: [0x82,0x88] diff --git a/llvm/test/MC/RISCV/cheri/rv64cxcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv64cxcheri-cap-mode-only-valid.s index 87a16729b9d4..9aef8cfef0a0 100644 --- a/llvm/test/MC/RISCV/cheri/rv64cxcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv64cxcheri-cap-mode-only-valid.s @@ -8,25 +8,49 @@ # CHECK-ASM-AND-OBJ: c.clccsp cra, 32(csp) # CHECK-ASM-SAME: encoding: [0x82,0x30] c.clccsp cra, 32(csp) +# CHECK-ASM-AND-OBJ: c.clccsp cra, 32(csp) +# CHECK-ASM-SAME: encoding: [0x82,0x30] +c.lcsp cra, 32(csp) # CHECK-ASM-AND-OBJ-NEXT: c.csccsp cra, 256(csp) # CHECK-ASM-SAME: encoding: [0x06,0xa2] c.csccsp cra, 256(csp) +# CHECK-ASM-AND-OBJ-NEXT: c.csccsp cra, 256(csp) +# CHECK-ASM-SAME: encoding: [0x06,0xa2] +c.scsp cra, 256(csp) # CHECK-ASM-AND-OBJ-NEXT: c.clc ca2, 16(ca0) # CHECK-ASM-SAME: encoding: [0x10,0x29] c.clc ca2, 16(ca0) +# CHECK-ASM-AND-OBJ-NEXT: c.clc ca2, 16(ca0) +# CHECK-ASM-SAME: encoding: [0x10,0x29] +c.lc ca2, 16(ca0) # CHECK-ASM-AND-OBJ-NEXT: c.csc ca5, 128(ca3) # CHECK-ASM-SAME: encoding: [0xdc,0xa2] c.csc ca5, 128(ca3) +# CHECK-ASM-AND-OBJ-NEXT: c.csc ca5, 128(ca3) +# CHECK-ASM-SAME: encoding: [0xdc,0xa2] +c.sc ca5, 128(ca3) ## *D operations need RV64C: # CHECK-ASM-AND-OBJ-NEXT: c.cldcsp ra, 40(csp) # CHECK-ASM-SAME: encoding: [0xa2,0x70] c.cldcsp ra, 40(csp) +# CHECK-ASM-AND-OBJ-NEXT: c.cldcsp ra, 40(csp) +# CHECK-ASM-SAME: encoding: [0xa2,0x70] +c.ldsp ra, 40(csp) +# CHECK-ASM-AND-OBJ-NEXT: c.csdcsp ra, 256(csp) +# CHECK-ASM-SAME: encoding: [0x06,0xe2] +c.sdsp ra, 256(csp) # CHECK-ASM-AND-OBJ-NEXT: c.csdcsp ra, 256(csp) # CHECK-ASM-SAME: encoding: [0x06,0xe2] -c.csdcsp ra, 256(csp) +c.sdsp ra, 256(csp) # CHECK-ASM-AND-OBJ-NEXT: c.cld a2, 16(ca0) # CHECK-ASM-SAME: encoding: [0x10,0x69] c.cld a2, 16(ca0) +# CHECK-ASM-AND-OBJ-NEXT: c.cld a2, 16(ca0) +# CHECK-ASM-SAME: encoding: [0x10,0x69] +c.ld a2, 16(ca0) # CHECK-ASM-AND-OBJ-NEXT: c.csd a5, 128(ca3) # CHECK-ASM-SAME: encoding: [0xdc,0xe2] c.csd a5, 128(ca3) +# CHECK-ASM-AND-OBJ-NEXT: c.csd a5, 128(ca3) +# CHECK-ASM-SAME: encoding: [0xdc,0xe2] +c.sd a5, 128(ca3) From 72911949ac0c02e8c919985bd36a0062253a4f2b Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 26 Aug 2024 23:25:56 -0700 Subject: [PATCH 10/11] [CHERI-RISC-V] Add MC tests for floating point loads/stores --- .../cheri/rv32fdcxcheri-cap-mode-only-valid.s | 21 ++++++++++ .../RISCV/cheri/rv32fdxcheri-cap-mode-valid.s | 40 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s create mode 100644 llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s diff --git a/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s new file mode 100644 index 000000000000..16d3a5630ea4 --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s @@ -0,0 +1,21 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+c,+xcheri,+cap-mode,+f,+d -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+xcheri,+cap-mode,+f,+d < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+c,+xcheri,+cap-mode,+f,+d -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + +## Floating-point store is only supported in capmode for RV32 + +# CHECK-ASM-AND-OBJ: c.cfsd fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x08,0xb5] +c.cfsd fa0, 40(ca0) +# CHECK-ASM-AND-OBJ: c.cfld fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x08,0x35] +c.cfld fa0, 40(ca0) + +# CHECK-ASM-AND-OBJ: c.cfsdcsp ft1, 40(csp) +# CHECK-ASM-SAME: encoding: [0x06,0xb4] +c.cfsdcsp ft1, 40(csp) +# CHECK-ASM-AND-OBJ: c.cfldcsp ft1, 40(csp) +# CHECK-ASM-SAME: encoding: [0xa2,0x30] +c.cfldcsp ft1, 40(csp) diff --git a/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s new file mode 100644 index 000000000000..5c35b17f551f --- /dev/null +++ b/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s @@ -0,0 +1,40 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+xcheri,+cap-mode,+f,+d -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xcheri,+cap-mode,+f,+d < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode,+f,+d -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+xcheri,+cap-mode,+f,+d -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+xcheri,+cap-mode,+f,+d < %s \ +# RUN: | llvm-objdump -M no-aliases --mattr=+xcheri,+cap-mode,+f,+d -d - \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM-AND-OBJ %s + + +# CHECK-ASM-AND-OBJ: cfsd fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x34,0xa5,0x02] +cfsd fa0, 40(ca0) +# CHECK-ASM-AND-OBJ: cfld fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x07,0x35,0x85,0x02] +cfld fa0, 40(ca0) + +# CHECK-ASM-AND-OBJ: cfsw ft1, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x24,0x15,0x02] +cfsw ft1, 40(ca0) +# CHECK-ASM-AND-OBJ: cflw ft1, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x87,0x20,0x85,0x02] +cflw ft1, 40(ca0) + + +# CHECK-ASM-AND-OBJ: cfsd fa0, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x30,0xa5,0x00] +cfsd fa0, (ca0) +# CHECK-ASM-AND-OBJ: cfld fa0, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x07,0x35,0x05,0x00] +cfld fa0, (ca0) + +# CHECK-ASM-AND-OBJ: cfsw ft1, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x20,0x15,0x00] +cfsw ft1, (ca0) +# CHECK-ASM-AND-OBJ: cflw ft1, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x87,0x20,0x05,0x00] +cflw ft1, (ca0) From 35604c06494b8646af466c154e0144cd8c52ce5d Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 26 Aug 2024 23:45:39 -0700 Subject: [PATCH 11/11] [CHERI-RISC-V] Allow load/store mnemonics without the c prefix [5/n] This adds the floating point loads and stores and should conclude this series of patches. --- llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td | 25 ++++++++++++++++--- .../cheri/rv32fdcxcheri-cap-mode-only-valid.s | 12 +++++++++ .../RISCV/cheri/rv32fdxcheri-cap-mode-valid.s | 25 ++++++++++++++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td index 378bf228d2d0..535a2c658978 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCheri.td @@ -916,8 +916,13 @@ def CFSW : RVInstS<0b010, OPC_STORE_FP, (outs), (ins FPR32:$rs2, GPCR:$rs1, simm12:$imm12), "cfsw", "$rs2, ${imm12}(${rs1})">; -def : InstAlias<"cflw $rd, (${rs1})", (CFLW FPR32:$rd, GPCR:$rs1, 0), 0>; -def : InstAlias<"cfsw $rs2, (${rs1})", (CFSW FPR32:$rs2, GPCR:$rs1, 0), 0>; +defm : CPrefixedInstAlias<"flw $rd, (${rs1})", (CFLW FPR32:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"fsw $rs2, (${rs1})", + (CFSW FPR32:$rs2, GPCR:$rs1, 0)>; +def : InstAlias<"flw $rd, ${imm12}(${rs1})", + (CFLW FPR32:$rd, GPCR:$rs1, simm12:$imm12), 0>; +def : InstAlias<"fsw $rs2, ${imm12}(${rs1})", + (CFSW FPR32:$rs2, GPCR:$rs1, simm12:$imm12), 0>; } // Predicates = [HasCheri, HasStdExtF, IsCapMode] /// 'D' (Single-Precision Floating-Point) extension @@ -935,8 +940,13 @@ def CFSD : RVInstS<0b011, OPC_STORE_FP, (outs), (ins FPR64:$rs2, GPCR:$rs1, simm12:$imm12), "cfsd", "$rs2, ${imm12}(${rs1})">; -def : InstAlias<"cfld $rd, (${rs1})", (CFLD FPR64:$rd, GPCR:$rs1, 0), 0>; -def : InstAlias<"cfsd $rs2, (${rs1})", (CFSD FPR64:$rs2, GPCR:$rs1, 0), 0>; +defm : CPrefixedInstAlias<"fld $rd, (${rs1})", (CFLD FPR64:$rd, GPCR:$rs1, 0)>; +defm : CPrefixedInstAlias<"fsd $rs2, (${rs1})", + (CFSD FPR64:$rs2, GPCR:$rs1, 0)>; +def : InstAlias<"fld $rd, ${imm12}(${rs1})", + (CFLD FPR64:$rd, GPCR:$rs1, simm12:$imm12), 0>; +def : InstAlias<"fsd $rs2, ${imm12}(${rs1})", + (CFSD FPR64:$rs2, GPCR:$rs1, simm12:$imm12), 0>; } // Predicates = [HasCheri, HasStdExtD, IsCapMode] /// 'C' (Compressed Instructions) extension @@ -1150,6 +1160,13 @@ def : MnemonicAlias<"c.sd", "c.csd">; def : MnemonicAlias<"c.ldsp", "c.cldcsp">; def : MnemonicAlias<"c.sdsp", "c.csdcsp">; } // Predicates = [HasCheri, HasCheriRVC, HasStdExtC, IsRV64, IsCapMode] +let Predicates = [HasCheri, HasCheriRVC, HasStdExtC, HasStdExtD, IsRV32, + IsCapMode] in { +def : MnemonicAlias<"c.fld", "c.cfld">; +def : MnemonicAlias<"c.fsd", "c.cfsd">; +def : MnemonicAlias<"c.fldsp", "c.cfldcsp">; +def : MnemonicAlias<"c.fsdsp", "c.cfsdcsp">; +} //===----------------------------------------------------------------------===// // Pseudo-instructions and codegen patterns diff --git a/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s b/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s index 16d3a5630ea4..22cd8d15a8f9 100644 --- a/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32fdcxcheri-cap-mode-only-valid.s @@ -9,13 +9,25 @@ # CHECK-ASM-AND-OBJ: c.cfsd fa0, 40(ca0) # CHECK-ASM-SAME: encoding: [0x08,0xb5] c.cfsd fa0, 40(ca0) +# CHECK-ASM-AND-OBJ: c.cfsd fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x08,0xb5] +c.fsd fa0, 40(ca0) # CHECK-ASM-AND-OBJ: c.cfld fa0, 40(ca0) # CHECK-ASM-SAME: encoding: [0x08,0x35] c.cfld fa0, 40(ca0) +# CHECK-ASM-AND-OBJ: c.cfld fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x08,0x35] +c.fld fa0, 40(ca0) # CHECK-ASM-AND-OBJ: c.cfsdcsp ft1, 40(csp) # CHECK-ASM-SAME: encoding: [0x06,0xb4] c.cfsdcsp ft1, 40(csp) +# CHECK-ASM-AND-OBJ: c.cfsdcsp ft1, 40(csp) +# CHECK-ASM-SAME: encoding: [0x06,0xb4] +c.fsdsp ft1, 40(csp) # CHECK-ASM-AND-OBJ: c.cfldcsp ft1, 40(csp) # CHECK-ASM-SAME: encoding: [0xa2,0x30] c.cfldcsp ft1, 40(csp) +# CHECK-ASM-AND-OBJ: c.cfldcsp ft1, 40(csp) +# CHECK-ASM-SAME: encoding: [0xa2,0x30] +c.fldsp ft1, 40(csp) diff --git a/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s b/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s index 5c35b17f551f..8a6821100fce 100644 --- a/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s +++ b/llvm/test/MC/RISCV/cheri/rv32fdxcheri-cap-mode-valid.s @@ -13,6 +13,12 @@ # CHECK-ASM-AND-OBJ: cfsd fa0, 40(ca0) # CHECK-ASM-SAME: encoding: [0x27,0x34,0xa5,0x02] cfsd fa0, 40(ca0) +# CHECK-ASM-AND-OBJ: cfsd fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x34,0xa5,0x02] +fsd fa0, 40(ca0) +# CHECK-ASM-AND-OBJ: cfld fa0, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x07,0x35,0x85,0x02] +cfld fa0, 40(ca0) # CHECK-ASM-AND-OBJ: cfld fa0, 40(ca0) # CHECK-ASM-SAME: encoding: [0x07,0x35,0x85,0x02] cfld fa0, 40(ca0) @@ -20,21 +26,38 @@ cfld fa0, 40(ca0) # CHECK-ASM-AND-OBJ: cfsw ft1, 40(ca0) # CHECK-ASM-SAME: encoding: [0x27,0x24,0x15,0x02] cfsw ft1, 40(ca0) +# CHECK-ASM-AND-OBJ: cfsw ft1, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x24,0x15,0x02] +fsw ft1, 40(ca0) # CHECK-ASM-AND-OBJ: cflw ft1, 40(ca0) # CHECK-ASM-SAME: encoding: [0x87,0x20,0x85,0x02] cflw ft1, 40(ca0) - +# CHECK-ASM-AND-OBJ: cflw ft1, 40(ca0) +# CHECK-ASM-SAME: encoding: [0x87,0x20,0x85,0x02] +flw ft1, 40(ca0) # CHECK-ASM-AND-OBJ: cfsd fa0, 0(ca0) # CHECK-ASM-SAME: encoding: [0x27,0x30,0xa5,0x00] cfsd fa0, (ca0) +# CHECK-ASM-AND-OBJ: cfsd fa0, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x30,0xa5,0x00] +fsd fa0, (ca0) # CHECK-ASM-AND-OBJ: cfld fa0, 0(ca0) # CHECK-ASM-SAME: encoding: [0x07,0x35,0x05,0x00] cfld fa0, (ca0) +# CHECK-ASM-AND-OBJ: cfld fa0, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x07,0x35,0x05,0x00] +fld fa0, (ca0) # CHECK-ASM-AND-OBJ: cfsw ft1, 0(ca0) # CHECK-ASM-SAME: encoding: [0x27,0x20,0x15,0x00] cfsw ft1, (ca0) +# CHECK-ASM-AND-OBJ: cfsw ft1, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x27,0x20,0x15,0x00] +fsw ft1, (ca0) # CHECK-ASM-AND-OBJ: cflw ft1, 0(ca0) # CHECK-ASM-SAME: encoding: [0x87,0x20,0x05,0x00] cflw ft1, (ca0) +# CHECK-ASM-AND-OBJ: cflw ft1, 0(ca0) +# CHECK-ASM-SAME: encoding: [0x87,0x20,0x05,0x00] +flw ft1, (ca0)