Add vx variant support to `vsha` and `vshl`

PiperOrigin-RevId: 557259090
diff --git a/sim/kelvin_shift.bin_fmt b/sim/kelvin_shift.bin_fmt
index fb061ed..ba2f37f 100644
--- a/sim/kelvin_shift.bin_fmt
+++ b/sim/kelvin_shift.bin_fmt
@@ -45,31 +45,55 @@
 
   //vsha
   vsha_b_vv       : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b00;
+  vsha_b_vx       : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b10;
   vsha_b_vv_m     : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b00;
+  vsha_b_vx_m     : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b10;
   vsha_h_vv       : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b00;
+  vsha_h_vx       : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b10;
   vsha_h_vv_m     : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b00;
+  vsha_h_vx_m     : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b10;
   vsha_w_vv       : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b00;
+  vsha_w_vx       : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b10;
   vsha_w_vv_m     : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b00;
+  vsha_w_vx_m     : KelvinV2ArgsType : func2 == 0b00'1000, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b10;
   vsha_b_r_vv     : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b00;
+  vsha_b_r_vx     : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b10;
   vsha_b_r_vv_m   : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b00;
+  vsha_b_r_vx_m   : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b10;
   vsha_h_r_vv     : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b00;
+  vsha_h_r_vx     : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b10;
   vsha_h_r_vv_m   : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b00;
+  vsha_h_r_vx_m   : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b10;
   vsha_w_r_vv     : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b00;
+  vsha_w_r_vx     : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b10;
   vsha_w_r_vv_m   : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b00;
+  vsha_w_r_vx_m   : KelvinV2ArgsType : func2 == 0b00'1010, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b10;
 
   //vshl
   vshl_b_vv       : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b00;
+  vshl_b_vx       : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b10;
   vshl_b_vv_m     : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b00;
+  vshl_b_vx_m     : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b10;
   vshl_h_vv       : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b00;
+  vshl_h_vx       : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b10;
   vshl_h_vv_m     : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b00;
+  vshl_h_vx_m     : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b10;
   vshl_w_vv       : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b00;
+  vshl_w_vx       : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b10;
   vshl_w_vv_m     : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b00;
+  vshl_w_vx_m     : KelvinV2ArgsType : func2 == 0b00'1001, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b10;
   vshl_b_r_vv     : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b00;
+  vshl_b_r_vx     : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b00, m == 0b00, func1 == 0b010, form == 0b10;
   vshl_b_r_vv_m   : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b00;
+  vshl_b_r_vx_m   : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b00, m == 0b01, func1 == 0b010, form == 0b10;
   vshl_h_r_vv     : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b00;
+  vshl_h_r_vx     : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b01, m == 0b00, func1 == 0b010, form == 0b10;
   vshl_h_r_vv_m   : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b00;
+  vshl_h_r_vx_m   : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b01, m == 0b01, func1 == 0b010, form == 0b10;
   vshl_w_r_vv     : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b00;
+  vshl_w_r_vx     : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b10, m == 0b00, func1 == 0b010, form == 0b10;
   vshl_w_r_vv_m   : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b00;
+  vshl_w_r_vx_m   : KelvinV2ArgsType : func2 == 0b00'1011, sz == 0b10, m == 0b01, func1 == 0b010, form == 0b10;
 
   //vnot
   vnot_v          : KelvinV2ArgsType : func2 == 0b00'0011, vs2 == 0, m == 0b00, func1 == 0b001, form == 0b10;
diff --git a/sim/kelvin_shift.isa b/sim/kelvin_shift.isa
index 9477806..fcc671c 100644
--- a/sim/kelvin_shift.isa
+++ b/sim/kelvin_shift.isa
@@ -133,78 +133,150 @@
     //vsha
     vsha_b_vv{: vs1, vs2 : vd},
       disasm: "vsha.b.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ false, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ false)";
+    vsha_b_vx{: vs1, vs2 : vd},
+      disasm: "vsha.b.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ false)";
     vsha_b_vv_m{: vs1, vs2 : vd},
       disasm: "vsha.b.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ false, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ true)";
+    vsha_b_vx_m{: vs1, vs2 : vd},
+      disasm: "vsha.b.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ true)";
     vsha_h_vv{: vs1, vs2 : vd},
       disasm: "vsha.h.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ false, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ false)";
+    vsha_h_vx{: vs1, vs2 : vd},
+      disasm: "vsha.h.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ false)";
     vsha_h_vv_m{: vs1, vs2 : vd},
       disasm: "vsha.h.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ false, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ true)";
+    vsha_h_vx_m{: vs1, vs2 : vd},
+      disasm: "vsha.h.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ true)";
     vsha_w_vv{: vs1, vs2 : vd},
       disasm: "vsha.w.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ false, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ false)";
+    vsha_w_vx{: vs1, vs2 : vd},
+      disasm: "vsha.w.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ false)";
     vsha_w_vv_m{: vs1, vs2 : vd},
       disasm: "vsha.w.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ false, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ true)";
+    vsha_w_vx_m{: vs1, vs2 : vd},
+      disasm: "vsha.w.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ true)";
     vsha_b_r_vv{: vs1, vs2 : vd},
       disasm: "vsha.b.r.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ true, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ false)";
+    vsha_b_r_vx{: vs1, vs2 : vd},
+      disasm: "vsha.b.r.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ false)";
     vsha_b_r_vv_m{: vs1, vs2 : vd},
       disasm: "vsha.b.r.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ true, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ true)";
+    vsha_b_r_vx_m{: vs1, vs2 : vd},
+      disasm: "vsha.b.r.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int8_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ true)";
     vsha_h_r_vv{: vs1, vs2 : vd},
       disasm: "vsha.h.r.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ true, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ false)";
+    vsha_h_r_vx{: vs1, vs2 : vd},
+      disasm: "vsha.h.r.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ false)";
     vsha_h_r_vv_m{: vs1, vs2 : vd},
       disasm: "vsha.h.r.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ true, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ true)";
+    vsha_h_r_vx_m{: vs1, vs2 : vd},
+      disasm: "vsha.h.r.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int16_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ true)";
     vsha_w_r_vv{: vs1, vs2 : vd},
       disasm: "vsha.w.r.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ true, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ false)";
+    vsha_w_r_vx{: vs1, vs2 : vd},
+      disasm: "vsha.w.r.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ false)";
     vsha_w_r_vv_m{: vs1, vs2 : vd},
       disasm: "vsha.w.r.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ true, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ true)";
+    vsha_w_r_vx_m{: vs1, vs2 : vd},
+      disasm: "vsha.w.r.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<int32_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ true)";
 
     //vshl
     vshl_b_vv{: vs1, vs2 : vd},
       disasm: "vshl.b.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ false, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ false)";
+    vshl_b_vx{: vs1, vs2 : vd},
+      disasm: "vshl.b.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ false)";
     vshl_b_vv_m{: vs1, vs2 : vd},
       disasm: "vshl.b.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ false, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ true)";
+    vshl_b_vx_m{: vs1, vs2 : vd},
+      disasm: "vshl.b.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ true)";
     vshl_h_vv{: vs1, vs2 : vd},
       disasm: "vshl.h.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ false, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ false)";
+    vshl_h_vx{: vs1, vs2 : vd},
+      disasm: "vshl.h.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ false)";
     vshl_h_vv_m{: vs1, vs2 : vd},
       disasm: "vshl.h.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ false, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ true)";
+    vshl_h_vx_m{: vs1, vs2 : vd},
+      disasm: "vshl.h.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ true)";
     vshl_w_vv{: vs1, vs2 : vd},
       disasm: "vshl.w.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ false, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ false)";
+    vshl_w_vx{: vs1, vs2 : vd},
+      disasm: "vshl.w.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ false)";
     vshl_w_vv_m{: vs1, vs2 : vd},
       disasm: "vshl.w.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ false, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ false, /* scalar */ false, /*strip_mine*/ true)";
+    vshl_w_vx_m{: vs1, vs2 : vd},
+      disasm: "vshl.w.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ false, /* scalar */ true, /*strip_mine*/ true)";
     vshl_b_r_vv{: vs1, vs2 : vd},
       disasm: "vshl.b.r.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ true, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ false)";
+    vshl_b_r_vx{: vs1, vs2 : vd},
+      disasm: "vshl.b.r.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ false)";
     vshl_b_r_vv_m{: vs1, vs2 : vd},
       disasm: "vshl.b.r.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ true, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ true)";
+    vshl_b_r_vx_m{: vs1, vs2 : vd},
+      disasm: "vshl.b.r.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint8_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ true)";
     vshl_h_r_vv{: vs1, vs2 : vd},
       disasm: "vshl.h.r.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ true, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ false)";
+    vshl_h_r_vx{: vs1, vs2 : vd},
+      disasm: "vshl.h.r.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ false)";
     vshl_h_r_vv_m{: vs1, vs2 : vd},
       disasm: "vshl.h.r.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ true, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ true)";
+    vshl_h_r_vx_m{: vs1, vs2 : vd},
+      disasm: "vshl.h.r.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint16_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ true)";
     vshl_w_r_vv{: vs1, vs2 : vd},
       disasm: "vshl.w.r.vv", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ true, /*strip_mine*/ false)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ false)";
+    vshl_w_r_vx{: vs1, vs2 : vd},
+      disasm: "vshl.w.r.vx", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ false)";
     vshl_w_r_vv_m{: vs1, vs2 : vd},
       disasm: "vshl.w.r.vv.m", "%vd, %vs1, %vs2",
-      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ true, /*strip_mine*/ true)";
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ true, /* scalar */ false, /*strip_mine*/ true)";
+    vshl_w_r_vx_m{: vs1, vs2 : vd},
+      disasm: "vshl.w.r.vx.m", "%vd, %vs1, %vs2",
+      semfunc: "absl::bind_front(&KelvinVShift<uint32_t>, /* round */ true, /* scalar */ true, /*strip_mine*/ true)";
 
     //vnot
     vnot_v{: vs1 : vd},
diff --git a/sim/kelvin_vector_instructions.cc b/sim/kelvin_vector_instructions.cc
index da4c8d7..432d91d 100644
--- a/sim/kelvin_vector_instructions.cc
+++ b/sim/kelvin_vector_instructions.cc
@@ -777,17 +777,17 @@
 }
 
 template <typename T>
-void KelvinVShift(bool round, bool strip_mine, Instruction *inst) {
+void KelvinVShift(bool round, bool scalar, bool strip_mine, Instruction *inst) {
   KelvinBinaryVectorOp(
-      inst, false /* scalar */, strip_mine,
+      inst, scalar, strip_mine,
       std::function<T(T, T)>(absl::bind_front(&KelvinVShiftHelper<T>, round)));
 }
-template void KelvinVShift<int8_t>(bool, bool, Instruction *);
-template void KelvinVShift<int16_t>(bool, bool, Instruction *);
-template void KelvinVShift<int32_t>(bool, bool, Instruction *);
-template void KelvinVShift<uint8_t>(bool, bool, Instruction *);
-template void KelvinVShift<uint16_t>(bool, bool, Instruction *);
-template void KelvinVShift<uint32_t>(bool, bool, Instruction *);
+template void KelvinVShift<int8_t>(bool, bool, bool, Instruction *);
+template void KelvinVShift<int16_t>(bool, bool, bool, Instruction *);
+template void KelvinVShift<int32_t>(bool, bool, bool, Instruction *);
+template void KelvinVShift<uint8_t>(bool, bool, bool, Instruction *);
+template void KelvinVShift<uint16_t>(bool, bool, bool, Instruction *);
+template void KelvinVShift<uint32_t>(bool, bool, bool, Instruction *);
 
 // Bitwise not.
 template <typename T>
diff --git a/sim/kelvin_vector_instructions.h b/sim/kelvin_vector_instructions.h
index 64a31c1..79887a8 100644
--- a/sim/kelvin_vector_instructions.h
+++ b/sim/kelvin_vector_instructions.h
@@ -108,7 +108,7 @@
 void KelvinVSrl(bool scalar, bool strip_mine, Instruction *inst);
 
 template <typename T>
-void KelvinVShift(bool round, bool strip_mine, Instruction *inst);
+void KelvinVShift(bool round, bool scalar, bool strip_mine, Instruction *inst);
 
 template <typename T>
 void KelvinVNot(bool strip_mine, Instruction *inst);
diff --git a/sim/test/kelvin_vector_instructions_test.cc b/sim/test/kelvin_vector_instructions_test.cc
index 8b5ed9c..5dd7bb6 100644
--- a/sim/test/kelvin_vector_instructions_test.cc
+++ b/sim/test/kelvin_vector_instructions_test.cc
@@ -204,29 +204,20 @@
   void KelvinVectorShiftBinaryOpHelper(absl::string_view name) {
     const auto name_with_type = absl::StrCat(name, KelvinTestTypeSuffix<T>());
 
-    // Vector OP vector-vector.
-    BinaryOpTestHelper<T, T, T>(
-        absl::bind_front(F<T, T, T>::KelvinOp, kNonRounding, kNonStripmine),
-        absl::StrCat(name_with_type, "VV"), kNonScalar, kNonStripmine,
-        absl::bind_front(F<T, T, T>::Op, kNonRounding));
-
-    // Vector OP vector-vector stripmined.
-    BinaryOpTestHelper<T, T, T>(
-        absl::bind_front(F<T, T, T>::KelvinOp, kNonRounding, kIsStripmine),
-        absl::StrCat(name_with_type, "VVM"), kNonScalar, kIsStripmine,
-        absl::bind_front(F<T, T, T>::Op, kNonRounding));
-
-    // Vector OP vector-vector with rounding.
-    BinaryOpTestHelper<T, T, T>(
-        absl::bind_front(F<T, T, T>::KelvinOp, kIsRounding, kNonStripmine),
-        absl::StrCat(name_with_type, "RVV"), kNonScalar, kNonStripmine,
-        absl::bind_front(F<T, T, T>::Op, kIsRounding));
-
-    // Vector OP vector-vector stripmined with rounding.
-    BinaryOpTestHelper<T, T, T>(
-        absl::bind_front(F<T, T, T>::KelvinOp, kIsRounding, kIsStripmine),
-        absl::StrCat(name_with_type, "RVVM"), kNonScalar, kIsStripmine,
-        absl::bind_front(F<T, T, T>::Op, kIsRounding));
+    // Test {R}.[VV, VX].{M} variants.
+    for (auto rounding : {kNonRounding, kIsRounding}) {
+      for (auto scalar : {kNonScalar, kIsScalar}) {
+        for (auto stripmine : {kNonStripmine, kIsStripmine}) {
+          auto op_name = absl::StrCat(name_with_type, rounding ? "R" : "", "V",
+                                      scalar ? "X" : "V", stripmine ? "M" : "");
+          BinaryOpTestHelper<T, T, T>(
+              absl::bind_front(F<T, T, T>::KelvinOp, rounding, scalar,
+                               stripmine),
+              op_name, scalar, stripmine,
+              absl::bind_front(F<T, T, T>::Op, rounding));
+        }
+      }
+    }
   }
 
   template <template <typename, typename, typename> class F, typename T,
@@ -1058,8 +1049,9 @@
     }
   }
 
-  static void KelvinOp(bool round, bool strip_mine, Instruction *inst) {
-    KelvinVShift<Vd>(round, strip_mine, inst);
+  static void KelvinOp(bool round, bool scalar, bool strip_mine,
+                       Instruction *inst) {
+    KelvinVShift<Vd>(round, scalar, strip_mine, inst);
   }
 };