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.