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.