e2k: Add phadd{,s}{h,w} and phsub{,s}{h,w} instrs.

This commit is contained in:
Denis Drakhnia 2021-01-16 16:03:20 +02:00 committed by Denis Drakhnia
parent e33a9d258b
commit 780ccf14ab
3 changed files with 41 additions and 8 deletions

View File

@ -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)

View File

@ -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; \

View File

@ -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: