提交 0411a972 编写于 作者: J j_mayer

Gprof prooved the PowerPC emulation spent too much time in MSR load and store

routines. Coming back to a raw MSR storage model then speed-up the emulation.
Improve fast MSR updates (wrtee wrteei and mtriee cases).
Share rfi family instructions helpers code to avoid bug in duplicated code.
Allow entering halt mode as the result of a rfi instruction.
Add a new helper_regs.h file to avoid duplication of special registers
 manipulation routines (currently XER and MSR).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3436 c046a42c-6fe2-441c-8c8c-71466251a162
上级 7ac256b8
......@@ -300,7 +300,7 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
}
/* nip, msr, ccr, lnk, ctr, xer, mq */
registers[96] = tswapl(env->nip);
registers[97] = tswapl(do_load_msr(env));
registers[97] = tswapl(env->msr);
tmp = 0;
for (i = 0; i < 8; i++)
tmp |= env->crf[i] << (32 - ((i + 1) * 4));
......@@ -329,7 +329,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
}
/* nip, msr, ccr, lnk, ctr, xer, mq */
env->nip = tswapl(registers[96]);
do_store_msr(env, tswapl(registers[97]));
ppc_store_msr(env, tswapl(registers[97]));
registers[98] = tswapl(registers[98]);
for (i = 0; i < 8; i++)
env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
......
......@@ -2168,14 +2168,13 @@ int main(int argc, char **argv)
}
cpu_ppc_register(env, def);
cpu_ppc_reset(env);
for (i = 0; i < 32; i++) {
if (i != 12 && i != 6 && i != 13)
env->msr[i] = (regs->msr >> i) & 1;
}
#if defined(TARGET_PPC64) && !defined(TARGET_ABI32)
msr_sf = 1;
env->msr = regs->msr & ~((1 << 6) | (1 << 12) | (1 << 13));
#if defined(TARGET_PPC64)
#if defined(TARGET_ABI32)
env->msr &= ~((target_ulong)1 << MSR_SF);
#else
msr_sf = 0;
env->msr |= (target_ulong)1 << MSR_SF;
#endif
#endif
env->nip = regs->nip;
for(i = 0; i < 32; i++) {
......
......@@ -1415,7 +1415,7 @@ static target_long monitor_get_msr (struct MonitorDef *md, int val)
CPUState *env = mon_get_cpu();
if (!env)
return 0;
return do_load_msr(env);
return env->msr;
}
static target_long monitor_get_xer (struct MonitorDef *md, int val)
......
......@@ -368,7 +368,7 @@ union ppc_tlb_t {
#define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC x */
#define MSR_FE1 8 /* Floating point exception mode 1 hflags */
#define MSR_AL 7 /* AL bit on POWER */
#define MSR_EP 3 /* Exception prefix on 601 */
#define MSR_EP 6 /* Exception prefix on 601 */
#define MSR_IR 5 /* Instruction relocate */
#define MSR_DR 4 /* Data relocate */
#define MSR_PE 3 /* Protection enable on 403 */
......@@ -376,41 +376,42 @@ union ppc_tlb_t {
#define MSR_PMM 2 /* Performance monitor mark on POWER x */
#define MSR_RI 1 /* Recoverable interrupt 1 */
#define MSR_LE 0 /* Little-endian mode 1 hflags */
#define msr_sf env->msr[MSR_SF]
#define msr_isf env->msr[MSR_ISF]
#define msr_hv env->msr[MSR_HV]
#define msr_cm env->msr[MSR_CM]
#define msr_icm env->msr[MSR_ICM]
#define msr_ucle env->msr[MSR_UCLE]
#define msr_vr env->msr[MSR_VR]
#define msr_spe env->msr[MSR_SPE]
#define msr_ap env->msr[MSR_AP]
#define msr_sa env->msr[MSR_SA]
#define msr_key env->msr[MSR_KEY]
#define msr_pow env->msr[MSR_POW]
#define msr_tgpr env->msr[MSR_TGPR]
#define msr_ce env->msr[MSR_CE]
#define msr_ile env->msr[MSR_ILE]
#define msr_ee env->msr[MSR_EE]
#define msr_pr env->msr[MSR_PR]
#define msr_fp env->msr[MSR_FP]
#define msr_me env->msr[MSR_ME]
#define msr_fe0 env->msr[MSR_FE0]
#define msr_se env->msr[MSR_SE]
#define msr_dwe env->msr[MSR_DWE]
#define msr_uble env->msr[MSR_UBLE]
#define msr_be env->msr[MSR_BE]
#define msr_de env->msr[MSR_DE]
#define msr_fe1 env->msr[MSR_FE1]
#define msr_al env->msr[MSR_AL]
#define msr_ir env->msr[MSR_IR]
#define msr_dr env->msr[MSR_DR]
#define msr_pe env->msr[MSR_PE]
#define msr_ep env->msr[MSR_EP]
#define msr_px env->msr[MSR_PX]
#define msr_pmm env->msr[MSR_PMM]
#define msr_ri env->msr[MSR_RI]
#define msr_le env->msr[MSR_LE]
#define msr_sf ((env->msr >> MSR_SF) & 1)
#define msr_isf ((env->msr >> MSR_ISF) & 1)
#define msr_hv ((env->msr >> MSR_HV) & 1)
#define msr_cm ((env->msr >> MSR_CM) & 1)
#define msr_icm ((env->msr >> MSR_ICM) & 1)
#define msr_ucle ((env->msr >> MSR_UCLE) & 1)
#define msr_vr ((env->msr >> MSR_VR) & 1)
#define msr_spe ((env->msr >> MSR_SE) & 1)
#define msr_ap ((env->msr >> MSR_AP) & 1)
#define msr_sa ((env->msr >> MSR_SA) & 1)
#define msr_key ((env->msr >> MSR_KEY) & 1)
#define msr_pow ((env->msr >> MSR_POW) & 1)
#define msr_tgpr ((env->msr >> MSR_TGPR) & 1)
#define msr_ce ((env->msr >> MSR_CE) & 1)
#define msr_ile ((env->msr >> MSR_ILE) & 1)
#define msr_ee ((env->msr >> MSR_EE) & 1)
#define msr_pr ((env->msr >> MSR_PR) & 1)
#define msr_fp ((env->msr >> MSR_FP) & 1)
#define msr_me ((env->msr >> MSR_ME) & 1)
#define msr_fe0 ((env->msr >> MSR_FE0) & 1)
#define msr_se ((env->msr >> MSR_SE) & 1)
#define msr_dwe ((env->msr >> MSR_DWE) & 1)
#define msr_uble ((env->msr >> MSR_UBLE) & 1)
#define msr_be ((env->msr >> MSR_BE) & 1)
#define msr_de ((env->msr >> MSR_DE) & 1)
#define msr_fe1 ((env->msr >> MSR_FE1) & 1)
#define msr_al ((env->msr >> MSR_AL) & 1)
#define msr_ep ((env->msr >> MSR_EP) & 1)
#define msr_ir ((env->msr >> MSR_IR) & 1)
#define msr_dr ((env->msr >> MSR_DR) & 1)
#define msr_pe ((env->msr >> MSR_PE) & 1)
#define msr_px ((env->msr >> MSR_PX) & 1)
#define msr_pmm ((env->msr >> MSR_PMM) & 1)
#define msr_ri ((env->msr >> MSR_RI) & 1)
#define msr_le ((env->msr >> MSR_LE) & 1)
enum {
POWERPC_FLAG_NONE = 0x00000000,
......@@ -468,7 +469,7 @@ struct CPUPPCState {
/* Those ones are used in supervisor mode only */
/* machine state register */
uint8_t msr[64];
target_ulong msr;
/* temporary general purpose registers */
ppc_gpr_t tgpr[4]; /* Used to speed-up TLB assist handlers */
......@@ -639,13 +640,8 @@ void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
#endif /* !defined(CONFIG_USER_ONLY) */
target_ulong ppc_load_xer (CPUPPCState *env);
void ppc_store_xer (CPUPPCState *env, target_ulong value);
target_ulong do_load_msr (CPUPPCState *env);
int do_store_msr (CPUPPCState *env, target_ulong value);
#if defined(TARGET_PPC64)
int ppc_store_msr_32 (CPUPPCState *env, uint32_t value);
#endif
void ppc_store_msr (CPUPPCState *env, target_ulong value);
void do_compute_hflags (CPUPPCState *env);
void cpu_ppc_reset (void *opaque);
CPUPPCState *cpu_ppc_init (void);
void cpu_ppc_close(CPUPPCState *env);
......
......@@ -118,7 +118,7 @@ static always_inline int cpu_halted (CPUState *env)
{
if (!env->halted)
return 0;
if (env->msr[MSR_EE] && (env->interrupt_request & CPU_INTERRUPT_HARD)) {
if (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD)) {
env->halted = 0;
return 0;
}
......
此差异已折叠。
/*
* PowerPC emulation special registers manipulation helpers for qemu.
*
* Copyright (c) 2003-2007 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if !defined(__HELPER_REGS_H__)
#define __HELPER_REGS_H__
static always_inline target_ulong hreg_load_xer (CPUPPCState *env)
{
return (xer_so << XER_SO) |
(xer_ov << XER_OV) |
(xer_ca << XER_CA) |
(xer_bc << XER_BC) |
(xer_cmp << XER_CMP);
}
static always_inline void hreg_store_xer (CPUPPCState *env, target_ulong value)
{
xer_so = (value >> XER_SO) & 0x01;
xer_ov = (value >> XER_OV) & 0x01;
xer_ca = (value >> XER_CA) & 0x01;
xer_cmp = (value >> XER_CMP) & 0xFF;
xer_bc = (value >> XER_BC) & 0x7F;
}
/* Swap temporary saved registers with GPRs */
static always_inline void hreg_swap_gpr_tgpr (CPUPPCState *env)
{
ppc_gpr_t tmp;
tmp = env->gpr[0];
env->gpr[0] = env->tgpr[0];
env->tgpr[0] = tmp;
tmp = env->gpr[1];
env->gpr[1] = env->tgpr[1];
env->tgpr[1] = tmp;
tmp = env->gpr[2];
env->gpr[2] = env->tgpr[2];
env->tgpr[2] = tmp;
tmp = env->gpr[3];
env->gpr[3] = env->tgpr[3];
env->tgpr[3] = tmp;
}
static always_inline void hreg_compute_hflags (CPUPPCState *env)
{
target_ulong hflags_mask;
/* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */
hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) |
(1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) |
(1 << MSR_LE);
#if defined (TARGET_PPC64)
hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF);
#if defined (TARGET_PPC64H)
hflags_mask |= 1ULL << MSR_HV;
/* Precompute MMU index */
if (msr_pr == 0 && msr_hv != 0)
env->mmu_idx = 2;
else
#endif
#endif
env->mmu_idx = 1 - msr_pr;
env->hflags = env->msr & hflags_mask;
}
static always_inline int hreg_store_msr (CPUPPCState *env, target_ulong value)
{
int enter_pm, excp;
excp = 0;
value &= env->msr_mask;
#if !defined (CONFIG_USER_ONLY)
if (((value >> MSR_IR) & 1) != msr_ir ||
((value >> MSR_DR) & 1) != msr_dr) {
/* Flush all tlb when changing translation mode */
tlb_flush(env, 1);
excp = POWERPC_EXCP_NONE;
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
((value ^ env->msr) & (1 << MSR_TGPR)))) {
/* Swap temporary saved registers with GPRs */
hreg_swap_gpr_tgpr(env);
}
if (unlikely((value >> MSR_EP) & 1) != msr_ep) {
/* Change the exception prefix on PowerPC 601 */
env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
}
#endif
env->msr = value;
hreg_compute_hflags(env);
enter_pm = 0;
#if !defined (CONFIG_USER_ONLY)
if (unlikely(msr_pow == 1)) {
switch (env->excp_model) {
case POWERPC_EXCP_603:
case POWERPC_EXCP_603E:
case POWERPC_EXCP_G2:
/* Don't handle SLEEP mode: we should disable all clocks...
* No dynamic power-management.
*/
if ((env->spr[SPR_HID0] & 0x00C00000) != 0)
enter_pm = 1;
break;
case POWERPC_EXCP_604:
enter_pm = 1;
break;
case POWERPC_EXCP_7x0:
if ((env->spr[SPR_HID0] & 0x00E00000) != 0)
enter_pm = 1;
break;
default:
break;
}
if (enter_pm) {
env->halted = 1;
excp = EXCP_HALTED;
}
}
#endif
return excp;
}
#endif /* !defined(__HELPER_REGS_H__) */
......@@ -22,6 +22,7 @@
#include "config.h"
#include "exec.h"
#include "helper_regs.h"
#include "op_helper.h"
#define REG 0
......@@ -284,13 +285,13 @@ void OPPROTO op_store_xer_bc (void)
void OPPROTO op_load_xer (void)
{
do_load_xer();
T0 = hreg_load_xer(env);
RETURN();
}
void OPPROTO op_store_xer (void)
{
do_store_xer();
hreg_store_xer(env, T0);
RETURN();
}
......@@ -358,37 +359,36 @@ void OPPROTO op_store_asr (void)
void OPPROTO op_load_msr (void)
{
T0 = do_load_msr(env);
T0 = env->msr;
RETURN();
}
void OPPROTO op_store_msr (void)
{
if (do_store_msr(env, T0)) {
env->halted = 1;
do_raise_exception(EXCP_HLT);
}
do_store_msr();
RETURN();
}
void OPPROTO op_update_riee (void)
#if defined (TARGET_PPC64)
void OPPROTO op_store_msr_32 (void)
{
msr_ri = (T0 >> MSR_RI) & 1;
msr_ee = (T0 >> MSR_EE) & 1;
T0 = (env->msr & ~0xFFFFFFFFULL) | (T0 & 0xFFFFFFFF);
do_store_msr();
RETURN();
}
#endif
#if defined (TARGET_PPC64)
void OPPROTO op_store_msr_32 (void)
void OPPROTO op_update_riee (void)
{
if (ppc_store_msr_32(env, T0)) {
env->halted = 1;
do_raise_exception(EXCP_HLT);
}
/* We don't call do_store_msr here as we won't trigger
* any special case nor change hflags
*/
T0 &= (1 << MSR_RI) | (1 << MSR_EE);
env->msr &= ~(1 << MSR_RI) | (1 << MSR_EE);
env->msr |= T0;
RETURN();
}
#endif
#endif
/* SPR */
void OPPROTO op_load_spr (void)
......@@ -2517,7 +2517,12 @@ void OPPROTO op_rfmci (void)
void OPPROTO op_wrte (void)
{
msr_ee = T0 >> 16;
/* We don't call do_store_msr here as we won't trigger
* any special case nor change hflags
*/
T0 &= 1 << MSR_EE;
env->msr &= ~(1 << MSR_EE);
env->msr |= T0;
RETURN();
}
......
......@@ -19,6 +19,7 @@
*/
#include "exec.h"
#include "helper_regs.h"
#include "op_helper.h"
#define MEMSUFFIX _raw
......@@ -98,24 +99,6 @@ void do_store_cr (uint32_t mask)
}
}
void do_load_xer (void)
{
T0 = (xer_so << XER_SO) |
(xer_ov << XER_OV) |
(xer_ca << XER_CA) |
(xer_bc << XER_BC) |
(xer_cmp << XER_CMP);
}
void do_store_xer (void)
{
xer_so = (T0 >> XER_SO) & 0x01;
xer_ov = (T0 >> XER_OV) & 0x01;
xer_ca = (T0 >> XER_CA) & 0x01;
xer_cmp = (T0 >> XER_CMP) & 0xFF;
xer_bc = (T0 >> XER_BC) & 0x7F;
}
#if defined(TARGET_PPC64)
void do_store_pri (int prio)
{
......@@ -970,56 +953,63 @@ void do_fcmpo (void)
#if !defined (CONFIG_USER_ONLY)
void cpu_dump_rfi (target_ulong RA, target_ulong msr);
void do_rfi (void)
void do_store_msr (void)
{
T0 = hreg_store_msr(env, T0);
if (T0 != 0) {
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
do_raise_exception(T0);
}
}
static always_inline void __do_rfi (target_ulong nip, target_ulong msr,
target_ulong msrm, int keep_msrh)
{
#if defined(TARGET_PPC64)
if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) {
env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003);
do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
if (msr & (1ULL << MSR_SF)) {
nip = (uint64_t)nip;
msr &= (uint64_t)msrm;
} else {
env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
ppc_store_msr_32(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
nip = (uint32_t)nip;
msr = (uint32_t)(msr & msrm);
if (keep_msrh)
msr |= env->msr & ~((uint64_t)0xFFFFFFFF);
}
#else
env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
nip = (uint32_t)nip;
msr &= (uint32_t)msrm;
#endif
/* XXX: beware: this is false if VLE is supported */
env->nip = nip & ~((target_ulong)0x00000003);
hreg_store_msr(env, msr);
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
cpu_dump_rfi(env->nip, env->msr);
#endif
/* No need to raise an exception here,
* as rfi is always the last insn of a TB
*/
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
}
void do_rfi (void)
{
__do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
~((target_ulong)0xFFFF0000), 1);
}
#if defined(TARGET_PPC64)
void do_rfid (void)
{
if (env->spr[SPR_SRR1] & (1ULL << MSR_SF)) {
env->nip = (uint64_t)(env->spr[SPR_SRR0] & ~0x00000003);
do_store_msr(env, (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
} else {
env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003);
do_store_msr(env, (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL));
}
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
__do_rfi(env->spr[SPR_SRR0], env->spr[SPR_SRR1],
~((target_ulong)0xFFFF0000), 0);
}
#endif
#if defined(TARGET_PPC64H)
void do_hrfid (void)
{
if (env->spr[SPR_HSRR1] & (1ULL << MSR_SF)) {
env->nip = (uint64_t)(env->spr[SPR_HSRR0] & ~0x00000003);
do_store_msr(env, (uint64_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
} else {
env->nip = (uint32_t)(env->spr[SPR_HSRR0] & ~0x00000003);
do_store_msr(env, (uint32_t)(env->spr[SPR_HSRR1] & ~0xFFFF0000UL));
}
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
__do_rfi(env->spr[SPR_HSRR0], env->spr[SPR_HSRR1],
~((target_ulong)0xFFFF0000), 0);
}
#endif
#endif
......@@ -1214,13 +1204,7 @@ void do_POWER_rac (void)
void do_POWER_rfsvc (void)
{
env->nip = env->lr & ~0x00000003UL;
T0 = env->ctr & 0x0000FFFFUL;
do_store_msr(env, T0);
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request |= CPU_INTERRUPT_EXITTB;
__do_rfi(env->lr, env->ctr, 0x0000FFFF, 0);
}
/* PowerPC 601 BAT management helper */
......@@ -1332,63 +1316,26 @@ void do_store_dcr (void)
#if !defined(CONFIG_USER_ONLY)
void do_40x_rfci (void)
{
env->nip = env->spr[SPR_40x_SRR2];
do_store_msr(env, env->spr[SPR_40x_SRR3] & ~0xFFFF0000);
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request = CPU_INTERRUPT_EXITTB;
__do_rfi(env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3],
~((target_ulong)0xFFFF0000), 0);
}
void do_rfci (void)
{
#if defined(TARGET_PPC64)
if (env->spr[SPR_BOOKE_CSRR1] & (1 << MSR_CM)) {
env->nip = (uint64_t)env->spr[SPR_BOOKE_CSRR0];
} else
#endif
{
env->nip = (uint32_t)env->spr[SPR_BOOKE_CSRR0];
}
do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_CSRR1] & ~0x3FFF0000);
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request = CPU_INTERRUPT_EXITTB;
__do_rfi(env->spr[SPR_BOOKE_CSRR0], SPR_BOOKE_CSRR1,
~((target_ulong)0x3FFF0000), 0);
}
void do_rfdi (void)
{
#if defined(TARGET_PPC64)
if (env->spr[SPR_BOOKE_DSRR1] & (1 << MSR_CM)) {
env->nip = (uint64_t)env->spr[SPR_BOOKE_DSRR0];
} else
#endif
{
env->nip = (uint32_t)env->spr[SPR_BOOKE_DSRR0];
}
do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_DSRR1] & ~0x3FFF0000);
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request = CPU_INTERRUPT_EXITTB;
__do_rfi(env->spr[SPR_BOOKE_DSRR0], SPR_BOOKE_DSRR1,
~((target_ulong)0x3FFF0000), 0);
}
void do_rfmci (void)
{
#if defined(TARGET_PPC64)
if (env->spr[SPR_BOOKE_MCSRR1] & (1 << MSR_CM)) {
env->nip = (uint64_t)env->spr[SPR_BOOKE_MCSRR0];
} else
#endif
{
env->nip = (uint32_t)env->spr[SPR_BOOKE_MCSRR0];
}
do_store_msr(env, (uint32_t)env->spr[SPR_BOOKE_MCSRR1] & ~0x3FFF0000);
#if defined (DEBUG_OP)
cpu_dump_rfi(env->nip, do_load_msr(env));
#endif
env->interrupt_request = CPU_INTERRUPT_EXITTB;
__do_rfi(env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1,
~((target_ulong)0x3FFF0000), 0);
}
void do_load_403_pb (int num)
......
......@@ -57,8 +57,6 @@ void do_print_mem_EA (target_ulong EA);
/* Registers load and stores */
void do_load_cr (void);
void do_store_cr (uint32_t mask);
void do_load_xer (void);
void do_store_xer (void);
#if defined(TARGET_PPC64)
void do_store_pri (int prio);
#endif
......@@ -129,6 +127,7 @@ void do_tw (int flags);
void do_td (int flags);
#endif
#if !defined(CONFIG_USER_ONLY)
void do_store_msr (void);
void do_rfi (void);
#if defined(TARGET_PPC64)
void do_rfid (void);
......
......@@ -6538,18 +6538,10 @@ GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
GEN_OPCODE_MARK(end);
#include "translate_init.c"
#include "helper_regs.h"
/*****************************************************************************/
/* Misc PowerPC helpers */
static always_inline uint32_t load_xer (CPUState *env)
{
return (xer_so << XER_SO) |
(xer_ov << XER_OV) |
(xer_ca << XER_CA) |
(xer_bc << XER_BC) |
(xer_cmp << XER_CMP);
}
void cpu_dump_state (CPUState *env, FILE *f,
int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
int flags)
......@@ -6566,8 +6558,8 @@ void cpu_dump_state (CPUState *env, FILE *f,
int i;
cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
env->nip, env->lr, env->ctr);
cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX " idx %d\n",
env->nip, env->lr, env->ctr, env->mmu_idx);
cpu_fprintf(f, "MSR " REGX FILL " XER %08x "
#if !defined(NO_TIMER_DUMP)
"TB %08x %08x "
......@@ -6576,7 +6568,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
#endif
#endif
"\n",
do_load_msr(env), load_xer(env)
env->msr, hreg_load_xer(env)
#if !defined(NO_TIMER_DUMP)
, cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
#if !defined(CONFIG_USER_ONLY)
......@@ -6753,7 +6745,7 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "----------------\n");
fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
ctx.nip, 1 - msr_pr, msr_ir);
ctx.nip, supervisor, (int)msr_ir);
}
#endif
ctx.opcode = ldl_code(ctx.nip);
......@@ -6787,12 +6779,12 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
fprintf(logfile, "invalid/unsupported opcode: "
"%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
opc1(ctx.opcode), opc2(ctx.opcode),
opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
} else {
printf("invalid/unsupported opcode: "
"%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
opc1(ctx.opcode), opc2(ctx.opcode),
opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
}
} else {
if (unlikely((ctx.opcode & handler->inval) != 0)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册