diff --git a/mips/mips_codegen.h b/mips/mips_codegen.h index 7fec123..6dd0392 100644 --- a/mips/mips_codegen.h +++ b/mips/mips_codegen.h @@ -152,6 +152,21 @@ typedef enum mips_opcode_cache = 0x2F, } mips_opcode; +#ifdef NINTENDO64 + +// nintendo 64 has a 1-cycle delay when branching, which causes the instruction +// after the branch to get executed -- so we should make that a nop. +// also, we need two nop's after mult's for the "VR4300 multiplication bug", +// aka mips64-gcc -mfix4300 + +#define mips_emit_nop_only_on_nintendo64() mips_emit_nop() + +#else + +#define mips_emit_nop_only_on_nintendo64() + +#endif + #define mips_emit_cache(operation, rs, immediate) \ *((u32 *)translation_ptr) = (mips_opcode_cache << 26) | \ (rs << 21) | (operation << 16) | (immediate & 0xFFFF); \ @@ -267,27 +282,15 @@ typedef enum #define mips_emit_mtlo(rs) \ mips_emit_special(mtlo, rs, 0, 0, 0) \ -#ifdef NINTENDO64 - -// "VR4300 multiplication bug", aka mips64-gcc -mfix4300 - #define mips_emit_mult(rs, rt) \ - mips_emit_special(mult, rs, rt, 0, 0) \ - ;mips_emit_nop(); mips_emit_nop() + mips_emit_special(mult, rs, rt, 0, 0); \ + mips_emit_nop_only_on_nintendo64(); \ + mips_emit_nop_only_on_nintendo64() #define mips_emit_multu(rs, rt) \ - mips_emit_special(multu, rs, rt, 0, 0) \ - ;mips_emit_nop(); mips_emit_nop() - -#else - -#define mips_emit_mult(rs, rt) \ - mips_emit_special(mult, rs, rt, 0, 0) \ - -#define mips_emit_multu(rs, rt) \ - mips_emit_special(multu, rs, rt, 0, 0) \ - -#endif + mips_emit_special(multu, rs, rt, 0, 0); \ + mips_emit_nop_only_on_nintendo64(); \ + mips_emit_nop_only_on_nintendo64() #define mips_emit_div(rs, rt) \ mips_emit_special(div, rs, rt, 0, 0) \ diff --git a/mips/mips_emit.h b/mips/mips_emit.h index 647aa51..27fa705 100644 --- a/mips/mips_emit.h +++ b/mips/mips_emit.h @@ -2040,6 +2040,7 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 address) 400258: 00441025 or v0,v0,a0 */ #define emit_eswap32(r) \ + mips_emit_nop(); \ mips_emit_sll(reg_temp, r, 24); \ mips_emit_srl(mips_reg_k0, r, 24); \ mips_emit_srl(mips_reg_k1, r, 8); \ @@ -2063,6 +2064,7 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 address) 400230: 3042ffff andi v0,v0,0xffff */ #define emit_eswap16(r, sext) \ + mips_emit_nop(); \ mips_emit_sll(reg_temp, r, 8); \ mips_emit_srl(r, r, 8); \ mips_emit_or(r, reg_temp, r); \