e2k: add gen_staaq
This commit is contained in:
parent
446abed271
commit
bd5206f3dd
|
@ -19,8 +19,8 @@ DEF_HELPER_FLAGS_2(probe_write_access, TCG_CALL_NO_RWG_SE, int, tl, int)
|
|||
DEF_HELPER_FLAGS_2(aau_load_program, TCG_CALL_NO_RWG, void, env, i64)
|
||||
DEF_HELPER_FLAGS_6(mova_ptr, TCG_CALL_NO_RWG, tl, env, int, int, int, int, int)
|
||||
DEF_HELPER_FLAGS_3(aau_am, TCG_CALL_NO_RWG, void, env, int, int)
|
||||
DEF_HELPER_FLAGS_4(aaurwd_aad_lo, TCG_CALL_NO_RWG, void, env, i32, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(aaurwd_aad_hi, TCG_CALL_NO_RWG, void, env, i32, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(aaurwd_aad, TCG_CALL_NO_RWG, void, env, i32, i64, i32)
|
||||
DEF_HELPER_FLAGS_4(aaurwq_aad, TCG_CALL_NO_RWG, void, env, i32, i128, i32)
|
||||
DEF_HELPER_FLAGS_4(aaurwd_aaind, TCG_CALL_NO_RWG, void, env, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_4(aaurwd_aasti, TCG_CALL_NO_RWG, void, env, i32, i32, i32)
|
||||
DEF_HELPER_FLAGS_4(aaurwd_aaincr, TCG_CALL_NO_RWG, void, env, i32, i32, i32)
|
||||
|
|
|
@ -91,7 +91,7 @@ void HELPER(aau_am)(CPUE2KState *env, int chan, int area)
|
|||
as->cdi += size * incr;
|
||||
}
|
||||
|
||||
void HELPER(aaurwd_aad_lo)(CPUE2KState *env, uint32_t aad, uint64_t val, uint32_t tag)
|
||||
void HELPER(aaurwd_aad)(CPUE2KState *env, uint32_t aad, uint64_t val, uint32_t tag)
|
||||
{
|
||||
env->aau.ds[aad].base = val;
|
||||
if (env->enable_tags) {
|
||||
|
@ -103,9 +103,10 @@ void HELPER(aaurwd_aad_lo)(CPUE2KState *env, uint32_t aad, uint64_t val, uint32_
|
|||
env->aau.ds[aad].rw = 3;
|
||||
}
|
||||
|
||||
void HELPER(aaurwd_aad_hi)(CPUE2KState *env, uint32_t aad, uint64_t val, uint32_t tag)
|
||||
void HELPER(aaurwq_aad)(CPUE2KState *env, uint32_t aad, Int128 val, uint32_t tag)
|
||||
{
|
||||
env->aau.ds[aad].hi = val & 0xffffffff00000000;
|
||||
helper_aaurwd_aad(env, aad, int128_getlo(val), tag);
|
||||
env->aau.ds[aad].hi = int128_gethi(val) & 0xffffffff00000000;
|
||||
}
|
||||
|
||||
void HELPER(aaurwd_aaind)(CPUE2KState *env, uint32_t index, uint32_t val, uint32_t tag)
|
||||
|
|
|
@ -4336,14 +4336,14 @@ IMPL_GEN_ADDR_SRC1(gen_addr_src1_i32, s, tcg_gen_ext_i32_tl)
|
|||
#define gen_stqp(i, a, b) gen_alopf3_mas(i, a, gen_st_raw_i128, MO_UQ, b)
|
||||
#define gen_stmqp(i, a, b) gen_alopf3_mas(i, a, gen_stm_raw_i128, MO_UQ, b)
|
||||
|
||||
static void gen_aaurwd_aad_lo(Alop *alop, TCGv_i64 arg1, TCGv_i32 tag)
|
||||
static void gen_aaurwd_aad(Alop *alop, TCGv_i64 arg1, TCGv_i32 tag)
|
||||
{
|
||||
gen_helper_aaurwd_aad_lo(tcg_env, tcg_constant_i32(alop->als.aad), arg1, tag);
|
||||
gen_helper_aaurwd_aad(tcg_env, tcg_constant_i32(alop->als.aad), arg1, tag);
|
||||
}
|
||||
|
||||
static void gen_aaurwd_aad_hi(Alop *alop, TCGv_i64 arg1, TCGv_i32 tag)
|
||||
static void gen_aaurwq_aad(Alop *alop, TCGv_i128 arg1, TCGv_i32 tag)
|
||||
{
|
||||
gen_helper_aaurwd_aad_hi(tcg_env, tcg_constant_i32(alop->als.aad), arg1, tag);
|
||||
gen_helper_aaurwq_aad(tcg_env, tcg_constant_i32(alop->als.aad), arg1, tag);
|
||||
}
|
||||
|
||||
static void gen_aaurwd_aasti(Alop *alop, TCGv_i32 val, TCGv_i32 tag)
|
||||
|
@ -4515,7 +4515,85 @@ static void gen_staaqp(Alop *alop)
|
|||
}
|
||||
}
|
||||
|
||||
static void gen_staa_i64(Alop *alop)
|
||||
static bool check_staaq_pair(DisasContext *ctx, int chan)
|
||||
{
|
||||
Alop *alop = &ctx->alops[chan == 2 ? 5 : 2];
|
||||
|
||||
if (ctx->version >= 7) {
|
||||
// optional staaq,[25] or empty ALC[25]
|
||||
if (alop->format != ALOPF_NONE && !(alop->format == ALOPF10 && alop->op == OP_STAAQ)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// staaq,[25] is required
|
||||
if (alop->format != ALOPF10 || alop->op != OP_STAAQ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void gen_staaq(Alop *alop)
|
||||
{
|
||||
DisasContext *ctx = alop->ctx;
|
||||
uint8_t mas = alop->mas;
|
||||
Tagged_i64 lo, hi;
|
||||
Tagged_i128 s4;
|
||||
|
||||
if (!check_staaq_pair(ctx, alop->chan) || (alop->chan == 5) != (alop->als.dst & 1)) {
|
||||
gen_tr_excp_illopc(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (alop->chan == 5) {
|
||||
// handle in alop2
|
||||
return;
|
||||
}
|
||||
|
||||
lo = gen_tagged_reg_d(ctx, alop->als.dst, 2);
|
||||
hi = gen_tagged_reg_d(ctx, alop->als.dst + 1, 2);
|
||||
s4 = tagged_temp_new_i128();
|
||||
gen_tag2(q, s4, lo, hi);
|
||||
tcg_gen_concat_i64_i128(s4.val, lo.val, hi.val);
|
||||
|
||||
if (mas == 0x3f) {
|
||||
if (alop->als.aaopc == 0) {
|
||||
gen_aaurwq_aad(alop, s4.val, s4.tag);
|
||||
} else {
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
tcg_gen_extrl_i64_i32(t0, lo.val);
|
||||
gen_aaurw_rest_i32(alop, t0, s4.tag);
|
||||
}
|
||||
} else {
|
||||
int mod = mas & 0x7;
|
||||
MemOp memop = memop_from_mas(MO_UQ, mas);
|
||||
TCGLabel *l0 = NULL;
|
||||
TCGv t0 = tcg_temp_new();
|
||||
|
||||
if (mod != 0) {
|
||||
e2k_todo(ctx, "staaq mod=%#x is not implemented", mod);
|
||||
}
|
||||
|
||||
gen_aad_ptr(ctx, t0, alop);
|
||||
|
||||
if (alop->als.sm) {
|
||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||
|
||||
l0 = gen_new_label();
|
||||
gen_probe_write_access(t1, t0, memop_size(memop), alop->ctx->mmuidx);
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l0);
|
||||
}
|
||||
|
||||
tcg_gen_qemu_st_i128(s4.val, t0, ctx->mmuidx, memop);
|
||||
|
||||
if (l0) {
|
||||
gen_set_label(l0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_staad(Alop *alop)
|
||||
{
|
||||
DisasContext *ctx = alop->ctx;
|
||||
uint8_t mas = alop->mas;
|
||||
|
@ -4524,11 +4602,7 @@ static void gen_staa_i64(Alop *alop)
|
|||
if (mas == 0x3f) {
|
||||
/* aaurwd */
|
||||
if (alop->als.aaopc == 0) {
|
||||
if (alop->chan == 5 && alop->als.opc1 == 0x3f) {
|
||||
gen_aaurwd_aad_hi(alop, s4.val, s4.tag);
|
||||
} else {
|
||||
gen_aaurwd_aad_lo(alop, s4.val, s4.tag);
|
||||
}
|
||||
gen_aaurwd_aad(alop, s4.val, s4.tag);
|
||||
} else {
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
tcg_gen_extrl_i64_i32(t0, s4.val);
|
||||
|
@ -4563,7 +4637,7 @@ static void gen_staa_i64(Alop *alop)
|
|||
}
|
||||
}
|
||||
|
||||
static void gen_staa_i32(Alop *alop, MemOp memop)
|
||||
static void gen_staaw(Alop *alop, MemOp memop)
|
||||
{
|
||||
DisasContext *ctx = alop->ctx;
|
||||
uint8_t mas = alop->mas;
|
||||
|
@ -4577,7 +4651,7 @@ static void gen_staa_i32(Alop *alop, MemOp memop)
|
|||
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_extu_i32_i64(t0, s4.val);
|
||||
gen_aaurwd_aad_lo(alop, t0, s4.tag);
|
||||
gen_aaurwd_aad(alop, t0, s4.tag);
|
||||
} else {
|
||||
gen_aaurw_rest_i32(alop, s4.val, s4.tag);
|
||||
}
|
||||
|
@ -5471,22 +5545,11 @@ static AlopResult gen_alop_simple(Alop *alop)
|
|||
case OP_PUTTAGS: return gen_puttags(alop);
|
||||
case OP_PUTTAGD: return gen_puttagd(alop);
|
||||
case OP_PUTTAGQP: return gen_puttagqp(alop);
|
||||
case OP_STAAB: gen_staa_i32(alop, MO_8); break;
|
||||
case OP_STAAH: gen_staa_i32(alop, MO_16); break;
|
||||
case OP_STAAW: gen_staa_i32(alop, MO_32); break;
|
||||
case OP_STAAD: gen_staa_i64(alop); break;
|
||||
case OP_STAAQ: {
|
||||
int pair_chan = alop->chan == 2 ? 5 : 2;
|
||||
if (!ctx->bundle.als_present[pair_chan] ||
|
||||
extract32(ctx->bundle.als[pair_chan], 24, 7) != 0x3f ||
|
||||
(alop->als.dst & 1) != (alop->chan == 2 ? 0 : 1))
|
||||
{
|
||||
gen_tr_excp_illopc(ctx);
|
||||
} else {
|
||||
gen_staa_i64(alop);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OP_STAAB: gen_staaw(alop, MO_8); break;
|
||||
case OP_STAAH: gen_staaw(alop, MO_16); break;
|
||||
case OP_STAAW: gen_staaw(alop, MO_32); break;
|
||||
case OP_STAAD: gen_staad(alop); break;
|
||||
case OP_STAAQ: gen_staaq(alop); break;
|
||||
case OP_STAAQP: gen_staaqp(alop); break;
|
||||
case OP_MULS: return gen_alopf1_sss(alop, tcg_gen_mul_i32);
|
||||
case OP_MULD: return gen_alopf1_ddd(alop, tcg_gen_mul_i64);
|
||||
|
|
Loading…
Reference in New Issue