diff --git a/target/e2k/helper.h b/target/e2k/helper.h index ed2aad9dea..0f20c9fb16 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -84,6 +84,7 @@ DEF_HELPER_2(pmaddubsh, i64, i64, i64) DEF_HELPER_2(pmulhh, i64, i64, i64) DEF_HELPER_2(pmullh, i64, i64, i64) DEF_HELPER_2(pmulhuh, i64, i64, i64) +DEF_HELPER_2(pmulubhh, i64, i64, i64) /* Packed Move Mask */ DEF_HELPER_2(pmovmskb, i64, i64, i64) diff --git a/target/e2k/helper_vec.c b/target/e2k/helper_vec.c index 37bfabd093..639a783ce2 100644 --- a/target/e2k/helper_vec.c +++ b/target/e2k/helper_vec.c @@ -36,6 +36,8 @@ typedef union { } vec64; #define ident(x) x +#define shr16(x) ((x) >> 16) +#define and16(x) ((x) & 0xffff) #define satsb(x) MIN(MAX(x, -128), 127) #define satsh(x) MIN(MAX(x, -32768), 32767) #define satub(x) MIN(MAX(x, 0), 255) @@ -146,14 +148,17 @@ GEN_HELPER_PACKED(psadbw, ub, { dst.uw[0] += s1.ub[i] - s2.ub[i]; }) GEN_HELPER_PACKED(pavgusb, ub, { dst.ub[i] = (s1.ub[i] + s2.ub[i] + 1) >> 1; }) GEN_HELPER_PACKED(pavgush, uh, { dst.uh[i] = (s1.uh[i] + s2.uh[i] + 1) >> 1; }) -GEN_HELPER_PACKED(pmulhh, sh, { \ - dst.sh[i] = ((int32_t) s1.sh[i] * s2.sh[i]) >> 16; \ -}) -GEN_HELPER_PACKED(pmullh, sh, { \ - dst.sh[i] = ((int32_t) s1.sh[i] * s2.sh[i]) & 0xffff; \ -}) -GEN_HELPER_PACKED(pmulhuh, uh, { \ - dst.uh[i] = ((uint32_t) s1.uh[i] * s2.uh[i]) >> 16; \ +#define GEN_HELPER_PACKED_MULH(name, type, cast, map) \ + GEN_HELPER_PACKED(name, type, { \ + dst.type[i] = map(((cast) s1.type[i]) * s2.type[i]); \ + }) + +GEN_HELPER_PACKED_MULH(pmulhh, sh, int32_t, shr16) +GEN_HELPER_PACKED_MULH(pmullh, sh, int32_t, and16) +GEN_HELPER_PACKED_MULH(pmulhuh, uh, uint32_t, shr16) + +GEN_HELPER_PACKED(pmulubhh, uh, { \ + dst.uh[i] = (((int16_t) s1.ub[i] * s2.sh[i]) + s1.ub[i]) >> 8; \ }) #define MOVMASK(mask_type, type) { \ diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index 4574aea9e1..4dc9688b70 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -3103,6 +3103,7 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_PMULHH: gen_alopf1_ddd(instr, gen_helper_pmulhh); break; case OP_PMULLH: gen_alopf1_ddd(instr, gen_helper_pmullh); break; case OP_PMULHUH: gen_alopf1_ddd(instr, gen_helper_pmulhuh); break; + case OP_PMULUBHH: gen_alopf1_ddd(instr, gen_helper_pmulubhh); break; case OP_PMADDH: gen_alopf1_ddd(instr, gen_helper_pmaddh); break; case OP_PMADDUBSH: gen_alopf1_ddd(instr, gen_helper_pmaddubsh); break; case OP_PSADBW: gen_alopf1_ddd(instr, gen_helper_psadbw); break; @@ -3426,7 +3427,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_MOVX: case OP_MOVXA: case OP_MOVXC: - case OP_PMULUBHH: case OP_MPSADBH: case OP_PACKUSWH: case OP_PFHADDS: