Add `vv` variant to `vrev` and `vror`
PiperOrigin-RevId: 557944295
diff --git a/sim/kelvin_arith.bin_fmt b/sim/kelvin_arith.bin_fmt
index ac657dd..b679386 100644
--- a/sim/kelvin_arith.bin_fmt
+++ b/sim/kelvin_arith.bin_fmt
@@ -563,19 +563,31 @@
vxor_w_vx_m : KelvinV2ArgsType : func2 == 0b00'0010, sz == 0b10, m == 0b01, func1 == 0b001, form == 0b10;
//vrev
+ vrev_b_vv : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b00, m == 0b00, func1 == 0b001, form == 0b00;
vrev_b_vx : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b00, m == 0b00, func1 == 0b001, form == 0b10;
+ vrev_b_vv_m : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b00, m == 0b01, func1 == 0b001, form == 0b00;
vrev_b_vx_m : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b00, m == 0b01, func1 == 0b001, form == 0b10;
+ vrev_h_vv : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b01, m == 0b00, func1 == 0b001, form == 0b00;
vrev_h_vx : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b01, m == 0b00, func1 == 0b001, form == 0b10;
+ vrev_h_vv_m : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b01, m == 0b01, func1 == 0b001, form == 0b00;
vrev_h_vx_m : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b01, m == 0b01, func1 == 0b001, form == 0b10;
+ vrev_w_vv : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b10, m == 0b00, func1 == 0b001, form == 0b00;
vrev_w_vx : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b10, m == 0b00, func1 == 0b001, form == 0b10;
+ vrev_w_vv_m : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b10, m == 0b01, func1 == 0b001, form == 0b00;
vrev_w_vx_m : KelvinV2ArgsType : func2 == 0b00'0100, sz == 0b10, m == 0b01, func1 == 0b001, form == 0b10;
//vror
+ vror_b_vv : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b00, m == 0b00, func1 == 0b001, form == 0b00;
vror_b_vx : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b00, m == 0b00, func1 == 0b001, form == 0b10;
+ vror_b_vv_m : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b00, m == 0b01, func1 == 0b001, form == 0b00;
vror_b_vx_m : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b00, m == 0b01, func1 == 0b001, form == 0b10;
+ vror_h_vv : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b01, m == 0b00, func1 == 0b001, form == 0b00;
vror_h_vx : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b01, m == 0b00, func1 == 0b001, form == 0b10;
+ vror_h_vv_m : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b01, m == 0b01, func1 == 0b001, form == 0b00;
vror_h_vx_m : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b01, m == 0b01, func1 == 0b001, form == 0b10;
+ vror_w_vv : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b10, m == 0b00, func1 == 0b001, form == 0b00;
vror_w_vx : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b10, m == 0b00, func1 == 0b001, form == 0b10;
+ vror_w_vv_m : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b10, m == 0b01, func1 == 0b001, form == 0b00;
vror_w_vx_m : KelvinV2ArgsType : func2 == 0b00'0101, sz == 0b10, m == 0b01, func1 == 0b001, form == 0b10;
//vmvp
diff --git a/sim/kelvin_arith.isa b/sim/kelvin_arith.isa
index 3ed2350..0b4ad8f 100644
--- a/sim/kelvin_arith.isa
+++ b/sim/kelvin_arith.isa
@@ -1504,44 +1504,80 @@
semfunc: "absl::bind_front(&KelvinVXor<uint32_t>, /*scalar*/ true, /*strip_mine*/ true)";
//vrev
+ vrev_b_vv{: vs1, vs2 : vd},
+ disasm: "vrev.b.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRev<uint8_t>, /*scalar*/ false, /*strip_mine*/ false)";
vrev_b_vx{: vs1, vs2 : vd},
disasm: "vrev.b.vx", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRev<uint8_t>, /*strip_mine*/ false)";
+ semfunc: "absl::bind_front(&KelvinVRev<uint8_t>, /*scalar*/ true, /*strip_mine*/ false)";
+ vrev_b_vv_m{: vs1, vs2 : vd},
+ disasm: "vrev.b.vv.m", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRev<uint8_t>, /*scalar*/ false, /*strip_mine*/ true)";
vrev_b_vx_m{: vs1, vs2 : vd},
disasm: "vrev.b.vx.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRev<uint8_t>, /*strip_mine*/ true)";
+ semfunc: "absl::bind_front(&KelvinVRev<uint8_t>, /*scalar*/ true, /*strip_mine*/ true)";
+ vrev_h_vv{: vs1, vs2 : vd},
+ disasm: "vrev.h.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRev<uint16_t>, /*scalar*/ false, /*strip_mine*/ false)";
vrev_h_vx{: vs1, vs2 : vd},
disasm: "vrev.h.vx", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRev<uint16_t>, /*strip_mine*/ false)";
+ semfunc: "absl::bind_front(&KelvinVRev<uint16_t>, /*scalar*/ true, /*strip_mine*/ false)";
+ vrev_h_vv_m{: vs1, vs2 : vd},
+ disasm: "vrev.h.vv.m", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRev<uint16_t>, /*scalar*/ false, /*strip_mine*/ true)";
vrev_h_vx_m{: vs1, vs2 : vd},
disasm: "vrev.h.vx.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRev<uint16_t>, /*strip_mine*/ true)";
+ semfunc: "absl::bind_front(&KelvinVRev<uint16_t>, /*scalar*/ true, /*strip_mine*/ true)";
+ vrev_w_vv{: vs1, vs2 : vd},
+ disasm: "vrev.w.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRev<uint32_t>, /*scalar*/ false, /*strip_mine*/ false)";
vrev_w_vx{: vs1, vs2 : vd},
disasm: "vrev.w.vx", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRev<uint32_t>, /*strip_mine*/ false)";
+ semfunc: "absl::bind_front(&KelvinVRev<uint32_t>, /*scalar*/ true, /*strip_mine*/ false)";
+ vrev_w_vv_m{: vs1, vs2 : vd},
+ disasm: "vrev.w.vv.m", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRev<uint32_t>, /*scalar*/ false, /*strip_mine*/ true)";
vrev_w_vx_m{: vs1, vs2 : vd},
disasm: "vrev.w.vx.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRev<uint32_t>, /*strip_mine*/ true)";
+ semfunc: "absl::bind_front(&KelvinVRev<uint32_t>, /*scalar*/ true, /*strip_mine*/ true)";
//vror
+ vror_b_vv{: vs1, vs2 : vd},
+ disasm: "vror.b.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRor<uint8_t>, /*scalar*/ false, /*strip_mine*/ false)";
vror_b_vx{: vs1, vs2 : vd},
disasm: "vror.b.vx", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRor<uint8_t>, /*strip_mine*/ false)";
+ semfunc: "absl::bind_front(&KelvinVRor<uint8_t>, /*scalar*/ true, /*strip_mine*/ false)";
+ vror_b_vv_m{: vs1, vs2 : vd},
+ disasm: "vror.b.vv.m", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRor<uint8_t>, /*scalar*/ false, /*strip_mine*/ true)";
vror_b_vx_m{: vs1, vs2 : vd},
disasm: "vror.b.vx.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRor<uint8_t>, /*strip_mine*/ true)";
+ semfunc: "absl::bind_front(&KelvinVRor<uint8_t>, /*scalar*/ true, /*strip_mine*/ true)";
+ vror_h_vv{: vs1, vs2 : vd},
+ disasm: "vror.h.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRor<uint16_t>, /*scalar*/ false, /*strip_mine*/ false)";
vror_h_vx{: vs1, vs2 : vd},
disasm: "vror.h.vx", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRor<uint16_t>, /*strip_mine*/ false)";
+ semfunc: "absl::bind_front(&KelvinVRor<uint16_t>, /*scalar*/ true, /*strip_mine*/ false)";
+ vror_h_vv_m{: vs1, vs2 : vd},
+ disasm: "vror.h.vv.m", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRor<uint16_t>, /*scalar*/ false, /*strip_mine*/ true)";
vror_h_vx_m{: vs1, vs2 : vd},
disasm: "vror.h.vx.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRor<uint16_t>, /*strip_mine*/ true)";
+ semfunc: "absl::bind_front(&KelvinVRor<uint16_t>, /*scalar*/ true, /*strip_mine*/ true)";
+ vror_w_vv{: vs1, vs2 : vd},
+ disasm: "vror.w.vv", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRor<uint32_t>, /*scalar*/ false, /*strip_mine*/ false)";
vror_w_vx{: vs1, vs2 : vd},
disasm: "vror.w.vx", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRor<uint32_t>, /*strip_mine*/ false)";
+ semfunc: "absl::bind_front(&KelvinVRor<uint32_t>, /*scalar*/ true, /*strip_mine*/ false)";
+ vror_w_vv_m{: vs1, vs2 : vd},
+ disasm: "vror.w.vv.m", "%vd, %vs1, %vs2",
+ semfunc: "absl::bind_front(&KelvinVRor<uint32_t>, /*scalar*/ false, /*strip_mine*/ true)";
vror_w_vx_m{: vs1, vs2 : vd},
disasm: "vror.w.vx.m", "%vd, %vs1, %vs2",
- semfunc: "absl::bind_front(&KelvinVRor<uint32_t>, /*strip_mine*/ true)";
+ semfunc: "absl::bind_front(&KelvinVRor<uint32_t>, /*scalar*/ true, /*strip_mine*/ true)";
//vmvp
vmvp_vv{: vs1, vs2 : vd},
diff --git a/sim/kelvin_vector_instructions.cc b/sim/kelvin_vector_instructions.cc
index 1afa457..23c2dfa 100644
--- a/sim/kelvin_vector_instructions.cc
+++ b/sim/kelvin_vector_instructions.cc
@@ -618,10 +618,9 @@
// Generalized reverse using bit ladder.
template <typename T>
-void KelvinVRev(bool strip_mine, Instruction *inst) {
+void KelvinVRev(bool scalar, bool strip_mine, Instruction *inst) {
KelvinBinaryVectorOp(
- inst, true /* scalar */, strip_mine,
- std::function<T(T, T)>([](T vs1, T vs2) -> T {
+ inst, scalar, strip_mine, std::function<T(T, T)>([](T vs1, T vs2) -> T {
T r = vs1;
T count = vs2 & 0b11111;
if (count & 1) r = ((r & 0x55555555) << 1) | ((r & 0xAAAAAAAA) >> 1);
@@ -634,14 +633,14 @@
return r;
}));
}
-template void KelvinVRev<uint8_t>(bool, Instruction *);
-template void KelvinVRev<uint16_t>(bool, Instruction *);
-template void KelvinVRev<uint32_t>(bool, Instruction *);
+template void KelvinVRev<uint8_t>(bool, bool, Instruction *);
+template void KelvinVRev<uint16_t>(bool, bool, Instruction *);
+template void KelvinVRev<uint32_t>(bool, bool, Instruction *);
// Cyclic rotation right using a bit ladder.
template <typename T>
-void KelvinVRor(bool strip_mine, Instruction *inst) {
- KelvinBinaryVectorOp(inst, true /* scalar */, strip_mine,
+void KelvinVRor(bool scalar, bool strip_mine, Instruction *inst) {
+ KelvinBinaryVectorOp(inst, scalar, strip_mine,
std::function<T(T, T)>([](T vs1, T vs2) -> T {
T r = vs1;
T count = vs2 & static_cast<T>(sizeof(T) * 8 - 1);
@@ -652,9 +651,9 @@
return r;
}));
}
-template void KelvinVRor<uint8_t>(bool, Instruction *);
-template void KelvinVRor<uint16_t>(bool, Instruction *);
-template void KelvinVRor<uint32_t>(bool, Instruction *);
+template void KelvinVRor<uint8_t>(bool, bool, Instruction *);
+template void KelvinVRor<uint16_t>(bool, bool, Instruction *);
+template void KelvinVRor<uint32_t>(bool, bool, Instruction *);
// Returns Arg1 as either vs1 or vs2 based on dst_reg_index.
template <typename Vd, typename Vs1, typename Vs2>
diff --git a/sim/kelvin_vector_instructions.h b/sim/kelvin_vector_instructions.h
index 79887a8..ac4e556 100644
--- a/sim/kelvin_vector_instructions.h
+++ b/sim/kelvin_vector_instructions.h
@@ -90,10 +90,10 @@
void KelvinVXor(bool scalar, bool strip_mine, Instruction *inst);
template <typename T>
-void KelvinVRev(bool strip_mine, Instruction *inst);
+void KelvinVRev(bool scalar, bool strip_mine, Instruction *inst);
template <typename T>
-void KelvinVRor(bool strip_mine, Instruction *inst);
+void KelvinVRor(bool scalar, bool strip_mine, Instruction *inst);
template <typename T>
void KelvinVMvp(bool scalar, bool strip_mine, Instruction *inst);
diff --git a/sim/test/kelvin_vector_instructions_test.cc b/sim/test/kelvin_vector_instructions_test.cc
index 91cc4c4..a71530c 100644
--- a/sim/test/kelvin_vector_instructions_test.cc
+++ b/sim/test/kelvin_vector_instructions_test.cc
@@ -885,15 +885,15 @@
if (count & 16) r = ((r & 0x0000FFFF) << 16) | ((r & 0xFFFF0000) >> 16);
return r;
}
- static void KelvinOp(bool strip_mine, Instruction *inst) {
- KelvinVRev<Vd>(strip_mine, inst);
+ static void KelvinOp(bool scalar, bool strip_mine, Instruction *inst) {
+ KelvinVRev<Vd>(scalar, strip_mine, inst);
}
};
TEST_F(KelvinVectorInstructionsTest, VRev) {
- KelvinVectorVXBinaryOpHelper<VRevOp, uint8_t, uint8_t, uint8_t, uint16_t,
- uint16_t, uint16_t, uint32_t, uint32_t,
- uint32_t>("VRevOp");
+ KelvinVectorBinaryOpHelper<VRevOp, uint8_t, uint8_t, uint8_t, uint16_t,
+ uint16_t, uint16_t, uint32_t, uint32_t, uint32_t>(
+ "VRevOp");
}
// Cyclic rotation right using a bit ladder.
@@ -907,15 +907,15 @@
}
return r;
}
- static void KelvinOp(bool strip_mine, Instruction *inst) {
- KelvinVRor<Vd>(strip_mine, inst);
+ static void KelvinOp(bool scalar, bool strip_mine, Instruction *inst) {
+ KelvinVRor<Vd>(scalar, strip_mine, inst);
}
};
TEST_F(KelvinVectorInstructionsTest, VRor) {
- KelvinVectorVXBinaryOpHelper<VRorOp, uint8_t, uint8_t, uint8_t, uint16_t,
- uint16_t, uint16_t, uint32_t, uint32_t,
- uint32_t>("VRorOp");
+ KelvinVectorBinaryOpHelper<VRorOp, uint8_t, uint8_t, uint8_t, uint16_t,
+ uint16_t, uint16_t, uint32_t, uint32_t, uint32_t>(
+ "VRorOp");
}
// Vector move pair.