diff options
-rw-r--r-- | target-ppc/exec.h | 2 | ||||
-rw-r--r-- | target-ppc/helper.c | 13 | ||||
-rw-r--r-- | target-ppc/op.c | 12 | ||||
-rw-r--r-- | target-ppc/op_helper.c | 10 | ||||
-rw-r--r-- | target-ppc/translate.c | 6 |
5 files changed, 30 insertions, 13 deletions
diff --git a/target-ppc/exec.h b/target-ppc/exec.h index 72bd03e..f4d20a8 100644 --- a/target-ppc/exec.h +++ b/target-ppc/exec.h @@ -139,6 +139,8 @@ void do_sraw(void); void do_fctiw (void); void do_fctiwz (void); +void do_fnmadds (void); +void do_fnmsubs (void); void do_fsqrt (void); void do_fsqrts (void); void do_fres (void); diff --git a/target-ppc/helper.c b/target-ppc/helper.c index ccfd2ea..dc2737e 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -163,7 +163,6 @@ static int get_bat (CPUState *env, uint32_t *real, int *prot, *BATu, *BATl, BEPIu, BEPIl, bl); } #endif - env->spr[DAR] = virtual; } /* No hit */ return ret; @@ -543,12 +542,12 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, access_type = env->access_type; if (env->user_mode_only) { /* user mode only emulation */ - ret = -1; + ret = -2; goto do_fault; } /* NASTY BUG workaround */ if (access_type == ACCESS_CODE && rw) { - // printf("%s: ERROR WRITE CODE ACCESS\n", __func__); + printf("%s: ERROR WRITE CODE ACCESS\n", __func__); access_type = ACCESS_INT; } ret = get_physical_address(env, &physical, &prot, @@ -674,10 +673,10 @@ uint32_t _load_msr (CPUState *env) void _store_msr (CPUState *env, uint32_t value) { - if (((T0 >> MSR_IR) & 0x01) != msr_ir || - ((T0 >> MSR_DR) & 0x01) != msr_dr) { + if (((value >> MSR_IR) & 0x01) != msr_ir || + ((value >> MSR_DR) & 0x01) != msr_dr) { /* Flush all tlb when changing translation mode or privilege level */ - do_tlbia(); + tlb_flush(env, 1); } msr_pow = (value >> MSR_POW) & 0x03; msr_ile = (value >> MSR_ILE) & 0x01; @@ -931,7 +930,7 @@ void do_interrupt (CPUState *env) env->nip = excp << 8; env->exception_index = EXCP_NONE; /* Invalidate all TLB as we may have changed translation mode */ - do_tlbia(); + tlb_flush(env, 1); /* ensure that no TB jump will be modified as the program flow was changed */ #ifdef __sparc__ diff --git a/target-ppc/op.c b/target-ppc/op.c index 12c9289..de7e247 100644 --- a/target-ppc/op.c +++ b/target-ppc/op.c @@ -1368,28 +1368,32 @@ PPC_OP(fmsubs) /* fnmadd - fnmadd. - fnmadds - fnmadds. */ PPC_OP(fnmadd) { - FT0 = -((FT0 * FT1) + FT2); + FT0 *= FT1; + FT0 += FT2; + FT0 = -FT0; RETURN(); } /* fnmadds - fnmadds. */ PPC_OP(fnmadds) { - FTS0 = -((FTS0 * FTS1) + FTS2); + do_fnmadds(); RETURN(); } /* fnmsub - fnmsub. */ PPC_OP(fnmsub) { - FT0 = -((FT0 * FT1) - FT2); + FT0 *= FT1; + FT0 -= FT2; + FT0 = -FT0; RETURN(); } /* fnmsubs - fnmsubs. */ PPC_OP(fnmsubs) { - FTS0 = -((FTS0 * FTS1) - FTS2); + do_fnmsubs(); RETURN(); } diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 0bb48e7..ae3d254 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -267,6 +267,16 @@ void do_fctiwz (void) fesetround(cround); } +void do_fnmadds (void) +{ + FTS0 = -((FTS0 * FTS1) + FTS2); +} + +void do_fnmsubs (void) +{ + FTS0 = -((FTS0 * FTS1) - FTS2); +} + void do_fsqrt (void) { FT0 = sqrt(FT0); diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 35bd660..50d1ec1 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -276,7 +276,7 @@ static inline uint32_t MASK (uint32_t start, uint32_t end) } #define GEN_OPCODE(name, op1, op2, op3, invl, _typ) \ -__attribute__ ((section(".opcodes"), unused)) \ +__attribute__ ((section(".opcodes"), unused, aligned (8) )) \ static opcode_t opc_##name = { \ .opc1 = op1, \ .opc2 = op2, \ @@ -289,7 +289,7 @@ static opcode_t opc_##name = { \ } #define GEN_OPCODE_MARK(name) \ -__attribute__ ((section(".opcodes"), unused)) \ +__attribute__ ((section(".opcodes"), unused, aligned (8) )) \ static opcode_t opc_##name = { \ .opc1 = 0xFF, \ .opc2 = 0xFF, \ @@ -3144,7 +3144,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, fprintf(logfile, "---------------- excp: %04x\n", ctx.exception); cpu_ppc_dump_state(env, logfile, 0); fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start)); +#if defined(CONFIG_USER_ONLY) disas(logfile, (void *)pc_start, ctx.nip - pc_start, 0, 0); +#endif fprintf(logfile, "\n"); fprintf(logfile, "OP:\n"); |