Merge changes I5d034506,I05390f79
* changes:
[MIPS64] target-mips : implement unaligned loads using TCG
[MIPS] Refactor page table walk
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7ecfa23..339f100 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -234,6 +234,11 @@
#define CP0VPEOpt_DWX0 0
target_ulong CP0_EntryLo0;
target_ulong CP0_EntryLo1;
+#define CP0ENTRYLO_PFN 6
+#define CP0ENTRYLO_C 3
+#define CP0ENTRYLO_D 2
+#define CP0ENTRYLO_V 1
+#define CP0ENTRYLO_G 0
target_ulong CP0_Context;
int32_t CP0_PageMask;
int32_t CP0_PageGrain;
diff --git a/target-mips/helper.c b/target-mips/helper.c
index b9ad090..b078991 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -268,6 +268,28 @@
int softshift;
} linux_pte_info = {0};
+static inline void pagetable_walk(CPUMIPSState *env,
+ target_ulong pgd_addr, target_ulong vaddr,
+ target_ulong *entrylo0, target_ulong *entrylo1)
+{
+ target_ulong ptw_phys, pt_addr, index;
+
+ /* 32bit PTE lookup */
+ ptw_phys = pgd_addr & 0x1fffffffUL; /* Assume pgd is in KSEG0/KSEG1 */
+ index = (vaddr >> 22) << 2; /* Use bits 31..22 to index pgd */
+ ptw_phys += index;
+
+ pt_addr = ldl_phys(ptw_phys);
+
+ ptw_phys = pt_addr & 0x1fffffffUL; /* Assume pgt is in KSEG0/KSEG1 */
+ index = ((vaddr >> 13) & 0x1ff) << 3; /* Use bits 21..13 to index pgt */
+ ptw_phys += index;
+
+ /* Get the entrylo values from pgt */
+ *entrylo0 = ldl_phys(ptw_phys) >> linux_pte_info.softshift;
+ *entrylo1 = ldl_phys(ptw_phys+4) >> linux_pte_info.softshift;
+}
+
static inline target_ulong cpu_mips_get_pgd(CPUMIPSState *env)
{
if (unlikely(linux_pte_info.pgd_current_p == 0)) {
@@ -342,17 +364,21 @@
// in target-mips/op_helper.c
extern void r4k_helper_ptw_tlbrefill(CPUMIPSState*);
-static inline int cpu_mips_tlb_refill(CPUMIPSState *env, target_ulong address, int rw ,
+static inline int cpu_mips_tlb_refill(CPUMIPSState *env, target_ulong address, int rw,
int mmu_idx, int is_softmmu)
{
int32_t saved_hflags;
target_ulong saved_badvaddr,saved_entryhi,saved_context;
-
- target_ulong pgd_addr,pt_addr,index;
- target_ulong fault_addr, ptw_phys;
- target_ulong elo_even,elo_odd;
+ target_ulong pgd_addr;
+ target_ulong fault_addr;
+ target_ulong entrylo0, entrylo1;
int ret;
+ pgd_addr = cpu_mips_get_pgd(env);
+ // if pgd_addr is unknown return TLBRET_NOMATCH to allow software handler to run
+ if (unlikely(pgd_addr == 0))
+ return TLBRET_NOMATCH;
+
saved_badvaddr = env->CP0_BadVAddr;
saved_context = env->CP0_Context;
saved_entryhi = env->CP0_EntryHi;
@@ -368,55 +394,33 @@
fault_addr = env->CP0_BadVAddr;
- pgd_addr = cpu_mips_get_pgd(env);
- if (unlikely(!pgd_addr))
- {
- /*not valid pgd_addr,just return.*/
- //return TLBRET_NOMATCH;
- ret = TLBRET_NOMATCH;
- goto out;
- }
+ pagetable_walk(env, pgd_addr, fault_addr, &entrylo0, &entrylo1);
- ptw_phys = pgd_addr - (int32_t)0x80000000UL;
- index = (fault_addr>>22)<<2;
- ptw_phys += index;
-
- pt_addr = ldl_phys(ptw_phys);
-
- ptw_phys = pt_addr - (int32_t)0x80000000UL;
- index = (env->CP0_Context>>1)&0xff8;
- ptw_phys += index;
-
- /* get the page table entry*/
- elo_even = ldl_phys(ptw_phys);
- elo_odd = ldl_phys(ptw_phys+4);
- elo_even = elo_even >> linux_pte_info.softshift;
- elo_odd = elo_odd >> linux_pte_info.softshift;
- env->CP0_EntryLo0 = elo_even;
- env->CP0_EntryLo1 = elo_odd;
- /* Done. refill the TLB */
+ /* Refill the TLB */
+ env->CP0_EntryLo0 = entrylo0;
+ env->CP0_EntryLo1 = entrylo1;
r4k_helper_ptw_tlbrefill(env);
- /* Since we know the value of TLB entry, we can
+ /* Since we know the TLB contents, we can
* return the TLB lookup value here.
*/
env->hflags = saved_hflags;
target_ulong mask = env->CP0_PageMask | ~(TARGET_PAGE_MASK << 1);
- int n = !!(address & mask & ~(mask >> 1));
- /* Check access rights */
- if (!(n ? (elo_odd & 2) != 0 : (elo_even & 2) != 0))
- {
+ target_ulong lo = (address & mask & ~(mask >> 1)) ? entrylo1 : entrylo0;
+ /* Is the TLB entry valid? */
+ if ((lo & (1 << CP0ENTRYLO_V)) == 0) {
ret = TLBRET_INVALID;
goto out;
}
- if (rw == 0 || (n ? (elo_odd & 4) != 0 : (elo_even & 4) != 0)) {
- target_ulong physical = (n?(elo_odd >> 6) << 12 : (elo_even >> 6) << 12);
- physical |= (address & (mask >> 1));
+ /* Is this a read access or a write to a modifiable page? */
+ if (rw == 0 || (lo & (1 << CP0ENTRYLO_D))) {
+ target_ulong physical = (lo >> CP0ENTRYLO_PFN) << 12;
+ physical |= address & (mask >> 1);
int prot = PAGE_READ;
- if (n ? (elo_odd & 4) != 0 : (elo_even & 4) != 0)
+ if (lo & (1 << CP0ENTRYLO_D))
prot |= PAGE_WRITE;
tlb_set_page(env, address & TARGET_PAGE_MASK,
@@ -516,33 +520,16 @@
ret = get_physical_address(env, &phys_addr, &prot, addr, 0, ACCESS_INT);
if (ret != TLBRET_MATCH && ret != TLBRET_DIRTY) {
- target_ulong pgd_addr = cpu_mips_get_pgd(env);
- if (unlikely(!pgd_addr)) {
- phys_addr = -1;
- }
- else {
- target_ulong pgd_phys, pgd_index;
- target_ulong pt_addr, pt_phys, pt_index;
- target_ulong lo;
- /* Mimic the steps taken for a TLB refill */
- pgd_phys = pgd_addr - (int32_t)0x80000000UL;
- pgd_index = (addr >> 22) << 2;
- pt_addr = ldl_phys(pgd_phys + pgd_index);
- pt_phys = pt_addr - (int32_t)0x80000000UL;
- pt_index = (((addr >> 9) & 0x007ffff0) >> 1) & 0xff8;
- /* get the entrylo value */
- if (addr & 0x1000)
- lo = ldl_phys(pt_phys + pt_index + 4);
- else
- lo = ldl_phys(pt_phys + pt_index);
- /* convert software TLB entry to hardware value */
- lo >>= linux_pte_info.softshift;
- if (lo & 0x00000002)
- /* It is valid */
- phys_addr = (lo >> 6) << 12;
- else
- phys_addr = -1;
- }
+ target_ulong pgd_addr = cpu_mips_get_pgd(env);
+ phys_addr = -1;
+ if (likely(pgd_addr)) {
+ target_ulong entrylo0, entrylo1;
+ pagetable_walk(env, pgd_addr, addr, &entrylo0, &entrylo1);
+ target_ulong mask = env->CP0_PageMask | ~(TARGET_PAGE_MASK << 1);
+ target_ulong lo = (addr & mask & ~(mask >> 1)) ? entrylo1 : entrylo0;
+ if (lo & (1 << CP0ENTRYLO_V))
+ phys_addr = (lo >> CP0ENTRYLO_PFN) << 12;
+ }
}
return phys_addr;
#endif
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 3e6557a..31a77ac 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -5,13 +5,9 @@
DEF_HELPER_1(interrupt_restart, void, env)
#ifdef TARGET_MIPS64
-DEF_HELPER_4(ldl, tl, env, tl, tl, int)
-DEF_HELPER_4(ldr, tl, env, tl, tl, int)
DEF_HELPER_4(sdl, void, env, tl, tl, int)
DEF_HELPER_4(sdr, void, env, tl, tl, int)
#endif
-DEF_HELPER_4(lwl, tl, env, tl, tl, int)
-DEF_HELPER_4(lwr, tl, env, tl, tl, int)
DEF_HELPER_4(swl, void, env, tl, tl, int)
DEF_HELPER_4(swr, void, env, tl, tl, int)
@@ -29,8 +25,8 @@
#ifdef TARGET_MIPS64
DEF_HELPER_FLAGS_1(dclo, TCG_CALL_NO_RWG_SE, tl, tl)
DEF_HELPER_FLAGS_1(dclz, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_2(dmult, void, tl, tl)
-DEF_HELPER_2(dmultu, void, tl, tl)
+DEF_HELPER_3(dmult, void, env, tl, tl)
+DEF_HELPER_3(dmultu, void, env, tl, tl)
#endif
DEF_HELPER_3(muls, tl, env, tl, tl)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 9f8adfd..66c2cab 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -415,56 +415,6 @@
#define GET_OFFSET(addr, offset) (addr - (offset))
#endif
-target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
- int mem_idx)
-{
- target_ulong tmp;
-
- tmp = do_lbu(env, arg2, mem_idx);
- arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
-
- if (GET_LMASK(arg2) <= 2) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);
- arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
- }
-
- if (GET_LMASK(arg2) <= 1) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);
- arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
- }
-
- if (GET_LMASK(arg2) == 0) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);
- arg1 = (arg1 & 0xFFFFFF00) | tmp;
- }
- return (int32_t)arg1;
-}
-
-target_ulong helper_lwr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
- int mem_idx)
-{
- target_ulong tmp;
-
- tmp = do_lbu(env, arg2, mem_idx);
- arg1 = (arg1 & 0xFFFFFF00) | tmp;
-
- if (GET_LMASK(arg2) >= 1) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);
- arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
- }
-
- if (GET_LMASK(arg2) >= 2) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);
- arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
- }
-
- if (GET_LMASK(arg2) == 3) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);
- arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
- }
- return (int32_t)arg1;
-}
-
void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
int mem_idx)
{
@@ -505,98 +455,6 @@
#define GET_LMASK64(v) (((v) & 7) ^ 7)
#endif
-target_ulong helper_ldl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
- int mem_idx)
-{
- uint64_t tmp;
-
- tmp = do_lbu(env, arg2, mem_idx);
- arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
-
- if (GET_LMASK64(arg2) <= 6) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);
- arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
- }
-
- if (GET_LMASK64(arg2) <= 5) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);
- arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
- }
-
- if (GET_LMASK64(arg2) <= 4) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);
- arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
- }
-
- if (GET_LMASK64(arg2) <= 3) {
- tmp = do_lbu(GET_OFFSET(arg2, 4), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
- }
-
- if (GET_LMASK64(arg2) <= 2) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 5), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
- }
-
- if (GET_LMASK64(arg2) <= 1) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 6), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
- }
-
- if (GET_LMASK64(arg2) == 0) {
- tmp = do_lbu(env, GET_OFFSET(arg2, 7), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
- }
-
- return arg1;
-}
-
-target_ulong helper_ldr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
- int mem_idx)
-{
- uint64_t tmp;
-
- tmp = do_lbu(env, arg2, mem_idx);
- arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
-
- if (GET_LMASK64(arg2) >= 1) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
- }
-
- if (GET_LMASK64(arg2) >= 2) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
- }
-
- if (GET_LMASK64(arg2) >= 3) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);
- arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
- }
-
- if (GET_LMASK64(arg2) >= 4) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -4), mem_idx);
- arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
- }
-
- if (GET_LMASK64(arg2) >= 5) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -5), mem_idx);
- arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
- }
-
- if (GET_LMASK64(arg2) >= 6) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -6), mem_idx);
- arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
- }
-
- if (GET_LMASK64(arg2) == 7) {
- tmp = do_lbu(env, GET_OFFSET(arg2, -7), mem_idx);
- arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
- }
-
- return arg1;
-}
-
void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
int mem_idx)
{
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 683c936..798517b 100755
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -988,8 +988,10 @@
int base, int16_t offset)
{
const char * __attribute__((unused)) opn = "ldst";
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
+ TCGv t0, t1, t2;
+
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
if (base == 0) {
tcg_gen_movi_tl(t0, offset);
@@ -1028,10 +1030,22 @@
opn = "sd";
break;
case OPC_LDL:
- save_cpu_state(ctx, 1);
+ tcg_gen_andi_tl(t1, t0, 7);
+#ifndef TARGET_WORDS_BIGENDIAN
+ tcg_gen_xori_tl(t1, t1, 7);
+#endif
+ tcg_gen_shli_tl(t1, t1, 3);
+ tcg_gen_andi_tl(t0, t0, ~7);
+ tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
+ tcg_gen_shl_tl(t0, t0, t1);
+ tcg_gen_xori_tl(t1, t1, 63);
+ t2 = tcg_const_tl(0x7fffffffffffffffull);
+ tcg_gen_shr_tl(t2, t2, t1);
gen_load_gpr(t1, rt);
- gen_helper_4i(ldl, t1, cpu_env, t1, t0, ctx->mem_idx);
- gen_store_gpr(t1, rt);
+ tcg_gen_and_tl(t1, t1, t2);
+ tcg_temp_free(t2);
+ tcg_gen_or_tl(t0, t0, t1);
+ gen_store_gpr(t0, rt);
opn = "ldl";
break;
case OPC_SDL:
@@ -1041,10 +1055,22 @@
opn = "sdl";
break;
case OPC_LDR:
- save_cpu_state(ctx, 1);
+ tcg_gen_andi_tl(t1, t0, 7);
+#ifdef TARGET_WORDS_BIGENDIAN
+ tcg_gen_xori_tl(t1, t1, 7);
+#endif
+ tcg_gen_shli_tl(t1, t1, 3);
+ tcg_gen_andi_tl(t0, t0, ~7);
+ tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
+ tcg_gen_shr_tl(t0, t0, t1);
+ tcg_gen_xori_tl(t1, t1, 63);
+ t2 = tcg_const_tl(0xfffffffffffffffeull);
+ tcg_gen_shl_tl(t2, t2, t1);
gen_load_gpr(t1, rt);
- gen_helper_4i(ldr, t1, cpu_env, t1, t0, ctx->mem_idx);
- gen_store_gpr(t1, rt);
+ tcg_gen_and_tl(t1, t1, t2);
+ tcg_temp_free(t2);
+ tcg_gen_or_tl(t0, t0, t1);
+ gen_store_gpr(t0, rt);
opn = "ldr";
break;
case OPC_SDR:
@@ -1103,10 +1129,23 @@
opn = "lbu";
break;
case OPC_LWL:
- save_cpu_state(ctx, 1);
+ tcg_gen_andi_tl(t1, t0, 3);
+#ifndef TARGET_WORDS_BIGENDIAN
+ tcg_gen_xori_tl(t1, t1, 3);
+#endif
+ tcg_gen_shli_tl(t1, t1, 3);
+ tcg_gen_andi_tl(t0, t0, ~3);
+ tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
+ tcg_gen_shl_tl(t0, t0, t1);
+ tcg_gen_xori_tl(t1, t1, 31);
+ t2 = tcg_const_tl(0x7fffffffull);
+ tcg_gen_shr_tl(t2, t2, t1);
gen_load_gpr(t1, rt);
- gen_helper_4i(lwl, t1, cpu_env, t1, t0, ctx->mem_idx);
- gen_store_gpr(t1, rt);
+ tcg_gen_and_tl(t1, t1, t2);
+ tcg_temp_free(t2);
+ tcg_gen_or_tl(t0, t0, t1);
+ tcg_gen_ext32s_tl(t0, t0);
+ gen_store_gpr(t0, rt);
opn = "lwl";
break;
case OPC_SWL:
@@ -1116,10 +1155,22 @@
opn = "swl";
break;
case OPC_LWR:
- save_cpu_state(ctx, 1);
+ tcg_gen_andi_tl(t1, t0, 3);
+#ifdef TARGET_WORDS_BIGENDIAN
+ tcg_gen_xori_tl(t1, t1, 3);
+#endif
+ tcg_gen_shli_tl(t1, t1, 3);
+ tcg_gen_andi_tl(t0, t0, ~3);
+ tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
+ tcg_gen_shr_tl(t0, t0, t1);
+ tcg_gen_xori_tl(t1, t1, 31);
+ t2 = tcg_const_tl(0xfffffffeull);
+ tcg_gen_shl_tl(t2, t2, t1);
gen_load_gpr(t1, rt);
- gen_helper_4i(lwr, t1, cpu_env, t1, t0, ctx->mem_idx);
- gen_store_gpr(t1, rt);
+ tcg_gen_and_tl(t1, t1, t2);
+ tcg_temp_free(t2);
+ tcg_gen_or_tl(t0, t0, t1);
+ gen_store_gpr(t0, rt);
opn = "lwr";
break;
case OPC_SWR:
@@ -2138,11 +2189,11 @@
opn = "ddivu";
break;
case OPC_DMULT:
- gen_helper_dmult(t0, t1);
+ gen_helper_dmult(cpu_env, t0, t1);
opn = "dmult";
break;
case OPC_DMULTU:
- gen_helper_dmultu(t0, t1);
+ gen_helper_dmultu(cpu_env, t0, t1);
opn = "dmultu";
break;
#endif
@@ -4091,17 +4142,17 @@
break;
case 1:
check_insn(env, ctx, ASE_MT);
- gen_helper_mfc0_mvpcontrol(arg);
+ gen_helper_mfc0_mvpcontrol(arg, cpu_env);
rn = "MVPControl";
break;
case 2:
check_insn(env, ctx, ASE_MT);
- gen_helper_mfc0_mvpconf0(arg);
+ gen_helper_mfc0_mvpconf0(arg, cpu_env);
rn = "MVPConf0";
break;
case 3:
check_insn(env, ctx, ASE_MT);
- gen_helper_mfc0_mvpconf1(arg);
+ gen_helper_mfc0_mvpconf1(arg, cpu_env);
rn = "MVPConf1";
break;
default:
@@ -4111,7 +4162,7 @@
case 1:
switch (sel) {
case 0:
- gen_helper_mfc0_random(arg);
+ gen_helper_mfc0_random(arg, cpu_env);
rn = "Random";
break;
case 1:
@@ -4161,12 +4212,12 @@
break;
case 1:
check_insn(env, ctx, ASE_MT);
- gen_helper_mfc0_tcstatus(arg);
+ gen_helper_mfc0_tcstatus(arg, cpu_env);
rn = "TCStatus";
break;
case 2:
check_insn(env, ctx, ASE_MT);
- gen_helper_mfc0_tcbind(arg);
+ gen_helper_mfc0_tcbind(arg, cpu_env);
rn = "TCBind";
break;
case 3:
@@ -4299,7 +4350,7 @@
/* Mark as an IO operation because we read the time. */
if (use_icount)
gen_io_start();
- gen_helper_mfc0_count(arg);
+ gen_helper_mfc0_count(arg, cpu_env);
if (use_icount) {
gen_io_end();
ctx->bstate = BS_STOP;
@@ -4436,7 +4487,7 @@
case 18:
switch (sel) {
case 0 ... 7:
- gen_helper_1i(dmfc0_watchlo, arg, sel);
+ gen_helper_2i(dmfc0_watchlo, arg, cpu_env, sel);
rn = "WatchLo";
break;
default:
@@ -4446,7 +4497,7 @@
case 19:
switch (sel) {
case 0 ... 7:
- gen_helper_1i(mfc0_watchhi, arg, sel);
+ gen_helper_2i(mfc0_watchhi, arg, cpu_env, sel);
rn = "WatchHi";
break;
default: