Fix `vzip` stripmine instruction PiperOrigin-RevId: 561748361
diff --git a/sim/kelvin_vector_instructions.cc b/sim/kelvin_vector_instructions.cc index 48d484f..241789d 100644 --- a/sim/kelvin_vector_instructions.cc +++ b/sim/kelvin_vector_instructions.cc
@@ -1283,17 +1283,20 @@ template void KelvinVEvnodd<int32_t>(bool, bool, Instruction *); // Interleave even/odd lanes of two operands. -// Returns odd elements of concatenated registers. +// Returns even elements of concatenated registers. template <typename T> T VZipOpGetArg1(const Instruction *inst, bool scalar, int num_ops, int op_index, int dst_element_index, int dst_reg_index) { auto state = static_cast<KelvinState *>(inst->state()); const int vector_size_in_bytes = state->vector_length() / 8; const int elts_per_register = vector_size_in_bytes / sizeof(T); + const int half_elts_per_register = elts_per_register / 2; - auto src_element_index = op_index * elts_per_register + + // Only takes the even elements. For the stripmine version, the offset are + // counted as half of the register size. + auto src_element_index = op_index * half_elts_per_register + dst_element_index / 2 + - dst_reg_index * elts_per_register / 2; + dst_reg_index * half_elts_per_register * num_ops; if (dst_element_index & 1) { return GetInstructionSource<T>(inst, 1, scalar ? 0 : src_element_index);
diff --git a/sim/test/kelvin_vector_instructions_test.cc b/sim/test/kelvin_vector_instructions_test.cc index 7a11d44..4b057e3 100644 --- a/sim/test/kelvin_vector_instructions_test.cc +++ b/sim/test/kelvin_vector_instructions_test.cc
@@ -1654,8 +1654,9 @@ const std::vector<T> &vs1_value, int vs2_size, bool s2_scalar, const std::vector<T> &vs2_value, T rs2_value, bool halftype_op, bool vmvp_op) { - auto src_index = - op_num * vs1_size + element_index / 2 + dest_reg_sub_index * vs1_size / 2; + auto src_index = (op_num * vs1_size + element_index + + dest_reg_sub_index * vs1_size * num_ops) / + 2; T arg1; if (element_index & 1) {