提交 d9bce9d9 编写于 作者: J j_mayer

Make it safe to use 64 bits GPR and/or 64 bits host registers.

For "symetry", add 64 bits versions of all modified functions.
As a side effect, add a lot of code provision for PowerPC 64 support.
Move overflow and carry checks in common routines for simple cases.
Add isel and popcntb instructions from PowerPC 2.03 specification.
Remove remaining micro-operations helpers prototypes from op.c.
Fix XER_BC field to be 7 bits long.
Add power management support for PowerPC 603 & 604.
Fix compilation warnings.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2482 c046a42c-6fe2-441c-8c8c-71466251a162
上级 5fd46862
......@@ -365,6 +365,8 @@ enum {
PPC_E500_VECTOR = 0x20000000,
/* PowerPC 4xx dedicated instructions */
PPC_4xx_COMMON = 0x40000000,
/* PowerPC 2.03 specification extensions */
PPC_203 = 0x80000000,
};
/* CPU run-time flags (MMU and exception model) */
......@@ -385,6 +387,8 @@ enum {
PPC_FLAGS_MMU_403 = 0x00000005,
/* Freescale e500 MMU model */
PPC_FLAGS_MMU_e500 = 0x00000006,
/* BookE MMU model */
PPC_FLAGS_MMU_BOOKE = 0x00000007,
/* Exception model */
PPC_FLAGS_EXCP_MASK = 0x000000F0,
/* Standard PowerPC exception model */
......@@ -407,6 +411,8 @@ enum {
PPC_FLAGS_EXCP_74xx = 0x00000080,
/* PowerPC 970 exception model */
PPC_FLAGS_EXCP_970 = 0x00000090,
/* BookE exception model */
PPC_FLAGS_EXCP_BOOKE = 0x000000A0,
};
#define PPC_MMU(env) (env->flags & PPC_FLAGS_MMU_MASK)
......@@ -437,11 +443,11 @@ enum {
/* PowerPC 440 */
#define PPC_INSNS_440 (PPC_INSNS_EMB | PPC_CACHE_OPT | PPC_BOOKE | \
PPC_4xx_COMMON | PPC_405_MAC | PPC_440_SPEC)
#define PPC_FLAGS_440 (PPC_FLAGS_TODO)
#define PPC_FLAGS_440 (PPC_FLAGS_MMU_BOOKE | PPC_FLAGS_EXCP_BOOKE)
/* Generic BookE PowerPC */
#define PPC_INSNS_BOOKE (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \
PPC_FLOAT | PPC_FLOAT_OPT | PPC_CACHE_OPT)
#define PPC_FLAGS_BOOKE (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x)
#define PPC_FLAGS_BOOKE (PPC_FLAGS_MMU_BOOKE | PPC_FLAGS_EXCP_BOOKE)
/* e500 core */
#define PPC_INSNS_E500 (PPC_INSNS_EMB | PPC_BOOKE | PPC_MEM_EIEIO | \
PPC_CACHE_OPT | PPC_E500_VECTOR)
......@@ -502,7 +508,6 @@ typedef struct ppc_dcr_t ppc_dcr_t;
typedef struct ppc_avr_t ppc_avr_t;
typedef struct ppc_tlb_t ppc_tlb_t;
/* SPR access micro-ops generations callbacks */
struct ppc_spr_t {
void (*uea_read)(void *opaque, int spr_num);
......@@ -619,6 +624,8 @@ struct CPUPPCState {
*/
target_ulong t0, t1, t2;
#endif
ppc_avr_t t0_avr, t1_avr, t2_avr;
/* general purpose registers */
ppc_gpr_t gpr[32];
/* LR */
......@@ -674,6 +681,9 @@ struct CPUPPCState {
/* Altivec registers */
ppc_avr_t avr[32];
uint32_t vscr;
/* SPE registers */
ppc_gpr_t spe_acc;
uint32_t spe_fscr;
/* Internal devices resources */
/* Time base and decrementer */
......@@ -762,8 +772,10 @@ void do_store_dbatu (CPUPPCState *env, int nr, target_ulong value);
void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value);
target_ulong do_load_sdr1 (CPUPPCState *env);
void do_store_sdr1 (CPUPPCState *env, target_ulong value);
target_ulong do_load_asr (CPUPPCState *env);
void do_store_asr (CPUPPCState *env, target_ulong value);
#if defined(TARGET_PPC64)
target_ulong ppc_load_asr (CPUPPCState *env);
void ppc_store_asr (CPUPPCState *env, target_ulong value);
#endif
target_ulong do_load_sr (CPUPPCState *env, int srnum);
void do_store_sr (CPUPPCState *env, int srnum, target_ulong value);
#endif
......@@ -771,6 +783,7 @@ uint32_t ppc_load_xer (CPUPPCState *env);
void ppc_store_xer (CPUPPCState *env, uint32_t value);
target_ulong do_load_msr (CPUPPCState *env);
void do_store_msr (CPUPPCState *env, target_ulong value);
void ppc_store_msr32 (CPUPPCState *env, uint32_t value);
void do_compute_hflags (CPUPPCState *env);
......@@ -787,6 +800,16 @@ void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value);
uint32_t cpu_ppc_load_decr (CPUPPCState *env);
void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env);
uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env);
#if !defined(CONFIG_USER_ONLY)
void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value);
void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value);
target_ulong load_40x_pit (CPUPPCState *env);
void store_40x_pit (CPUPPCState *env, target_ulong val);
void store_booke_tcr (CPUPPCState *env, target_ulong val);
void store_booke_tsr (CPUPPCState *env, target_ulong val);
#endif
#endif
#define TARGET_PAGE_BITS 12
......
......@@ -34,19 +34,25 @@ register struct CPUPPCState *env asm(AREG0);
#define T1 (env->t1)
#define T2 (env->t2)
#else
/* This may be more efficient if HOST_LONG_BITS > TARGET_LONG_BITS
* To be set to one when we'll be sure it does not cause bugs....
*/
#if 0
register unsigned long T0 asm(AREG1);
register unsigned long T1 asm(AREG2);
register unsigned long T2 asm(AREG3);
#else
register target_ulong T0 asm(AREG1);
register target_ulong T1 asm(AREG2);
register target_ulong T2 asm(AREG3);
#endif
/* We may, sometime, need 64 bits registers on 32 bits target */
#if defined(TARGET_PPC64) || (HOST_LONG_BITS == 64)
#define T0_64 T0
#define T1_64 T0
#define T2_64 T0
#else
/* no registers can be used */
#define T0_64 (env->t0)
#define T1_64 (env->t1)
#define T2_64 (env->t2)
#endif
/* Provision for Altivec */
#define T0_avr (env->t0_avr)
#define T1_avr (env->t1_avr)
#define T2_avr (env->t2_avr)
/* XXX: to clean: remove this mess */
#define PARAM(n) ((uint32_t)PARAM##n)
......
......@@ -37,12 +37,12 @@
/*****************************************************************************/
/* PowerPC MMU emulation */
#if defined(CONFIG_USER_ONLY)
#if defined(CONFIG_USER_ONLY)
int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
int is_user, int is_softmmu)
{
int exception, error_code;
if (rw == 2) {
exception = EXCP_ISI;
error_code = 0;
......@@ -277,7 +277,7 @@ static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
ppc_tlb_t *tlb;
int nr, best, way;
int ret;
best = -1;
ret = -1; /* No TLB found */
for (way = 0; way < env->nb_ways; way++) {
......@@ -672,7 +672,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
if (loglevel > 0) {
fprintf(logfile, "%s\n", __func__);
}
#endif
#endif
if ((access_type == ACCESS_CODE && msr_ir == 0) ||
(access_type != ACCESS_CODE && msr_dr == 0)) {
/* No address translation */
......@@ -693,7 +693,7 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
__func__, eaddr, ctx->raddr);
}
#endif
return ret;
}
......@@ -715,7 +715,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
int exception = 0, error_code = 0;
int access_type;
int ret = 0;
if (rw == 2) {
/* code access */
rw = 0;
......@@ -975,6 +975,21 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
/*****************************************************************************/
/* Special registers manipulation */
#if defined(TARGET_PPC64)
target_ulong ppc_load_asr (CPUPPCState *env)
{
return env->asr;
}
void ppc_store_asr (CPUPPCState *env, target_ulong value)
{
if (env->asr != value) {
env->asr = value;
tlb_flush(env, 1);
}
}
#endif
target_ulong do_load_sdr1 (CPUPPCState *env)
{
return env->sdr1;
......@@ -1039,7 +1054,7 @@ void ppc_store_xer (CPUPPCState *env, uint32_t value)
xer_ov = (value >> XER_OV) & 0x01;
xer_ca = (value >> XER_CA) & 0x01;
xer_cmp = (value >> XER_CMP) & 0xFF;
xer_bc = (value >> XER_BC) & 0x3F;
xer_bc = (value >> XER_BC) & 0x7F;
}
/* Swap temporary saved registers with GPRs */
......@@ -1066,34 +1081,34 @@ target_ulong do_load_msr (CPUPPCState *env)
{
return
#if defined (TARGET_PPC64)
(msr_sf << MSR_SF) |
(msr_isf << MSR_ISF) |
(msr_hv << MSR_HV) |
((target_ulong)msr_sf << MSR_SF) |
((target_ulong)msr_isf << MSR_ISF) |
((target_ulong)msr_hv << MSR_HV) |
#endif
(msr_ucle << MSR_UCLE) |
(msr_vr << MSR_VR) | /* VR / SPE */
(msr_ap << MSR_AP) |
(msr_sa << MSR_SA) |
(msr_key << MSR_KEY) |
(msr_pow << MSR_POW) | /* POW / WE */
(msr_tlb << MSR_TLB) | /* TLB / TGPE / CE */
(msr_ile << MSR_ILE) |
(msr_ee << MSR_EE) |
(msr_pr << MSR_PR) |
(msr_fp << MSR_FP) |
(msr_me << MSR_ME) |
(msr_fe0 << MSR_FE0) |
(msr_se << MSR_SE) | /* SE / DWE / UBLE */
(msr_be << MSR_BE) | /* BE / DE */
(msr_fe1 << MSR_FE1) |
(msr_al << MSR_AL) |
(msr_ip << MSR_IP) |
(msr_ir << MSR_IR) | /* IR / IS */
(msr_dr << MSR_DR) | /* DR / DS */
(msr_pe << MSR_PE) | /* PE / EP */
(msr_px << MSR_PX) | /* PX / PMM */
(msr_ri << MSR_RI) |
(msr_le << MSR_LE);
((target_ulong)msr_ucle << MSR_UCLE) |
((target_ulong)msr_vr << MSR_VR) | /* VR / SPE */
((target_ulong)msr_ap << MSR_AP) |
((target_ulong)msr_sa << MSR_SA) |
((target_ulong)msr_key << MSR_KEY) |
((target_ulong)msr_pow << MSR_POW) | /* POW / WE */
((target_ulong)msr_tlb << MSR_TLB) | /* TLB / TGPE / CE */
((target_ulong)msr_ile << MSR_ILE) |
((target_ulong)msr_ee << MSR_EE) |
((target_ulong)msr_pr << MSR_PR) |
((target_ulong)msr_fp << MSR_FP) |
((target_ulong)msr_me << MSR_ME) |
((target_ulong)msr_fe0 << MSR_FE0) |
((target_ulong)msr_se << MSR_SE) | /* SE / DWE / UBLE */
((target_ulong)msr_be << MSR_BE) | /* BE / DE */
((target_ulong)msr_fe1 << MSR_FE1) |
((target_ulong)msr_al << MSR_AL) |
((target_ulong)msr_ip << MSR_IP) |
((target_ulong)msr_ir << MSR_IR) | /* IR / IS */
((target_ulong)msr_dr << MSR_DR) | /* DR / DS */
((target_ulong)msr_pe << MSR_PE) | /* PE / EP */
((target_ulong)msr_px << MSR_PX) | /* PX / PMM */
((target_ulong)msr_ri << MSR_RI) |
((target_ulong)msr_le << MSR_LE);
}
void do_store_msr (CPUPPCState *env, target_ulong value)
......@@ -1156,6 +1171,17 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
enter_pm = 0;
switch (PPC_EXCP(env)) {
case PPC_FLAGS_EXCP_603:
/* Don't handle SLEEP mode: we should disable all clocks...
* No dynamic power-management.
*/
if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00C00000) != 0)
enter_pm = 1;
break;
case PPC_FLAGS_EXCP_604:
if (msr_pow == 1)
enter_pm = 1;
break;
case PPC_FLAGS_EXCP_7x0:
if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
enter_pm = 1;
......@@ -1171,15 +1197,22 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
}
}
#if defined(TARGET_PPC64)
void ppc_store_msr_32 (CPUPPCState *env, target_ulong value)
{
do_store_msr(env, (uint32_t)value);
}
#endif
void do_compute_hflags (CPUPPCState *env)
{
/* Compute current hflags */
env->hflags = (msr_pr << MSR_PR) | (msr_le << MSR_LE) |
(msr_fp << MSR_FP) | (msr_fe0 << MSR_FE0) | (msr_fe1 << MSR_FE1) |
(msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
(msr_vr << MSR_VR) | (msr_ap << MSR_AP) | (msr_sa << MSR_SA) |
(msr_se << MSR_SE) | (msr_be << MSR_BE);
#if defined (TARGET_PPC64)
env->hflags |= (msr_sf << MSR_SF) | (msr_hv << MSR_HV);
env->hflags |= (msr_sf << (MSR_SF - 32)) | (msr_hv << (MSR_HV - 32));
#endif
}
......@@ -1193,8 +1226,8 @@ void do_interrupt (CPUState *env)
#else /* defined (CONFIG_USER_ONLY) */
static void dump_syscall(CPUState *env)
{
fprintf(logfile, "syscall r0=0x%08x r3=0x%08x r4=0x%08x "
"r5=0x%08x r6=0x%08x nip=0x%08x\n",
fprintf(logfile, "syscall r0=0x" REGX " r3=0x" REGX " r4=0x" REGX
" r5=0x" REGX " r6=0x" REGX " nip=0x" REGX "\n",
env->gpr[0], env->gpr[3], env->gpr[4],
env->gpr[5], env->gpr[6], env->nip);
}
......
此差异已折叠。
此差异已折叠。
......@@ -35,6 +35,17 @@ void glue(do_POWER2_lfq_le, MEMSUFFIX) (void);
void glue(do_POWER2_stfq, MEMSUFFIX) (void);
void glue(do_POWER2_stfq_le, MEMSUFFIX) (void);
#if defined(TARGET_PPC64)
void glue(do_lsw_64, MEMSUFFIX) (int dst);
void glue(do_lsw_le_64, MEMSUFFIX) (int dst);
void glue(do_stsw_64, MEMSUFFIX) (int src);
void glue(do_stsw_le_64, MEMSUFFIX) (int src);
void glue(do_lmw_64, MEMSUFFIX) (int dst);
void glue(do_lmw_le_64, MEMSUFFIX) (int dst);
void glue(do_stmw_64, MEMSUFFIX) (int src);
void glue(do_stmw_le_64, MEMSUFFIX) (int src);
#endif
#else
/* Registers load and stores */
......@@ -46,23 +57,34 @@ void do_load_fpscr (void);
void do_store_fpscr (uint32_t mask);
/* Integer arithmetic helpers */
void do_addo (void);
void do_addco (void);
void do_adde (void);
void do_addeo (void);
void do_addmeo (void);
void do_addzeo (void);
void do_divwo (void);
void do_divwuo (void);
void do_mullwo (void);
void do_nego (void);
void do_subfo (void);
void do_subfco (void);
void do_subfe (void);
void do_subfeo (void);
void do_subfmeo (void);
void do_subfzeo (void);
void do_sraw(void);
void do_sraw (void);
#if defined(TARGET_PPC64)
void do_adde_64 (void);
void do_addmeo_64 (void);
void do_imul64 (uint64_t *tl, uint64_t *th);
void do_mul64 (uint64_t *tl, uint64_t *th);
void do_divdo (void);
void do_divduo (void);
void do_mulldo (void);
void do_nego_64 (void);
void do_subfe_64 (void);
void do_subfmeo_64 (void);
void do_subfzeo_64 (void);
void do_srad (void);
#endif
void do_popcntb (void);
#if defined(TARGET_PPC64)
void do_popcntb_64 (void);
#endif
/* Floating-point arithmetic helpers */
void do_fsqrt (void);
......@@ -77,13 +99,29 @@ void do_fcmpu (void);
void do_fcmpo (void);
void do_tw (int flags);
#if defined(TARGET_PPC64)
void do_td (int flags);
#endif
void do_icbi (void);
#if defined(TARGET_PPC64)
void do_icbi_64 (void);
#endif
#if !defined(CONFIG_USER_ONLY)
void do_rfi (void);
#if defined(TARGET_PPC64)
void do_rfi_32 (void);
#endif
void do_tlbia (void);
void do_tlbie (void);
#if defined(TARGET_PPC64)
void do_tlbie_64 (void);
#endif
void do_load_6xx_tlb (int is_code);
#if defined(TARGET_PPC64)
void do_slbia (void);
void do_slbie (void);
#endif
#endif
/* POWER / PowerPC 601 specific helpers */
......
/*
* PowerPC emulation micro-operations helpers for qemu.
*
*
* Copyright (c) 2003-2007 Jocelyn Mayer
*
* This library is free software; you can redistribute it and/or
......@@ -37,98 +37,210 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, target_ulong data)
void glue(do_lmw, MEMSUFFIX) (int dst)
{
for (; dst < 32; dst++, T0 += 4) {
ugpr(dst) = glue(ldl, MEMSUFFIX)(T0);
ugpr(dst) = glue(ldl, MEMSUFFIX)((uint32_t)T0);
}
}
#if defined(TARGET_PPC64)
void glue(do_lmw_64, MEMSUFFIX) (int dst)
{
for (; dst < 32; dst++, T0 += 4) {
ugpr(dst) = glue(ldl, MEMSUFFIX)((uint64_t)T0);
}
}
#endif
void glue(do_stmw, MEMSUFFIX) (int src)
{
for (; src < 32; src++, T0 += 4) {
glue(stl, MEMSUFFIX)(T0, ugpr(src));
glue(stl, MEMSUFFIX)((uint32_t)T0, ugpr(src));
}
}
#if defined(TARGET_PPC64)
void glue(do_stmw_64, MEMSUFFIX) (int src)
{
for (; src < 32; src++, T0 += 4) {
glue(stl, MEMSUFFIX)((uint64_t)T0, ugpr(src));
}
}
#endif
void glue(do_lmw_le, MEMSUFFIX) (int dst)
{
for (; dst < 32; dst++, T0 += 4) {
ugpr(dst) = glue(ld32r, MEMSUFFIX)(T0);
ugpr(dst) = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
}
}
#if defined(TARGET_PPC64)
void glue(do_lmw_le_64, MEMSUFFIX) (int dst)
{
for (; dst < 32; dst++, T0 += 4) {
ugpr(dst) = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
}
}
#endif
void glue(do_stmw_le, MEMSUFFIX) (int src)
{
for (; src < 32; src++, T0 += 4) {
glue(st32r, MEMSUFFIX)(T0, ugpr(src));
glue(st32r, MEMSUFFIX)((uint32_t)T0, ugpr(src));
}
}
#if defined(TARGET_PPC64)
void glue(do_stmw_le_64, MEMSUFFIX) (int src)
{
for (; src < 32; src++, T0 += 4) {
glue(st32r, MEMSUFFIX)((uint64_t)T0, ugpr(src));
}
}
#endif
void glue(do_lsw, MEMSUFFIX) (int dst)
{
uint32_t tmp;
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
ugpr(dst++) = glue(ldl, MEMSUFFIX)(T0);
ugpr(dst++) = glue(ldl, MEMSUFFIX)((uint32_t)T0);
if (unlikely(dst == 32))
dst = 0;
}
if (unlikely(T1 != 0)) {
tmp = 0;
for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
tmp |= glue(ldub, MEMSUFFIX)(T0) << sh;
tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh;
}
ugpr(dst) = tmp;
}
}
#if defined(TARGET_PPC64)
void glue(do_lsw_64, MEMSUFFIX) (int dst)
{
uint32_t tmp;
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
ugpr(dst++) = glue(ldl, MEMSUFFIX)((uint64_t)T0);
if (unlikely(dst == 32))
dst = 0;
}
if (unlikely(T1 != 0)) {
tmp = 0;
for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh;
}
ugpr(dst) = tmp;
}
}
#endif
void glue(do_stsw, MEMSUFFIX) (int src)
{
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
glue(stl, MEMSUFFIX)(T0, ugpr(src++));
glue(stl, MEMSUFFIX)((uint32_t)T0, ugpr(src++));
if (unlikely(src == 32))
src = 0;
}
if (unlikely(T1 != 0)) {
for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF);
glue(stb, MEMSUFFIX)((uint32_t)T0, (ugpr(src) >> sh) & 0xFF);
}
}
#if defined(TARGET_PPC64)
void glue(do_stsw_64, MEMSUFFIX) (int src)
{
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
glue(stl, MEMSUFFIX)((uint64_t)T0, ugpr(src++));
if (unlikely(src == 32))
src = 0;
}
if (unlikely(T1 != 0)) {
for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
glue(stb, MEMSUFFIX)((uint64_t)T0, (ugpr(src) >> sh) & 0xFF);
}
}
#endif
void glue(do_lsw_le, MEMSUFFIX) (int dst)
{
uint32_t tmp;
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
ugpr(dst++) = glue(ld32r, MEMSUFFIX)(T0);
ugpr(dst++) = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
if (unlikely(dst == 32))
dst = 0;
}
if (unlikely(T1 != 0)) {
tmp = 0;
for (sh = 0; T1 > 0; T1--, T0++, sh += 8) {
tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh;
}
ugpr(dst) = tmp;
}
}
#if defined(TARGET_PPC64)
void glue(do_lsw_le_64, MEMSUFFIX) (int dst)
{
uint32_t tmp;
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
ugpr(dst++) = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
if (unlikely(dst == 32))
dst = 0;
}
if (unlikely(T1 != 0)) {
tmp = 0;
for (sh = 0; T1 > 0; T1--, T0++, sh += 8) {
tmp |= glue(ldub, MEMSUFFIX)(T0) << sh;
tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh;
}
ugpr(dst) = tmp;
}
}
#endif
void glue(do_stsw_le, MEMSUFFIX) (int src)
{
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
glue(st32r, MEMSUFFIX)(T0, ugpr(src++));
glue(st32r, MEMSUFFIX)((uint32_t)T0, ugpr(src++));
if (unlikely(src == 32))
src = 0;
}
if (unlikely(T1 != 0)) {
for (sh = 0; T1 > 0; T1--, T0++, sh += 8)
glue(stb, MEMSUFFIX)((uint32_t)T0, (ugpr(src) >> sh) & 0xFF);
}
}
#if defined(TARGET_PPC64)
void glue(do_stsw_le_64, MEMSUFFIX) (int src)
{
int sh;
for (; T1 > 3; T1 -= 4, T0 += 4) {
glue(st32r, MEMSUFFIX)((uint64_t)T0, ugpr(src++));
if (unlikely(src == 32))
src = 0;
}
if (unlikely(T1 != 0)) {
for (sh = 0; T1 > 0; T1--, T0++, sh += 8)
glue(stb, MEMSUFFIX)(T0, (ugpr(src) >> sh) & 0xFF);
glue(stb, MEMSUFFIX)((uint64_t)T0, (ugpr(src) >> sh) & 0xFF);
}
}
#endif
/* PPC 601 specific instructions (POWER bridge) */
// XXX: to be tested
......@@ -139,7 +251,7 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
d = 24;
reg = dest;
for (i = 0; i < T1; i++) {
c = glue(ldub, MEMSUFFIX)(T0++);
c = glue(ldub, MEMSUFFIX)((uint32_t)T0++);
/* ra (if not 0) and rb are never modified */
if (likely(reg != rb && (ra == 0 || reg != ra))) {
ugpr(reg) = (ugpr(reg) & ~(0xFF << d)) | (c << d);
......@@ -160,8 +272,8 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
/* XXX: TAGs are not managed */
void glue(do_POWER2_lfq, MEMSUFFIX) (void)
{
FT0 = glue(ldfq, MEMSUFFIX)(T0);
FT1 = glue(ldfq, MEMSUFFIX)(T0 + 4);
FT0 = glue(ldfq, MEMSUFFIX)((uint32_t)T0);
FT1 = glue(ldfq, MEMSUFFIX)((uint32_t)(T0 + 4));
}
static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
......@@ -186,14 +298,14 @@ static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
void glue(do_POWER2_lfq_le, MEMSUFFIX) (void)
{
FT0 = glue(ldfqr, MEMSUFFIX)(T0 + 4);
FT1 = glue(ldfqr, MEMSUFFIX)(T0);
FT0 = glue(ldfqr, MEMSUFFIX)((uint32_t)(T0 + 4));
FT1 = glue(ldfqr, MEMSUFFIX)((uint32_t)T0);
}
void glue(do_POWER2_stfq, MEMSUFFIX) (void)
{
glue(stfq, MEMSUFFIX)(T0, FT0);
glue(stfq, MEMSUFFIX)(T0 + 4, FT1);
glue(stfq, MEMSUFFIX)((uint32_t)T0, FT0);
glue(stfq, MEMSUFFIX)((uint32_t)(T0 + 4), FT1);
}
static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
......@@ -217,8 +329,8 @@ static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
void glue(do_POWER2_stfq_le, MEMSUFFIX) (void)
{
glue(stfqr, MEMSUFFIX)(T0 + 4, FT0);
glue(stfqr, MEMSUFFIX)(T0, FT1);
glue(stfqr, MEMSUFFIX)((uint32_t)(T0 + 4), FT0);
glue(stfqr, MEMSUFFIX)((uint32_t)T0, FT1);
}
#undef MEMSUFFIX
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册