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.