diff --git a/riscv/decode_macros.h b/riscv/decode_macros.h index c853c470..b8cddb60 100644 --- a/riscv/decode_macros.h +++ b/riscv/decode_macros.h @@ -236,8 +236,8 @@ static inline bool is_aligned(const unsigned val, const unsigned pos) #define zext(x, pos) (((reg_t)(x) << (64 - (pos))) >> (64 - (pos))) #define sext_xlen(x) sext(x, xlen) #define zext_xlen(x) zext(x, xlen) -#define sext_xlen_pair(x) sext(x, xlen * 2) -#define zext_xlen_pair(x) zext(x, xlen * 2) +#define sext_xlen_pair(x) (xlen == 32 ? sext(x, 64) : (sreg_t)(x)) +#define zext_xlen_pair(x) (xlen == 32 ? zext(x, 64) : (reg_t)(x)) #define set_pc(x) \ do { if (unlikely((x) & ~p->pc_alignment_mask())) \ diff --git a/riscv/insns/addd.h b/riscv/insns/addd.h new file mode 100644 index 00000000..0a4901f5 --- /dev/null +++ b/riscv/insns/addd.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RS1_PAIR + P_RS2_PAIR); \ No newline at end of file diff --git a/riscv/insns/mqrwacc.h b/riscv/insns/mqrwacc.h new file mode 100644 index 00000000..0aa2e73d --- /dev/null +++ b/riscv/insns/mqrwacc.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RD_PAIR + (((sreg_t)RS1*(sreg_t)RS2 + 0x40000000) >> 31)); \ No newline at end of file diff --git a/riscv/insns/mqwacc.h b/riscv/insns/mqwacc.h new file mode 100644 index 00000000..6f7cacdc --- /dev/null +++ b/riscv/insns/mqwacc.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RD_PAIR + (((sreg_t)RS1*(sreg_t)RS2) >> 31)); \ No newline at end of file diff --git a/riscv/insns/nclip.h b/riscv/insns/nclip.h new file mode 100644 index 00000000..f1ecfc76 --- /dev/null +++ b/riscv/insns/nclip.h @@ -0,0 +1,5 @@ +require_extension('P'); +require_rv32; +sreg_t tmp = (sreg_t)P_RS1_PAIR >> (RS2 & 0x3f); +int32_t result = P_SAT(32, tmp); +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipi.h b/riscv/insns/nclipi.h new file mode 100644 index 00000000..79bc1f2a --- /dev/null +++ b/riscv/insns/nclipi.h @@ -0,0 +1,5 @@ +require_extension('P'); +require_rv32; +sreg_t tmp = (sreg_t)P_RS1_PAIR >> insn.shamtd(); +int32_t result = P_SAT(32, tmp); +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipiu.h b/riscv/insns/nclipiu.h new file mode 100644 index 00000000..d8608d10 --- /dev/null +++ b/riscv/insns/nclipiu.h @@ -0,0 +1,5 @@ +require_extension('P'); +require_rv32; +reg_t tmp = (reg_t)P_RS1_PAIR >> insn.shamtd(); +uint32_t result = P_USAT_FULL(32, (sreg_t)tmp); +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipr.h b/riscv/insns/nclipr.h new file mode 100644 index 00000000..e9aca14e --- /dev/null +++ b/riscv/insns/nclipr.h @@ -0,0 +1,11 @@ +require_extension('P'); +require_rv32; +sreg_t val = (sreg_t)P_RS1_PAIR; +uint32_t shamt = RS2 & 0x3f; +sreg_t result; +if (shamt == 0) { + result = P_SAT(32, val); +} else { + result = P_SAT(32, (val >> shamt) + ((val >> (shamt - 1)) & 1)); +} +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipri.h b/riscv/insns/nclipri.h new file mode 100644 index 00000000..17528201 --- /dev/null +++ b/riscv/insns/nclipri.h @@ -0,0 +1,11 @@ +require_extension('P'); +require_rv32; +sreg_t val = (sreg_t)P_RS1_PAIR; +uint32_t shamt = insn.shamtd(); +sreg_t result; +if (shamt == 0) { + result = P_SAT(32, val); +} else { + result = P_SAT(32, (val >> shamt) + ((val >> (shamt - 1)) & 1)); +} +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipriu.h b/riscv/insns/nclipriu.h new file mode 100644 index 00000000..2595dbc8 --- /dev/null +++ b/riscv/insns/nclipriu.h @@ -0,0 +1,11 @@ +require_extension('P'); +require_rv32; +reg_t val = (reg_t)P_RS1_PAIR; +uint32_t shamt = insn.shamtd(); +reg_t result; +if (shamt == 0) { + result = P_USAT_FULL(32, (sreg_t)val); +} else { + result = P_USAT_FULL(32, (sreg_t)((val >> shamt) + ((val >> (shamt - 1)) & 1))); +} +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipru.h b/riscv/insns/nclipru.h new file mode 100644 index 00000000..c8044ed0 --- /dev/null +++ b/riscv/insns/nclipru.h @@ -0,0 +1,11 @@ +require_extension('P'); +require_rv32; +reg_t val = (reg_t)P_RS1_PAIR; +uint32_t shamt = RS2 & 0x3f; +reg_t result; +if (shamt == 0) { + result = P_USAT_FULL(32, (sreg_t)val); +} else { + result = P_USAT_FULL(32, (sreg_t)((val >> shamt) + ((val >> (shamt - 1)) & 1))); +} +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nclipu.h b/riscv/insns/nclipu.h new file mode 100644 index 00000000..a1e6099d --- /dev/null +++ b/riscv/insns/nclipu.h @@ -0,0 +1,5 @@ +require_extension('P'); +require_rv32; +reg_t tmp = (reg_t)P_RS1_PAIR >> (RS2 & 0x3f); +uint32_t result = P_USAT_FULL(32, (sreg_t)tmp); +WRITE_RD(result); \ No newline at end of file diff --git a/riscv/insns/nsra.h b/riscv/insns/nsra.h new file mode 100644 index 00000000..7cf9f39f --- /dev/null +++ b/riscv/insns/nsra.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_RD((sreg_t)P_RS1_PAIR >> (RS2 & 0x3f)); \ No newline at end of file diff --git a/riscv/insns/nsrai.h b/riscv/insns/nsrai.h new file mode 100644 index 00000000..63e287ca --- /dev/null +++ b/riscv/insns/nsrai.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_RD((sreg_t)P_RS1_PAIR >> insn.shamtd()); \ No newline at end of file diff --git a/riscv/insns/nsrar.h b/riscv/insns/nsrar.h new file mode 100644 index 00000000..b0879d3f --- /dev/null +++ b/riscv/insns/nsrar.h @@ -0,0 +1,11 @@ +require_extension('P'); +require_rv32; +sreg_t val = (sreg_t)P_RS1_PAIR; +uint32_t shamt = RS2 & 0x3f; +sreg_t result; +if (shamt == 0) { + result = val; +} else { + result = (val >> shamt) + ((val >> (shamt - 1)) & 1); +} +WRITE_RD(result); diff --git a/riscv/insns/nsrari.h b/riscv/insns/nsrari.h new file mode 100644 index 00000000..4e5fb806 --- /dev/null +++ b/riscv/insns/nsrari.h @@ -0,0 +1,11 @@ +require_extension('P'); +require_rv32; +sreg_t val = (sreg_t)P_RS1_PAIR; +uint32_t shamt = insn.shamtd(); +sreg_t result; +if (shamt == 0) { + result = val; +} else { + result = (val >> shamt) + ((val >> (shamt - 1)) & 1); +} +WRITE_RD(result); diff --git a/riscv/insns/nsrl.h b/riscv/insns/nsrl.h new file mode 100644 index 00000000..7de7e5b8 --- /dev/null +++ b/riscv/insns/nsrl.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_RD(P_RS1_PAIR >> (RS2 & 0x3f)); \ No newline at end of file diff --git a/riscv/insns/nsrli.h b/riscv/insns/nsrli.h new file mode 100644 index 00000000..b85a84ee --- /dev/null +++ b/riscv/insns/nsrli.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_RD(P_RS1_PAIR >> insn.shamtd()); \ No newline at end of file diff --git a/riscv/insns/paadd_db.h b/riscv/insns/paadd_db.h new file mode 100644 index 00000000..4ce1e126 --- /dev/null +++ b/riscv/insns/paadd_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8,8,8, { + p_rd = (p_rs1 + p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/paadd_dh.h b/riscv/insns/paadd_dh.h new file mode 100644 index 00000000..966921c6 --- /dev/null +++ b/riscv/insns/paadd_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16,16,16, { + p_rd = (p_rs1 + p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/paadd_dw.h b/riscv/insns/paadd_dw.h new file mode 100644 index 00000000..2409cf55 --- /dev/null +++ b/riscv/insns/paadd_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32,32,32, { + p_rd = ((sreg_t)p_rs1 + (sreg_t)p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/paaddu_db.h b/riscv/insns/paaddu_db.h new file mode 100644 index 00000000..71899a34 --- /dev/null +++ b/riscv/insns/paaddu_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8,8,8, { + p_rd = (p_rs1 + p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/paaddu_dh.h b/riscv/insns/paaddu_dh.h new file mode 100644 index 00000000..884b277e --- /dev/null +++ b/riscv/insns/paaddu_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16,16,16, { + p_rd = (p_rs1 + p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/paaddu_dw.h b/riscv/insns/paaddu_dw.h new file mode 100644 index 00000000..0ba41340 --- /dev/null +++ b/riscv/insns/paaddu_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32,32,32, { + p_rd = ((reg_t)p_rs1 + (reg_t)p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/paas_dhx.h b/riscv/insns/paas_dhx.h new file mode 100644 index 00000000..43ff1a26 --- /dev/null +++ b/riscv/insns/paas_dhx.h @@ -0,0 +1,6 @@ +require_rv32; +P_CROSS_DW_LOOP(16, { + p_rd = (p_rs1 + p_rs2) >> 1; +}, { + p_rd = (p_rs1 - p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pabd_db.h b/riscv/insns/pabd_db.h new file mode 100644 index 00000000..495f4aa1 --- /dev/null +++ b/riscv/insns/pabd_db.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = (p_rs1 < p_rs2) ? (int8_t)((uint8_t)p_rs2 - (uint8_t)p_rs1) + : (int8_t)((uint8_t)p_rs1 - (uint8_t)p_rs2); +}) \ No newline at end of file diff --git a/riscv/insns/pabd_dh.h b/riscv/insns/pabd_dh.h new file mode 100644 index 00000000..035de401 --- /dev/null +++ b/riscv/insns/pabd_dh.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = (p_rs1 < p_rs2) ? (int16_t)((uint16_t)p_rs2 - (uint16_t)p_rs1) + : (int16_t)((uint16_t)p_rs1 - (uint16_t)p_rs2); +}) diff --git a/riscv/insns/pabdu_db.h b/riscv/insns/pabdu_db.h new file mode 100644 index 00000000..a60eef91 --- /dev/null +++ b/riscv/insns/pabdu_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8, 8, 8, { + p_rd = (p_rs1 < p_rs2) ? p_rs2 - p_rs1 : p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pabdu_dh.h b/riscv/insns/pabdu_dh.h new file mode 100644 index 00000000..6bff1079 --- /dev/null +++ b/riscv/insns/pabdu_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16, 16, 16, { + p_rd = (p_rs1 < p_rs2) ? p_rs2 - p_rs1 : p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/padd_db.h b/riscv/insns/padd_db.h new file mode 100644 index 00000000..6f0ae17e --- /dev/null +++ b/riscv/insns/padd_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/padd_dbs.h b/riscv/insns/padd_dbs.h new file mode 100644 index 00000000..9fc77320 --- /dev/null +++ b/riscv/insns/padd_dbs.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(8, 8, { + p_rd = p_rs1 + P_FIELD(RS2, 0, 8); +}) \ No newline at end of file diff --git a/riscv/insns/padd_dh.h b/riscv/insns/padd_dh.h new file mode 100644 index 00000000..eec465cc --- /dev/null +++ b/riscv/insns/padd_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/padd_dhs.h b/riscv/insns/padd_dhs.h new file mode 100644 index 00000000..c268c755 --- /dev/null +++ b/riscv/insns/padd_dhs.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = p_rs1 + P_FIELD(RS2, 0, 16); +}) \ No newline at end of file diff --git a/riscv/insns/padd_dw.h b/riscv/insns/padd_dw.h new file mode 100644 index 00000000..9bf943db --- /dev/null +++ b/riscv/insns/padd_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/padd_dws.h b/riscv/insns/padd_dws.h new file mode 100644 index 00000000..58f1dd47 --- /dev/null +++ b/riscv/insns/padd_dws.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = p_rs1 + P_FIELD(RS2, 0, 32); +}) \ No newline at end of file diff --git a/riscv/insns/pas_dhx.h b/riscv/insns/pas_dhx.h new file mode 100644 index 00000000..3c74af3b --- /dev/null +++ b/riscv/insns/pas_dhx.h @@ -0,0 +1,6 @@ +require_rv32; +P_CROSS_DW_LOOP(16, { + p_rd = p_rs1 + p_rs2; +}, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pasa_dhx.h b/riscv/insns/pasa_dhx.h new file mode 100644 index 00000000..253c9c5b --- /dev/null +++ b/riscv/insns/pasa_dhx.h @@ -0,0 +1,6 @@ +require_rv32; +P_CROSS_DW_LOOP(16, { + p_rd = (p_rs1 - p_rs2) >> 1; +}, { + p_rd = (p_rs1 + p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pasub_db.h b/riscv/insns/pasub_db.h new file mode 100644 index 00000000..b2f4674e --- /dev/null +++ b/riscv/insns/pasub_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8,8,8, { + p_rd = (p_rs1 - p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pasub_dh.h b/riscv/insns/pasub_dh.h new file mode 100644 index 00000000..72fbf04d --- /dev/null +++ b/riscv/insns/pasub_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16,16,16, { + p_rd = (p_rs1 - p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pasub_dw.h b/riscv/insns/pasub_dw.h new file mode 100644 index 00000000..4305989f --- /dev/null +++ b/riscv/insns/pasub_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32,32,32, { + p_rd = ((sreg_t)p_rs1 - (sreg_t)p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pasubu_db.h b/riscv/insns/pasubu_db.h new file mode 100644 index 00000000..cafdcd2e --- /dev/null +++ b/riscv/insns/pasubu_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8,8,8, { + p_rd = (p_rs1 - p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pasubu_dh.h b/riscv/insns/pasubu_dh.h new file mode 100644 index 00000000..b6d1bff3 --- /dev/null +++ b/riscv/insns/pasubu_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16,16,16, { + p_rd = (p_rs1 - p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pasubu_dw.h b/riscv/insns/pasubu_dw.h new file mode 100644 index 00000000..415fc7f9 --- /dev/null +++ b/riscv/insns/pasubu_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32,32,32, { + p_rd = ((reg_t)p_rs1 - (reg_t)p_rs2) >> 1; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wadd_h.h b/riscv/insns/pm2wadd_h.h new file mode 100644 index 00000000..be756fb7 --- /dev/null +++ b/riscv/insns/pm2wadd_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_LOOP(32, 16, false, false, { + p_res += sext32(p_rs1) * sext32(p_rs2); +}) \ No newline at end of file diff --git a/riscv/insns/pm2wadd_hx.h b/riscv/insns/pm2wadd_hx.h new file mode 100644 index 00000000..dd000bbf --- /dev/null +++ b/riscv/insns/pm2wadd_hx.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_CROSS_LOOP(32, 16, false, false, { + p_res += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wadda_h.h b/riscv/insns/pm2wadda_h.h new file mode 100644 index 00000000..a0a1bb65 --- /dev/null +++ b/riscv/insns/pm2wadda_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_LOOP(32, 16, true, false, { + p_res += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wadda_hx.h b/riscv/insns/pm2wadda_hx.h new file mode 100644 index 00000000..8ef3e387 --- /dev/null +++ b/riscv/insns/pm2wadda_hx.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_CROSS_LOOP(32, 16, true, false, { + p_res += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2waddasu_h.h b/riscv/insns/pm2waddasu_h.h new file mode 100644 index 00000000..b525feb4 --- /dev/null +++ b/riscv/insns/pm2waddasu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_SULOOP(32, 16, true, false, { + p_res += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2waddau_h.h b/riscv/insns/pm2waddau_h.h new file mode 100644 index 00000000..5e67a7a5 --- /dev/null +++ b/riscv/insns/pm2waddau_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_ULOOP(32, 16, true, false, { + p_res += (uint32_t)p_rs1 * (uint32_t)p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2waddsu_h.h b/riscv/insns/pm2waddsu_h.h new file mode 100644 index 00000000..8c845953 --- /dev/null +++ b/riscv/insns/pm2waddsu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_SULOOP(32, 16, false, false, { + p_res += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2waddu_h.h b/riscv/insns/pm2waddu_h.h new file mode 100644 index 00000000..30a4ad1f --- /dev/null +++ b/riscv/insns/pm2waddu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_REDUCTION_ULOOP(32, 16, false, false, { + p_res += (uint32_t)p_rs1 * (uint32_t)p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wsub_h.h b/riscv/insns/pm2wsub_h.h new file mode 100644 index 00000000..903cbe30 --- /dev/null +++ b/riscv/insns/pm2wsub_h.h @@ -0,0 +1,7 @@ +require_rv32; +P_WIDEN_REDUCTION_LOOP(32, 16, false, false, { + if (j & 1) + p_res += p_rs1 * p_rs2; + else + p_res -= p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wsub_hx.h b/riscv/insns/pm2wsub_hx.h new file mode 100644 index 00000000..81da3652 --- /dev/null +++ b/riscv/insns/pm2wsub_hx.h @@ -0,0 +1,7 @@ +require_rv32; +P_WIDEN_REDUCTION_CROSS_LOOP(32, 16, false, false, { + if (j & 1) + p_res += p_rs1 * p_rs2; + else + p_res -= p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wsuba_h.h b/riscv/insns/pm2wsuba_h.h new file mode 100644 index 00000000..600b77e2 --- /dev/null +++ b/riscv/insns/pm2wsuba_h.h @@ -0,0 +1,7 @@ +require_rv32; +P_WIDEN_REDUCTION_LOOP(32, 16, true, false, { + if (j & 1) + p_res += p_rs1 * p_rs2; + else + p_res -= p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pm2wsuba_hx.h b/riscv/insns/pm2wsuba_hx.h new file mode 100644 index 00000000..58a99d03 --- /dev/null +++ b/riscv/insns/pm2wsuba_hx.h @@ -0,0 +1,7 @@ +require_rv32; +P_WIDEN_REDUCTION_CROSS_LOOP(32, 16, true, false, { + if (j & 1) + p_res += p_rs1 * p_rs2; + else + p_res -= p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmax_db.h b/riscv/insns/pmax_db.h new file mode 100644 index 00000000..83c08cbb --- /dev/null +++ b/riscv/insns/pmax_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = (p_rs1 > p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmax_dh.h b/riscv/insns/pmax_dh.h new file mode 100644 index 00000000..02b641aa --- /dev/null +++ b/riscv/insns/pmax_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = (p_rs1 > p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmax_dw.h b/riscv/insns/pmax_dw.h new file mode 100644 index 00000000..e9df1181 --- /dev/null +++ b/riscv/insns/pmax_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = (p_rs1 > p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmaxu_db.h b/riscv/insns/pmaxu_db.h new file mode 100644 index 00000000..43ad8537 --- /dev/null +++ b/riscv/insns/pmaxu_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8, 8, 8, { + p_rd = (p_rs1 > p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmaxu_dh.h b/riscv/insns/pmaxu_dh.h new file mode 100644 index 00000000..7d04b443 --- /dev/null +++ b/riscv/insns/pmaxu_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16, 16, 16, { + p_rd = (p_rs1 > p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmaxu_dw.h b/riscv/insns/pmaxu_dw.h new file mode 100644 index 00000000..5c3586d4 --- /dev/null +++ b/riscv/insns/pmaxu_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32, 32, 32, { + p_rd = (p_rs1 > p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmin_db.h b/riscv/insns/pmin_db.h new file mode 100644 index 00000000..7da8293a --- /dev/null +++ b/riscv/insns/pmin_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = (p_rs1 < p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmin_dh.h b/riscv/insns/pmin_dh.h new file mode 100644 index 00000000..709f9d94 --- /dev/null +++ b/riscv/insns/pmin_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = (p_rs1 < p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmin_dw.h b/riscv/insns/pmin_dw.h new file mode 100644 index 00000000..ba14e5ac --- /dev/null +++ b/riscv/insns/pmin_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = (p_rs1 < p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pminu_db.h b/riscv/insns/pminu_db.h new file mode 100644 index 00000000..fd4a3799 --- /dev/null +++ b/riscv/insns/pminu_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8, 8, 8, { + p_rd = (p_rs1 < p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pminu_dh.h b/riscv/insns/pminu_dh.h new file mode 100644 index 00000000..8932cf0a --- /dev/null +++ b/riscv/insns/pminu_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16, 16, 16, { + p_rd = (p_rs1 < p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pminu_dw.h b/riscv/insns/pminu_dw.h new file mode 100644 index 00000000..051fcb94 --- /dev/null +++ b/riscv/insns/pminu_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32, 32, 32, { + p_rd = (p_rs1 < p_rs2) ? p_rs1 : p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pmqrwacc_h.h b/riscv/insns/pmqrwacc_h.h new file mode 100644 index 00000000..41ab71ea --- /dev/null +++ b/riscv/insns/pmqrwacc_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd += (p_rs1 * p_rs2 + 0x4000) >> 15; +}) \ No newline at end of file diff --git a/riscv/insns/pmqwacc_h.h b/riscv/insns/pmqwacc_h.h new file mode 100644 index 00000000..e6629270 --- /dev/null +++ b/riscv/insns/pmqwacc_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd += (p_rs1 * p_rs2) >> 15; +}) \ No newline at end of file diff --git a/riscv/insns/pmseq_db.h b/riscv/insns/pmseq_db.h new file mode 100644 index 00000000..5013861a --- /dev/null +++ b/riscv/insns/pmseq_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = (p_rs1 == p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmseq_dh.h b/riscv/insns/pmseq_dh.h new file mode 100644 index 00000000..9abeae08 --- /dev/null +++ b/riscv/insns/pmseq_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = (p_rs1 == p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmseq_dw.h b/riscv/insns/pmseq_dw.h new file mode 100644 index 00000000..920020fd --- /dev/null +++ b/riscv/insns/pmseq_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = (p_rs1 == p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmslt_db.h b/riscv/insns/pmslt_db.h new file mode 100644 index 00000000..807f65b5 --- /dev/null +++ b/riscv/insns/pmslt_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = (p_rs1 < p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmslt_dh.h b/riscv/insns/pmslt_dh.h new file mode 100644 index 00000000..6d6b997b --- /dev/null +++ b/riscv/insns/pmslt_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = (p_rs1 < p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmslt_dw.h b/riscv/insns/pmslt_dw.h new file mode 100644 index 00000000..889a368f --- /dev/null +++ b/riscv/insns/pmslt_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = (p_rs1 < p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmsltu_db.h b/riscv/insns/pmsltu_db.h new file mode 100644 index 00000000..e03d7e3a --- /dev/null +++ b/riscv/insns/pmsltu_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8 ,8 ,8, { + p_rd = (p_rs1 < p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmsltu_dh.h b/riscv/insns/pmsltu_dh.h new file mode 100644 index 00000000..84f3def2 --- /dev/null +++ b/riscv/insns/pmsltu_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16, 16, 16, { + p_rd = (p_rs1 < p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pmsltu_dw.h b/riscv/insns/pmsltu_dw.h new file mode 100644 index 00000000..cc397ef9 --- /dev/null +++ b/riscv/insns/pmsltu_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32, 32, 32, { + p_rd = (p_rs1 < p_rs2) ? -1 : 0; +}) \ No newline at end of file diff --git a/riscv/insns/pnclip_bs.h b/riscv/insns/pnclip_bs.h new file mode 100644 index 00000000..267aac7c --- /dev/null +++ b/riscv/insns/pnclip_bs.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + p_rd = P_SAT(8, p_rs1 >> (P_FIELD(RS2, 0, 8) & 0xF)); +}) \ No newline at end of file diff --git a/riscv/insns/pnclip_hs.h b/riscv/insns/pnclip_hs.h new file mode 100644 index 00000000..c0adb127 --- /dev/null +++ b/riscv/insns/pnclip_hs.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + p_rd = P_SAT(16, p_rs1 >> (P_FIELD(RS2, 0, 16) & 0X1F)); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipi_b.h b/riscv/insns/pnclipi_b.h new file mode 100644 index 00000000..d18b3f4e --- /dev/null +++ b/riscv/insns/pnclipi_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + p_rd = P_SAT(8, p_rs1 >> insn.shamth()); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipi_h.h b/riscv/insns/pnclipi_h.h new file mode 100644 index 00000000..470afa04 --- /dev/null +++ b/riscv/insns/pnclipi_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + p_rd = P_SAT(16, p_rs1 >> insn.shamtw()); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipiu_b.h b/riscv/insns/pnclipiu_b.h new file mode 100644 index 00000000..062ea472 --- /dev/null +++ b/riscv/insns/pnclipiu_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(8, 16, { + p_rd = P_USAT(8, p_rs1 >> insn.shamth()); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipiu_h.h b/riscv/insns/pnclipiu_h.h new file mode 100644 index 00000000..efd46b03 --- /dev/null +++ b/riscv/insns/pnclipiu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(16, 32, { + p_rd = P_USAT(16, (p_rs1 >> insn.shamtw())); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipr_bs.h b/riscv/insns/pnclipr_bs.h new file mode 100644 index 00000000..0d668354 --- /dev/null +++ b/riscv/insns/pnclipr_bs.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + uint16_t shamt = P_FIELD(RS2, 0, 8) & 0xF; + sreg_t result; + if (shamt == 0) { + result = p_rs1; + } else { + sreg_t shifted = (sreg_t)p_rs1 >> shamt; + sreg_t roundbit = ((sreg_t)p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_SAT(8, result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipr_hs.h b/riscv/insns/pnclipr_hs.h new file mode 100644 index 00000000..3755a641 --- /dev/null +++ b/riscv/insns/pnclipr_hs.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + uint32_t shamt = P_FIELD(RS2, 0, 16) & 0x1F; + sreg_t result; + if (shamt == 0) { + result = p_rs1; + } else { + sreg_t shifted = (sreg_t)p_rs1 >> shamt; + sreg_t roundbit = ((sreg_t)p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_SAT(16, result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipri_b.h b/riscv/insns/pnclipri_b.h new file mode 100644 index 00000000..e2e21b63 --- /dev/null +++ b/riscv/insns/pnclipri_b.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + uint16_t shamt = insn.shamth(); + sreg_t result; + if (shamt == 0) { + result = p_rs1; + } else { + sreg_t shifted = (sreg_t)p_rs1 >> shamt; + sreg_t roundbit = ((sreg_t)p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_SAT(8, result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipri_h.h b/riscv/insns/pnclipri_h.h new file mode 100644 index 00000000..67bdcad9 --- /dev/null +++ b/riscv/insns/pnclipri_h.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + uint32_t shamt = insn.shamtw(); + sreg_t result; + if (shamt == 0) { + result = p_rs1; + } else { + sreg_t shifted = (sreg_t)p_rs1 >> shamt; + sreg_t roundbit = ((sreg_t)p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_SAT(16, result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipriu_b.h b/riscv/insns/pnclipriu_b.h new file mode 100644 index 00000000..bb55a149 --- /dev/null +++ b/riscv/insns/pnclipriu_b.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(8, 16, { + uint32_t shamt = insn.shamth(); + uint32_t result; + if (shamt == 0) { + result = p_rs1; + } else { + uint32_t shifted = p_rs1 >> shamt; + uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_USAT_FULL(8, (sreg_t)result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipriu_h.h b/riscv/insns/pnclipriu_h.h new file mode 100644 index 00000000..4d2dbd9b --- /dev/null +++ b/riscv/insns/pnclipriu_h.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(16, 32, { + uint32_t shamt = insn.shamtw(); + uint32_t result; + if (shamt == 0) { + result = p_rs1; + } else { + uint32_t shifted = p_rs1 >> shamt; + uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_USAT_FULL(16, (sreg_t)result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipru_bs.h b/riscv/insns/pnclipru_bs.h new file mode 100644 index 00000000..25921dc6 --- /dev/null +++ b/riscv/insns/pnclipru_bs.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(8, 16, { + uint32_t shamt = P_UFIELD(RS2, 0, 8) & 0xF; + uint32_t result; + if (shamt == 0) { + result = p_rs1; + } else { + uint32_t shifted = p_rs1 >> shamt; + uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_USAT_FULL(8, (sreg_t)result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipru_hs.h b/riscv/insns/pnclipru_hs.h new file mode 100644 index 00000000..d4f82e88 --- /dev/null +++ b/riscv/insns/pnclipru_hs.h @@ -0,0 +1,13 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(16, 32, { + uint32_t shamt = P_UFIELD(RS2, 0, 16) & 0x1F; + uint32_t result; + if (shamt == 0) { + result = p_rs1; + } else { + uint32_t shifted = p_rs1 >> shamt; + uint32_t roundbit = (p_rs1 >> (shamt - 1)) & 1; + result = shifted + roundbit; + } + p_rd = P_USAT_FULL(16, (sreg_t)result); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipu_bs.h b/riscv/insns/pnclipu_bs.h new file mode 100644 index 00000000..af10838c --- /dev/null +++ b/riscv/insns/pnclipu_bs.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(8, 16, { + p_rd = P_USAT_FULL(8, (sreg_t)(p_rs1 >> (P_UFIELD(RS2, 0, 8) & 0xF))); +}) \ No newline at end of file diff --git a/riscv/insns/pnclipu_hs.h b/riscv/insns/pnclipu_hs.h new file mode 100644 index 00000000..377bd407 --- /dev/null +++ b/riscv/insns/pnclipu_hs.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(16, 32, { + p_rd = P_USAT_FULL(16, (sreg_t)(p_rs1 >> (P_UFIELD(RS2, 0, 16) & 0X1F))); +}) \ No newline at end of file diff --git a/riscv/insns/pnsra_bs.h b/riscv/insns/pnsra_bs.h new file mode 100644 index 00000000..6a6ad366 --- /dev/null +++ b/riscv/insns/pnsra_bs.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + p_rd = p_rs1 >> (P_FIELD(RS2, 0, 8) & 0xF); +}) \ No newline at end of file diff --git a/riscv/insns/pnsra_hs.h b/riscv/insns/pnsra_hs.h new file mode 100644 index 00000000..0b6ee714 --- /dev/null +++ b/riscv/insns/pnsra_hs.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + p_rd = p_rs1 >> (P_FIELD(RS2, 0, 16) & 0x1F); +}) \ No newline at end of file diff --git a/riscv/insns/pnsrai_b.h b/riscv/insns/pnsrai_b.h new file mode 100644 index 00000000..001bb3b3 --- /dev/null +++ b/riscv/insns/pnsrai_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + p_rd = p_rs1 >> insn.shamth(); +}) \ No newline at end of file diff --git a/riscv/insns/pnsrai_h.h b/riscv/insns/pnsrai_h.h new file mode 100644 index 00000000..d673a763 --- /dev/null +++ b/riscv/insns/pnsrai_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + p_rd = p_rs1 >> insn.shamtw(); +}) \ No newline at end of file diff --git a/riscv/insns/pnsrar_bs.h b/riscv/insns/pnsrar_bs.h new file mode 100644 index 00000000..8b9291a9 --- /dev/null +++ b/riscv/insns/pnsrar_bs.h @@ -0,0 +1,12 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + uint32_t shamt = P_FIELD(RS2, 0, 8) & 0xF; + if (shamt != 0) { + sreg_t val = (sreg_t)p_rs1; + sreg_t shifted = val >> shamt; + sreg_t roundbit = (val >> (shamt - 1)) & 1; + p_rd = (shifted + roundbit) & 0xFF; + } else { + p_rd = p_rs1 & 0xFF; + } +}) \ No newline at end of file diff --git a/riscv/insns/pnsrar_hs.h b/riscv/insns/pnsrar_hs.h new file mode 100644 index 00000000..602bdd57 --- /dev/null +++ b/riscv/insns/pnsrar_hs.h @@ -0,0 +1,12 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + uint32_t shamt = P_FIELD(RS2, 0, 16) & 0x1F; + if (shamt != 0) { + sreg_t val = (sreg_t)p_rs1; + sreg_t shifted = val >> shamt; + sreg_t roundbit = (val >> (shamt - 1)) & 1; + p_rd = (shifted + roundbit) & 0xFFFF; + } else { + p_rd = p_rs1 & 0xFFFF; + } +}) \ No newline at end of file diff --git a/riscv/insns/pnsrari_b.h b/riscv/insns/pnsrari_b.h new file mode 100644 index 00000000..7ca82f5b --- /dev/null +++ b/riscv/insns/pnsrari_b.h @@ -0,0 +1,12 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(8, 16, { + uint32_t shamt = insn.shamth(); + if (shamt != 0) { + sreg_t val = (sreg_t)p_rs1; + sreg_t shifted = val >> shamt; + sreg_t roundbit = (val >> (shamt - 1)) & 1; + p_rd = (shifted + roundbit) & 0xFF; + } else { + p_rd = p_rs1 & 0xFF; + } +}) \ No newline at end of file diff --git a/riscv/insns/pnsrari_h.h b/riscv/insns/pnsrari_h.h new file mode 100644 index 00000000..84136826 --- /dev/null +++ b/riscv/insns/pnsrari_h.h @@ -0,0 +1,12 @@ +require_rv32; +P_NARROW_RD_RS1_LOOP(16, 32, { + uint32_t shamt = insn.shamtw(); + if (shamt != 0) { + sreg_t val = (sreg_t)p_rs1; + sreg_t shifted = val >> shamt; + sreg_t roundbit = (val >> (shamt - 1)) & 1; + p_rd = (shifted + roundbit) & 0xFFFF; + } else { + p_rd = p_rs1 & 0xFFFF; + } +}) \ No newline at end of file diff --git a/riscv/insns/pnsrl_bs.h b/riscv/insns/pnsrl_bs.h new file mode 100644 index 00000000..244bd6c9 --- /dev/null +++ b/riscv/insns/pnsrl_bs.h @@ -0,0 +1,5 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(8, 16, { + uint8_t shamt = (uint8_t)(P_UFIELD(RS2, 0, 8) & 0xF); + p_rd = (uint8_t)((uint16_t)p_rs1 >> shamt); +}) diff --git a/riscv/insns/pnsrl_hs.h b/riscv/insns/pnsrl_hs.h new file mode 100644 index 00000000..42d28f5a --- /dev/null +++ b/riscv/insns/pnsrl_hs.h @@ -0,0 +1,5 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(16, 32, { + uint16_t shamt = (uint16_t)(P_UFIELD(RS2, 0, 16) & 0x1F); + p_rd = (uint16_t)((uint32_t)p_rs1 >> shamt); +}) \ No newline at end of file diff --git a/riscv/insns/pnsrli_b.h b/riscv/insns/pnsrli_b.h new file mode 100644 index 00000000..55f19c6f --- /dev/null +++ b/riscv/insns/pnsrli_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(8, 16, { + p_rd = (uint8_t)((uint16_t)p_rs1 >> insn.shamth()); +}) \ No newline at end of file diff --git a/riscv/insns/pnsrli_h.h b/riscv/insns/pnsrli_h.h new file mode 100644 index 00000000..80f17245 --- /dev/null +++ b/riscv/insns/pnsrli_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_NARROW_RD_RS1_ULOOP(16, 32, { + p_rd = (uint16_t)((uint32_t)p_rs1 >> insn.shamtw()); +}) \ No newline at end of file diff --git a/riscv/insns/ppaire_db.h b/riscv/insns/ppaire_db.h new file mode 100644 index 00000000..64f7c1c0 --- /dev/null +++ b/riscv/insns/ppaire_db.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(8, 0, 0); \ No newline at end of file diff --git a/riscv/insns/ppaire_dh.h b/riscv/insns/ppaire_dh.h new file mode 100644 index 00000000..ada431d1 --- /dev/null +++ b/riscv/insns/ppaire_dh.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(16, 0, 0); \ No newline at end of file diff --git a/riscv/insns/ppaireo_db.h b/riscv/insns/ppaireo_db.h new file mode 100644 index 00000000..4b6e1158 --- /dev/null +++ b/riscv/insns/ppaireo_db.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(8, 0, 1); \ No newline at end of file diff --git a/riscv/insns/ppaireo_dh.h b/riscv/insns/ppaireo_dh.h new file mode 100644 index 00000000..46ef708d --- /dev/null +++ b/riscv/insns/ppaireo_dh.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(16, 0, 1); \ No newline at end of file diff --git a/riscv/insns/ppairo_db.h b/riscv/insns/ppairo_db.h new file mode 100644 index 00000000..ad04f358 --- /dev/null +++ b/riscv/insns/ppairo_db.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(8, 1, 1); \ No newline at end of file diff --git a/riscv/insns/ppairo_dh.h b/riscv/insns/ppairo_dh.h new file mode 100644 index 00000000..d9291d87 --- /dev/null +++ b/riscv/insns/ppairo_dh.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(16, 1, 1); \ No newline at end of file diff --git a/riscv/insns/ppairoe_db.h b/riscv/insns/ppairoe_db.h new file mode 100644 index 00000000..61a334d7 --- /dev/null +++ b/riscv/insns/ppairoe_db.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(8, 1, 0); \ No newline at end of file diff --git a/riscv/insns/ppairoe_dh.h b/riscv/insns/ppairoe_dh.h new file mode 100644 index 00000000..f9467db8 --- /dev/null +++ b/riscv/insns/ppairoe_dh.h @@ -0,0 +1,2 @@ +require_rv32; +P_PACK_DW(16, 1, 0); \ No newline at end of file diff --git a/riscv/insns/predsum_dbs.h b/riscv/insns/predsum_dbs.h new file mode 100644 index 00000000..0f8afe42 --- /dev/null +++ b/riscv/insns/predsum_dbs.h @@ -0,0 +1,5 @@ +require_rv32; +reg_t rd_tmp = RS2; +P_RS1_DW_LOOP(8, { + rd_tmp += sext_xlen(p_rs1); +}) \ No newline at end of file diff --git a/riscv/insns/predsum_dhs.h b/riscv/insns/predsum_dhs.h new file mode 100644 index 00000000..4c8e012c --- /dev/null +++ b/riscv/insns/predsum_dhs.h @@ -0,0 +1,5 @@ +require_rv32; +reg_t rd_tmp = RS2; +P_RS1_DW_LOOP(16, { + rd_tmp += sext_xlen(p_rs1); +}) \ No newline at end of file diff --git a/riscv/insns/predsumu_dbs.h b/riscv/insns/predsumu_dbs.h new file mode 100644 index 00000000..26cb2d39 --- /dev/null +++ b/riscv/insns/predsumu_dbs.h @@ -0,0 +1,5 @@ +require_rv32; +reg_t rd_tmp = RS2; +P_RS1_DW_ULOOP(8, { + rd_tmp += zext_xlen(p_rs1); +}) \ No newline at end of file diff --git a/riscv/insns/predsumu_dhs.h b/riscv/insns/predsumu_dhs.h new file mode 100644 index 00000000..a9393eeb --- /dev/null +++ b/riscv/insns/predsumu_dhs.h @@ -0,0 +1,5 @@ +require_rv32; +reg_t rd_tmp = RS2; +P_RS1_DW_ULOOP(16, { + rd_tmp += zext_xlen(p_rs1); +}) \ No newline at end of file diff --git a/riscv/insns/psa_dhx.h b/riscv/insns/psa_dhx.h new file mode 100644 index 00000000..f7b30af5 --- /dev/null +++ b/riscv/insns/psa_dhx.h @@ -0,0 +1,6 @@ +require_rv32; +P_CROSS_DW_LOOP(16, { + p_rd = p_rs1 - p_rs2; +}, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/psabs_db.h b/riscv/insns/psabs_db.h new file mode 100644 index 00000000..5efe61d3 --- /dev/null +++ b/riscv/insns/psabs_db.h @@ -0,0 +1,6 @@ +require_rv32; +P_RD_RS1_DW_LOOP(8, 8, { + sreg_t abs_val = p_rs1 > 0 ? p_rs1 : -sext32(p_rs1); + p_rd = P_SAT(8, abs_val); + if (p_rd != abs_val) P.VU.vxsat->write(1); +}) \ No newline at end of file diff --git a/riscv/insns/psabs_dh.h b/riscv/insns/psabs_dh.h new file mode 100644 index 00000000..13411c9e --- /dev/null +++ b/riscv/insns/psabs_dh.h @@ -0,0 +1,6 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + sreg_t abs_val = p_rs1 > 0 ? p_rs1 : -sext32(p_rs1); + p_rd = P_SAT(16, abs_val); + if (p_rd != abs_val) P.VU.vxsat->write(1); +}) \ No newline at end of file diff --git a/riscv/insns/psadd_db.h b/riscv/insns/psadd_db.h new file mode 100644 index 00000000..3c297868 --- /dev/null +++ b/riscv/insns/psadd_db.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8,8,8, { + bool sat = false; + p_rd = (sat_add(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psadd_dh.h b/riscv/insns/psadd_dh.h new file mode 100644 index 00000000..bd14a581 --- /dev/null +++ b/riscv/insns/psadd_dh.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16,16,16, { + bool sat = false; + p_rd = (sat_add(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psadd_dw.h b/riscv/insns/psadd_dw.h new file mode 100644 index 00000000..5ec3466d --- /dev/null +++ b/riscv/insns/psadd_dw.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32,32,32, { + bool sat = false; + p_rd = (sat_add(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psaddu_db.h b/riscv/insns/psaddu_db.h new file mode 100644 index 00000000..a181f24a --- /dev/null +++ b/riscv/insns/psaddu_db.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8,8,8, { + bool sat = false; + p_rd = (sat_addu(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psaddu_dh.h b/riscv/insns/psaddu_dh.h new file mode 100644 index 00000000..035d91fc --- /dev/null +++ b/riscv/insns/psaddu_dh.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16,16,16, { + bool sat = false; + p_rd = (sat_addu(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psaddu_dw.h b/riscv/insns/psaddu_dw.h new file mode 100644 index 00000000..ebc4d8bb --- /dev/null +++ b/riscv/insns/psaddu_dw.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32,32,32, { + bool sat = false; + p_rd = (sat_addu(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psas_dhx.h b/riscv/insns/psas_dhx.h new file mode 100644 index 00000000..0757ba6d --- /dev/null +++ b/riscv/insns/psas_dhx.h @@ -0,0 +1,8 @@ +require_rv32; +P_CROSS_DW_ULOOP(16, { + bool sat = false; + p_rd = (sat_add(p_rs1, p_rs2, sat)); +}, { + bool sat = false; + p_rd = (sat_sub(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psati_dh.h b/riscv/insns/psati_dh.h new file mode 100644 index 00000000..f95fe6e5 --- /dev/null +++ b/riscv/insns/psati_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = P_SAT(insn.shamth() + 1, p_rs1); +}) \ No newline at end of file diff --git a/riscv/insns/psati_dw.h b/riscv/insns/psati_dw.h new file mode 100644 index 00000000..f49c44a0 --- /dev/null +++ b/riscv/insns/psati_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = P_SAT(insn.shamtw() + 1, p_rs1); +}) \ No newline at end of file diff --git a/riscv/insns/psext_dh_b.h b/riscv/insns/psext_dh_b.h new file mode 100644 index 00000000..651246f9 --- /dev/null +++ b/riscv/insns/psext_dh_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = (int16_t)(int8_t)p_rs1; +}) \ No newline at end of file diff --git a/riscv/insns/psext_dw_b.h b/riscv/insns/psext_dw_b.h new file mode 100644 index 00000000..996e00e0 --- /dev/null +++ b/riscv/insns/psext_dw_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = (int32_t)(int8_t)p_rs1; +}) \ No newline at end of file diff --git a/riscv/insns/psext_dw_h.h b/riscv/insns/psext_dw_h.h new file mode 100644 index 00000000..e94d83bf --- /dev/null +++ b/riscv/insns/psext_dw_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = (int32_t)(int16_t)p_rs1; +}) \ No newline at end of file diff --git a/riscv/insns/psh1add_dh.h b/riscv/insns/psh1add_dh.h new file mode 100644 index 00000000..33787153 --- /dev/null +++ b/riscv/insns/psh1add_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = (p_rs1 << 1) + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/psh1add_dw.h b/riscv/insns/psh1add_dw.h new file mode 100644 index 00000000..e143e4b4 --- /dev/null +++ b/riscv/insns/psh1add_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = (p_rs1 << 1) + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/psll_dbs.h b/riscv/insns/psll_dbs.h new file mode 100644 index 00000000..a5dea881 --- /dev/null +++ b/riscv/insns/psll_dbs.h @@ -0,0 +1,7 @@ +require_rv32; +P_RD_RS1_DW_LOOP(8, 8, { + uint8_t m = P_FIELD(RS2, 0, 8); + const uint64_t maskN = 0xFFull; + if (m >= 8) p_rd = 0; + else p_rd = (uint8_t)((p_rs1 << m) & maskN); +}) \ No newline at end of file diff --git a/riscv/insns/psll_dhs.h b/riscv/insns/psll_dhs.h new file mode 100644 index 00000000..33e31738 --- /dev/null +++ b/riscv/insns/psll_dhs.h @@ -0,0 +1,7 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + uint8_t m = P_FIELD(RS2, 0, 8); + const uint64_t maskN = 0xFFFFull; + if (m >= 16) p_rd = 0; + else p_rd = (uint16_t)((p_rs1 << m) & maskN); +}) \ No newline at end of file diff --git a/riscv/insns/psll_dws.h b/riscv/insns/psll_dws.h new file mode 100644 index 00000000..ec71edbf --- /dev/null +++ b/riscv/insns/psll_dws.h @@ -0,0 +1,7 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + uint8_t m = P_FIELD(RS2, 0, 8); + const uint64_t maskN = 0xFFFFFFFFull; + if (m >= 32) p_rd = 0; + else p_rd = (uint32_t)((p_rs1 << m) & maskN); +}) \ No newline at end of file diff --git a/riscv/insns/pslli_db.h b/riscv/insns/pslli_db.h new file mode 100644 index 00000000..ab35e17c --- /dev/null +++ b/riscv/insns/pslli_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(8, 8, { + p_rd = p_rs1 << insn.shamtb(); +}) \ No newline at end of file diff --git a/riscv/insns/pslli_dh.h b/riscv/insns/pslli_dh.h new file mode 100644 index 00000000..06a0b8af --- /dev/null +++ b/riscv/insns/pslli_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = p_rs1 << insn.shamth(); +}) \ No newline at end of file diff --git a/riscv/insns/pslli_dw.h b/riscv/insns/pslli_dw.h new file mode 100644 index 00000000..2c654498 --- /dev/null +++ b/riscv/insns/pslli_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = p_rs1 << insn.shamtw(); +}) \ No newline at end of file diff --git a/riscv/insns/psra_dbs.h b/riscv/insns/psra_dbs.h new file mode 100644 index 00000000..f68e5488 --- /dev/null +++ b/riscv/insns/psra_dbs.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(8, 8, { + p_rd = p_rs1 >> (RS2 & (8 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/psra_dhs.h b/riscv/insns/psra_dhs.h new file mode 100644 index 00000000..3689c9b1 --- /dev/null +++ b/riscv/insns/psra_dhs.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = p_rs1 >> (RS2 & (16 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/psra_dws.h b/riscv/insns/psra_dws.h new file mode 100644 index 00000000..47ab0d56 --- /dev/null +++ b/riscv/insns/psra_dws.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = p_rs1 >> (RS2 & (32 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/psrai_db.h b/riscv/insns/psrai_db.h new file mode 100644 index 00000000..1949e200 --- /dev/null +++ b/riscv/insns/psrai_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(8, 8, { + p_rd = p_rs1 >> insn.shamtb(); +}) \ No newline at end of file diff --git a/riscv/insns/psrai_dh.h b/riscv/insns/psrai_dh.h new file mode 100644 index 00000000..f2066098 --- /dev/null +++ b/riscv/insns/psrai_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = p_rs1 >> insn.shamth(); +}) \ No newline at end of file diff --git a/riscv/insns/psrai_dw.h b/riscv/insns/psrai_dw.h new file mode 100644 index 00000000..0342780e --- /dev/null +++ b/riscv/insns/psrai_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = p_rs1 >> insn.shamtw(); +}) \ No newline at end of file diff --git a/riscv/insns/psrari_dh.h b/riscv/insns/psrari_dh.h new file mode 100644 index 00000000..4ccc49bd --- /dev/null +++ b/riscv/insns/psrari_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = insn.shamth() ? ((p_rs1 >> insn.shamth()) + ((p_rs1 >> (insn.shamth() - 1)) & 1)) : p_rs1; +}) \ No newline at end of file diff --git a/riscv/insns/psrari_dw.h b/riscv/insns/psrari_dw.h new file mode 100644 index 00000000..c3c66216 --- /dev/null +++ b/riscv/insns/psrari_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = insn.shamtw() ? ((p_rs1 >> insn.shamtw()) + ((p_rs1 >> (insn.shamtw() - 1)) & 1)) : p_rs1; +}) \ No newline at end of file diff --git a/riscv/insns/psrl_dbs.h b/riscv/insns/psrl_dbs.h new file mode 100644 index 00000000..00d6b6d4 --- /dev/null +++ b/riscv/insns/psrl_dbs.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(8, 8, { + p_rd = p_rs1 >> (RS2 & (8 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/psrl_dhs.h b/riscv/insns/psrl_dhs.h new file mode 100644 index 00000000..add4b858 --- /dev/null +++ b/riscv/insns/psrl_dhs.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(16, 16, { + p_rd = p_rs1 >> (RS2 & (16 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/psrl_dws.h b/riscv/insns/psrl_dws.h new file mode 100644 index 00000000..0f102d7e --- /dev/null +++ b/riscv/insns/psrl_dws.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(32, 32, { + p_rd = p_rs1 >> (RS2 & (32 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/psrli_db.h b/riscv/insns/psrli_db.h new file mode 100644 index 00000000..91ef7964 --- /dev/null +++ b/riscv/insns/psrli_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(8, 8, { + p_rd = p_rs1 >> insn.shamtb(); +}) \ No newline at end of file diff --git a/riscv/insns/psrli_dh.h b/riscv/insns/psrli_dh.h new file mode 100644 index 00000000..c67229a5 --- /dev/null +++ b/riscv/insns/psrli_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(16, 16, { + p_rd = p_rs1 >> insn.shamth(); +}) \ No newline at end of file diff --git a/riscv/insns/psrli_dw.h b/riscv/insns/psrli_dw.h new file mode 100644 index 00000000..9702ff8c --- /dev/null +++ b/riscv/insns/psrli_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(32, 32, { + p_rd = p_rs1 >> insn.shamtw(); +}) \ No newline at end of file diff --git a/riscv/insns/pssa_dhx.h b/riscv/insns/pssa_dhx.h new file mode 100644 index 00000000..4790270c --- /dev/null +++ b/riscv/insns/pssa_dhx.h @@ -0,0 +1,8 @@ +require_rv32; +P_CROSS_DW_ULOOP(16, { + bool sat = false; + p_rd = (sat_sub(p_rs1, p_rs2, sat)); +}, { + bool sat = false; + p_rd = (sat_add(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/pssh1sadd_dh.h b/riscv/insns/pssh1sadd_dh.h new file mode 100644 index 00000000..4939978d --- /dev/null +++ b/riscv/insns/pssh1sadd_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = P_SAT(16, P_SAT(16, p_rs1 << 1) + p_rs2); +}) \ No newline at end of file diff --git a/riscv/insns/pssh1sadd_dw.h b/riscv/insns/pssh1sadd_dw.h new file mode 100644 index 00000000..4ae54950 --- /dev/null +++ b/riscv/insns/pssh1sadd_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = P_SAT(32, P_SAT(32, (sreg_t)p_rs1 << 1) + (sreg_t)p_rs2); +}) \ No newline at end of file diff --git a/riscv/insns/pssha_dhs.h b/riscv/insns/pssha_dhs.h new file mode 100644 index 00000000..9489ced7 --- /dev/null +++ b/riscv/insns/pssha_dhs.h @@ -0,0 +1,44 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + uint64_t bits_SMIN = (uint64_t{1} << (16 - 1)); + uint64_t bits_SMAX = ((uint64_t{1} << (16 - 1)) - 1); + bool ov = false; + int8_t m = P_FIELD(RS2, 0, 8); + int8_t rev = static_cast(m); + rev = (m < 0) ? static_cast(~m + 1u) : m; + uint64_t mask = ((uint64_t{1} << 16) - 1); + p_rs1 &= mask; + if(m < 0){ + unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; + uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; + + if(sh >= 16) p_rd = (uint16_t)(sign ? mask : 0u); + else{ + uint64_t shifted = (p_rs1 >> sh); + uint64_t fill = (~uint64_t{0}) << (16 - sh); + shifted |= fill; + p_rd = (uint16_t)(shifted & mask); + } + } + else{ + if(rev==0) p_rd = (uint16_t)p_rs1; + else if(rev >= 16){ + if(p_rs1==0) p_rd = 0; + else{ + ov = true; + uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; + p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); + } + } + else{ + uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; + uint64_t top = (p_rs1 >> (16 - rev)); + uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; + ov = (top != need); + if(ov) + p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); + else + p_rd = (uint16_t)((p_rs1 << rev) & mask); + } + } +}) \ No newline at end of file diff --git a/riscv/insns/pssha_dws.h b/riscv/insns/pssha_dws.h new file mode 100644 index 00000000..5a43e20d --- /dev/null +++ b/riscv/insns/pssha_dws.h @@ -0,0 +1,44 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + uint64_t bits_SMIN = (uint64_t{1} << (32 - 1)); + uint64_t bits_SMAX = ((uint64_t{1} << (32 - 1)) - 1); + bool ov = false; + int8_t m = P_FIELD(RS2, 0, 8); + int8_t rev = static_cast(m); + rev = (m < 0) ? static_cast(~m + 1u) : m; + uint64_t mask = ((uint64_t{1} << 32) - 1); + p_rs1 &= mask; + if(m < 0){ + unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; + uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; + + if(sh >= 32) p_rd = (uint32_t)(sign ? mask : 0u); + else{ + uint64_t shifted = (p_rs1 >> sh); + uint64_t fill = (~uint64_t{0}) << (32 - sh); + shifted |= fill; + p_rd = (uint32_t)(shifted & mask); + } + } + else{ + if(rev==0) p_rd = (uint32_t)p_rs1; + else if(rev >= 32){ + if(p_rs1==0) p_rd = 0; + else{ + ov = true; + uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; + p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); + } + } + else{ + uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; + uint64_t top = (p_rs1 >> (32 - rev)); + uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; + ov = (top != need); + if(ov) + p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); + else + p_rd = (uint32_t)((p_rs1 << rev) & mask); + } + } +}) diff --git a/riscv/insns/psshar_dhs.h b/riscv/insns/psshar_dhs.h new file mode 100644 index 00000000..5208256a --- /dev/null +++ b/riscv/insns/psshar_dhs.h @@ -0,0 +1,63 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + uint64_t bits_SMIN = (uint64_t{1} << (16 - 1)); + uint64_t bits_SMAX = ((uint64_t{1} << (16 - 1)) - 1); + bool ov = false; + int8_t m = P_FIELD(RS2, 0, 8); + int8_t rev = static_cast(m); + rev = (m < 0) ? static_cast(~m + 1u) : m; + uint64_t mask = ((uint64_t{1} << 16) - 1); + p_rs1 &= mask; + if(m < 0){ + if ((rev & 0xFFu) == 0u) + p_rd = (uint16_t)p_rs1; + else{ + __int128 v_sext; + bool neg = ((p_rs1 >> (16 - 1)) & 1u); + if(!neg) v_sext = static_cast<__int128>(p_rs1); + else v_sext = (static_cast<__int128>(-1) << 16) | static_cast<__int128>(p_rs1); + __int128 v_cat0 = v_sext << 1; + + unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; + + __int128 sra_val; + if(sh == 0) + sra_val = v_cat0; + else if(sh >=127) + sra_val = (v_cat0 < 0) ? static_cast<__int128>(-1) : static_cast<__int128>(0); + else{ + __int128 ux = static_cast(v_cat0); + __int128 shifted = ux >> sh; + if(v_cat0 < 0) + shifted |= (~static_cast(0)) << (128 - sh); + sra_val = static_cast<__int128>(shifted); + } + + __int128 plus1 = sra_val + static_cast<__int128>(1); + unsigned __int128 ures = static_cast(plus1); + p_rd = (uint16_t)(static_cast((ures >> 1) & static_cast(mask))); + } + } + else{ + if(rev==0) p_rd = (uint16_t)p_rs1; + else if(rev >= 16){ + if(p_rs1==0) + p_rd = 0; + else{ + ov = true; + uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; + p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); + } + } + else{ + uint64_t sign = (p_rs1 >> (16 - 1)) & 1u; + uint64_t top = (p_rs1 >> (16 - rev)); + uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; + ov = (top != need); + if(ov) + p_rd = (uint16_t)(sign ? bits_SMIN : bits_SMAX); + else + p_rd = (uint16_t)((p_rs1 << rev) & mask); + } + } +}) diff --git a/riscv/insns/psshar_dws.h b/riscv/insns/psshar_dws.h new file mode 100644 index 00000000..ad7abb28 --- /dev/null +++ b/riscv/insns/psshar_dws.h @@ -0,0 +1,63 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + uint64_t bits_SMIN = (uint64_t{1} << (32 - 1)); + uint64_t bits_SMAX = ((uint64_t{1} << (32 - 1)) - 1); + bool ov = false; + int8_t m = P_FIELD(RS2, 0, 8); + int8_t rev = static_cast(m); + rev = (m < 0) ? static_cast(~m + 1u) : m; + uint64_t mask = ((uint64_t{1} << 32) - 1); + p_rs1 &= mask; + if(m < 0){ + if ((rev & 0xFFu) == 0u) + p_rd = (uint32_t)p_rs1; + else{ + __int128 v_sext; + bool neg = ((p_rs1 >> (32 - 1)) & 1u); + if(!neg) v_sext = static_cast<__int128>(p_rs1); + else v_sext = (static_cast<__int128>(-1) << 32) | static_cast<__int128>(p_rs1); + __int128 v_cat0 = v_sext << 1; + + unsigned sh = ((unsigned)(uint8_t)rev > 255u) ? 255u : (unsigned)(uint8_t)rev; + + __int128 sra_val; + if(sh == 0) + sra_val = v_cat0; + else if(sh >=127) + sra_val = (v_cat0 < 0) ? static_cast<__int128>(-1) : static_cast<__int128>(0); + else{ + __int128 ux = static_cast(v_cat0); + __int128 shifted = ux >> sh; + if(v_cat0 < 0) + shifted |= (~static_cast(0)) << (128 - sh); + sra_val = static_cast<__int128>(shifted); + } + + __int128 plus1 = sra_val + static_cast<__int128>(1); + unsigned __int128 ures = static_cast(plus1); + p_rd = (uint32_t)(static_cast((ures >> 1) & static_cast(mask))); + } + } + else{ + if(rev==0) p_rd = (uint32_t)p_rs1; + else if(rev >= 32){ + if(p_rs1==0) + p_rd = 0; + else{ + ov = true; + uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; + p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); + } + } + else{ + uint64_t sign = (p_rs1 >> (32 - 1)) & 1u; + uint64_t top = (p_rs1 >> (32 - rev)); + uint64_t need = sign ? ((uint64_t{1} << rev) - 1) : 0u; + ov = (top != need); + if(ov) + p_rd = (uint32_t)(sign ? bits_SMIN : bits_SMAX); + else + p_rd = (uint32_t)((p_rs1 << rev) & mask); + } + } +}) diff --git a/riscv/insns/psslai_dh.h b/riscv/insns/psslai_dh.h new file mode 100644 index 00000000..43b7dc07 --- /dev/null +++ b/riscv/insns/psslai_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(16, 16, { + p_rd = P_SAT(16, sext32(p_rs1) << insn.shamth()); +}) \ No newline at end of file diff --git a/riscv/insns/psslai_dw.h b/riscv/insns/psslai_dw.h new file mode 100644 index 00000000..27280421 --- /dev/null +++ b/riscv/insns/psslai_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_DW_LOOP(32, 32, { + p_rd = P_SAT(32, sext32(p_rs1) << insn.shamtw()); +}) \ No newline at end of file diff --git a/riscv/insns/pssub_db.h b/riscv/insns/pssub_db.h new file mode 100644 index 00000000..1fd3d79e --- /dev/null +++ b/riscv/insns/pssub_db.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8,8,8, { + bool sat = false; + p_rd = (sat_sub(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/pssub_dh.h b/riscv/insns/pssub_dh.h new file mode 100644 index 00000000..8c16a47c --- /dev/null +++ b/riscv/insns/pssub_dh.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16,16,16, { + bool sat = false; + p_rd = (sat_sub(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/pssub_dw.h b/riscv/insns/pssub_dw.h new file mode 100644 index 00000000..be55dc5a --- /dev/null +++ b/riscv/insns/pssub_dw.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32,32,32, { + bool sat = false; + p_rd = (sat_sub(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/pssubu_db.h b/riscv/insns/pssubu_db.h new file mode 100644 index 00000000..fd564a5f --- /dev/null +++ b/riscv/insns/pssubu_db.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(8,8,8, { + bool sat = false; + p_rd = (sat_subu(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/pssubu_dh.h b/riscv/insns/pssubu_dh.h new file mode 100644 index 00000000..b910ce5d --- /dev/null +++ b/riscv/insns/pssubu_dh.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(16,16,16, { + bool sat = false; + p_rd = (sat_subu(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/pssubu_dw.h b/riscv/insns/pssubu_dw.h new file mode 100644 index 00000000..aa9063a2 --- /dev/null +++ b/riscv/insns/pssubu_dw.h @@ -0,0 +1,5 @@ +require_rv32; +P_RD_RS1_RS2_DW_ULOOP(32,32,32, { + bool sat = false; + p_rd = (sat_subu(p_rs1, p_rs2, sat)); +}) \ No newline at end of file diff --git a/riscv/insns/psub_db.h b/riscv/insns/psub_db.h new file mode 100644 index 00000000..9dd13238 --- /dev/null +++ b/riscv/insns/psub_db.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(8, 8, 8, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/psub_dh.h b/riscv/insns/psub_dh.h new file mode 100644 index 00000000..ffb1c44e --- /dev/null +++ b/riscv/insns/psub_dh.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(16, 16, 16, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/psub_dw.h b/riscv/insns/psub_dw.h new file mode 100644 index 00000000..cababad7 --- /dev/null +++ b/riscv/insns/psub_dw.h @@ -0,0 +1,4 @@ +require_rv32; +P_RD_RS1_RS2_DW_LOOP(32, 32, 32, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pusati_dh.h b/riscv/insns/pusati_dh.h new file mode 100644 index 00000000..d204bdc9 --- /dev/null +++ b/riscv/insns/pusati_dh.h @@ -0,0 +1,11 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(16, 16, { + uint64_t uint_max = insn.shamth() ? UINT64_MAX >> (64 - insn.shamth()) : 0; + int16_t s = (int16_t)p_rs1; + p_rd = p_rs1; + if (s < 0) { + p_rd = 0; + } else if ((uint64_t)s > uint_max) { + p_rd = uint_max; + } +}) \ No newline at end of file diff --git a/riscv/insns/pusati_dw.h b/riscv/insns/pusati_dw.h new file mode 100644 index 00000000..7aa833d0 --- /dev/null +++ b/riscv/insns/pusati_dw.h @@ -0,0 +1,11 @@ +require_rv32; +P_RD_RS1_DW_ULOOP(32, 32, { + uint64_t uint_max = insn.shamtw() ? UINT64_MAX >> (64 - insn.shamtw()) : 0; + int32_t s = (int32_t)p_rs1; + p_rd = p_rs1; + if (s < 0) { + p_rd = 0; + } else if ((uint64_t)s > uint_max) { + p_rd = uint_max; + } +}) \ No newline at end of file diff --git a/riscv/insns/pwadd_b.h b/riscv/insns/pwadd_b.h new file mode 100644 index 00000000..2470b57e --- /dev/null +++ b/riscv/insns/pwadd_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(8, 8, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwadd_h.h b/riscv/insns/pwadd_h.h new file mode 100644 index 00000000..c139c3fc --- /dev/null +++ b/riscv/insns/pwadd_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwadda_b.h b/riscv/insns/pwadda_b.h new file mode 100644 index 00000000..492fdbe9 --- /dev/null +++ b/riscv/insns/pwadda_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(8, 8, { + p_rd += p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwadda_h.h b/riscv/insns/pwadda_h.h new file mode 100644 index 00000000..0fbfc16e --- /dev/null +++ b/riscv/insns/pwadda_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd += p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwaddau_b.h b/riscv/insns/pwaddau_b.h new file mode 100644 index 00000000..20e4b744 --- /dev/null +++ b/riscv/insns/pwaddau_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(8, 8, { + p_rd += p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwaddau_h.h b/riscv/insns/pwaddau_h.h new file mode 100644 index 00000000..25a5720c --- /dev/null +++ b/riscv/insns/pwaddau_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(16, 16, { + p_rd += p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwaddu_b.h b/riscv/insns/pwaddu_b.h new file mode 100644 index 00000000..e08f5d30 --- /dev/null +++ b/riscv/insns/pwaddu_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(8, 8, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwaddu_h.h b/riscv/insns/pwaddu_h.h new file mode 100644 index 00000000..7da0db35 --- /dev/null +++ b/riscv/insns/pwaddu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(16, 16, { + p_rd = p_rs1 + p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmacc_h.h b/riscv/insns/pwmacc_h.h new file mode 100644 index 00000000..fcd8bc69 --- /dev/null +++ b/riscv/insns/pwmacc_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmaccsu_h.h b/riscv/insns/pwmaccsu_h.h new file mode 100644 index 00000000..9e8a07af --- /dev/null +++ b/riscv/insns/pwmaccsu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_SULOOP(16, 16, { + p_rd += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmaccu_h.h b/riscv/insns/pwmaccu_h.h new file mode 100644 index 00000000..0bf6df37 --- /dev/null +++ b/riscv/insns/pwmaccu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(16, 16, { + p_rd += p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmul_b.h b/riscv/insns/pwmul_b.h new file mode 100644 index 00000000..25fd0490 --- /dev/null +++ b/riscv/insns/pwmul_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(8, 8, { + p_rd = p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmul_h.h b/riscv/insns/pwmul_h.h new file mode 100644 index 00000000..5b7d431c --- /dev/null +++ b/riscv/insns/pwmul_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd = p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmulsu_b.h b/riscv/insns/pwmulsu_b.h new file mode 100644 index 00000000..f94f1e1c --- /dev/null +++ b/riscv/insns/pwmulsu_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_SULOOP(8, 8, { + p_rd = p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmulsu_h.h b/riscv/insns/pwmulsu_h.h new file mode 100644 index 00000000..0756787b --- /dev/null +++ b/riscv/insns/pwmulsu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_SULOOP(16, 16, { + p_rd = p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmulu_b.h b/riscv/insns/pwmulu_b.h new file mode 100644 index 00000000..886ac77e --- /dev/null +++ b/riscv/insns/pwmulu_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(8, 8, { + p_rd = p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwmulu_h.h b/riscv/insns/pwmulu_h.h new file mode 100644 index 00000000..ceeb9d56 --- /dev/null +++ b/riscv/insns/pwmulu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(16, 16, { + p_rd = p_rs1 * p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsla_bs.h b/riscv/insns/pwsla_bs.h new file mode 100644 index 00000000..6e4ef920 --- /dev/null +++ b/riscv/insns/pwsla_bs.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_LOOP(8, { + p_rd = p_rs1 << (RS2 & (16 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/pwsla_hs.h b/riscv/insns/pwsla_hs.h new file mode 100644 index 00000000..c63b9f45 --- /dev/null +++ b/riscv/insns/pwsla_hs.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_LOOP(16, { + p_rd = p_rs1 << (RS2 & (32 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/pwslai_b.h b/riscv/insns/pwslai_b.h new file mode 100644 index 00000000..df0a143c --- /dev/null +++ b/riscv/insns/pwslai_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_LOOP(8, { + p_rd = p_rs1 << insn.shamth(); +}) \ No newline at end of file diff --git a/riscv/insns/pwslai_h.h b/riscv/insns/pwslai_h.h new file mode 100644 index 00000000..6504974a --- /dev/null +++ b/riscv/insns/pwslai_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_LOOP(16, { + p_rd = p_rs1 << insn.shamtw(); +}) \ No newline at end of file diff --git a/riscv/insns/pwsll_bs.h b/riscv/insns/pwsll_bs.h new file mode 100644 index 00000000..24804320 --- /dev/null +++ b/riscv/insns/pwsll_bs.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_ULOOP(8, { + p_rd = p_rs1 << (RS2 & (16 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/pwsll_hs.h b/riscv/insns/pwsll_hs.h new file mode 100644 index 00000000..17a6326e --- /dev/null +++ b/riscv/insns/pwsll_hs.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_ULOOP(16, { + p_rd = p_rs1 << (RS2 & (32 - 1)); +}) \ No newline at end of file diff --git a/riscv/insns/pwslli_b.h b/riscv/insns/pwslli_b.h new file mode 100644 index 00000000..f2548cbe --- /dev/null +++ b/riscv/insns/pwslli_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_ULOOP(8, { + p_rd = (uint16_t)p_rs1 << insn.shamth(); +}) \ No newline at end of file diff --git a/riscv/insns/pwslli_h.h b/riscv/insns/pwslli_h.h new file mode 100644 index 00000000..59e8e41b --- /dev/null +++ b/riscv/insns/pwslli_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_ULOOP(16, { + p_rd = (uint32_t)p_rs1 << insn.shamtw(); +}) \ No newline at end of file diff --git a/riscv/insns/pwsub_b.h b/riscv/insns/pwsub_b.h new file mode 100644 index 00000000..97c09925 --- /dev/null +++ b/riscv/insns/pwsub_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(8, 8, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsub_h.h b/riscv/insns/pwsub_h.h new file mode 100644 index 00000000..1be15dee --- /dev/null +++ b/riscv/insns/pwsub_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsuba_b.h b/riscv/insns/pwsuba_b.h new file mode 100644 index 00000000..99ad5357 --- /dev/null +++ b/riscv/insns/pwsuba_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(8, 8, { + p_rd += p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsuba_h.h b/riscv/insns/pwsuba_h.h new file mode 100644 index 00000000..0107c690 --- /dev/null +++ b/riscv/insns/pwsuba_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_LOOP(16, 16, { + p_rd += p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsubau_b.h b/riscv/insns/pwsubau_b.h new file mode 100644 index 00000000..2b0b236a --- /dev/null +++ b/riscv/insns/pwsubau_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(8, 8, { + p_rd += p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsubau_h.h b/riscv/insns/pwsubau_h.h new file mode 100644 index 00000000..8281dcd1 --- /dev/null +++ b/riscv/insns/pwsubau_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(16, 16, { + p_rd += p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsubu_b.h b/riscv/insns/pwsubu_b.h new file mode 100644 index 00000000..a53818cd --- /dev/null +++ b/riscv/insns/pwsubu_b.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(8, 8, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/pwsubu_h.h b/riscv/insns/pwsubu_h.h new file mode 100644 index 00000000..c944ea38 --- /dev/null +++ b/riscv/insns/pwsubu_h.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ULOOP(16, 16, { + p_rd = p_rs1 - p_rs2; +}) \ No newline at end of file diff --git a/riscv/insns/subd.h b/riscv/insns/subd.h new file mode 100644 index 00000000..768c8d40 --- /dev/null +++ b/riscv/insns/subd.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RS1_PAIR - P_RS2_PAIR); \ No newline at end of file diff --git a/riscv/insns/wadd.h b/riscv/insns/wadd.h new file mode 100644 index 00000000..351c8648 --- /dev/null +++ b/riscv/insns/wadd.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(RS1+RS2); \ No newline at end of file diff --git a/riscv/insns/wadda.h b/riscv/insns/wadda.h new file mode 100644 index 00000000..7b011792 --- /dev/null +++ b/riscv/insns/wadda.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RD_PAIR+RS1+RS2); \ No newline at end of file diff --git a/riscv/insns/waddau.h b/riscv/insns/waddau.h new file mode 100644 index 00000000..33500295 --- /dev/null +++ b/riscv/insns/waddau.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR((reg_t)P_RD_PAIR+(uint32_t)RS1+(uint32_t)RS2); \ No newline at end of file diff --git a/riscv/insns/waddu.h b/riscv/insns/waddu.h new file mode 100644 index 00000000..e7b8c092 --- /dev/null +++ b/riscv/insns/waddu.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(0ULL + (uint32_t)RS1 + (uint32_t)RS2); \ No newline at end of file diff --git a/riscv/insns/wmacc.h b/riscv/insns/wmacc.h new file mode 100644 index 00000000..e416e857 --- /dev/null +++ b/riscv/insns/wmacc.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RD_PAIR+RS1*RS2); \ No newline at end of file diff --git a/riscv/insns/wmaccsu.h b/riscv/insns/wmaccsu.h new file mode 100644 index 00000000..6f5be847 --- /dev/null +++ b/riscv/insns/wmaccsu.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR((sreg_t)P_RD_PAIR+RS1*(uint32_t)RS2); \ No newline at end of file diff --git a/riscv/insns/wmaccu.h b/riscv/insns/wmaccu.h new file mode 100644 index 00000000..bb84fc7a --- /dev/null +++ b/riscv/insns/wmaccu.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR((reg_t)P_RD_PAIR+zext32(RS1)*zext32(RS2)); \ No newline at end of file diff --git a/riscv/insns/wmul.h b/riscv/insns/wmul.h new file mode 100644 index 00000000..67a1f1d3 --- /dev/null +++ b/riscv/insns/wmul.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(RS1*RS2); \ No newline at end of file diff --git a/riscv/insns/wmulsu.h b/riscv/insns/wmulsu.h new file mode 100644 index 00000000..4447070a --- /dev/null +++ b/riscv/insns/wmulsu.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(RS1*(uint32_t)RS2); \ No newline at end of file diff --git a/riscv/insns/wmulu.h b/riscv/insns/wmulu.h new file mode 100644 index 00000000..ffd284b6 --- /dev/null +++ b/riscv/insns/wmulu.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(zext32(RS1)*zext32(RS2)); \ No newline at end of file diff --git a/riscv/insns/wsla.h b/riscv/insns/wsla.h new file mode 100644 index 00000000..6f8a6451 --- /dev/null +++ b/riscv/insns/wsla.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(RS1 << (RS2 & (64 - 1))); \ No newline at end of file diff --git a/riscv/insns/wslai.h b/riscv/insns/wslai.h new file mode 100644 index 00000000..41675a2b --- /dev/null +++ b/riscv/insns/wslai.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(RS1 << insn.shamtd()); \ No newline at end of file diff --git a/riscv/insns/wsll.h b/riscv/insns/wsll.h new file mode 100644 index 00000000..7aaf14f0 --- /dev/null +++ b/riscv/insns/wsll.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR((uint64_t)(uint32_t)RS1 << (RS2 & (64 - 1))); \ No newline at end of file diff --git a/riscv/insns/wslli.h b/riscv/insns/wslli.h new file mode 100644 index 00000000..cf9c9bec --- /dev/null +++ b/riscv/insns/wslli.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR((uint64_t)(uint32_t)RS1 << insn.shamtd()); \ No newline at end of file diff --git a/riscv/insns/wsub.h b/riscv/insns/wsub.h new file mode 100644 index 00000000..ea3250df --- /dev/null +++ b/riscv/insns/wsub.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(RS1-RS2); \ No newline at end of file diff --git a/riscv/insns/wsuba.h b/riscv/insns/wsuba.h new file mode 100644 index 00000000..ca81a9ca --- /dev/null +++ b/riscv/insns/wsuba.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RD_PAIR+RS1-RS2); \ No newline at end of file diff --git a/riscv/insns/wsubau.h b/riscv/insns/wsubau.h new file mode 100644 index 00000000..e668a33a --- /dev/null +++ b/riscv/insns/wsubau.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(P_RD_PAIR+(uint32_t)RS1-(uint32_t)RS2); \ No newline at end of file diff --git a/riscv/insns/wsubu.h b/riscv/insns/wsubu.h new file mode 100644 index 00000000..b8de8368 --- /dev/null +++ b/riscv/insns/wsubu.h @@ -0,0 +1,3 @@ +require_extension('P'); +require_rv32; +WRITE_P_RD_PAIR(0ULL + (uint32_t)RS1-(uint32_t)RS2); \ No newline at end of file diff --git a/riscv/insns/wzip16p.h b/riscv/insns/wzip16p.h new file mode 100644 index 00000000..a73e4197 --- /dev/null +++ b/riscv/insns/wzip16p.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ZIP_LOOP(16, 16, { + p_rd = p_rs2 << 16 | p_rs1; +}) \ No newline at end of file diff --git a/riscv/insns/wzip8p.h b/riscv/insns/wzip8p.h new file mode 100644 index 00000000..bfcf04e0 --- /dev/null +++ b/riscv/insns/wzip8p.h @@ -0,0 +1,4 @@ +require_rv32; +P_WIDEN_RD_RS1_RS2_ZIP_LOOP(8, 8, { + p_rd = p_rs2 << 8 | p_rs1; +}) \ No newline at end of file diff --git a/riscv/p_ext_macros.h b/riscv/p_ext_macros.h index 40bf1f6f..b867a375 100644 --- a/riscv/p_ext_macros.h +++ b/riscv/p_ext_macros.h @@ -144,6 +144,26 @@ sreg_t p_res = P_UFIELD(rd_tmp, i, BIT); \ for (sreg_t j = i * len_inner; j < (i + 1) * len_inner; ++j) { +#define P_WIDEN_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + require_extension('P'); \ + require(BIT == e16 || BIT == e32 || BIT == e64); \ + reg_t rd_tmp = USE_RD ? zext_xlen_pair(P_RD_PAIR) : 0; \ + reg_t rs1 = zext_xlen(RS1); \ + reg_t rs2 = zext_xlen(RS2); \ + sreg_t len_inner = BIT / BIT_INNER; \ + sreg_t p_res = P_FIELD(rd_tmp, 0, BIT * 2); \ + for (sreg_t j = len_inner - 1; j >= 0 ; --j) { + +#define P_WIDEN_REDUCTION_ULOOP_BASE(BIT, BIT_INNER, USE_RD) \ + require_extension('P'); \ + require(BIT == e16 || BIT == e32 || BIT == e64); \ + reg_t rd_tmp = USE_RD ? zext_xlen_pair(P_RD_PAIR) : 0; \ + reg_t rs1 = zext_xlen(RS1); \ + reg_t rs2 = zext_xlen(RS2); \ + sreg_t len_inner = BIT / BIT_INNER; \ + sreg_t p_res = P_UFIELD(rd_tmp, 0, BIT * 2); \ + for (sreg_t j = 0; j < len_inner; ++j) { + #define P_RD_DW_LOOP_BASE(BIT) \ require_extension('P'); \ require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ @@ -151,6 +171,64 @@ sreg_t len = xlen / (BIT) * 2; \ for (sreg_t i = len - 1; i >= 0; --i) { +#define P_RD_RS1_DW_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rd_tmp = P_RD_PAIR; \ + reg_t rs1 = P_RS1_PAIR; \ + sreg_t len = xlen / (BIT) * 2; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_RS1_DW_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rs1 = P_RS1_PAIR; \ + sreg_t len = xlen / (BIT) * 2; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_WIDEN_RD_RS1_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rd_tmp = P_RD_PAIR; \ + reg_t rs1 = RS1; \ + sreg_t len = xlen / (BIT); \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_WIDEN_RD_RS1_RS2_ZIP_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rd_tmp = P_RD_PAIR; \ + reg_t rs1 = RS1; \ + reg_t rs2 = RS2; \ + sreg_t len = xlen / (BIT); \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_WIDEN_RD_RS1_RS2_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rd_tmp = P_RD_PAIR; \ + reg_t rs1 = RS1; \ + reg_t rs2 = RS2; \ + sreg_t len = xlen / (BIT); \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_RD_RS1_RS2_DW_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rd_tmp = P_RD_PAIR; \ + reg_t rs1 = P_RS1_PAIR; \ + reg_t rs2 = P_RS2_PAIR; \ + sreg_t len = xlen / (BIT) * 2; \ + for (sreg_t i = len - 1; i >= 0; --i) { + +#define P_NARROW_RD_RS1_LOOP_BASE(BIT) \ + require_extension('P'); \ + require((BIT) == e8 || (BIT) == e16 || (BIT) == e32); \ + reg_t rd_tmp = RD; \ + reg_t rs1 = P_RS1_PAIR; \ + sreg_t len = xlen / (BIT); \ + for (sreg_t i = len - 1; i >= 0; --i) { + // Loop body #define P_RD_LOOP_BODY(BIT, BODY) { \ P_RD_PARAMS(BIT) \ @@ -158,6 +236,16 @@ WRITE_P_RD(); \ } +#define P_RS1_LOOP_BODY(BIT_RS1, BODY) { \ + P_RS1_PARAMS(BIT_RS1) \ + BODY \ +} + +#define P_RS1_ULOOP_BODY(BIT_RS1, BODY) { \ + P_RS1_UPARAMS(BIT_RS1) \ + BODY \ +} + #define P_RD_RS1_LOOP_BODY(BIT_RD, BIT_RS1, BODY) { \ P_RD_PARAMS(BIT_RD) \ P_RS1_PARAMS(BIT_RS1) \ @@ -308,6 +396,14 @@ WRITE_P_RD(); \ } +#define P_WIDEN_RD_RS1_RS2_ZIP_LOOP_BODY(BIT_RD, BIT_RS1, BIT_RS2, BODY) { \ + P_RD_PARAMS(BIT_RD) \ + P_RS1_UPARAMS(BIT_RS1) \ + P_RS2_UPARAMS(BIT_RS2) \ + BODY \ + WRITE_P_RD(); \ +} + // Loop end #define P_RD_LOOP_END() \ } \ @@ -330,6 +426,13 @@ } \ WRITE_RD(sext_xlen(rd_tmp)); +#define P_REDUCTION_DW_LOOP_END(BIT, IS_SAT) \ + } \ + if (IS_SAT) { \ + p_res = P_SAT(BIT * 2, p_res); \ + } \ + WRITE_P_RD_PAIR(p_res); + #define P_RD_DW_LOOP_END() \ } \ WRITE_P_RD_PAIR(rd_tmp); @@ -482,20 +585,166 @@ P_RD_LOOP_BODY(BIT_RD, BODY) \ P_RD_DW_LOOP_END() +#define P_RD_RS1_DW_LOOP(BIT_RD, BIT_RS1, BODY) \ + P_RD_RS1_DW_LOOP_BASE(BIT_RD) \ + P_RD_RS1_LOOP_BODY(BIT_RD, BIT_RS1, BODY) \ + P_RD_DW_LOOP_END() + +#define P_RS1_DW_LOOP(BIT_RS1, BODY) \ + P_RS1_DW_LOOP_BASE(BIT_RS1) \ + P_RS1_LOOP_BODY(BIT_RS1, BODY) \ + P_RD_LOOP_END() + +#define P_RS1_DW_ULOOP(BIT_RS1, BODY) \ + P_RS1_DW_LOOP_BASE(BIT_RS1) \ + P_RS1_ULOOP_BODY(BIT_RS1, BODY) \ + P_RD_LOOP_END() + +#define P_WIDEN_RD_RS1_LOOP(BIT_RS1, BODY) \ + P_WIDEN_RD_RS1_LOOP_BASE(BIT_RS1) \ + P_RD_RS1_LOOP_BODY((BIT_RS1) * 2, BIT_RS1, BODY) \ + P_RD_DW_LOOP_END() + +#define P_WIDEN_RD_RS1_ULOOP(BIT_RS1, BODY) \ + P_WIDEN_RD_RS1_LOOP_BASE(BIT_RS1) \ + P_RD_RS1_ULOOP_BODY((BIT_RS1) * 2, BIT_RS1, BODY) \ + P_RD_DW_LOOP_END() + +#define P_WIDEN_RD_RS1_RS2_ZIP_LOOP(BIT_RS1, BIT_RS2, BODY) \ + P_WIDEN_RD_RS1_RS2_ZIP_LOOP_BASE(BIT_RS1) \ + P_WIDEN_RD_RS1_RS2_ZIP_LOOP_BODY((BIT_RS1 * 2), BIT_RS1, BIT_RS2, BODY) \ + P_RD_DW_LOOP_END() + +#define P_WIDEN_RD_RS1_RS2_LOOP(BIT_RS1, BIT_RS2, BODY) \ + P_WIDEN_RD_RS1_RS2_LOOP_BASE(BIT_RS1) \ + P_RD_RS1_RS2_LOOP_BODY((BIT_RS1) * 2, BIT_RS1, BIT_RS2, BODY) \ + P_RD_DW_LOOP_END() + +#define P_WIDEN_RD_RS1_RS2_ULOOP(BIT_RS1, BIT_RS2, BODY) \ + P_WIDEN_RD_RS1_RS2_LOOP_BASE(BIT_RS1) \ + P_RD_RS1_RS2_ULOOP_BODY((BIT_RS1) * 2, BIT_RS1, BIT_RS2, BODY) \ + P_RD_DW_LOOP_END() + +#define P_WIDEN_RD_RS1_RS2_SULOOP(BIT_RS1, BIT_RS2, BODY) \ + P_WIDEN_RD_RS1_RS2_LOOP_BASE(BIT_RS1) \ + P_RD_RS1_RS2_SULOOP_BODY((BIT_RS1) * 2, BIT_RS1, BIT_RS2, BODY) \ + P_RD_DW_LOOP_END() + +#define P_WIDEN_REDUCTION_LOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_WIDEN_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_RS1_INNER_PARAMS(BIT_INNER) \ + P_RS2_INNER_PARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_DW_LOOP_END(BIT, IS_SAT) + +#define P_WIDEN_REDUCTION_ULOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_WIDEN_REDUCTION_ULOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_RS1_INNER_UPARAMS(BIT_INNER) \ + P_RS2_INNER_UPARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_DW_LOOP_END(BIT, IS_SAT) + +#define P_WIDEN_REDUCTION_SULOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_WIDEN_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_RS1_INNER_PARAMS(BIT_INNER) \ + P_RS2_INNER_UPARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_DW_LOOP_END(BIT, IS_SAT) + +#define P_WIDEN_REDUCTION_CROSS_LOOP(BIT, BIT_INNER, USE_RD, IS_SAT, BODY) \ + P_WIDEN_REDUCTION_LOOP_BASE(BIT, BIT_INNER, USE_RD) \ + P_RS1_INNER_PARAMS(BIT_INNER) \ + P_RS2_INNER_CROSS_PARAMS(BIT_INNER) \ + BODY \ + P_REDUCTION_DW_LOOP_END(BIT, IS_SAT) + +#define P_RD_RS1_DW_LOOP(BIT_RD, BIT_RS1, BODY) \ + P_RD_RS1_DW_LOOP_BASE(BIT_RD) \ + P_RD_RS1_LOOP_BODY(BIT_RD, BIT_RS1, BODY) \ + P_RD_DW_LOOP_END() + +#define P_RD_RS1_DW_ULOOP(BIT_RD, BIT_RS1, BODY) \ + P_RD_RS1_DW_LOOP_BASE(BIT_RD) \ + P_RD_RS1_ULOOP_BODY(BIT_RD, BIT_RS1, BODY) \ + P_RD_DW_LOOP_END() + +#define P_RD_RS1_RS2_DW_LOOP(BIT_RD, BIT_RS1, BIT_RS2, BODY) \ + P_RD_RS1_RS2_DW_LOOP_BASE(BIT_RD) \ + P_RD_RS1_RS2_LOOP_BODY(BIT_RD, BIT_RS1, BIT_RS2, BODY) \ + P_RD_DW_LOOP_END() + +#define P_RD_RS1_RS2_DW_ULOOP(BIT_RD, BIT_RS1, BIT_RS2, BODY) \ + P_RD_RS1_RS2_DW_LOOP_BASE(BIT_RD) \ + P_RD_RS1_RS2_ULOOP_BODY(BIT_RD, BIT_RS1, BIT_RS2, BODY) \ + P_RD_DW_LOOP_END() + +#define P_NARROW_RD_RS1_LOOP(BIT_RD, BIT_RS1, BODY) \ + P_NARROW_RD_RS1_LOOP_BASE(BIT_RD) \ + P_RD_RS1_LOOP_BODY(BIT_RD, BIT_RS1, BODY) \ + P_RD_LOOP_END() + +#define P_NARROW_RD_RS1_ULOOP(BIT_RD, BIT_RS1, BODY) \ + P_NARROW_RD_RS1_LOOP_BASE(BIT_RD) \ + P_RD_RS1_ULOOP_BODY(BIT_RD, BIT_RS1, BODY) \ + P_RD_LOOP_END() + +#define P_CROSS_DW_LOOP(BIT, BODY1, BODY2) \ + P_RD_RS1_RS2_DW_LOOP_BASE(BIT) \ + P_CROSS_LOOP_BODY(BIT, BODY1) \ + --i; \ + if (sizeof(#BODY2) == 1) { \ + P_CROSS_LOOP_BODY(BIT, BODY1) \ + } \ + else { \ + P_CROSS_LOOP_BODY(BIT, BODY2) \ + } \ + P_RD_DW_LOOP_END() + +#define P_CROSS_DW_ULOOP(BIT, BODY1, BODY2) \ + P_RD_RS1_RS2_DW_LOOP_BASE(BIT) \ + P_CROSS_ULOOP_BODY(BIT, BODY1) \ + --i; \ + if (sizeof(#BODY2) == 1) { \ + P_CROSS_ULOOP_BODY(BIT, BODY1) \ + } \ + else { \ + P_CROSS_ULOOP_BODY(BIT, BODY2) \ + } \ + P_RD_DW_LOOP_END() + // Misc -#define P_SAT(BIT, R) ( \ - ((BIT) == 64) ? (R) : \ - ((R) > ((1LL << ((BIT) - 1)) - 1)) ? ((1LL << ((BIT) - 1)) - 1) : \ - ((R) < -(1LL << ((BIT) - 1))) ? -(1LL << ((BIT) - 1)) : \ - (R) \ -) - -#define P_USAT(BIT, R) ( \ - ((R) < 0) ? 0 : \ - ((BIT) == 64) ? (R) : \ - ((R) > ((1LL << ((BIT) - 1)) - 1)) ? ((1LL << ((BIT) - 1)) - 1) : \ - (R) \ -) +#define P_SAT(BIT, R) ({ \ + sreg_t _psat_in = (R); \ + sreg_t _psat_out; \ + if ((BIT) == 64) _psat_out = _psat_in; \ + else if (_psat_in > (sreg_t)((reg_t(1) << ((BIT) - 1)) - 1)) _psat_out = (sreg_t)((reg_t(1) << ((BIT) - 1)) - 1); \ + else if (_psat_in < (sreg_t)(reg_t(-1) << ((BIT) - 1))) _psat_out = (sreg_t)(reg_t(-1) << ((BIT) - 1)); \ + else _psat_out = _psat_in; \ + if (_psat_out != _psat_in) P.VU.vxsat->write(1); \ + _psat_out; \ +}) + +#define P_USAT(BIT, R) ({ \ + sreg_t _pusat_in = (R); \ + sreg_t _pusat_out; \ + if (_pusat_in < 0) _pusat_out = 0; \ + else if ((BIT) == 64) _pusat_out = _pusat_in; \ + else if (_pusat_in > (sreg_t)((reg_t(1) << ((BIT) - 1)) - 1)) _pusat_out = (sreg_t)((reg_t(1) << ((BIT) - 1)) - 1); \ + else _pusat_out = _pusat_in; \ + if (_pusat_out != _pusat_in) P.VU.vxsat->write(1); \ + _pusat_out; \ +}) + +#define P_USAT_FULL(BIT, R) ({ \ + sreg_t _pusatf_in = (R); \ + sreg_t _pusatf_out; \ + if (_pusatf_in < 0) _pusatf_out = 0; \ + else if ((BIT) >= 64) _pusatf_out = _pusatf_in; \ + else if (_pusatf_in > (sreg_t)((reg_t(1) << (BIT)) - 1)) _pusatf_out = (sreg_t)((reg_t(1) << (BIT)) - 1); \ + else _pusatf_out = _pusatf_in; \ + if (_pusatf_out != _pusatf_in) P.VU.vxsat->write(1); \ + _pusatf_out; \ +}) #define P_PACK(BIT, X, Y) \ require_extension('P'); \ @@ -509,4 +758,16 @@ } \ WRITE_RD(sext_xlen(rd_tmp)); +#define P_PACK_DW(BIT, X, Y) \ + require_extension('P'); \ + require(BIT == e8 || BIT == e16); \ + reg_t rd_tmp = 0, rs1 = P_RS1_PAIR, rs2 = P_RS2_PAIR; \ + for (sreg_t i = 0; i < 64 / BIT / 2; i++) { \ + rd_tmp = set_field(rd_tmp, make_mask64((i * 2 + 1) * BIT, BIT), \ + P_UFIELD(rs2, i * 2 + Y, BIT)); \ + rd_tmp = set_field(rd_tmp, make_mask64(i * 2 * BIT, BIT), \ + P_UFIELD(rs1, i * 2 + X, BIT)); \ + } \ + WRITE_P_RD_PAIR(rd_tmp); + #endif \ No newline at end of file diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index e1f1add8..7af13b96 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -1359,6 +1359,234 @@ riscv_insn_ext_p = \ pli_db \ pli_dh \ plui_dh \ + pwadd_b \ + pwadd_h \ + wadd \ + pwadda_b \ + pwadda_h \ + wadda \ + pwaddu_b \ + pwaddu_h \ + waddu \ + pwaddau_b \ + pwaddau_h \ + waddau \ + pwsub_b \ + pwsub_h \ + wsub \ + pwsuba_b \ + pwsuba_h \ + wsuba \ + pwsubu_b \ + pwsubu_h \ + wsubu \ + pwsubau_b \ + pwsubau_h \ + wsubau \ + padd_db \ + padd_dh \ + padd_dw \ + psub_db \ + psub_dh \ + psub_dw \ + psadd_db \ + psadd_dh \ + psadd_dw \ + psaddu_db \ + psaddu_dh \ + psaddu_dw \ + pssub_db \ + pssub_dh \ + pssub_dw \ + pssubu_db \ + pssubu_dh \ + pssubu_dw \ + paadd_db \ + paadd_dh \ + paadd_dw \ + paaddu_db \ + paaddu_dh \ + paaddu_dw \ + pasub_db \ + pasub_dh \ + pasub_dw \ + pasubu_db \ + pasubu_dh \ + pasubu_dw \ + psh1add_dh \ + psh1add_dw \ + pssh1sadd_dh \ + pssh1sadd_dw \ + addd \ + subd \ + padd_dbs \ + padd_dhs \ + padd_dws \ + pas_dhx \ + psa_dhx \ + psas_dhx \ + pssa_dhx \ + paas_dhx \ + pasa_dhx \ + pabd_db \ + pabd_dh \ + pabdu_db \ + pabdu_dh \ + psabs_db \ + psabs_dh \ + predsum_dbs \ + predsum_dhs \ + predsumu_dbs \ + predsumu_dhs \ + psext_dh_b \ + psext_dw_b \ + psext_dw_h \ + psati_dh \ + psati_dw \ + pusati_dh \ + pusati_dw \ + pslli_db \ + pslli_dh \ + pslli_dw \ + psrli_db \ + psrli_dh \ + psrli_dw \ + psrai_db \ + psrai_dh \ + psrai_dw \ + psslai_dh \ + psslai_dw \ + psrari_dh \ + psrari_dw \ + psll_dbs \ + psll_dhs \ + psll_dws \ + psrl_dbs \ + psrl_dhs \ + psrl_dws \ + psra_dbs \ + psra_dhs \ + psra_dws \ + pssha_dhs \ + pssha_dws \ + psshar_dhs \ + psshar_dws \ + pwslli_b \ + pwslli_h \ + wslli \ + pwsll_bs \ + pwsll_hs \ + wsll \ + pwslai_b \ + pwslai_h \ + wslai \ + pwsla_bs \ + pwsla_hs \ + wsla \ + pmin_db \ + pmin_dh \ + pmin_dw \ + pminu_db \ + pminu_dh \ + pminu_dw \ + pmax_db \ + pmax_dh \ + pmax_dw \ + pmaxu_db \ + pmaxu_dh \ + pmaxu_dw \ + pmseq_db \ + pmseq_dh \ + pmseq_dw \ + pmslt_db \ + pmslt_dh \ + pmslt_dw \ + pmsltu_db \ + pmsltu_dh \ + pmsltu_dw \ + ppaire_db \ + ppaire_dh \ + ppaireo_db \ + ppaireo_dh \ + ppairoe_db \ + ppairoe_dh \ + ppairo_db \ + ppairo_dh \ + wzip8p \ + wzip16p \ + pnsrli_b \ + pnsrli_h \ + nsrli \ + pnsrl_bs \ + pnsrl_hs \ + nsrl \ + pnsrai_b \ + pnsrai_h \ + nsrai \ + pnsra_bs \ + pnsra_hs \ + nsra \ + pnsrari_b \ + pnsrari_h \ + nsrari \ + pnsrar_bs \ + pnsrar_hs \ + nsrar \ + pnclipi_b \ + pnclipi_h \ + nclipi \ + pnclip_bs \ + pnclip_hs \ + nclip \ + pnclipri_b \ + pnclipri_h \ + nclipri \ + pnclipr_bs \ + pnclipr_hs \ + nclipr \ + pnclipiu_b \ + pnclipiu_h \ + nclipiu \ + pnclipu_bs \ + pnclipu_hs \ + nclipu \ + pnclipriu_b \ + pnclipriu_h \ + nclipriu \ + pnclipru_bs \ + pnclipru_hs \ + nclipru \ + pwmul_b \ + pwmul_h \ + wmul \ + pwmulsu_b \ + pwmulsu_h \ + wmulsu \ + pwmulu_b \ + pwmulu_h \ + wmulu \ + pmqwacc_h \ + mqwacc \ + pmqrwacc_h \ + mqrwacc \ + pwmacc_h \ + wmacc \ + pwmaccsu_h \ + wmaccsu \ + pwmaccu_h \ + wmaccu \ + pm2wadd_h \ + pm2wadda_h \ + pm2waddsu_h \ + pm2waddasu_h \ + pm2waddu_h \ + pm2waddau_h \ + pm2wadd_hx \ + pm2wadda_hx \ + pm2wsub_h \ + pm2wsuba_h \ + pm2wsub_hx \ + pm2wsuba_hx \ riscv_insn_list = \ $(riscv_insn_ext_i) \