mirror of https://github.com/xqemu/xqemu.git
tcg-mips: add guest base support
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
489722cf3f
commit
cc01cc8ea2
|
@ -707,6 +707,9 @@ case "$cpu" in
|
||||||
ppc*)
|
ppc*)
|
||||||
host_guest_base="yes"
|
host_guest_base="yes"
|
||||||
;;
|
;;
|
||||||
|
mips*)
|
||||||
|
host_guest_base="yes"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
[ -z "$guest_base" ] && guest_base="$host_guest_base"
|
[ -z "$guest_base" ] && guest_base="$host_guest_base"
|
||||||
|
|
|
@ -222,8 +222,8 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
|
||||||
case 'S': /* qemu_st constraint */
|
case 'S': /* qemu_st constraint */
|
||||||
ct->ct |= TCG_CT_REG;
|
ct->ct |= TCG_CT_REG;
|
||||||
tcg_regset_set(ct->u.regs, 0xffffffff);
|
tcg_regset_set(ct->u.regs, 0xffffffff);
|
||||||
#if defined(CONFIG_SOFTMMU)
|
|
||||||
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
|
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
|
||||||
|
#if defined(CONFIG_SOFTMMU)
|
||||||
# if TARGET_LONG_BITS == 64
|
# if TARGET_LONG_BITS == 64
|
||||||
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
|
tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
|
||||||
# endif
|
# endif
|
||||||
|
@ -858,54 +858,55 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
|
||||||
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
|
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
|
||||||
offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);
|
offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);
|
||||||
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
|
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_A0, addr_regl);
|
||||||
|
#else
|
||||||
addr_reg1 = TCG_REG_V0;
|
if (GUEST_BASE == (int16_t)GUEST_BASE) {
|
||||||
|
tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_V0, addr_reg1, GUEST_BASE);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_V0, GUEST_BASE);
|
||||||
|
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_V0, TCG_REG_V0, addr_reg1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(opc) {
|
switch(opc) {
|
||||||
case 0:
|
case 0:
|
||||||
tcg_out_opc_imm(s, OPC_LBU, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LBU, data_reg1, TCG_REG_V0, 0);
|
||||||
break;
|
break;
|
||||||
case 0 | 4:
|
case 0 | 4:
|
||||||
tcg_out_opc_imm(s, OPC_LB, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LB, data_reg1, TCG_REG_V0, 0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
|
||||||
tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
|
tcg_out_bswap16(s, data_reg1, TCG_REG_T0);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_LHU, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LHU, data_reg1, TCG_REG_V0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1 | 4:
|
case 1 | 4:
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LHU, TCG_REG_T0, TCG_REG_V0, 0);
|
||||||
tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
|
tcg_out_bswap16s(s, data_reg1, TCG_REG_T0);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_LH, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LH, data_reg1, TCG_REG_V0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
|
||||||
tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
|
tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_LW, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
#if !defined(CONFIG_SOFTMMU)
|
|
||||||
tcg_out_mov(s, TCG_REG_V0, addr_reg1);
|
|
||||||
addr_reg1 = TCG_REG_V0;
|
|
||||||
#endif
|
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, addr_reg1, 4);
|
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 4);
|
||||||
tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
|
tcg_out_bswap32(s, data_reg1, TCG_REG_T0);
|
||||||
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LW, TCG_REG_T0, TCG_REG_V0, 0);
|
||||||
tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
|
tcg_out_bswap32(s, data_reg2, TCG_REG_T0);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_LW, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0);
|
||||||
tcg_out_opc_imm(s, OPC_LW, data_reg2, addr_reg1, 4);
|
tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1044,39 +1045,45 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
|
||||||
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
|
tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0,
|
||||||
offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);
|
offsetof(CPUState, tlb_table[mem_index][0].addend) + addr_meml);
|
||||||
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
|
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_regl);
|
||||||
|
#else
|
||||||
|
if (GUEST_BASE == (int16_t)GUEST_BASE) {
|
||||||
|
tcg_out_opc_imm(s, OPC_ADDIU, TCG_REG_A0, addr_reg1, GUEST_BASE);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, GUEST_BASE);
|
||||||
|
tcg_out_opc_reg(s, OPC_ADDU, TCG_REG_A0, TCG_REG_A0, addr_reg1);
|
||||||
|
}
|
||||||
|
|
||||||
addr_reg1 = TCG_REG_A0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(opc) {
|
switch(opc) {
|
||||||
case 0:
|
case 0:
|
||||||
tcg_out_opc_imm(s, OPC_SB, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SB, data_reg1, TCG_REG_A0, 0);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
|
tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
|
||||||
tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_SH, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
|
tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
|
||||||
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_SW, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (TCG_NEED_BSWAP) {
|
if (TCG_NEED_BSWAP) {
|
||||||
tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
|
tcg_out_bswap32(s, TCG_REG_T0, data_reg2);
|
||||||
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 0);
|
||||||
tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
|
tcg_out_bswap32(s, TCG_REG_T0, data_reg1);
|
||||||
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, addr_reg1, 4);
|
tcg_out_opc_imm(s, OPC_SW, TCG_REG_T0, TCG_REG_A0, 4);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_opc_imm(s, OPC_SW, data_reg1, addr_reg1, 0);
|
tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0);
|
||||||
tcg_out_opc_imm(s, OPC_SW, data_reg2, addr_reg1, 4);
|
tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -99,6 +99,9 @@ enum {
|
||||||
/* Note: must be synced with dyngen-exec.h */
|
/* Note: must be synced with dyngen-exec.h */
|
||||||
#define TCG_AREG0 TCG_REG_FP
|
#define TCG_AREG0 TCG_REG_FP
|
||||||
|
|
||||||
|
/* guest base is supported */
|
||||||
|
#define TCG_TARGET_HAS_GUEST_BASE
|
||||||
|
|
||||||
#include <sys/cachectl.h>
|
#include <sys/cachectl.h>
|
||||||
|
|
||||||
static inline void flush_icache_range(unsigned long start, unsigned long stop)
|
static inline void flush_icache_range(unsigned long start, unsigned long stop)
|
||||||
|
|
Loading…
Reference in New Issue