e2k: Add pshufw instr.
This commit is contained in:
parent
dc9b17e91a
commit
06471fe869
@ -25,7 +25,6 @@ DEF_HELPER_1(break_restore_state, void, env)
|
||||
DEF_HELPER_2(setwd, void, env, i32)
|
||||
DEF_HELPER_2(probe_read_access, int, env, tl)
|
||||
DEF_HELPER_2(probe_write_access, int, env, tl)
|
||||
DEF_HELPER_3(packed_shuffle_i64, i64, i64, i64, i64)
|
||||
|
||||
DEF_HELPER_1(aau_load_program, void, env)
|
||||
DEF_HELPER_3(mova_ptr, tl, env, int, int)
|
||||
@ -96,6 +95,10 @@ DEF_HELPER_2(packsshb, i64, i64, i64)
|
||||
DEF_HELPER_2(packsswh, i64, i64, i64)
|
||||
DEF_HELPER_2(packushb, i64, i64, i64)
|
||||
|
||||
/* Packed shuffle */
|
||||
DEF_HELPER_3(pshufb, i64, i64, i64, i64)
|
||||
DEF_HELPER_3(pshufw, i64, i64, i64, i32)
|
||||
|
||||
/* Packed uncategorized */
|
||||
DEF_HELPER_2(psadbw, i64, i64, i64)
|
||||
DEF_HELPER_2(pavgusb, i64, i64, i64)
|
||||
|
@ -41,75 +41,6 @@ typedef union {
|
||||
#define satub(x) MIN(MAX(x, 0), 255)
|
||||
#define satuh(x) MIN(MAX(x, 0), 65535)
|
||||
|
||||
uint64_t HELPER(packed_shuffle_i64)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
{
|
||||
vec64 ret, s1, s2, s3;
|
||||
unsigned int i;
|
||||
|
||||
s1.ud[0] = src1;
|
||||
s2.ud[0] = src2;
|
||||
s3.ud[0] = src3;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint8_t desc = s3.ub[i];
|
||||
int index = extract8(desc, 0, 3);
|
||||
uint8_t byte;
|
||||
|
||||
if (desc < 0x80) {
|
||||
if (desc & 0x08) {
|
||||
byte = s1.ub[index];
|
||||
} else {
|
||||
byte = s2.ub[index];
|
||||
}
|
||||
|
||||
switch(desc >> 5) {
|
||||
case 0x1:
|
||||
byte = reverse_bits(byte);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((byte & 0x80) != 0) {
|
||||
byte = 0xff;
|
||||
} else {
|
||||
byte = 0;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
if ((byte & 1) != 0) {
|
||||
byte = 0xff;
|
||||
} else {
|
||||
byte = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (desc & 0x10) {
|
||||
byte = ~byte;
|
||||
}
|
||||
} else {
|
||||
switch(desc >> 6) {
|
||||
case 0xa:
|
||||
byte = 0x7f;
|
||||
break;
|
||||
case 0xc:
|
||||
byte = 0x80;
|
||||
break;
|
||||
case 0xe:
|
||||
byte = 0xff;
|
||||
break;
|
||||
default:
|
||||
byte = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret.ub[i] = byte;
|
||||
}
|
||||
|
||||
return ret.ud[0];
|
||||
}
|
||||
|
||||
#define GEN_HELPER_PACKED(name, type, code) \
|
||||
uint64_t HELPER(name)(uint64_t src1, uint64_t src2) \
|
||||
{ \
|
||||
@ -242,3 +173,84 @@ GEN_HELPER_PACKED(pmovmskpd, sd, MOVMASK(ub, sd))
|
||||
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))
|
||||
|
||||
uint64_t HELPER(pshufb)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
{
|
||||
vec64 ret, s1, s2, s3;
|
||||
unsigned int i;
|
||||
|
||||
s1.ud[0] = src1;
|
||||
s2.ud[0] = src2;
|
||||
s3.ud[0] = src3;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint8_t desc = s3.ub[i];
|
||||
int index = extract8(desc, 0, 3);
|
||||
uint8_t byte;
|
||||
|
||||
if (desc < 0x80) {
|
||||
if (desc & 0x08) {
|
||||
byte = s1.ub[index];
|
||||
} else {
|
||||
byte = s2.ub[index];
|
||||
}
|
||||
|
||||
switch(desc >> 5) {
|
||||
case 0x1:
|
||||
byte = reverse_bits(byte);
|
||||
break;
|
||||
case 0x2:
|
||||
if ((byte & 0x80) != 0) {
|
||||
byte = 0xff;
|
||||
} else {
|
||||
byte = 0;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
if ((byte & 1) != 0) {
|
||||
byte = 0xff;
|
||||
} else {
|
||||
byte = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (desc & 0x10) {
|
||||
byte = ~byte;
|
||||
}
|
||||
} else {
|
||||
switch(desc >> 6) {
|
||||
case 0xa:
|
||||
byte = 0x7f;
|
||||
break;
|
||||
case 0xc:
|
||||
byte = 0x80;
|
||||
break;
|
||||
case 0xe:
|
||||
byte = 0xff;
|
||||
break;
|
||||
default:
|
||||
byte = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret.ub[i] = byte;
|
||||
}
|
||||
|
||||
return ret.ud[0];
|
||||
}
|
||||
|
||||
uint64_t HELPER(pshufw)(uint64_t src1, uint64_t src2, uint32_t imm8)
|
||||
{
|
||||
int i;
|
||||
vec64 s1 = { .ud[0] = src1 }, s2 = { .ud[0] = src2 }, dst;
|
||||
for (i = 0; i < vec64_uw; i++) {
|
||||
int sel = (imm8 >> (i * 2)) & 0x3;
|
||||
int j = sel & 1;
|
||||
dst.uw[i] = sel > 1 ? s1.uw[j] : s2.uw[j];
|
||||
}
|
||||
return dst.ud[0];
|
||||
}
|
||||
|
@ -1910,6 +1910,14 @@ static inline void gen_pextrh(TCGv_i64 ret, TCGv_i64 src1,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_pshufw(TCGv_i64 ret, TCGv_i64 src1,
|
||||
TCGv_i64 src2, int i)
|
||||
{
|
||||
TCGv_i32 imm8 = tcg_const_i32(i);
|
||||
gen_helper_pshufw(ret, src1, src2, imm8);
|
||||
tcg_temp_free_i32(imm8);
|
||||
}
|
||||
|
||||
static void gen_aad_tag(TCGv_i64 ret, TCGv_i32 tag)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
@ -3101,6 +3109,7 @@ static void gen_op(DisasContext *ctx, Instr *instr)
|
||||
case OP_PSRLQH: gen_alopf11_dddi(instr, gen_psrlqh); break;
|
||||
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;
|
||||
@ -3311,7 +3320,6 @@ static void gen_op(DisasContext *ctx, Instr *instr)
|
||||
case OP_PFCMPNLTD:
|
||||
case OP_PFCMPNLED:
|
||||
case OP_PFCMPODD:
|
||||
case OP_PSHUFW:
|
||||
case OP_PUNPCKHBH:
|
||||
case OP_PUNPCKHHW:
|
||||
case OP_PUNPCKHWD:
|
||||
@ -4275,7 +4283,7 @@ static void gen_pfcmb1(DisasContext *ctx, Instr *instr)
|
||||
case 0x4d:
|
||||
if (is_chan_0134(instr->chan) && ctx->version >= 2) {
|
||||
/* pshufb */
|
||||
gen_alopf21_i64(ctx, instr, gen_helper_packed_shuffle_i64);
|
||||
gen_alopf21_i64(ctx, instr, gen_helper_pshufb);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user