No public description
PiperOrigin-RevId: 550581558
diff --git a/sim/kelvin.bin_fmt b/sim/kelvin.bin_fmt
index b68959b..71b48d3 100644
--- a/sim/kelvin.bin_fmt
+++ b/sim/kelvin.bin_fmt
@@ -1199,6 +1199,18 @@
vmadd_w_vx_m : KelvinV2ArgsType : func2 == 0b01'0101, sz == 0b10, m == 0b01, func1 == 0b011, form == 0b10;
//vslidevn
+ vsliden_b_1_vv : KelvinV2ArgsType : func2 == 0b00'0000, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_b_2_vv : KelvinV2ArgsType : func2 == 0b00'0001, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_b_3_vv : KelvinV2ArgsType : func2 == 0b00'0010, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_b_4_vv : KelvinV2ArgsType : func2 == 0b00'0011, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_h_1_vv : KelvinV2ArgsType : func2 == 0b00'0000, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_h_2_vv : KelvinV2ArgsType : func2 == 0b00'0001, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_h_3_vv : KelvinV2ArgsType : func2 == 0b00'0010, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_h_4_vv : KelvinV2ArgsType : func2 == 0b00'0011, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_w_1_vv : KelvinV2ArgsType : func2 == 0b00'0000, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_w_2_vv : KelvinV2ArgsType : func2 == 0b00'0001, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_w_3_vv : KelvinV2ArgsType : func2 == 0b00'0010, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
+ vsliden_w_4_vv : KelvinV2ArgsType : func2 == 0b00'0011, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
vslidevn_b_1_vv_m : KelvinV2ArgsType : func2 == 0b00'0000, sz == 0b00, m == 0b01, func1 == 0b110, form == 0b00;
vslidevn_b_2_vv_m : KelvinV2ArgsType : func2 == 0b00'0001, sz == 0b00, m == 0b01, func1 == 0b110, form == 0b00;
vslidevn_b_3_vv_m : KelvinV2ArgsType : func2 == 0b00'0010, sz == 0b00, m == 0b01, func1 == 0b110, form == 0b00;
@@ -1227,6 +1239,18 @@
vslidehn_w_4_vv_m : KelvinV2ArgsType : func2 == 0b00'0111, sz == 0b10, m == 0b01, func1 == 0b110, form == 0b00;
//vslidevp
+ vslidep_b_1_vv : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_b_2_vv : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_b_3_vv : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_b_4_vv : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b00, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_h_1_vv : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_h_2_vv : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_h_3_vv : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_h_4_vv : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b01, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_w_1_vv : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_w_2_vv : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_w_3_vv : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
+ vslidep_w_4_vv : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b10, m == 0b00, func1 == 0b110, form == 0b00;
vslidevp_b_1_vv_m : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b00, m == 0b01, func1 == 0b110, form == 0b00;
vslidevp_b_2_vv_m : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b00, m == 0b01, func1 == 0b110, form == 0b00;
vslidevp_b_3_vv_m : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b00, m == 0b01, func1 == 0b110, form == 0b00;
diff --git a/sim/kelvin.isa b/sim/kelvin.isa
index 764d413..6cf7aaa 100644
--- a/sim/kelvin.isa
+++ b/sim/kelvin.isa
@@ -375,7 +375,7 @@
}
// Kelvin simd instructions:
-// https://spacebeaker.googlesource.com/shodan/experimental-kelvin/+/refs/heads/master/docs/arch/isa.md
+// https://spacebeaker.googlesource.com/shodan/sw/kelvin/+/refs/heads/master/docs/kelvin_isa.md
slot kelvin_arith {
includes {
#include "sim/kelvin_instructions.h"
@@ -2866,42 +2866,78 @@
semfunc: "absl::bind_front(&KelvinVMadd<int32_t>, /*scalar*/ true, /*strip_mine*/ true)";
//vslidevn
+ vsliden_b_1_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.b.1.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 1 /* index */, false /* strip_mine */)";
+ vsliden_b_2_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.b.2.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 2 /* index */, false /* strip_mine */)";
+ vsliden_b_3_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.b.3.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 3 /* index */, false /* strip_mine */)";
+ vsliden_b_4_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.b.4.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 4 /* index */, false /* strip_mine */)";
+ vsliden_h_1_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.h.1.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 1 /* index */, false /* strip_mine */)";
+ vsliden_h_2_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.h.2.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 2 /* index */, false /* strip_mine */)";
+ vsliden_h_3_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.h.3.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 3 /* index */, false /* strip_mine */)";
+ vsliden_h_4_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.h.4.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 4 /* index */, false /* strip_mine */)";
+ vsliden_w_1_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.w.1.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 1 /* index */, false /* strip_mine */)";
+ vsliden_w_2_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.w.2.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 2 /* index */, false /* strip_mine */)";
+ vsliden_w_3_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.w.3.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 3 /* index */, false /* strip_mine */)";
+ vsliden_w_4_vv{: vs1, vs2 : vd},
+ disasm: "vsliden.w.4.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 4 /* index */, false /* strip_mine */)";
vslidevn_b_1_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.b.1.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 1 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 1 /* index */, true /* strip_mine */)";
vslidevn_b_2_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.b.2.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 2 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 2 /* index */, true /* strip_mine */)";
vslidevn_b_3_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.b.3.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 3 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 3 /* index */, true /* strip_mine */)";
vslidevn_b_4_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.b.4.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 4 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int8_t>, 4 /* index */, true /* strip_mine */)";
vslidevn_h_1_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.h.1.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 1 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 1 /* index */, true /* strip_mine */)";
vslidevn_h_2_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.h.2.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 2 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 2 /* index */, true /* strip_mine */)";
vslidevn_h_3_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.h.3.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 3 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 3 /* index */, true /* strip_mine */)";
vslidevn_h_4_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.h.4.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 4 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int16_t>, 4 /* index */, true /* strip_mine */)";
vslidevn_w_1_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.w.1.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 1 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 1 /* index */, true /* strip_mine */)";
vslidevn_w_2_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.w.2.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 2 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 2 /* index */, true /* strip_mine */)";
vslidevn_w_3_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.w.3.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 3 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 3 /* index */, true /* strip_mine */)";
vslidevn_w_4_vv_m{: vs1, vs2 : vd},
disasm: "vslidevn.w.4.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 4 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevn<int32_t>, 4 /* index */, true /* strip_mine */)";
//vslidehn
vslidehn_b_1_vv_m{: vs1, vs2 : vd},
@@ -2942,42 +2978,78 @@
semfunc: "absl::bind_front(&KelvinVSlidehn<int32_t>, 4 /* index */)";
//vslidevp
+ vslidep_b_1_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.b.1.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 1 /* index */, false /* strip_mine */)";
+ vslidep_b_2_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.b.2.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 2 /* index */, false /* strip_mine */)";
+ vslidep_b_3_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.b.3.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 3 /* index */, false /* strip_mine */)";
+ vslidep_b_4_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.b.4.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 4 /* index */, false /* strip_mine */)";
+ vslidep_h_1_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.h.1.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 1 /* index */, false /* strip_mine */)";
+ vslidep_h_2_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.h.2.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 2 /* index */, false /* strip_mine */)";
+ vslidep_h_3_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.h.3.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 3 /* index */, false /* strip_mine */)";
+ vslidep_h_4_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.h.4.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 4 /* index */, false /* strip_mine */)";
+ vslidep_w_1_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.w.1.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 1 /* index */, false /* strip_mine */)";
+ vslidep_w_2_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.w.2.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 2 /* index */, false /* strip_mine */)";
+ vslidep_w_3_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.w.3.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 3 /* index */, false /* strip_mine */)";
+ vslidep_w_4_vv{: vs1, vs2 : vd},
+ disasm: "vslidep.w.4.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 4 /* index */, false /* strip_mine */)";
vslidevp_b_1_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.b.1.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 1 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 1 /* index */, true /* strip_mine */)";
vslidevp_b_2_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.b.2.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 2 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 2 /* index */, true /* strip_mine */)";
vslidevp_b_3_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.b.3.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 3 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 3 /* index */, true /* strip_mine */)";
vslidevp_b_4_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.b.4.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 4 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int8_t>, 4 /* index */, true /* strip_mine */)";
vslidevp_h_1_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.h.1.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 1 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 1 /* index */, true /* strip_mine */)";
vslidevp_h_2_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.h.2.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 2 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 2 /* index */, true /* strip_mine */)";
vslidevp_h_3_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.h.3.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 3 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 3 /* index */, true /* strip_mine */)";
vslidevp_h_4_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.h.4.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 4 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int16_t>, 4 /* index */, true /* strip_mine */)";
vslidevp_w_1_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.w.1.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 1 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 1 /* index */, true /* strip_mine */)";
vslidevp_w_2_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.w.2.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 2 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 2 /* index */, true /* strip_mine */)";
vslidevp_w_3_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.w.3.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 3 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 3 /* index */, true /* strip_mine */)";
vslidevp_w_4_vv_m{: vs1, vs2 : vd},
disasm: "vslidevp.w.4.vv.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 4 /* index */)";
+ semfunc: "absl::bind_front(&KelvinVSlidevp<int32_t>, 4 /* index */, true /* strip_mine */)";
//vslidehp
vslidehp_b_1_vv_m{: vs1, vs2 : vd},
diff --git a/sim/kelvin_vector_instructions.cc b/sim/kelvin_vector_instructions.cc
index 33e6401..94c9724 100644
--- a/sim/kelvin_vector_instructions.cc
+++ b/sim/kelvin_vector_instructions.cc
@@ -19,7 +19,6 @@
using mpact::sim::generic::DataBuffer;
using mpact::sim::generic::GetInstructionSource;
-using mpact::sim::generic::Instruction;
using mpact::sim::riscv::RV32VectorDestinationOperand;
template <typename Vd, typename Vs1, typename Vs2>
@@ -1018,11 +1017,23 @@
int register_num;
int source_arg;
};
- const Interleave interleave_start[2][4] = {{{3, 0}, {2, 0}, {1, 0}, {0, 0}},
- {{3, 0}, {2, 0}, {1, 0}, {0, 0}}};
- const Interleave interleave_end[2][4] = {{{3, 1}, {2, 1}, {1, 1}, {0, 1}},
- {{0, 1}, {3, 0}, {2, 0}, {1, 0}}};
-
+ const Interleave interleave_start[2][4] = {{{0, 0}, {1, 0}, {2, 0}, {3, 0}},
+ {{0, 0}, {1, 0}, {2, 0}, {3, 0}}};
+ const Interleave interleave_end[2][4] = {{{0, 1}, {1, 1}, {2, 1}, {3, 1}},
+ {{1, 0}, {2, 0}, {3, 0}, {0, 1}}};
+ // Get the elements from the right up to `index`.
+ // For the horizontal mode, it treats the stripmine `vm` register based on
+ // `vs1` as a contiguous block, and only the first `index` elements from `vs2`
+ // will be used.
+ //
+ // For the vertical mode, each stripmine vector register `op_index` is mapped
+ // separatedly. it mimics the imaging tiling process shift of
+ // |--------|--------|
+ // | 4xVLEN | 4xVLEN |
+ // | (vs1) | (vs2) |
+ // |--------|--------|
+ // The vertical mode can also support the non-stripmine version to handle
+ // the last columns of the image.
if (dst_element_index + index < elts_per_register) {
auto src_element_index =
interleave_start[horizontal][op_index].register_num *
@@ -1042,16 +1053,16 @@
// Slide next register vertically by index.
template <typename T>
-void KelvinVSlidevn(int index, Instruction *inst) {
+void KelvinVSlidevn(int index, bool strip_mine, Instruction *inst) {
KelvinBinaryVectorOp(
- inst, false /* scalar */, true /* strip_mine */,
+ inst, false /* scalar */, strip_mine,
std::function<T(T, T)>([](T vs1, T vs2) -> T { return vs1; }),
SourceArgGetter<T, T, T, T>(absl::bind_front(
VSlidenOpGetArg1<T>, false /* horizontal */, index)));
}
-template void KelvinVSlidevn<int8_t>(int, Instruction *);
-template void KelvinVSlidevn<int16_t>(int, Instruction *);
-template void KelvinVSlidevn<int32_t>(int, Instruction *);
+template void KelvinVSlidevn<int8_t>(int, bool, Instruction *);
+template void KelvinVSlidevn<int16_t>(int, bool, Instruction *);
+template void KelvinVSlidevn<int32_t>(int, bool, Instruction *);
// Slide next register horizontally by index.
template <typename T>
@@ -1080,16 +1091,28 @@
int register_num;
int source_arg;
};
- const Interleave interleave_start[2][4] = {{{3, 0}, {2, 0}, {1, 0}, {0, 0}},
- {{3, 0}, {2, 0}, {1, 0}, {0, 0}}};
- const Interleave interleave_end[2][4] = {{{2, 0}, {1, 0}, {0, 0}, {3, 1}},
- {{0, 1}, {3, 0}, {2, 0}, {1, 0}}};
-
- if (dst_element_index >= index) {
+ const Interleave interleave_start[2][4] = {{{0, 0}, {1, 0}, {2, 0}, {3, 0}},
+ {{3, 0}, {0, 1}, {1, 1}, {2, 1}}};
+ const Interleave interleave_end[2][4] = {{{0, 1}, {1, 1}, {2, 1}, {3, 1}},
+ {{0, 1}, {1, 1}, {2, 1}, {3, 1}}};
+ // Get the elements from the left up to `index`.
+ // For the horizontal mode, it treats the stripmine `vm` register based on
+ // `vs2` as a contiguous block, and only the LAST `index` elements from
+ // stripmine vm register based on `vs1` will be used AT THE BEGINNING.
+ //
+ // For the vertical mode, each stripmine vector register `op_index` is mapped
+ // separatedly. it mimics the imaging tiling process shift of
+ // |--------|--------|
+ // | 4xVLEN | 4xVLEN |
+ // | (vs1) | (vs2) |
+ // |--------|--------|
+ // The vertical mode can also support the non-stripmine version to handle
+ // the last columns of the image.
+ if (dst_element_index < index) {
auto src_element_index =
interleave_start[horizontal][op_index].register_num *
elts_per_register +
- dst_element_index - index;
+ dst_element_index - index + elts_per_register;
return GetInstructionSource<T>(
inst, interleave_start[horizontal][op_index].source_arg,
src_element_index);
@@ -1097,23 +1120,23 @@
auto src_element_index =
interleave_end[horizontal][op_index].register_num * elts_per_register +
- elts_per_register + dst_element_index - index;
+ dst_element_index - index;
return GetInstructionSource<T>(
inst, interleave_end[horizontal][op_index].source_arg, src_element_index);
}
// Slide previous register vertically by index.
template <typename T>
-void KelvinVSlidevp(int index, Instruction *inst) {
+void KelvinVSlidevp(int index, bool strip_mine, Instruction *inst) {
KelvinBinaryVectorOp(
- inst, false /* scalar */, true /* strip_mine */,
+ inst, false /* scalar */, strip_mine,
std::function<T(T, T)>([](T vs1, T vs2) -> T { return vs1; }),
SourceArgGetter<T, T, T, T>(absl::bind_front(
VSlidepOpGetArg1<T>, false /* horizontal */, index)));
}
-template void KelvinVSlidevp<int8_t>(int, Instruction *);
-template void KelvinVSlidevp<int16_t>(int, Instruction *);
-template void KelvinVSlidevp<int32_t>(int, Instruction *);
+template void KelvinVSlidevp<int8_t>(int, bool, Instruction *);
+template void KelvinVSlidevp<int16_t>(int, bool, Instruction *);
+template void KelvinVSlidevp<int32_t>(int, bool, Instruction *);
// Slide previous register horizontally by index.
template <typename T>
diff --git a/sim/kelvin_vector_instructions.h b/sim/kelvin_vector_instructions.h
index 447dcc4..64a31c1 100644
--- a/sim/kelvin_vector_instructions.h
+++ b/sim/kelvin_vector_instructions.h
@@ -151,13 +151,13 @@
void KelvinVMadd(bool scalar, bool strip_mine, Instruction *inst);
template <typename T>
-void KelvinVSlidevn(int index, Instruction *inst);
+void KelvinVSlidevn(int index, bool strip_mine, Instruction *inst);
template <typename T>
void KelvinVSlidehn(int index, Instruction *inst);
template <typename T>
-void KelvinVSlidevp(int index, Instruction *inst);
+void KelvinVSlidevp(int index, bool strip_mine, Instruction *inst);
template <typename T>
void KelvinVSlidehp(int index, Instruction *inst);
diff --git a/sim/test/kelvin_vector_instructions_test.cc b/sim/test/kelvin_vector_instructions_test.cc
index f4c4c0b..ee6ccfb 100644
--- a/sim/test/kelvin_vector_instructions_test.cc
+++ b/sim/test/kelvin_vector_instructions_test.cc
@@ -259,23 +259,26 @@
}
template <template <typename> class F, typename T>
- void KelvinSlideOpHelper(absl::string_view name, bool horizontal) {
+ void KelvinSlideOpHelper(absl::string_view name, bool horizontal,
+ bool strip_mine) {
const auto name_with_type = absl::StrCat(name, KelvinTestTypeSuffix<T>());
for (int i = 1; i < 5; ++i) {
BinaryOpTestHelper<T, T, T>(
- absl::bind_front(F<T>::KelvinOp, i),
- absl::StrCat(name_with_type, i, "VM"), kNonScalar, kIsStripmine,
- F<T>::Op, absl::bind_front(F<T>::kArgsGetter, horizontal, i),
- kNonHalftypeOp, kNonVmvpOp, kNonWidenDst);
+ absl::bind_front(F<T>::KelvinOp, i, strip_mine),
+ absl::StrCat(name_with_type, i, "V", strip_mine ? "M" : ""),
+ kNonScalar, strip_mine, F<T>::Op,
+ absl::bind_front(F<T>::kArgsGetter, horizontal, i), kNonHalftypeOp,
+ kNonVmvpOp, kNonWidenDst);
}
}
template <template <typename> class F, typename T, typename TNext1,
typename... TNext>
- void KelvinSlideOpHelper(absl::string_view name, bool horizontal) {
- KelvinSlideOpHelper<F, T>(name, horizontal);
- KelvinSlideOpHelper<F, TNext1, TNext...>(name, horizontal);
+ void KelvinSlideOpHelper(absl::string_view name, bool horizontal,
+ bool strip_mine) {
+ KelvinSlideOpHelper<F, T>(name, horizontal, strip_mine);
+ KelvinSlideOpHelper<F, TNext1, TNext...>(name, horizontal, strip_mine);
}
template <template <typename> class F, typename T>
@@ -1429,10 +1432,10 @@
int register_num;
int source_arg;
};
- const Interleave interleave_start[2][4] = {{{3, 0}, {2, 0}, {1, 0}, {0, 0}},
- {{3, 0}, {2, 0}, {1, 0}, {0, 0}}};
- const Interleave interleave_end[2][4] = {{{3, 1}, {2, 1}, {1, 1}, {0, 1}},
- {{0, 1}, {3, 0}, {2, 0}, {1, 0}}};
+ const Interleave interleave_start[2][4] = {{{0, 0}, {1, 0}, {2, 0}, {3, 0}},
+ {{0, 0}, {1, 0}, {2, 0}, {3, 0}}};
+ const Interleave interleave_end[2][4] = {{{0, 1}, {1, 1}, {2, 1}, {3, 1}},
+ {{1, 0}, {2, 0}, {3, 0}, {0, 1}}};
T arg1;
if (element_index + index < vd_size) {
@@ -1460,29 +1463,33 @@
struct VSlidehnOp {
static constexpr auto kArgsGetter = SlidenArgsGetter<T>;
static T Op(T vs1, T vs2) { return vs1; }
- static void KelvinOp(int index, Instruction *inst) {
+ static void KelvinOp(int index, bool strip_mine, Instruction *inst) {
KelvinVSlidehn<T>(index, inst);
}
};
-TEST_F(KelvinVectorInstructionsTest, VSlidehnOp) {
- KelvinSlideOpHelper<VSlidehnOp, int8_t, int16_t, int32_t>("VSlidehnOp",
- kHorizontal);
+TEST_F(KelvinVectorInstructionsTest, VSlidehn) {
+ KelvinSlideOpHelper<VSlidehnOp, int8_t, int16_t, int32_t>(
+ "VSlidehnOp", kHorizontal, true /* strip_mine */);
}
-// Slide next register vertically by index.
template <typename T>
struct VSlidevnOp {
static constexpr auto kArgsGetter = SlidenArgsGetter<T>;
static T Op(T vs1, T vs2) { return vs1; }
- static void KelvinOp(int index, Instruction *inst) {
- KelvinVSlidevn<T>(index, inst);
+ static void KelvinOp(int index, bool strip_mine, Instruction *inst) {
+ KelvinVSlidevn<T>(index, strip_mine, inst);
}
};
-TEST_F(KelvinVectorInstructionsTest, VSlidevnOp) {
- KelvinSlideOpHelper<VSlidevnOp, int8_t, int16_t, int32_t>("VSlidevnOp",
- kVertical);
+TEST_F(KelvinVectorInstructionsTest, VSliden) {
+ KelvinSlideOpHelper<VSlidevnOp, int8_t, int16_t, int32_t>(
+ "VSlidenOp", kVertical, false /* strip_mine */);
+}
+
+TEST_F(KelvinVectorInstructionsTest, VSlidevn) {
+ KelvinSlideOpHelper<VSlidevnOp, int8_t, int16_t, int32_t>(
+ "VSlidevnOp", kVertical, true /* strip_mine */);
}
// Slide previous register by index.
@@ -1499,23 +1506,23 @@
int register_num;
int source_arg;
};
- const Interleave interleave_start[2][4] = {{{3, 0}, {2, 0}, {1, 0}, {0, 0}},
- {{3, 0}, {2, 0}, {1, 0}, {0, 0}}};
- const Interleave interleave_end[2][4] = {{{2, 0}, {1, 0}, {0, 0}, {3, 1}},
- {{0, 1}, {3, 0}, {2, 0}, {1, 0}}};
+ const Interleave interleave_start[2][4] = {{{0, 0}, {1, 0}, {2, 0}, {3, 0}},
+ {{3, 0}, {0, 1}, {1, 1}, {2, 1}}};
+ const Interleave interleave_end[2][4] = {{{0, 1}, {1, 1}, {2, 1}, {3, 1}},
+ {{0, 1}, {1, 1}, {2, 1}, {3, 1}}};
T arg1;
- if (element_index >= index) {
+ if (element_index < index) {
auto src_element_index =
interleave_start[horizontal][op_num].register_num * vd_size +
- element_index - index;
+ element_index - index + vd_size;
arg1 = interleave_start[horizontal][op_num].source_arg
? vs2_value[src_element_index]
: vs1_value[src_element_index];
} else {
auto src_element_index =
interleave_end[horizontal][op_num].register_num * vd_size +
- element_index - index + vd_size;
+ element_index - index;
arg1 = interleave_end[horizontal][op_num].source_arg
? vs2_value[src_element_index]
@@ -1530,29 +1537,33 @@
struct VSlidehpOp {
static constexpr auto kArgsGetter = SlidepArgsGetter<T>;
static T Op(T vs1, T vs2) { return vs1; }
- static void KelvinOp(int index, Instruction *inst) {
+ static void KelvinOp(int index, bool strip_mine, Instruction *inst) {
KelvinVSlidehp<T>(index, inst);
}
};
-TEST_F(KelvinVectorInstructionsTest, VSlidehpOp) {
- KelvinSlideOpHelper<VSlidehpOp, int8_t, int16_t, int32_t>("VSlidehpOp",
- kHorizontal);
+TEST_F(KelvinVectorInstructionsTest, VSlidehp) {
+ KelvinSlideOpHelper<VSlidehpOp, int8_t, int16_t, int32_t>(
+ "VSlidehpOp", kHorizontal, true /* strip_mine */);
}
-// Slide previous register vertically by index.
template <typename T>
struct VSlidevpOp {
static constexpr auto kArgsGetter = SlidepArgsGetter<T>;
static T Op(T vs1, T vs2) { return vs1; }
- static void KelvinOp(int index, Instruction *inst) {
- KelvinVSlidevp<T>(index, inst);
+ static void KelvinOp(int index, bool strip_mine, Instruction *inst) {
+ KelvinVSlidevp<T>(index, strip_mine, inst);
}
};
-TEST_F(KelvinVectorInstructionsTest, VSlidevpOp) {
- KelvinSlideOpHelper<VSlidevpOp, int8_t, int16_t, int32_t>("VSlidevpOp",
- kVertical);
+TEST_F(KelvinVectorInstructionsTest, VSlidep) {
+ KelvinSlideOpHelper<VSlidevpOp, int8_t, int16_t, int32_t>(
+ "VSlidepOp", kVertical, false /* strip_mine */);
+}
+
+TEST_F(KelvinVectorInstructionsTest, VSlidevp) {
+ KelvinSlideOpHelper<VSlidevpOp, int8_t, int16_t, int32_t>(
+ "VSlidevpOp", kVertical, true /* strip_mine */);
}
// Select lanes from two operands with vector selection boolean.