target: e2k: Partial staa{d,w} implementation.
This commit is contained in:
parent
51048a3f3e
commit
683d96b8fa
|
@ -286,6 +286,88 @@ typedef struct {
|
||||||
bool fx;
|
bool fx;
|
||||||
} E2KWdState;
|
} 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 {
|
typedef struct CPUArchState {
|
||||||
/* register file */
|
/* register file */
|
||||||
uint64_t regs[E2K_REG_COUNT]; /* registers */
|
uint64_t regs[E2K_REG_COUNT]; /* registers */
|
||||||
|
@ -334,6 +416,8 @@ typedef struct CPUArchState {
|
||||||
uint32_t fpcr; // Floating point control register (FPCR)
|
uint32_t fpcr; // Floating point control register (FPCR)
|
||||||
uint32_t fpsr; // Floating point state register (FPSR)
|
uint32_t fpsr; // Floating point state register (FPSR)
|
||||||
|
|
||||||
|
E2KAauState aau;
|
||||||
|
|
||||||
int interrupt_index;
|
int interrupt_index;
|
||||||
uint32_t is_bp; /* breakpoint flag */
|
uint32_t is_bp; /* breakpoint flag */
|
||||||
int syscall_wbs; // FIXME: temp for syscall
|
int syscall_wbs; // FIXME: temp for syscall
|
||||||
|
|
|
@ -90,42 +90,42 @@ int e2k_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
|
||||||
|
|
||||||
if (76 <= n && n < 140) {
|
if (76 <= n && n < 140) {
|
||||||
if (n & 1) {
|
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 {
|
} 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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
switch (n) {
|
||||||
case 293: return gdb_get_reg64(mem_buf, 0); // aaldm
|
case 293: return gdb_get_reg64(mem_buf, env->aau.ldm); // aaldm
|
||||||
case 294: return gdb_get_reg64(mem_buf, 0); // aasr
|
case 294: return gdb_get_reg64(mem_buf, env->aau.sr.raw); // aasr
|
||||||
case 295: return gdb_get_reg64(mem_buf, 0); // aafstr
|
case 295: return gdb_get_reg64(mem_buf, env->aau.fstr); // aafstr
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (296 <= n && n < 312) {
|
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) {
|
switch (n) {
|
||||||
|
|
|
@ -16,3 +16,9 @@ DEF_HELPER_2(setwd, void, env, i32)
|
||||||
DEF_HELPER_2(probe_read_access, int, env, tl)
|
DEF_HELPER_2(probe_read_access, int, env, tl)
|
||||||
DEF_HELPER_2(probe_write_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_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)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ e2k_ss.add(files(
|
||||||
'helper_int.c',
|
'helper_int.c',
|
||||||
'helper_sm.c',
|
'helper_sm.c',
|
||||||
'helper_vec.c',
|
'helper_vec.c',
|
||||||
|
'helper_aau.c',
|
||||||
'translate.c',
|
'translate.c',
|
||||||
'translate/state.c',
|
'translate/state.c',
|
||||||
'translate/control.c',
|
'translate/control.c',
|
||||||
|
|
|
@ -1020,6 +1020,109 @@ static void gen_ld(DisasContext *ctx, int chan, MemOp memop)
|
||||||
tcg_temp_free_i64(t0);
|
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)
|
static void gen_st(DisasContext *ctx, int chan, MemOp memop)
|
||||||
{
|
{
|
||||||
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
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);
|
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) {
|
switch(opc) {
|
||||||
case 0x08: if (chan == 2 || chan == 5) {
|
case 0x08: gen_gettag_i32(ctx, chan); break; /* gettags */
|
||||||
gen_gettag_i32(ctx, chan); /* gettags */
|
case 0x09: gen_gettag_i64(ctx, chan); break; /* gettagd */
|
||||||
} else {
|
case 0x0a: gen_puttag_i32(ctx, chan); break; /* puttags */
|
||||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
case 0x0b: gen_puttag_i64(ctx, chan); break; /* puttagd */
|
||||||
}
|
case 0x1e: gen_staa_i32(ctx, chan); break; /* staaw */
|
||||||
break;
|
case 0x1f: gen_staa_i64(ctx, chan); break; /* staad */
|
||||||
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;
|
|
||||||
default:
|
default:
|
||||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue