target: e2k: Impl speculative execution.
This commit is contained in:
parent
7d03b739e9
commit
57b3469cda
|
@ -58,7 +58,7 @@ void cpu_loop(CPUE2KState *env)
|
||||||
} else if (ret != -TARGET_QEMU_ESIGRETURN) {
|
} else if (ret != -TARGET_QEMU_ESIGRETURN) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
regs[0] = ret;
|
regs[offset % E2K_NR_COUNT] = ret;
|
||||||
for (i = 1; i < 8; i++) {
|
for (i = 1; i < 8; i++) {
|
||||||
regs[(i + offset) % E2K_NR_COUNT] = 0;
|
regs[(i + offset) % E2K_NR_COUNT] = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ void e2k_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
||||||
for (i = 0; i < E2K_REG_COUNT; i++) {
|
for (i = 0; i < E2K_REG_COUNT; i++) {
|
||||||
char name = i < E2K_NR_COUNT ? 'r' : 'g';
|
char name = i < E2K_NR_COUNT ? 'r' : 'g';
|
||||||
int tag = extract_tag(env->tags, i);
|
int tag = extract_tag(env->tags, i);
|
||||||
qemu_fprintf(f, "%%%c%d\t<%d%d> 0x%lx\n", name, i, tag & 3, tag >> 2,
|
qemu_fprintf(f, "%%%c%d\t<%d%d> 0x%lx\n", name, i, tag >> 2, tag & 3,
|
||||||
env->regs[i]);
|
env->regs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,3 +13,5 @@ DEF_HELPER_3(state_reg_write_i32, void, env, int, i32)
|
||||||
DEF_HELPER_2(getsp, i64, env, i64) /* FIXME: return tl? */
|
DEF_HELPER_2(getsp, i64, env, i64) /* FIXME: return tl? */
|
||||||
DEF_HELPER_1(break_restore_state, void, env)
|
DEF_HELPER_1(break_restore_state, void, env)
|
||||||
DEF_HELPER_2(setwd, void, env, i32)
|
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)
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#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"
|
||||||
|
|
||||||
|
int HELPER(probe_read_access)(CPUE2KState *env, target_ulong addr)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
void *ignore;
|
||||||
|
|
||||||
|
flags = probe_access_flags(env, addr, MMU_DATA_LOAD, 0, true, &ignore, 0);
|
||||||
|
|
||||||
|
return (flags & TLB_INVALID_MASK) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int HELPER(probe_write_access)(CPUE2KState *env, target_ulong addr)
|
||||||
|
{
|
||||||
|
int flags;
|
||||||
|
void *ignore;
|
||||||
|
|
||||||
|
flags = probe_access_flags(env, addr, MMU_DATA_STORE, 0, true, &ignore, 0);
|
||||||
|
|
||||||
|
return (flags & TLB_INVALID_MASK) == 0;
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ e2k_ss.add(files(
|
||||||
'gdbstub.c',
|
'gdbstub.c',
|
||||||
'helper.c',
|
'helper.c',
|
||||||
'helper_int.c',
|
'helper_int.c',
|
||||||
|
'helper_sm.c',
|
||||||
'translate.c',
|
'translate.c',
|
||||||
'translate/state.c',
|
'translate/state.c',
|
||||||
'translate/control.c',
|
'translate/control.c',
|
||||||
|
|
|
@ -299,8 +299,7 @@ static inline void e2k_gen_lcntex(TCGv_i32 ret)
|
||||||
|
|
||||||
void e2k_gen_store_preg(int idx, TCGv_i64 val);
|
void e2k_gen_store_preg(int idx, TCGv_i64 val);
|
||||||
|
|
||||||
void e2k_gen_reg_tag_read_i64(TCGv_i32 ret, TCGv_i32 idx);
|
void e2k_gen_reg_tag_read(TCGv_i32 ret, TCGv_i32 idx);
|
||||||
void e2k_gen_reg_tag_read_i32(TCGv_i32 ret, TCGv_i32 idx);
|
|
||||||
void e2k_gen_reg_tag_write_i64(TCGv_i32 value, TCGv_i32 idx);
|
void e2k_gen_reg_tag_write_i64(TCGv_i32 value, TCGv_i32 idx);
|
||||||
void e2k_gen_reg_tag_write_i32(TCGv_i32 value, TCGv_i32 idx);
|
void e2k_gen_reg_tag_write_i32(TCGv_i32 value, TCGv_i32 idx);
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ static inline void gen_reg_i64(DisasContext *ctx, Src64 *ret, uint8_t arg)
|
||||||
gen_reg_index(t0, arg);
|
gen_reg_index(t0, arg);
|
||||||
ret->tag = e2k_get_temp_i32(ctx);
|
ret->tag = e2k_get_temp_i32(ctx);
|
||||||
ret->value = e2k_get_temp_i64(ctx);
|
ret->value = e2k_get_temp_i64(ctx);
|
||||||
e2k_gen_reg_tag_read_i32(ret->tag, t0);
|
e2k_gen_reg_tag_read(ret->tag, t0);
|
||||||
e2k_gen_reg_read_i64(ret->value, t0);
|
e2k_gen_reg_read_i64(ret->value, t0);
|
||||||
|
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
|
@ -46,7 +46,7 @@ static inline void gen_reg_i32(DisasContext *ctx, Src32 *ret, uint8_t arg)
|
||||||
gen_reg_index(t0, arg);
|
gen_reg_index(t0, arg);
|
||||||
ret->tag = e2k_get_temp_i32(ctx);
|
ret->tag = e2k_get_temp_i32(ctx);
|
||||||
ret->value = e2k_get_temp_i32(ctx);
|
ret->value = e2k_get_temp_i32(ctx);
|
||||||
e2k_gen_reg_tag_read_i32(ret->tag, t0);
|
e2k_gen_reg_tag_read(ret->tag, t0);
|
||||||
e2k_gen_reg_read_i32(ret->value, t0);
|
e2k_gen_reg_read_i32(ret->value, t0);
|
||||||
|
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
|
@ -247,51 +247,107 @@ static inline void set_al_result_preg(DisasContext *ctx, int chan, int index,
|
||||||
res->preg.value = value;
|
res->preg.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_andn_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y)
|
static void gen_tag_check_i64(bool sm, TCGv_i64 dst, TCGv_i32 dst_tag,
|
||||||
|
TCGv_i32 src_tag, TCGLabel *l)
|
||||||
|
{
|
||||||
|
if (src_tag != NULL) {
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
e2k_gen_reg_tag_check_i64(t0, src_tag);
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l0);
|
||||||
|
if (sm) {
|
||||||
|
if (dst_tag != NULL) {
|
||||||
|
tcg_gen_movi_i32(dst_tag, 5);
|
||||||
|
}
|
||||||
|
if (dst != NULL) {
|
||||||
|
tcg_gen_ori_i64(dst, dst, (1UL << 62) | (1UL << 30));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e2k_gen_exception(E2K_EXCP_ILLOPN);
|
||||||
|
}
|
||||||
|
if (l != NULL) {
|
||||||
|
tcg_gen_br(l);
|
||||||
|
}
|
||||||
|
gen_set_label(l0);
|
||||||
|
|
||||||
|
tcg_temp_free_i32(t0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_tag_check_i32(bool sm, TCGv_i32 dst, TCGv_i32 dst_tag,
|
||||||
|
TCGv_i32 tag, TCGLabel *l)
|
||||||
|
{
|
||||||
|
if (tag != NULL) {
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
e2k_gen_reg_tag_check_i32(t0, tag);
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l0);
|
||||||
|
if (sm) {
|
||||||
|
if (dst_tag != NULL) {
|
||||||
|
tcg_gen_movi_i32(dst_tag, 1);
|
||||||
|
}
|
||||||
|
if (dst != NULL) {
|
||||||
|
tcg_gen_ori_i32(dst, dst, 1 << 30);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
e2k_gen_exception(E2K_EXCP_ILLOPN);
|
||||||
|
}
|
||||||
|
if (l != NULL) {
|
||||||
|
tcg_gen_br(l);
|
||||||
|
}
|
||||||
|
gen_set_label(l0);
|
||||||
|
|
||||||
|
tcg_temp_free_i32(t0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gen_andn_i32(TCGv_i32 ret, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
{
|
{
|
||||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
tcg_gen_and_i32(t0, x, y);
|
tcg_gen_not_i32(t0, src2);
|
||||||
tcg_gen_not_i32(ret, t0);
|
tcg_gen_and_i32(ret, src1, t0);
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_andn_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y)
|
static inline void gen_andn_i64(TCGv_i64 ret, TCGv_i64 src1, TCGv_i64 src2)
|
||||||
{
|
{
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||||
tcg_gen_and_i64(t0, x, y);
|
tcg_gen_not_i64(t0, src2);
|
||||||
tcg_gen_not_i64(ret, t0);
|
tcg_gen_and_i64(ret, src1, t0);
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_orn_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y)
|
static inline void gen_orn_i32(TCGv_i32 ret, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
{
|
{
|
||||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
tcg_gen_or_i32(t0, x, y);
|
tcg_gen_not_i32(t0, src2);
|
||||||
tcg_gen_not_i32(ret, t0);
|
tcg_gen_or_i32(ret, src1, t0);
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_orn_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y)
|
static inline void gen_orn_i64(TCGv_i64 ret, TCGv_i64 src1, TCGv_i64 src2)
|
||||||
{
|
{
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||||
tcg_gen_or_i64(t0, x, y);
|
tcg_gen_not_i64(t0, src2);
|
||||||
tcg_gen_not_i64(ret, t0);
|
tcg_gen_or_i64(ret, src1, t0);
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_xorn_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y)
|
static inline void gen_xorn_i32(TCGv_i32 ret, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
{
|
{
|
||||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
tcg_gen_xor_i32(t0, x, y);
|
tcg_gen_not_i32(t0, src2);
|
||||||
tcg_gen_not_i32(ret, t0);
|
tcg_gen_xor_i32(ret, src1, t0);
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_xorn_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y)
|
static inline void gen_xorn_i64(TCGv_i64 ret, TCGv_i64 src1, TCGv_i64 src2)
|
||||||
{
|
{
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||||
tcg_gen_xor_i64(t0, x, y);
|
tcg_gen_not_i64(t0, src2);
|
||||||
tcg_gen_not_i64(ret, t0);
|
tcg_gen_xor_i64(ret, src1, t0);
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,16 +571,16 @@ static inline void gen_movehl_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y)
|
||||||
|
|
||||||
static inline void gen_merge_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y, TCGv_i32 cond)
|
static inline void gen_merge_i32(TCGv_i32 ret, TCGv_i32 x, TCGv_i32 y, TCGv_i32 cond)
|
||||||
{
|
{
|
||||||
TCGv_i32 one = tcg_const_i32(1);
|
TCGv_i32 zero = tcg_const_i32(0);
|
||||||
tcg_gen_movcond_i32(TCG_COND_EQ, ret, cond, one, x, y);
|
tcg_gen_movcond_i32(TCG_COND_EQ, ret, cond, zero, x, y);
|
||||||
tcg_temp_free_i32(one);
|
tcg_temp_free_i32(zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_merge_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y, TCGv_i64 cond)
|
static inline void gen_merge_i64(TCGv_i64 ret, TCGv_i64 x, TCGv_i64 y, TCGv_i64 cond)
|
||||||
{
|
{
|
||||||
TCGv_i64 one = tcg_const_i64(1);
|
TCGv_i64 zero = tcg_const_i64(0);
|
||||||
tcg_gen_movcond_i64(TCG_COND_EQ, ret, cond, one, x, y);
|
tcg_gen_movcond_i64(TCG_COND_EQ, ret, cond, zero, x, y);
|
||||||
tcg_temp_free_i64(one);
|
tcg_temp_free_i64(zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_mrgc(uint16_t rlp, int chan)
|
static inline bool is_mrgc(uint16_t rlp, int chan)
|
||||||
|
@ -590,17 +646,12 @@ static uint16_t find_cond(DisasContext *ctx, int chan)
|
||||||
static inline void gen_mrgc_i64(DisasContext *ctx, int chan, TCGv_i64 ret)
|
static inline void gen_mrgc_i64(DisasContext *ctx, int chan, TCGv_i64 ret)
|
||||||
{
|
{
|
||||||
uint16_t rlp = find_mrgc(ctx, chan);
|
uint16_t rlp = find_mrgc(ctx, chan);
|
||||||
TCGv_i64 inv = tcg_const_i64(GET_BIT(rlp, 7 + chan % 3));
|
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_new_i64();
|
||||||
TCGv_i64 t1 = tcg_temp_new_i64();
|
|
||||||
|
|
||||||
e2k_gen_cond_i64(ctx, t0, rlp & 0x7f);
|
e2k_gen_cond_i64(ctx, t0, rlp & 0x7f);
|
||||||
tcg_gen_not_i64(t1, t0);
|
tcg_gen_xori_i64(ret, t0, GET_BIT(rlp, 7 + chan % 3));
|
||||||
tcg_gen_movcond_i64(TCG_COND_EQ, ret, t0, inv, t0, t1);
|
|
||||||
|
|
||||||
tcg_temp_free_i64(t1);
|
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
tcg_temp_free_i64(inv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_mrgc_i32(DisasContext *dc, int chan, TCGv_i32 ret)
|
static inline void gen_mrgc_i32(DisasContext *dc, int chan, TCGv_i32 ret)
|
||||||
|
@ -611,6 +662,78 @@ static inline void gen_mrgc_i32(DisasContext *dc, int chan, TCGv_i32 ret)
|
||||||
tcg_temp_free(t0);
|
tcg_temp_free(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gen_udivd(TCGv_i64 ret, TCGv_i32 ret_tag, bool sm,
|
||||||
|
TCGv_i64 src1, TCGv_i64 src2)
|
||||||
|
{
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
|
||||||
|
if (sm) {
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
|
tcg_gen_brcondi_i64(TCG_COND_NE, src2, 0, l1);
|
||||||
|
tcg_gen_movi_i32(ret_tag, 5);
|
||||||
|
tcg_gen_movi_i64(ret, 0);
|
||||||
|
tcg_gen_br(l0);
|
||||||
|
gen_set_label(l1);
|
||||||
|
}
|
||||||
|
tcg_gen_movi_i32(ret_tag, 0);
|
||||||
|
tcg_gen_divu_i64(ret, src1, src2);
|
||||||
|
gen_set_label(l0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gen_udivs(TCGv_i32 ret, TCGv_i32 ret_tag, bool sm,
|
||||||
|
TCGv_i32 src1, TCGv_i32 src2)
|
||||||
|
{
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
|
||||||
|
if (sm) {
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_NE, src2, 0, l1);
|
||||||
|
tcg_gen_movi_i32(ret_tag, 5);
|
||||||
|
tcg_gen_movi_i32(ret, 0);
|
||||||
|
tcg_gen_br(l0);
|
||||||
|
gen_set_label(l1);
|
||||||
|
}
|
||||||
|
tcg_gen_movi_i32(ret_tag, 0);
|
||||||
|
tcg_gen_divu_i32(ret, src1, src2);
|
||||||
|
gen_set_label(l0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gen_sdivd(TCGv_i64 ret, TCGv_i32 ret_tag, bool sm,
|
||||||
|
TCGv_i64 src1, TCGv_i64 src2)
|
||||||
|
{
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
|
||||||
|
if (sm) {
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
|
tcg_gen_brcondi_i64(TCG_COND_NE, src2, 0, l1);
|
||||||
|
tcg_gen_movi_i32(ret_tag, 5);
|
||||||
|
tcg_gen_movi_i64(ret, 0);
|
||||||
|
tcg_gen_br(l0);
|
||||||
|
gen_set_label(l1);
|
||||||
|
}
|
||||||
|
tcg_gen_movi_i32(ret_tag, 0);
|
||||||
|
tcg_gen_div_i64(ret, src1, src2);
|
||||||
|
gen_set_label(l0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void gen_sdivs(TCGv_i32 ret, TCGv_i32 ret_tag, bool sm,
|
||||||
|
TCGv_i32 src1, TCGv_i32 src2)
|
||||||
|
{
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
|
||||||
|
if (sm) {
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_NE, src2, 0, l1);
|
||||||
|
tcg_gen_movi_i32(ret_tag, 5);
|
||||||
|
tcg_gen_movi_i32(ret, 0);
|
||||||
|
tcg_gen_br(l0);
|
||||||
|
gen_set_label(l1);
|
||||||
|
}
|
||||||
|
tcg_gen_movi_i32(ret_tag, 0);
|
||||||
|
tcg_gen_div_i32(ret, src1, src2);
|
||||||
|
gen_set_label(l0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void gen_rr_i64(DisasContext *ctx, int chan)
|
static inline void gen_rr_i64(DisasContext *ctx, int chan)
|
||||||
{
|
{
|
||||||
uint32_t als = ctx->bundle.als[chan];
|
uint32_t als = ctx->bundle.als[chan];
|
||||||
|
@ -639,9 +762,10 @@ static inline void gen_rw_i64(DisasContext *ctx, int chan)
|
||||||
{
|
{
|
||||||
uint32_t als = ctx->bundle.als[chan];
|
uint32_t als = ctx->bundle.als[chan];
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
TCGv_i32 t0 = tcg_const_i32(als & 0xff);
|
TCGv_i32 t0;
|
||||||
|
|
||||||
// TODO: check tags
|
gen_tag_check_i64(false, NULL, NULL, s2.tag, NULL);
|
||||||
|
t0 = tcg_const_i32(als & 0xff);
|
||||||
gen_helper_state_reg_write_i64(cpu_env, t0, s2.value);
|
gen_helper_state_reg_write_i64(cpu_env, t0, s2.value);
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
}
|
}
|
||||||
|
@ -650,9 +774,10 @@ static inline void gen_rw_i32(DisasContext *ctx, int chan)
|
||||||
{
|
{
|
||||||
uint32_t als = ctx->bundle.als[chan];
|
uint32_t als = ctx->bundle.als[chan];
|
||||||
Src32 s2 = get_src2_i32(ctx, chan);
|
Src32 s2 = get_src2_i32(ctx, chan);
|
||||||
TCGv_i32 t0 = tcg_const_i32(als & 0xff);
|
TCGv_i32 t0;
|
||||||
|
|
||||||
// TODO: check tags
|
gen_tag_check_i32(false, NULL, NULL, s2.tag, NULL);
|
||||||
|
t0 = tcg_const_i32(als & 0xff);
|
||||||
gen_helper_state_reg_write_i32(cpu_env, t0, s2.value);
|
gen_helper_state_reg_write_i32(cpu_env, t0, s2.value);
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
}
|
}
|
||||||
|
@ -667,14 +792,10 @@ static void gen_getsp(DisasContext *ctx, int chan)
|
||||||
set_al_result_reg64(ctx, chan, dst);
|
set_al_result_reg64(ctx, chan, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: movtd: don't know what it does */
|
|
||||||
static void gen_movtd(DisasContext *ctx, int chan)
|
static void gen_movtd(DisasContext *ctx, int chan)
|
||||||
{
|
{
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
set_al_result_reg64_tag(ctx, chan, s2.value, s2.tag);
|
||||||
|
|
||||||
tcg_gen_mov_i64(dst, s2.value);
|
|
||||||
set_al_result_reg64(ctx, chan, dst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MemOp gen_mas(DisasContext *ctx, int chan, MemOp memop, TCGv_i64 addr)
|
static MemOp gen_mas(DisasContext *ctx, int chan, MemOp memop, TCGv_i64 addr)
|
||||||
|
@ -704,31 +825,71 @@ static MemOp gen_mas(DisasContext *ctx, int chan, MemOp memop, TCGv_i64 addr)
|
||||||
|
|
||||||
static void gen_ld(DisasContext *ctx, int chan, MemOp memop)
|
static void gen_ld(DisasContext *ctx, int chan, MemOp memop)
|
||||||
{
|
{
|
||||||
|
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
Src64 s1 = get_src1_i64(ctx, chan);
|
Src64 s1 = get_src1_i64(ctx, chan);
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_local_new_i64();
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||||
|
|
||||||
// TODO: check tags
|
tcg_gen_movi_i64(dst, 0);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s1.tag, l1);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s2.tag, l1);
|
||||||
|
|
||||||
tcg_gen_add_i64(t0, s1.value, s2.value);
|
tcg_gen_add_i64(t0, s1.value, s2.value);
|
||||||
memop = gen_mas(ctx, chan, memop, t0);
|
memop = gen_mas(ctx, chan, memop, t0);
|
||||||
|
|
||||||
|
if (sm) {
|
||||||
|
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
gen_helper_probe_read_access(t1, cpu_env, t0);
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 1, l0);
|
||||||
|
tcg_temp_free_i32(t1);
|
||||||
|
tcg_gen_movi_i32(tag, 5);
|
||||||
|
tcg_gen_movi_i64(dst, 0x4afafafa4afafafa);
|
||||||
|
tcg_gen_br(l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_set_label(l0);
|
||||||
|
tcg_gen_movi_i32(tag, 0);
|
||||||
tcg_gen_qemu_ld_i64(dst, t0, ctx->mmuidx, memop);
|
tcg_gen_qemu_ld_i64(dst, t0, ctx->mmuidx, memop);
|
||||||
set_al_result_reg64(ctx, chan, dst);
|
|
||||||
|
gen_set_label(l1);
|
||||||
|
set_al_result_reg64_tag(ctx, chan, dst, tag);
|
||||||
|
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(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);
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
Src64 s1 = get_src1_i64(ctx, chan);
|
Src64 s1 = get_src1_i64(ctx, chan);
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
Src64 s4 = get_src4_i64(ctx, chan);
|
Src64 s4 = get_src4_i64(ctx, chan);
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
TCGv_i64 t0 = tcg_temp_local_new_i64();
|
||||||
|
|
||||||
|
gen_tag_check_i64(sm, NULL, NULL, s1.tag, l1);
|
||||||
|
gen_tag_check_i64(sm, NULL, NULL, s2.tag, l1);
|
||||||
|
gen_tag_check_i64(sm, NULL, NULL, s4.tag, l1);
|
||||||
|
|
||||||
// TODO: check tags
|
|
||||||
tcg_gen_add_i64(t0, s1.value, s2.value);
|
tcg_gen_add_i64(t0, s1.value, s2.value);
|
||||||
memop = gen_mas(ctx, chan, memop, t0);
|
memop = gen_mas(ctx, chan, memop, t0);
|
||||||
|
|
||||||
|
if (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, l1);
|
||||||
|
tcg_temp_free_i32(t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
gen_set_label(l0);
|
||||||
tcg_gen_qemu_st_i64(s4.value, t0, ctx->mmuidx, memop);
|
tcg_gen_qemu_st_i64(s4.value, t0, ctx->mmuidx, memop);
|
||||||
|
gen_set_label(l1);
|
||||||
|
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i64(t0);
|
||||||
}
|
}
|
||||||
|
@ -736,39 +897,112 @@ static void gen_st(DisasContext *ctx, int chan, MemOp memop)
|
||||||
static void gen_alopf1_i32(DisasContext *ctx, int chan,
|
static void gen_alopf1_i32(DisasContext *ctx, int chan,
|
||||||
void (*op)(TCGv_i32, TCGv_i32, TCGv_i32))
|
void (*op)(TCGv_i32, TCGv_i32, TCGv_i32))
|
||||||
{
|
{
|
||||||
|
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||||
Src32 s1 = get_src1_i32(ctx, chan);
|
Src32 s1 = get_src1_i32(ctx, chan);
|
||||||
Src32 s2 = get_src2_i32(ctx, chan);
|
Src32 s2 = get_src2_i32(ctx, chan);
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
TCGv_i32 dst = e2k_get_temp_i32(ctx);
|
TCGv_i32 dst = e2k_get_temp_i32(ctx);
|
||||||
|
|
||||||
// TODO: check tags
|
tcg_gen_movi_i32(tag, 0);
|
||||||
(*op)(dst, s1.value, s2.value);
|
(*op)(dst, s1.value, s2.value);
|
||||||
set_al_result_reg32(ctx, chan, dst);
|
|
||||||
|
gen_tag_check_i32(sm, dst, tag, s1.tag, NULL);
|
||||||
|
gen_tag_check_i32(sm, dst, tag, s2.tag, NULL);
|
||||||
|
|
||||||
|
set_al_result_reg32_tag(ctx, chan, dst, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_alopf1_i64(DisasContext *ctx, int chan,
|
static void gen_alopf1_i64(DisasContext *ctx, int chan,
|
||||||
void (*op)(TCGv_i64, TCGv_i64, TCGv_i64))
|
void (*op)(TCGv_i64, TCGv_i64, TCGv_i64))
|
||||||
{
|
{
|
||||||
|
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||||
Src64 s1 = get_src1_i64(ctx, chan);
|
Src64 s1 = get_src1_i64(ctx, chan);
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||||
|
|
||||||
// TODO: check tags
|
tcg_gen_movi_i32(tag, 0);
|
||||||
(*op)(dst, s1.value, s2.value);
|
(*op)(dst, s1.value, s2.value);
|
||||||
set_al_result_reg64(ctx, chan, dst);
|
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s1.tag, NULL);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s2.tag, NULL);
|
||||||
|
|
||||||
|
set_al_result_reg64_tag(ctx, chan, dst, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_alopf1_tag_i64(DisasContext *ctx, int chan,
|
||||||
|
void (*op)(TCGv_i64, TCGv_i32, bool, TCGv_i64, TCGv_i64))
|
||||||
|
{
|
||||||
|
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
|
Src64 s1 = get_src1_i64(ctx, chan);
|
||||||
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
|
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||||
|
|
||||||
|
tcg_gen_movi_i32(tag, 0);
|
||||||
|
(*op)(dst, tag, sm, s1.value, s2.value);
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_EQ, tag, 0, l0);
|
||||||
|
tcg_gen_ori_i64(dst, dst, (1UL << 62) | (1UL << 30));
|
||||||
|
tcg_gen_br(l1);
|
||||||
|
|
||||||
|
gen_set_label(l0);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s1.tag, NULL);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s2.tag, NULL);
|
||||||
|
|
||||||
|
gen_set_label(l1);
|
||||||
|
set_al_result_reg64_tag(ctx, chan, dst, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_alopf1_tag_i32(DisasContext *ctx, int chan,
|
||||||
|
void (*op)(TCGv_i32, TCGv_i32, bool, TCGv_i32, TCGv_i32))
|
||||||
|
{
|
||||||
|
bool sm = GET_BIT(ctx->bundle.als[chan], 31);
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
|
Src32 s1 = get_src1_i32(ctx, chan);
|
||||||
|
Src32 s2 = get_src2_i32(ctx, chan);
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
|
TCGv_i32 dst = e2k_get_temp_i32(ctx);
|
||||||
|
|
||||||
|
tcg_gen_movi_i32(tag, 0);
|
||||||
|
(*op)(dst, tag, sm, s1.value, s2.value);
|
||||||
|
tcg_gen_brcondi_i32(TCG_COND_EQ, tag, 0, l0);
|
||||||
|
tcg_gen_ori_i32(dst, dst, 1UL << 30);
|
||||||
|
tcg_gen_br(l1);
|
||||||
|
|
||||||
|
gen_set_label(l0);
|
||||||
|
gen_tag_check_i32(sm, dst, tag, s1.tag, NULL);
|
||||||
|
gen_tag_check_i32(sm, dst, tag, s2.tag, NULL);
|
||||||
|
|
||||||
|
gen_set_label(l1);
|
||||||
|
set_al_result_reg32_tag(ctx, chan, dst, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_alopf1_cmp_i64(DisasContext *ctx, int chan,
|
static void gen_alopf1_cmp_i64(DisasContext *ctx, int chan,
|
||||||
void (*op)(TCGv_i64, int, TCGv_i64, TCGv_i64))
|
void (*op)(TCGv_i64, int, TCGv_i64, TCGv_i64))
|
||||||
{
|
{
|
||||||
uint32_t als = ctx->bundle.als[chan];
|
uint32_t als = ctx->bundle.als[chan];
|
||||||
|
bool sm = extract32(als, 31, 1);
|
||||||
int opc = extract32(als, 5, 3);
|
int opc = extract32(als, 5, 3);
|
||||||
int idx = extract32(als, 0, 5);
|
int idx = extract32(als, 0, 5);
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
Src64 s1 = get_src1_i64(ctx, chan);
|
Src64 s1 = get_src1_i64(ctx, chan);
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||||
|
|
||||||
// TODO: check tags
|
gen_tag_check_i32(sm, NULL, NULL, s1.tag, l0);
|
||||||
|
gen_tag_check_i32(sm, NULL, NULL, s2.tag, l0);
|
||||||
|
|
||||||
(*op)(dst, opc, s1.value, s2.value);
|
(*op)(dst, opc, s1.value, s2.value);
|
||||||
|
tcg_gen_br(l1);
|
||||||
|
|
||||||
|
gen_set_label(l0);
|
||||||
|
tcg_gen_movi_i64(dst, 2);
|
||||||
|
|
||||||
|
gen_set_label(l1);
|
||||||
set_al_result_preg(ctx, chan, idx, dst);
|
set_al_result_preg(ctx, chan, idx, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -776,49 +1010,65 @@ static void gen_alopf1_cmp_i32(DisasContext *ctx, int chan,
|
||||||
void (*op)(TCGv_i32, int, TCGv_i32, TCGv_i32))
|
void (*op)(TCGv_i32, int, TCGv_i32, TCGv_i32))
|
||||||
{
|
{
|
||||||
uint32_t als = ctx->bundle.als[chan];
|
uint32_t als = ctx->bundle.als[chan];
|
||||||
|
bool sm = extract32(als, 31, 1);
|
||||||
int opc = extract32(als, 5, 3);
|
int opc = extract32(als, 5, 3);
|
||||||
int idx = extract32(als, 0, 5);
|
int idx = extract32(als, 0, 5);
|
||||||
|
TCGLabel *l0 = gen_new_label();
|
||||||
|
TCGLabel *l1 = gen_new_label();
|
||||||
Src32 s1 = get_src1_i32(ctx, chan);
|
Src32 s1 = get_src1_i32(ctx, chan);
|
||||||
Src32 s2 = get_src2_i32(ctx, chan);
|
Src32 s2 = get_src2_i32(ctx, chan);
|
||||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
|
|
||||||
// TODO: check tags
|
gen_tag_check_i32(sm, NULL, NULL, s1.tag, l0);
|
||||||
|
gen_tag_check_i32(sm, NULL, NULL, s2.tag, l0);
|
||||||
|
|
||||||
(*op)(t0, opc, s1.value, s2.value);
|
(*op)(t0, opc, s1.value, s2.value);
|
||||||
tcg_gen_extu_i32_i64(dst, t0);
|
tcg_gen_extu_i32_i64(dst, t0);
|
||||||
|
tcg_gen_br(l1);
|
||||||
tcg_temp_free_i32(t0);
|
tcg_temp_free_i32(t0);
|
||||||
|
|
||||||
|
gen_set_label(l0);
|
||||||
|
tcg_gen_movi_i64(dst, 2);
|
||||||
|
|
||||||
|
gen_set_label(l1);
|
||||||
set_al_result_preg(ctx, chan, idx, dst);
|
set_al_result_preg(ctx, chan, idx, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_alopf1_mrgc_i32(DisasContext *ctx, int chan)
|
static void gen_alopf1_mrgc_i32(DisasContext *ctx, int chan)
|
||||||
{
|
{
|
||||||
Src64 s1 = get_src1_i64(ctx, chan);
|
bool sm = extract32(ctx->bundle.als[chan], 31, 1);
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src32 s1 = get_src1_i32(ctx, chan);
|
||||||
|
Src32 s2 = get_src2_i32(ctx, chan);
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
TCGv_i32 dst = e2k_get_temp_i32(ctx);
|
TCGv_i32 dst = e2k_get_temp_i32(ctx);
|
||||||
TCGv_i64 cond = tcg_temp_new_i64();
|
TCGv_i32 cond = tcg_temp_new_i32();
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64();
|
|
||||||
|
|
||||||
// TODO: check tags
|
gen_mrgc_i32(ctx, chan, cond);
|
||||||
gen_mrgc_i64(ctx, chan, cond);
|
gen_merge_i32(dst, s1.value, s2.value, cond);
|
||||||
gen_merge_i64(t0, s1.value, s2.value, cond);
|
tcg_gen_movi_i32(tag, 0);
|
||||||
tcg_gen_extrl_i64_i32(dst, t0);
|
gen_tag_check_i32(sm, dst, tag, s1.tag, NULL);
|
||||||
set_al_result_reg32(ctx, chan, dst);
|
gen_tag_check_i32(sm, dst, tag, s2.tag, NULL);
|
||||||
|
set_al_result_reg32_tag(ctx, chan, dst, tag);
|
||||||
|
|
||||||
tcg_temp_free_i64(t0);
|
tcg_temp_free_i32(cond);
|
||||||
tcg_temp_free_i64(cond);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_alopf1_mrgc_i64(DisasContext *ctx, int chan)
|
static void gen_alopf1_mrgc_i64(DisasContext *ctx, int chan)
|
||||||
{
|
{
|
||||||
|
bool sm = extract32(ctx->bundle.als[chan], 31, 1);
|
||||||
Src64 s1 = get_src1_i64(ctx, chan);
|
Src64 s1 = get_src1_i64(ctx, chan);
|
||||||
Src64 s2 = get_src2_i64(ctx, chan);
|
Src64 s2 = get_src2_i64(ctx, chan);
|
||||||
TCGv_i64 cond = tcg_temp_new_i64();
|
TCGv_i64 cond = tcg_temp_new_i64();
|
||||||
|
TCGv_i32 tag = e2k_get_temp_i32(ctx);
|
||||||
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
TCGv_i64 dst = e2k_get_temp_i64(ctx);
|
||||||
|
|
||||||
// TODO: check tags
|
|
||||||
gen_mrgc_i64(ctx, chan, cond);
|
gen_mrgc_i64(ctx, chan, cond);
|
||||||
gen_merge_i64(dst, s1.value, s2.value, cond);
|
gen_merge_i64(dst, s1.value, s2.value, cond);
|
||||||
set_al_result_reg64(ctx, chan, dst);
|
tcg_gen_movi_i32(tag, 0);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s1.tag, NULL);
|
||||||
|
gen_tag_check_i64(sm, dst, tag, s2.tag, NULL);
|
||||||
|
set_al_result_reg64_tag(ctx, chan, dst, tag);
|
||||||
|
|
||||||
tcg_temp_free_i64(cond);
|
tcg_temp_free_i64(cond);
|
||||||
}
|
}
|
||||||
|
@ -929,28 +1179,28 @@ static void execute_alopf_simple(DisasContext *dc, int chan)
|
||||||
e2k_gen_exception(0);
|
e2k_gen_exception(0);
|
||||||
gen_set_label(l0);
|
gen_set_label(l0);
|
||||||
|
|
||||||
gen_alopf1_i32(dc, chan, tcg_gen_divu_i32);
|
gen_alopf1_tag_i32(dc, chan, gen_udivs); /* udivs */
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x41:
|
case 0x41:
|
||||||
if (is_div_chan(chan)) {
|
if (is_div_chan(chan)) {
|
||||||
gen_alopf1_i64(dc, chan, tcg_gen_divu_i64);
|
gen_alopf1_tag_i64(dc, chan, gen_udivd); /* udivd */
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x42:
|
case 0x42:
|
||||||
if (is_div_chan(chan)) {
|
if (is_div_chan(chan)) {
|
||||||
gen_alopf1_i32(dc, chan, tcg_gen_div_i32);
|
gen_alopf1_tag_i32(dc, chan, gen_sdivs); /* sdivs */
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x43:
|
case 0x43:
|
||||||
if (is_div_chan(chan)) {
|
if (is_div_chan(chan)) {
|
||||||
gen_alopf1_i64(dc, chan, tcg_gen_div_i64);
|
gen_alopf1_tag_i64(dc, chan, gen_sdivd); /* sdivd */
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -1100,7 +1350,6 @@ void e2k_alc_commit(DisasContext *ctx)
|
||||||
e2k_gen_reg_write_i64(res->reg.v64, res->reg.index);
|
e2k_gen_reg_write_i64(res->reg.v64, res->reg.index);
|
||||||
break;
|
break;
|
||||||
case AL_RESULT_PREG:
|
case AL_RESULT_PREG:
|
||||||
// TODO: write predicate register tag
|
|
||||||
e2k_gen_store_preg(res->preg.index, res->preg.value);
|
e2k_gen_store_preg(res->preg.index, res->preg.value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -78,8 +78,8 @@ void e2k_gen_store_preg(int idx, TCGv_i64 val)
|
||||||
|
|
||||||
gen_preg_offset(t0, idx);
|
gen_preg_offset(t0, idx);
|
||||||
gen_preg_clear(t1, t0);
|
gen_preg_clear(t1, t0);
|
||||||
tcg_gen_setcondi_i64(TCG_COND_NE, t2, val, 0);
|
tcg_gen_andi_i64(t2, val, 3);
|
||||||
tcg_gen_shl_i64(t3, t2, t0);
|
tcg_gen_shl_i64(t3, val, t0);
|
||||||
tcg_gen_or_i64(e2k_cs.pregs, t1, t3);
|
tcg_gen_or_i64(e2k_cs.pregs, t1, t3);
|
||||||
|
|
||||||
tcg_temp_free_i64(t3);
|
tcg_temp_free_i64(t3);
|
||||||
|
@ -137,43 +137,29 @@ static inline void gen_reg_tags_read(TCGv_i32 ret, TCGv_i32 idx, int len)
|
||||||
tcg_temp_free_i64(t4);
|
tcg_temp_free_i64(t4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2k_gen_reg_tag_read_i64(TCGv_i32 ret, TCGv_i32 idx)
|
void e2k_gen_reg_tag_read(TCGv_i32 ret, TCGv_i32 idx)
|
||||||
{
|
{
|
||||||
gen_reg_tags_read(ret, idx, E2K_REG_TAGS_SIZE);
|
gen_reg_tags_read(ret, idx, E2K_REG_TAGS_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2k_gen_reg_tag_read_i32(TCGv_i32 ret, TCGv_i32 idx)
|
|
||||||
{
|
|
||||||
gen_reg_tags_read(ret, idx, E2K_TAG_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gen_tag_check(TCGv_i32 ret, TCGv_i32 tag)
|
static inline void gen_tag_check(TCGv_i32 ret, TCGv_i32 tag)
|
||||||
{
|
{
|
||||||
// FIXME: what CPU does if tag is greater than 1?
|
// FIXME: what CPU does if tag is greater than 1?
|
||||||
tcg_gen_setcondi_i32(TCG_COND_GTU, ret, tag, 0);
|
tcg_gen_setcondi_i32(TCG_COND_NE, ret, tag, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2k_gen_reg_tag_check_i64(TCGv_i32 ret, TCGv_i32 tag)
|
void e2k_gen_reg_tag_check_i64(TCGv_i32 ret, TCGv_i32 tag)
|
||||||
{
|
{
|
||||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
gen_tag_check(ret, tag);
|
||||||
TCGv_i32 t1 = tcg_temp_new_i32();
|
|
||||||
TCGv_i32 t2 = tcg_temp_new_i32();
|
|
||||||
TCGv_i32 t3 = tcg_temp_new_i32();
|
|
||||||
|
|
||||||
e2k_gen_reg_tag_extract_lo(t0, tag);
|
|
||||||
gen_tag_check(t1, t0);
|
|
||||||
tcg_temp_free_i32(t0);
|
|
||||||
e2k_gen_reg_tag_extract_hi(t2, tag);
|
|
||||||
gen_tag_check(t3, t2);
|
|
||||||
tcg_temp_free_i32(t2);
|
|
||||||
tcg_gen_or_i32(ret, t1, t3);
|
|
||||||
tcg_temp_free_i32(t1);
|
|
||||||
tcg_temp_free_i32(t3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2k_gen_reg_tag_check_i32(TCGv_i32 ret, TCGv_i32 tag)
|
void e2k_gen_reg_tag_check_i32(TCGv_i32 ret, TCGv_i32 tag)
|
||||||
{
|
{
|
||||||
gen_tag_check(ret, tag);
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
e2k_gen_reg_tag_extract_lo(t0, tag);
|
||||||
|
gen_tag_check(ret, t0);
|
||||||
|
tcg_temp_free_i32(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_reg_tags_write(TCGv_i32 value, TCGv_i32 idx, int len)
|
static inline void gen_reg_tags_write(TCGv_i32 value, TCGv_i32 idx, int len)
|
||||||
|
@ -184,7 +170,7 @@ static inline void gen_reg_tags_write(TCGv_i32 value, TCGv_i32 idx, int len)
|
||||||
TCGv_i64 t3 = tcg_temp_new_i64();
|
TCGv_i64 t3 = tcg_temp_new_i64();
|
||||||
TCGv_i64 t4 = tcg_const_i64(len);
|
TCGv_i64 t4 = tcg_const_i64(len);
|
||||||
TCGv_i64 t5 = tcg_temp_new_i64();
|
TCGv_i64 t5 = tcg_temp_new_i64();
|
||||||
|
|
||||||
gen_reg_tags_group_ptr(t0, idx);
|
gen_reg_tags_group_ptr(t0, idx);
|
||||||
tcg_gen_ld_i64(t1, t0, 0);
|
tcg_gen_ld_i64(t1, t0, 0);
|
||||||
tcg_gen_extu_i32_i64(t2, value);
|
tcg_gen_extu_i32_i64(t2, value);
|
||||||
|
|
Loading…
Reference in New Issue