diff options
author | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-04-03 00:46:57 -0700 |
---|---|---|
committer | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-04-03 00:46:57 -0700 |
commit | eb9770e3aedf2a88d745c0d68d8ec92bb145cdce (patch) | |
tree | 420d213f447a405b73ca90e9cd6351e04cab10f4 /riscv | |
parent | a1133dcf763446fe23e018339504d6cb4eb2eb1d (diff) | |
download | spike-eb9770e3aedf2a88d745c0d68d8ec92bb145cdce.zip spike-eb9770e3aedf2a88d745c0d68d8ec92bb145cdce.tar.gz spike-eb9770e3aedf2a88d745c0d68d8ec92bb145cdce.tar.bz2 |
rvv:add widing saturation instruction
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Diffstat (limited to 'riscv')
-rw-r--r-- | riscv/insns/vwsmacc_vv.h | 41 | ||||
-rw-r--r-- | riscv/insns/vwsmacc_vx.h | 39 | ||||
-rw-r--r-- | riscv/insns/vwsmaccu_vv.h | 41 | ||||
-rw-r--r-- | riscv/insns/vwsmaccu_vx.h | 41 | ||||
-rw-r--r-- | riscv/insns/vwsmsac_vv.h | 41 | ||||
-rw-r--r-- | riscv/insns/vwsmsac_vx.h | 34 | ||||
-rw-r--r-- | riscv/insns/vwsmsacu_vv.h | 41 | ||||
-rw-r--r-- | riscv/insns/vwsmsacu_vx.h | 36 |
8 files changed, 284 insertions, 30 deletions
diff --git a/riscv/insns/vwsmacc_vv.h b/riscv/insns/vwsmacc_vv.h index 5a6316f..53e51ff 100644 --- a/riscv/insns/vwsmacc_vv.h +++ b/riscv/insns/vwsmacc_vv.h @@ -1,5 +1,36 @@ -// vwsmacc -VI_VV_LOOP -({ - // NOT IMPLEMENTED YET -}) +// vwsmacc.vv vd, vs2, vs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type vs1 = STATE.VU.elt<type_sew_t<sew1>::type>(rs1_num, i); \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + int##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + int##sew2##_t res; \ + bool sat = false; \ + res = ((((int##sew2##_t)(int##sew1##_t)vs2 * (int##sew2##_t)(int##sew1##_t)vs1) + round) >> gb); \ + vd = sat_add<int##sew2##_t, uint##sew2##_t>(vd, res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END + +#undef WIDE_FUNC diff --git a/riscv/insns/vwsmacc_vx.h b/riscv/insns/vwsmacc_vx.h index 71412c8..57e6443 100644 --- a/riscv/insns/vwsmacc_vx.h +++ b/riscv/insns/vwsmacc_vx.h @@ -1,5 +1,34 @@ -// vwsmacc -VI_VX_LOOP -({ - // NOT IMPLEMENTED YET -}) +// vwsmacc.vx vd, vs2, rs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type rs1 = RS1; \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + int##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + int##sew2##_t res; \ + bool sat = false; \ + res = ((((int##sew2##_t)(int##sew1##_t)vs2 * (int##sew2##_t)(int##sew1##_t)rs1) + round) >> gb); \ + vd = sat_add<int##sew2##_t, uint##sew2##_t>(vd, res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END diff --git a/riscv/insns/vwsmaccu_vv.h b/riscv/insns/vwsmaccu_vv.h index dbea439..dc5726b 100644 --- a/riscv/insns/vwsmaccu_vv.h +++ b/riscv/insns/vwsmaccu_vv.h @@ -1,5 +1,36 @@ -// vwsmaccu -VI_VV_LOOP -({ - // NOT IMPLEMENTED YET -}) +// vwsmaccu.vv vd, vs2, vs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type vs1 = STATE.VU.elt<type_sew_t<sew1>::type>(rs1_num, i); \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + uint##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + uint##sew2##_t res; \ + bool sat = false; \ + res = ((((uint##sew2##_t)(uint##sew1##_t)vs2 * (uint##sew2##_t)(uint##sew1##_t)vs1) + round) >> gb); \ + vd = sat_addu<uint##sew2##_t>(vd, res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END + +#undef WIDE_FUNC diff --git a/riscv/insns/vwsmaccu_vx.h b/riscv/insns/vwsmaccu_vx.h index e049bcd..f0a1028 100644 --- a/riscv/insns/vwsmaccu_vx.h +++ b/riscv/insns/vwsmaccu_vx.h @@ -1,5 +1,36 @@ -// vwsmaccu -VI_VX_LOOP -({ - // NOT IMPLEMENTED YET -}) +// vwsmaccu vd, vs2, rs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type rs1 = RS1; \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + uint##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + uint##sew2##_t res; \ + bool sat = false; \ + res = ((((uint##sew2##_t)(uint##sew1##_t)vs2 * (uint##sew2##_t)(uint##sew1##_t)rs1) + round) >> gb); \ + vd = sat_addu<uint##sew2##_t>(vd, res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END + +#undef WIDE_FUNC diff --git a/riscv/insns/vwsmsac_vv.h b/riscv/insns/vwsmsac_vv.h index fb8a7c7..e0a3e89 100644 --- a/riscv/insns/vwsmsac_vv.h +++ b/riscv/insns/vwsmsac_vv.h @@ -1,5 +1,36 @@ -// vwsmsac -VI_VV_LOOP -({ - // NOT IMPLEMENTED YET -}) +// vwsmsac.vv vd, vs2, vs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type vs1 = STATE.VU.elt<type_sew_t<sew1>::type>(rs1_num, i); \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + int##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + int##sew2##_t res; \ + bool sat = false; \ + res = ((((int##sew2##_t)(int##sew1##_t)vs2 * (int##sew2##_t)(int##sew1##_t)vs1) + round) >> gb); \ + vd = sat_add<int##sew2##_t, uint##sew2##_t>(vd, -res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END + +#undef WIDE_FUNC diff --git a/riscv/insns/vwsmsac_vx.h b/riscv/insns/vwsmsac_vx.h new file mode 100644 index 0000000..dd13dab --- /dev/null +++ b/riscv/insns/vwsmsac_vx.h @@ -0,0 +1,34 @@ +// vwsmsac.vx vd, vs2, rs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type rs1 = RS1; \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + int##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + int##sew2##_t res; \ + bool sat = false; \ + res = ((((int##sew2##_t)(int##sew1##_t)vs2 * (int##sew2##_t)(int##sew1##_t)rs1) + round) >> gb); \ + vd = sat_add<int##sew2##_t, uint##sew2##_t>(vd, -res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END diff --git a/riscv/insns/vwsmsacu_vv.h b/riscv/insns/vwsmsacu_vv.h index d8a0bab..92726f7 100644 --- a/riscv/insns/vwsmsacu_vv.h +++ b/riscv/insns/vwsmsacu_vv.h @@ -1,5 +1,36 @@ -// vwsmsacu -VI_VV_LOOP -({ - // NOT IMPLEMENTED YET -}) +// vwsmsacu vd, vs2, vs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type vs1 = STATE.VU.elt<type_sew_t<sew1>::type>(rs1_num, i); \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + uint##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + uint##sew2##_t res; \ + bool sat = false; \ + res = ((((uint##sew2##_t)(uint##sew1##_t)vs2 * (uint##sew2##_t)(uint##sew1##_t)vs1) + round) >> gb); \ + vd = sat_addu<uint##sew2##_t>(vd, -res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END + +#undef WIDE_FUNC diff --git a/riscv/insns/vwsmsacu_vx.h b/riscv/insns/vwsmsacu_vx.h new file mode 100644 index 0000000..71e7797 --- /dev/null +++ b/riscv/insns/vwsmsacu_vx.h @@ -0,0 +1,36 @@ +// vwsmsacu vd, vs2, rs1 +V_WIDE_CHECK; +VRM vrm = STATE.VU.get_vround_mode(); +const int gb = STATE.VU.vsew / 2; + +#define WIDE_FUNC(sew1, sew2) \ + { \ + type_sew_t<sew2>::type &vd = STATE.VU.elt<type_sew_t<sew2>::type>(rd_num, i); \ + type_sew_t<sew1>::type rs1 = RS1; \ + type_sew_t<sew1>::type vs2 = STATE.VU.elt<type_sew_t<sew1>::type>(rs2_num, i); \ + uint##sew2##_t round = (vrm == VRM::RUN) ? 1 << (gb - 1) : 0; \ + uint##sew2##_t res; \ + bool sat = false; \ + res = ((((uint##sew2##_t)(uint##sew1##_t)vs2 * (uint##sew2##_t)(uint##sew1##_t)rs1) + round) >> gb); \ + vd = sat_addu<uint##sew2##_t>(vd, -res, sat); \ + STATE.VU.vxsat = sat; \ + } + +VI_LOOP_BASE + V_LOOP_ELEMENT_SKIP; + + switch(STATE.VU.vsew) { + case e8: + WIDE_FUNC(8, 16); + break; + case e16: + WIDE_FUNC(16, 32); + break; + default: + WIDE_FUNC(32, 64); + break; + } + +VI_LOOP_END + +#undef WIDE_FUNC |