diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 123cb3f91b..1776a3577a 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -24,8 +24,6 @@ #include "cpu-defs.h" -//#define USE_OPEN_FIRMWARE - #include "config.h" #include diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 21e89008f4..a9424dfa70 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -18,10 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "exec.h" -#if defined (USE_OPEN_FIRMWARE) -#include -#include "of.h" -#endif //#define DEBUG_MMU //#define DEBUG_BATS @@ -688,18 +684,6 @@ void do_interrupt (CPUState *env) } /* Generate informations in save/restore registers */ switch (excp) { - case EXCP_OFCALL: -#if defined (USE_OPEN_FIRMWARE) - env->gpr[3] = OF_client_entry((void *)env->gpr[3]); -#endif - return; - case EXCP_RTASCALL: -#if defined (USE_OPEN_FIRMWARE) - printf("RTAS call !\n"); - env->gpr[3] = RTAS_entry((void *)env->gpr[3]); - printf("RTAS call done\n"); -#endif - return; case EXCP_NONE: /* Do nothing */ #if defined (DEBUG_EXCEPTIONS) diff --git a/target-ppc/op.c b/target-ppc/op.c index c6c0989ce9..5accc55064 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -697,9 +697,9 @@ PPC_OP(addzeo) PPC_OP(divw) { if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { - Ts0 = (-1) * (T0 >> 31); + T0 = (int32_t)((-1) * (T0 >> 31)); } else { - Ts0 /= Ts1; + T0 = (Ts0 / Ts1); } RETURN(); } @@ -712,7 +712,7 @@ PPC_OP(divwo) T0 = (-1) * (T0 >> 31); } else { xer_ov = 0; - Ts0 /= Ts1; + T0 = (Ts0 / Ts1); } RETURN(); } @@ -744,7 +744,7 @@ PPC_OP(divwuo) /* multiply high word */ PPC_OP(mulhw) { - Ts0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32; + T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32; RETURN(); } @@ -758,7 +758,7 @@ PPC_OP(mulhwu) /* multiply low immediate */ PPC_OP(mulli) { - Ts0 *= SPARAM(1); + T0 = (Ts0 * SPARAM(1)); RETURN(); } @@ -779,7 +779,7 @@ PPC_OP(mullwo) } else { xer_ov = 0; } - Ts0 = res; + T0 = (int32_t)res; RETURN(); } @@ -787,7 +787,7 @@ PPC_OP(mullwo) PPC_OP(neg) { if (T0 != 0x80000000) { - Ts0 = -Ts0; + T0 = -Ts0; } RETURN(); } @@ -799,7 +799,7 @@ PPC_OP(nego) xer_so = 1; } else { xer_ov = 0; - Ts0 = -Ts0; + T0 = -Ts0; } RETURN(); } @@ -1047,14 +1047,14 @@ PPC_OP(eqv) /* extend sign byte */ PPC_OP(extsb) { - Ts0 = (int8_t)(Ts0); + T0 = (int32_t)((int8_t)(Ts0)); RETURN(); } /* extend sign half word */ PPC_OP(extsh) { - Ts0 = (int16_t)(Ts0); + T0 = (int32_t)((int16_t)(Ts0)); RETURN(); } @@ -1175,8 +1175,8 @@ PPC_OP(sraw) /* shift right algebraic word immediate */ PPC_OP(srawi) { - Ts1 = Ts0; - Ts0 = Ts0 >> PARAM(1); + T1 = T0; + T0 = (Ts0 >> PARAM(1)); if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) { xer_ca = 1; } else { @@ -1207,7 +1207,7 @@ PPC_OP(fadd) /* fadds - fadds. */ PPC_OP(fadds) { - FTS0 += FTS1; + FT0 = FTS0 + FTS1; RETURN(); } @@ -1221,7 +1221,7 @@ PPC_OP(fsub) /* fsubs - fsubs. */ PPC_OP(fsubs) { - FTS0 -= FTS1; + FT0 = FTS0 - FTS1; RETURN(); } @@ -1235,7 +1235,7 @@ PPC_OP(fmul) /* fmuls - fmuls. */ PPC_OP(fmuls) { - FTS0 *= FTS1; + FT0 = FTS0 * FTS1; RETURN(); } @@ -1249,7 +1249,7 @@ PPC_OP(fdiv) /* fdivs - fdivs. */ PPC_OP(fdivs) { - FTS0 /= FTS1; + FT0 = FTS0 / FTS1; RETURN(); } @@ -1299,7 +1299,7 @@ PPC_OP(fmadd) /* fmadds - fmadds. */ PPC_OP(fmadds) { - FTS0 = (FTS0 * FTS1) + FTS2; + FT0 = (FTS0 * FTS1) + FTS2; RETURN(); } @@ -1313,7 +1313,7 @@ PPC_OP(fmsub) /* fmsubs - fmsubs. */ PPC_OP(fmsubs) { - FTS0 = (FTS0 * FTS1) - FTS2; + FT0 = (FTS0 * FTS1) - FTS2; RETURN(); } @@ -1349,7 +1349,7 @@ PPC_OP(fnmsubs) /* frsp - frsp. */ PPC_OP(frsp) { - FTS0 = FT0; + FT0 = (float)FT0; RETURN(); } diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 433f6b1284..20aba8b6eb 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -188,10 +188,17 @@ void do_load_fpscr (void) } u; int i; - u.s.u[0] = 0; - u.s.u[1] = 0; +#ifdef WORDS_BIGENDIAN +#define WORD0 0 +#define WORD1 1 +#else +#define WORD0 1 +#define WORD1 0 +#endif + u.s.u[WORD0] = 0; + u.s.u[WORD1] = 0; for (i = 0; i < 8; i++) - u.s.u[1] |= env->fpscr[i] << (4 * i); + u.s.u[WORD1] |= env->fpscr[i] << (4 * i); FT0 = u.d; } @@ -210,10 +217,10 @@ void do_store_fpscr (uint32_t mask) u.d = FT0; if (mask & 0x80) - env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[1] >> 28) & ~0x9); + env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[WORD1] >> 28) & ~0x9); for (i = 1; i < 7; i++) { if (mask & (1 << (7 - i))) - env->fpscr[i] = (u.s.u[1] >> (4 * (7 - i))) & 0xF; + env->fpscr[i] = (u.s.u[WORD1] >> (4 * (7 - i))) & 0xF; } /* TODO: update FEX & VX */ /* Set rounding mode */ diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 4de116f185..bb3bbbb544 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -134,12 +134,13 @@ typedef struct DisasContext { target_ulong nip; uint32_t opcode; uint32_t exception; - /* Execution mode */ + /* Routine used to access memory */ + int mem_idx; + /* Translation flags */ #if !defined(CONFIG_USER_ONLY) int supervisor; #endif - /* Routine used to access memory */ - int mem_idx; + int fpu_enabled; } DisasContext; typedef struct opc_handler_t { @@ -330,19 +331,6 @@ GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON) RET_EXCP(ctx, EXCP_HLT, 0); } -/* Special opcode to call open-firmware */ -GEN_HANDLER(of_enter, 0x06, 0x01, 0xFF, 0x03FFFFC1, PPC_COMMON) -{ - RET_EXCP(ctx, EXCP_OFCALL, 0); -} - -/* Special opcode to call RTAS */ -GEN_HANDLER(rtas_enter, 0x06, 0x02, 0xFF, 0x03FFFFC1, PPC_COMMON) -{ - printf("RTAS entry point !\n"); - RET_EXCP(ctx, EXCP_RTASCALL, 0); -} - static opc_handler_t invalid_handler = { .inval = 0xFFFFFFFF, .type = PPC_NONE, @@ -764,6 +752,10 @@ __GEN_LOGICAL2(srw, 0x18, 0x10); #define _GEN_FLOAT_ACB(name, op1, op2) \ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \ { \ + if (!ctx->fpu_enabled) { \ + RET_EXCP(ctx, EXCP_NO_FP, 0); \ + return; \ + } \ gen_op_reset_scrfx(); \ gen_op_load_fpr_FT0(rA(ctx->opcode)); \ gen_op_load_fpr_FT1(rC(ctx->opcode)); \ @@ -781,6 +773,10 @@ _GEN_FLOAT_ACB(name##s, 0x3B, op2); #define _GEN_FLOAT_AB(name, op1, op2, inval) \ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ { \ + if (!ctx->fpu_enabled) { \ + RET_EXCP(ctx, EXCP_NO_FP, 0); \ + return; \ + } \ gen_op_reset_scrfx(); \ gen_op_load_fpr_FT0(rA(ctx->opcode)); \ gen_op_load_fpr_FT1(rB(ctx->opcode)); \ @@ -796,6 +792,10 @@ _GEN_FLOAT_AB(name##s, 0x3B, op2, inval); #define _GEN_FLOAT_AC(name, op1, op2, inval) \ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ { \ + if (!ctx->fpu_enabled) { \ + RET_EXCP(ctx, EXCP_NO_FP, 0); \ + return; \ + } \ gen_op_reset_scrfx(); \ gen_op_load_fpr_FT0(rA(ctx->opcode)); \ gen_op_load_fpr_FT1(rC(ctx->opcode)); \ @@ -811,6 +811,10 @@ _GEN_FLOAT_AC(name##s, 0x3B, op2, inval); #define GEN_FLOAT_B(name, op2, op3) \ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ { \ + if (!ctx->fpu_enabled) { \ + RET_EXCP(ctx, EXCP_NO_FP, 0); \ + return; \ + } \ gen_op_reset_scrfx(); \ gen_op_load_fpr_FT0(rB(ctx->opcode)); \ gen_op_f##name(); \ @@ -822,6 +826,10 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ #define GEN_FLOAT_BS(name, op2) \ GEN_HANDLER(f##name, 0x3F, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ { \ + if (!ctx->fpu_enabled) { \ + RET_EXCP(ctx, EXCP_NO_FP, 0); \ + return; \ + } \ gen_op_reset_scrfx(); \ gen_op_load_fpr_FT0(rB(ctx->opcode)); \ gen_op_f##name(); \ @@ -853,6 +861,10 @@ GEN_FLOAT_BS(sqrt, 0x16); GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_reset_scrfx(); gen_op_load_fpr_FT0(rB(ctx->opcode)); gen_op_fsqrts(); @@ -883,6 +895,10 @@ GEN_FLOAT_B(rsp, 0x0C, 0x00); /* fcmpo */ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_reset_scrfx(); gen_op_load_fpr_FT0(rA(ctx->opcode)); gen_op_load_fpr_FT1(rB(ctx->opcode)); @@ -893,6 +909,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) /* fcmpu */ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_reset_scrfx(); gen_op_load_fpr_FT0(rA(ctx->opcode)); gen_op_load_fpr_FT1(rB(ctx->opcode)); @@ -907,6 +927,10 @@ GEN_FLOAT_B(abs, 0x08, 0x08); /* fmr - fmr. */ GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_reset_scrfx(); gen_op_load_fpr_FT0(rB(ctx->opcode)); gen_op_store_FT0_fpr(rD(ctx->opcode)); @@ -923,6 +947,10 @@ GEN_FLOAT_B(neg, 0x08, 0x01); /* mcrfs */ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_load_fpscr_T0(crfS(ctx->opcode)); gen_op_store_T0_crf(crfD(ctx->opcode)); gen_op_clear_fpscr(crfS(ctx->opcode)); @@ -931,6 +959,10 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) /* mffs */ GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_load_fpscr(); gen_op_store_FT0_fpr(rD(ctx->opcode)); if (Rc(ctx->opcode)) @@ -942,6 +974,10 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) { uint8_t crb; + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } crb = crbD(ctx->opcode) >> 2; gen_op_load_fpscr_T0(crb); gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03))); @@ -955,6 +991,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) { uint8_t crb; + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } crb = crbD(ctx->opcode) >> 2; gen_op_load_fpscr_T0(crb); gen_op_ori(1 << (crbD(ctx->opcode) & 0x03)); @@ -966,6 +1006,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) /* mtfsf */ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_load_fpr_FT0(rB(ctx->opcode)); gen_op_store_fpscr(FM(ctx->opcode)); if (Rc(ctx->opcode)) @@ -975,6 +1019,10 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) /* mtfsfi */ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode)); if (Rc(ctx->opcode)) gen_op_set_Rc1(); @@ -1525,6 +1573,10 @@ GEN_STFS(fs, 0x14); /* stfiwx */ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) { + if (!ctx->fpu_enabled) { + RET_EXCP(ctx, EXCP_NO_FP, 0); + return; + } RET_INVAL(ctx); } @@ -2978,10 +3030,6 @@ void cpu_dump_state(CPUState *env, FILE *f, cpu_fprintf(f, "reservation 0x%08x\n", env->reserve); } -#if !defined(CONFIG_USER_ONLY) && defined (USE_OPENFIRMWARE) -int setup_machine (CPUPPCState *env, uint32_t mid); -#endif - CPUPPCState *cpu_ppc_init(void) { CPUPPCState *env; @@ -2991,14 +3039,10 @@ CPUPPCState *cpu_ppc_init(void) env = qemu_mallocz(sizeof(CPUPPCState)); if (!env) return NULL; -#if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE) - setup_machine(env, 0); -#else // env->spr[PVR] = 0; /* Basic PPC */ env->spr[PVR] = 0x00080100; /* G3 CPU */ // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */ // env->spr[PVR] = 0x00070100; /* IBM 750FX */ -#endif tlb_flush(env, 1); #if defined (DO_SINGLE_STEP) /* Single step trace mode */ @@ -3053,8 +3097,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, ctx.mem_idx = 0; #else ctx.supervisor = 1 - msr_pr; - ctx.mem_idx = (1 - msr_pr); + ctx.mem_idx = 1 - msr_pr; #endif + ctx.fpu_enabled = msr_fp; #if defined (DO_SINGLE_STEP) /* Single step trace mode */ msr_se = 1;