diff --git a/target/e2k/helper.h b/target/e2k/helper.h index d299f654e0..062691be6a 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -95,6 +95,14 @@ DEF_HELPER_2(packsshb, i64, i64, i64) DEF_HELPER_2(packsswh, i64, i64, i64) DEF_HELPER_2(packushb, i64, i64, i64) +/* Packed unpacks */ +DEF_HELPER_2(punpcklbh, i64, i64, i64) +DEF_HELPER_2(punpcklhw, i64, i64, i64) +DEF_HELPER_2(punpcklwd, i64, i64, i64) +DEF_HELPER_2(punpckhbh, i64, i64, i64) +DEF_HELPER_2(punpckhhw, i64, i64, i64) +DEF_HELPER_2(punpckhwd, i64, i64, i64) + /* Packed shuffle */ DEF_HELPER_3(pshufb, i64, i64, i64, i64) DEF_HELPER_3(pshufw, i64, i64, i64, i32) diff --git a/target/e2k/helper_vec.c b/target/e2k/helper_vec.c index 155151d3bb..2ce596975e 100644 --- a/target/e2k/helper_vec.c +++ b/target/e2k/helper_vec.c @@ -174,6 +174,19 @@ GEN_HELPER_PACKED(packsshb, sh, PACK(sb, sh, satsb)) GEN_HELPER_PACKED(packushb, uh, PACK(ub, sh, satub)) GEN_HELPER_PACKED(packsswh, sw, PACK(sh, sw, satsh)) +#define GEN_HELPER_PACKED_UNPACK(name, type, offset) \ + GEN_HELPER_PACKED(name, type, { \ + int j = offset + i / 2; \ + dst.type[i] = i & 1 ? s1.type[j] : s2.type[j]; \ + }) + +GEN_HELPER_PACKED_UNPACK(punpcklbh, ub, 0) +GEN_HELPER_PACKED_UNPACK(punpcklhw, uh, 0) +GEN_HELPER_PACKED_UNPACK(punpcklwd, uw, 0) +GEN_HELPER_PACKED_UNPACK(punpckhbh, ub, 4) +GEN_HELPER_PACKED_UNPACK(punpckhhw, uh, 2) +GEN_HELPER_PACKED_UNPACK(punpckhwd, uw, 1) + uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3) { vec64 ret, s1, s2, s3; diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index ca9308cb43..5d2b95f677 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -3110,16 +3110,22 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_PINSH: gen_alopf11_dddi(instr, gen_pinsh); break; case OP_PEXTRH: gen_alopf11_dddi(instr, gen_pextrh); break; case OP_PSHUFW: gen_alopf11_dddi(instr, gen_pshufw); break; - case OP_GETTAGS: gen_gettag_i32(instr); break; - case OP_GETTAGD: gen_gettag_i64(instr); break; - case OP_PUTTAGS: gen_puttag_i32(instr); break; - case OP_PUTTAGD: gen_puttag_i64(instr); break; case OP_PMOVMSKB: gen_alopf1_ddd(instr, gen_helper_pmovmskb); break; case OP_PMOVMSKPS: gen_alopf1_ddd(instr, gen_helper_pmovmskps); break; case OP_PMOVMSKPD: gen_alopf1_ddd(instr, gen_helper_pmovmskpd); break; case OP_PACKSSHB: gen_alopf1_ddd(instr, gen_helper_packsshb); break; case OP_PACKUSHB: gen_alopf1_ddd(instr, gen_helper_packushb); break; case OP_PACKSSWH: gen_alopf1_ddd(instr, gen_helper_packsswh); break; + case OP_PUNPCKLBH: gen_alopf1_ddd(instr, gen_helper_punpcklbh); break; + case OP_PUNPCKLHW: gen_alopf1_ddd(instr, gen_helper_punpcklhw); break; + case OP_PUNPCKLWD: gen_alopf1_ddd(instr, gen_helper_punpcklwd); break; + case OP_PUNPCKHBH: gen_alopf1_ddd(instr, gen_helper_punpckhbh); break; + case OP_PUNPCKHHW: gen_alopf1_ddd(instr, gen_helper_punpckhhw); break; + case OP_PUNPCKHWD: gen_alopf1_ddd(instr, gen_helper_punpckhwd); break; + case OP_GETTAGS: gen_gettag_i32(instr); break; + case OP_GETTAGD: gen_gettag_i64(instr); break; + case OP_PUTTAGS: gen_puttag_i32(instr); break; + case OP_PUTTAGD: gen_puttag_i64(instr); break; case OP_STAAB: gen_staa_i32(instr, MO_8); break; case OP_STAAH: gen_staa_i32(instr, MO_16); break; case OP_STAAW: gen_staa_i32(instr, MO_32); break; @@ -3320,12 +3326,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_PFCMPNLTD: case OP_PFCMPNLED: case OP_PFCMPODD: - case OP_PUNPCKHBH: - case OP_PUNPCKHHW: - case OP_PUNPCKHWD: - case OP_PUNPCKLBH: - case OP_PUNPCKLHW: - case OP_PUNPCKLWD: case OP_LDGDB: case OP_LDGDH: case OP_LDGDW: