diff --git a/configure b/configure index f9e08f6999a38793f88e21014f48d01fe5ab5629..664c920b1e272ab644640d31d001897282c0097b 100755 --- a/configure +++ b/configure @@ -707,6 +707,9 @@ case "$cpu" in ppc*) host_guest_base="yes" ;; + mips*) + host_guest_base="yes" + ;; esac [ -z "$guest_base" ] && guest_base="$host_guest_base" diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 7744281ff85b7c9d2ef75629349f3d70a1a4af83..3e55871d126ce4c8eb03388b08ab44688ec77a02 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -222,8 +222,8 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str) case 'S': /* qemu_st constraint */ ct->ct |= TCG_CT_REG; tcg_regset_set(ct->u.regs, 0xffffffff); -#if defined(CONFIG_SOFTMMU) tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0); +#if defined(CONFIG_SOFTMMU) # if TARGET_LONG_BITS == 64 tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1); # 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, 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); - - addr_reg1 = TCG_REG_V0; +#else + 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 switch(opc) { 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; 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; case 1: 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); } 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; case 1 | 4: 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); } 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; case 2: 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); } 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; 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) { - 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_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); } else { - tcg_out_opc_imm(s, OPC_LW, data_reg1, addr_reg1, 0); - tcg_out_opc_imm(s, OPC_LW, data_reg2, addr_reg1, 4); + tcg_out_opc_imm(s, OPC_LW, data_reg1, TCG_REG_V0, 0); + tcg_out_opc_imm(s, OPC_LW, data_reg2, TCG_REG_V0, 4); } break; 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, 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); +#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 switch(opc) { 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; case 1: if (TCG_NEED_BSWAP) { 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 { - 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; case 2: if (TCG_NEED_BSWAP) { 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 { - 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; case 3: if (TCG_NEED_BSWAP) { 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_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 { - tcg_out_opc_imm(s, OPC_SW, data_reg1, addr_reg1, 0); - tcg_out_opc_imm(s, OPC_SW, data_reg2, addr_reg1, 4); + tcg_out_opc_imm(s, OPC_SW, data_reg1, TCG_REG_A0, 0); + tcg_out_opc_imm(s, OPC_SW, data_reg2, TCG_REG_A0, 4); } break; default: diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h index 5f8b00a9b85dc7cdf5676e6aee598b72ca129bd2..172577a71e9c6064e7ed674200a6f84c5e14bbe9 100644 --- a/tcg/mips/tcg-target.h +++ b/tcg/mips/tcg-target.h @@ -99,6 +99,9 @@ enum { /* Note: must be synced with dyngen-exec.h */ #define TCG_AREG0 TCG_REG_FP +/* guest base is supported */ +#define TCG_TARGET_HAS_GUEST_BASE + #include static inline void flush_icache_range(unsigned long start, unsigned long stop)