target: e2k: Add staa{b,h} instrs.
This commit is contained in:
parent
3267e9ddab
commit
2ab153e322
@ -52,6 +52,7 @@ static void e2k_cpu_reset(DeviceState *dev)
|
||||
env->bn.base = 8;
|
||||
env->bn.size = 8;
|
||||
env->bn.cur = 0;
|
||||
env->aau.incrs[0] = 1; /* always one */
|
||||
|
||||
// FIXME: testing
|
||||
env->idr = 0x3a207; // mimic 8c
|
||||
|
@ -324,13 +324,13 @@ typedef enum {
|
||||
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 base : 48; /* 48:0 */
|
||||
uint64_t unused1 : 6; /* 53:48 */
|
||||
uint64_t tag : 3; /* 56:54 */
|
||||
uint64_t mb : 1; /* 57 */
|
||||
uint64_t ed : 1; /* 58 */
|
||||
uint64_t rw : 2; /* 60:59 */
|
||||
uint64_t unused2 : 3; /* 63:60 */
|
||||
};
|
||||
uint64_t lo;
|
||||
};
|
||||
|
@ -18,9 +18,3 @@ 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_2(pcmpeqb, 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)
|
||||
|
@ -4,61 +4,3 @@
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
@ -497,6 +497,9 @@ void e2k_tcg_initialize(void) {
|
||||
{ &e2k_cs.psize, offsetof(CPUE2KState, bp.size), "psize" },
|
||||
{ &e2k_cs.pcur, offsetof(CPUE2KState, bp.cur), "pcur" },
|
||||
{ &e2k_cs.is_bp, offsetof(CPUE2KState, is_bp), "is_bp" },
|
||||
{ &e2k_cs.aasti_tags, offsetof(CPUE2KState, aau.sti_tags), "aasti_tags" },
|
||||
{ &e2k_cs.aaind_tags, offsetof(CPUE2KState, aau.ind_tags), "aaind_tags" },
|
||||
{ &e2k_cs.aaincr_tags, offsetof(CPUE2KState, aau.incr_tags), "aaincr_tags" },
|
||||
};
|
||||
|
||||
static const struct { TCGv_i64 *ptr; int off; const char *name; } r64[] = {
|
||||
@ -545,7 +548,34 @@ void e2k_tcg_initialize(void) {
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%%ctpr%d", i + 1);
|
||||
e2k_cs.ctprs[i] = tcg_global_mem_new(cpu_env,
|
||||
e2k_cs.ctprs[i] = tcg_global_mem_new_i64(cpu_env,
|
||||
offsetof(CPUE2KState, ctprs[i]), buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%%aasti%d", i);
|
||||
e2k_cs.aasti[i] = tcg_global_mem_new_i32(cpu_env,
|
||||
offsetof(CPUE2KState, aau.stis[i]), buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%%aaind%d", i);
|
||||
e2k_cs.aaind[i] = tcg_global_mem_new_i32(cpu_env,
|
||||
offsetof(CPUE2KState, aau.inds[i]), buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%%aaincr%d", i);
|
||||
e2k_cs.aaincr[i] = tcg_global_mem_new_i32(cpu_env,
|
||||
offsetof(CPUE2KState, aau.incrs[i]), buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%%aad%d_lo", i);
|
||||
e2k_cs.aad_lo[i] = tcg_global_mem_new_i64(cpu_env,
|
||||
offsetof(CPUE2KState, aau.ds[i].lo), buf);
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%%aad%d_hi", i);
|
||||
e2k_cs.aad_hi[i] = tcg_global_mem_new_i64(cpu_env,
|
||||
offsetof(CPUE2KState, aau.ds[i].hi), buf);
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,15 @@ typedef struct CPUE2KStateTCG {
|
||||
TCGv_i64 pregs;
|
||||
TCGv_i32 psize; /* holds psz */
|
||||
TCGv_i32 pcur; /* holds pcur */
|
||||
/* AAU */
|
||||
TCGv_i32 aasti[16];
|
||||
TCGv_i32 aasti_tags;
|
||||
TCGv_i32 aaind[16];
|
||||
TCGv_i32 aaind_tags;
|
||||
TCGv_i32 aaincr[8];
|
||||
TCGv_i32 aaincr_tags;
|
||||
TCGv_i64 aad_lo[32];
|
||||
TCGv_i64 aad_hi[32];
|
||||
} CPUE2KStateTCG;
|
||||
|
||||
extern struct CPUE2KStateTCG e2k_cs;
|
||||
|
@ -33,13 +33,18 @@ typedef struct {
|
||||
struct {
|
||||
uint32_t dst_preg: 5;
|
||||
uint32_t opc_cmp: 3;
|
||||
uint32_t lts: 2;
|
||||
uint32_t inc: 1;
|
||||
uint32_t ind_type: 1;
|
||||
uint32_t incr: 3;
|
||||
uint32_t index: 4;
|
||||
uint32_t desc: 5;
|
||||
uint32_t unused2: 24;
|
||||
};
|
||||
/* staa/ldaa/aaurw/aaurr */
|
||||
struct {
|
||||
uint32_t unused3: 8;
|
||||
uint32_t aalit: 2;
|
||||
uint32_t aaopc: 2;
|
||||
uint32_t aaincr: 3;
|
||||
/* aaind/aasti/aaincr for aaurw/aaurr */
|
||||
uint32_t aaind: 4;
|
||||
uint32_t aad: 5;
|
||||
uint32_t unused4: 8;
|
||||
};
|
||||
};
|
||||
union {
|
||||
@ -50,7 +55,7 @@ typedef struct {
|
||||
};
|
||||
struct {
|
||||
uint16_t opce3: 8;
|
||||
uint16_t unused4: 8;
|
||||
uint16_t unused5: 8;
|
||||
};
|
||||
};
|
||||
TCGv_i32 mrgc;
|
||||
@ -511,6 +516,38 @@ static uint16_t find_cond(DisasContext *ctx, int chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t find_am_cond(DisasContext *ctx, int chan)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < ctx->bundle.cds_present[i]; i++) {
|
||||
uint16_t *cds = (uint16_t *) &ctx->bundle.cds[i];
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
int opc = extract16(cds[j], 13, 3);
|
||||
int req = chan <= 2 ? 1 : 3;
|
||||
|
||||
if (opc == req) {
|
||||
return cds[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void gen_am_cond_i32(DisasContext *ctx, TCGv_i32 ret, int chan,
|
||||
uint16_t rlp)
|
||||
{
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
|
||||
e2k_gen_cond_i32(ctx, t0, extract16(rlp, 0, 7));
|
||||
// FIXME: It isn't clear if am can be the only one cond in RLP.
|
||||
tcg_gen_xori_i32(ret, t0, GET_BIT(rlp, 7 + chan % 3));
|
||||
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static inline void gen_mrgc_i64(DisasContext *ctx, int chan, TCGv_i64 ret)
|
||||
{
|
||||
uint16_t rlp = find_mrgc(ctx, chan);
|
||||
@ -1339,107 +1376,250 @@ static void gen_st_i32(DisasContext *ctx, int chan, MemOp memop)
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static void gen_staa_i64(DisasContext *ctx, int chan)
|
||||
static void gen_aad_tag(TCGv_i64 ret, TCGv_i32 tag)
|
||||
{
|
||||
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;
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
|
||||
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);
|
||||
}
|
||||
tcg_gen_setcondi_i32(TCG_COND_NE, t0, tag, 0);
|
||||
tcg_gen_extu_i32_i64(t1, t0);
|
||||
tcg_gen_shli_i64(ret, t1, 54);
|
||||
|
||||
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_i64(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]) {
|
||||
static void gen_aaurw_aad_i64(Instr *instr, TCGv_i64 arg1, TCGv_i32 tag)
|
||||
{
|
||||
TCGv_i64 lo = e2k_cs.aad_lo[instr->aad];
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_andi_i64(t0, arg1, 3UL << 57);
|
||||
tcg_gen_andi_i64(lo, lo, !(0x1fUL << 54));
|
||||
tcg_gen_or_i64(lo, lo, t0);
|
||||
tcg_gen_deposit_i64(lo, lo, arg1, 0, 48);
|
||||
tcg_gen_ori_i64(lo, lo, 3UL << 59);
|
||||
gen_aad_tag(t1, tag);
|
||||
tcg_gen_or_i64(lo, lo, t1);
|
||||
|
||||
tcg_temp_free_i64(t1);
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static void gen_aaurw_aad_i32(Instr *instr, TCGv_i32 arg1, TCGv_i32 tag)
|
||||
{
|
||||
TCGv_i64 lo = e2k_cs.aad_lo[instr->aad];
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
||||
TCGv_i64 t2 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_extu_i32_i64(t0, arg1);
|
||||
tcg_gen_deposit_i64(lo, lo, t0, 0, 48);
|
||||
tcg_gen_ori_i64(lo, lo, 3UL << 59);
|
||||
tcg_gen_andi_i64(lo, lo, !(0x7UL << 54));
|
||||
gen_aad_tag(t1, tag);
|
||||
tcg_gen_or_i64(lo, lo, t1);
|
||||
|
||||
tcg_temp_free_i64(t2);
|
||||
tcg_temp_free_i64(t1);
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
static void gen_aaurw_rest_i32(Instr* instr, TCGv_i32 arg1, TCGv_i32 tag)
|
||||
{
|
||||
int idx = instr->aaind;
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
tcg_gen_setcondi_i32(TCG_COND_NE, t0, tag, 0);
|
||||
switch(instr->aaopc) {
|
||||
case 1: /* aaurwd src4, aasti */
|
||||
tcg_gen_mov_i32(e2k_cs.aasti[idx], arg1);
|
||||
tcg_gen_deposit_i32(e2k_cs.aasti_tags, e2k_cs.aasti_tags, t0, idx, 1);
|
||||
break;
|
||||
case 2: { /* aaurwd src4, aaind */
|
||||
if (idx == 0) {
|
||||
tcg_gen_movi_i32(e2k_cs.aaind[idx], 0);
|
||||
} else {
|
||||
tcg_gen_mov_i32(e2k_cs.aaind[idx], arg1);
|
||||
tcg_gen_deposit_i32(e2k_cs.aaind_tags, e2k_cs.aaind_tags, t0,
|
||||
idx, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: /* aaurwd src4, aaincr */
|
||||
idx &= 7;
|
||||
if (idx > 0) {
|
||||
tcg_gen_mov_i32(e2k_cs.aaincr[idx], arg1);
|
||||
tcg_gen_deposit_i32(e2k_cs.aaincr_tags, e2k_cs.aaincr_tags, t0,
|
||||
idx, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static void gen_aasti_incr(DisasContext *ctx, Instr *instr, int size)
|
||||
{
|
||||
uint16_t rlp = find_am_cond(ctx, instr->chan);
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
|
||||
if (rlp != 0) {
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
|
||||
gen_am_cond_i32(ctx, t1, instr->chan, rlp);
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0);
|
||||
tcg_temp_free_i32(t1);
|
||||
}
|
||||
|
||||
tcg_gen_muli_i32(t0, e2k_cs.aaincr[instr->aaincr], size);
|
||||
tcg_gen_add_i32(e2k_cs.aasti[instr->aaind], e2k_cs.aasti[instr->aaind], t0);
|
||||
gen_set_label(l0);
|
||||
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
|
||||
static void gen_aad_ptr(DisasContext *ctx, TCGv ret, Instr *instr)
|
||||
{
|
||||
uint32_t lit = 0;
|
||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
TCGv t1 = tcg_temp_new();
|
||||
TCGv t2 = tcg_temp_new();
|
||||
|
||||
if (instr->aalit) {
|
||||
int lts = instr->aalit - 1;
|
||||
if (ctx->bundle.lts_present[lts]) {
|
||||
lit = ctx->bundle.lts[lts];
|
||||
} else {
|
||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPN);
|
||||
return;
|
||||
}
|
||||
t4 = tcg_const_i32(ctx->bundle.lts[lit - 1]);
|
||||
}
|
||||
|
||||
tcg_gen_extract_i64(t0, e2k_cs.aad_lo[instr->aad], 0, 48);
|
||||
tcg_gen_trunc_i64_tl(t1, t0);
|
||||
tcg_gen_ext_i32_tl(t2, e2k_cs.aasti[instr->aaind]);
|
||||
if (lit != 0) {
|
||||
TCGv t3 = tcg_temp_new();
|
||||
tcg_gen_add_tl(t3, t1, t2);
|
||||
tcg_gen_addi_tl(ret, t3, lit);
|
||||
tcg_temp_free(t3);
|
||||
} else {
|
||||
t4 = tcg_const_i32(0);
|
||||
tcg_gen_add_tl(ret, t1, t2);
|
||||
}
|
||||
tcg_temp_free(t2);
|
||||
tcg_temp_free(t1);
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
|
||||
if (sm) {
|
||||
qemu_log_mask(LOG_UNIMP, "staaw: sm is not implemented\n");
|
||||
abort();
|
||||
}
|
||||
static void gen_staa_i64(DisasContext *ctx, Instr *instr)
|
||||
{
|
||||
uint8_t mas = ctx->mas[instr->chan];
|
||||
Src64 s4 = get_src4_i64(ctx, instr->chan);
|
||||
|
||||
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);
|
||||
gen_tag_check(ctx, instr->sm, s4.tag);
|
||||
if (mas == 0x3f) {
|
||||
/* aaurwd */
|
||||
if (instr->aaopc == 0) {
|
||||
gen_aaurw_aad_i64(instr, s4.value, s4.tag);
|
||||
} else {
|
||||
gen_helper_set_aasti_i32(cpu_env, s4.value, t2);
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
tcg_gen_extrl_i64_i32(t0, s4.value);
|
||||
gen_aaurw_rest_i32(instr, t0, s4.tag);
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
} else {
|
||||
qemu_log_mask(LOG_UNIMP, "staaw: not implemented mas\n");
|
||||
abort();
|
||||
}
|
||||
/* staad */
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
TCGv t0 = tcg_temp_local_new();
|
||||
|
||||
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);
|
||||
if (mas != 0) {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"0x%lx: staad mas=%#x is not implemented\n", ctx->pc, mas);
|
||||
}
|
||||
|
||||
gen_aad_ptr(ctx, t0, instr);
|
||||
|
||||
if (instr->sm) {
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
gen_helper_probe_write_access(t1, cpu_env, t0);
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_i64(s4.value, t0, 0, MO_Q);
|
||||
gen_set_label(l0);
|
||||
tcg_temp_free(t0);
|
||||
|
||||
if (instr->aaopc & 1) {
|
||||
gen_aasti_incr(ctx, instr, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_staa_i32(DisasContext *ctx, Instr *instr, MemOp memop)
|
||||
{
|
||||
uint8_t mas = ctx->mas[instr->chan];
|
||||
Src32 s4 = get_src4_i32(ctx, instr->chan);
|
||||
|
||||
gen_tag_check(ctx, instr->sm, s4.tag);
|
||||
if (mas == 0x3f) {
|
||||
/* aaurw */
|
||||
/* CPU do nothing if size less than 32 bits */
|
||||
if ((memop & MO_SIZE) == MO_32) {
|
||||
if (instr->aaopc == 0) {
|
||||
gen_aaurw_aad_i32(instr, s4.value, s4.tag);
|
||||
} else {
|
||||
gen_aaurw_rest_i32(instr, s4.value, s4.tag);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* staaw */
|
||||
int len;
|
||||
TCGLabel *l0 = gen_new_label();
|
||||
TCGv t0 = tcg_temp_local_new();
|
||||
|
||||
if (mas != 0) {
|
||||
char c;
|
||||
switch(memop & MO_SIZE) {
|
||||
case MO_8: c = 'b'; break;
|
||||
case MO_16: c = 'h'; break;
|
||||
case MO_32: c = 'w'; break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"0x%lx: staa%c mas=%#x is not implemented\n", ctx->pc, c, mas);
|
||||
}
|
||||
|
||||
gen_aad_ptr(ctx, t0, instr);
|
||||
|
||||
if (instr->sm) {
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
gen_helper_probe_write_access(t1, cpu_env, t0);
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_i32(s4.value, t0, 0, memop);
|
||||
gen_set_label(l0);
|
||||
tcg_temp_free(t0);
|
||||
|
||||
switch(memop & MO_SIZE) {
|
||||
case MO_8: len = 1; break;
|
||||
case MO_16: len = 2; break;
|
||||
case MO_32: len = 4; break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
|
||||
if (instr->aaopc & 1) {
|
||||
gen_aasti_incr(ctx, instr, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_alopf1_i64(DisasContext *ctx, int chan,
|
||||
@ -1854,8 +2034,10 @@ static void execute_ext_01_25(DisasContext *ctx, Instr *instr)
|
||||
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 */
|
||||
case 0x1c: gen_staa_i32(ctx, instr, MO_8); break; /* staab */
|
||||
case 0x1d: gen_staa_i32(ctx, instr, MO_16); break; /* staah */
|
||||
case 0x1e: gen_staa_i32(ctx, instr, MO_32); break; /* staaw */
|
||||
case 0x1f: gen_staa_i64(ctx, instr); break; /* staad */
|
||||
default:
|
||||
e2k_tr_gen_exception(ctx, E2K_EXCP_ILLOPC);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user