aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-06-19 12:11:56 -0700
committerGitHub <noreply@github.com>2023-06-19 12:11:56 -0700
commit8b10de64dd2048e813438dbb5e4ed24d09feb8eb (patch)
tree75a90f0f823c1b8c21b6549d84985ce173d0ab20
parentb6dc274bcf6d18db229f5f6e1ae238e1a3c409b7 (diff)
parentf71bda9637366c2bb06612cf03ed126c628df678 (diff)
downloadriscv-isa-sim-8b10de64dd2048e813438dbb5e4ed24d09feb8eb.zip
riscv-isa-sim-8b10de64dd2048e813438dbb5e4ed24d09feb8eb.tar.gz
riscv-isa-sim-8b10de64dd2048e813438dbb5e4ed24d09feb8eb.tar.bz2
Merge pull request #1364 from glg-rv/dev/glguida/amocas
Zacas extension
-rw-r--r--disasm/disasm.cc6
-rw-r--r--fesvr/byteorder.h7
-rw-r--r--riscv/decode_macros.h5
-rw-r--r--riscv/encoding.h134
-rw-r--r--riscv/insns/amocas_d.h37
-rw-r--r--riscv/insns/amocas_q.h34
-rw-r--r--riscv/insns/amocas_w.h2
-rw-r--r--riscv/isa_parser.cc6
-rw-r--r--riscv/isa_parser.h1
-rw-r--r--riscv/mmu.cc17
-rw-r--r--riscv/mmu.h11
-rw-r--r--riscv/processor.cc5
-rw-r--r--riscv/riscv.mk.in6
13 files changed, 263 insertions, 8 deletions
diff --git a/disasm/disasm.cc b/disasm/disasm.cc
index 7834799..096c38f 100644
--- a/disasm/disasm.cc
+++ b/disasm/disasm.cc
@@ -815,6 +815,12 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
DEFINE_XAMO(sc_d)
}
+ if (isa->extension_enabled(EXT_ZACAS)) {
+ DEFINE_XAMO(amocas_w)
+ DEFINE_XAMO(amocas_d)
+ DEFINE_XAMO(amocas_q)
+ }
+
add_insn(new disasm_insn_t("j", match_jal, mask_jal | mask_rd, {&jump_target}));
add_insn(new disasm_insn_t("jal", match_jal | match_rd_ra, mask_jal | mask_rd, {&jump_target}));
add_insn(new disasm_insn_t("jal", match_jal, mask_jal, {&xrd, &jump_target}));
diff --git a/fesvr/byteorder.h b/fesvr/byteorder.h
index 2b1dbf9..d9e503a 100644
--- a/fesvr/byteorder.h
+++ b/fesvr/byteorder.h
@@ -15,6 +15,13 @@ static inline int16_t swap(int16_t n) { return int16_t(swap(uint16_t(n))); }
static inline int32_t swap(int32_t n) { return int32_t(swap(uint32_t(n))); }
static inline int64_t swap(int64_t n) { return int64_t(swap(uint64_t(n))); }
+#ifdef HAVE_INT128
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+static inline uint128_t swap(uint128_t n) { return (uint128_t(swap(uint64_t(n))) << 64) | swap(uint64_t(n >> 64)); }
+static inline int128_t swap(int128_t n) { return int128_t(swap(uint128_t(n))); }
+#endif
+
#ifdef WORDS_BIGENDIAN
template<typename T> static inline T from_be(T n) { return n; }
template<typename T> static inline T to_be(T n) { return n; }
diff --git a/riscv/decode_macros.h b/riscv/decode_macros.h
index 7ba132c..f39149b 100644
--- a/riscv/decode_macros.h
+++ b/riscv/decode_macros.h
@@ -10,11 +10,6 @@
#include "softfloat_types.h"
#include "specialize.h"
-#ifdef HAVE_INT128
-typedef __int128 int128_t;
-typedef unsigned __int128 uint128_t;
-#endif
-
// helpful macros, etc
#define MMU (*p->get_mmu())
#define STATE (*p->get_state())
diff --git a/riscv/encoding.h b/riscv/encoding.h
index e39f535..db7b021 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -4,7 +4,7 @@
/*
* This file is auto-generated by running 'make' in
- * https://github.com/riscv/riscv-opcodes (8d70e77)
+ * https://github.com/riscv/riscv-opcodes (3ca60c5)
*/
#ifndef RISCV_CSR_ENCODING_H
@@ -421,6 +421,12 @@
#define MASK_AMOAND_D 0xf800707f
#define MATCH_AMOAND_W 0x6000202f
#define MASK_AMOAND_W 0xf800707f
+#define MATCH_AMOCAS_D 0x2800302f
+#define MASK_AMOCAS_D 0xf800707f
+#define MATCH_AMOCAS_Q 0x2800402f
+#define MASK_AMOCAS_Q 0xf800707f
+#define MATCH_AMOCAS_W 0x2800202f
+#define MASK_AMOCAS_W 0xf800707f
#define MATCH_AMOMAX_D 0xa000302f
#define MASK_AMOMAX_D 0xf800707f
#define MATCH_AMOMAX_W 0xa000202f
@@ -1995,6 +2001,28 @@
#define MASK_VADD_VV 0xfc00707f
#define MATCH_VADD_VX 0x4057
#define MASK_VADD_VX 0xfc00707f
+#define MATCH_VAESDF_VS 0xa600a077
+#define MASK_VAESDF_VS 0xfe0ff07f
+#define MATCH_VAESDF_VV 0xa200a077
+#define MASK_VAESDF_VV 0xfe0ff07f
+#define MATCH_VAESDM_VS 0xa6002077
+#define MASK_VAESDM_VS 0xfe0ff07f
+#define MATCH_VAESDM_VV 0xa2002077
+#define MASK_VAESDM_VV 0xfe0ff07f
+#define MATCH_VAESEF_VS 0xa601a077
+#define MASK_VAESEF_VS 0xfe0ff07f
+#define MATCH_VAESEF_VV 0xa201a077
+#define MASK_VAESEF_VV 0xfe0ff07f
+#define MATCH_VAESEM_VS 0xa6012077
+#define MASK_VAESEM_VS 0xfe0ff07f
+#define MATCH_VAESEM_VV 0xa2012077
+#define MASK_VAESEM_VV 0xfe0ff07f
+#define MATCH_VAESKF1_VI 0x8a002077
+#define MASK_VAESKF1_VI 0xfe00707f
+#define MATCH_VAESKF2_VI 0xaa002077
+#define MASK_VAESKF2_VI 0xfe00707f
+#define MATCH_VAESZ_VS 0xa603a077
+#define MASK_VAESZ_VS 0xfe0ff07f
#define MATCH_VAMOADDEI16_V 0x502f
#define MASK_VAMOADDEI16_V 0xf800707f
#define MATCH_VAMOADDEI32_V 0x602f
@@ -2073,6 +2101,10 @@
#define MASK_VAND_VV 0xfc00707f
#define MATCH_VAND_VX 0x24004057
#define MASK_VAND_VX 0xfc00707f
+#define MATCH_VANDN_VV 0x4000057
+#define MASK_VANDN_VV 0xfc00707f
+#define MATCH_VANDN_VX 0x4004057
+#define MASK_VANDN_VX 0xfc00707f
#define MATCH_VASUB_VV 0x2c002057
#define MASK_VASUB_VV 0xfc00707f
#define MATCH_VASUB_VX 0x2c006057
@@ -2081,10 +2113,28 @@
#define MASK_VASUBU_VV 0xfc00707f
#define MATCH_VASUBU_VX 0x28006057
#define MASK_VASUBU_VX 0xfc00707f
+#define MATCH_VBREV8_V 0x48042057
+#define MASK_VBREV8_V 0xfc0ff07f
+#define MATCH_VBREV_V 0x48052057
+#define MASK_VBREV_V 0xfc0ff07f
+#define MATCH_VCLMUL_VV 0x30002057
+#define MASK_VCLMUL_VV 0xfc00707f
+#define MATCH_VCLMUL_VX 0x30006057
+#define MASK_VCLMUL_VX 0xfc00707f
+#define MATCH_VCLMULH_VV 0x34002057
+#define MASK_VCLMULH_VV 0xfc00707f
+#define MATCH_VCLMULH_VX 0x34006057
+#define MASK_VCLMULH_VX 0xfc00707f
+#define MATCH_VCLZ_V 0x48062057
+#define MASK_VCLZ_V 0xfc0ff07f
#define MATCH_VCOMPRESS_VM 0x5e002057
#define MASK_VCOMPRESS_VM 0xfe00707f
#define MATCH_VCPOP_M 0x40082057
#define MASK_VCPOP_M 0xfc0ff07f
+#define MATCH_VCPOP_V 0x48072057
+#define MASK_VCPOP_V 0xfc0ff07f
+#define MATCH_VCTZ_V 0x4806a057
+#define MASK_VCTZ_V 0xfc0ff07f
#define MATCH_VDIV_VV 0x84002057
#define MASK_VDIV_VV 0xfc00707f
#define MATCH_VDIV_VX 0x84006057
@@ -2285,6 +2335,10 @@
#define MASK_VFWSUB_WF 0xfc00707f
#define MATCH_VFWSUB_WV 0xd8001057
#define MASK_VFWSUB_WV 0xfc00707f
+#define MATCH_VGHSH_VV 0xb2002077
+#define MASK_VGHSH_VV 0xfe00707f
+#define MATCH_VGMUL_VV 0xa208a077
+#define MASK_VGMUL_VV 0xfe0ff07f
#define MATCH_VID_V 0x5008a057
#define MASK_VID_V 0xfdfff07f
#define MATCH_VIOTA_M 0x50082057
@@ -2631,6 +2685,8 @@
#define MASK_VREMU_VV 0xfc00707f
#define MATCH_VREMU_VX 0x88006057
#define MASK_VREMU_VX 0xfc00707f
+#define MATCH_VREV8_V 0x4804a057
+#define MASK_VREV8_V 0xfc0ff07f
#define MATCH_VRGATHER_VI 0x30003057
#define MASK_VRGATHER_VI 0xfc00707f
#define MATCH_VRGATHER_VV 0x30000057
@@ -2639,6 +2695,16 @@
#define MASK_VRGATHER_VX 0xfc00707f
#define MATCH_VRGATHEREI16_VV 0x38000057
#define MASK_VRGATHEREI16_VV 0xfc00707f
+#define MATCH_VROL_VV 0x54000057
+#define MASK_VROL_VV 0xfc00707f
+#define MATCH_VROL_VX 0x54004057
+#define MASK_VROL_VX 0xfc00707f
+#define MATCH_VROR_VI 0x50003057
+#define MASK_VROR_VI 0xf800707f
+#define MATCH_VROR_VV 0x50000057
+#define MASK_VROR_VV 0xfc00707f
+#define MATCH_VROR_VX 0x50004057
+#define MASK_VROR_VX 0xfc00707f
#define MATCH_VRSUB_VI 0xc003057
#define MASK_VRSUB_VI 0xfc00707f
#define MATCH_VRSUB_VX 0xc004057
@@ -2695,6 +2761,12 @@
#define MASK_VSEXT_VF4 0xfc0ff07f
#define MATCH_VSEXT_VF8 0x4801a057
#define MASK_VSEXT_VF8 0xfc0ff07f
+#define MATCH_VSHA2CH_VV 0xba002077
+#define MASK_VSHA2CH_VV 0xfe00707f
+#define MATCH_VSHA2CL_VV 0xbe002077
+#define MASK_VSHA2CL_VV 0xfe00707f
+#define MATCH_VSHA2MS_VV 0xb6002077
+#define MASK_VSHA2MS_VV 0xfe00707f
#define MATCH_VSLIDE1DOWN_VX 0x3c006057
#define MASK_VSLIDE1DOWN_VX 0xfc00707f
#define MATCH_VSLIDE1UP_VX 0x38006057
@@ -2713,6 +2785,16 @@
#define MASK_VSLL_VV 0xfc00707f
#define MATCH_VSLL_VX 0x94004057
#define MASK_VSLL_VX 0xfc00707f
+#define MATCH_VSM3C_VI 0xae002077
+#define MASK_VSM3C_VI 0xfe00707f
+#define MATCH_VSM3ME_VV 0x82002077
+#define MASK_VSM3ME_VV 0xfe00707f
+#define MATCH_VSM4K_VI 0x86002077
+#define MASK_VSM4K_VI 0xfe00707f
+#define MATCH_VSM4R_VS 0xa6082077
+#define MASK_VSM4R_VS 0xfe0ff07f
+#define MATCH_VSM4R_VV 0xa2082077
+#define MASK_VSM4R_VV 0xfe0ff07f
#define MATCH_VSM_V 0x2b00027
#define MASK_VSM_V 0xfff0707f
#define MATCH_VSMUL_VV 0x9c000057
@@ -2849,6 +2931,12 @@
#define MASK_VWREDSUM_VS 0xfc00707f
#define MATCH_VWREDSUMU_VS 0xc0000057
#define MASK_VWREDSUMU_VS 0xfc00707f
+#define MATCH_VWSLL_VI 0xd4003057
+#define MASK_VWSLL_VI 0xfc00707f
+#define MATCH_VWSLL_VV 0xd4000057
+#define MASK_VWSLL_VV 0xfc00707f
+#define MATCH_VWSLL_VX 0xd4004057
+#define MASK_VWSLL_VX 0xfc00707f
#define MATCH_VWSUB_VV 0xcc002057
#define MASK_VWSUB_VV 0xfc00707f
#define MATCH_VWSUB_VX 0xcc006057
@@ -3486,6 +3574,9 @@ DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
+DECLARE_INSN(amocas_d, MATCH_AMOCAS_D, MASK_AMOCAS_D)
+DECLARE_INSN(amocas_q, MATCH_AMOCAS_Q, MASK_AMOCAS_Q)
+DECLARE_INSN(amocas_w, MATCH_AMOCAS_W, MASK_AMOCAS_W)
DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
@@ -4273,6 +4364,17 @@ DECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM)
DECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI)
DECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV)
DECLARE_INSN(vadd_vx, MATCH_VADD_VX, MASK_VADD_VX)
+DECLARE_INSN(vaesdf_vs, MATCH_VAESDF_VS, MASK_VAESDF_VS)
+DECLARE_INSN(vaesdf_vv, MATCH_VAESDF_VV, MASK_VAESDF_VV)
+DECLARE_INSN(vaesdm_vs, MATCH_VAESDM_VS, MASK_VAESDM_VS)
+DECLARE_INSN(vaesdm_vv, MATCH_VAESDM_VV, MASK_VAESDM_VV)
+DECLARE_INSN(vaesef_vs, MATCH_VAESEF_VS, MASK_VAESEF_VS)
+DECLARE_INSN(vaesef_vv, MATCH_VAESEF_VV, MASK_VAESEF_VV)
+DECLARE_INSN(vaesem_vs, MATCH_VAESEM_VS, MASK_VAESEM_VS)
+DECLARE_INSN(vaesem_vv, MATCH_VAESEM_VV, MASK_VAESEM_VV)
+DECLARE_INSN(vaeskf1_vi, MATCH_VAESKF1_VI, MASK_VAESKF1_VI)
+DECLARE_INSN(vaeskf2_vi, MATCH_VAESKF2_VI, MASK_VAESKF2_VI)
+DECLARE_INSN(vaesz_vs, MATCH_VAESZ_VS, MASK_VAESZ_VS)
DECLARE_INSN(vamoaddei16_v, MATCH_VAMOADDEI16_V, MASK_VAMOADDEI16_V)
DECLARE_INSN(vamoaddei32_v, MATCH_VAMOADDEI32_V, MASK_VAMOADDEI32_V)
DECLARE_INSN(vamoaddei64_v, MATCH_VAMOADDEI64_V, MASK_VAMOADDEI64_V)
@@ -4312,12 +4414,23 @@ DECLARE_INSN(vamoxorei8_v, MATCH_VAMOXOREI8_V, MASK_VAMOXOREI8_V)
DECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI)
DECLARE_INSN(vand_vv, MATCH_VAND_VV, MASK_VAND_VV)
DECLARE_INSN(vand_vx, MATCH_VAND_VX, MASK_VAND_VX)
+DECLARE_INSN(vandn_vv, MATCH_VANDN_VV, MASK_VANDN_VV)
+DECLARE_INSN(vandn_vx, MATCH_VANDN_VX, MASK_VANDN_VX)
DECLARE_INSN(vasub_vv, MATCH_VASUB_VV, MASK_VASUB_VV)
DECLARE_INSN(vasub_vx, MATCH_VASUB_VX, MASK_VASUB_VX)
DECLARE_INSN(vasubu_vv, MATCH_VASUBU_VV, MASK_VASUBU_VV)
DECLARE_INSN(vasubu_vx, MATCH_VASUBU_VX, MASK_VASUBU_VX)
+DECLARE_INSN(vbrev8_v, MATCH_VBREV8_V, MASK_VBREV8_V)
+DECLARE_INSN(vbrev_v, MATCH_VBREV_V, MASK_VBREV_V)
+DECLARE_INSN(vclmul_vv, MATCH_VCLMUL_VV, MASK_VCLMUL_VV)
+DECLARE_INSN(vclmul_vx, MATCH_VCLMUL_VX, MASK_VCLMUL_VX)
+DECLARE_INSN(vclmulh_vv, MATCH_VCLMULH_VV, MASK_VCLMULH_VV)
+DECLARE_INSN(vclmulh_vx, MATCH_VCLMULH_VX, MASK_VCLMULH_VX)
+DECLARE_INSN(vclz_v, MATCH_VCLZ_V, MASK_VCLZ_V)
DECLARE_INSN(vcompress_vm, MATCH_VCOMPRESS_VM, MASK_VCOMPRESS_VM)
DECLARE_INSN(vcpop_m, MATCH_VCPOP_M, MASK_VCPOP_M)
+DECLARE_INSN(vcpop_v, MATCH_VCPOP_V, MASK_VCPOP_V)
+DECLARE_INSN(vctz_v, MATCH_VCTZ_V, MASK_VCTZ_V)
DECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV)
DECLARE_INSN(vdiv_vx, MATCH_VDIV_VX, MASK_VDIV_VX)
DECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV)
@@ -4418,6 +4531,8 @@ DECLARE_INSN(vfwsub_vf, MATCH_VFWSUB_VF, MASK_VFWSUB_VF)
DECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV)
DECLARE_INSN(vfwsub_wf, MATCH_VFWSUB_WF, MASK_VFWSUB_WF)
DECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV)
+DECLARE_INSN(vghsh_vv, MATCH_VGHSH_VV, MASK_VGHSH_VV)
+DECLARE_INSN(vgmul_vv, MATCH_VGMUL_VV, MASK_VGMUL_VV)
DECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V)
DECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M)
DECLARE_INSN(vl1re16_v, MATCH_VL1RE16_V, MASK_VL1RE16_V)
@@ -4591,10 +4706,16 @@ DECLARE_INSN(vrem_vv, MATCH_VREM_VV, MASK_VREM_VV)
DECLARE_INSN(vrem_vx, MATCH_VREM_VX, MASK_VREM_VX)
DECLARE_INSN(vremu_vv, MATCH_VREMU_VV, MASK_VREMU_VV)
DECLARE_INSN(vremu_vx, MATCH_VREMU_VX, MASK_VREMU_VX)
+DECLARE_INSN(vrev8_v, MATCH_VREV8_V, MASK_VREV8_V)
DECLARE_INSN(vrgather_vi, MATCH_VRGATHER_VI, MASK_VRGATHER_VI)
DECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV)
DECLARE_INSN(vrgather_vx, MATCH_VRGATHER_VX, MASK_VRGATHER_VX)
DECLARE_INSN(vrgatherei16_vv, MATCH_VRGATHEREI16_VV, MASK_VRGATHEREI16_VV)
+DECLARE_INSN(vrol_vv, MATCH_VROL_VV, MASK_VROL_VV)
+DECLARE_INSN(vrol_vx, MATCH_VROL_VX, MASK_VROL_VX)
+DECLARE_INSN(vror_vi, MATCH_VROR_VI, MASK_VROR_VI)
+DECLARE_INSN(vror_vv, MATCH_VROR_VV, MASK_VROR_VV)
+DECLARE_INSN(vror_vx, MATCH_VROR_VX, MASK_VROR_VX)
DECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI)
DECLARE_INSN(vrsub_vx, MATCH_VRSUB_VX, MASK_VRSUB_VX)
DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V)
@@ -4623,6 +4744,9 @@ DECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI)
DECLARE_INSN(vsext_vf2, MATCH_VSEXT_VF2, MASK_VSEXT_VF2)
DECLARE_INSN(vsext_vf4, MATCH_VSEXT_VF4, MASK_VSEXT_VF4)
DECLARE_INSN(vsext_vf8, MATCH_VSEXT_VF8, MASK_VSEXT_VF8)
+DECLARE_INSN(vsha2ch_vv, MATCH_VSHA2CH_VV, MASK_VSHA2CH_VV)
+DECLARE_INSN(vsha2cl_vv, MATCH_VSHA2CL_VV, MASK_VSHA2CL_VV)
+DECLARE_INSN(vsha2ms_vv, MATCH_VSHA2MS_VV, MASK_VSHA2MS_VV)
DECLARE_INSN(vslide1down_vx, MATCH_VSLIDE1DOWN_VX, MASK_VSLIDE1DOWN_VX)
DECLARE_INSN(vslide1up_vx, MATCH_VSLIDE1UP_VX, MASK_VSLIDE1UP_VX)
DECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI)
@@ -4632,6 +4756,11 @@ DECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX)
DECLARE_INSN(vsll_vi, MATCH_VSLL_VI, MASK_VSLL_VI)
DECLARE_INSN(vsll_vv, MATCH_VSLL_VV, MASK_VSLL_VV)
DECLARE_INSN(vsll_vx, MATCH_VSLL_VX, MASK_VSLL_VX)
+DECLARE_INSN(vsm3c_vi, MATCH_VSM3C_VI, MASK_VSM3C_VI)
+DECLARE_INSN(vsm3me_vv, MATCH_VSM3ME_VV, MASK_VSM3ME_VV)
+DECLARE_INSN(vsm4k_vi, MATCH_VSM4K_VI, MASK_VSM4K_VI)
+DECLARE_INSN(vsm4r_vs, MATCH_VSM4R_VS, MASK_VSM4R_VS)
+DECLARE_INSN(vsm4r_vv, MATCH_VSM4R_VV, MASK_VSM4R_VV)
DECLARE_INSN(vsm_v, MATCH_VSM_V, MASK_VSM_V)
DECLARE_INSN(vsmul_vv, MATCH_VSMUL_VV, MASK_VSMUL_VV)
DECLARE_INSN(vsmul_vx, MATCH_VSMUL_VX, MASK_VSMUL_VX)
@@ -4700,6 +4829,9 @@ DECLARE_INSN(vwmulu_vv, MATCH_VWMULU_VV, MASK_VWMULU_VV)
DECLARE_INSN(vwmulu_vx, MATCH_VWMULU_VX, MASK_VWMULU_VX)
DECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS)
DECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS)
+DECLARE_INSN(vwsll_vi, MATCH_VWSLL_VI, MASK_VWSLL_VI)
+DECLARE_INSN(vwsll_vv, MATCH_VWSLL_VV, MASK_VWSLL_VV)
+DECLARE_INSN(vwsll_vx, MATCH_VWSLL_VX, MASK_VWSLL_VX)
DECLARE_INSN(vwsub_vv, MATCH_VWSUB_VV, MASK_VWSUB_VV)
DECLARE_INSN(vwsub_vx, MATCH_VWSUB_VX, MASK_VWSUB_VX)
DECLARE_INSN(vwsub_wv, MATCH_VWSUB_WV, MASK_VWSUB_WV)
diff --git a/riscv/insns/amocas_d.h b/riscv/insns/amocas_d.h
new file mode 100644
index 0000000..e002e6a
--- /dev/null
+++ b/riscv/insns/amocas_d.h
@@ -0,0 +1,37 @@
+require_extension(EXT_ZACAS);
+
+if (xlen == 32) {
+ // RV32: the spec defines two 32-bit comparisons. Since we're
+ // loading 64-bit for memory we have to adjust for endianness.
+ uint64_t comp, swap, res;
+
+ require_align(insn.rd(), 2);
+ require_align(insn.rs2(), 2);
+ if (insn.rd() == 0) {
+ comp = 0;
+ } else if (MMU.is_target_big_endian()) {
+ comp = (uint32_t)READ_REG(insn.rd() + 1) | (RD << 32);
+ } else {
+ comp = (uint32_t)RD | (READ_REG(insn.rd() + 1) << 32);
+ }
+ if (insn.rs2() == 0) {
+ swap = 0;
+ } else if (MMU.is_target_big_endian()) {
+ swap = (uint32_t)READ_REG(insn.rs2() + 1) | (RS2 << 32);
+ } else {
+ swap = (uint32_t)RS2 | (READ_REG(insn.rs2() + 1) << 32);
+ }
+ res = MMU.amo_compare_and_swap<uint64_t>(RS1, comp, swap);
+ if (insn.rd() != 0) {
+ if (MMU.is_target_big_endian()) {
+ WRITE_REG(insn.rd() + 1, sext32((uint32_t)res));
+ WRITE_REG(insn.rd(), sext32(res >> 32));
+ } else {
+ WRITE_REG(insn.rd(), sext32((uint32_t)res));
+ WRITE_REG(insn.rd() + 1, sext32(res >> 32));
+ }
+ }
+ } else {
+ // RV64
+ WRITE_RD(MMU.amo_compare_and_swap<uint64_t>(RS1, RD, RS2));
+}
diff --git a/riscv/insns/amocas_q.h b/riscv/insns/amocas_q.h
new file mode 100644
index 0000000..0b7593b
--- /dev/null
+++ b/riscv/insns/amocas_q.h
@@ -0,0 +1,34 @@
+require_extension(EXT_ZACAS);
+require_rv64;
+require_align(insn.rd(), 2);
+require_align(insn.rs2(), 2);
+
+// The spec defines two 64-bit comparisons. Since we're loading
+// 128-bit for memory we have to adjust for endianness.
+
+uint128_t comp, swap, res;
+
+if (insn.rd() == 0) {
+ comp = 0;
+} else if (MMU.is_target_big_endian()) {
+ comp = READ_REG(insn.rd() + 1) | ((uint128_t)RD << 64);
+} else {
+ comp = RD | ((uint128_t)READ_REG(insn.rd() + 1) << 64);
+}
+if (insn.rs2() == 0) {
+ swap = 0;
+} else if (MMU.is_target_big_endian()) {
+ swap = READ_REG(insn.rs2() + 1) | ((uint128_t)RS2 << 64);
+} else {
+ swap = RS2 | ((uint128_t)READ_REG(insn.rs2() + 1) << 64);
+}
+res = MMU.amo_compare_and_swap<uint128_t>(RS1, comp, swap);
+if (insn.rd() != 0) {
+ if (MMU.is_target_big_endian()) {
+ WRITE_REG(insn.rd(), res >> 64);
+ WRITE_REG(insn.rd() + 1, res);
+ } else {
+ WRITE_REG(insn.rd(), res);
+ WRITE_REG(insn.rd() + 1, res >> 64);
+ }
+}
diff --git a/riscv/insns/amocas_w.h b/riscv/insns/amocas_w.h
new file mode 100644
index 0000000..a78c21c
--- /dev/null
+++ b/riscv/insns/amocas_w.h
@@ -0,0 +1,2 @@
+require_extension(EXT_ZACAS);
+WRITE_RD(sext32(MMU.amo_compare_and_swap<uint32_t>(RS1, RD, RS2)));
diff --git a/riscv/isa_parser.cc b/riscv/isa_parser.cc
index 8bb8c49..1c4300c 100644
--- a/riscv/isa_parser.cc
+++ b/riscv/isa_parser.cc
@@ -120,6 +120,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
// HINTs encoded in base-ISA instructions are always present.
} else if (ext_str == "zihintntl") {
// HINTs encoded in base-ISA instructions are always present.
+ } else if (ext_str == "zacas") {
+ extension_table[EXT_ZACAS] = true;
} else if (ext_str == "zmmul") {
extension_table[EXT_ZMMUL] = true;
} else if (ext_str == "zba") {
@@ -301,6 +303,10 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
bad_isa_string(str, "'Zcf/Zcd/Zcb/Zcmp/Zcmt' extensions require 'Zca' extension");
}
+ if (extension_table[EXT_ZACAS] && !extension_table['A']) {
+ bad_isa_string(str, "'Zacas' extension requires 'A' extension");
+ }
+
std::string lowercase = strtolower(priv);
bool user = false, supervisor = false;
diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h
index 4e68561..3cbee7d 100644
--- a/riscv/isa_parser.h
+++ b/riscv/isa_parser.h
@@ -61,6 +61,7 @@ typedef enum {
EXT_ZVFBFMIN,
EXT_ZVFBFWMA,
EXT_SSTC,
+ EXT_ZACAS,
EXT_INTERNAL_ZFH_MOVE,
NUM_ISA_EXTENSIONS
} isa_extension_t;
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 358ccd3..3f90060 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -242,6 +242,11 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, xlate_flags_t
load_slow_path_intrapage(len - len_page0, bytes + len_page0, access_info.split_misaligned_access(len_page0));
}
+ while (len > sizeof(reg_t)) {
+ check_triggers(triggers::OPERATION_LOAD, addr, access_info.effective_virt, reg_from_bytes(sizeof(reg_t), bytes));
+ len -= sizeof(reg_t);
+ bytes += sizeof(reg_t);
+ }
check_triggers(triggers::OPERATION_LOAD, addr, access_info.effective_virt, reg_from_bytes(len, bytes));
}
@@ -275,8 +280,16 @@ void mmu_t::store_slow_path_intrapage(reg_t len, const uint8_t* bytes, mem_acces
void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, xlate_flags_t xlate_flags, bool actually_store, bool UNUSED require_alignment)
{
auto access_info = generate_access_info(addr, STORE, xlate_flags);
- if (actually_store)
- check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(len, bytes));
+ if (actually_store) {
+ reg_t trig_len = len;
+ const uint8_t* trig_bytes = bytes;
+ while (trig_len > sizeof(reg_t)) {
+ check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(sizeof(reg_t), trig_bytes));
+ trig_len -= sizeof(reg_t);
+ trig_bytes += sizeof(reg_t);
+ }
+ check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(trig_len, trig_bytes));
+ }
if (addr & (len - 1)) {
bool gva = access_info.effective_virt;
diff --git a/riscv/mmu.h b/riscv/mmu.h
index efc6e9d..46c54ce 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -187,6 +187,17 @@ public:
})
}
+ template<typename T>
+ T amo_compare_and_swap(reg_t addr, T comp, T swap) {
+ convert_load_traps_to_store_traps({
+ store_slow_path(addr, sizeof(T), nullptr, {false, false, false}, false, true);
+ auto lhs = load<T>(addr);
+ if (lhs == comp)
+ store<T>(addr, swap);
+ return lhs;
+ })
+ }
+
void store_float128(reg_t addr, float128_t val)
{
if (unlikely(addr & (sizeof(float128_t)-1)) && !is_misaligned_enabled()) {
diff --git a/riscv/processor.cc b/riscv/processor.cc
index a75b0ff..1d5675a 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -47,6 +47,11 @@ processor_t::processor_t(const isa_parser_t *isa, const cfg_t *cfg,
fprintf(stderr, "V extension is not supported on platforms without __int128 type\n");
abort();
}
+
+ if (isa->extension_enabled(EXT_ZACAS) && isa->get_max_xlen() == 64) {
+ fprintf(stderr, "Zacas extension is not supported on 64-bit platforms without __int128 type\n");
+ abort();
+ }
#endif
parse_varch_string(cfg->varch());
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index db63290..6472982 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -1335,6 +1335,11 @@ riscv_insn_ext_bf16 = \
$(riscv_insn_ext_zvfbfmin) \
$(riscv_insn_ext_zvfbfwma) \
+riscv_insn_ext_zacas = \
+ amocas_w \
+ amocas_d \
+ $(if $(HAVE_INT128),amocas_q)
+
riscv_insn_list = \
$(riscv_insn_ext_a) \
$(riscv_insn_ext_c) \
@@ -1360,6 +1365,7 @@ riscv_insn_list = \
$(riscv_insn_ext_cmo) \
$(riscv_insn_ext_zicond) \
$(riscv_insn_ext_bf16) \
+ $(riscv_insn_ext_zacas) \
riscv_gen_srcs = $(addsuffix .cc,$(riscv_insn_list))