target: e2k: Add pshufb instr.
This commit is contained in:
parent
c481a3c875
commit
5f46345413
@ -88,7 +88,7 @@ void cpu_e2k_set_id(CPUE2KState *env, unsigned int cpu)
|
||||
static const struct e2k_def_t e2k_defs[] = {
|
||||
{
|
||||
.name = "any",
|
||||
.isa_version = 0xffffffff,
|
||||
.isa_version = 4,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -16,3 +16,4 @@ 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)
|
||||
|
89
target/e2k/helper_vec.c
Normal file
89
target/e2k/helper_vec.c
Normal file
@ -0,0 +1,89 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/log.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "translate.h"
|
||||
|
||||
static uint8_t reverse_bits(uint8_t b)
|
||||
{
|
||||
b = ((b & 0xf0) >> 4) | ((b & 0x0f) << 4);
|
||||
b = ((b & 0xcc) >> 2) | ((b & 0x33) << 2);
|
||||
b = ((b & 0xaa) >> 1) | ((b & 0x55) << 1);
|
||||
return b;
|
||||
}
|
||||
|
||||
typedef union {
|
||||
uint64_t n;
|
||||
uint8_t s[8];
|
||||
} u8x8;
|
||||
|
||||
uint64_t HELPER(packed_shuffle_i64)(uint64_t src1, uint64_t src2, uint64_t src3)
|
||||
{
|
||||
u8x8 ret, s1, s2, s3;
|
||||
unsigned int i;
|
||||
|
||||
s1.n = src1;
|
||||
s2.n = src2;
|
||||
s3.n = src3;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint8_t desc = s3.s[i];
|
||||
int index = extract8(desc, 0, 3);
|
||||
uint8_t byte;
|
||||
|
||||
if (desc < 0x80) {
|
||||
if (desc & 0x08) {
|
||||
byte = s1.s[index];
|
||||
} else {
|
||||
byte = s2.s[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.s[i] = byte;
|
||||
}
|
||||
|
||||
return ret.n;
|
||||
}
|
@ -5,6 +5,7 @@ e2k_ss.add(files(
|
||||
'helper.c',
|
||||
'helper_int.c',
|
||||
'helper_sm.c',
|
||||
'helper_vec.c',
|
||||
'translate.c',
|
||||
'translate/state.c',
|
||||
'translate/control.c',
|
||||
|
@ -1530,6 +1530,24 @@ static void execute_ext_0b(DisasContext *ctx, int chan)
|
||||
}
|
||||
}
|
||||
|
||||
static void execute_ext_0f(DisasContext *ctx, int chan)
|
||||
{
|
||||
uint8_t opc = GET_FIELD(ctx->bundle.als[chan], 24, 7);
|
||||
|
||||
switch(opc) {
|
||||
case 0x4d:
|
||||
if (is_cmp_chan(chan) && ctx->version >= 2) {
|
||||
gen_alopf21_i64(ctx, chan, gen_helper_packed_shuffle_i64); /* pshufb */
|
||||
} else {
|
||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void e2k_alc_execute(DisasContext *ctx, int chan)
|
||||
{
|
||||
const UnpackedBundle *bundle = &ctx->bundle;
|
||||
@ -1566,6 +1584,9 @@ void e2k_alc_execute(DisasContext *ctx, int chan)
|
||||
case 0x0b:
|
||||
execute_ext_0b(ctx, chan);
|
||||
break;
|
||||
case 0x0f:
|
||||
execute_ext_0f(ctx, chan);
|
||||
break;
|
||||
default:
|
||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user