* 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
}
/* 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)
{
env->nip = PARAM(1);
- if (env->exceptions != 0) {
- do_check_exception_state();
- }
+}
+
+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 */
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();
}
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();
}
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)
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 */
}
/* 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)
/* 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();
}
}
/* 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"
#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();
}
(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();
}
(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();
}