target: e2k: Partial staa{d,w} implementation.

This commit is contained in:
Denis Drakhnia 2020-12-03 16:59:58 +02:00 committed by Denis Drakhnia
parent 51048a3f3e
commit 683d96b8fa
6 changed files with 280 additions and 35 deletions

View File

@ -286,6 +286,88 @@ typedef struct {
bool fx;
} E2KWdState;
typedef enum {
AASR_NULL = 0,
AASR_READY = 1,
AASR_ACTIVE = 3,
AASR_STOPPED = 5,
} E2KAasrState;
typedef union {
struct {
uint32_t unused : 5;
uint32_t stb : 1;
uint32_t iab : 1;
uint32_t lds : 3;
};
uint32_t raw;
} E2KAasr;
typedef enum {
AAD_TAG_UNV = 0,
AAD_TAG_UDT = 1,
AAD_TAG_UET = 2,
AAD_TAG_UAP = 4,
AAD_TAG_USAP = 5,
AAD_TAG_UDS = 6,
} E2KAadTag;
typedef struct {
union {
struct {
uint64_t base : 48;
uint64_t unused1 : 6;
uint64_t tag : 3;
uint64_t mb : 1;
uint64_t ed : 1;
uint64_t rw : 2;
uint64_t unused2 : 3;
};
uint64_t lo;
};
union {
struct {
uint64_t unused3 : 32;
uint64_t size : 32;
};
uint64_t hi;
};
} E2KAad;
typedef enum {
AALDA_EXC_EIO = 1,
AALDA_EXC_EPM = 2,
AALDA_EXC_EPMSI = 3,
} E2KAaldaExc;
typedef union {
struct {
uint8_t exc: 2;
uint8_t cincr: 1;
uint8_t unused1: 1;
uint8_t root: 1;
uint8_t unused2: 3;
};
uint8_t raw;
} E2KAalda;
typedef struct {
E2KAasr sr;
uint32_t fstr;
uint64_t ldm;
uint64_t ldv;
uint32_t stis[16];
uint32_t sti_tags;
uint32_t incrs[8];
uint32_t incr_tags;
uint32_t inds[16];
uint32_t ind_tags;
E2KAad ds[32];
uint32_t ldi[64];
E2KAalda lda[64];
} E2KAauState;
typedef struct {
typedef struct CPUArchState {
/* register file */
uint64_t regs[E2K_REG_COUNT]; /* registers */
@ -334,6 +416,8 @@ typedef struct CPUArchState {
uint32_t fpcr; // Floating point control register (FPCR)
uint32_t fpsr; // Floating point state register (FPSR)
E2KAauState aau;
int interrupt_index;
uint32_t is_bp; /* breakpoint flag */
int syscall_wbs; // FIXME: temp for syscall

View File

@ -90,42 +90,42 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
if (76 <= n && n < 140) {
if (n & 1) {
return gdb_get_reg64(mem_buf, 0); // addN_hi
return gdb_get_reg64(mem_buf, env->aau.ds[n - 76].hi); // addN_hi
} else {
return gdb_get_reg64(mem_buf, 0); // addN_lo
return gdb_get_reg64(mem_buf, env->aau.ds[n - 76].lo); // addN_lo
}
}
if (140 <= n && n < 156) {
return gdb_get_reg64(mem_buf, 0); // aaindN
return gdb_get_reg64(mem_buf, env->aau.inds[n - 140]); // aaindN
}
if (156 <= n && n < 164) {
return gdb_get_reg64(mem_buf, 0); // aaincrN
return gdb_get_reg64(mem_buf, env->aau.incrs[n - 156]); // aaincrN
}
if (164 <= n && n < 228) {
return gdb_get_reg64(mem_buf, 0); // aaldiN
return gdb_get_reg64(mem_buf, env->aau.ldi[n - 164]); // aaldiN
}
if (n == 228) {
return gdb_get_reg64(mem_buf, 0); // aaldv
return gdb_get_reg64(mem_buf, env->aau.ldv); // aaldv
}
if (229 <= n && n < 293) {
return gdb_get_reg64(mem_buf, 0); // aaldaN
return gdb_get_reg64(mem_buf, env->aau.lda[n - 229].raw); // aaldaN
}
switch (n) {
case 293: return gdb_get_reg64(mem_buf, 0); // aaldm
case 294: return gdb_get_reg64(mem_buf, 0); // aasr
case 295: return gdb_get_reg64(mem_buf, 0); // aafstr
case 293: return gdb_get_reg64(mem_buf, env->aau.ldm); // aaldm
case 294: return gdb_get_reg64(mem_buf, env->aau.sr.raw); // aasr
case 295: return gdb_get_reg64(mem_buf, env->aau.fstr); // aafstr
default:
break;
}
if (296 <= n && n < 312) {
return gdb_get_reg64(mem_buf, 0); // aastiN
return gdb_get_reg64(mem_buf, env->aau.stis[n - 296]); // aastiN
}
switch (n) {

View File

@ -16,3 +16,9 @@ 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_4(set_aad_i64, void, env, i64, int, int)
DEF_HELPER_4(set_aad_i32, void, env, i32, int, int)
DEF_HELPER_3(set_aasti_i64, void, env, i64, int)
DEF_HELPER_3(set_aasti_i32, void, env, i32, int)
DEF_HELPER_7(staa_i64, void, env, i64, i32, int, int, int, int)
DEF_HELPER_7(staa_i32, void, env, i32, i32, int, int, int, int)

64
target/e2k/helper_aau.c Normal file
View File

@ -0,0 +1,64 @@
#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"
void HELPER(set_aad_i64)(CPUE2KState *env, uint64_t src4, int incr, int d)
{
assert(d < 32);
// FIXME: What register default values should be?
env->aau.ds[d].lo = 0;
env->aau.ds[d].hi = 0;
env->aau.ds[d].base = extract64(src4, 0, 48);
env->aau.ds[d].rw = 3;
env->aau.incrs[incr] = 1;
}
void HELPER(set_aad_i32)(CPUE2KState *env, uint32_t src4, int incr, int d)
{
assert(d < 32);
// FIXME: What register default values should be?
env->aau.ds[d].lo = 0;
env->aau.ds[d].hi = 0;
env->aau.ds[d].base = src4;
env->aau.ds[d].rw = 3;
env->aau.incrs[incr] = 1;
}
void HELPER(set_aasti_i64)(CPUE2KState *env, uint64_t src4, int ind)
{
assert(ind < 16);
env->aau.stis[ind] = src4;
}
void HELPER(set_aasti_i32)(CPUE2KState *env, uint32_t src4, int ind)
{
assert(ind < 16);
env->aau.stis[ind] = src4;
}
void HELPER(staa_i64)(CPUE2KState *env, uint64_t src4, uint32_t lit, int am,
int incr, int ind, int d)
{
abi_ulong ptr = env->aau.ds[d].base + env->aau.stis[ind] + lit;
cpu_stq_le_data_ra(env, ptr, src4, GETPC());
if (am) {
env->aau.stis[ind] += env->aau.incrs[incr] * 8;
}
}
void HELPER(staa_i32)(CPUE2KState *env, uint32_t src4, uint32_t lit, int am,
int incr, int ind, int d)
{
abi_ulong ptr = env->aau.ds[d].base + env->aau.stis[ind] + lit;
cpu_stl_le_data_ra(env, ptr, src4, GETPC());
if (am) {
env->aau.stis[ind] += env->aau.incrs[incr] * 4;
}
}

View File

@ -6,6 +6,7 @@ e2k_ss.add(files(
'helper_int.c',
'helper_sm.c',
'helper_vec.c',
'helper_aau.c',
'translate.c',
'translate/state.c',
'translate/control.c',

View File

@ -1020,6 +1020,109 @@ static void gen_ld(DisasContext *ctx, int chan, MemOp memop)
tcg_temp_free_i64(t0);
}
static void gen_staa_i64(DisasContext *ctx, int chan)
{
uint32_t als = ctx->bundle.als[chan];
uint8_t mas = ctx->mas[chan];
bool sm = extract32(als, 31, 1);
int lit = extract32(als, 8, 2);
int am = extract32(als, 10, 1);
int incr = extract32(als, 12, 3);
int ind = extract32(als, 15, 4);
int d = extract32(als, 19, 5);
Src64 s4 = get_src4_i64(ctx, chan);
TCGv_i32 t0 = tcg_const_i32(am);
TCGv_i32 t1 = tcg_const_i32(incr);
TCGv_i32 t2 = tcg_const_i32(ind);
TCGv_i32 t3 = tcg_const_i32(d);
TCGv_i32 t4;
if (lit) {
if (!ctx->bundle.lts_present[lit - 1]) {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPN);
return;
}
t4 = tcg_const_i32(ctx->bundle.lts[lit - 1]);
} else {
t4 = tcg_const_i32(0);
}
if (sm) {
qemu_log_mask(LOG_UNIMP, "staad: sm is not implemented\n");
abort();
}
if (mas == 0) {
gen_helper_staa_i64(cpu_env, s4.value, t4, t0, t1, t2, t3);
} else if (mas == 0x3f) {
if (!am) {
gen_helper_set_aad_i64(cpu_env, s4.value, t1, t3);
} else {
gen_helper_set_aasti_i64(cpu_env, s4.value, t2);
}
} else {
qemu_log_mask(LOG_UNIMP, "staad: not implemented mas\n");
abort();
}
tcg_temp_free_i32(t4);
tcg_temp_free_i32(t3);
tcg_temp_free_i32(t2);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
}
static void gen_staa_i32(DisasContext *ctx, int chan)
{
uint32_t als = ctx->bundle.als[chan];
uint8_t mas = ctx->mas[chan];
bool sm = extract32(als, 31, 1);
int lit = extract32(als, 8, 2);
int am = extract32(als, 10, 1);
int incr = extract32(als, 12, 3);
int ind = extract32(als, 15, 4);
int d = extract32(als, 19, 5);
Src32 s4 = get_src4_i32(ctx, chan);
TCGv_i32 t0 = tcg_const_i32(am);
TCGv_i32 t1 = tcg_const_i32(incr);
TCGv_i32 t2 = tcg_const_i32(ind);
TCGv_i32 t3 = tcg_const_i32(d);
TCGv_i32 t4;
if (lit) {
if (!ctx->bundle.lts_present[lit - 1]) {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPN);
return;
}
t4 = tcg_const_i32(ctx->bundle.lts[lit - 1]);
} else {
t4 = tcg_const_i32(0);
}
if (sm) {
qemu_log_mask(LOG_UNIMP, "staaw: sm is not implemented\n");
abort();
}
if (mas == 0) {
gen_helper_staa_i32(cpu_env, s4.value, t4, t0, t1, t2, t3);
} else if (mas == 0x3f) {
if (!am) {
gen_helper_set_aad_i32(cpu_env, s4.value, t1, t3);
} else {
gen_helper_set_aasti_i32(cpu_env, s4.value, t2);
}
} else {
qemu_log_mask(LOG_UNIMP, "staaw: not implemented mas\n");
abort();
}
tcg_temp_free_i32(t4);
tcg_temp_free_i32(t3);
tcg_temp_free_i32(t2);
tcg_temp_free_i32(t1);
tcg_temp_free_i32(t0);
}
static void gen_st(DisasContext *ctx, int chan, MemOp memop)
{
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
@ -1452,31 +1555,18 @@ static void execute_ext_01_25(DisasContext *ctx, int chan)
{
uint8_t opc = GET_FIELD(ctx->bundle.als[chan], 24, 7);
if (chan != 2 && chan != 5) {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
return;
}
switch(opc) {
case 0x08: if (chan == 2 || chan == 5) {
gen_gettag_i32(ctx, chan); /* gettags */
} else {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
}
break;
case 0x09: if (chan == 2 || chan == 5) {
gen_gettag_i64(ctx, chan); /* gettagd */
} else {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
}
break;
case 0x0a: if (chan == 2 || chan == 5) {
gen_puttag_i32(ctx, chan); /* puttags */
} else {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
}
break;
case 0x0b: if (chan == 2 || chan == 5) {
gen_puttag_i64(ctx, chan); /* puttagd */
} else {
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
}
break;
case 0x08: gen_gettag_i32(ctx, chan); break; /* gettags */
case 0x09: gen_gettag_i64(ctx, chan); break; /* gettagd */
case 0x0a: gen_puttag_i32(ctx, chan); break; /* puttags */
case 0x0b: gen_puttag_i64(ctx, chan); break; /* puttagd */
case 0x1e: gen_staa_i32(ctx, chan); break; /* staaw */
case 0x1f: gen_staa_i64(ctx, chan); break; /* staad */
default:
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
break;