target: e2k: Add pshufb instr.

This commit is contained in:
Denis Drakhnia 2020-12-02 20:38:14 +02:00
parent c481a3c875
commit 5f46345413
5 changed files with 113 additions and 1 deletions

View File

@ -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,
}
};

View File

@ -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
View 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;
}

View File

@ -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',

View File

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