From 780ccf14abd5d8e1dc85166f0844f31af3f506ef Mon Sep 17 00:00:00 2001 From: Denis Drakhnya Date: Sat, 16 Jan 2021 16:03:20 +0200 Subject: [PATCH] e2k: Add phadd{,s}{h,w} and phsub{,s}{h,w} instrs. --- target/e2k/helper.h | 10 ++++++++++ target/e2k/helper_vec.c | 27 +++++++++++++++++++++++++-- target/e2k/translate/alc.c | 12 ++++++------ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/target/e2k/helper.h b/target/e2k/helper.h index 8181be6a8d..989589afc7 100644 --- a/target/e2k/helper.h +++ b/target/e2k/helper.h @@ -56,6 +56,16 @@ DEF_HELPER_2(pcmpgth, i64, i64, i64) DEF_HELPER_2(pcmpgtw, i64, i64, i64) DEF_HELPER_2(pcmpgtd, i64, i64, i64) +/* Pached Horizontal Add */ +DEF_HELPER_2(phaddh, i64, i64, i64) +DEF_HELPER_2(phaddw, i64, i64, i64) +DEF_HELPER_2(phaddsh, i64, i64, i64) + +/* Packed Horizontal Sub */ +DEF_HELPER_2(phsubh, i64, i64, i64) +DEF_HELPER_2(phsubw, i64, i64, i64) +DEF_HELPER_2(phsubsh, i64, i64, i64) + /* Packed Add using saturation */ DEF_HELPER_2(paddsb, i64, i64, i64) DEF_HELPER_2(paddsh, i64, i64, i64) diff --git a/target/e2k/helper_vec.c b/target/e2k/helper_vec.c index d0b9358a22..d42a12137f 100644 --- a/target/e2k/helper_vec.c +++ b/target/e2k/helper_vec.c @@ -24,6 +24,8 @@ static uint8_t reverse_bits(uint8_t b) #define vec64_sw vec64_uw #define vec64_sd vec64_ud +#define vec64_len(type) glue(vec64_, type) + typedef union { uint8_t ub[vec64_ub]; uint16_t uh[vec64_uh]; @@ -43,17 +45,24 @@ typedef union { #define satub(x) MIN(MAX(x, 0), 255) #define satuh(x) MIN(MAX(x, 0), 65535) -#define GEN_HELPER_PACKED(name, type, code) \ +#define add(a, b) ((a) + (b)) +#define sub(a, b) ((a) - (b)) +#define mul(a, b) ((a) * (b)) +#define div(a, b) ((a) / (b)) + +#define GEN_HELPER_PACKED_N(name, n, code) \ uint64_t HELPER(name)(uint64_t src1, uint64_t src2) \ { \ size_t i = 0; \ vec64 s1 = { .ud[0] = src1 }, s2 = { .ud[0] = src2 }; \ vec64 dst = { .ud[0] = 0 }; \ - for (; i < glue(vec64_, type); i++) { \ + for (; i < n; i++) { \ code \ } \ return dst.ud[0]; \ } +#define GEN_HELPER_PACKED(name, type, code) \ + GEN_HELPER_PACKED_N(name, vec64_len(type), code) #define GEN_HELPER_PACKED_SCALAR(name, type, code) \ uint64_t HELPER(name)(uint64_t src1, uint64_t s2) \ { \ @@ -113,6 +122,20 @@ GEN_HELPER_PACKED_BINOP_MAP(psubsh, sh, -, int32_t, satsh) GEN_HELPER_PACKED_BINOP_MAP(psubusb, ub, -, uint16_t, satub) GEN_HELPER_PACKED_BINOP_MAP(psubush, uh, -, uint32_t, satuh) +#define GEN_HELPER_PACKED_HORIZONTAL_OP(name, type, op, map) \ + GEN_HELPER_PACKED_N(name, vec64_len(type) / 2, { \ + int j = i * 2; \ + dst.type[i ] = map(op(s1.type[j], s1.type[j + 1])); \ + dst.type[i + vec64_len(type) / 2] = map(op(s2.type[j], s2.type[j + 1])); \ + }) + +GEN_HELPER_PACKED_HORIZONTAL_OP(phaddh, sh, add, ident) +GEN_HELPER_PACKED_HORIZONTAL_OP(phaddw, sw, add, ident) +GEN_HELPER_PACKED_HORIZONTAL_OP(phaddsh, sh, add, satsh) +GEN_HELPER_PACKED_HORIZONTAL_OP(phsubh, sh, sub, ident) +GEN_HELPER_PACKED_HORIZONTAL_OP(phsubw, sw, sub, ident) +GEN_HELPER_PACKED_HORIZONTAL_OP(phsubsh, sh, sub, satsh) + #define GEN_HELPER_PACKED_SCALAR_BINOP(name, type, op) \ GEN_HELPER_PACKED_SCALAR(name, type, { \ dst.type[i] = s1.type[i] op s2; \ diff --git a/target/e2k/translate/alc.c b/target/e2k/translate/alc.c index 301c166d6b..eb39671f1b 100644 --- a/target/e2k/translate/alc.c +++ b/target/e2k/translate/alc.c @@ -3092,6 +3092,9 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_PADDSH: gen_alopf1_ddd(instr, gen_helper_paddsh); break; case OP_PADDUSB: gen_alopf1_ddd(instr, gen_helper_paddusb); break; case OP_PADDUSH: gen_alopf1_ddd(instr, gen_helper_paddush); break; + case OP_PHADDH: gen_alopf1_ddd(instr, gen_helper_phaddh); break; + case OP_PHADDW: gen_alopf1_ddd(instr, gen_helper_phaddw); break; + case OP_PHADDSH: gen_alopf1_ddd(instr, gen_helper_phaddsh); break; case OP_PSUBB: gen_alopf1_ddd(instr, tcg_gen_vec_sub8_i64); break; case OP_PSUBH: gen_alopf1_ddd(instr, tcg_gen_vec_sub16_i64); break; case OP_PSUBW: gen_alopf1_ddd(instr, tcg_gen_vec_sub32_i64); break; @@ -3100,6 +3103,9 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_PSUBSH: gen_alopf1_ddd(instr, gen_helper_psubsh); break; case OP_PSUBUSB: gen_alopf1_ddd(instr, gen_helper_psubusb); break; case OP_PSUBUSH: gen_alopf1_ddd(instr, gen_helper_psubush); break; + case OP_PHSUBH: gen_alopf1_ddd(instr, gen_helper_phsubh); break; + case OP_PHSUBW: gen_alopf1_ddd(instr, gen_helper_phsubw); break; + case OP_PHSUBSH: gen_alopf1_ddd(instr, gen_helper_phsubsh); break; 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; @@ -3434,12 +3440,6 @@ static void gen_op(DisasContext *ctx, Instr *instr) case OP_PFADDSUBS: case OP_PFSTOIFS: case OP_PFDTOIFD: - case OP_PHADDH: - case OP_PHADDW: - case OP_PHADDSH: - case OP_PHSUBH: - case OP_PHSUBW: - case OP_PHSUBSH: case OP_PSIGNB: case OP_PSIGNH: case OP_PSIGNW: