Browse Source

Merge pull request #1364 from glg-rv/dev/glguida/amocas

Zacas extension
pull/1388/head
Andrew Waterman 3 years ago
committed by GitHub
parent
commit
8b10de64dd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      disasm/disasm.cc
  2. 7
      fesvr/byteorder.h
  3. 5
      riscv/decode_macros.h
  4. 134
      riscv/encoding.h
  5. 37
      riscv/insns/amocas_d.h
  6. 34
      riscv/insns/amocas_q.h
  7. 2
      riscv/insns/amocas_w.h
  8. 6
      riscv/isa_parser.cc
  9. 1
      riscv/isa_parser.h
  10. 17
      riscv/mmu.cc
  11. 11
      riscv/mmu.h
  12. 5
      riscv/processor.cc
  13. 6
      riscv/riscv.mk.in

6
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}));

7
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; }

5
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())

134
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)

37
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));
}

34
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);
}
}

2
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)));

6
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;

1
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;

17
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;

11
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()) {

5
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());

6
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))

Loading…
Cancel
Save