├── .gitignore ├── .gitmodules ├── ChangeLog.md ├── LICENSE ├── Makefile.in ├── README.md ├── VERSION ├── aclocal.m4 ├── config.h.in ├── configure ├── configure.ac ├── debug_rom ├── .gitignore ├── Makefile ├── debug_rom.S ├── debug_rom.h └── link.ld ├── dummy_rocc ├── dummy_rocc.ac ├── dummy_rocc.cc ├── dummy_rocc.mk.in └── dummy_rocc_test.c ├── fesvr ├── context.cc ├── context.h ├── debug_defines.h ├── device.cc ├── device.h ├── dtm.cc ├── dtm.h ├── dummy.cc ├── elf.h ├── elf2hex.cc ├── elfloader.cc ├── elfloader.h ├── fesvr.ac ├── fesvr.mk.in ├── fesvr.pc.in ├── htif.cc ├── htif.h ├── htif_hexwriter.cc ├── htif_hexwriter.h ├── htif_pthread.cc ├── htif_pthread.h ├── memif.cc ├── memif.h ├── option_parser.cc ├── option_parser.h ├── rfb.cc ├── rfb.h ├── syscall.cc ├── syscall.h ├── term.cc ├── term.h ├── tsi.cc └── tsi.h ├── riscv-dummy_rocc.pc.in ├── riscv-fesvr.pc.in ├── riscv-riscv.pc.in ├── riscv-softfloat.pc.in ├── riscv-spike.pc.in ├── riscv-spike_main.pc.in ├── riscv ├── arith.h ├── cachesim.cc ├── cachesim.h ├── clint.cc ├── common.h ├── debug_defines.h ├── debug_module.cc ├── debug_module.h ├── debug_rom_defines.h ├── decode.h ├── devices.cc ├── devices.h ├── disasm.h ├── dts.cc ├── dts.h ├── encoding.h ├── execute.cc ├── extension.cc ├── extension.h ├── extensions.cc ├── gen_icache ├── insn_template.cc ├── insn_template.h ├── insns │ ├── add.h │ ├── addi.h │ ├── addiw.h │ ├── addw.h │ ├── amoadd_d.h │ ├── amoadd_w.h │ ├── amoand_d.h │ ├── amoand_w.h │ ├── amomax_d.h │ ├── amomax_w.h │ ├── amomaxu_d.h │ ├── amomaxu_w.h │ ├── amomin_d.h │ ├── amomin_w.h │ ├── amominu_d.h │ ├── amominu_w.h │ ├── amoor_d.h │ ├── amoor_w.h │ ├── amoswap_d.h │ ├── amoswap_w.h │ ├── amoxor_d.h │ ├── amoxor_w.h │ ├── and.h │ ├── andi.h │ ├── auipc.h │ ├── beq.h │ ├── bge.h │ ├── bgeu.h │ ├── blt.h │ ├── bltu.h │ ├── bne.h │ ├── c_add.h │ ├── c_addi.h │ ├── c_addi4spn.h │ ├── c_addw.h │ ├── c_and.h │ ├── c_andi.h │ ├── c_beqz.h │ ├── c_bnez.h │ ├── c_ebreak.h │ ├── c_fld.h │ ├── c_fldsp.h │ ├── c_flw.h │ ├── c_flwsp.h │ ├── c_fsd.h │ ├── c_fsdsp.h │ ├── c_fsw.h │ ├── c_fswsp.h │ ├── c_j.h │ ├── c_jal.h │ ├── c_jalr.h │ ├── c_jr.h │ ├── c_li.h │ ├── c_lui.h │ ├── c_lw.h │ ├── c_lwsp.h │ ├── c_mv.h │ ├── c_or.h │ ├── c_slli.h │ ├── c_srai.h │ ├── c_srli.h │ ├── c_sub.h │ ├── c_subw.h │ ├── c_sw.h │ ├── c_swsp.h │ ├── c_xor.h │ ├── csrrc.h │ ├── csrrci.h │ ├── csrrs.h │ ├── csrrsi.h │ ├── csrrw.h │ ├── csrrwi.h │ ├── div.h │ ├── divu.h │ ├── divuw.h │ ├── divw.h │ ├── dret.h │ ├── ebreak.h │ ├── ecall.h │ ├── fadd_d.h │ ├── fadd_q.h │ ├── fadd_s.h │ ├── fclass_d.h │ ├── fclass_q.h │ ├── fclass_s.h │ ├── fcvt_d_l.h │ ├── fcvt_d_lu.h │ ├── fcvt_d_q.h │ ├── fcvt_d_s.h │ ├── fcvt_d_w.h │ ├── fcvt_d_wu.h │ ├── fcvt_l_d.h │ ├── fcvt_l_q.h │ ├── fcvt_l_s.h │ ├── fcvt_lu_d.h │ ├── fcvt_lu_q.h │ ├── fcvt_lu_s.h │ ├── fcvt_q_d.h │ ├── fcvt_q_l.h │ ├── fcvt_q_lu.h │ ├── fcvt_q_s.h │ ├── fcvt_q_w.h │ ├── fcvt_q_wu.h │ ├── fcvt_s_d.h │ ├── fcvt_s_l.h │ ├── fcvt_s_lu.h │ ├── fcvt_s_q.h │ ├── fcvt_s_w.h │ ├── fcvt_s_wu.h │ ├── fcvt_w_d.h │ ├── fcvt_w_q.h │ ├── fcvt_w_s.h │ ├── fcvt_wu_d.h │ ├── fcvt_wu_q.h │ ├── fcvt_wu_s.h │ ├── fdiv_d.h │ ├── fdiv_q.h │ ├── fdiv_s.h │ ├── fence.h │ ├── fence_i.h │ ├── feq_d.h │ ├── feq_q.h │ ├── feq_s.h │ ├── fld.h │ ├── fle_d.h │ ├── fle_q.h │ ├── fle_s.h │ ├── flq.h │ ├── flt_d.h │ ├── flt_q.h │ ├── flt_s.h │ ├── flw.h │ ├── fmadd_d.h │ ├── fmadd_q.h │ ├── fmadd_s.h │ ├── fmax_d.h │ ├── fmax_q.h │ ├── fmax_s.h │ ├── fmin_d.h │ ├── fmin_q.h │ ├── fmin_s.h │ ├── fmsub_d.h │ ├── fmsub_q.h │ ├── fmsub_s.h │ ├── fmul_d.h │ ├── fmul_q.h │ ├── fmul_s.h │ ├── fmv_d_x.h │ ├── fmv_w_x.h │ ├── fmv_x_d.h │ ├── fmv_x_w.h │ ├── fnmadd_d.h │ ├── fnmadd_q.h │ ├── fnmadd_s.h │ ├── fnmsub_d.h │ ├── fnmsub_q.h │ ├── fnmsub_s.h │ ├── fsd.h │ ├── fsgnj_d.h │ ├── fsgnj_q.h │ ├── fsgnj_s.h │ ├── fsgnjn_d.h │ ├── fsgnjn_q.h │ ├── fsgnjn_s.h │ ├── fsgnjx_d.h │ ├── fsgnjx_q.h │ ├── fsgnjx_s.h │ ├── fsq.h │ ├── fsqrt_d.h │ ├── fsqrt_q.h │ ├── fsqrt_s.h │ ├── fsub_d.h │ ├── fsub_q.h │ ├── fsub_s.h │ ├── fsw.h │ ├── jal.h │ ├── jalr.h │ ├── lb.h │ ├── lbu.h │ ├── ld.h │ ├── lh.h │ ├── lhu.h │ ├── lr_d.h │ ├── lr_w.h │ ├── lui.h │ ├── lw.h │ ├── lwu.h │ ├── mret.h │ ├── mul.h │ ├── mulh.h │ ├── mulhsu.h │ ├── mulhu.h │ ├── mulw.h │ ├── or.h │ ├── ori.h │ ├── rem.h │ ├── remu.h │ ├── remuw.h │ ├── remw.h │ ├── sb.h │ ├── sc_d.h │ ├── sc_w.h │ ├── sd.h │ ├── sfence_vma.h │ ├── sh.h │ ├── sll.h │ ├── slli.h │ ├── slliw.h │ ├── sllw.h │ ├── slt.h │ ├── slti.h │ ├── sltiu.h │ ├── sltu.h │ ├── sra.h │ ├── srai.h │ ├── sraiw.h │ ├── sraw.h │ ├── sret.h │ ├── srl.h │ ├── srli.h │ ├── srliw.h │ ├── srlw.h │ ├── sub.h │ ├── subw.h │ ├── sw.h │ ├── vaadd_vi.h │ ├── vaadd_vv.h │ ├── vaadd_vx.h │ ├── vadc_vim.h │ ├── vadc_vvm.h │ ├── vadc_vxm.h │ ├── vadd_vi.h │ ├── vadd_vv.h │ ├── vadd_vx.h │ ├── vand_vi.h │ ├── vand_vv.h │ ├── vand_vx.h │ ├── vasub_vv.h │ ├── vasub_vx.h │ ├── vcompress_vm.h │ ├── vdiv_vv.h │ ├── vdiv_vx.h │ ├── vdivu_vv.h │ ├── vdivu_vx.h │ ├── vdot_vv.h │ ├── vdotu_vv.h │ ├── vext_x_v.h │ ├── vfadd_vf.h │ ├── vfadd_vv.h │ ├── vfclass_v.h │ ├── vfcvt_f_x_v.h │ ├── vfcvt_f_xu_v.h │ ├── vfcvt_x_f_v.h │ ├── vfcvt_xu_f_v.h │ ├── vfdiv_vf.h │ ├── vfdiv_vv.h │ ├── vfdot_vv.h │ ├── vfirst_m.h │ ├── vfmacc_vf.h │ ├── vfmacc_vv.h │ ├── vfmadd_vf.h │ ├── vfmadd_vv.h │ ├── vfmax_vf.h │ ├── vfmax_vv.h │ ├── vfmerge_vfm.h │ ├── vfmin_vf.h │ ├── vfmin_vv.h │ ├── vfmsac_vf.h │ ├── vfmsac_vv.h │ ├── vfmsub_vf.h │ ├── vfmsub_vv.h │ ├── vfmul_vf.h │ ├── vfmul_vv.h │ ├── vfmv_f_s.h │ ├── vfmv_s_f.h │ ├── vfmv_v_f.h │ ├── vfncvt_f_f_v.h │ ├── vfncvt_f_x_v.h │ ├── vfncvt_f_xu_v.h │ ├── vfncvt_x_f_v.h │ ├── vfncvt_xu_f_v.h │ ├── vfnmacc_vf.h │ ├── vfnmacc_vv.h │ ├── vfnmadd_vf.h │ ├── vfnmadd_vv.h │ ├── vfnmsac_vf.h │ ├── vfnmsac_vv.h │ ├── vfnmsub_vf.h │ ├── vfnmsub_vv.h │ ├── vfrdiv_vf.h │ ├── vfredmax_vs.h │ ├── vfredmin_vs.h │ ├── vfredosum_vs.h │ ├── vfredsum_vs.h │ ├── vfrsub_vf.h │ ├── vfsgnj_vf.h │ ├── vfsgnj_vv.h │ ├── vfsgnjn_vf.h │ ├── vfsgnjn_vv.h │ ├── vfsgnjx_vf.h │ ├── vfsgnjx_vv.h │ ├── vfsqrt_v.h │ ├── vfsub_vf.h │ ├── vfsub_vv.h │ ├── vfwadd_vf.h │ ├── vfwadd_vv.h │ ├── vfwadd_wf.h │ ├── vfwadd_wv.h │ ├── vfwcvt_f_f_v.h │ ├── vfwcvt_f_x_v.h │ ├── vfwcvt_f_xu_v.h │ ├── vfwcvt_x_f_v.h │ ├── vfwcvt_xu_f_v.h │ ├── vfwmacc_vf.h │ ├── vfwmacc_vv.h │ ├── vfwmsac_vf.h │ ├── vfwmsac_vv.h │ ├── vfwmul_vf.h │ ├── vfwmul_vv.h │ ├── vfwnmacc_vf.h │ ├── vfwnmacc_vv.h │ ├── vfwnmsac_vf.h │ ├── vfwnmsac_vv.h │ ├── vfwredosum_vs.h │ ├── vfwredsum_vs.h │ ├── vfwsub_vf.h │ ├── vfwsub_vv.h │ ├── vfwsub_wf.h │ ├── vfwsub_wv.h │ ├── vid_v.h │ ├── viota_m.h │ ├── vlb_v.h │ ├── vlbff_v.h │ ├── vlbu_v.h │ ├── vlbuff_v.h │ ├── vle_v.h │ ├── vleff_v.h │ ├── vlh_v.h │ ├── vlhff_v.h │ ├── vlhu_v.h │ ├── vlhuff_v.h │ ├── vlsb_v.h │ ├── vlsbu_v.h │ ├── vlse_v.h │ ├── vlsh_v.h │ ├── vlshu_v.h │ ├── vlsw_v.h │ ├── vlswu_v.h │ ├── vlw_v.h │ ├── vlwff_v.h │ ├── vlwu_v.h │ ├── vlwuff_v.h │ ├── vlxb_v.h │ ├── vlxbu_v.h │ ├── vlxe_v.h │ ├── vlxh_v.h │ ├── vlxhu_v.h │ ├── vlxw_v.h │ ├── vlxwu_v.h │ ├── vmacc_vv.h │ ├── vmacc_vx.h │ ├── vmadc_vim.h │ ├── vmadc_vvm.h │ ├── vmadc_vxm.h │ ├── vmadd_vv.h │ ├── vmadd_vx.h │ ├── vmand_mm.h │ ├── vmandnot_mm.h │ ├── vmax_vv.h │ ├── vmax_vx.h │ ├── vmaxu_vv.h │ ├── vmaxu_vx.h │ ├── vmerge_vim.h │ ├── vmerge_vvm.h │ ├── vmerge_vxm.h │ ├── vmfeq_vf.h │ ├── vmfeq_vv.h │ ├── vmfge_vf.h │ ├── vmfgt_vf.h │ ├── vmfle_vf.h │ ├── vmfle_vv.h │ ├── vmflt_vf.h │ ├── vmflt_vv.h │ ├── vmfne_vf.h │ ├── vmfne_vv.h │ ├── vmford_vf.h │ ├── vmford_vv.h │ ├── vmin_vv.h │ ├── vmin_vx.h │ ├── vminu_vv.h │ ├── vminu_vx.h │ ├── vmnand_mm.h │ ├── vmnor_mm.h │ ├── vmor_mm.h │ ├── vmornot_mm.h │ ├── vmsbc_vvm.h │ ├── vmsbc_vxm.h │ ├── vmsbf_m.h │ ├── vmseq_vi.h │ ├── vmseq_vv.h │ ├── vmseq_vx.h │ ├── vmsgt_vi.h │ ├── vmsgt_vx.h │ ├── vmsgtu_vi.h │ ├── vmsgtu_vx.h │ ├── vmsif_m.h │ ├── vmsle_vi.h │ ├── vmsle_vv.h │ ├── vmsle_vx.h │ ├── vmsleu_vi.h │ ├── vmsleu_vv.h │ ├── vmsleu_vx.h │ ├── vmslt_vv.h │ ├── vmslt_vx.h │ ├── vmsltu_vv.h │ ├── vmsltu_vx.h │ ├── vmsne_vi.h │ ├── vmsne_vv.h │ ├── vmsne_vx.h │ ├── vmsof_m.h │ ├── vmul_vv.h │ ├── vmul_vx.h │ ├── vmulh_vv.h │ ├── vmulh_vx.h │ ├── vmulhsu_vv.h │ ├── vmulhsu_vx.h │ ├── vmulhu_vv.h │ ├── vmulhu_vx.h │ ├── vmv_s_x.h │ ├── vmv_v_i.h │ ├── vmv_v_v.h │ ├── vmv_v_x.h │ ├── vmxnor_mm.h │ ├── vmxor_mm.h │ ├── vnclip_vi.h │ ├── vnclip_vv.h │ ├── vnclip_vx.h │ ├── vnclipu_vi.h │ ├── vnclipu_vv.h │ ├── vnclipu_vx.h │ ├── vnmsac_vv.h │ ├── vnmsac_vx.h │ ├── vnmsub_vv.h │ ├── vnmsub_vx.h │ ├── vnsra_vi.h │ ├── vnsra_vv.h │ ├── vnsra_vx.h │ ├── vnsrl_vi.h │ ├── vnsrl_vv.h │ ├── vnsrl_vx.h │ ├── vor_vi.h │ ├── vor_vv.h │ ├── vor_vx.h │ ├── vpopc_m.h │ ├── vredand_vs.h │ ├── vredmax_vs.h │ ├── vredmaxu_vs.h │ ├── vredmin_vs.h │ ├── vredminu_vs.h │ ├── vredor_vs.h │ ├── vredsum_vs.h │ ├── vredxor_vs.h │ ├── vrem_vv.h │ ├── vrem_vx.h │ ├── vremu_vv.h │ ├── vremu_vx.h │ ├── vrgather_vi.h │ ├── vrgather_vv.h │ ├── vrgather_vx.h │ ├── vrsub_vi.h │ ├── vrsub_vx.h │ ├── vsadd_vi.h │ ├── vsadd_vv.h │ ├── vsadd_vx.h │ ├── vsaddu_vi.h │ ├── vsaddu_vv.h │ ├── vsaddu_vx.h │ ├── vsb_v.h │ ├── vsbc_vvm.h │ ├── vsbc_vxm.h │ ├── vse_v.h │ ├── vsetvl.h │ ├── vsetvli.h │ ├── vsh_v.h │ ├── vslide1down_vx.h │ ├── vslide1up_vx.h │ ├── vslidedown_vi.h │ ├── vslidedown_vx.h │ ├── vslideup_vi.h │ ├── vslideup_vx.h │ ├── vsll_vi.h │ ├── vsll_vv.h │ ├── vsll_vx.h │ ├── vsmul_vv.h │ ├── vsmul_vx.h │ ├── vsra_vi.h │ ├── vsra_vv.h │ ├── vsra_vx.h │ ├── vsrl_vi.h │ ├── vsrl_vv.h │ ├── vsrl_vx.h │ ├── vssb_v.h │ ├── vsse_v.h │ ├── vssh_v.h │ ├── vssra_vi.h │ ├── vssra_vv.h │ ├── vssra_vx.h │ ├── vssrl_vi.h │ ├── vssrl_vv.h │ ├── vssrl_vx.h │ ├── vssub_vv.h │ ├── vssub_vx.h │ ├── vssubu_vv.h │ ├── vssubu_vx.h │ ├── vssw_v.h │ ├── vsub_vv.h │ ├── vsub_vx.h │ ├── vsuxb_v.h │ ├── vsuxe_v.h │ ├── vsuxh_v.h │ ├── vsuxw_v.h │ ├── vsw_v.h │ ├── vsxb_v.h │ ├── vsxe_v.h │ ├── vsxh_v.h │ ├── vsxw_v.h │ ├── vwadd_vv.h │ ├── vwadd_vx.h │ ├── vwadd_wv.h │ ├── vwadd_wx.h │ ├── vwaddu_vv.h │ ├── vwaddu_vx.h │ ├── vwaddu_wv.h │ ├── vwaddu_wx.h │ ├── vwmacc_vv.h │ ├── vwmacc_vx.h │ ├── vwmaccsu_vv.h │ ├── vwmaccsu_vx.h │ ├── vwmaccu_vv.h │ ├── vwmaccu_vx.h │ ├── vwmaccus_vx.h │ ├── vwmul_vv.h │ ├── vwmul_vx.h │ ├── vwmulsu_vv.h │ ├── vwmulsu_vx.h │ ├── vwmulu_vv.h │ ├── vwmulu_vx.h │ ├── vwredsum_vs.h │ ├── vwredsumu_vs.h │ ├── vwsmacc_vv.h │ ├── vwsmacc_vx.h │ ├── vwsmaccsu_vv.h │ ├── vwsmaccsu_vx.h │ ├── vwsmaccu_vv.h │ ├── vwsmaccu_vx.h │ ├── vwsmaccus_vx.h │ ├── vwsub_vv.h │ ├── vwsub_vx.h │ ├── vwsub_wv.h │ ├── vwsub_wx.h │ ├── vwsubu_vv.h │ ├── vwsubu_vx.h │ ├── vwsubu_wv.h │ ├── vwsubu_wx.h │ ├── vxor_vi.h │ ├── vxor_vv.h │ ├── vxor_vx.h │ ├── wfi.h │ ├── xor.h │ └── xori.h ├── interactive.cc ├── jtag_dtm.cc ├── jtag_dtm.h ├── memtracer.h ├── mmu.cc ├── mmu.h ├── opcodes.h ├── processor.cc ├── processor.h ├── regnames.cc ├── remote_bitbang.cc ├── remote_bitbang.h ├── riscv.ac ├── riscv.mk.in ├── rocc.cc ├── rocc.h ├── rom.cc ├── sim.cc ├── sim.h ├── simif.h ├── tlb.cc ├── tlb.h ├── tracer.h ├── trap.cc └── trap.h ├── scripts ├── config.guess ├── config.sub ├── install.sh ├── mk-install-dirs.sh └── vcs-version.sh ├── softfloat ├── f128_add.c ├── f128_classify.c ├── f128_div.c ├── f128_eq.c ├── f128_eq_signaling.c ├── f128_isSignalingNaN.c ├── f128_le.c ├── f128_le_quiet.c ├── f128_lt.c ├── f128_lt_quiet.c ├── f128_mul.c ├── f128_mulAdd.c ├── f128_rem.c ├── f128_roundToInt.c ├── f128_sqrt.c ├── f128_sub.c ├── f128_to_f16.c ├── f128_to_f32.c ├── f128_to_f64.c ├── f128_to_i32.c ├── f128_to_i32_r_minMag.c ├── f128_to_i64.c ├── f128_to_i64_r_minMag.c ├── f128_to_ui32.c ├── f128_to_ui32_r_minMag.c ├── f128_to_ui64.c ├── f128_to_ui64_r_minMag.c ├── f16_add.c ├── f16_div.c ├── f16_eq.c ├── f16_eq_signaling.c ├── f16_isSignalingNaN.c ├── f16_le.c ├── f16_le_quiet.c ├── f16_lt.c ├── f16_lt_quiet.c ├── f16_mul.c ├── f16_mulAdd.c ├── f16_rem.c ├── f16_roundToInt.c ├── f16_sqrt.c ├── f16_sub.c ├── f16_to_f128.c ├── f16_to_f32.c ├── f16_to_f64.c ├── f16_to_i32.c ├── f16_to_i32_r_minMag.c ├── f16_to_i64.c ├── f16_to_i64_r_minMag.c ├── f16_to_ui32.c ├── f16_to_ui32_r_minMag.c ├── f16_to_ui64.c ├── f16_to_ui64_r_minMag.c ├── f32_add.c ├── f32_classify.c ├── f32_div.c ├── f32_eq.c ├── f32_eq_signaling.c ├── f32_isSignalingNaN.c ├── f32_le.c ├── f32_le_quiet.c ├── f32_lt.c ├── f32_lt_quiet.c ├── f32_mul.c ├── f32_mulAdd.c ├── f32_rem.c ├── f32_roundToInt.c ├── f32_sqrt.c ├── f32_sub.c ├── f32_to_f128.c ├── f32_to_f16.c ├── f32_to_f64.c ├── f32_to_i32.c ├── f32_to_i32_r_minMag.c ├── f32_to_i64.c ├── f32_to_i64_r_minMag.c ├── f32_to_ui32.c ├── f32_to_ui32_r_minMag.c ├── f32_to_ui64.c ├── f32_to_ui64_r_minMag.c ├── f64_add.c ├── f64_classify.c ├── f64_div.c ├── f64_eq.c ├── f64_eq_signaling.c ├── f64_isSignalingNaN.c ├── f64_le.c ├── f64_le_quiet.c ├── f64_lt.c ├── f64_lt_quiet.c ├── f64_mul.c ├── f64_mulAdd.c ├── f64_rem.c ├── f64_roundToInt.c ├── f64_sqrt.c ├── f64_sub.c ├── f64_to_f128.c ├── f64_to_f16.c ├── f64_to_f32.c ├── f64_to_i32.c ├── f64_to_i32_r_minMag.c ├── f64_to_i64.c ├── f64_to_i64_r_minMag.c ├── f64_to_ui32.c ├── f64_to_ui32_r_minMag.c ├── f64_to_ui64.c ├── f64_to_ui64_r_minMag.c ├── fall_maxmin.c ├── i32_to_f128.c ├── i32_to_f16.c ├── i32_to_f32.c ├── i32_to_f64.c ├── i64_to_f128.c ├── i64_to_f16.c ├── i64_to_f32.c ├── i64_to_f64.c ├── internals.h ├── platform.h ├── primitiveTypes.h ├── primitives.h ├── s_add128.c ├── s_add256M.c ├── s_addCarryM.c ├── s_addComplCarryM.c ├── s_addM.c ├── s_addMagsF128.c ├── s_addMagsF16.c ├── s_addMagsF32.c ├── s_addMagsF64.c ├── s_approxRecip32_1.c ├── s_approxRecipSqrt32_1.c ├── s_approxRecipSqrt_1Ks.c ├── s_approxRecip_1Ks.c ├── s_commonNaNToF128UI.c ├── s_commonNaNToF16UI.c ├── s_commonNaNToF32UI.c ├── s_commonNaNToF64UI.c ├── s_compare128M.c ├── s_compare96M.c ├── s_countLeadingZeros16.c ├── s_countLeadingZeros32.c ├── s_countLeadingZeros64.c ├── s_countLeadingZeros8.c ├── s_eq128.c ├── s_f128UIToCommonNaN.c ├── s_f16UIToCommonNaN.c ├── s_f32UIToCommonNaN.c ├── s_f64UIToCommonNaN.c ├── s_le128.c ├── s_lt128.c ├── s_mul128By32.c ├── s_mul128MTo256M.c ├── s_mul128To256M.c ├── s_mul64ByShifted32To128.c ├── s_mul64To128.c ├── s_mul64To128M.c ├── s_mulAddF128.c ├── s_mulAddF16.c ├── s_mulAddF32.c ├── s_mulAddF64.c ├── s_negXM.c ├── s_normRoundPackToF128.c ├── s_normRoundPackToF16.c ├── s_normRoundPackToF32.c ├── s_normRoundPackToF64.c ├── s_normSubnormalF128Sig.c ├── s_normSubnormalF16Sig.c ├── s_normSubnormalF32Sig.c ├── s_normSubnormalF64Sig.c ├── s_propagateNaNF128UI.c ├── s_propagateNaNF16UI.c ├── s_propagateNaNF32UI.c ├── s_propagateNaNF64UI.c ├── s_remStepMBy32.c ├── s_roundMToI64.c ├── s_roundMToUI64.c ├── s_roundPackMToI64.c ├── s_roundPackMToUI64.c ├── s_roundPackToF128.c ├── s_roundPackToF16.c ├── s_roundPackToF32.c ├── s_roundPackToF64.c ├── s_roundPackToI32.c ├── s_roundPackToI64.c ├── s_roundPackToUI32.c ├── s_roundPackToUI64.c ├── s_roundToI32.c ├── s_roundToI64.c ├── s_roundToUI32.c ├── s_roundToUI64.c ├── s_shiftRightJam128.c ├── s_shiftRightJam128Extra.c ├── s_shiftRightJam256M.c ├── s_shiftRightJam32.c ├── s_shiftRightJam64.c ├── s_shiftRightJam64Extra.c ├── s_shortShiftLeft128.c ├── s_shortShiftLeft64To96M.c ├── s_shortShiftRight128.c ├── s_shortShiftRightExtendM.c ├── s_shortShiftRightJam128.c ├── s_shortShiftRightJam128Extra.c ├── s_shortShiftRightJam64.c ├── s_shortShiftRightJam64Extra.c ├── s_shortShiftRightM.c ├── s_sub128.c ├── s_sub1XM.c ├── s_sub256M.c ├── s_subM.c ├── s_subMagsF128.c ├── s_subMagsF16.c ├── s_subMagsF32.c ├── s_subMagsF64.c ├── softfloat.ac ├── softfloat.h ├── softfloat.mk.in ├── softfloat_raiseFlags.c ├── softfloat_state.c ├── softfloat_types.h ├── specialize.h ├── ui32_to_f128.c ├── ui32_to_f16.c ├── ui32_to_f32.c ├── ui32_to_f64.c ├── ui64_to_f128.c ├── ui64_to_f16.c ├── ui64_to_f32.c └── ui64_to_f64.c ├── spike_main ├── disasm.cc ├── spike-dasm.cc ├── spike-log-parser.cc ├── spike.cc ├── spike_main.ac ├── spike_main.mk.in ├── termios-xspike.cc └── xspike.cc └── tests ├── ebreak.py ├── ebreak.s └── testlib.py /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.gch 3 | autom4te.cache/ 4 | .*.swp 5 | *.o 6 | *.d 7 | .gdb_history 8 | *~ 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cache_model"] 2 | path = cache_model 3 | url = ../cache-model 4 | -------------------------------------------------------------------------------- /ChangeLog.md: -------------------------------------------------------------------------------- 1 | Version 1.0.1-dev 2 | ----------------- 3 | - Preliminary support for a subset of the Vector Extension, v0.7.1. 4 | - Support S-mode vectored interrupts (i.e. `stvec[0]` is now writable). 5 | - Several debug-related additions and changes: 6 | - Added `hasel` debug feature. 7 | - Added `--dm-no-abstract-csr` command-line option. 8 | - Added `--dm-no-halt-groups` command line option. 9 | - Renamed `--progsize` to `--dm-progsize`. 10 | - Renamed `--debug-sba` to `--dm-sba`. 11 | - Renamed `--debug-auth` to `--dm-auth`. 12 | - Renamed `--abstract-rti` to `--dm-abstract-rti`. 13 | - Renamed `--without-hasel` to `--dm-no-hasel`. 14 | 15 | Version 1.0.0 (2019-03-30) 16 | -------------------------- 17 | - First versioned release. 18 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | #define SPIKE_VERSION "1.0.1-dev" 2 | -------------------------------------------------------------------------------- /debug_rom/.gitignore: -------------------------------------------------------------------------------- 1 | /debug_rom 2 | /debug_rom32 3 | /debug_rom64 4 | /debug_rom32.h 5 | /debug_rom64.h 6 | -------------------------------------------------------------------------------- /debug_rom/Makefile: -------------------------------------------------------------------------------- 1 | # Recursive make is bad, but in this case we're cross compiling which is a 2 | # pretty unusual use case. 3 | 4 | CC = $(RISCV)/bin/riscv64-unknown-elf-gcc 5 | OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy 6 | 7 | COMPILE = $(CC) -nostdlib -nostartfiles -I.. -Tlink.ld 8 | 9 | ELFS = debug_rom 10 | DEPS = debug_rom.S link.ld ../riscv/debug_rom_defines.h ../riscv/encoding.h 11 | 12 | all: $(patsubst %,%.h,$(ELFS)) 13 | 14 | %.h: %.raw 15 | xxd -i $^ | sed "s/^unsigned/static const unsigned/" > $@ 16 | 17 | %.raw: % 18 | $(OBJCOPY) -O binary --only-section .text $^ $@ 19 | 20 | debug_rom: $(DEPS) 21 | $(COMPILE) -o $@ $^ 22 | 23 | clean: 24 | rm -f $(ELFS) debug_rom*.raw debug_rom.h 25 | -------------------------------------------------------------------------------- /debug_rom/debug_rom.h: -------------------------------------------------------------------------------- 1 | static const unsigned char debug_rom_raw[] = { 2 | 0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0xc0, 0x05, 0x6f, 0x00, 0x80, 0x03, 3 | 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, 4 | 0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00, 5 | 0x63, 0x12, 0x04, 0x02, 0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40, 6 | 0x13, 0x74, 0x24, 0x00, 0x63, 0x16, 0x04, 0x02, 0x73, 0x00, 0x50, 0x10, 7 | 0x6f, 0xf0, 0x9f, 0xfd, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, 8 | 0x73, 0x24, 0x40, 0xf1, 0x23, 0x22, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, 9 | 0x0f, 0x00, 0xf0, 0x0f, 0x0f, 0x10, 0x00, 0x00, 0x67, 0x00, 0x00, 0x30, 10 | 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, 11 | 0x73, 0x00, 0x20, 0x7b 12 | }; 13 | static const unsigned int debug_rom_raw_len = 112; 14 | -------------------------------------------------------------------------------- /debug_rom/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH( "riscv" ) 2 | ENTRY( entry ) 3 | SECTIONS 4 | { 5 | .whereto 0x300 : 6 | { 7 | *(.whereto) 8 | } 9 | . = 0x800; 10 | .text : 11 | { 12 | *(.text) 13 | } 14 | _end = .; 15 | } 16 | -------------------------------------------------------------------------------- /dummy_rocc/dummy_rocc.ac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comparch-security/spike-cache/3639dd7ee57c43b3eb5d70bedfd5b2fdeece3f42/dummy_rocc/dummy_rocc.ac -------------------------------------------------------------------------------- /dummy_rocc/dummy_rocc.mk.in: -------------------------------------------------------------------------------- 1 | dummy_rocc_subproject_deps = \ 2 | spike_main \ 3 | riscv \ 4 | softfloat \ 5 | 6 | dummy_rocc_srcs = \ 7 | dummy_rocc.cc \ 8 | -------------------------------------------------------------------------------- /dummy_rocc/dummy_rocc_test.c: -------------------------------------------------------------------------------- 1 | // The following is a RISC-V program to test the functionality of the 2 | // dummy RoCC accelerator. 3 | // Compile with riscv64-unknown-elf-gcc dummy_rocc_test.c 4 | // Run with spike --extension=dummy_rocc pk a.out 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | int main() { 11 | uint64_t x = 123, y = 456, z = 0; 12 | // load x into accumulator 2 (funct=0) 13 | asm volatile ("custom0 x0, %0, 2, 0" : : "r"(x)); 14 | // read it back into z (funct=1) to verify it 15 | asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); 16 | assert(z == x); 17 | // accumulate 456 into it (funct=3) 18 | asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); 19 | // verify it 20 | asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); 21 | assert(z == x+y); 22 | // do it all again, but initialize acc2 via memory this time (funct=2) 23 | asm volatile ("custom0 x0, %0, 2, 2" : : "r"(&x)); 24 | asm volatile ("custom0 x0, %0, 2, 3" : : "r"(y)); 25 | asm volatile ("custom0 %0, x0, 2, 1" : "=r"(z)); 26 | assert(z == x+y); 27 | 28 | printf("success!\n"); 29 | } 30 | -------------------------------------------------------------------------------- /fesvr/dummy.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | // help out poor, C-centric autoconf 4 | extern "C" void libfesvr_is_present() {} 5 | -------------------------------------------------------------------------------- /fesvr/elfloader.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _ELFLOADER_H 4 | #define _ELFLOADER_H 5 | 6 | #include "elf.h" 7 | #include 8 | #include 9 | 10 | class memif_t; 11 | std::map load_elf(const char* fn, memif_t* memif, reg_t* entry); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /fesvr/fesvr.ac: -------------------------------------------------------------------------------- 1 | AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([libpthread is required])]) 2 | -------------------------------------------------------------------------------- /fesvr/fesvr.mk.in: -------------------------------------------------------------------------------- 1 | fesvr_hdrs = \ 2 | elf.h \ 3 | elfloader.h \ 4 | htif.h \ 5 | dtm.h \ 6 | memif.h \ 7 | syscall.h \ 8 | context.h \ 9 | htif_pthread.h \ 10 | htif_hexwriter.h \ 11 | option_parser.h \ 12 | term.h \ 13 | device.h \ 14 | rfb.h \ 15 | tsi.h \ 16 | 17 | fesvr_CFLAGS = -fPIC 18 | 19 | fesvr_install_hdrs = $(fesvr_hdrs) 20 | 21 | fesvr_install_lib = yes 22 | 23 | fesvr_srcs = \ 24 | elfloader.cc \ 25 | htif.cc \ 26 | memif.cc \ 27 | dtm.cc \ 28 | syscall.cc \ 29 | device.cc \ 30 | rfb.cc \ 31 | context.cc \ 32 | htif_pthread.cc \ 33 | htif_hexwriter.cc \ 34 | dummy.cc \ 35 | option_parser.cc \ 36 | term.cc \ 37 | tsi.cc \ 38 | 39 | fesvr_install_prog_srcs = \ 40 | elf2hex.cc \ 41 | -------------------------------------------------------------------------------- /fesvr/fesvr.pc.in: -------------------------------------------------------------------------------- 1 | #========================================================================= 2 | # Modular C++ Build System Subproject Package Config 3 | #========================================================================= 4 | # Please read the documenation in 'mcppbs-uguide.txt' for more details 5 | # on how the Modular C++ Build System works. 6 | 7 | #------------------------------------------------------------------------- 8 | # Generic variables 9 | #------------------------------------------------------------------------- 10 | 11 | prefix=@prefix@ 12 | include_dir=${prefix}/include/fesvr 13 | lib_dir=${prefix}/lib 14 | 15 | #------------------------------------------------------------------------- 16 | # Keywords 17 | #------------------------------------------------------------------------- 18 | 19 | Name : fesvr 20 | Version : @PACKAGE_VERSION@ 21 | Description : Frontend Server C/C++ API 22 | Requires : @fesvr_pkcdeps@ 23 | Cflags : -I${include_dir} @CPPFLAGS@ @fesvr_extra_cppflags@ 24 | Libs : -L${lib_dir} @LDFLAGS@ @fesvr_extra_ldflags@ \ 25 | -lfesvr @fesvr_extra_libs@ 26 | 27 | -------------------------------------------------------------------------------- /fesvr/htif_hexwriter.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef __HTIF_HEXWRITER_H 4 | #define __HTIF_HEXWRITER_H 5 | 6 | #include 7 | #include 8 | #include 9 | #include "memif.h" 10 | 11 | class htif_hexwriter_t : public chunked_memif_t 12 | { 13 | public: 14 | htif_hexwriter_t(size_t b, size_t w, size_t d); 15 | 16 | protected: 17 | size_t base; 18 | size_t width; 19 | size_t depth; 20 | std::map > mem; 21 | 22 | void read_chunk(addr_t taddr, size_t len, void* dst); 23 | void write_chunk(addr_t taddr, size_t len, const void* src); 24 | void clear_chunk(addr_t taddr, size_t len) {} 25 | 26 | size_t chunk_max_size() { return width; } 27 | size_t chunk_align() { return width; } 28 | 29 | friend std::ostream& operator<< (std::ostream&, const htif_hexwriter_t&); 30 | }; 31 | 32 | #endif // __HTIF_HEXWRITER_H 33 | -------------------------------------------------------------------------------- /fesvr/htif_pthread.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _HTIF_PTHREAD_H 4 | #define _HTIF_PTHREAD_H 5 | 6 | #include "htif.h" 7 | #include "context.h" 8 | #include 9 | 10 | class htif_pthread_t : public htif_t 11 | { 12 | public: 13 | htif_pthread_t(int argc, char** argv); 14 | virtual ~htif_pthread_t(); 15 | 16 | // target inteface 17 | void send(const void* buf, size_t size); 18 | void recv(void* buf, size_t size); 19 | bool recv_nonblocking(void* buf, size_t size); 20 | 21 | protected: 22 | // host interface 23 | virtual ssize_t read(void* buf, size_t max_size); 24 | virtual ssize_t write(const void* buf, size_t size); 25 | 26 | virtual size_t chunk_align() { return 64; } 27 | virtual size_t chunk_max_size() { return 1024; } 28 | 29 | private: 30 | context_t host; 31 | context_t* target; 32 | std::deque th_data; 33 | std::deque ht_data; 34 | 35 | static void thread_main(void* htif); 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /fesvr/option_parser.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _OPTION_PARSER_H 4 | #define _OPTION_PARSER_H 5 | 6 | #include 7 | #include 8 | 9 | class option_parser_t 10 | { 11 | public: 12 | option_parser_t() : helpmsg(0) {} 13 | void help(void (*helpm)(void)) { helpmsg = helpm; } 14 | void option(char c, const char* s, int arg, std::function action); 15 | const char* const* parse(const char* const* argv0); 16 | private: 17 | struct option_t 18 | { 19 | char chr; 20 | const char* str; 21 | int arg; 22 | std::function func; 23 | option_t(char chr, const char* str, int arg, std::function func) 24 | : chr(chr), str(str), arg(arg), func(func) {} 25 | }; 26 | std::vector opts; 27 | void (*helpmsg)(void); 28 | void error(const char* msg, const char* argv0, const char* arg); 29 | }; 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /fesvr/term.h: -------------------------------------------------------------------------------- 1 | #ifndef _TERM_H 2 | #define _TERM_H 3 | 4 | class canonical_terminal_t 5 | { 6 | public: 7 | static int read(); 8 | static void write(char); 9 | }; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /riscv-dummy_rocc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=${prefix}/@libdir@ 4 | includedir=${prefix}/@includedir@ 5 | 6 | Name: riscv-dummy_rocc 7 | Description: Example RISC-V ROCC accelerator 8 | Version: git 9 | Libs: -Wl,-rpath,${libdir} -L${libdir} -ldummy_rocc 10 | Cflags: -I${includedir} 11 | URL: http://riscv.org/download.html#tab_spike 12 | -------------------------------------------------------------------------------- /riscv-fesvr.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=${prefix}/@libdir@ 4 | includedir=${prefix}/@includedir@ 5 | 6 | Name: riscv-fesvr 7 | Description: RISC-V front-end server 8 | Version: git 9 | Libs: -Wl,-rpath,${libdir} -L${libdir} -lfesvr 10 | Cflags: -I${includedir} 11 | URL: http://riscv.org/download.html#tab_fesvr 12 | -------------------------------------------------------------------------------- /riscv-riscv.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=${prefix}/@libdir@ 4 | includedir=${prefix}/@includedir@ 5 | 6 | Name: riscv-riscv 7 | Description: RISC-V 8 | Version: git 9 | Libs: -Wl,-rpath,${libdir} -L${libdir} -lriscv 10 | Cflags: -I${includedir} 11 | URL: http://riscv.org/download.html#tab_spike 12 | -------------------------------------------------------------------------------- /riscv-softfloat.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=${prefix}/@libdir@ 4 | includedir=${prefix}/@includedir@ 5 | 6 | Name: riscv-softfloat 7 | Description: RISC-V softfloat library 8 | Version: git 9 | Libs: -Wl,-rpath,${libdir} -L${libdir} -lsoftfloat 10 | Cflags: -I${includedir} 11 | URL: http://riscv.org/download.html#tab_spike 12 | -------------------------------------------------------------------------------- /riscv-spike.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=${prefix}/@libdir@ 4 | includedir=${prefix}/@includedir@ 5 | 6 | Name: riscv-spike 7 | Description: RISC-V spike meta library 8 | Version: git 9 | Depends: riscv-spike_main riscv-riscv riscv-softfloat 10 | URL: http://riscv.org/download.html#tab_spike 11 | -------------------------------------------------------------------------------- /riscv-spike_main.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@prefix@ 3 | libdir=${prefix}/@libdir@ 4 | includedir=${prefix}/@includedir@ 5 | 6 | Name: riscv-spike_main 7 | Description: RISC-V ISA simulator library 8 | Version: git 9 | Depends: riscv-riscv riscv-softfloat 10 | Libs: -Wl,-rpath,${libdir} -L${libdir} -lspike_main 11 | Cflags: -I${includedir} 12 | URL: http://riscv.org/download.html#tab_spike 13 | -------------------------------------------------------------------------------- /riscv/common.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _RISCV_COMMON_H 4 | #define _RISCV_COMMON_H 5 | 6 | #define likely(x) __builtin_expect(x, 1) 7 | #define unlikely(x) __builtin_expect(x, 0) 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /riscv/debug_rom_defines.h: -------------------------------------------------------------------------------- 1 | // See LICENSE file for license details. 2 | 3 | #ifndef DEBUG_ROM_DEFINES_H 4 | #define DEBUG_ROM_DEFINES_H 5 | 6 | // These are implementation-specific addresses in the Debug Module 7 | #define DEBUG_ROM_HALTED 0x100 8 | #define DEBUG_ROM_GOING 0x104 9 | #define DEBUG_ROM_RESUMING 0x108 10 | #define DEBUG_ROM_EXCEPTION 0x10C 11 | 12 | // Region of memory where each hart has 1 13 | // byte to read. 14 | #define DEBUG_ROM_FLAGS 0x400 15 | #define DEBUG_ROM_FLAG_GO 0 16 | #define DEBUG_ROM_FLAG_RESUME 1 17 | 18 | // These needs to match the link.ld 19 | #define DEBUG_ROM_WHERETO 0x300 20 | #define DEBUG_ROM_ENTRY 0x800 21 | #define DEBUG_ROM_TVEC 0x808 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /riscv/dts.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | #ifndef _RISCV_DTS_H 3 | #define _RISCV_DTS_H 4 | 5 | #include "processor.h" 6 | #include "mmu.h" 7 | #include 8 | 9 | std::string make_dts(size_t insns_per_rtc_tick, size_t cpu_hz, 10 | std::vector procs, 11 | std::vector> mems); 12 | 13 | std::string dts_compile(const std::string& dts); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /riscv/extension.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include "extension.h" 4 | #include "trap.h" 5 | 6 | extension_t::~extension_t() 7 | { 8 | } 9 | 10 | void extension_t::illegal_instruction() 11 | { 12 | throw trap_illegal_instruction(0); 13 | } 14 | 15 | void extension_t::raise_interrupt() 16 | { 17 | p->take_interrupt((reg_t)1 << IRQ_COP); // must not return 18 | throw std::logic_error("a COP exception was posted, but interrupts are disabled!"); 19 | } 20 | 21 | void extension_t::clear_interrupt() 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /riscv/extension.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _RISCV_COPROCESSOR_H 4 | #define _RISCV_COPROCESSOR_H 5 | 6 | #include "processor.h" 7 | #include "disasm.h" 8 | #include 9 | #include 10 | 11 | class extension_t 12 | { 13 | public: 14 | virtual std::vector get_instructions() = 0; 15 | virtual std::vector get_disasms() = 0; 16 | virtual const char* name() = 0; 17 | virtual void reset() {}; 18 | virtual void set_debug(bool value) {}; 19 | virtual ~extension_t(); 20 | 21 | void set_processor(processor_t* _p) { p = _p; } 22 | protected: 23 | processor_t* p; 24 | 25 | void illegal_instruction(); 26 | void raise_interrupt(); 27 | void clear_interrupt(); 28 | }; 29 | 30 | std::function find_extension(const char* name); 31 | void register_extension(const char* name, std::function f); 32 | 33 | #define REGISTER_EXTENSION(name, constructor) \ 34 | class register_##name { \ 35 | public: register_##name() { register_extension(#name, constructor); } \ 36 | }; static register_##name dummy_##name; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /riscv/extensions.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include "extension.h" 4 | #include 5 | #include 6 | #include 7 | 8 | static std::map>& extensions() 9 | { 10 | static std::map> v; 11 | return v; 12 | } 13 | 14 | void register_extension(const char* name, std::function f) 15 | { 16 | extensions()[name] = f; 17 | } 18 | 19 | std::function find_extension(const char* name) 20 | { 21 | if (!extensions().count(name)) { 22 | // try to find extension xyz by loading libxyz.so 23 | std::string libname = std::string("lib") + name + ".so"; 24 | if (!dlopen(libname.c_str(), RTLD_LAZY)) { 25 | fprintf(stderr, "couldn't find extension '%s' (or library '%s')\n", 26 | name, libname.c_str()); 27 | exit(-1); 28 | } 29 | if (!extensions().count(name)) { 30 | fprintf(stderr, "couldn't find extension '%s' in shared library '%s'\n", 31 | name, libname.c_str()); 32 | exit(-1); 33 | } 34 | } 35 | 36 | return extensions()[name]; 37 | } 38 | -------------------------------------------------------------------------------- /riscv/gen_icache: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | n=$(($1-1)) 3 | for i in `seq 0 $n` 4 | do 5 | echo case $i: ICACHE_ACCESS\($i\)\; 6 | done 7 | echo 8 | -------------------------------------------------------------------------------- /riscv/insn_template.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include "insn_template.h" 4 | 5 | reg_t rv32_NAME(processor_t* p, insn_t insn, reg_t pc) 6 | { 7 | int xlen = 32; 8 | reg_t npc = sext_xlen(pc + insn_length(OPCODE)); 9 | #include "insns/NAME.h" 10 | trace_opcode(p, OPCODE, insn); 11 | return npc; 12 | } 13 | 14 | reg_t rv64_NAME(processor_t* p, insn_t insn, reg_t pc) 15 | { 16 | int xlen = 64; 17 | reg_t npc = sext_xlen(pc + insn_length(OPCODE)); 18 | #include "insns/NAME.h" 19 | trace_opcode(p, OPCODE, insn); 20 | return npc; 21 | } 22 | -------------------------------------------------------------------------------- /riscv/insn_template.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include "arith.h" 4 | #include "mmu.h" 5 | #include "softfloat.h" 6 | #include "internals.h" 7 | #include "specialize.h" 8 | #include "tracer.h" 9 | #include 10 | -------------------------------------------------------------------------------- /riscv/insns/add.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(RS1 + RS2)); 2 | -------------------------------------------------------------------------------- /riscv/insns/addi.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(RS1 + insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/addiw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(insn.i_imm() + RS1)); 3 | -------------------------------------------------------------------------------- /riscv/insns/addw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(RS1 + RS2)); 3 | -------------------------------------------------------------------------------- /riscv/insns/amoadd_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs + RS2; })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amoadd_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs + RS2; }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amoand_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs & RS2; })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amoand_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs & RS2; }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amomax_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](int64_t lhs) { return std::max(lhs, int64_t(RS2)); })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amomax_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](int32_t lhs) { return std::max(lhs, int32_t(RS2)); }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amomaxu_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return std::max(lhs, RS2); })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amomaxu_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return std::max(lhs, uint32_t(RS2)); }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amomin_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](int64_t lhs) { return std::min(lhs, int64_t(RS2)); })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amomin_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](int32_t lhs) { return std::min(lhs, int32_t(RS2)); }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amominu_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return std::min(lhs, RS2); })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amominu_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return std::min(lhs, uint32_t(RS2)); }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amoor_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs | RS2; })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amoor_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs | RS2; }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amoswap_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return RS2; })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amoswap_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return RS2; }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/amoxor_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs ^ RS2; })); 4 | -------------------------------------------------------------------------------- /riscv/insns/amoxor_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs ^ RS2; }))); 3 | -------------------------------------------------------------------------------- /riscv/insns/and.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(RS1 & RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/andi.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(insn.i_imm() & RS1); 2 | -------------------------------------------------------------------------------- /riscv/insns/auipc.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(insn.u_imm() + pc)); 2 | -------------------------------------------------------------------------------- /riscv/insns/beq.h: -------------------------------------------------------------------------------- 1 | if(RS1 == RS2) 2 | set_pc(BRANCH_TARGET); 3 | -------------------------------------------------------------------------------- /riscv/insns/bge.h: -------------------------------------------------------------------------------- 1 | if(sreg_t(RS1) >= sreg_t(RS2)) 2 | set_pc(BRANCH_TARGET); 3 | -------------------------------------------------------------------------------- /riscv/insns/bgeu.h: -------------------------------------------------------------------------------- 1 | if(RS1 >= RS2) 2 | set_pc(BRANCH_TARGET); 3 | -------------------------------------------------------------------------------- /riscv/insns/blt.h: -------------------------------------------------------------------------------- 1 | if(sreg_t(RS1) < sreg_t(RS2)) 2 | set_pc(BRANCH_TARGET); 3 | -------------------------------------------------------------------------------- /riscv/insns/bltu.h: -------------------------------------------------------------------------------- 1 | if(RS1 < RS2) 2 | set_pc(BRANCH_TARGET); 3 | -------------------------------------------------------------------------------- /riscv/insns/bne.h: -------------------------------------------------------------------------------- 1 | if(RS1 != RS2) 2 | set_pc(BRANCH_TARGET); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_add.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_rs2() != 0); 3 | WRITE_RD(sext_xlen(RVC_RS1 + RVC_RS2)); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_addi.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RD(sext_xlen(RVC_RS1 + insn.rvc_imm())); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_addi4spn.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_addi4spn_imm() != 0); 3 | WRITE_RVC_RS2S(sext_xlen(RVC_SP + insn.rvc_addi4spn_imm())); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_addw.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require_rv64; 3 | WRITE_RVC_RS1S(sext32(RVC_RS1S + RVC_RS2S)); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_and.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RVC_RS1S(RVC_RS1S & RVC_RS2S); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_andi.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RVC_RS1S(RVC_RS1S & insn.rvc_imm()); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_beqz.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (RVC_RS1S == 0) 3 | set_pc(pc + insn.rvc_b_imm()); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_bnez.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (RVC_RS1S != 0) 3 | set_pc(pc + insn.rvc_b_imm()); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_ebreak.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | throw trap_breakpoint(pc); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_fld.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require_extension('D'); 3 | require_fp; 4 | WRITE_RVC_FRS2S(f64(MMU.load_uint64(RVC_RS1S + insn.rvc_ld_imm()))); 5 | -------------------------------------------------------------------------------- /riscv/insns/c_fldsp.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require_extension('D'); 3 | require_fp; 4 | WRITE_FRD(f64(MMU.load_uint64(RVC_SP + insn.rvc_ldsp_imm()))); 5 | -------------------------------------------------------------------------------- /riscv/insns/c_flw.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (xlen == 32) { 3 | require_extension('F'); 4 | require_fp; 5 | WRITE_RVC_FRS2S(f32(MMU.load_uint32(RVC_RS1S + insn.rvc_lw_imm()))); 6 | } else { // c.ld 7 | WRITE_RVC_RS2S(MMU.load_int64(RVC_RS1S + insn.rvc_ld_imm())); 8 | } 9 | -------------------------------------------------------------------------------- /riscv/insns/c_flwsp.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (xlen == 32) { 3 | require_extension('F'); 4 | require_fp; 5 | WRITE_FRD(f32(MMU.load_uint32(RVC_SP + insn.rvc_lwsp_imm()))); 6 | } else { // c.ldsp 7 | require(insn.rvc_rd() != 0); 8 | WRITE_RD(MMU.load_int64(RVC_SP + insn.rvc_ldsp_imm())); 9 | } 10 | -------------------------------------------------------------------------------- /riscv/insns/c_fsd.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require_extension('D'); 3 | require_fp; 4 | MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_FRS2S.v[0]); 5 | -------------------------------------------------------------------------------- /riscv/insns/c_fsdsp.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require_extension('D'); 3 | require_fp; 4 | MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_FRS2.v[0]); 5 | -------------------------------------------------------------------------------- /riscv/insns/c_fsw.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (xlen == 32) { 3 | require_extension('F'); 4 | require_fp; 5 | MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v[0]); 6 | } else { // c.sd 7 | MMU.store_uint64(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S); 8 | } 9 | -------------------------------------------------------------------------------- /riscv/insns/c_fswsp.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (xlen == 32) { 3 | require_extension('F'); 4 | require_fp; 5 | MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v[0]); 6 | } else { // c.sdsp 7 | MMU.store_uint64(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2); 8 | } 9 | -------------------------------------------------------------------------------- /riscv/insns/c_j.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | set_pc(pc + insn.rvc_j_imm()); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_jal.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (xlen == 32) { 3 | reg_t tmp = npc; 4 | set_pc(pc + insn.rvc_j_imm()); 5 | WRITE_REG(X_RA, tmp); 6 | } else { // c.addiw 7 | require(insn.rvc_rd() != 0); 8 | WRITE_RD(sext32(RVC_RS1 + insn.rvc_imm())); 9 | } 10 | -------------------------------------------------------------------------------- /riscv/insns/c_jalr.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_rs1() != 0); 3 | reg_t tmp = npc; 4 | set_pc(RVC_RS1 & ~reg_t(1)); 5 | WRITE_REG(X_RA, tmp); 6 | -------------------------------------------------------------------------------- /riscv/insns/c_jr.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_rs1() != 0); 3 | set_pc(RVC_RS1 & ~reg_t(1)); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_li.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RD(insn.rvc_imm()); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_lui.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | if (insn.rvc_rd() == 2) { // c.addi16sp 3 | require(insn.rvc_addi16sp_imm() != 0); 4 | WRITE_REG(X_SP, sext_xlen(RVC_SP + insn.rvc_addi16sp_imm())); 5 | } else { 6 | require(insn.rvc_imm() != 0); 7 | WRITE_RD(insn.rvc_imm() << 12); 8 | } 9 | -------------------------------------------------------------------------------- /riscv/insns/c_lw.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RVC_RS2S(MMU.load_int32(RVC_RS1S + insn.rvc_lw_imm())); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_lwsp.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_rd() != 0); 3 | WRITE_RD(MMU.load_int32(RVC_SP + insn.rvc_lwsp_imm())); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_mv.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_rs2() != 0); 3 | WRITE_RD(RVC_RS2); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_or.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RVC_RS1S(RVC_RS1S | RVC_RS2S); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_slli.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_zimm() < xlen); 3 | WRITE_RD(sext_xlen(RVC_RS1 << insn.rvc_zimm())); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_srai.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_zimm() < xlen); 3 | WRITE_RVC_RS1S(sext_xlen(sext_xlen(RVC_RS1S) >> insn.rvc_zimm())); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_srli.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require(insn.rvc_zimm() < xlen); 3 | WRITE_RVC_RS1S(sext_xlen(zext_xlen(RVC_RS1S) >> insn.rvc_zimm())); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_sub.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RVC_RS1S(sext_xlen(RVC_RS1S - RVC_RS2S)); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_subw.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | require_rv64; 3 | WRITE_RVC_RS1S(sext32(RVC_RS1S - RVC_RS2S)); 4 | -------------------------------------------------------------------------------- /riscv/insns/c_sw.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | MMU.store_uint32(RVC_RS1S + insn.rvc_lw_imm(), RVC_RS2S); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_swsp.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | MMU.store_uint32(RVC_SP + insn.rvc_swsp_imm(), RVC_RS2); 3 | -------------------------------------------------------------------------------- /riscv/insns/c_xor.h: -------------------------------------------------------------------------------- 1 | require_extension('C'); 2 | WRITE_RVC_RS1S(RVC_RS1S ^ RVC_RS2S); 3 | -------------------------------------------------------------------------------- /riscv/insns/csrrc.h: -------------------------------------------------------------------------------- 1 | bool write = insn.rs1() != 0; 2 | int csr = validate_csr(insn.csr(), write); 3 | reg_t old = p->get_csr(csr); 4 | if (write) { 5 | p->set_csr(csr, old & ~RS1); 6 | } 7 | WRITE_RD(sext_xlen(old)); 8 | serialize(); 9 | -------------------------------------------------------------------------------- /riscv/insns/csrrci.h: -------------------------------------------------------------------------------- 1 | bool write = insn.rs1() != 0; 2 | int csr = validate_csr(insn.csr(), write); 3 | reg_t old = p->get_csr(csr); 4 | if (write) { 5 | p->set_csr(csr, old & ~(reg_t)insn.rs1()); 6 | } 7 | WRITE_RD(sext_xlen(old)); 8 | serialize(); 9 | -------------------------------------------------------------------------------- /riscv/insns/csrrs.h: -------------------------------------------------------------------------------- 1 | bool write = insn.rs1() != 0; 2 | int csr = validate_csr(insn.csr(), write); 3 | reg_t old = p->get_csr(csr); 4 | if (write) { 5 | p->set_csr(csr, old | RS1); 6 | } 7 | WRITE_RD(sext_xlen(old)); 8 | serialize(); 9 | -------------------------------------------------------------------------------- /riscv/insns/csrrsi.h: -------------------------------------------------------------------------------- 1 | bool write = insn.rs1() != 0; 2 | int csr = validate_csr(insn.csr(), write); 3 | reg_t old = p->get_csr(csr); 4 | if (write) { 5 | p->set_csr(csr, old | insn.rs1()); 6 | } 7 | WRITE_RD(sext_xlen(old)); 8 | serialize(); 9 | -------------------------------------------------------------------------------- /riscv/insns/csrrw.h: -------------------------------------------------------------------------------- 1 | int csr = validate_csr(insn.csr(), true); 2 | reg_t old = p->get_csr(csr); 3 | p->set_csr(csr, RS1); 4 | WRITE_RD(sext_xlen(old)); 5 | serialize(); 6 | -------------------------------------------------------------------------------- /riscv/insns/csrrwi.h: -------------------------------------------------------------------------------- 1 | int csr = validate_csr(insn.csr(), true); 2 | reg_t old = p->get_csr(csr); 3 | p->set_csr(csr, insn.rs1()); 4 | WRITE_RD(sext_xlen(old)); 5 | serialize(); 6 | -------------------------------------------------------------------------------- /riscv/insns/div.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | sreg_t lhs = sext_xlen(RS1); 3 | sreg_t rhs = sext_xlen(RS2); 4 | if(rhs == 0) 5 | WRITE_RD(UINT64_MAX); 6 | else if(lhs == INT64_MIN && rhs == -1) 7 | WRITE_RD(lhs); 8 | else 9 | WRITE_RD(sext_xlen(lhs / rhs)); 10 | -------------------------------------------------------------------------------- /riscv/insns/divu.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | reg_t lhs = zext_xlen(RS1); 3 | reg_t rhs = zext_xlen(RS2); 4 | if(rhs == 0) 5 | WRITE_RD(UINT64_MAX); 6 | else 7 | WRITE_RD(sext_xlen(lhs / rhs)); 8 | -------------------------------------------------------------------------------- /riscv/insns/divuw.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | require_rv64; 3 | reg_t lhs = zext32(RS1); 4 | reg_t rhs = zext32(RS2); 5 | if(rhs == 0) 6 | WRITE_RD(UINT64_MAX); 7 | else 8 | WRITE_RD(sext32(lhs / rhs)); 9 | -------------------------------------------------------------------------------- /riscv/insns/divw.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | require_rv64; 3 | sreg_t lhs = sext32(RS1); 4 | sreg_t rhs = sext32(RS2); 5 | if(rhs == 0) 6 | WRITE_RD(UINT64_MAX); 7 | else 8 | WRITE_RD(sext32(lhs / rhs)); 9 | -------------------------------------------------------------------------------- /riscv/insns/dret.h: -------------------------------------------------------------------------------- 1 | require(STATE.debug_mode); 2 | set_pc_and_serialize(STATE.dpc); 3 | p->set_privilege(STATE.dcsr.prv); 4 | 5 | /* We're not in Debug Mode anymore. */ 6 | STATE.debug_mode = false; 7 | 8 | if (STATE.dcsr.step) 9 | STATE.single_step = STATE.STEP_STEPPING; 10 | -------------------------------------------------------------------------------- /riscv/insns/ebreak.h: -------------------------------------------------------------------------------- 1 | throw trap_breakpoint(pc); 2 | -------------------------------------------------------------------------------- /riscv/insns/ecall.h: -------------------------------------------------------------------------------- 1 | switch (STATE.prv) 2 | { 3 | case PRV_U: throw trap_user_ecall(); 4 | case PRV_S: throw trap_supervisor_ecall(); 5 | case PRV_M: throw trap_machine_ecall(); 6 | default: abort(); 7 | } 8 | -------------------------------------------------------------------------------- /riscv/insns/fadd_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_add(f64(FRS1), f64(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fadd_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_add(f128(FRS1), f128(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fadd_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_add(f32(FRS1), f32(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fclass_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_RD(f64_classify(f64(FRS1))); 4 | -------------------------------------------------------------------------------- /riscv/insns/fclass_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_RD(f128_classify(f128(FRS1))); 4 | -------------------------------------------------------------------------------- /riscv/insns/fclass_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_RD(f32_classify(f32(FRS1))); 4 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_d_l.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_FRD(i64_to_f64(RS1)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_d_lu.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_FRD(ui64_to_f64(RS1)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_d_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_to_f64(f128(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_d_s.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_to_f64(f32(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_d_w.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(i32_to_f64((int32_t)RS1)); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_d_wu.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(ui32_to_f64((uint32_t)RS1)); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_l_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_RD(f64_to_i64(f64(FRS1), RM, true)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_l_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_RD(f128_to_i64(f128(FRS1), RM, true)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_l_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_RD(f32_to_i64(f32(FRS1), RM, true)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_lu_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_RD(f64_to_ui64(f64(FRS1), RM, true)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_lu_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_RD(f128_to_ui64(f128(FRS1), RM, true)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_lu_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_RD(f32_to_ui64(f32(FRS1), RM, true)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_q_d.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_to_f128(f64(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_q_l.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_FRD(i64_to_f128(RS1)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_q_lu.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_FRD(ui64_to_f128(RS1)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_q_s.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_to_f128(f32(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_q_w.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(i32_to_f128((int32_t)RS1)); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_q_wu.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(ui32_to_f128((uint32_t)RS1)); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_s_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_to_f32(f64(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_s_l.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_FRD(i64_to_f32(RS1)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_s_lu.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_rv64; 3 | require_fp; 4 | softfloat_roundingMode = RM; 5 | WRITE_FRD(ui64_to_f32(RS1)); 6 | set_fp_exceptions; 7 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_s_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_to_f32(f128(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_s_w.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(i32_to_f32((int32_t)RS1)); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_s_wu.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(ui32_to_f32((uint32_t)RS1)); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_w_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_RD(sext32(f64_to_i32(f64(FRS1), RM, true))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_w_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_RD(sext32(f128_to_i32(f128(FRS1), RM, true))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_w_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_RD(sext32(f32_to_i32(f32(FRS1), RM, true))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_wu_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_RD(sext32(f64_to_ui32(f64(FRS1), RM, true))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_wu_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_RD(sext32(f128_to_ui32(f128(FRS1), RM, true))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fcvt_wu_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_RD(sext32(f32_to_ui32(f32(FRS1), RM, true))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fdiv_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_div(f64(FRS1), f64(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fdiv_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_div(f128(FRS1), f128(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fdiv_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_div(f32(FRS1), f32(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fence.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comparch-security/spike-cache/3639dd7ee57c43b3eb5d70bedfd5b2fdeece3f42/riscv/insns/fence.h -------------------------------------------------------------------------------- /riscv/insns/fence_i.h: -------------------------------------------------------------------------------- 1 | MMU.flush_icache(); 2 | -------------------------------------------------------------------------------- /riscv/insns/feq_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_RD(f64_eq(f64(FRS1), f64(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/feq_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_RD(f128_eq(f128(FRS1), f128(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/feq_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_RD(f32_eq(f32(FRS1), f32(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/fld.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_FRD(f64(MMU.load_uint64(RS1 + insn.i_imm()))); 4 | -------------------------------------------------------------------------------- /riscv/insns/fle_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_RD(f64_le(f64(FRS1), f64(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/fle_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_RD(f128_le(f128(FRS1), f128(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/fle_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_RD(f32_le(f32(FRS1), f32(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/flq.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_FRD(MMU.load_float128(RS1 + insn.i_imm())); 4 | -------------------------------------------------------------------------------- /riscv/insns/flt_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_RD(f64_lt(f64(FRS1), f64(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/flt_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_RD(f128_lt(f128(FRS1), f128(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/flt_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_RD(f32_lt(f32(FRS1), f32(FRS2))); 4 | set_fp_exceptions; 5 | -------------------------------------------------------------------------------- /riscv/insns/flw.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_FRD(f32(MMU.load_uint32(RS1 + insn.i_imm()))); 4 | -------------------------------------------------------------------------------- /riscv/insns/fmadd_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmadd_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_mulAdd(f128(FRS1), f128(FRS2), f128(FRS3))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmadd_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmax_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | bool greater = f64_lt_quiet(f64(FRS2), f64(FRS1)) || 4 | (f64_eq(f64(FRS2), f64(FRS1)) && (f64(FRS2).v & F64_SIGN)); 5 | if (isNaNF64UI(f64(FRS1).v) && isNaNF64UI(f64(FRS2).v)) 6 | WRITE_FRD(f64(defaultNaNF64UI)); 7 | else 8 | WRITE_FRD(greater || isNaNF64UI(f64(FRS2).v) ? FRS1 : FRS2); 9 | set_fp_exceptions; 10 | -------------------------------------------------------------------------------- /riscv/insns/fmax_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | bool greater = f128_lt_quiet(f128(FRS2), f128(FRS1)) || 4 | (f128_eq(f128(FRS2), f128(FRS1)) && (f128(FRS2).v[1] & F64_SIGN)); 5 | if (isNaNF128(f128(FRS1)) && isNaNF128(f128(FRS2))) 6 | WRITE_FRD(f128(defaultNaNF128())); 7 | else 8 | WRITE_FRD(greater || isNaNF128(f128(FRS2)) ? FRS1 : FRS2); 9 | set_fp_exceptions; 10 | -------------------------------------------------------------------------------- /riscv/insns/fmax_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | bool greater = f32_lt_quiet(f32(FRS2), f32(FRS1)) || 4 | (f32_eq(f32(FRS2), f32(FRS1)) && (f32(FRS2).v & F32_SIGN)); 5 | if (isNaNF32UI(f32(FRS1).v) && isNaNF32UI(f32(FRS2).v)) 6 | WRITE_FRD(f32(defaultNaNF32UI)); 7 | else 8 | WRITE_FRD(greater || isNaNF32UI(f32(FRS2).v) ? FRS1 : FRS2); 9 | set_fp_exceptions; 10 | -------------------------------------------------------------------------------- /riscv/insns/fmin_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | bool less = f64_lt_quiet(f64(FRS1), f64(FRS2)) || 4 | (f64_eq(f64(FRS1), f64(FRS2)) && (f64(FRS1).v & F64_SIGN)); 5 | if (isNaNF64UI(f64(FRS1).v) && isNaNF64UI(f64(FRS2).v)) 6 | WRITE_FRD(f64(defaultNaNF64UI)); 7 | else 8 | WRITE_FRD(less || isNaNF64UI(f64(FRS2).v) ? FRS1 : FRS2); 9 | set_fp_exceptions; 10 | -------------------------------------------------------------------------------- /riscv/insns/fmin_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | bool less = f128_lt_quiet(f128(FRS1), f128(FRS2)) || 4 | (f128_eq(f128(FRS1), f128(FRS2)) && (f128(FRS1).v[1] & F64_SIGN)); 5 | if (isNaNF128(f128(FRS1)) && isNaNF128(f128(FRS2))) 6 | WRITE_FRD(f128(defaultNaNF128())); 7 | else 8 | WRITE_FRD(less || isNaNF128(f128(FRS2)) ? FRS1 : FRS2); 9 | set_fp_exceptions; 10 | -------------------------------------------------------------------------------- /riscv/insns/fmin_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | bool less = f32_lt_quiet(f32(FRS1), f32(FRS2)) || 4 | (f32_eq(f32(FRS1), f32(FRS2)) && (f32(FRS1).v & F32_SIGN)); 5 | if (isNaNF32UI(f32(FRS1).v) && isNaNF32UI(f32(FRS2).v)) 6 | WRITE_FRD(f32(defaultNaNF32UI)); 7 | else 8 | WRITE_FRD(less || isNaNF32UI(f32(FRS2).v) ? FRS1 : FRS2); 9 | set_fp_exceptions; 10 | -------------------------------------------------------------------------------- /riscv/insns/fmsub_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(f64(FRS3).v ^ F64_SIGN))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmsub_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_mulAdd(f128(FRS1), f128(FRS2), f128_negate(f128(FRS3)))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmsub_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(f32(FRS3).v ^ F32_SIGN))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmul_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_mul(f64(FRS1), f64(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmul_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_mul(f128(FRS1), f128(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmul_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_mul(f32(FRS1), f32(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fmv_d_x.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_rv64; 3 | require_fp; 4 | WRITE_FRD(f64(RS1)); 5 | -------------------------------------------------------------------------------- /riscv/insns/fmv_w_x.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_FRD(f32(RS1)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fmv_x_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_rv64; 3 | require_fp; 4 | WRITE_RD(FRS1.v[0]); 5 | -------------------------------------------------------------------------------- /riscv/insns/fmv_x_w.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_RD(sext32(FRS1.v[0])); 4 | -------------------------------------------------------------------------------- /riscv/insns/fnmadd_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_mulAdd(f64(f64(FRS1).v ^ F64_SIGN), f64(FRS2), f64(f64(FRS3).v ^ F64_SIGN))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fnmadd_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_mulAdd(f128_negate(f128(FRS1)), f128(FRS2), f128_negate(f128(FRS3)))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fnmadd_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_mulAdd(f32(f32(FRS1).v ^ F32_SIGN), f32(FRS2), f32(f32(FRS3).v ^ F32_SIGN))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fnmsub_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_mulAdd(f64(f64(FRS1).v ^ F64_SIGN), f64(FRS2), f64(FRS3))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fnmsub_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_mulAdd(f128_negate(f128(FRS1)), f128(FRS2), f128(FRS3))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fnmsub_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_mulAdd(f32(f32(FRS1).v ^ F32_SIGN), f32(FRS2), f32(FRS3))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsd.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | MMU.store_uint64(RS1 + insn.s_imm(), FRS2.v[0]); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnj_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_FRD(fsgnj64(FRS1, FRS2, false, false)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnj_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_FRD(fsgnj128(FRS1, FRS2, false, false)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnj_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_FRD(fsgnj32(FRS1, FRS2, false, false)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnjn_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_FRD(fsgnj64(FRS1, FRS2, true, false)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnjn_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_FRD(fsgnj128(FRS1, FRS2, true, false)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnjn_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_FRD(fsgnj32(FRS1, FRS2, true, false)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnjx_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | WRITE_FRD(fsgnj64(FRS1, FRS2, false, true)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnjx_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | WRITE_FRD(fsgnj128(FRS1, FRS2, false, true)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsgnjx_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | WRITE_FRD(fsgnj32(FRS1, FRS2, false, true)); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsq.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | MMU.store_float128(RS1 + insn.s_imm(), FRS2); 4 | -------------------------------------------------------------------------------- /riscv/insns/fsqrt_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_sqrt(f64(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsqrt_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_sqrt(f128(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsqrt_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_sqrt(f32(FRS1))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsub_d.h: -------------------------------------------------------------------------------- 1 | require_extension('D'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f64_sub(f64(FRS1), f64(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsub_q.h: -------------------------------------------------------------------------------- 1 | require_extension('Q'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f128_sub(f128(FRS1), f128(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsub_s.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | softfloat_roundingMode = RM; 4 | WRITE_FRD(f32_sub(f32(FRS1), f32(FRS2))); 5 | set_fp_exceptions; 6 | -------------------------------------------------------------------------------- /riscv/insns/fsw.h: -------------------------------------------------------------------------------- 1 | require_extension('F'); 2 | require_fp; 3 | MMU.store_uint32(RS1 + insn.s_imm(), FRS2.v[0]); 4 | -------------------------------------------------------------------------------- /riscv/insns/jal.h: -------------------------------------------------------------------------------- 1 | reg_t tmp = npc; 2 | set_pc(JUMP_TARGET); 3 | WRITE_RD(tmp); 4 | -------------------------------------------------------------------------------- /riscv/insns/jalr.h: -------------------------------------------------------------------------------- 1 | reg_t tmp = npc; 2 | set_pc((RS1 + insn.i_imm()) & ~reg_t(1)); 3 | WRITE_RD(tmp); 4 | -------------------------------------------------------------------------------- /riscv/insns/lb.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(MMU.load_int8(RS1 + insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/lbu.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(MMU.load_uint8(RS1 + insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/ld.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(MMU.load_int64(RS1 + insn.i_imm())); 3 | -------------------------------------------------------------------------------- /riscv/insns/lh.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(MMU.load_int16(RS1 + insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/lhu.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(MMU.load_uint16(RS1 + insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/lr_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | MMU.acquire_load_reservation(RS1); 4 | WRITE_RD(MMU.load_int64(RS1)); 5 | -------------------------------------------------------------------------------- /riscv/insns/lr_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | MMU.acquire_load_reservation(RS1); 3 | WRITE_RD(MMU.load_int32(RS1)); 4 | -------------------------------------------------------------------------------- /riscv/insns/lui.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(insn.u_imm()); 2 | -------------------------------------------------------------------------------- /riscv/insns/lw.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(MMU.load_int32(RS1 + insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/lwu.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(MMU.load_uint32(RS1 + insn.i_imm())); 3 | -------------------------------------------------------------------------------- /riscv/insns/mret.h: -------------------------------------------------------------------------------- 1 | require_privilege(PRV_M); 2 | set_pc_and_serialize(p->get_state()->mepc); 3 | reg_t s = STATE.mstatus; 4 | reg_t prev_prv = get_field(s, MSTATUS_MPP); 5 | s = set_field(s, MSTATUS_MIE, get_field(s, MSTATUS_MPIE)); 6 | s = set_field(s, MSTATUS_MPIE, 1); 7 | s = set_field(s, MSTATUS_MPP, PRV_U); 8 | p->set_privilege(prev_prv); 9 | p->set_csr(CSR_MSTATUS, s); 10 | -------------------------------------------------------------------------------- /riscv/insns/mul.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | WRITE_RD(sext_xlen(RS1 * RS2)); 3 | -------------------------------------------------------------------------------- /riscv/insns/mulh.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | if (xlen == 64) 3 | WRITE_RD(mulh(RS1, RS2)); 4 | else 5 | WRITE_RD(sext32((sext32(RS1) * sext32(RS2)) >> 32)); 6 | -------------------------------------------------------------------------------- /riscv/insns/mulhsu.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | if (xlen == 64) 3 | WRITE_RD(mulhsu(RS1, RS2)); 4 | else 5 | WRITE_RD(sext32((sext32(RS1) * reg_t((uint32_t)RS2)) >> 32)); 6 | -------------------------------------------------------------------------------- /riscv/insns/mulhu.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | if (xlen == 64) 3 | WRITE_RD(mulhu(RS1, RS2)); 4 | else 5 | WRITE_RD(sext32(((uint64_t)(uint32_t)RS1 * (uint64_t)(uint32_t)RS2) >> 32)); 6 | -------------------------------------------------------------------------------- /riscv/insns/mulw.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | require_rv64; 3 | WRITE_RD(sext32(RS1 * RS2)); 4 | -------------------------------------------------------------------------------- /riscv/insns/or.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(RS1 | RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/ori.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(insn.i_imm() | RS1); 2 | -------------------------------------------------------------------------------- /riscv/insns/rem.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | sreg_t lhs = sext_xlen(RS1); 3 | sreg_t rhs = sext_xlen(RS2); 4 | if(rhs == 0) 5 | WRITE_RD(lhs); 6 | else if(lhs == INT64_MIN && rhs == -1) 7 | WRITE_RD(0); 8 | else 9 | WRITE_RD(sext_xlen(lhs % rhs)); 10 | -------------------------------------------------------------------------------- /riscv/insns/remu.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | reg_t lhs = zext_xlen(RS1); 3 | reg_t rhs = zext_xlen(RS2); 4 | if(rhs == 0) 5 | WRITE_RD(sext_xlen(RS1)); 6 | else 7 | WRITE_RD(sext_xlen(lhs % rhs)); 8 | -------------------------------------------------------------------------------- /riscv/insns/remuw.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | require_rv64; 3 | reg_t lhs = zext32(RS1); 4 | reg_t rhs = zext32(RS2); 5 | if(rhs == 0) 6 | WRITE_RD(sext32(lhs)); 7 | else 8 | WRITE_RD(sext32(lhs % rhs)); 9 | -------------------------------------------------------------------------------- /riscv/insns/remw.h: -------------------------------------------------------------------------------- 1 | require_extension('M'); 2 | require_rv64; 3 | sreg_t lhs = sext32(RS1); 4 | sreg_t rhs = sext32(RS2); 5 | if(rhs == 0) 6 | WRITE_RD(lhs); 7 | else 8 | WRITE_RD(sext32(lhs % rhs)); 9 | -------------------------------------------------------------------------------- /riscv/insns/sb.h: -------------------------------------------------------------------------------- 1 | MMU.store_uint8(RS1 + insn.s_imm(), RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/sc_d.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | require_rv64; 3 | 4 | bool have_reservation = MMU.check_load_reservation(RS1); 5 | MMU.amo_uint64(RS1, [&](uint64_t lhs) { return have_reservation ? RS2 : lhs; }); 6 | MMU.yield_load_reservation(); 7 | 8 | WRITE_RD(!have_reservation); 9 | -------------------------------------------------------------------------------- /riscv/insns/sc_w.h: -------------------------------------------------------------------------------- 1 | require_extension('A'); 2 | 3 | bool have_reservation = MMU.check_load_reservation(RS1); 4 | MMU.amo_uint32(RS1, [&](uint32_t lhs) { return have_reservation ? RS2 : lhs; }); 5 | MMU.yield_load_reservation(); 6 | 7 | WRITE_RD(!have_reservation); 8 | -------------------------------------------------------------------------------- /riscv/insns/sd.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | MMU.store_uint64(RS1 + insn.s_imm(), RS2); 3 | -------------------------------------------------------------------------------- /riscv/insns/sfence_vma.h: -------------------------------------------------------------------------------- 1 | require_privilege(get_field(STATE.mstatus, MSTATUS_TVM) ? PRV_M : PRV_S); 2 | MMU.flush_tlb(); 3 | // this is a simplified implementation ignoring rs1 and rs2 4 | // See privileged spec 4.2.1: 5 | // Supervisor Memory-Management Fence Instruction 6 | MMU.flush_hard_tlb_d(); 7 | MMU.flush_hard_tlb_i(); 8 | -------------------------------------------------------------------------------- /riscv/insns/sh.h: -------------------------------------------------------------------------------- 1 | MMU.store_uint16(RS1 + insn.s_imm(), RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/sll.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(RS1 << (RS2 & (xlen-1)))); 2 | -------------------------------------------------------------------------------- /riscv/insns/slli.h: -------------------------------------------------------------------------------- 1 | require(SHAMT < xlen); 2 | WRITE_RD(sext_xlen(RS1 << SHAMT)); 3 | -------------------------------------------------------------------------------- /riscv/insns/slliw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(RS1 << SHAMT)); 3 | -------------------------------------------------------------------------------- /riscv/insns/sllw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(RS1 << (RS2 & 0x1F))); 3 | -------------------------------------------------------------------------------- /riscv/insns/slt.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sreg_t(RS1) < sreg_t(RS2)); 2 | -------------------------------------------------------------------------------- /riscv/insns/slti.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sreg_t(RS1) < sreg_t(insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/sltiu.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(RS1 < reg_t(insn.i_imm())); 2 | -------------------------------------------------------------------------------- /riscv/insns/sltu.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(RS1 < RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/sra.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(sext_xlen(RS1) >> (RS2 & (xlen-1)))); 2 | -------------------------------------------------------------------------------- /riscv/insns/srai.h: -------------------------------------------------------------------------------- 1 | require(SHAMT < xlen); 2 | WRITE_RD(sext_xlen(sext_xlen(RS1) >> SHAMT)); 3 | -------------------------------------------------------------------------------- /riscv/insns/sraiw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(int32_t(RS1) >> SHAMT)); 3 | -------------------------------------------------------------------------------- /riscv/insns/sraw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(int32_t(RS1) >> (RS2 & 0x1F))); 3 | -------------------------------------------------------------------------------- /riscv/insns/sret.h: -------------------------------------------------------------------------------- 1 | require_privilege(get_field(STATE.mstatus, MSTATUS_TSR) ? PRV_M : PRV_S); 2 | set_pc_and_serialize(p->get_state()->sepc); 3 | reg_t s = STATE.mstatus; 4 | reg_t prev_prv = get_field(s, MSTATUS_SPP); 5 | s = set_field(s, MSTATUS_SIE, get_field(s, MSTATUS_SPIE)); 6 | s = set_field(s, MSTATUS_SPIE, 1); 7 | s = set_field(s, MSTATUS_SPP, PRV_U); 8 | p->set_privilege(prev_prv); 9 | p->set_csr(CSR_MSTATUS, s); 10 | -------------------------------------------------------------------------------- /riscv/insns/srl.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(zext_xlen(RS1) >> (RS2 & (xlen-1)))); 2 | -------------------------------------------------------------------------------- /riscv/insns/srli.h: -------------------------------------------------------------------------------- 1 | require(SHAMT < xlen); 2 | WRITE_RD(sext_xlen(zext_xlen(RS1) >> SHAMT)); 3 | -------------------------------------------------------------------------------- /riscv/insns/srliw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32((uint32_t)RS1 >> SHAMT)); 3 | -------------------------------------------------------------------------------- /riscv/insns/srlw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32((uint32_t)RS1 >> (RS2 & 0x1F))); 3 | -------------------------------------------------------------------------------- /riscv/insns/sub.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(sext_xlen(RS1 - RS2)); 2 | -------------------------------------------------------------------------------- /riscv/insns/subw.h: -------------------------------------------------------------------------------- 1 | require_rv64; 2 | WRITE_RD(sext32(RS1 - RS2)); 3 | 4 | -------------------------------------------------------------------------------- /riscv/insns/sw.h: -------------------------------------------------------------------------------- 1 | MMU.store_uint32(RS1 + insn.s_imm(), RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/vaadd_vi.h: -------------------------------------------------------------------------------- 1 | // vaadd: Averaging adds of integers 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VI_LOOP 4 | ({ 5 | int64_t result = simm5 + vs2; 6 | INT_ROUNDING(result, xrm, 1); 7 | result = vzext(result >> 1, sew); 8 | vd = result; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vaadd_vv.h: -------------------------------------------------------------------------------- 1 | // vaadd.vv vd, vs2, vs1 2 | VI_VVX_LOOP_AVG(vs1, +); 3 | -------------------------------------------------------------------------------- /riscv/insns/vaadd_vx.h: -------------------------------------------------------------------------------- 1 | // vaadd.vx vd, vs2, rs1 2 | VI_VVX_LOOP_AVG(rs1, +); 3 | -------------------------------------------------------------------------------- /riscv/insns/vadc_vim.h: -------------------------------------------------------------------------------- 1 | // vadc.vim vd, vs2, simm5 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VI_LOOP 4 | ({ 5 | auto &v0 = P.VU.elt(0, midx); 6 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 7 | uint64_t carry = (v0 >> mpos) & 0x1; 8 | 9 | uint128_t res = (op_mask & simm5) + (op_mask & vs2) + carry; 10 | vd = res; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vadc_vvm.h: -------------------------------------------------------------------------------- 1 | // vadc.vvm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VV_LOOP 4 | ({ 5 | auto &v0 = P.VU.elt(0, midx); 6 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 7 | uint64_t carry = (v0 >> mpos) & 0x1; 8 | 9 | uint128_t res = (op_mask & vs1) + (op_mask & vs2) + carry; 10 | vd = res; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vadc_vxm.h: -------------------------------------------------------------------------------- 1 | // vadc.vxm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VX_LOOP 4 | ({ 5 | auto &v0 = P.VU.elt(0, midx); 6 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 7 | uint64_t carry = (v0 >> mpos) & 0x1; 8 | 9 | uint128_t res = (op_mask & rs1) + (op_mask & vs2) + carry; 10 | vd = res; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vadd_vi.h: -------------------------------------------------------------------------------- 1 | // vadd.vi vd, simm5, vs2, vm 2 | VI_VI_LOOP 3 | ({ 4 | vd = simm5 + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vadd_vv.h: -------------------------------------------------------------------------------- 1 | // vadd.vv vd, vs1, vs2, vm 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs1 + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vadd_vx.h: -------------------------------------------------------------------------------- 1 | // vadd.vx vd, rs1, vs2, vm 2 | VI_VX_LOOP 3 | ({ 4 | vd = rs1 + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vand_vi.h: -------------------------------------------------------------------------------- 1 | // vand.vi vd, simm5, vs2, vm 2 | VI_VI_LOOP 3 | ({ 4 | vd = simm5 & vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vand_vv.h: -------------------------------------------------------------------------------- 1 | // vand.vv vd, vs1, vs2, vm 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs1 & vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vand_vx.h: -------------------------------------------------------------------------------- 1 | // vand.vx vd, rs1, vs2, vm 2 | VI_VX_LOOP 3 | ({ 4 | vd = rs1 & vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vasub_vv.h: -------------------------------------------------------------------------------- 1 | // vasub.vv vd, vs2, vs1 2 | VI_VVX_LOOP_AVG(vs1, -); 3 | -------------------------------------------------------------------------------- /riscv/insns/vasub_vx.h: -------------------------------------------------------------------------------- 1 | // vasub.vx vd, vs2, rs1 2 | VI_VVX_LOOP_AVG(rs1, -); 3 | -------------------------------------------------------------------------------- /riscv/insns/vdiv_vv.h: -------------------------------------------------------------------------------- 1 | // vdiv.vv vd, vs2, vs1 2 | VI_VV_LOOP 3 | ({ 4 | if (vs1 == 0) 5 | vd = -1; 6 | else if (vs2 == -(1 << (sew - 1)) && vs1 == -1) 7 | vd = vs2; 8 | else 9 | vd = vs2 / vs1; 10 | }) 11 | -------------------------------------------------------------------------------- /riscv/insns/vdiv_vx.h: -------------------------------------------------------------------------------- 1 | // vdiv.vx vd, vs2, rs1 2 | VI_VX_LOOP 3 | ({ 4 | if(rs1 == 0) 5 | vd = -1; 6 | else if(vs2 == -(1 << (sew - 1)) && rs1 == -1) 7 | vd = vs2; 8 | else 9 | vd = vs2 / rs1; 10 | }) 11 | -------------------------------------------------------------------------------- /riscv/insns/vdivu_vv.h: -------------------------------------------------------------------------------- 1 | // vdivu.vv vd, vs2, vs1 2 | VI_VV_ULOOP 3 | ({ 4 | if(vs1 == 0) 5 | vd = -1; 6 | else 7 | vd = vs2 / vs1; 8 | }) 9 | -------------------------------------------------------------------------------- /riscv/insns/vdivu_vx.h: -------------------------------------------------------------------------------- 1 | // vdivu.vx vd, vs2, rs1 2 | VI_VX_ULOOP 3 | ({ 4 | if(rs1 == 0) 5 | vd = -1; 6 | else 7 | vd = vs2 / rs1; 8 | }) 9 | -------------------------------------------------------------------------------- /riscv/insns/vdot_vv.h: -------------------------------------------------------------------------------- 1 | // vdot vd, vs2, vs1 2 | VI_VV_LOOP 3 | ({ 4 | vd += vs2 * vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vdotu_vv.h: -------------------------------------------------------------------------------- 1 | // vdotu vd, vs2, vs1 2 | VI_VV_ULOOP 3 | ({ 4 | vd += vs2 * vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vext_x_v.h: -------------------------------------------------------------------------------- 1 | // vext_x_v: rd = vs2[rs1] 2 | require(insn.v_vm() == 1); 3 | uint64_t xmask = UINT64_MAX >> (64 - P.get_max_xlen()); 4 | reg_t rs1 = RS1; 5 | VI_LOOP_BASE 6 | VI_LOOP_END_NO_TAIL_ZERO 7 | if (!(rs1 >= 0 && rs1 < (P.VU.get_vlen()/sew))) { 8 | WRITE_RD(0); 9 | } else { 10 | switch(sew) { 11 | case e8: 12 | WRITE_RD(P.VU.elt(rs2_num, rs1)); 13 | break; 14 | case e16: 15 | WRITE_RD(P.VU.elt(rs2_num, rs1)); 16 | break; 17 | case e32: 18 | if (P.get_max_xlen() == 32) 19 | WRITE_RD(P.VU.elt(rs2_num, rs1)); 20 | else 21 | WRITE_RD(P.VU.elt(rs2_num, rs1)); 22 | break; 23 | case e64: 24 | if (P.get_max_xlen() <= sew) 25 | WRITE_RD(P.VU.elt(rs2_num, rs1) & xmask); 26 | else 27 | WRITE_RD(P.VU.elt(rs2_num, rs1)); 28 | break; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /riscv/insns/vfadd_vf.h: -------------------------------------------------------------------------------- 1 | // vfadd.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_add(rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfadd_vv.h: -------------------------------------------------------------------------------- 1 | // vfadd.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_add(vs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfclass_v.h: -------------------------------------------------------------------------------- 1 | // vfclass.v vd, vs2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd.v = f32_classify(vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfcvt_f_x_v.h: -------------------------------------------------------------------------------- 1 | // vfcvt.f.x.v vd, vd2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | auto vs2_i = P.VU.elt(rs2_num, i); 5 | vd = i32_to_f32(vs2_i); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vfcvt_f_xu_v.h: -------------------------------------------------------------------------------- 1 | // vfcvt.f.xu.v vd, vd2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | auto vs2_u = P.VU.elt(rs2_num, i); 5 | vd = ui32_to_f32(vs2_u); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vfcvt_x_f_v.h: -------------------------------------------------------------------------------- 1 | // vfcvt.x.f.v vd, vd2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | P.VU.elt(rd_num, i) = f32_to_i32(vs2, STATE.frm, true); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfcvt_xu_f_v.h: -------------------------------------------------------------------------------- 1 | // vfcvt.xu.f.v vd, vd2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | P.VU.elt(rd_num, i) = f32_to_ui32(vs2, STATE.frm, true); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfdiv_vf.h: -------------------------------------------------------------------------------- 1 | // vfdiv.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_div(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfdiv_vv.h: -------------------------------------------------------------------------------- 1 | // vfdiv.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_div(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfdot_vv.h: -------------------------------------------------------------------------------- 1 | // vfdot.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_add(vd, f32_mul(vs2, vs1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfirst_m.h: -------------------------------------------------------------------------------- 1 | // vmfirst rd, vs2 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs2_num = insn.rs2(); 8 | require(P.VU.vstart == 0); 9 | reg_t pos = -1; 10 | for (reg_t i=P.VU.vstart; i < vl; ++i) { 11 | VI_LOOP_ELEMENT_SKIP() 12 | 13 | bool vs2_lsb = ((P.VU.elt(rs2_num, midx ) >> mpos) & 0x1) == 1; 14 | if (vs2_lsb) { 15 | pos = i; 16 | break; 17 | } 18 | } 19 | P.VU.vstart = 0; 20 | WRITE_RD(pos); 21 | -------------------------------------------------------------------------------- /riscv/insns/vfmacc_vf.h: -------------------------------------------------------------------------------- 1 | // vfmacc.vf vd, rs1, vs2, vm # vd[i] = +(vs2[i] * x[rs1]) + vd[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(rs1, vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vfmacc.vv vd, rs1, vs2, vm # vd[i] = +(vs2[i] * vs1[i]) + vd[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(vs1, vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmadd_vf.h: -------------------------------------------------------------------------------- 1 | // vfmadd: vd[i] = +(vd[i] * f[rs1]) + vs2[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(vd, rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmadd_vv.h: -------------------------------------------------------------------------------- 1 | // vfmadd: vd[i] = +(vd[i] * vs1[i]) + vs2[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(vd, vs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmax_vf.h: -------------------------------------------------------------------------------- 1 | // vfmax 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_max(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmax_vv.h: -------------------------------------------------------------------------------- 1 | // vfmax 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_max(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmerge_vfm.h: -------------------------------------------------------------------------------- 1 | // vfmerge_vf vd, vs2, vs1, vm 2 | require_extension('F'); 3 | require_fp; 4 | require(P.VU.vsew == 32); 5 | require(!P.VU.vill); 6 | reg_t vl = P.VU.vl; 7 | reg_t sew = P.VU.vsew; 8 | reg_t rd_num = insn.rd(); 9 | reg_t rs1_num = insn.rs1(); 10 | reg_t rs2_num = insn.rs2(); 11 | for (reg_t i=P.VU.vstart; i(rd_num, i); 13 | auto rs1 = f32(READ_FREG(rs1_num)); 14 | auto vs2 = P.VU.elt(rs2_num, i); 15 | 16 | int midx = (P.VU.vmlen * i) / 64; 17 | int mpos = (P.VU.vmlen * i) % 64; 18 | bool use_first = (P.VU.elt(0, midx) >> mpos) & 0x1; 19 | 20 | vd = use_first ? rs1 : vs2; 21 | } 22 | 23 | VI_TAIL_ZERO(1); 24 | P.VU.vstart = 0; 25 | set_fp_exceptions; 26 | -------------------------------------------------------------------------------- /riscv/insns/vfmin_vf.h: -------------------------------------------------------------------------------- 1 | // vfmin vd, vs2, rs1 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_min(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmin_vv.h: -------------------------------------------------------------------------------- 1 | // vfmin vd, vs2, vs1 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_min(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmsac_vf.h: -------------------------------------------------------------------------------- 1 | // vfmsac: vd[i] = +(f[rs1] * vs2[i]) - vd[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(rs1, vs2, f32(vd.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmsac_vv.h: -------------------------------------------------------------------------------- 1 | // vfmsac: vd[i] = +(vs1[i] * vs2[i]) - vd[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(vs1, vs2, f32(vd.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmsub_vf.h: -------------------------------------------------------------------------------- 1 | // vfmsub: vd[i] = +(vd[i] * f[rs1]) - vs2[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(vd, rs1, f32(vs2.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmsub_vv.h: -------------------------------------------------------------------------------- 1 | // vfmsub: vd[i] = +(vd[i] * vs1[i]) - vs2[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(vd, vs1, f32(vs2.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmul_vf.h: -------------------------------------------------------------------------------- 1 | // vfmul.vf vd, vs2, rs1, vm 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mul(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmul_vv.h: -------------------------------------------------------------------------------- 1 | // vfmul.vv vd, vs1, vs2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mul(vs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfmv_f_s.h: -------------------------------------------------------------------------------- 1 | // vfmv_f_s: rd = vs2[0] (rs1=0) 2 | require(insn.v_vm() == 1); 3 | require_fp; 4 | require(P.VU.vsew == e8 || P.VU.vsew == e16 || P.VU.vsew == e32 || P.VU.vsew == e64); 5 | 6 | reg_t rs2_num = insn.rs2(); 7 | uint64_t vs2_0 = 0; 8 | const reg_t sew = P.VU.vsew; 9 | switch(sew) { 10 | case e8: 11 | vs2_0 = P.VU.elt(rs2_num, 0); 12 | break; 13 | case e16: 14 | vs2_0 = P.VU.elt(rs2_num, 0); 15 | break; 16 | case e32: 17 | vs2_0 = P.VU.elt(rs2_num, 0); 18 | break; 19 | default: 20 | vs2_0 = P.VU.elt(rs2_num, 0); 21 | break; 22 | } 23 | 24 | // nan_extened 25 | if (FLEN > sew) { 26 | vs2_0 = vs2_0 | ~((1ul << sew) - 1); 27 | } 28 | 29 | if (FLEN == 64) { 30 | WRITE_FRD(f64(vs2_0)); 31 | } else { 32 | WRITE_FRD(f32(vs2_0)); 33 | } 34 | -------------------------------------------------------------------------------- /riscv/insns/vfmv_s_f.h: -------------------------------------------------------------------------------- 1 | // vfmv_s_f: vd[0] = rs1 (vs2=0) 2 | require(insn.v_vm() == 1); 3 | require_fp; 4 | require(P.VU.vsew == e32); 5 | reg_t vl = P.VU.vl; 6 | 7 | if (vl > 0) { 8 | reg_t rd_num = insn.rd(); 9 | reg_t sew = P.VU.vsew; 10 | 11 | if (FLEN == 64) 12 | P.VU.elt(rd_num, 0) = f64(FRS1).v; 13 | else 14 | P.VU.elt(rd_num, 0) = f32(FRS1).v; 15 | 16 | const reg_t max_len = P.VU.VLEN / sew; 17 | for (reg_t i = 1; i < max_len; ++i) { 18 | switch(sew) { 19 | case e32: 20 | P.VU.elt(rd_num, i) = 0; 21 | break; 22 | default: 23 | require(false); 24 | break; 25 | } 26 | } 27 | 28 | vl = 0; 29 | } 30 | -------------------------------------------------------------------------------- /riscv/insns/vfmv_v_f.h: -------------------------------------------------------------------------------- 1 | // vfmerge_vf vd, vs2, vs1, vm 2 | require_extension('F'); 3 | require_fp; 4 | require(P.VU.vsew == 32); 5 | require(!P.VU.vill); 6 | reg_t vl = P.VU.vl; 7 | reg_t sew = P.VU.vsew; 8 | reg_t rd_num = insn.rd(); 9 | reg_t rs1_num = insn.rs1(); 10 | reg_t rs2_num = insn.rs2(); 11 | for (reg_t i=P.VU.vstart; i(rd_num, i); 13 | auto rs1 = f32(READ_FREG(rs1_num)); 14 | 15 | vd = rs1; 16 | } 17 | 18 | VI_TAIL_ZERO(1); 19 | P.VU.vstart = 0; 20 | set_fp_exceptions; 21 | -------------------------------------------------------------------------------- /riscv/insns/vfncvt_f_f_v.h: -------------------------------------------------------------------------------- 1 | // vfncvt.f.f.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_SD; 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = f64_to_f32(vs2); 6 | VI_VFP_LOOP_END 7 | -------------------------------------------------------------------------------- /riscv/insns/vfncvt_f_x_v.h: -------------------------------------------------------------------------------- 1 | // vfncvt.f.x.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_SD; 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = i64_to_f32(vs2); 6 | VI_VFP_LOOP_END 7 | -------------------------------------------------------------------------------- /riscv/insns/vfncvt_f_xu_v.h: -------------------------------------------------------------------------------- 1 | // vfncvt.f.xu.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_SD; 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = ui64_to_f32(vs2); 6 | VI_VFP_LOOP_END 7 | -------------------------------------------------------------------------------- /riscv/insns/vfncvt_x_f_v.h: -------------------------------------------------------------------------------- 1 | // vfncvt.x.f.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_SD; 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = f64_to_i32(vs2, STATE.frm, true); 6 | VI_VFP_LOOP_END 7 | -------------------------------------------------------------------------------- /riscv/insns/vfncvt_xu_f_v.h: -------------------------------------------------------------------------------- 1 | // vfncvt.xu.f.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_SD; 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = f64_to_ui32(vs2, STATE.frm, true); 6 | VI_VFP_LOOP_END 7 | -------------------------------------------------------------------------------- /riscv/insns/vfnmacc_vf.h: -------------------------------------------------------------------------------- 1 | // vfnmacc: vd[i] = -(f[rs1] * vs2[i]) - vd[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(rs1, f32(vs2.v ^ F32_SIGN), f32(vd.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vfnmacc: vd[i] = -(vs1[i] * vs2[i]) - vd[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(f32(vs2.v ^ F32_SIGN), vs1, f32(vd.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmadd_vf.h: -------------------------------------------------------------------------------- 1 | // vfnmadd: vd[i] = -(vd[i] * f[rs1]) - vs2[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(f32(vd.v ^ F32_SIGN), rs1, f32(vs2.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmadd_vv.h: -------------------------------------------------------------------------------- 1 | // vfnmadd: vd[i] = -(vd[i] * vs1[i]) - vs2[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(f32(vd.v ^ F32_SIGN), vs1, f32(vs2.v ^ F32_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmsac_vf.h: -------------------------------------------------------------------------------- 1 | // vfnmsac: vd[i] = -(f[rs1] * vs2[i]) + vd[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(rs1, f32(vs2.v ^ F32_SIGN), vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmsac_vv.h: -------------------------------------------------------------------------------- 1 | // vfnmsac.vv vd, vs1, vs2, vm # vd[i] = -(vs2[i] * vs1[i]) + vd[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(f32(vs1.v ^ F32_SIGN), vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmsub_vf.h: -------------------------------------------------------------------------------- 1 | // vfnmsub: vd[i] = -(vd[i] * f[rs1]) + vs2[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_mulAdd(f32(vd.v ^ F32_SIGN), rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfnmsub_vv.h: -------------------------------------------------------------------------------- 1 | // vfnmsub: vd[i] = -(vd[i] * vs1[i]) + vs2[i] 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_mulAdd(f32(vd.v ^ F32_SIGN), vs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfrdiv_vf.h: -------------------------------------------------------------------------------- 1 | // vfrdiv.vf vd, vs2, rs1, vm # scalar-vector, vd[i] = f[rs1]/vs2[i] 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_div(rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfredmax_vs.h: -------------------------------------------------------------------------------- 1 | // vfredmax vd, vs2, vs1 2 | VI_VFP_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0 = f32_max(vd_0, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfredmin_vs.h: -------------------------------------------------------------------------------- 1 | // vfredmin vd, vs2, vs1 2 | VI_VFP_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0 = f32_min(vd_0, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfredosum_vs.h: -------------------------------------------------------------------------------- 1 | // vfredosum: vd[0] = sum( vs2[*] , vs1[0] ) 2 | VI_VFP_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0 = f32_add(vd_0, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfredsum_vs.h: -------------------------------------------------------------------------------- 1 | // vfredsum: vd[0] = sum( vs2[*] , vs1[0] ) 2 | VI_VFP_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0 = f32_add(vd_0, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfrsub_vf.h: -------------------------------------------------------------------------------- 1 | // vfsub.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_sub(rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsgnj_vf.h: -------------------------------------------------------------------------------- 1 | // vfsgnj vd, vs2, vs1 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = fsgnj32(rs1.v, vs2.v, false, false); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsgnj_vv.h: -------------------------------------------------------------------------------- 1 | // vfsgnj 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = fsgnj32(vs1.v, vs2.v, false, false); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsgnjn_vf.h: -------------------------------------------------------------------------------- 1 | // vfsgnn 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = fsgnj32(rs1.v, vs2.v, true, false); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsgnjn_vv.h: -------------------------------------------------------------------------------- 1 | // vfsgnn 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = fsgnj32(vs1.v, vs2.v, true, false); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsgnjx_vf.h: -------------------------------------------------------------------------------- 1 | // vfsgnx 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = fsgnj32(rs1.v, vs2.v, false, true); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsgnjx_vv.h: -------------------------------------------------------------------------------- 1 | // vfsgnx 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = fsgnj32(vs1.v, vs2.v, false, true); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsqrt_v.h: -------------------------------------------------------------------------------- 1 | // vsqrt.v vd, vd2, vm 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_sqrt(vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsub_vf.h: -------------------------------------------------------------------------------- 1 | // vfsub.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP 3 | ({ 4 | vd = f32_sub(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfsub_vv.h: -------------------------------------------------------------------------------- 1 | // vfsub.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP 3 | ({ 4 | vd = f32_sub(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwadd_vf.h: -------------------------------------------------------------------------------- 1 | // vfwadd.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_add(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwadd_vv.h: -------------------------------------------------------------------------------- 1 | // vfwadd.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_add(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwadd_wf.h: -------------------------------------------------------------------------------- 1 | // vfwadd.wf vd, vs2, vs1 2 | VI_VFP_WF_LOOP_WIDE 3 | ({ 4 | vd = f64_add(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwadd_wv.h: -------------------------------------------------------------------------------- 1 | // vfwadd.wv vd, vs2, vs1 2 | VI_VFP_WV_LOOP_WIDE 3 | ({ 4 | vd = f64_add(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwcvt_f_f_v.h: -------------------------------------------------------------------------------- 1 | // vfwcvt.f.f.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_DSS(false); 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = f32_to_f64(vs2); 6 | set_fp_exceptions; 7 | VI_VFP_LOOP_WIDE_END 8 | -------------------------------------------------------------------------------- /riscv/insns/vfwcvt_f_x_v.h: -------------------------------------------------------------------------------- 1 | // vfwcvt.f.x.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_DSS(false); 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = i32_to_f64(vs2); 6 | set_fp_exceptions; 7 | VI_VFP_LOOP_WIDE_END 8 | -------------------------------------------------------------------------------- /riscv/insns/vfwcvt_f_xu_v.h: -------------------------------------------------------------------------------- 1 | // vfwcvt.f.xu.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_DSS(false); 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = ui32_to_f64(vs2); 6 | set_fp_exceptions; 7 | VI_VFP_LOOP_WIDE_END 8 | -------------------------------------------------------------------------------- /riscv/insns/vfwcvt_x_f_v.h: -------------------------------------------------------------------------------- 1 | // vfwcvt.x.f.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_DSS(false); 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = f32_to_i64(vs2, STATE.frm, true); 6 | set_fp_exceptions; 7 | VI_VFP_LOOP_WIDE_END 8 | -------------------------------------------------------------------------------- /riscv/insns/vfwcvt_xu_f_v.h: -------------------------------------------------------------------------------- 1 | // vfwcvt.xu.f.v vd, vs2, vm 2 | VI_VFP_LOOP_BASE 3 | VI_CHECK_DSS(false); 4 | auto vs2 = P.VU.elt(rs2_num, i); 5 | P.VU.elt(rd_num, i) = f32_to_ui64(vs2, STATE.frm, true); 6 | set_fp_exceptions; 7 | VI_VFP_LOOP_WIDE_END 8 | -------------------------------------------------------------------------------- /riscv/insns/vfwmacc_vf.h: -------------------------------------------------------------------------------- 1 | // vfwmacc.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(rs1, vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vfwmacc.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(vs1, vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwmsac_vf.h: -------------------------------------------------------------------------------- 1 | // vfwmsac.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(rs1, vs2, f64(vd.v ^ F64_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwmsac_vv.h: -------------------------------------------------------------------------------- 1 | // vfwmsac.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(vs1, vs2, f64(vd.v ^ F64_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwmul_vf.h: -------------------------------------------------------------------------------- 1 | // vfwmul.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_mul(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwmul_vv.h: -------------------------------------------------------------------------------- 1 | // vfwmul.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_mul(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwnmacc_vf.h: -------------------------------------------------------------------------------- 1 | // vfwnmacc.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(f64(rs1.v ^ F64_SIGN), vs2, f64(vd.v ^ F64_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwnmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vfwnmacc.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(f64(vs1.v ^ F64_SIGN), vs2, f64(vd.v ^ F64_SIGN)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwnmsac_vf.h: -------------------------------------------------------------------------------- 1 | // vfwnmacc.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(f64(rs1.v ^ F64_SIGN), vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwnmsac_vv.h: -------------------------------------------------------------------------------- 1 | // vfwnmsac.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_mulAdd(f64(vs1.v ^ F64_SIGN), vs2, vd); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwredosum_vs.h: -------------------------------------------------------------------------------- 1 | // vfwredosum.vs vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE_REDUCTION 3 | ({ 4 | vd_0 = f64_add(vd_0, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwredsum_vs.h: -------------------------------------------------------------------------------- 1 | // vfwredsum.vs vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE_REDUCTION 3 | ({ 4 | vd_0 = f64_add(vd_0, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwsub_vf.h: -------------------------------------------------------------------------------- 1 | // vfwsub.vf vd, vs2, rs1 2 | VI_VFP_VF_LOOP_WIDE 3 | ({ 4 | vd = f64_sub(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwsub_vv.h: -------------------------------------------------------------------------------- 1 | // vfwsub.vv vd, vs2, vs1 2 | VI_VFP_VV_LOOP_WIDE 3 | ({ 4 | vd = f64_sub(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwsub_wf.h: -------------------------------------------------------------------------------- 1 | // vfwsub.wf vd, vs2, rs1 2 | VI_VFP_WF_LOOP_WIDE 3 | ({ 4 | vd = f64_sub(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vfwsub_wv.h: -------------------------------------------------------------------------------- 1 | // vfwsub.wv vd, vs2, vs1 2 | VI_VFP_WV_LOOP_WIDE 3 | ({ 4 | vd = f64_sub(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vid_v.h: -------------------------------------------------------------------------------- 1 | // vmpopc rd, vs2, vm 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs1_num = insn.rs1(); 8 | reg_t rs2_num = insn.rs2(); 9 | 10 | for (reg_t i = P.VU.vstart ; i < P.VU.vl; ++i) { 11 | VI_LOOP_ELEMENT_SKIP(); 12 | 13 | switch (sew) { 14 | case e8: 15 | P.VU.elt(rd_num, i) = i; 16 | break; 17 | case e16: 18 | P.VU.elt(rd_num, i) = i; 19 | break; 20 | case e32: 21 | P.VU.elt(rd_num, i) = i; 22 | break; 23 | default: 24 | P.VU.elt(rd_num, i) = i; 25 | break; 26 | } 27 | } 28 | 29 | VI_TAIL_ZERO(1); 30 | P.VU.vstart = 0; 31 | -------------------------------------------------------------------------------- /riscv/insns/vlb_v.h: -------------------------------------------------------------------------------- 1 | // vlb.v and vlseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_LD(0, i * nf + fn, int8, 1); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlbff_v.h: -------------------------------------------------------------------------------- 1 | // vlbff.v and vlseg[2-8]bff.v 2 | VI_LDST_FF(int, 8); 3 | -------------------------------------------------------------------------------- /riscv/insns/vlbu_v.h: -------------------------------------------------------------------------------- 1 | // vlbu.v and vlseg[2-8]bu.v 2 | require(P.VU.vsew >= e8); 3 | VI_LD(0, i * nf + fn, uint8, 1); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlbuff_v.h: -------------------------------------------------------------------------------- 1 | // vlbuff.v and vlseg[2-8]buff.v 2 | VI_LDST_FF(uint, 8); 3 | -------------------------------------------------------------------------------- /riscv/insns/vle_v.h: -------------------------------------------------------------------------------- 1 | // vle.v and vlseg[2-8]e.v 2 | reg_t sew = P.VU.vsew; 3 | 4 | if (sew == e8) { 5 | VI_LD(0, (i * nf + fn), int8, 1); 6 | } else if (sew == e16) { 7 | VI_LD(0, (i * nf + fn), int16, 2); 8 | } else if (sew == e32) { 9 | VI_LD(0, (i * nf + fn), int32, 4); 10 | } else if (sew == e64) { 11 | VI_LD(0, (i * nf + fn), int64, 8); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /riscv/insns/vlh_v.h: -------------------------------------------------------------------------------- 1 | // vlh.v and vlseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_LD(0, i * nf + fn, int16, 2); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlhff_v.h: -------------------------------------------------------------------------------- 1 | // vlh.v and vlseg[2-8]hff.v 2 | VI_LDST_FF(int, 16); 3 | -------------------------------------------------------------------------------- /riscv/insns/vlhu_v.h: -------------------------------------------------------------------------------- 1 | // vlhu.v and vlseg[2-8]hu.v 2 | require(P.VU.vsew >= e16); 3 | VI_LD(0, i * nf + fn, uint16, 2); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlhuff_v.h: -------------------------------------------------------------------------------- 1 | // vlhuff.v and vlseg[2-8]huff.v 2 | VI_LDST_FF(uint, 16); 3 | -------------------------------------------------------------------------------- /riscv/insns/vlsb_v.h: -------------------------------------------------------------------------------- 1 | // vlsb.v and vlsseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_LD(i * RS2, fn, int8, 1); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlsbu_v.h: -------------------------------------------------------------------------------- 1 | // vlsb.v and vlsseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_LD(i * RS2, fn, uint8, 1); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlse_v.h: -------------------------------------------------------------------------------- 1 | // vlse.v and vlsseg[2-8]e.v 2 | reg_t sew = P.VU.vsew; 3 | 4 | if (sew == e8) { 5 | VI_LD(i * RS2, fn, int8, 1); 6 | } else if (sew == e16) { 7 | VI_LD(i * RS2, fn, int16, 2); 8 | } else if (sew == e32) { 9 | VI_LD(i * RS2, fn, int32, 4); 10 | } else if (sew == e64) { 11 | VI_LD(i * RS2, fn, int64, 8); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /riscv/insns/vlsh_v.h: -------------------------------------------------------------------------------- 1 | // vlsh.v and vlsseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_LD(i * RS2, fn, int16, 2); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlshu_v.h: -------------------------------------------------------------------------------- 1 | // vlsh.v and vlsseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_LD(i * RS2, fn, uint16, 2); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlsw_v.h: -------------------------------------------------------------------------------- 1 | // vlsw.v and vlsseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_LD(i * RS2, fn, int32, 4); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlswu_v.h: -------------------------------------------------------------------------------- 1 | // vlsw.v and vlsseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_LD(i * RS2, fn, uint32, 4); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlw_v.h: -------------------------------------------------------------------------------- 1 | // vlw.v and vlseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_LD(0, i * nf + fn, int32, 4); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlwff_v.h: -------------------------------------------------------------------------------- 1 | // vlwff.v 2 | // vlw.v and vlseg[2-8]wff.v 3 | VI_LDST_FF(int, 32); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlwu_v.h: -------------------------------------------------------------------------------- 1 | // vlwu.v and vlseg[2-8]wu.v 2 | require(P.VU.vsew >= e32); 3 | VI_LD(0, i * nf + fn, uint32, 4); 4 | -------------------------------------------------------------------------------- /riscv/insns/vlwuff_v.h: -------------------------------------------------------------------------------- 1 | // vlwuff.v and vlseg[2-8]wuff.v 2 | VI_LDST_FF(uint, 32); 3 | -------------------------------------------------------------------------------- /riscv/insns/vlxb_v.h: -------------------------------------------------------------------------------- 1 | // vlxb.v and vlsseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_LD(index[i], fn, int8, 1); 5 | -------------------------------------------------------------------------------- /riscv/insns/vlxbu_v.h: -------------------------------------------------------------------------------- 1 | // vlxbu.v and vlxseg[2-8]bu.v 2 | require(P.VU.vsew >= e8); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_LD(index[i], fn, uint8, 1); 5 | -------------------------------------------------------------------------------- /riscv/insns/vlxe_v.h: -------------------------------------------------------------------------------- 1 | // vlxe.v and vlxseg[2-8]e.v 2 | reg_t sew = P.VU.vsew; 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | if (sew == e8) { 5 | VI_LD(index[i], fn, int8, 1); 6 | } else if (sew == e16) { 7 | VI_LD(index[i], fn, int16, 2); 8 | } else if (sew == e32) { 9 | VI_LD(index[i], fn, int32, 4); 10 | } else if (sew == e64) { 11 | VI_LD(index[i], fn, int64, 8); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /riscv/insns/vlxh_v.h: -------------------------------------------------------------------------------- 1 | // vlxh.v and vlxseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_LD(index[i], fn, int16, 2); 5 | -------------------------------------------------------------------------------- /riscv/insns/vlxhu_v.h: -------------------------------------------------------------------------------- 1 | // vlxh.v and vlxseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_LD(index[i], fn, uint16, 2); 5 | -------------------------------------------------------------------------------- /riscv/insns/vlxw_v.h: -------------------------------------------------------------------------------- 1 | // vlxw.v and vlxseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_LD(index[i], fn, int32, 4); 5 | 6 | -------------------------------------------------------------------------------- /riscv/insns/vlxwu_v.h: -------------------------------------------------------------------------------- 1 | // vlxwu.v and vlxseg[2-8]wu.v 2 | require(P.VU.vsew >= e32); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_LD(index[i], fn, uint32, 4); 5 | -------------------------------------------------------------------------------- /riscv/insns/vmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vmacc.vv: vd[i] = +(vs1[i] * vs2[i]) + vd[i] 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs1 * vs2 + vd; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmacc_vx.h: -------------------------------------------------------------------------------- 1 | // vmacc.vx: vd[i] = +(x[rs1] * vs2[i]) + vd[i] 2 | VI_VX_LOOP 3 | ({ 4 | vd = rs1 * vs2 + vd; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmadc_vim.h: -------------------------------------------------------------------------------- 1 | // vmadc.vim vd, vs2, simm5 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_XI_LOOP_CARRY 4 | ({ 5 | auto v0 = P.VU.elt(0, midx); 6 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 7 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 8 | uint64_t carry = (v0 >> mpos) & 0x1; 9 | 10 | uint128_t res = (op_mask & simm5) + (op_mask & vs2) + carry; 11 | 12 | carry = (res >> sew) & 0x1u; 13 | vd = (vd & ~mmask) | ((carry << mpos) & mmask); 14 | }) 15 | -------------------------------------------------------------------------------- /riscv/insns/vmadc_vvm.h: -------------------------------------------------------------------------------- 1 | // vmadc.vvm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VV_LOOP_CARRY 4 | ({ 5 | auto v0 = P.VU.elt(0, midx); 6 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 7 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 8 | uint64_t carry = (v0 >> mpos) & 0x1; 9 | 10 | uint128_t res = (op_mask & vs1) + (op_mask & vs2) + carry; 11 | 12 | carry = (res >> sew) & 0x1u; 13 | vd = (vd & ~mmask) | ((carry << mpos) & mmask); 14 | }) 15 | -------------------------------------------------------------------------------- /riscv/insns/vmadc_vxm.h: -------------------------------------------------------------------------------- 1 | // vadc.vx vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_XI_LOOP_CARRY 4 | ({ 5 | auto v0 = P.VU.elt(0, midx); 6 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 7 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 8 | uint64_t carry = (v0 >> mpos) & 0x1; 9 | 10 | uint128_t res = (op_mask & rs1) + (op_mask & vs2) + carry; 11 | 12 | carry = (res >> sew) & 0x1u; 13 | vd = (vd & ~mmask) | ((carry << mpos) & mmask); 14 | }) 15 | -------------------------------------------------------------------------------- /riscv/insns/vmadd_vv.h: -------------------------------------------------------------------------------- 1 | // vmadd: vd[i] = (vd[i] * vs1[i]) + vs2[i] 2 | VI_VV_LOOP 3 | ({ 4 | vd = vd * vs1 + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmadd_vx.h: -------------------------------------------------------------------------------- 1 | // vmadd: vd[i] = (vd[i] * x[rs1]) + vs2[i] 2 | VI_VX_LOOP 3 | ({ 4 | vd = vd * rs1 + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmand_mm.h: -------------------------------------------------------------------------------- 1 | // vmand.mm vd, vs2, vs1 2 | VI_LOOP_MASK(vs2 & vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmandnot_mm.h: -------------------------------------------------------------------------------- 1 | // vmandnot.mm vd, vs2, vs1 2 | VI_LOOP_MASK(vs2 & ~vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmax_vv.h: -------------------------------------------------------------------------------- 1 | // vmax.vv vd, vs2, vs1, vm # Vector-vector 2 | VI_VV_LOOP 3 | ({ 4 | if (vs1 >= vs2) { 5 | vd = vs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | 10 | }) 11 | -------------------------------------------------------------------------------- /riscv/insns/vmax_vx.h: -------------------------------------------------------------------------------- 1 | // vmax.vx vd, vs2, rs1, vm # vector-scalar 2 | VI_VX_LOOP 3 | ({ 4 | if (rs1 >= vs2) { 5 | vd = rs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | 10 | }) 11 | -------------------------------------------------------------------------------- /riscv/insns/vmaxu_vv.h: -------------------------------------------------------------------------------- 1 | // vmaxu.vv vd, vs2, vs1, vm # Vector-vector 2 | VI_VV_ULOOP 3 | ({ 4 | if (vs1 >= vs2) { 5 | vd = vs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vmaxu_vx.h: -------------------------------------------------------------------------------- 1 | // vmaxu.vx vd, vs2, rs1, vm # vector-scalar 2 | VI_VX_ULOOP 3 | ({ 4 | if (rs1 >= vs2) { 5 | vd = rs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vmerge_vim.h: -------------------------------------------------------------------------------- 1 | // vmerge.vim vd, vs2, simm5 2 | VI_VVXI_MERGE_LOOP 3 | ({ 4 | int midx = (P.VU.vmlen * i) / 64; 5 | int mpos = (P.VU.vmlen * i) % 64; 6 | bool use_first = (P.VU.elt(0, midx) >> mpos) & 0x1; 7 | 8 | vd = use_first ? simm5 : vs2; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vmerge_vvm.h: -------------------------------------------------------------------------------- 1 | // vmerge.vvm vd, vs2, vs1 2 | VI_VVXI_MERGE_LOOP 3 | ({ 4 | int midx = (P.VU.vmlen * i) / 64; 5 | int mpos = (P.VU.vmlen * i) % 64; 6 | bool use_first = (P.VU.elt(0, midx) >> mpos) & 0x1; 7 | 8 | vd = use_first ? vs1 : vs2; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vmerge_vxm.h: -------------------------------------------------------------------------------- 1 | // vmerge.vxm vd, vs2, rs1 2 | VI_VVXI_MERGE_LOOP 3 | ({ 4 | int midx = (P.VU.vmlen * i) / 64; 5 | int mpos = (P.VU.vmlen * i) % 64; 6 | bool use_first = (P.VU.elt(0, midx) >> mpos) & 0x1; 7 | 8 | vd = use_first ? rs1 : vs2; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vmfeq_vf.h: -------------------------------------------------------------------------------- 1 | // vfeq.vf vd, vs2, fs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_eq(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfeq_vv.h: -------------------------------------------------------------------------------- 1 | // vfeq.vv vd, vs2, vs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_eq(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfge_vf.h: -------------------------------------------------------------------------------- 1 | // vfge.vf vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_le_quiet(rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfgt_vf.h: -------------------------------------------------------------------------------- 1 | // vfgt.vf vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_lt_quiet(rs1, vs2); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfle_vf.h: -------------------------------------------------------------------------------- 1 | // vfle.vf vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_le(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfle_vv.h: -------------------------------------------------------------------------------- 1 | // vfle.vv vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_le_quiet(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmflt_vf.h: -------------------------------------------------------------------------------- 1 | // vflt.vf vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_lt_quiet(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmflt_vv.h: -------------------------------------------------------------------------------- 1 | // vflt.vv vd, vs2, vs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = f32_lt_quiet(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfne_vf.h: -------------------------------------------------------------------------------- 1 | // vfne.vf vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = !f32_eq(vs2, rs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmfne_vv.h: -------------------------------------------------------------------------------- 1 | // vfne.vv vd, vs2, rs1 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = !f32_eq(vs2, vs1); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmford_vf.h: -------------------------------------------------------------------------------- 1 | // vford.vf vd, vs2, rs1, vm 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = !(f32_isSignalingNaN(vs2) || f32_isSignalingNaN(rs1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmford_vv.h: -------------------------------------------------------------------------------- 1 | // vford.vv vd, vs2, vs1, vm 2 | VI_VFP_LOOP_CMP 3 | ({ 4 | res = !(f32_isSignalingNaN(vs2) || f32_isSignalingNaN(vs1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmin_vv.h: -------------------------------------------------------------------------------- 1 | // vmin.vv vd, vs2, vs1, vm # Vector-vector 2 | VI_VV_LOOP 3 | ({ 4 | if (vs1 <= vs2) { 5 | vd = vs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | 10 | 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vmin_vx.h: -------------------------------------------------------------------------------- 1 | // vminx.vx vd, vs2, rs1, vm # vector-scalar 2 | VI_VX_LOOP 3 | ({ 4 | if (rs1 <= vs2) { 5 | vd = rs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | 10 | 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vminu_vv.h: -------------------------------------------------------------------------------- 1 | // vminu.vv vd, vs2, vs1, vm # Vector-vector 2 | VI_VV_ULOOP 3 | ({ 4 | if (vs1 <= vs2) { 5 | vd = vs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vminu_vx.h: -------------------------------------------------------------------------------- 1 | // vminu.vx vd, vs2, rs1, vm # vector-scalar 2 | VI_VX_ULOOP 3 | ({ 4 | if (rs1 <= vs2) { 5 | vd = rs1; 6 | } else { 7 | vd = vs2; 8 | } 9 | 10 | }) 11 | -------------------------------------------------------------------------------- /riscv/insns/vmnand_mm.h: -------------------------------------------------------------------------------- 1 | // vmnand.mm vd, vs2, vs1 2 | VI_LOOP_MASK(~(vs2 & vs1)); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmnor_mm.h: -------------------------------------------------------------------------------- 1 | // vmnor.mm vd, vs2, vs1 2 | VI_LOOP_MASK(~(vs2 | vs1)); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmor_mm.h: -------------------------------------------------------------------------------- 1 | // vmor.mm vd, vs2, vs1 2 | VI_LOOP_MASK(vs2 | vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmornot_mm.h: -------------------------------------------------------------------------------- 1 | // vmornot.mm vd, vs2, vs1 2 | VI_LOOP_MASK(vs2 | ~vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmsbc_vvm.h: -------------------------------------------------------------------------------- 1 | // vmsbc.vvm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VV_LOOP_CARRY 4 | ({ 5 | auto v0 = P.VU.elt(0, midx); 6 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 7 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 8 | uint64_t carry = (v0 >> mpos) & 0x1; 9 | 10 | uint128_t res = (op_mask & vs1) - (op_mask & vs2) - carry; 11 | 12 | carry = (res >> sew) & 0x1u; 13 | vd = (vd & ~mmask) | ((carry << mpos) & mmask); 14 | }) 15 | -------------------------------------------------------------------------------- /riscv/insns/vmsbc_vxm.h: -------------------------------------------------------------------------------- 1 | // vmsbc.vxm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_XI_LOOP_CARRY 4 | ({ 5 | auto &v0 = P.VU.elt(0, midx); 6 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 7 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 8 | uint64_t carry = (v0 >> mpos) & 0x1; 9 | 10 | uint128_t res = (op_mask & rs1) - (op_mask & vs2) - carry; 11 | 12 | carry = (res >> sew) & 0x1u; 13 | vd = (vd & ~mmask) | ((carry << mpos) & mmask); 14 | }) 15 | -------------------------------------------------------------------------------- /riscv/insns/vmsbf_m.h: -------------------------------------------------------------------------------- 1 | // vmsbf.m vd, vs2, vm 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs1_num = insn.rs1(); 8 | reg_t rs2_num = insn.rs2(); 9 | 10 | bool has_one = false; 11 | for (reg_t i = P.VU.vstart; i < vl; ++i) { 12 | const int mlen = P.VU.vmlen; 13 | const int midx = (mlen * i) / 64; 14 | const int mpos = (mlen * i) % 64; 15 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 16 | 17 | bool vs2_lsb = ((P.VU.elt(rs2_num, midx) >> mpos) & 0x1) == 1; 18 | bool do_mask = (P.VU.elt(0, midx) >> mpos) & 0x1; 19 | auto &vd = P.VU.elt(rd_num, midx); 20 | 21 | 22 | if (insn.v_vm() == 1 || (insn.v_vm() == 0 && do_mask)) { 23 | uint64_t res = 0; 24 | if (!has_one && !vs2_lsb) { 25 | res = 1; 26 | } else if(!has_one && vs2_lsb) { 27 | has_one = true; 28 | } 29 | vd = (vd & ~mmask) | ((res << mpos) & mmask); 30 | } 31 | } 32 | 33 | VI_TAIL_ZERO_MASK(rd_num); 34 | P.VU.vstart = 0; 35 | -------------------------------------------------------------------------------- /riscv/insns/vmseq_vi.h: -------------------------------------------------------------------------------- 1 | // vseq.vi vd, vs2, simm5 2 | VI_VI_LOOP_CMP 3 | ({ 4 | res = simm5 == vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmseq_vv.h: -------------------------------------------------------------------------------- 1 | // vseq.vv vd, vs2, vs1 2 | VI_VV_LOOP_CMP 3 | ({ 4 | res = vs2 == vs1; 5 | }) 6 | 7 | -------------------------------------------------------------------------------- /riscv/insns/vmseq_vx.h: -------------------------------------------------------------------------------- 1 | // vseq.vx vd, vs2, rs1 2 | VI_VX_LOOP_CMP 3 | ({ 4 | res = rs1 == vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsgt_vi.h: -------------------------------------------------------------------------------- 1 | // vsgt.vi vd, vs2, simm5 2 | VI_VI_LOOP_CMP 3 | ({ 4 | res = vs2 > simm5; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsgt_vx.h: -------------------------------------------------------------------------------- 1 | // vsgt.vx vd, vs2, rs1 2 | VI_VX_LOOP_CMP 3 | ({ 4 | res = vs2 > rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsgtu_vi.h: -------------------------------------------------------------------------------- 1 | // vsgtu.vi vd, vd2, zimm5 2 | VI_VI_ULOOP_CMP 3 | ({ 4 | res = vs2 > simm5; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsgtu_vx.h: -------------------------------------------------------------------------------- 1 | // vsgtu.vx vd, vs2, rs1 2 | VI_VX_ULOOP_CMP 3 | ({ 4 | res = vs2 > rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsif_m.h: -------------------------------------------------------------------------------- 1 | // vmpopc rd, vs2, vm 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs1_num = insn.rs1(); 8 | reg_t rs2_num = insn.rs2(); 9 | 10 | bool has_one = false; 11 | for (reg_t i = P.VU.vstart ; i < vl; ++i) { 12 | const int mlen = P.VU.vmlen; 13 | const int midx = (mlen * i) / 64; 14 | const int mpos = (mlen * i) % 64; 15 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 16 | 17 | bool vs2_lsb = ((P.VU.elt(rs2_num, midx ) >> mpos) & 0x1) == 1; 18 | bool do_mask = (P.VU.elt(0, midx) >> mpos) & 0x1; 19 | auto &vd = P.VU.elt(rd_num, midx); 20 | 21 | if (insn.v_vm() == 1 || (insn.v_vm() == 0 && do_mask)) { 22 | uint64_t res = 0; 23 | if (!has_one && !vs2_lsb) { 24 | res = 1; 25 | } else if(!has_one && vs2_lsb) { 26 | has_one = true; 27 | res = 1; 28 | } 29 | vd = (vd & ~mmask) | ((res << mpos) & mmask); 30 | } 31 | } 32 | 33 | VI_TAIL_ZERO_MASK(rd_num); 34 | P.VU.vstart = 0; 35 | -------------------------------------------------------------------------------- /riscv/insns/vmsle_vi.h: -------------------------------------------------------------------------------- 1 | // vsle.vi vd, vs2, simm5 2 | VI_VI_LOOP_CMP 3 | ({ 4 | res = vs2 <= simm5; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsle_vv.h: -------------------------------------------------------------------------------- 1 | // vsle.vv vd, vs2, vs1 2 | VI_VV_LOOP_CMP 3 | ({ 4 | res = vs2 <= vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsle_vx.h: -------------------------------------------------------------------------------- 1 | // vsle.vx vd, vs2, rs1 2 | VI_VX_LOOP_CMP 3 | ({ 4 | res = vs2 <= rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsleu_vi.h: -------------------------------------------------------------------------------- 1 | // vsleu.vi vd, vs2, zimm5 2 | VI_VI_ULOOP_CMP 3 | ({ 4 | res = vs2 <= simm5; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsleu_vv.h: -------------------------------------------------------------------------------- 1 | // vsleu.vv vd, vs2, vs1 2 | VI_VV_ULOOP_CMP 3 | ({ 4 | res = vs2 <= vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsleu_vx.h: -------------------------------------------------------------------------------- 1 | // vsleu.vx vd, vs2, rs1 2 | VI_VX_ULOOP_CMP 3 | ({ 4 | res = vs2 <= rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmslt_vv.h: -------------------------------------------------------------------------------- 1 | // vslt.vv vd, vd2, vs1 2 | VI_VV_LOOP_CMP 3 | ({ 4 | res = vs2 < vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmslt_vx.h: -------------------------------------------------------------------------------- 1 | // vslt.vx vd, vs2, vs1 2 | VI_VX_LOOP_CMP 3 | ({ 4 | res = vs2 < rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsltu_vv.h: -------------------------------------------------------------------------------- 1 | // vsltu.vv vd, vs2, vs1 2 | VI_VV_ULOOP_CMP 3 | ({ 4 | res = vs2 < vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsltu_vx.h: -------------------------------------------------------------------------------- 1 | // vsltu.vx vd, vs2, vs1 2 | VI_VX_ULOOP_CMP 3 | ({ 4 | res = vs2 < rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsne_vi.h: -------------------------------------------------------------------------------- 1 | // vsne.vi vd, vs2, simm5 2 | VI_VI_LOOP_CMP 3 | ({ 4 | res = vs2 != simm5; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsne_vv.h: -------------------------------------------------------------------------------- 1 | // vneq.vv vd, vs2, vs1 2 | VI_VV_LOOP_CMP 3 | ({ 4 | res = vs2 != vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsne_vx.h: -------------------------------------------------------------------------------- 1 | // vsne.vx vd, vs2, rs1 2 | VI_VX_LOOP_CMP 3 | ({ 4 | res = vs2 != rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmsof_m.h: -------------------------------------------------------------------------------- 1 | // vmsof.m rd, vs2, vm 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs1_num = insn.rs1(); 8 | reg_t rs2_num = insn.rs2(); 9 | 10 | bool has_one = false; 11 | for (reg_t i = P.VU.vstart ; i < vl; ++i) { 12 | const int mlen = P.VU.vmlen; 13 | const int midx = (mlen * i) / 64; 14 | const int mpos = (mlen * i) % 64; 15 | const uint64_t mmask = (UINT64_MAX << (64 - mlen)) >> (64 - mlen - mpos); 16 | 17 | bool vs2_lsb = ((P.VU.elt(rs2_num, midx ) >> mpos) & 0x1) == 1; 18 | bool do_mask = (P.VU.elt(0, midx) >> mpos) & 0x1; 19 | uint64_t &vd = P.VU.elt(rd_num, midx); 20 | 21 | if (insn.v_vm() == 1 || (insn.v_vm() == 0 && do_mask)) { 22 | uint64_t res = 0; 23 | if(!has_one && vs2_lsb) { 24 | has_one = true; 25 | res = 1; 26 | } 27 | vd = (vd & ~mmask) | ((res << mpos) & mmask); 28 | } 29 | } 30 | 31 | VI_TAIL_ZERO_MASK(rd_num); 32 | P.VU.vstart = 0; 33 | -------------------------------------------------------------------------------- /riscv/insns/vmul_vv.h: -------------------------------------------------------------------------------- 1 | // vmul vd, vs2, vs1 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs2 * vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmul_vx.h: -------------------------------------------------------------------------------- 1 | // vmul vd, vs2, rs1 2 | VI_VX_LOOP 3 | ({ 4 | vd = vs2 * rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmulh_vv.h: -------------------------------------------------------------------------------- 1 | // vmulh vd, vs2, vs1 2 | VI_VV_LOOP 3 | ({ 4 | vd = ((int128_t)vs2 * vs1) >> sew; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmulh_vx.h: -------------------------------------------------------------------------------- 1 | // vmulh vd, vs2, rs1 2 | VI_VX_LOOP 3 | ({ 4 | vd = ((int128_t)vs2 * rs1) >> sew; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmulhsu_vv.h: -------------------------------------------------------------------------------- 1 | // vmulhsu.vv vd, vs2, vs1 2 | VI_LOOP_BASE 3 | switch(sew) { 4 | case e8: { 5 | auto &vd = P.VU.elt(rd_num, i); 6 | auto vs2 = P.VU.elt(rs2_num, i); 7 | auto vs1 = P.VU.elt(rs1_num, i); 8 | 9 | vd = ((int16_t)vs2 * (uint16_t)vs1) >> sew; 10 | break; 11 | } 12 | case e16: { 13 | auto &vd = P.VU.elt(rd_num, i); 14 | auto vs2 = P.VU.elt(rs2_num, i); 15 | auto vs1 = P.VU.elt(rs1_num, i); 16 | 17 | vd = ((int32_t)vs2 * (uint32_t)vs1) >> sew; 18 | break; 19 | } 20 | case e32: { 21 | auto &vd = P.VU.elt(rd_num, i); 22 | auto vs2 = P.VU.elt(rs2_num, i); 23 | auto vs1 = P.VU.elt(rs1_num, i); 24 | 25 | vd = ((int64_t)vs2 * (uint64_t)vs1) >> sew; 26 | break; 27 | } 28 | default: { 29 | auto &vd = P.VU.elt(rd_num, i); 30 | auto vs2 = P.VU.elt(rs2_num, i); 31 | auto vs1 = P.VU.elt(rs1_num, i); 32 | 33 | vd = ((int128_t)vs2 * (uint128_t)vs1) >> sew; 34 | break; 35 | } 36 | } 37 | VI_LOOP_END 38 | -------------------------------------------------------------------------------- /riscv/insns/vmulhsu_vx.h: -------------------------------------------------------------------------------- 1 | // vmulhsu.vx vd, vs2, rs1 2 | VI_LOOP_BASE 3 | switch(sew) { 4 | case e8: { 5 | auto &vd = P.VU.elt(rd_num, i); 6 | auto vs2 = P.VU.elt(rs2_num, i); 7 | uint8_t rs1 = RS1; 8 | 9 | vd = ((int16_t)vs2 * (uint16_t)rs1) >> sew; 10 | break; 11 | } 12 | case e16: { 13 | auto &vd = P.VU.elt(rd_num, i); 14 | auto vs2 = P.VU.elt(rs2_num, i); 15 | uint16_t rs1 = RS1; 16 | 17 | vd = ((int32_t)vs2 * (uint32_t)rs1) >> sew; 18 | break; 19 | } 20 | case e32: { 21 | auto &vd = P.VU.elt(rd_num, i); 22 | auto vs2 = P.VU.elt(rs2_num, i); 23 | uint32_t rs1 = RS1; 24 | 25 | vd = ((int64_t)vs2 * (uint64_t)rs1) >> sew; 26 | break; 27 | } 28 | default: { 29 | auto &vd = P.VU.elt(rd_num, i); 30 | auto vs2 = P.VU.elt(rs2_num, i); 31 | uint64_t rs1 = RS1; 32 | 33 | vd = ((int128_t)vs2 * (uint128_t)rs1) >> sew; 34 | break; 35 | } 36 | } 37 | VI_LOOP_END 38 | -------------------------------------------------------------------------------- /riscv/insns/vmulhu_vv.h: -------------------------------------------------------------------------------- 1 | // vmulhu vd ,vs2, vs1 2 | VI_VV_ULOOP 3 | ({ 4 | vd = ((uint128_t)vs2 * vs1) >> sew; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmulhu_vx.h: -------------------------------------------------------------------------------- 1 | // vmulhu vd ,vs2, rs1 2 | VI_VX_ULOOP 3 | ({ 4 | vd = ((uint128_t)vs2 * rs1) >> sew; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmv_s_x.h: -------------------------------------------------------------------------------- 1 | // vmv_s_x: vd[0] = rs1 2 | require(insn.v_vm() == 1); 3 | require(P.VU.vsew == e8 || P.VU.vsew == e16 || 4 | P.VU.vsew == e32 || P.VU.vsew == e64); 5 | reg_t vl = P.VU.vl; 6 | 7 | if (vl > 0) { 8 | reg_t rd_num = insn.rd(); 9 | reg_t sew = P.VU.vsew; 10 | 11 | switch(sew) { 12 | case e8: 13 | P.VU.elt(rd_num, 0) = RS1; 14 | break; 15 | case e16: 16 | P.VU.elt(rd_num, 0) = RS1; 17 | break; 18 | case e32: 19 | P.VU.elt(rd_num, 0) = RS1; 20 | break; 21 | default: 22 | P.VU.elt(rd_num, 0) = RS1; 23 | break; 24 | } 25 | 26 | const reg_t max_len = P.VU.VLEN / sew; 27 | for (reg_t i = 1; i < max_len; ++i) { 28 | switch(sew) { 29 | case e8: 30 | P.VU.elt(rd_num, i) = 0; 31 | break; 32 | case e16: 33 | P.VU.elt(rd_num, i) = 0; 34 | break; 35 | case e32: 36 | P.VU.elt(rd_num, i) = 0; 37 | break; 38 | default: 39 | P.VU.elt(rd_num, i) = 0; 40 | break; 41 | } 42 | } 43 | 44 | vl = 0; 45 | } 46 | -------------------------------------------------------------------------------- /riscv/insns/vmv_v_i.h: -------------------------------------------------------------------------------- 1 | // vmv.v.i vd, simm5 2 | VI_VVXI_MERGE_LOOP 3 | ({ 4 | vd = simm5; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmv_v_v.h: -------------------------------------------------------------------------------- 1 | // vvmv.v.v vd, vs1 2 | VI_VVXI_MERGE_LOOP 3 | ({ 4 | vd = vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmv_v_x.h: -------------------------------------------------------------------------------- 1 | // vmv.v.x vd, rs1 2 | VI_VVXI_MERGE_LOOP 3 | ({ 4 | vd = rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vmxnor_mm.h: -------------------------------------------------------------------------------- 1 | // vmnxor.mm vd, vs2, vs1 2 | VI_LOOP_MASK(~(vs2 ^ vs1)); 3 | -------------------------------------------------------------------------------- /riscv/insns/vmxor_mm.h: -------------------------------------------------------------------------------- 1 | // vmxor.mm vd, vs2, vs1 2 | VI_LOOP_MASK(vs2 ^ vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vnclip_vi.h: -------------------------------------------------------------------------------- 1 | // vnclip: vd[i] = clip(round(vs2[i] + rnd) >> simm) 2 | VRM xrm = P.VU.get_vround_mode(); 3 | int64_t int_max = (1 << (P.VU.vsew - 1)) - 1; 4 | int64_t int_min = -(1 << (P.VU.vsew - 1)); 5 | VI_VVXI_LOOP_NARROW 6 | ({ 7 | 8 | int64_t result = vs2; 9 | // rounding 10 | INT_ROUNDING(result, xrm, sew); 11 | 12 | result = vsext(result, sew * 2) >> (zimm5 & ((sew * 2) < 32? (sew * 2) - 1: 31)); 13 | 14 | // saturation 15 | if (result < int_min) { 16 | result = int_min; 17 | P.VU.vxsat = 1; 18 | } else if (result > int_max) { 19 | result = int_max; 20 | P.VU.vxsat = 1; 21 | } 22 | 23 | vd = result; 24 | }) 25 | -------------------------------------------------------------------------------- /riscv/insns/vnclip_vv.h: -------------------------------------------------------------------------------- 1 | // vnclip: vd[i] = clip(round(vs2[i] + rnd) >> vs1[i]) 2 | VRM xrm = P.VU.get_vround_mode(); 3 | int64_t int_max = (1 << (P.VU.vsew - 1)) - 1; 4 | int64_t int_min = -(1 << (P.VU.vsew - 1)); 5 | VI_VVXI_LOOP_NARROW 6 | ({ 7 | 8 | int64_t result = vs2; 9 | // rounding 10 | INT_ROUNDING(result, xrm, sew); 11 | 12 | // unsigned shifting to rs1 13 | uint64_t unsigned_shift_amount = (uint64_t)(vs1 & ((sew * 2) - 1)); 14 | if (unsigned_shift_amount >= (2 * sew)) { 15 | unsigned_shift_amount = 2 * sew - 1; 16 | } 17 | 18 | result = (vsext(result, sew * 2)) >> unsigned_shift_amount; 19 | 20 | // saturation 21 | if (result < int_min) { 22 | result = int_min; 23 | P.VU.vxsat = 1; 24 | } else if (result > int_max) { 25 | result = int_max; 26 | P.VU.vxsat = 1; 27 | } 28 | 29 | vd = result; 30 | }) 31 | -------------------------------------------------------------------------------- /riscv/insns/vnclip_vx.h: -------------------------------------------------------------------------------- 1 | // vnclip: vd[i] = clip(round(vs2[i] + rnd) >> rs1[i]) 2 | VRM xrm = P.VU.get_vround_mode(); 3 | int64_t int_max = (1 << (P.VU.vsew - 1)) - 1; 4 | int64_t int_min = -(1 << (P.VU.vsew - 1)); 5 | VI_VVXI_LOOP_NARROW 6 | ({ 7 | 8 | int64_t result = vs2; 9 | // rounding 10 | INT_ROUNDING(result, xrm, sew); 11 | 12 | // unsigned shifting to rs1 13 | uint64_t unsigned_shift_amount = (uint64_t)(rs1 & ((sew * 2) - 1)); 14 | if (unsigned_shift_amount >= (2 * sew)) { 15 | unsigned_shift_amount = 2 * sew - 1; 16 | } 17 | result = vsext(result, sew * 2) >> unsigned_shift_amount; 18 | 19 | // saturation 20 | if (result < int_min) { 21 | result = int_min; 22 | P.VU.vxsat = 1; 23 | } else if (result > int_max) { 24 | result = int_max; 25 | P.VU.vxsat = 1; 26 | } 27 | 28 | vd = result; 29 | }) 30 | -------------------------------------------------------------------------------- /riscv/insns/vnclipu_vi.h: -------------------------------------------------------------------------------- 1 | // vnclipu: vd[i] = clip(round(vs2[i] + rnd) >> simm) 2 | VRM xrm = P.VU.get_vround_mode(); 3 | uint64_t int_max = ~(-1ll << P.VU.vsew); 4 | VI_VVXI_LOOP_NARROW 5 | ({ 6 | uint64_t result = vs2_u; 7 | // rounding 8 | INT_ROUNDING(result, xrm, sew); 9 | 10 | // unsigned shifting to rs1 11 | result = vzext(result, sew * 2) >> (zimm5 & ((sew * 2) < 32? (sew * 2) - 1: 31)); 12 | 13 | // saturation 14 | if (result & (uint64_t)(-1ll << sew)) { 15 | result = int_max; 16 | P.VU.vxsat = 1; 17 | } 18 | 19 | vd = result; 20 | }) 21 | -------------------------------------------------------------------------------- /riscv/insns/vnclipu_vv.h: -------------------------------------------------------------------------------- 1 | // vnclipu: vd[i] = clip(round(vs2[i] + rnd) >> vs1[i]) 2 | VRM xrm = P.VU.get_vround_mode(); 3 | uint64_t int_max = ~(-1ll << P.VU.vsew); 4 | VI_VVXI_LOOP_NARROW 5 | ({ 6 | 7 | uint64_t result = vs2_u; 8 | 9 | // rounding 10 | INT_ROUNDING(result, xrm, sew); 11 | 12 | // unsigned shifting to rs1 13 | uint64_t unsigned_shift_amount = (uint64_t)(vs1 & ((sew * 2) - 1)); 14 | if (unsigned_shift_amount >= (2 * sew)) { 15 | result = 0; 16 | } else { 17 | result = vzext(result, sew * 2) >> unsigned_shift_amount; 18 | } 19 | // saturation 20 | if (result & (uint64_t)(-1ll << sew)) { 21 | result = int_max; 22 | P.VU.vxsat = 1; 23 | } 24 | 25 | vd = result; 26 | }) 27 | -------------------------------------------------------------------------------- /riscv/insns/vnclipu_vx.h: -------------------------------------------------------------------------------- 1 | // vnclipu: vd[i] = clip(round(vs2[i] + rnd) >> rs1[i]) 2 | VRM xrm = P.VU.get_vround_mode(); 3 | uint64_t int_max = ~(-1ll << P.VU.vsew); 4 | VI_VVXI_LOOP_NARROW 5 | ({ 6 | uint64_t result = vs2; 7 | 8 | // rounding 9 | INT_ROUNDING(result, xrm, sew); 10 | 11 | // unsigned shifting to rs1 12 | uint64_t unsigned_shift_amount = (uint64_t)(rs1 & ((sew * 2) - 1)); 13 | if (unsigned_shift_amount >= (2 * sew)) { 14 | result = 0; 15 | } else { 16 | result = vzext(result, sew * 2) >> unsigned_shift_amount; 17 | } 18 | 19 | // saturation 20 | if (result & (uint64_t)(-1ll << sew)) { 21 | result = int_max; 22 | P.VU.vxsat = 1; 23 | } 24 | 25 | vd = result; 26 | }) 27 | -------------------------------------------------------------------------------- /riscv/insns/vnmsac_vv.h: -------------------------------------------------------------------------------- 1 | // vmsac.vv: vd[i] = -(vs1[i] * vs2[i]) + vd[i] 2 | VI_VV_LOOP 3 | ({ 4 | vd = -(vs1 * vs2) + vd; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnmsac_vx.h: -------------------------------------------------------------------------------- 1 | // vmsac: vd[i] = -(x[rs1] * vs2[i]) + vd[i] 2 | VI_VX_LOOP 3 | ({ 4 | vd = -(rs1 * vs2) + vd; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnmsub_vv.h: -------------------------------------------------------------------------------- 1 | // vnmsub.vv: vd[i] = -(vd[i] * vs1[i]) + vs2[i] 2 | VI_VV_LOOP 3 | ({ 4 | vd = -(vd * vs1) + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnmsub_vx.h: -------------------------------------------------------------------------------- 1 | // vnmsub.vx: vd[i] = -(vd[i] * x[rs1]) + vs2[i] 2 | VI_VX_LOOP 3 | ({ 4 | vd = -(vd * rs1) + vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnsra_vi.h: -------------------------------------------------------------------------------- 1 | // vnsra.vi vd, vs2, zimm5 2 | VI_VI_LOOP_NSHIFT 3 | ({ 4 | vd = vs2 >> (zimm5 & (sew * 2 - 1) & 0x1f); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnsra_vv.h: -------------------------------------------------------------------------------- 1 | // vnsra.vv vd, vs2, vs1 2 | VI_VV_LOOP_NSHIFT 3 | ({ 4 | vd = vs2 >> (vs1 & (sew * 2 - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnsra_vx.h: -------------------------------------------------------------------------------- 1 | // vnsra.vx vd, vs2, rs1 2 | VI_VX_LOOP_NSHIFT 3 | ({ 4 | vd = vs2 >> (rs1 & (sew * 2 - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnsrl_vi.h: -------------------------------------------------------------------------------- 1 | // vnsrl.vi vd, vs2, zimm5 2 | VI_VI_LOOP_NSHIFT 3 | ({ 4 | vd = vs2_u >> (zimm5 & (sew * 2 - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnsrl_vv.h: -------------------------------------------------------------------------------- 1 | // vnsrl.vv vd, vs2, vs1 2 | VI_VV_LOOP_NSHIFT 3 | ({ 4 | vd = vs2_u >> (vs1 & (sew * 2 - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vnsrl_vx.h: -------------------------------------------------------------------------------- 1 | // vnsrl.vx vd, vs2, rs1 2 | VI_VX_LOOP_NSHIFT 3 | ({ 4 | vd = vs2_u >> (rs1 & (sew * 2 - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vor_vi.h: -------------------------------------------------------------------------------- 1 | // vor 2 | VI_VI_LOOP 3 | ({ 4 | vd = simm5 | vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vor_vv.h: -------------------------------------------------------------------------------- 1 | // vor 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs1 | vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vor_vx.h: -------------------------------------------------------------------------------- 1 | // vor 2 | VI_VX_LOOP 3 | ({ 4 | vd = rs1 | vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vpopc_m.h: -------------------------------------------------------------------------------- 1 | // vmpopc rd, vs2, vm 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs2_num = insn.rs2(); 8 | require(P.VU.vstart == 0); 9 | reg_t popcount = 0; 10 | for (reg_t i=P.VU.vstart; i(rs2_num, midx ) >> mpos) & 0x1) == 1; 16 | if (insn.v_vm() == 1) { 17 | popcount += vs2_lsb; 18 | } else { 19 | bool do_mask = (P.VU.elt(0, midx) >> mpos) & 0x1; 20 | popcount += (vs2_lsb && do_mask); 21 | } 22 | } 23 | P.VU.vstart = 0; 24 | WRITE_RD(popcount); 25 | -------------------------------------------------------------------------------- /riscv/insns/vredand_vs.h: -------------------------------------------------------------------------------- 1 | // vredand.vs vd, vs2 ,vs1 2 | VI_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0_res &= vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredmax_vs.h: -------------------------------------------------------------------------------- 1 | // vredmax.vs vd, vs2 ,vs1 2 | VI_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0_res = (vd_0_res >= vs2) ? vd_0_res : vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredmaxu_vs.h: -------------------------------------------------------------------------------- 1 | // vredmaxu.vs vd, vs2 ,vs1 2 | VI_VV_ULOOP_REDUCTION 3 | ({ 4 | vd_0_res = (vd_0_res >= vs2) ? vd_0_res : vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredmin_vs.h: -------------------------------------------------------------------------------- 1 | // vredmin.vs vd, vs2 ,vs1 2 | VI_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0_res = (vd_0_res <= vs2) ? vd_0_res : vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredminu_vs.h: -------------------------------------------------------------------------------- 1 | // vredminu.vs vd, vs2 ,vs1 2 | VI_VV_ULOOP_REDUCTION 3 | ({ 4 | vd_0_res = (vd_0_res <= vs2) ? vd_0_res : vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredor_vs.h: -------------------------------------------------------------------------------- 1 | // vredor.vs vd, vs2 ,vs1 2 | VI_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0_res |= vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredsum_vs.h: -------------------------------------------------------------------------------- 1 | // vredsum.vs vd, vs2 ,vs1 2 | VI_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0_res += vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vredxor_vs.h: -------------------------------------------------------------------------------- 1 | // vredxor.vs vd, vs2 ,vs1 2 | VI_VV_LOOP_REDUCTION 3 | ({ 4 | vd_0_res ^= vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vrem_vv.h: -------------------------------------------------------------------------------- 1 | // vrem.vv vd, vs2, vs1 2 | VI_VV_LOOP 3 | ({ 4 | if (vs1 == 0) 5 | vd = vs2; 6 | else if(vs2 == -(1 << (sew - 1)) && vs1 == -1) 7 | vd = 0; 8 | else { 9 | vd = vs2 % vs1; 10 | } 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vrem_vx.h: -------------------------------------------------------------------------------- 1 | // vrem.vx vd, vs2, rs1 2 | VI_VX_LOOP 3 | ({ 4 | if (rs1 == 0) 5 | vd = vs2; 6 | else if (vs2 == -(1 << (sew - 1)) && rs1 == -1) 7 | vd = 0; 8 | else 9 | vd = vs2 % rs1; 10 | }) 11 | -------------------------------------------------------------------------------- /riscv/insns/vremu_vv.h: -------------------------------------------------------------------------------- 1 | // vremu.vv vd, vs2, vs1 2 | VI_VV_ULOOP 3 | ({ 4 | if (vs1 == 0) 5 | vd = vs2; 6 | else 7 | vd = vs2 % vs1; 8 | }) 9 | -------------------------------------------------------------------------------- /riscv/insns/vremu_vx.h: -------------------------------------------------------------------------------- 1 | // vremu.vx vd, vs2, rs1 2 | VI_VX_ULOOP 3 | ({ 4 | if (rs1 == 0) 5 | vd = vs2; 6 | else 7 | vd = vs2 % rs1; 8 | }) 9 | -------------------------------------------------------------------------------- /riscv/insns/vrgather_vi.h: -------------------------------------------------------------------------------- 1 | // vrgather.vi vd, vs2, zimm5 vm # vd[i] = (zimm5 >= VLMAX) ? 0 : vs2[zimm5]; 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs2_num = insn.rs2(); 8 | reg_t zimm5 = insn.v_zimm5(); 9 | for (reg_t i = P.VU.vstart; i < vl; ++i) { 10 | VI_LOOP_ELEMENT_SKIP(); 11 | 12 | switch (sew) { 13 | case e8: 14 | P.VU.elt(rd_num, i) = zimm5 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, zimm5); 15 | break; 16 | case e16: 17 | P.VU.elt(rd_num, i) = zimm5 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, zimm5); 18 | break; 19 | case e32: 20 | P.VU.elt(rd_num, i) = zimm5 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, zimm5); 21 | break; 22 | default: 23 | P.VU.elt(rd_num, i) = zimm5 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, zimm5); 24 | break; 25 | } 26 | } 27 | 28 | VI_TAIL_ZERO(1); 29 | P.VU.vstart = 0; 30 | -------------------------------------------------------------------------------- /riscv/insns/vrgather_vx.h: -------------------------------------------------------------------------------- 1 | // vrgather.vx vd, vs2, rs1, vm # vd[i] = (rs1 >= VLMAX) ? 0 : vs2[rs1]; 2 | require(P.VU.vsew >= e8 && P.VU.vsew <= e64); 3 | require(!P.VU.vill); 4 | reg_t vl = P.VU.vl; 5 | reg_t sew = P.VU.vsew; 6 | reg_t rd_num = insn.rd(); 7 | reg_t rs1_num = insn.rs1(); 8 | reg_t rs2_num = insn.rs2(); 9 | reg_t rs1 = RS1; 10 | for (reg_t i = P.VU.vstart; i < vl; ++i) { 11 | VI_LOOP_ELEMENT_SKIP(); 12 | 13 | switch (sew) { 14 | case e8: 15 | P.VU.elt(rd_num, i) = rs1 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, rs1); 16 | break; 17 | case e16: 18 | P.VU.elt(rd_num, i) = rs1 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, rs1); 19 | break; 20 | case e32: 21 | P.VU.elt(rd_num, i) = rs1 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, rs1); 22 | break; 23 | default: 24 | P.VU.elt(rd_num, i) = rs1 >= P.VU.vlmax ? 0 : P.VU.elt(rs2_num, rs1); 25 | break; 26 | } 27 | } 28 | 29 | VI_TAIL_ZERO(1); 30 | P.VU.vstart = 0; 31 | -------------------------------------------------------------------------------- /riscv/insns/vrsub_vi.h: -------------------------------------------------------------------------------- 1 | // vrsub.vi vd, vs2, imm, vm # vd[i] = imm - vs2[i] 2 | VI_VI_LOOP 3 | ({ 4 | vd = simm5 - vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vrsub_vx.h: -------------------------------------------------------------------------------- 1 | // vrsub.vx vd, vs2, rs1, vm # vd[i] = rs1 - vs2[i] 2 | VI_VX_LOOP 3 | ({ 4 | vd = rs1 - vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsadd_vi.h: -------------------------------------------------------------------------------- 1 | // vsadd.vi vd, vs2 simm5 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | switch(sew) { 5 | case e8: { 6 | VI_PARAMS(e8); 7 | vd = sat_add(vs2, vsext(simm5, sew), sat); 8 | break; 9 | } 10 | case e16: { 11 | VI_PARAMS(e16); 12 | vd = sat_add(vs2, vsext(simm5, sew), sat); 13 | break; 14 | } 15 | case e32: { 16 | VI_PARAMS(e32); 17 | vd = sat_add(vs2, vsext(simm5, sew), sat); 18 | break; 19 | } 20 | default: { 21 | VI_PARAMS(e64); 22 | vd = sat_add(vs2, vsext(simm5, sew), sat); 23 | break; 24 | } 25 | } 26 | P.VU.vxsat |= sat; 27 | VI_LOOP_END 28 | -------------------------------------------------------------------------------- /riscv/insns/vsadd_vv.h: -------------------------------------------------------------------------------- 1 | // vsadd.vv vd, vs2, vs1 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | switch(sew) { 5 | case e8: { 6 | VV_PARAMS(e8); 7 | vd = sat_add(vs2, vs1, sat); 8 | break; 9 | } 10 | case e16: { 11 | VV_PARAMS(e16); 12 | vd = sat_add(vs2, vs1, sat); 13 | break; 14 | } 15 | case e32: { 16 | VV_PARAMS(e32); 17 | vd = sat_add(vs2, vs1, sat); 18 | break; 19 | } 20 | default: { 21 | VV_PARAMS(e64); 22 | vd = sat_add(vs2, vs1, sat); 23 | break; 24 | } 25 | } 26 | P.VU.vxsat |= sat; 27 | VI_LOOP_END 28 | 29 | -------------------------------------------------------------------------------- /riscv/insns/vsadd_vx.h: -------------------------------------------------------------------------------- 1 | // vsadd.vx vd, vs2, rs1 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | switch(sew) { 5 | case e8: { 6 | VX_PARAMS(e8); 7 | vd = sat_add(vs2, rs1, sat); 8 | break; 9 | } 10 | case e16: { 11 | VX_PARAMS(e16); 12 | vd = sat_add(vs2, rs1, sat); 13 | break; 14 | } 15 | case e32: { 16 | VX_PARAMS(e32); 17 | vd = sat_add(vs2, rs1, sat); 18 | break; 19 | } 20 | default: { 21 | VX_PARAMS(e64); 22 | vd = sat_add(vs2, rs1, sat); 23 | break; 24 | } 25 | } 26 | P.VU.vxsat |= sat; 27 | VI_LOOP_END 28 | -------------------------------------------------------------------------------- /riscv/insns/vsaddu_vi.h: -------------------------------------------------------------------------------- 1 | // vsaddu vd, vs2, zimm5 2 | VI_VI_ULOOP 3 | ({ 4 | bool sat = false; 5 | vd = vs2 + simm5; 6 | 7 | sat = vd < vs2; 8 | vd |= -(vd < vs2); 9 | 10 | P.VU.vxsat |= sat; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vsaddu_vv.h: -------------------------------------------------------------------------------- 1 | // vsaddu vd, vs2, vs1 2 | VI_VV_ULOOP 3 | ({ 4 | bool sat = false; 5 | vd = vs2 + vs1; 6 | 7 | sat = vd < vs2; 8 | vd |= -(vd < vs2); 9 | 10 | P.VU.vxsat |= sat; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vsaddu_vx.h: -------------------------------------------------------------------------------- 1 | // vsaddu vd, vs2, rs1 2 | VI_VX_ULOOP 3 | ({ 4 | bool sat = false; 5 | vd = vs2 + rs1; 6 | 7 | sat = vd < vs2; 8 | vd |= -(vd < vs2); 9 | 10 | P.VU.vxsat |= sat; 11 | 12 | }) 13 | -------------------------------------------------------------------------------- /riscv/insns/vsb_v.h: -------------------------------------------------------------------------------- 1 | // vsb.v and vsseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_ST(0, i * nf + fn, uint8, 1); 4 | -------------------------------------------------------------------------------- /riscv/insns/vsbc_vvm.h: -------------------------------------------------------------------------------- 1 | // vsbc.vvm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VV_LOOP 4 | ({ 5 | auto &v0 = P.VU.elt(0, midx); 6 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 7 | uint64_t carry = (v0 >> mpos) & 0x1; 8 | 9 | uint128_t res = (op_mask & vs1) - (op_mask & vs2) - carry; 10 | vd = res; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vsbc_vxm.h: -------------------------------------------------------------------------------- 1 | // vsbc.vxm vd, vs2, rs1 2 | require(!(insn.rd() == 0 && P.VU.vlmul > 1)); 3 | VI_VX_ULOOP 4 | ({ 5 | auto &v0 = P.VU.elt(0, midx); 6 | const uint128_t op_mask = (UINT64_MAX >> (64 - sew)); 7 | uint64_t carry = (v0 >> mpos) & 0x1; 8 | 9 | uint128_t res = (op_mask & rs1) - (op_mask & vs2) - carry; 10 | vd = res; 11 | }) 12 | -------------------------------------------------------------------------------- /riscv/insns/vse_v.h: -------------------------------------------------------------------------------- 1 | // vsw.v and vsseg[2-8]w.v 2 | reg_t sew = P.VU.vsew; 3 | 4 | if (sew == e8) { 5 | VI_ST(0, (i * nf + fn), uint8, 1); 6 | } else if (sew == e16) { 7 | VI_ST(0, (i * nf + fn), uint16, 2); 8 | } else if (sew == e32) { 9 | VI_ST(0, (i * nf + fn), uint32, 4); 10 | } else if (sew == e64) { 11 | VI_ST(0, (i * nf + fn), uint64, 8); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /riscv/insns/vsetvl.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(P.VU.set_vl(insn.rs1(), RS1, RS2)); 2 | -------------------------------------------------------------------------------- /riscv/insns/vsetvli.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(P.VU.set_vl(insn.rs1(), RS1, insn.v_zimm11())); 2 | -------------------------------------------------------------------------------- /riscv/insns/vsh_v.h: -------------------------------------------------------------------------------- 1 | // vsh.v and vsseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_ST(0, i * nf + fn, uint16, 2); 4 | -------------------------------------------------------------------------------- /riscv/insns/vslide1down_vx.h: -------------------------------------------------------------------------------- 1 | //vslide1down.vx vd, vs2, rs1 2 | VI_LOOP_BASE 3 | if (i != vl - 1) { 4 | switch (sew) { 5 | case e8: { 6 | VI_XI_SLIDEDOWN_PARAMS(e8, 1); 7 | vd = vs2; 8 | } 9 | break; 10 | case e16: { 11 | VI_XI_SLIDEDOWN_PARAMS(e16, 1); 12 | vd = vs2; 13 | } 14 | break; 15 | case e32: { 16 | VI_XI_SLIDEDOWN_PARAMS(e32, 1); 17 | vd = vs2; 18 | } 19 | break; 20 | default: { 21 | VI_XI_SLIDEDOWN_PARAMS(e64, 1); 22 | vd = vs2; 23 | } 24 | break; 25 | } 26 | } else { 27 | switch (sew) { 28 | case e8: 29 | P.VU.elt(rd_num, vl - 1) = RS1; 30 | break; 31 | case e16: 32 | P.VU.elt(rd_num, vl - 1) = RS1; 33 | break; 34 | case e32: 35 | P.VU.elt(rd_num, vl - 1) = RS1; 36 | break; 37 | default: 38 | P.VU.elt(rd_num, vl - 1) = RS1; 39 | break; 40 | } 41 | } 42 | VI_LOOP_END 43 | -------------------------------------------------------------------------------- /riscv/insns/vslide1up_vx.h: -------------------------------------------------------------------------------- 1 | //vslide1up.vx vd, vs2, rs1 2 | if (insn.v_vm() == 0) 3 | require(insn.rd() != 0); 4 | 5 | VI_CHECK_SS 6 | VI_LOOP_BASE 7 | if (i != 0) { 8 | if (sew == e8) { 9 | VI_XI_SLIDEUP_PARAMS(e8, 1); 10 | vd = vs2; 11 | } else if(sew == e16) { 12 | VI_XI_SLIDEUP_PARAMS(e16, 1); 13 | vd = vs2; 14 | } else if(sew == e32) { 15 | VI_XI_SLIDEUP_PARAMS(e32, 1); 16 | vd = vs2; 17 | } else if(sew == e64) { 18 | VI_XI_SLIDEUP_PARAMS(e64, 1); 19 | vd = vs2; 20 | } 21 | } else { 22 | if (sew == e8) { 23 | P.VU.elt(rd_num, 0) = RS1; 24 | } else if(sew == e16) { 25 | P.VU.elt(rd_num, 0) = RS1; 26 | } else if(sew == e32) { 27 | P.VU.elt(rd_num, 0) = RS1; 28 | } else if(sew == e64) { 29 | P.VU.elt(rd_num, 0) = RS1; 30 | } 31 | } 32 | VI_LOOP_END 33 | -------------------------------------------------------------------------------- /riscv/insns/vslidedown_vi.h: -------------------------------------------------------------------------------- 1 | // vslidedown.vi vd, vs2, rs1 2 | VI_LOOP_BASE 3 | const reg_t sh = insn.v_zimm5(); 4 | bool is_valid = (i + sh) < P.VU.vlmax; 5 | reg_t offset = 0; 6 | 7 | if (is_valid) { 8 | offset = sh; 9 | } 10 | 11 | switch (sew) { 12 | case e8: { 13 | VI_XI_SLIDEDOWN_PARAMS(e8, offset); 14 | vd = is_valid ? vs2 : 0; 15 | } 16 | break; 17 | case e16: { 18 | VI_XI_SLIDEDOWN_PARAMS(e16, offset); 19 | vd = is_valid ? vs2 : 0; 20 | } 21 | break; 22 | case e32: { 23 | VI_XI_SLIDEDOWN_PARAMS(e32, offset); 24 | vd = is_valid ? vs2 : 0; 25 | } 26 | break; 27 | default: { 28 | VI_XI_SLIDEDOWN_PARAMS(e64, offset); 29 | vd = is_valid ? vs2 : 0; 30 | } 31 | break; 32 | } 33 | VI_LOOP_END 34 | -------------------------------------------------------------------------------- /riscv/insns/vslidedown_vx.h: -------------------------------------------------------------------------------- 1 | //vslidedown.vx vd, vs2, rs1 2 | VI_LOOP_BASE 3 | 4 | reg_t offset = RS1 == (reg_t)-1 ? ((RS1 & (P.VU.vlmax * 2 - 1)) + i) : RS1; 5 | bool is_valid = offset < P.VU.vlmax; 6 | 7 | if (!is_valid) { 8 | offset = 0; 9 | } 10 | 11 | switch (sew) { 12 | case e8: { 13 | VI_XI_SLIDEDOWN_PARAMS(e8, offset); 14 | vd = is_valid ? vs2 : 0; 15 | } 16 | break; 17 | case e16: { 18 | VI_XI_SLIDEDOWN_PARAMS(e16, offset); 19 | vd = is_valid ? vs2 : 0; 20 | } 21 | break; 22 | case e32: { 23 | VI_XI_SLIDEDOWN_PARAMS(e32, offset); 24 | vd = is_valid ? vs2 : 0; 25 | } 26 | break; 27 | default: { 28 | VI_XI_SLIDEDOWN_PARAMS(e64, offset); 29 | vd = is_valid ? vs2 : 0; 30 | } 31 | break; 32 | } 33 | VI_LOOP_END 34 | -------------------------------------------------------------------------------- /riscv/insns/vslideup_vi.h: -------------------------------------------------------------------------------- 1 | // vslideup.vi vd, vs2, rs1 2 | if (insn.v_vm() == 0) 3 | require(insn.rd() != 0); 4 | 5 | VI_CHECK_SS 6 | const reg_t offset = insn.v_zimm5(); 7 | VI_LOOP_BASE 8 | if (P.VU.vstart < offset && i < offset) 9 | continue; 10 | 11 | switch (sew) { 12 | case e8: { 13 | VI_XI_SLIDEUP_PARAMS(e8, offset); 14 | vd = vs2; 15 | } 16 | break; 17 | case e16: { 18 | VI_XI_SLIDEUP_PARAMS(e16, offset); 19 | vd = vs2; 20 | } 21 | break; 22 | case e32: { 23 | VI_XI_SLIDEUP_PARAMS(e32, offset); 24 | vd = vs2; 25 | } 26 | break; 27 | default: { 28 | VI_XI_SLIDEUP_PARAMS(e64, offset); 29 | vd = vs2; 30 | } 31 | break; 32 | } 33 | VI_LOOP_END 34 | -------------------------------------------------------------------------------- /riscv/insns/vslideup_vx.h: -------------------------------------------------------------------------------- 1 | //vslideup.vx vd, vs2, rs1 2 | const reg_t offset = RS1; 3 | VI_LOOP_BASE 4 | if (P.VU.vstart < offset && i < offset) 5 | continue; 6 | 7 | switch (sew) { 8 | case e8: { 9 | VI_XI_SLIDEUP_PARAMS(e8, offset); 10 | vd = vs2; 11 | } 12 | break; 13 | case e16: { 14 | VI_XI_SLIDEUP_PARAMS(e16, offset); 15 | vd = vs2; 16 | } 17 | break; 18 | case e32: { 19 | VI_XI_SLIDEUP_PARAMS(e32, offset); 20 | vd = vs2; 21 | } 22 | break; 23 | default: { 24 | VI_XI_SLIDEUP_PARAMS(e64, offset); 25 | vd = vs2; 26 | } 27 | break; 28 | } 29 | VI_LOOP_END 30 | -------------------------------------------------------------------------------- /riscv/insns/vsll_vi.h: -------------------------------------------------------------------------------- 1 | // vsll.vi vd, vs2, zimm5 2 | VI_VI_LOOP 3 | ({ 4 | vd = vs2 << (simm5 & (sew - 1) & 0x1f); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsll_vv.h: -------------------------------------------------------------------------------- 1 | // vsll 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs2 << (vs1 & (sew - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsll_vx.h: -------------------------------------------------------------------------------- 1 | // vsll 2 | VI_VX_LOOP 3 | ({ 4 | vd = vs2 << (rs1 & (sew - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsmul_vv.h: -------------------------------------------------------------------------------- 1 | // vsmul: Signed saturating and rounding fractional multiply 2 | VRM xrm = P.VU.get_vround_mode(); 3 | uint64_t int_max = (1ul << (P.VU.vsew - 1)) - 1; 4 | uint64_t int_min = - (1 << (P.VU.vsew - 1)); 5 | uint64_t sign_mask = ((1ul << (P.VU.vsew - 1))); 6 | 7 | VI_VV_ULOOP 8 | ({ 9 | uint64_t vs1_sign; 10 | uint64_t vs2_sign; 11 | uint64_t result_sign; 12 | 13 | vs1_sign = vs1 & sign_mask; 14 | vs2_sign = vs2 & sign_mask; 15 | bool overflow = vs1 == vs2 && vs1 == int_min; 16 | 17 | uint128_t result = (uint128_t)vs1 * (uint128_t)vs2; 18 | result &= ((uint128_t)1llu << ((sew * 2) - 2)) - 1; 19 | result_sign = (vs1_sign ^ vs2_sign) & sign_mask; 20 | // rounding 21 | INT_ROUNDING(result, xrm, sew - 1); 22 | // unsigned shifting 23 | result = result >> (sew - 1); 24 | 25 | // saturation 26 | if (overflow) { 27 | result = int_max; 28 | P.VU.vxsat = 1; 29 | } else { 30 | result |= result_sign; 31 | } 32 | vd = result; 33 | }) 34 | -------------------------------------------------------------------------------- /riscv/insns/vsmul_vx.h: -------------------------------------------------------------------------------- 1 | // vsmul 2 | VRM xrm = P.VU.get_vround_mode(); 3 | uint128_t int_max = (1ul << (P.VU.vsew - 1)) - 1; 4 | uint128_t int_min = - (1 << (P.VU.vsew - 1)); 5 | uint128_t sign_mask = ((1ul << (P.VU.vsew - 1))); 6 | 7 | VI_VX_ULOOP 8 | ({ 9 | uint128_t rs1_sign; 10 | uint128_t vs2_sign; 11 | uint128_t result_sign; 12 | 13 | rs1_sign = rs1 & sign_mask; 14 | vs2_sign = vs2 & sign_mask; 15 | bool overflow = rs1 == vs2 && rs1 == int_min; 16 | 17 | uint128_t result = (uint128_t)rs1 * (uint128_t)vs2; 18 | result &= ((uint128_t)1llu << ((sew * 2) - 2)) - 1; 19 | result_sign = (rs1_sign ^ vs2_sign) & sign_mask; 20 | // rounding 21 | INT_ROUNDING(result, xrm, sew - 1); 22 | 23 | // unsigned shifting 24 | result = result >> (sew - 1); 25 | 26 | // saturation 27 | if (overflow) { 28 | result = int_max; 29 | P.VU.vxsat = 1; 30 | } else { 31 | result |= result_sign; 32 | } 33 | vd = result; 34 | }) 35 | -------------------------------------------------------------------------------- /riscv/insns/vsra_vi.h: -------------------------------------------------------------------------------- 1 | // vsra.vi vd, vs2, zimm5 2 | VI_VI_LOOP 3 | ({ 4 | vd = vs2 >> (simm5 & (sew - 1) & 0x1f); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsra_vv.h: -------------------------------------------------------------------------------- 1 | // vsra.vv vd, vs2, vs1 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs2 >> (vs1 & (sew - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsra_vx.h: -------------------------------------------------------------------------------- 1 | // vsra.vx vd, vs2, rs1 2 | VI_VX_LOOP 3 | ({ 4 | vd = vs2 >> (rs1 & (sew - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsrl_vi.h: -------------------------------------------------------------------------------- 1 | // vsrl.vi vd, vs2, zimm5 2 | VI_VI_ULOOP 3 | ({ 4 | vd = vs2 >> (simm5 & (sew - 1) & 0x1f); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsrl_vv.h: -------------------------------------------------------------------------------- 1 | // vsrl.vv vd, vs2, vs1 2 | VI_VV_ULOOP 3 | ({ 4 | vd = vs2 >> (vs1 & (sew - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsrl_vx.h: -------------------------------------------------------------------------------- 1 | // vsrl.vx vd, vs2, rs1 2 | VI_VX_ULOOP 3 | ({ 4 | vd = vs2 >> (rs1 & (sew - 1)); 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vssb_v.h: -------------------------------------------------------------------------------- 1 | // vssb.v and vssseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_ST(i * RS2, fn, uint8, 1); 4 | -------------------------------------------------------------------------------- /riscv/insns/vsse_v.h: -------------------------------------------------------------------------------- 1 | // vsse.v and vssseg[2-8]e.v 2 | reg_t sew = P.VU.vsew; 3 | 4 | if (sew == e8) { 5 | VI_ST(i * RS2, fn, uint8, 1); 6 | } else if (sew == e16) { 7 | VI_ST(i * RS2, fn, uint16, 2); 8 | } else if (sew == e32) { 9 | VI_ST(i * RS2, fn, uint32, 4); 10 | } else if (sew == e64) { 11 | VI_ST(i * RS2, fn, uint64, 8); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /riscv/insns/vssh_v.h: -------------------------------------------------------------------------------- 1 | // vssh.v and vssseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_ST(i * RS2, fn, uint16, 2); 4 | -------------------------------------------------------------------------------- /riscv/insns/vssra_vi.h: -------------------------------------------------------------------------------- 1 | // vssra.vi vd, vs2, simm5 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VI_LOOP 4 | ({ 5 | int sh = simm5 & (sew - 1) & 0x1f; 6 | INT_ROUNDING(vs2, xrm, sh); 7 | vd = vs2 >> sh; 8 | }) 9 | -------------------------------------------------------------------------------- /riscv/insns/vssra_vv.h: -------------------------------------------------------------------------------- 1 | // vssra.vv vd, vs2, vs1 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VV_LOOP 4 | ({ 5 | int sh = vs1 & (sew - 1); 6 | 7 | INT_ROUNDING(vs2, xrm, sh); 8 | vd = vs2 >> sh; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vssra_vx.h: -------------------------------------------------------------------------------- 1 | // vssra.vx vd, vs2, rs1 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VX_LOOP 4 | ({ 5 | int sh = rs1 & (sew - 1); 6 | 7 | INT_ROUNDING(vs2, xrm, sh); 8 | vd = vs2 >> sh; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vssrl_vi.h: -------------------------------------------------------------------------------- 1 | // vssra.vi vd, vs2, simm5 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VI_ULOOP 4 | ({ 5 | int sh = simm5 & (sew - 1) & 0x1f; 6 | 7 | INT_ROUNDING(vs2, xrm, sh); 8 | vd = vs2 >> sh; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vssrl_vv.h: -------------------------------------------------------------------------------- 1 | // vssrl.vv vd, vs2, vs1 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VV_ULOOP 4 | ({ 5 | int sh = vs1 & (sew - 1); 6 | 7 | INT_ROUNDING(vs2, xrm, sh); 8 | vd = vs2 >> sh; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vssrl_vx.h: -------------------------------------------------------------------------------- 1 | // vssrl.vx vd, vs2, rs1 2 | VRM xrm = P.VU.get_vround_mode(); 3 | VI_VX_ULOOP 4 | ({ 5 | int sh = rs1 & (sew - 1); 6 | 7 | INT_ROUNDING(vs2, xrm, sh); 8 | vd = vs2 >> sh; 9 | }) 10 | -------------------------------------------------------------------------------- /riscv/insns/vssub_vv.h: -------------------------------------------------------------------------------- 1 | // vssub.vv vd, vs2, vs1 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | 5 | switch (sew) { 6 | case e8: { 7 | VV_PARAMS(e8); 8 | vd = sat_sub(vs2, vs1, sat); 9 | break; 10 | } 11 | case e16: { 12 | VV_PARAMS(e16); 13 | vd = sat_sub(vs2, vs1, sat); 14 | break; 15 | } 16 | case e32: { 17 | VV_PARAMS(e32); 18 | vd = sat_sub(vs2, vs1, sat); 19 | break; 20 | } 21 | default: { 22 | VV_PARAMS(e64); 23 | vd = sat_sub(vs2, vs1, sat); 24 | break; 25 | } 26 | } 27 | P.VU.vxsat |= sat; 28 | VI_LOOP_END 29 | -------------------------------------------------------------------------------- /riscv/insns/vssub_vx.h: -------------------------------------------------------------------------------- 1 | // vssub.vx vd, vs2, rs1 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | 5 | switch (sew) { 6 | case e8: { 7 | VX_PARAMS(e8); 8 | vd = sat_sub(vs2, rs1, sat); 9 | break; 10 | } 11 | case e16: { 12 | VX_PARAMS(e16); 13 | vd = sat_sub(vs2, rs1, sat); 14 | break; 15 | } 16 | case e32: { 17 | VX_PARAMS(e32); 18 | vd = sat_sub(vs2, rs1, sat); 19 | break; 20 | } 21 | default: { 22 | VX_PARAMS(e64); 23 | vd = sat_sub(vs2, rs1, sat); 24 | break; 25 | } 26 | } 27 | P.VU.vxsat |= sat; 28 | VI_LOOP_END 29 | -------------------------------------------------------------------------------- /riscv/insns/vssubu_vv.h: -------------------------------------------------------------------------------- 1 | // vssubu.vv vd, vs2, vs1 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | 5 | switch (sew) { 6 | case e8: { 7 | VV_U_PARAMS(e8); 8 | vd = sat_subu(vs2, vs1, sat); 9 | break; 10 | } 11 | case e16: { 12 | VV_U_PARAMS(e16); 13 | vd = sat_subu(vs2, vs1, sat); 14 | break; 15 | } 16 | case e32: { 17 | VV_U_PARAMS(e32); 18 | vd = sat_subu(vs2, vs1, sat); 19 | break; 20 | } 21 | default: { 22 | VV_U_PARAMS(e64); 23 | vd = sat_subu(vs2, vs1, sat); 24 | break; 25 | } 26 | } 27 | P.VU.vxsat |= sat; 28 | 29 | VI_LOOP_END 30 | -------------------------------------------------------------------------------- /riscv/insns/vssubu_vx.h: -------------------------------------------------------------------------------- 1 | // vssubu.vx vd, vs2, rs1 2 | VI_LOOP_BASE 3 | bool sat = false; 4 | 5 | switch (sew) { 6 | case e8: { 7 | VX_U_PARAMS(e8); 8 | vd = sat_subu(vs2, rs1, sat); 9 | break; 10 | } 11 | case e16: { 12 | VX_U_PARAMS(e16); 13 | vd = sat_subu(vs2, rs1, sat); 14 | break; 15 | } 16 | case e32: { 17 | VX_U_PARAMS(e32); 18 | vd = sat_subu(vs2, rs1, sat); 19 | break; 20 | } 21 | default: { 22 | VX_U_PARAMS(e64); 23 | vd = sat_subu(vs2, rs1, sat); 24 | break; 25 | } 26 | } 27 | P.VU.vxsat |= sat; 28 | VI_LOOP_END 29 | -------------------------------------------------------------------------------- /riscv/insns/vssw_v.h: -------------------------------------------------------------------------------- 1 | // vssw.v and vssseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_ST(i * RS2, fn, uint32, 4); 4 | -------------------------------------------------------------------------------- /riscv/insns/vsub_vv.h: -------------------------------------------------------------------------------- 1 | // vsub 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs2 - vs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsub_vx.h: -------------------------------------------------------------------------------- 1 | // vsub: vd[i] = (vd[i] * x[rs1]) - vs2[i] 2 | VI_VX_LOOP 3 | ({ 4 | vd = vs2 - rs1; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vsuxb_v.h: -------------------------------------------------------------------------------- 1 | // vsuxb.v and vsxseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | reg_t vl = P.VU.vl; 4 | reg_t baseAddr = RS1; 5 | reg_t stride = insn.rs2(); 6 | reg_t vs3 = insn.rd(); 7 | reg_t vlmax = P.VU.vlmax; 8 | VI_DUPLICATE_VREG(stride, vlmax); 9 | for (reg_t i = 0; i < vlmax && vl != 0; ++i) { 10 | bool is_valid = true; 11 | VI_ELEMENT_SKIP(i); 12 | VI_STRIP(i) 13 | 14 | switch (P.VU.vsew) { 15 | case e8: 16 | if (is_valid) 17 | MMU.store_uint8(baseAddr + index[i], 18 | P.VU.elt(vs3, vreg_inx)); 19 | break; 20 | case e16: 21 | if (is_valid) 22 | MMU.store_uint8(baseAddr + index[i], 23 | P.VU.elt(vs3, vreg_inx)); 24 | break; 25 | case e32: 26 | if (is_valid) 27 | MMU.store_uint8(baseAddr + index[i], 28 | P.VU.elt(vs3, vreg_inx)); 29 | break; 30 | case e64: 31 | if (is_valid) 32 | MMU.store_uint8(baseAddr + index[i], 33 | P.VU.elt(vs3, vreg_inx)); 34 | break; 35 | } 36 | } 37 | P.VU.vstart = 0; 38 | -------------------------------------------------------------------------------- /riscv/insns/vsuxe_v.h: -------------------------------------------------------------------------------- 1 | // vsxe.v and vsxseg[2-8]e.v 2 | const reg_t sew = P.VU.vsew; 3 | const reg_t vl = P.VU.vl; 4 | require(sew >= e8 && sew <= e64); 5 | reg_t baseAddr = RS1; 6 | reg_t stride = insn.rs2(); 7 | reg_t vs3 = insn.rd(); 8 | reg_t vlmax = P.VU.vlmax; 9 | VI_DUPLICATE_VREG(stride, vlmax); 10 | for (reg_t i = 0; i < vlmax && vl != 0; ++i) { 11 | bool is_valid = true; 12 | VI_ELEMENT_SKIP(i); 13 | VI_STRIP(i) 14 | 15 | switch (sew) { 16 | case e8: 17 | if (is_valid) 18 | MMU.store_uint8(baseAddr + index[i], 19 | P.VU.elt(vs3, vreg_inx)); 20 | break; 21 | case e16: 22 | if (is_valid) 23 | MMU.store_uint16(baseAddr + index[i], 24 | P.VU.elt(vs3, vreg_inx)); 25 | break; 26 | case e32: 27 | if (is_valid) 28 | MMU.store_uint32(baseAddr + index[i], 29 | P.VU.elt(vs3, vreg_inx)); 30 | break; 31 | case e64: 32 | if (is_valid) 33 | MMU.store_uint64(baseAddr + index[i], 34 | P.VU.elt(vs3, vreg_inx)); 35 | break; 36 | } 37 | } 38 | P.VU.vstart = 0; 39 | -------------------------------------------------------------------------------- /riscv/insns/vsuxh_v.h: -------------------------------------------------------------------------------- 1 | // vsxh.v and vsxseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | reg_t vl = P.VU.vl; 4 | reg_t baseAddr = RS1; 5 | reg_t stride = insn.rs2(); 6 | reg_t vs3 = insn.rd(); 7 | reg_t vlmax = P.VU.vlmax; 8 | VI_DUPLICATE_VREG(stride, vlmax); 9 | for (reg_t i = 0; i < vlmax && vl != 0; ++i) { 10 | bool is_valid = true; 11 | VI_ELEMENT_SKIP(i); 12 | VI_STRIP(i) 13 | 14 | switch (P.VU.vsew) { 15 | case e16: 16 | if (is_valid) 17 | MMU.store_uint16(baseAddr + index[i], 18 | P.VU.elt(vs3, vreg_inx)); 19 | break; 20 | case e32: 21 | if (is_valid) 22 | MMU.store_uint16(baseAddr + index[i], 23 | P.VU.elt(vs3, vreg_inx)); 24 | break; 25 | case e64: 26 | if (is_valid) 27 | MMU.store_uint16(baseAddr + index[i], 28 | P.VU.elt(vs3, vreg_inx)); 29 | break; 30 | } 31 | } 32 | P.VU.vstart = 0; 33 | -------------------------------------------------------------------------------- /riscv/insns/vsuxw_v.h: -------------------------------------------------------------------------------- 1 | // vsxw.v and vsxseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | reg_t vl = P.VU.vl; 4 | reg_t baseAddr = RS1; 5 | reg_t stride = insn.rs2(); 6 | reg_t vs3 = insn.rd(); 7 | reg_t vlmax = P.VU.vlmax; 8 | VI_DUPLICATE_VREG(stride, vlmax); 9 | for (reg_t i = 0; i < vlmax && vl != 0; ++i) { 10 | bool is_valid = true; 11 | VI_ELEMENT_SKIP(i); 12 | VI_STRIP(i) 13 | 14 | switch (P.VU.vsew) { 15 | case e32: 16 | if (is_valid) 17 | MMU.store_uint32(baseAddr + index[i], 18 | P.VU.elt(vs3, vreg_inx)); 19 | break; 20 | case e64: 21 | if (is_valid) 22 | MMU.store_uint32(baseAddr + index[i], 23 | P.VU.elt(vs3, vreg_inx)); 24 | break; 25 | } 26 | } 27 | P.VU.vstart = 0; 28 | -------------------------------------------------------------------------------- /riscv/insns/vsw_v.h: -------------------------------------------------------------------------------- 1 | // vsw.v and vsseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_ST(0, i * nf + fn, uint32, 4); 4 | -------------------------------------------------------------------------------- /riscv/insns/vsxb_v.h: -------------------------------------------------------------------------------- 1 | // vsxb.v and vsxseg[2-8]b.v 2 | require(P.VU.vsew >= e8); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_ST(index[i], fn, uint8, 1); 5 | -------------------------------------------------------------------------------- /riscv/insns/vsxe_v.h: -------------------------------------------------------------------------------- 1 | // vsxe.v and vsxseg[2-8]e.v 2 | reg_t sew = P.VU.vsew; 3 | require(sew >= e8 && sew <= e64); 4 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 5 | if (sew == e8) { 6 | VI_ST(index[i], fn, uint8, 1); 7 | } else if (sew == e16) { 8 | VI_ST(index[i], fn, uint16, 2); 9 | } else if (sew == e32) { 10 | VI_ST(index[i], fn, uint32, 4); 11 | } else if (sew == e64) { 12 | VI_ST(index[i], fn, uint64, 8); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /riscv/insns/vsxh_v.h: -------------------------------------------------------------------------------- 1 | // vsxh.v and vsxseg[2-8]h.v 2 | require(P.VU.vsew >= e16); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_ST(index[i], fn, uint16, 2); 5 | -------------------------------------------------------------------------------- /riscv/insns/vsxw_v.h: -------------------------------------------------------------------------------- 1 | // vsxw.v and vsxseg[2-8]w.v 2 | require(P.VU.vsew >= e32); 3 | VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); 4 | VI_ST(index[i], fn, uint32, 4); 5 | -------------------------------------------------------------------------------- /riscv/insns/vwadd_vv.h: -------------------------------------------------------------------------------- 1 | // vwadd.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, 0, +, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwadd_vx.h: -------------------------------------------------------------------------------- 1 | // vwadd.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, 0, +, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwadd_wv.h: -------------------------------------------------------------------------------- 1 | // vwadd.wv vd, vs2, vs1 2 | VI_CHECK_DDS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(vs1, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwadd_wx.h: -------------------------------------------------------------------------------- 1 | // vwaddu.wx vd, vs2, rs1 2 | VI_CHECK_DDS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(rs1, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwaddu_vv.h: -------------------------------------------------------------------------------- 1 | // vwaddu.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, 0, +, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwaddu_vx.h: -------------------------------------------------------------------------------- 1 | // vwaddu.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, 0, +, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwaddu_wv.h: -------------------------------------------------------------------------------- 1 | // vwaddu.wv vd, vs2, vs1 2 | VI_CHECK_DDS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(vs1, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwaddu_wx.h: -------------------------------------------------------------------------------- 1 | // vwaddu.wx vd, vs2, rs1 2 | VI_CHECK_DDS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(rs1, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vwmacc.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, vd_w, *, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmacc_vx.h: -------------------------------------------------------------------------------- 1 | // vwmacc.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, vd_w, *, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmaccsu_vv.h: -------------------------------------------------------------------------------- 1 | // vwmaccsu.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN_MIX(vs2, vs1, vd_w, *, +, int, uint, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmaccsu_vx.h: -------------------------------------------------------------------------------- 1 | // vwmaccsu.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN_MIX(vs2, rs1, vd_w, *, +, int, uint, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmaccu_vv.h: -------------------------------------------------------------------------------- 1 | // vwmaccu.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, vd_w, *, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmaccu_vx.h: -------------------------------------------------------------------------------- 1 | // vwmaccu.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, vd_w, *, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmaccus_vx.h: -------------------------------------------------------------------------------- 1 | // vwmaccus.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN_MIX(vs2, rs1, vd_w, *, +, int, int, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmul_vv.h: -------------------------------------------------------------------------------- 1 | // vwmul.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, 0, *, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmul_vx.h: -------------------------------------------------------------------------------- 1 | // vwmul.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, 0, *, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmulsu_vv.h: -------------------------------------------------------------------------------- 1 | // vwmulsu.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | switch(P.VU.vsew) { 6 | case e8: 7 | P.VU.elt(rd_num, i) = (int16_t)(int8_t)vs2 * (int16_t)(uint8_t)vs1; 8 | break; 9 | case e16: 10 | P.VU.elt(rd_num, i) = (int32_t)(int16_t)vs2 * (int32_t)(uint16_t)vs1; 11 | break; 12 | default: 13 | P.VU.elt(rd_num, i) = (int64_t)(int32_t)vs2 * (int64_t)(uint32_t)vs1; 14 | break; 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /riscv/insns/vwmulsu_vx.h: -------------------------------------------------------------------------------- 1 | // vwmulsu.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | switch(P.VU.vsew) { 6 | case e8: 7 | P.VU.elt(rd_num, i) = (int16_t)(int8_t)vs2 * (int16_t)(uint8_t)rs1; 8 | break; 9 | case e16: 10 | P.VU.elt(rd_num, i) = (int32_t)(int16_t)vs2 * (int32_t)(uint16_t)rs1; 11 | break; 12 | default: 13 | P.VU.elt(rd_num, i) = (int64_t)(int32_t)vs2 * (int64_t)(uint32_t)rs1; 14 | break; 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /riscv/insns/vwmulu_vv.h: -------------------------------------------------------------------------------- 1 | // vwmulu.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, 0, *, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwmulu_vx.h: -------------------------------------------------------------------------------- 1 | // vwmul.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, 0, *, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwredsum_vs.h: -------------------------------------------------------------------------------- 1 | // vwredsum.vs vd, vs2, vs1 2 | VI_VV_LOOP_WIDE_REDUCTION 3 | ({ 4 | vd_0_res += vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vwredsumu_vs.h: -------------------------------------------------------------------------------- 1 | // vwredsum.vs vd, vs2, vs1 2 | VI_VV_ULOOP_WIDE_REDUCTION 3 | ({ 4 | vd_0_res += vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vwsmacc_vv.h: -------------------------------------------------------------------------------- 1 | // vwsmacc.vv vd, vs2, vs1 2 | VI_VVX_LOOP_WIDE_SSMA(vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsmacc_vx.h: -------------------------------------------------------------------------------- 1 | // vwsmacc.vx vd, vs2, rs1 2 | VI_VVX_LOOP_WIDE_SSMA(rs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsmaccsu_vv.h: -------------------------------------------------------------------------------- 1 | // vwsmaccsu.vx vd, vs2, vs1 2 | VI_VVX_LOOP_WIDE_SU_SSMA(vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsmaccsu_vx.h: -------------------------------------------------------------------------------- 1 | // vwsmaccsu.vx vd, vs2, rs1 2 | VI_VVX_LOOP_WIDE_SU_SSMA(rs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsmaccu_vv.h: -------------------------------------------------------------------------------- 1 | // vwsmaccu.vv vd, vs2, vs1 2 | VI_VVX_LOOP_WIDE_USSMA(vs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsmaccu_vx.h: -------------------------------------------------------------------------------- 1 | // vwsmaccu vd, vs2, rs1 2 | VI_VVX_LOOP_WIDE_USSMA(rs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsmaccus_vx.h: -------------------------------------------------------------------------------- 1 | // vwsmaccus.vx vd, vs2, rs1 2 | VI_VVX_LOOP_WIDE_US_SSMA(rs1); 3 | -------------------------------------------------------------------------------- /riscv/insns/vwsub_vv.h: -------------------------------------------------------------------------------- 1 | // vwsub.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, 0, -, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsub_vx.h: -------------------------------------------------------------------------------- 1 | // vwsub.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, 0, -, +, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsub_wv.h: -------------------------------------------------------------------------------- 1 | // vwsub.wv vd, vs2, vs1 2 | VI_CHECK_DDS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(vs1, -, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsub_wx.h: -------------------------------------------------------------------------------- 1 | // vwsub.wx vd, vs2, rs1 2 | VI_CHECK_DDS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(rs1, -, int); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsubu_vv.h: -------------------------------------------------------------------------------- 1 | // vwsubu.vv vd, vs2, vs1 2 | VI_CHECK_DSS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, vs1, 0, -, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsubu_vx.h: -------------------------------------------------------------------------------- 1 | // vwsubu.vx vd, vs2, rs1 2 | VI_CHECK_DSS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_OP_AND_ASSIGN(vs2, rs1, 0, -, +, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsubu_wv.h: -------------------------------------------------------------------------------- 1 | // vwsubu.wv vd, vs2, vs1 2 | VI_CHECK_DDS(true); 3 | VI_VV_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(vs1, -, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vwsubu_wx.h: -------------------------------------------------------------------------------- 1 | // vwsubu.wx vd, vs2, rs1 2 | VI_CHECK_DDS(false); 3 | VI_VX_LOOP_WIDEN 4 | ({ 5 | VI_WIDE_WVX_OP(rs1, -, uint); 6 | }) 7 | -------------------------------------------------------------------------------- /riscv/insns/vxor_vi.h: -------------------------------------------------------------------------------- 1 | // vxor 2 | VI_VI_LOOP 3 | ({ 4 | vd = simm5 ^ vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vxor_vv.h: -------------------------------------------------------------------------------- 1 | // vxor 2 | VI_VV_LOOP 3 | ({ 4 | vd = vs1 ^ vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/vxor_vx.h: -------------------------------------------------------------------------------- 1 | // vxor 2 | VI_VX_LOOP 3 | ({ 4 | vd = rs1 ^ vs2; 5 | }) 6 | -------------------------------------------------------------------------------- /riscv/insns/wfi.h: -------------------------------------------------------------------------------- 1 | require_privilege(get_field(STATE.mstatus, MSTATUS_TW) ? PRV_M : PRV_S); 2 | wfi(); 3 | -------------------------------------------------------------------------------- /riscv/insns/xor.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(RS1 ^ RS2); 2 | -------------------------------------------------------------------------------- /riscv/insns/xori.h: -------------------------------------------------------------------------------- 1 | WRITE_RD(insn.i_imm() ^ RS1); 2 | -------------------------------------------------------------------------------- /riscv/remote_bitbang.h: -------------------------------------------------------------------------------- 1 | #ifndef REMOTE_BITBANG_H 2 | #define REMOTE_BITBANG_H 3 | 4 | #include 5 | 6 | #include "jtag_dtm.h" 7 | 8 | class remote_bitbang_t 9 | { 10 | public: 11 | // Create a new server, listening for connections from localhost on the given 12 | // port. 13 | remote_bitbang_t(uint16_t port, jtag_dtm_t *tap); 14 | 15 | // Do a bit of work. 16 | void tick(); 17 | 18 | private: 19 | jtag_dtm_t *tap; 20 | 21 | int socket_fd; 22 | int client_fd; 23 | 24 | static const ssize_t buf_size = 64 * 1024; 25 | char recv_buf[buf_size]; 26 | ssize_t recv_start, recv_end; 27 | 28 | // Check for a client connecting, and accept if there is one. 29 | void accept(); 30 | // Execute any commands the client has for us. 31 | void execute_commands(); 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /riscv/rocc.h: -------------------------------------------------------------------------------- 1 | #ifndef _RISCV_ROCC_H 2 | #define _RISCV_ROCC_H 3 | 4 | #include "extension.h" 5 | 6 | struct rocc_insn_t 7 | { 8 | unsigned opcode : 7; 9 | unsigned rd : 5; 10 | unsigned xs2 : 1; 11 | unsigned xs1 : 1; 12 | unsigned xd : 1; 13 | unsigned rs1 : 5; 14 | unsigned rs2 : 5; 15 | unsigned funct : 7; 16 | }; 17 | 18 | union rocc_insn_union_t 19 | { 20 | rocc_insn_t r; 21 | insn_t i; 22 | }; 23 | 24 | class rocc_t : public extension_t 25 | { 26 | public: 27 | virtual reg_t custom0(rocc_insn_t insn, reg_t xs1, reg_t xs2); 28 | virtual reg_t custom1(rocc_insn_t insn, reg_t xs1, reg_t xs2); 29 | virtual reg_t custom2(rocc_insn_t insn, reg_t xs1, reg_t xs2); 30 | virtual reg_t custom3(rocc_insn_t insn, reg_t xs1, reg_t xs2); 31 | std::vector get_instructions(); 32 | std::vector get_disasms(); 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /riscv/rom.cc: -------------------------------------------------------------------------------- 1 | #include "devices.h" 2 | 3 | rom_device_t::rom_device_t(std::vector data) 4 | : data(data) 5 | { 6 | } 7 | 8 | bool rom_device_t::load(reg_t addr, size_t len, uint8_t* bytes) 9 | { 10 | if (addr + len > data.size()) 11 | return false; 12 | memcpy(bytes, &data[addr], len); 13 | return true; 14 | } 15 | 16 | bool rom_device_t::store(reg_t addr, size_t len, const uint8_t* bytes) 17 | { 18 | return false; 19 | } 20 | -------------------------------------------------------------------------------- /riscv/simif.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _RISCV_SIMIF_H 4 | #define _RISCV_SIMIF_H 5 | 6 | #include "decode.h" 7 | 8 | // this is the interface to the simulator used by the processors and memory 9 | class simif_t 10 | { 11 | public: 12 | // should return NULL for MMIO addresses 13 | virtual char* addr_to_mem(reg_t addr) = 0; 14 | // used for MMIO addresses 15 | virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0; 16 | virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0; 17 | // Callback for processors to let the simulation know they were reset. 18 | virtual void proc_reset(unsigned id) = 0; 19 | }; 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /riscv/tracer.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef _RISCV_TRACER_H 4 | #define _RISCV_TRACER_H 5 | 6 | #include "processor.h" 7 | 8 | static inline void trace_opcode(processor_t* p, insn_bits_t opc, insn_t insn) { 9 | } 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /riscv/trap.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include "trap.h" 4 | #include "processor.h" 5 | #include 6 | 7 | const char* trap_t::name() 8 | { 9 | const char* fmt = uint8_t(which) == which ? "trap #%u" : "interrupt #%u"; 10 | sprintf(_name, fmt, uint8_t(which)); 11 | return _name; 12 | } 13 | -------------------------------------------------------------------------------- /scripts/mk-install-dirs.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # mkinstalldirs --- make directory hierarchy 3 | # Author: Noah Friedman 4 | # Created: 1993-05-16 5 | # Public domain 6 | 7 | # $Id: mkinstalldirs,v 1.1 2003/09/09 22:24:03 mhampton Exp $ 8 | 9 | errstatus=0 10 | 11 | for file 12 | do 13 | set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` 14 | shift 15 | 16 | pathcomp= 17 | for d 18 | do 19 | pathcomp="$pathcomp$d" 20 | case "$pathcomp" in 21 | -* ) pathcomp=./$pathcomp ;; 22 | esac 23 | 24 | if test ! -d "$pathcomp"; then 25 | echo "mkdir $pathcomp" 1>&2 26 | 27 | mkdir "$pathcomp" || lasterr=$? 28 | 29 | if test ! -d "$pathcomp"; then 30 | errstatus=$lasterr 31 | fi 32 | fi 33 | 34 | pathcomp="$pathcomp/" 35 | done 36 | done 37 | 38 | exit $errstatus 39 | 40 | # mkinstalldirs ends here 41 | -------------------------------------------------------------------------------- /softfloat/s_commonNaNToF16UI.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/s_commonNaNToF32UI.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/s_commonNaNToF64UI.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/s_f128UIToCommonNaN.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/s_f16UIToCommonNaN.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/s_f32UIToCommonNaN.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/s_f64UIToCommonNaN.c: -------------------------------------------------------------------------------- 1 | 2 | /*---------------------------------------------------------------------------- 3 | | This file intentionally contains no code. 4 | *----------------------------------------------------------------------------*/ 5 | 6 | -------------------------------------------------------------------------------- /softfloat/softfloat.ac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comparch-security/spike-cache/3639dd7ee57c43b3eb5d70bedfd5b2fdeece3f42/softfloat/softfloat.ac -------------------------------------------------------------------------------- /spike_main/spike_main.ac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/comparch-security/spike-cache/3639dd7ee57c43b3eb5d70bedfd5b2fdeece3f42/spike_main/spike_main.ac -------------------------------------------------------------------------------- /spike_main/spike_main.mk.in: -------------------------------------------------------------------------------- 1 | spike_main_subproject_deps = \ 2 | fesvr \ 3 | softfloat \ 4 | riscv \ 5 | 6 | spike_main_install_prog_srcs = \ 7 | spike.cc \ 8 | spike-dasm.cc \ 9 | spike-log-parser.cc \ 10 | xspike.cc \ 11 | termios-xspike.cc \ 12 | 13 | spike_main_hdrs = \ 14 | 15 | spike_main_srcs = \ 16 | -------------------------------------------------------------------------------- /spike_main/termios-xspike.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | // termios-xspike sets up a canonical terminal and blocks forever. 4 | // It allows us to send Ctrl-C etc. to the target machine. 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | int main() 14 | { 15 | struct termios old_tios; 16 | if (tcgetattr(0, &old_tios) < 0) 17 | return -1; 18 | 19 | signal(SIGTERM, [](int) { }); 20 | 21 | struct termios new_tios = old_tios; 22 | new_tios.c_lflag &= ~(ICANON | ECHO | ISIG); 23 | if (tcsetattr(0, TCSANOW, &new_tios) < 0) 24 | return -1; 25 | 26 | pause(); 27 | 28 | return tcsetattr(0, TCSANOW, &old_tios); 29 | } 30 | -------------------------------------------------------------------------------- /tests/ebreak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os 4 | import testlib 5 | import unittest 6 | import tempfile 7 | import time 8 | 9 | class EbreakTest(unittest.TestCase): 10 | def setUp(self): 11 | self.binary = testlib.compile("ebreak.s") 12 | 13 | def test_noport(self): 14 | """Make sure that we can run past ebreak when --gdb-port isn't used.""" 15 | spike = testlib.Spike(self.binary, with_gdb=False, timeout=10) 16 | result = spike.wait() 17 | self.assertEqual(result, 0) 18 | 19 | def test_nogdb(self): 20 | """Make sure that we can run past ebreak when gdb isn't attached.""" 21 | spike = testlib.Spike(self.binary, timeout=10) 22 | result = spike.wait() 23 | self.assertEqual(result, 0) 24 | 25 | if __name__ == '__main__': 26 | unittest.main() 27 | -------------------------------------------------------------------------------- /tests/ebreak.s: -------------------------------------------------------------------------------- 1 | .global main 2 | main: 3 | li a0, 0 4 | ebreak 5 | ret 6 | --------------------------------------------------------------------------------