aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/op.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-ppc/op.c')
-rw-r--r--target-ppc/op.c653
1 files changed, 391 insertions, 262 deletions
diff --git a/target-ppc/op.c b/target-ppc/op.c
index cf77d5ee28..28722d6507 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -21,6 +21,8 @@
#include "config.h"
#include "exec.h"
+//#define DEBUG_OP
+
#define regs (env)
#define Ts0 (int32_t)T0
#define Ts1 (int32_t)T1
@@ -34,7 +36,7 @@
#define FTS1 ((float)env->ft1)
#define FTS2 ((float)env->ft2)
-#define PPC_OP(name) void op_##name(void)
+#define PPC_OP(name) void glue(op_, name)(void)
#define REG 0
#include "op_template.h"
@@ -145,7 +147,7 @@ PPC_OP(set_Rc0)
} else {
tmp = 0x02;
}
- set_CRn(0, tmp);
+ env->crf[0] = tmp;
RETURN();
}
@@ -161,21 +163,21 @@ PPC_OP(set_Rc0_ov)
tmp = 0x02;
}
tmp |= xer_ov;
- set_CRn(0, tmp);
+ env->crf[0] = tmp;
RETURN();
}
/* reset_Rc0 */
PPC_OP(reset_Rc0)
{
- set_CRn(0, 0x02 | xer_ov);
+ env->crf[0] = 0x02 | xer_ov;
RETURN();
}
/* set_Rc0_1 */
PPC_OP(set_Rc0_1)
{
- set_CRn(0, 0x04 | xer_ov);
+ env->crf[0] = 0x04 | xer_ov;
RETURN();
}
@@ -186,6 +188,7 @@ PPC_OP(set_Rc1)
RETURN();
}
+/* Constants load */
PPC_OP(set_T0)
{
T0 = PARAM(1);
@@ -204,23 +207,50 @@ PPC_OP(set_T2)
RETURN();
}
-/* Update time base */
-PPC_OP(update_tb)
+/* Generate exceptions */
+PPC_OP(queue_exception_err)
{
- T0 = regs->spr[SPR_ENCODE(268)];
- T1 = T0;
- T0 += PARAM(1);
- if (T0 < T1) {
- T1 = regs->spr[SPR_ENCODE(269)] + 1;
- regs->spr[SPR_ENCODE(269)] = T1;
+ do_queue_exception_err(PARAM(1), PARAM(2));
+}
+
+PPC_OP(queue_exception)
+{
+ do_queue_exception(PARAM(1));
+}
+
+PPC_OP(process_exceptions)
+{
+ if (env->exceptions != 0) {
+ env->nip = PARAM(1);
+ do_check_exception_state();
}
- regs->spr[SPR_ENCODE(268)] = T0;
+}
+
+/* Segment registers load and store with immediate index */
+PPC_OP(load_srin)
+{
+ T0 = regs->sr[T1 >> 28];
+ RETURN();
+}
+
+PPC_OP(store_srin)
+{
+#if defined (DEBUG_OP)
+ dump_store_sr(T1 >> 28);
+#endif
+ regs->sr[T1 >> 28] = T0;
+ RETURN();
+}
+
+PPC_OP(load_sdr1)
+{
+ T0 = regs->sdr1;
RETURN();
}
-PPC_OP(raise_exception)
+PPC_OP(store_sdr1)
{
- raise_exception(PARAM(1));
+ regs->sdr1 = T0;
RETURN();
}
@@ -229,15 +259,16 @@ PPC_OP(exit_tb)
EXIT_TB();
}
+/* Load/store special registers */
PPC_OP(load_cr)
{
- T0 = do_load_cr();
+ do_load_cr();
RETURN();
}
PPC_OP(store_cr)
{
- do_store_cr(PARAM(1), T0);
+ do_store_cr(PARAM(1));
RETURN();
}
@@ -257,40 +288,152 @@ PPC_OP(clear_xer_cr)
PPC_OP(load_xer_bc)
{
- T0 = xer_bc;
+ T1 = xer_bc;
RETURN();
}
PPC_OP(load_xer)
{
- T0 = do_load_xer();
+ do_load_xer();
RETURN();
}
PPC_OP(store_xer)
{
- do_store_xer(T0);
+ do_store_xer();
RETURN();
}
PPC_OP(load_msr)
{
- T0 = do_load_msr();
+ do_load_msr();
RETURN();
}
PPC_OP(store_msr)
{
- do_store_msr(T0);
+ do_store_msr();
+ RETURN();
+}
+
+/* SPR */
+PPC_OP(load_spr)
+{
+ T0 = regs->spr[PARAM(1)];
+ RETURN();
+}
+
+PPC_OP(store_spr)
+{
+ regs->spr[PARAM(1)] = T0;
RETURN();
}
PPC_OP(load_lr)
{
- regs->LR = PARAM(1);
+ T0 = regs->lr;
+ RETURN();
+}
+
+PPC_OP(store_lr)
+{
+ regs->lr = T0;
+ RETURN();
+}
+
+PPC_OP(load_ctr)
+{
+ T0 = regs->ctr;
+ RETURN();
+}
+
+PPC_OP(store_ctr)
+{
+ regs->ctr = T0;
+ RETURN();
+}
+
+/* Update time base */
+PPC_OP(update_tb)
+{
+ 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;
+ RETURN();
+}
+
+PPC_OP(load_tb)
+{
+ T0 = regs->tb[PARAM(1)];
+ RETURN();
+}
+
+PPC_OP(store_tb)
+{
+ regs->tb[PARAM(1)] = T0;
+#if defined (DEBUG_OP)
+ dump_store_tb(PARAM(1));
+#endif
RETURN();
}
+/* Update decrementer */
+PPC_OP(update_decr)
+{
+ T0 = regs->decr;
+ T1 = T0;
+ T0 -= PARAM(1);
+ regs->decr = T0;
+ if (PARAM(1) > T1) {
+ do_queue_exception(EXCP_DECR);
+ }
+ RETURN();
+}
+
+PPC_OP(store_decr)
+{
+ T1 = regs->decr;
+ regs->decr = T0;
+ if (Ts0 < 0 && Ts1 > 0) {
+ do_queue_exception(EXCP_DECR);
+ }
+ RETURN();
+}
+
+PPC_OP(load_ibat)
+{
+ T0 = regs->IBAT[PARAM(1)][PARAM(2)];
+}
+
+PPC_OP(store_ibat)
+{
+#if defined (DEBUG_OP)
+ dump_store_ibat(PARAM(1), PARAM(2));
+#endif
+ regs->IBAT[PARAM(1)][PARAM(2)] = T0;
+}
+
+PPC_OP(load_dbat)
+{
+ T0 = regs->DBAT[PARAM(1)][PARAM(2)];
+}
+
+PPC_OP(store_dbat)
+{
+#if defined (DEBUG_OP)
+ dump_store_dbat(PARAM(1), PARAM(2));
+#endif
+ regs->DBAT[PARAM(1)][PARAM(2)] = T0;
+}
+
/* FPSCR */
PPC_OP(load_fpscr)
{
@@ -313,14 +456,7 @@ PPC_OP(reset_scrfx)
/* Set reservation */
PPC_OP(set_reservation)
{
- regs->reserve = T1 & ~0x03;
- RETURN();
-}
-
-/* Reset reservation */
-PPC_OP(reset_reservation)
-{
- regs->reserve = 0;
+ regs->reserve = T0 & ~0x03;
RETURN();
}
@@ -344,47 +480,65 @@ 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) \
{ \
- regs->nip = (target); \
+ TB_DO_JUMP(glue(op_, name), T1, 0, (target)); \
RETURN(); \
}
-#define __PPC_OP_BL(name, target) \
+#define __PPC_OP_BL(name, target, link) \
PPC_OP(name) \
{ \
- regs->LR = PARAM(1); \
- regs->nip = (target); \
+ regs->lr = (link); \
+ TB_DO_JUMP(glue(op_, name), T1, 0, (target)); \
RETURN(); \
}
-#define PPC_OP_B(name, target) \
+#define PPC_OP_B(name, target, link) \
__PPC_OP_B(name, target); \
-__PPC_OP_BL(name##l, target)
+__PPC_OP_BL(glue(name, l), target, link)
#define __PPC_OP_BC(name, cond, target) \
PPC_OP(name) \
{ \
if (cond) { \
- T0 = (target); \
+ TB_DO_JUMP(glue(op_, name), T1, 1, (target)); \
} else { \
- T0 = PARAM(1); \
+ TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \
} \
- regs->nip = T0; \
RETURN(); \
}
#define __PPC_OP_BCL(name, cond, target) \
PPC_OP(name) \
{ \
+ regs->lr = PARAM(1); \
if (cond) { \
- T0 = (target); \
- regs->LR = PARAM(1); \
+ TB_DO_JUMP(glue(op_, name), T1, 1, (target)); \
} else { \
- T0 = PARAM(1); \
+ 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)); \
} \
- regs->nip = T0; \
RETURN(); \
}
@@ -396,48 +550,56 @@ __PPC_OP_BCL(namel, cond, target)
#define PPC_OP_BC(name, cond) \
_PPC_OP_BC(b_##name, bl_##name, cond, PARAM(2))
-PPC_OP_B(b, PARAM(1));
-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_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);
-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_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, blrl_##name, cond, regs->LR & ~0x03)
-
-PPC_OP_B(blr, regs->LR & ~0x03);
-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_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));
/* CTR maintenance */
PPC_OP(dec_ctr)
{
- regs->CTR--;
+ regs->ctr--;
RETURN();
}
@@ -1077,7 +1239,7 @@ PPC_OP(slw)
/* shift right algebraic word */
PPC_OP(sraw)
{
- Ts0 = do_sraw(Ts0, T1);
+ do_sraw();
RETURN();
}
@@ -1106,313 +1268,280 @@ PPC_OP(srw)
}
/*** Floating-Point arithmetic ***/
-
-/*** Floating-Point multiply-and-add ***/
-
-/*** Floating-Point round & convert ***/
-
-/*** Floating-Point compare ***/
-
-/*** Floating-Point status & ctrl register ***/
-
-/*** Integer load ***/
-#define ld16x(x) s_ext16(ld16(x))
-#define PPC_ILD_OPX(name, op) \
-PPC_OP(l##name##x_z) \
-{ \
- T1 = op(T0); \
- RETURN(); \
-} \
-PPC_OP(l##name##x) \
-{ \
- T0 += T1; \
- T1 = op(T0); \
- RETURN(); \
-}
-
-#define PPC_ILD_OP(name, op) \
-PPC_OP(l##name##_z) \
-{ \
- T1 = op(SPARAM(1)); \
- RETURN(); \
-} \
-PPC_OP(l##name) \
-{ \
- T0 += SPARAM(1); \
- T1 = op(T0); \
- RETURN(); \
-} \
-PPC_ILD_OPX(name, op)
-
-PPC_ILD_OP(bz, ld8);
-PPC_ILD_OP(ha, ld16x);
-PPC_ILD_OP(hz, ld16);
-PPC_ILD_OP(wz, ld32);
-
-/*** Integer store ***/
-#define PPC_IST_OPX(name, op) \
-PPC_OP(st##name##x_z) \
-{ \
- op(T0, T1); \
- RETURN(); \
-} \
-PPC_OP(st##name##x) \
-{ \
- T0 += T1; \
- op(T0, T2); \
- RETURN(); \
-}
-
-#define PPC_IST_OP(name, op) \
-PPC_OP(st##name##_z) \
-{ \
- op(SPARAM(1), T0); \
- RETURN(); \
-} \
-PPC_OP(st##name) \
-{ \
- T0 += SPARAM(1); \
- op(T0, T1); \
- RETURN(); \
-} \
-PPC_IST_OPX(name, op);
-
-PPC_IST_OP(b, st8);
-PPC_IST_OP(h, st16);
-PPC_IST_OP(w, st32);
-
-/*** Integer load and store with byte reverse ***/
-PPC_ILD_OPX(hbr, ld16r);
-PPC_ILD_OPX(wbr, ld32r);
-PPC_IST_OPX(hbr, st16r);
-PPC_IST_OPX(wbr, st32r);
-
-/*** Integer load and store multiple ***/
-PPC_OP(lmw)
+/* fadd - fadd. */
+PPC_OP(fadd)
{
- do_lmw(PARAM(1), SPARAM(2) + T0);
+ FT0 += FT1;
RETURN();
}
-PPC_OP(stmw)
+/* fadds - fadds. */
+PPC_OP(fadds)
{
- do_stmw(PARAM(1), SPARAM(2) + T0);
+ FTS0 += FTS1;
RETURN();
}
-/*** Integer load and store strings ***/
-PPC_OP(lswi)
+/* fsub - fsub. */
+PPC_OP(fsub)
{
- do_lsw(PARAM(1), PARAM(2), T0);
+ FT0 -= FT1;
RETURN();
}
-PPC_OP(lswx)
+/* fsubs - fsubs. */
+PPC_OP(fsubs)
{
- do_lsw(PARAM(1), T0, T1 + T2);
+ FTS0 -= FTS1;
RETURN();
}
-PPC_OP(stswi_z)
+/* fmul - fmul. */
+PPC_OP(fmul)
{
- do_stsw(PARAM(1), PARAM(2), 0);
+ FT0 *= FT1;
RETURN();
}
-PPC_OP(stswi)
+/* fmuls - fmuls. */
+PPC_OP(fmuls)
{
- do_stsw(PARAM(1), PARAM(2), T0);
+ FTS0 *= FTS1;
RETURN();
}
-PPC_OP(stswx_z)
+/* fdiv - fdiv. */
+PPC_OP(fdiv)
{
- do_stsw(PARAM(1), T0, T1);
+ FT0 /= FT1;
RETURN();
}
-PPC_OP(stswx)
+/* fdivs - fdivs. */
+PPC_OP(fdivs)
{
- do_stsw(PARAM(1), T0, T1 + T2);
+ FTS0 /= FTS1;
RETURN();
}
-/* SPR */
-PPC_OP(load_spr)
+/* fsqrt - fsqrt. */
+PPC_OP(fsqrt)
{
- T0 = regs->spr[PARAM(1)];
+ do_fsqrt();
+ RETURN();
}
-PPC_OP(store_spr)
+/* fsqrts - fsqrts. */
+PPC_OP(fsqrts)
{
- regs->spr[PARAM(1)] = T0;
+ do_fsqrts();
+ RETURN();
}
-/*** Floating-point store ***/
-
-PPC_OP(stfd_z_FT0)
+/* fres - fres. */
+PPC_OP(fres)
{
- stfq((void *)SPARAM(1), FT0);
+ do_fres();
+ RETURN();
}
-PPC_OP(stfd_FT0)
+/* frsqrte - frsqrte. */
+PPC_OP(frsqrte)
{
- T0 += SPARAM(1);
- stfq((void *)T0, FT0);
+ do_fsqrte();
+ RETURN();
}
-PPC_OP(stfdx_z_FT0)
+/* fsel - fsel. */
+PPC_OP(fsel)
{
- stfq((void *)T0, FT0);
+ do_fsel();
+ RETURN();
}
-PPC_OP(stfdx_FT0)
+/*** Floating-Point multiply-and-add ***/
+/* fmadd - fmadd. */
+PPC_OP(fmadd)
{
- T0 += T1;
- stfq((void *)T0, FT0);
+ FT0 = (FT0 * FT1) + FT2;
+ RETURN();
}
-PPC_OP(stfs_z_FT0)
+/* fmadds - fmadds. */
+PPC_OP(fmadds)
{
- float tmp = FT0;
- stfl((void *)SPARAM(1), tmp);
+ FTS0 = (FTS0 * FTS1) + FTS2;
+ RETURN();
}
-PPC_OP(stfs_FT0)
+/* fmsub - fmsub. */
+PPC_OP(fmsub)
{
- float tmp = FT0;
- T0 += SPARAM(1);
- stfl((void *)T0, tmp);
+ FT0 = (FT0 * FT1) - FT2;
+ RETURN();
}
-PPC_OP(stfsx_z_FT0)
+/* fmsubs - fmsubs. */
+PPC_OP(fmsubs)
{
- float tmp = FT0;
- stfl((void *)T0, tmp);
+ FTS0 = (FTS0 * FTS1) - FTS2;
+ RETURN();
}
-PPC_OP(stfsx_FT0)
+/* fnmadd - fnmadd. - fnmadds - fnmadds. */
+PPC_OP(fnmadd)
{
- float tmp = FT0;
- T0 += T1;
- stfl((void *)T0, tmp);
+ FT0 = -((FT0 * FT1) + FT2);
+ RETURN();
}
-/*** Floating-point load ***/
-PPC_OP(lfd_z_FT0)
+/* fnmadds - fnmadds. */
+PPC_OP(fnmadds)
{
- FT0 = ldfq((void *)SPARAM(1));
+ FTS0 = -((FTS0 * FTS1) + FTS2);
+ RETURN();
}
-PPC_OP(lfd_FT0)
+/* fnmsub - fnmsub. */
+PPC_OP(fnmsub)
{
- T0 += SPARAM(1);
- FT0 = ldfq((void *)T0);
+ FT0 = -((FT0 * FT1) - FT2);
+ RETURN();
}
-PPC_OP(lfdx_z_FT0)
+/* fnmsubs - fnmsubs. */
+PPC_OP(fnmsubs)
{
- FT0 = ldfq((void *)T0);
+ FTS0 = -((FTS0 * FTS1) - FTS2);
+ RETURN();
}
-PPC_OP(lfdx_FT0)
+/*** Floating-Point round & convert ***/
+/* frsp - frsp. */
+PPC_OP(frsp)
{
- T0 += T1;
- FT0 = ldfq((void *)T0);
+ FT0 = FTS0;
+ RETURN();
}
-PPC_OP(lfs_z_FT0)
+/* fctiw - fctiw. */
+PPC_OP(fctiw)
{
- float tmp = ldfl((void *)SPARAM(1));
- FT0 = tmp;
+ do_fctiw();
+ RETURN();
}
-PPC_OP(lfs_FT0)
+/* fctiwz - fctiwz. */
+PPC_OP(fctiwz)
{
- float tmp;
- T0 += SPARAM(1);
- tmp = ldfl((void *)T0);
- FT0 = tmp;
+ do_fctiwz();
+ RETURN();
}
-PPC_OP(lfsx_z_FT0)
+
+/*** Floating-Point compare ***/
+/* fcmpu */
+PPC_OP(fcmpu)
{
- float tmp;
- tmp = ldfl((void *)T0);
- FT0 = tmp;
+ do_fcmpu();
+ RETURN();
}
-PPC_OP(lfsx_FT0)
+/* fcmpo */
+PPC_OP(fcmpo)
{
- float tmp;
- T0 += T1;
- tmp = ldfl((void *)T0);
- FT0 = tmp;
+ do_fcmpo();
+ RETURN();
}
-PPC_OP(lwarx_z)
+/*** Floating-point move ***/
+/* fabs */
+PPC_OP(fabs)
{
- T1 = ld32(T0);
- regs->reserve = T0;
+ do_fabs();
RETURN();
}
-PPC_OP(lwarx)
+/* fnabs */
+PPC_OP(fnabs)
{
- T0 += T1;
- T1 = ld32(T0);
- regs->reserve = T0;
+ do_fnabs();
RETURN();
}
-PPC_OP(stwcx_z)
+/* fneg */
+PPC_OP(fneg)
{
- if (regs->reserve != T0) {
- env->crf[0] = xer_ov;
- } else {
- st32(T0, T1);
- env->crf[0] = xer_ov | 0x02;
- }
- regs->reserve = 0;
+ FT0 = -FT0;
RETURN();
}
-PPC_OP(stwcx)
+/* Load and store */
+#if defined(CONFIG_USER_ONLY)
+#define MEMSUFFIX _raw
+#include "op_mem.h"
+#else
+#define MEMSUFFIX _user
+#include "op_mem.h"
+
+#define MEMSUFFIX _kernel
+#include "op_mem.h"
+#endif
+
+/* Return from interrupt */
+PPC_OP(rfi)
{
- T0 += T1;
- if (regs->reserve != (T0 & ~0x03)) {
- env->crf[0] = xer_ov;
- } else {
- st32(T0, T2);
- env->crf[0] = xer_ov | 0x02;
+ T0 = regs->spr[SRR1] & ~0xFFFF0000;
+ do_store_msr();
+ do_tlbia();
+ dump_rfi();
+ regs->nip = regs->spr[SRR0] & ~0x00000003;
+ if (env->exceptions != 0) {
+ do_check_exception_state();
}
- regs->reserve = 0;
RETURN();
}
-PPC_OP(dcbz_z)
+/* Trap word */
+PPC_OP(tw)
{
- do_dcbz();
+ if ((Ts0 < Ts1 && (PARAM(1) & 0x10)) ||
+ (Ts0 > Ts1 && (PARAM(1) & 0x08)) ||
+ (Ts0 == Ts1 && (PARAM(1) & 0x04)) ||
+ (T0 < T1 && (PARAM(1) & 0x02)) ||
+ (T0 > T1 && (PARAM(1) & 0x01)))
+ do_queue_exception_err(EXCP_PROGRAM, EXCP_TRAP);
RETURN();
}
-PPC_OP(dcbz)
+PPC_OP(twi)
{
- T0 += T1;
- do_dcbz();
+ if ((Ts0 < SPARAM(1) && (PARAM(2) & 0x10)) ||
+ (Ts0 > SPARAM(1) && (PARAM(2) & 0x08)) ||
+ (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);
RETURN();
}
/* Instruction cache block invalidate */
-PPC_OP(icbi_z)
+PPC_OP(icbi)
{
do_icbi();
RETURN();
}
-PPC_OP(icbi)
+/* tlbia */
+PPC_OP(tlbia)
{
- T0 += T1;
- do_icbi();
+ do_tlbia();
+ RETURN();
+}
+
+/* tlbie */
+PPC_OP(tlbie)
+{
+ do_tlbie();
RETURN();
}