X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=target-ppc%2Fop.c;h=f439a81dfbde14772ce69d53dca6e37bbc4ddbd8;hb=6d463de2b3e261e95f224767605eef02acbd2701;hp=28722d6507a5c468856ccd346e0646bea263e552;hpb=9a64fbe4d89751524be0954f87dd514083295e99;p=qemu diff --git a/target-ppc/op.c b/target-ppc/op.c index 28722d6..f439a81 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -18,11 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +//#define DEBUG_OP + #include "config.h" #include "exec.h" -//#define DEBUG_OP - #define regs (env) #define Ts0 (int32_t)T0 #define Ts1 (int32_t)T1 @@ -208,22 +208,29 @@ PPC_OP(set_T2) } /* Generate exceptions */ -PPC_OP(queue_exception_err) +PPC_OP(raise_exception_err) { - do_queue_exception_err(PARAM(1), PARAM(2)); + do_raise_exception_err(PARAM(1), PARAM(2)); } -PPC_OP(queue_exception) +PPC_OP(raise_exception) { - do_queue_exception(PARAM(1)); + do_raise_exception(PARAM(1)); } -PPC_OP(process_exceptions) +PPC_OP(update_nip) { - if (env->exceptions != 0) { - env->nip = PARAM(1); - do_check_exception_state(); - } + env->nip = PARAM(1); +} + +PPC_OP(debug) +{ + env->nip = PARAM(1); +#if defined (DEBUG_OP) + dump_state(); +#endif + do_raise_exception(EXCP_DEBUG); + RETURN(); } /* Segment registers load and store with immediate index */ @@ -235,10 +242,7 @@ PPC_OP(load_srin) PPC_OP(store_srin) { -#if defined (DEBUG_OP) - dump_store_sr(T1 >> 28); -#endif - regs->sr[T1 >> 28] = T0; + do_store_sr(T1 >> 28); RETURN(); } @@ -353,58 +357,38 @@ PPC_OP(store_ctr) RETURN(); } -/* Update time base */ -PPC_OP(update_tb) +PPC_OP(load_tbl) { - T0 = regs->tb[0]; - T1 = T0; - T0 += PARAM(1); -#if defined (DEBUG_OP) - dump_update_tb(PARAM(1)); -#endif - if (T0 < T1) { - T1 = regs->tb[1] + 1; - regs->tb[1] = T1; - } - regs->tb[0] = T0; + T0 = cpu_ppc_load_tbl(regs); RETURN(); } -PPC_OP(load_tb) +PPC_OP(load_tbu) { - T0 = regs->tb[PARAM(1)]; + T0 = cpu_ppc_load_tbu(regs); RETURN(); } -PPC_OP(store_tb) +PPC_OP(store_tbl) { - regs->tb[PARAM(1)] = T0; -#if defined (DEBUG_OP) - dump_store_tb(PARAM(1)); -#endif + cpu_ppc_store_tbl(regs, T0); RETURN(); } -/* Update decrementer */ -PPC_OP(update_decr) +PPC_OP(store_tbu) { - T0 = regs->decr; - T1 = T0; - T0 -= PARAM(1); - regs->decr = T0; - if (PARAM(1) > T1) { - do_queue_exception(EXCP_DECR); - } + cpu_ppc_store_tbu(regs, T0); RETURN(); } -PPC_OP(store_decr) +PPC_OP(load_decr) { - T1 = regs->decr; - regs->decr = T0; - if (Ts0 < 0 && Ts1 > 0) { - do_queue_exception(EXCP_DECR); + T0 = cpu_ppc_load_decr(regs); } + +PPC_OP(store_decr) +{ + cpu_ppc_store_decr(regs, T0); RETURN(); } @@ -415,10 +399,7 @@ PPC_OP(load_ibat) PPC_OP(store_ibat) { -#if defined (DEBUG_OP) - dump_store_ibat(PARAM(1), PARAM(2)); -#endif - regs->IBAT[PARAM(1)][PARAM(2)] = T0; + do_store_ibat(PARAM(1), PARAM(2)); } PPC_OP(load_dbat) @@ -428,10 +409,7 @@ PPC_OP(load_dbat) PPC_OP(store_dbat) { -#if defined (DEBUG_OP) - dump_store_dbat(PARAM(1), PARAM(2)); -#endif - regs->DBAT[PARAM(1)][PARAM(2)] = T0; + do_store_dbat(PARAM(1), PARAM(2)); } /* FPSCR */ @@ -453,13 +431,6 @@ PPC_OP(reset_scrfx) RETURN(); } -/* Set reservation */ -PPC_OP(set_reservation) -{ - regs->reserve = T0 & ~0x03; - RETURN(); -} - /* crf operations */ PPC_OP(getbit_T0) { @@ -480,121 +451,94 @@ PPC_OP(setcrfbit) } /* Branch */ -#if 0 #define EIP regs->nip -#define TB_DO_JUMP(name, tb, n, target) JUMP_TB(name, tb, n, target) -#else -#define TB_DO_JUMP(name, tb, n, target) regs->nip = target; -#endif -#define __PPC_OP_B(name, target) \ -PPC_OP(name) \ -{ \ - TB_DO_JUMP(glue(op_, name), T1, 0, (target)); \ - RETURN(); \ -} - -#define __PPC_OP_BL(name, target, link) \ -PPC_OP(name) \ -{ \ - regs->lr = (link); \ - TB_DO_JUMP(glue(op_, name), T1, 0, (target)); \ - RETURN(); \ -} - -#define PPC_OP_B(name, target, link) \ -__PPC_OP_B(name, target); \ -__PPC_OP_BL(glue(name, l), target, link) - -#define __PPC_OP_BC(name, cond, target) \ -PPC_OP(name) \ -{ \ - if (cond) { \ - TB_DO_JUMP(glue(op_, name), T1, 1, (target)); \ - } else { \ - TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \ - } \ - RETURN(); \ -} - -#define __PPC_OP_BCL(name, cond, target) \ -PPC_OP(name) \ -{ \ - regs->lr = PARAM(1); \ - if (cond) { \ - TB_DO_JUMP(glue(op_, name), T1, 1, (target)); \ - } else { \ - TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \ - } \ - RETURN(); \ -} - -#define __PPC_OP_BCLRL(name, cond, target) \ -PPC_OP(name) \ -{ \ - T2 = (target); \ - regs->lr = PARAM(1); \ - if (cond) { \ - TB_DO_JUMP(glue(op_, name), T1, 1, T2); \ - } else { \ - TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \ - } \ - RETURN(); \ -} - -#define _PPC_OP_BC(name, namel, cond, target) \ -__PPC_OP_BC(name, cond, target); \ -__PPC_OP_BCL(namel, cond, target) - -/* Branch to target */ -#define PPC_OP_BC(name, cond) \ -_PPC_OP_BC(b_##name, bl_##name, cond, PARAM(2)) - -PPC_OP_B(b, PARAM(1), PARAM(2)); -PPC_OP_BC(ctr, (regs->ctr != 0)); -PPC_OP_BC(ctr_true, (regs->ctr != 0 && (T0 & PARAM(3)) != 0)); -PPC_OP_BC(ctr_false, (regs->ctr != 0 && (T0 & PARAM(3)) == 0)); -PPC_OP_BC(ctrz, (regs->ctr == 0)); -PPC_OP_BC(ctrz_true, (regs->ctr == 0 && (T0 & PARAM(3)) != 0)); -PPC_OP_BC(ctrz_false, (regs->ctr == 0 && (T0 & PARAM(3)) == 0)); -PPC_OP_BC(true, ((T0 & PARAM(3)) != 0)); -PPC_OP_BC(false, ((T0 & PARAM(3)) == 0)); - -/* Branch to CTR */ -#define PPC_OP_BCCTR(name, cond) \ -_PPC_OP_BC(bctr_##name, bctrl_##name, cond, regs->ctr & ~0x03) - -PPC_OP_B(bctr, regs->ctr & ~0x03, PARAM(1)); -PPC_OP_BCCTR(ctr, (regs->ctr != 0)); -PPC_OP_BCCTR(ctr_true, (regs->ctr != 0 && (T0 & PARAM(2)) != 0)); -PPC_OP_BCCTR(ctr_false, (regs->ctr != 0 && (T0 & PARAM(2)) == 0)); -PPC_OP_BCCTR(ctrz, (regs->ctr == 0)); -PPC_OP_BCCTR(ctrz_true, (regs->ctr == 0 && (T0 & PARAM(2)) != 0)); -PPC_OP_BCCTR(ctrz_false, (regs->ctr == 0 && (T0 & PARAM(2)) == 0)); -PPC_OP_BCCTR(true, ((T0 & PARAM(2)) != 0)); -PPC_OP_BCCTR(false, ((T0 & PARAM(2)) == 0)); - -/* Branch to LR */ -#define PPC_OP_BCLR(name, cond) \ -__PPC_OP_BC(blr_##name, cond, regs->lr & ~0x03); \ -__PPC_OP_BCLRL(blrl_##name, cond, regs->lr & ~0x03) - -__PPC_OP_B(blr, regs->lr & ~0x03); -PPC_OP(blrl) -{ - T0 = regs->lr & ~0x03; - regs->lr = PARAM(1); - TB_DO_JUMP(op_blrl, T1, 0, T0); - RETURN(); -} -PPC_OP_BCLR(ctr, (regs->ctr != 0)); -PPC_OP_BCLR(ctr_true, (regs->ctr != 0 && (T0 & PARAM(2)) != 0)); -PPC_OP_BCLR(ctr_false, (regs->ctr != 0 && (T0 & PARAM(2)) == 0)); -PPC_OP_BCLR(ctrz, (regs->ctr == 0)); -PPC_OP_BCLR(ctrz_true, (regs->ctr == 0 && (T0 & PARAM(2)) != 0)); -PPC_OP_BCLR(ctrz_false, (regs->ctr == 0 && (T0 & PARAM(2)) == 0)); -PPC_OP_BCLR(true, ((T0 & PARAM(2)) != 0)); -PPC_OP_BCLR(false, ((T0 & PARAM(2)) == 0)); +PPC_OP(setlr) +{ + regs->lr = PARAM1; +} + +PPC_OP(b) +{ + JUMP_TB(b1, PARAM1, 0, PARAM2); +} + +PPC_OP(b_T1) +{ + regs->nip = T1; +} + +PPC_OP(btest) +{ + if (T0) { + JUMP_TB(btest, PARAM1, 0, PARAM2); + } else { + JUMP_TB(btest, PARAM1, 1, PARAM3); + } + RETURN(); +} + +PPC_OP(btest_T1) +{ + if (T0) { + regs->nip = T1 & ~3; + } else { + regs->nip = PARAM1; + } + RETURN(); +} + +PPC_OP(movl_T1_ctr) +{ + T1 = regs->ctr; +} + +PPC_OP(movl_T1_lr) +{ + T1 = regs->lr; +} + +/* tests with result in T0 */ + +PPC_OP(test_ctr) +{ + T0 = regs->ctr; +} + +PPC_OP(test_ctr_true) +{ + T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0); +} + +PPC_OP(test_ctr_false) +{ + T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0); +} + +PPC_OP(test_ctrz) +{ + T0 = (regs->ctr == 0); +} + +PPC_OP(test_ctrz_true) +{ + T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0); +} + +PPC_OP(test_ctrz_false) +{ + T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0); +} + +PPC_OP(test_true) +{ + T0 = (T0 & PARAM(1)); +} + +PPC_OP(test_false) +{ + T0 = ((T0 & PARAM(1)) == 0); +} /* CTR maintenance */ PPC_OP(dec_ctr) @@ -1391,28 +1335,28 @@ PPC_OP(fmsubs) /* fnmadd - fnmadd. - fnmadds - fnmadds. */ PPC_OP(fnmadd) { - FT0 = -((FT0 * FT1) + FT2); + do_fnmadd(); RETURN(); } /* fnmadds - fnmadds. */ PPC_OP(fnmadds) { - FTS0 = -((FTS0 * FTS1) + FTS2); + do_fnmadds(); RETURN(); } /* fnmsub - fnmsub. */ PPC_OP(fnmsub) { - FT0 = -((FT0 * FT1) - FT2); + do_fnmsub(); RETURN(); } /* fnmsubs - fnmsubs. */ PPC_OP(fnmsubs) { - FTS0 = -((FTS0 * FTS1) - FTS2); + do_fnmsubs(); RETURN(); } @@ -1477,10 +1421,9 @@ PPC_OP(fneg) } /* Load and store */ -#if defined(CONFIG_USER_ONLY) #define MEMSUFFIX _raw #include "op_mem.h" -#else +#if !defined(CONFIG_USER_ONLY) #define MEMSUFFIX _user #include "op_mem.h" @@ -1488,17 +1431,28 @@ PPC_OP(fneg) #include "op_mem.h" #endif +/* Special op to check and maybe clear reservation */ +PPC_OP(check_reservation) +{ + do_check_reservation(); + RETURN(); +} + /* Return from interrupt */ PPC_OP(rfi) { + regs->nip = regs->spr[SRR0] & ~0x00000003; +#if 1 // TRY + T0 = regs->spr[SRR1] & ~0xFFF00000; +#else T0 = regs->spr[SRR1] & ~0xFFFF0000; +#endif do_store_msr(); - do_tlbia(); +#if defined (DEBUG_OP) dump_rfi(); - regs->nip = regs->spr[SRR0] & ~0x00000003; - if (env->exceptions != 0) { - do_check_exception_state(); - } +#endif + // do_tlbia(); + do_raise_exception(EXCP_RFI); RETURN(); } @@ -1510,7 +1464,7 @@ PPC_OP(tw) (Ts0 == Ts1 && (PARAM(1) & 0x04)) || (T0 < T1 && (PARAM(1) & 0x02)) || (T0 > T1 && (PARAM(1) & 0x01))) - do_queue_exception_err(EXCP_PROGRAM, EXCP_TRAP); + do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); RETURN(); } @@ -1521,7 +1475,7 @@ PPC_OP(twi) (Ts0 == SPARAM(1) && (PARAM(2) & 0x04)) || (T0 < (uint32_t)SPARAM(1) && (PARAM(2) & 0x02)) || (T0 > (uint32_t)SPARAM(1) && (PARAM(2) & 0x01))) - do_queue_exception_err(EXCP_PROGRAM, EXCP_TRAP); + do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); RETURN(); }