mirror of https://github.com/xemu-project/xemu.git
Allow NWINDOWS selection (CPU feature with model specific defaults)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4690 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
96d1912622
commit
1a14026e11
|
@ -404,7 +404,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size,
|
|||
qemu_register_reset(secondary_cpu_reset, env);
|
||||
env->halted = 1;
|
||||
}
|
||||
register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
|
||||
register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
|
||||
cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
|
||||
env->prom_addr = hwdef->slavio_base;
|
||||
}
|
||||
|
@ -579,7 +579,7 @@ static void sun4c_hw_init(const struct hwdef *hwdef, ram_addr_t RAM_size,
|
|||
cpu_sparc_set_id(env, 0);
|
||||
|
||||
qemu_register_reset(main_cpu_reset, env);
|
||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
||||
register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
|
||||
cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
|
||||
env->prom_addr = hwdef->slavio_base;
|
||||
|
||||
|
@ -1391,7 +1391,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
|
|||
qemu_register_reset(secondary_cpu_reset, env);
|
||||
env->halted = 1;
|
||||
}
|
||||
register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
|
||||
register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
|
||||
cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
|
||||
env->prom_addr = hwdef->slavio_base;
|
||||
}
|
||||
|
|
|
@ -260,7 +260,7 @@ static void sun4u_init(ram_addr_t RAM_size, int vga_ram_size,
|
|||
bh = qemu_bh_new(hstick_irq, env);
|
||||
env->hstick = ptimer_init(bh);
|
||||
ptimer_set_period(env->hstick, 1ULL);
|
||||
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
|
||||
register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
|
||||
qemu_register_reset(main_cpu_reset, env);
|
||||
main_cpu_reset(env);
|
||||
|
||||
|
|
|
@ -626,11 +626,11 @@ void cpu_loop(CPUARMState *env)
|
|||
can be found at http://www.sics.se/~psm/sparcstack.html */
|
||||
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
|
||||
{
|
||||
index = (index + cwp * 16) & (16 * NWINDOWS - 1);
|
||||
index = (index + cwp * 16) % (16 * env->nwindows);
|
||||
/* wrap handling : if cwp is on the last window, then we use the
|
||||
registers 'after' the end */
|
||||
if (index < 8 && env->cwp == (NWINDOWS - 1))
|
||||
index += (16 * NWINDOWS);
|
||||
if (index < 8 && env->cwp == env->nwindows - 1)
|
||||
index += 16 * env->nwindows;
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -656,12 +656,12 @@ static void save_window(CPUSPARCState *env)
|
|||
{
|
||||
#ifndef TARGET_SPARC64
|
||||
unsigned int new_wim;
|
||||
new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &
|
||||
((1LL << NWINDOWS) - 1);
|
||||
save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
|
||||
new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
|
||||
((1LL << env->nwindows) - 1);
|
||||
save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
|
||||
env->wim = new_wim;
|
||||
#else
|
||||
save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
|
||||
save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
|
||||
env->cansave++;
|
||||
env->canrestore--;
|
||||
#endif
|
||||
|
@ -672,11 +672,11 @@ static void restore_window(CPUSPARCState *env)
|
|||
unsigned int new_wim, i, cwp1;
|
||||
abi_ulong sp_ptr;
|
||||
|
||||
new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
|
||||
((1LL << NWINDOWS) - 1);
|
||||
new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
|
||||
((1LL << env->nwindows) - 1);
|
||||
|
||||
/* restore the invalid window */
|
||||
cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
|
||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
||||
sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
|
||||
#if defined(DEBUG_WIN)
|
||||
printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
|
||||
|
@ -690,8 +690,8 @@ static void restore_window(CPUSPARCState *env)
|
|||
env->wim = new_wim;
|
||||
#ifdef TARGET_SPARC64
|
||||
env->canrestore++;
|
||||
if (env->cleanwin < NWINDOWS - 1)
|
||||
env->cleanwin++;
|
||||
if (env->cleanwin < env->nwindows - 1)
|
||||
env->cleanwin++;
|
||||
env->cansave--;
|
||||
#endif
|
||||
}
|
||||
|
@ -703,14 +703,14 @@ static void flush_windows(CPUSPARCState *env)
|
|||
offset = 1;
|
||||
for(;;) {
|
||||
/* if restore would invoke restore_window(), then we can stop */
|
||||
cwp1 = (env->cwp + offset) & (NWINDOWS - 1);
|
||||
cwp1 = cpu_cwp_inc(env, env->cwp + offset);
|
||||
if (env->wim & (1 << cwp1))
|
||||
break;
|
||||
save_window_offset(env, cwp1);
|
||||
offset++;
|
||||
}
|
||||
/* set wim so that restore will reload the registers */
|
||||
cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
|
||||
cwp1 = cpu_cwp_inc(env, env->cwp + 1);
|
||||
env->wim = 1 << cwp1;
|
||||
#if defined(DEBUG_WIN)
|
||||
printf("flush_windows: nb=%d\n", offset - 1);
|
||||
|
|
|
@ -6,7 +6,6 @@ CPU common:
|
|||
slot next page)
|
||||
- Atomical instructions
|
||||
- CPU features should match real CPUs (also ASI selection)
|
||||
- Allow choosing of NWINDOWS (CPU model specific and as a CPU feature)
|
||||
- Optimizations/improvements:
|
||||
- Condition code/branch handling like x86, also for FPU?
|
||||
- Remove remaining explicit alignment checks
|
||||
|
|
|
@ -170,8 +170,9 @@
|
|||
#define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT)
|
||||
#define PG_CACHE_MASK (1 << PG_CACHE_BIT)
|
||||
|
||||
/* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */
|
||||
#define NWINDOWS 8
|
||||
/* 3 <= NWINDOWS <= 32. */
|
||||
#define MIN_NWINDOWS 3
|
||||
#define MAX_NWINDOWS 32
|
||||
|
||||
#if !defined(TARGET_SPARC64)
|
||||
#define NB_MMU_MODES 2
|
||||
|
@ -222,8 +223,9 @@ typedef struct CPUSPARCState {
|
|||
uint32_t mmu_cxr_mask;
|
||||
uint32_t mmu_sfsr_mask;
|
||||
uint32_t mmu_trcr_mask;
|
||||
uint32_t nwindows;
|
||||
/* NOTE: we allow 8 more registers to handle wrapping */
|
||||
target_ulong regbase[NWINDOWS * 16 + 8];
|
||||
target_ulong regbase[MAX_NWINDOWS * 16 + 8];
|
||||
|
||||
CPU_COMMON
|
||||
|
||||
|
@ -330,6 +332,20 @@ void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
|
|||
|
||||
#ifndef NO_CPU_IO_DEFS
|
||||
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
|
||||
|
||||
static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp)
|
||||
{
|
||||
if (unlikely(cwp >= env1->nwindows))
|
||||
cwp -= env1->nwindows;
|
||||
return cwp;
|
||||
}
|
||||
|
||||
static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp)
|
||||
{
|
||||
if (unlikely(cwp < 0))
|
||||
cwp += env1->nwindows;
|
||||
return cwp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PUT_PSR(env, val) do { int _tmp = val; \
|
||||
|
@ -348,9 +364,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
|
|||
env->xcc = (_tmp >> 4) << 20; \
|
||||
env->psr = (_tmp & 0xf) << 20; \
|
||||
} while (0)
|
||||
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp)
|
||||
#define PUT_CWP64(env, val) \
|
||||
cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1)))
|
||||
#define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp)
|
||||
|
||||
static inline void PUT_CWP64(CPUSPARCState *env1, int cwp)
|
||||
{
|
||||
if (unlikely(cwp >= env1->nwindows || cwp < 0))
|
||||
cwp = 0;
|
||||
cpu_set_cwp(env1, env1->nwindows - 1 - cwp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ struct sparc_def_t {
|
|||
uint32_t mmu_sfsr_mask;
|
||||
uint32_t mmu_trcr_mask;
|
||||
uint32_t features;
|
||||
uint32_t nwindows;
|
||||
};
|
||||
|
||||
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
|
||||
|
@ -750,11 +751,11 @@ void do_interrupt(CPUState *env)
|
|||
change_pstate(PS_PEF | PS_PRIV | PS_AG);
|
||||
|
||||
if (intno == TT_CLRWIN)
|
||||
cpu_set_cwp(env, (env->cwp - 1) & (NWINDOWS - 1));
|
||||
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
|
||||
else if ((intno & 0x1c0) == TT_SPILL)
|
||||
cpu_set_cwp(env, (env->cwp - env->cansave - 2) & (NWINDOWS - 1));
|
||||
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
|
||||
else if ((intno & 0x1c0) == TT_FILL)
|
||||
cpu_set_cwp(env, (env->cwp + 1) & (NWINDOWS - 1));
|
||||
cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
|
||||
env->tbr &= ~0x7fffULL;
|
||||
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
|
||||
if (env->tl < MAXTL - 1) {
|
||||
|
@ -853,7 +854,7 @@ void do_interrupt(CPUState *env)
|
|||
}
|
||||
#endif
|
||||
env->psret = 0;
|
||||
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
||||
cwp = cpu_cwp_dec(env, env->cwp - 1);
|
||||
cpu_set_cwp(env, cwp);
|
||||
env->regwptr[9] = env->pc;
|
||||
env->regwptr[10] = env->npc;
|
||||
|
@ -887,8 +888,8 @@ void cpu_reset(CPUSPARCState *env)
|
|||
#if defined(CONFIG_USER_ONLY)
|
||||
env->user_mode_only = 1;
|
||||
#ifdef TARGET_SPARC64
|
||||
env->cleanwin = NWINDOWS - 2;
|
||||
env->cansave = NWINDOWS - 2;
|
||||
env->cleanwin = env->nwindows - 2;
|
||||
env->cansave = env->nwindows - 2;
|
||||
env->pstate = PS_RMO | PS_PEF | PS_IE;
|
||||
env->asi = 0x82; // Primary no-fault
|
||||
#endif
|
||||
|
@ -921,6 +922,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
|
|||
env->cpu_model_str = cpu_model;
|
||||
env->version = def->iu_version;
|
||||
env->fsr = def->fpu_version;
|
||||
env->nwindows = def->nwindows;
|
||||
#if !defined(TARGET_SPARC64)
|
||||
env->mmu_bm = def->mmu_bm;
|
||||
env->mmu_ctpr_mask = def->mmu_ctpr_mask;
|
||||
|
@ -929,6 +931,8 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
|
|||
env->mmu_trcr_mask = def->mmu_trcr_mask;
|
||||
env->mmuregs[0] |= def->mmu_version;
|
||||
cpu_sparc_set_id(env, 0);
|
||||
#else
|
||||
env->version |= def->nwindows - 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -970,121 +974,136 @@ static const sparc_def_t sparc_defs[] = {
|
|||
{
|
||||
.name = "Fujitsu Sparc64",
|
||||
.iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 4,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Fujitsu Sparc64 III",
|
||||
.iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 5,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Fujitsu Sparc64 IV",
|
||||
.iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Fujitsu Sparc64 V",
|
||||
.iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "TI UltraSparc I",
|
||||
.iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "TI UltraSparc II",
|
||||
.iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "TI UltraSparc IIi",
|
||||
.iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "TI UltraSparc IIe",
|
||||
.iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Sun UltraSparc III",
|
||||
.iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Sun UltraSparc III Cu",
|
||||
.iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Sun UltraSparc IIIi",
|
||||
.iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Sun UltraSparc IV",
|
||||
.iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Sun UltraSparc IV+",
|
||||
.iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "Sun UltraSparc IIIi+",
|
||||
.iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
.name = "NEC UltraSparc I",
|
||||
.iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
|
||||
| (MAXTL << 8) | (NWINDOWS - 1)),
|
||||
| (MAXTL << 8)),
|
||||
.fpu_version = 0x00000000,
|
||||
.mmu_version = 0,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
#else
|
||||
|
@ -1098,6 +1117,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 7,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
|
||||
},
|
||||
{
|
||||
|
@ -1110,6 +1130,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x000000ff,
|
||||
.mmu_sfsr_mask = 0x00016fff,
|
||||
.mmu_trcr_mask = 0x00ffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1122,6 +1143,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x000000ff,
|
||||
.mmu_sfsr_mask = 0x00016fff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1134,6 +1156,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
|
||||
CPU_FEATURE_FSMULD,
|
||||
},
|
||||
|
@ -1147,6 +1170,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
|
||||
CPU_FEATURE_FSMULD,
|
||||
},
|
||||
|
@ -1160,6 +1184,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
|
||||
CPU_FEATURE_FSMULD,
|
||||
},
|
||||
|
@ -1173,6 +1198,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000ffff,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1185,6 +1211,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0x00016fff,
|
||||
.mmu_trcr_mask = 0x0000003f,
|
||||
.nwindows = 7,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
|
||||
CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
|
||||
CPU_FEATURE_FMUL,
|
||||
|
@ -1199,6 +1226,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x000000ff,
|
||||
.mmu_sfsr_mask = 0x00016fff,
|
||||
.mmu_trcr_mask = 0x00ffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1211,6 +1239,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x000000ff,
|
||||
.mmu_sfsr_mask = 0x00016bff,
|
||||
.mmu_trcr_mask = 0x00ffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1223,6 +1252,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000ffff,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1235,6 +1265,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000ffff,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1247,6 +1278,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000ffff,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1259,6 +1291,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000ffff,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1271,6 +1304,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000ffff,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1283,6 +1317,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1295,6 +1330,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1307,6 +1343,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
|
||||
CPU_FEATURE_FSMULD,
|
||||
},
|
||||
|
@ -1320,6 +1357,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
|
||||
CPU_FEATURE_FSMULD,
|
||||
},
|
||||
|
@ -1333,6 +1371,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1345,6 +1384,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
{
|
||||
|
@ -1357,6 +1397,7 @@ static const sparc_def_t sparc_defs[] = {
|
|||
.mmu_cxr_mask = 0x0000003f,
|
||||
.mmu_sfsr_mask = 0xffffffff,
|
||||
.mmu_trcr_mask = 0xffffffff,
|
||||
.nwindows = 8,
|
||||
.features = CPU_DEFAULT_FEATURES,
|
||||
},
|
||||
#endif
|
||||
|
@ -1411,7 +1452,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
|
|||
uint32_t plus_features = 0;
|
||||
uint32_t minus_features = 0;
|
||||
long long iu_version;
|
||||
uint32_t fpu_version, mmu_version;
|
||||
uint32_t fpu_version, mmu_version, nwindows;
|
||||
|
||||
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
||||
if (strcasecmp(name, sparc_defs[i].name) == 0) {
|
||||
|
@ -1467,6 +1508,19 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
|
|||
cpu_def->mmu_version = mmu_version;
|
||||
#ifdef DEBUG_FEATURES
|
||||
fprintf(stderr, "mmu_version %llx\n", mmu_version);
|
||||
#endif
|
||||
} else if (!strcmp(featurestr, "nwindows")) {
|
||||
char *err;
|
||||
|
||||
nwindows = strtol(val, &err, 0);
|
||||
if (!*val || *err || nwindows > MAX_NWINDOWS ||
|
||||
nwindows < MIN_NWINDOWS) {
|
||||
fprintf(stderr, "bad numerical value %s\n", val);
|
||||
goto error;
|
||||
}
|
||||
cpu_def->nwindows = nwindows;
|
||||
#ifdef DEBUG_FEATURES
|
||||
fprintf(stderr, "nwindows %d\n", nwindows);
|
||||
#endif
|
||||
} else {
|
||||
fprintf(stderr, "unrecognized feature %s\n", featurestr);
|
||||
|
@ -1497,11 +1551,12 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
|
||||
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ",
|
||||
(*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
|
||||
sparc_defs[i].name,
|
||||
sparc_defs[i].iu_version,
|
||||
sparc_defs[i].fpu_version,
|
||||
sparc_defs[i].mmu_version);
|
||||
sparc_defs[i].mmu_version,
|
||||
sparc_defs[i].nwindows);
|
||||
print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
|
||||
~sparc_defs[i].features, "-");
|
||||
print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
|
||||
|
@ -1512,7 +1567,7 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
|
|||
print_features(f, cpu_fprintf, -1, NULL);
|
||||
(*cpu_fprintf)(f, "\n");
|
||||
(*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version "
|
||||
"mmu_version\n");
|
||||
"mmu_version nwindows\n");
|
||||
}
|
||||
|
||||
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
|
||||
|
@ -1558,7 +1613,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
|
|||
cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d "
|
||||
"cleanwin %d cwp %d\n",
|
||||
env->cansave, env->canrestore, env->otherwin, env->wstate,
|
||||
env->cleanwin, NWINDOWS - 1 - env->cwp);
|
||||
env->cleanwin, env->nwindows - 1 - env->cwp);
|
||||
#else
|
||||
cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
|
||||
GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
|
||||
|
|
|
@ -31,7 +31,8 @@ void cpu_save(QEMUFile *f, void *opaque)
|
|||
|
||||
for(i = 0; i < 8; i++)
|
||||
qemu_put_betls(f, &env->gregs[i]);
|
||||
for(i = 0; i < NWINDOWS * 16; i++)
|
||||
qemu_put_be32s(f, &env->nwindows);
|
||||
for(i = 0; i < env->nwindows * 16; i++)
|
||||
qemu_put_betls(f, &env->regbase[i]);
|
||||
|
||||
/* FPU */
|
||||
|
@ -65,9 +66,12 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
|
|||
int i;
|
||||
uint32_t tmp;
|
||||
|
||||
if (version_id != 4)
|
||||
return -EINVAL;
|
||||
for(i = 0; i < 8; i++)
|
||||
qemu_get_betls(f, &env->gregs[i]);
|
||||
for(i = 0; i < NWINDOWS * 16; i++)
|
||||
qemu_get_be32s(f, &env->nwindows);
|
||||
for(i = 0; i < env->nwindows * 16; i++)
|
||||
qemu_get_betls(f, &env->regbase[i]);
|
||||
|
||||
/* FPU */
|
||||
|
|
|
@ -2178,7 +2178,7 @@ void helper_rett(void)
|
|||
raise_exception(TT_ILL_INSN);
|
||||
|
||||
env->psret = 1;
|
||||
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
||||
cwp = cpu_cwp_inc(env, env->cwp + 1) ;
|
||||
if (env->wim & (1 << cwp)) {
|
||||
raise_exception(TT_WIN_UNF);
|
||||
}
|
||||
|
@ -2399,7 +2399,7 @@ void helper_save(void)
|
|||
{
|
||||
uint32_t cwp;
|
||||
|
||||
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
||||
cwp = cpu_cwp_dec(env, env->cwp - 1);
|
||||
if (env->wim & (1 << cwp)) {
|
||||
raise_exception(TT_WIN_OVF);
|
||||
}
|
||||
|
@ -2410,7 +2410,7 @@ void helper_restore(void)
|
|||
{
|
||||
uint32_t cwp;
|
||||
|
||||
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
||||
cwp = cpu_cwp_inc(env, env->cwp + 1);
|
||||
if (env->wim & (1 << cwp)) {
|
||||
raise_exception(TT_WIN_UNF);
|
||||
}
|
||||
|
@ -2419,7 +2419,7 @@ void helper_restore(void)
|
|||
|
||||
void helper_wrpsr(target_ulong new_psr)
|
||||
{
|
||||
if ((new_psr & PSR_CWP) >= NWINDOWS)
|
||||
if ((new_psr & PSR_CWP) >= env->nwindows)
|
||||
raise_exception(TT_ILL_INSN);
|
||||
else
|
||||
PUT_PSR(env, new_psr);
|
||||
|
@ -2437,7 +2437,7 @@ void helper_save(void)
|
|||
{
|
||||
uint32_t cwp;
|
||||
|
||||
cwp = (env->cwp - 1) & (NWINDOWS - 1);
|
||||
cwp = cpu_cwp_dec(env, env->cwp - 1);
|
||||
if (env->cansave == 0) {
|
||||
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
|
@ -2458,7 +2458,7 @@ void helper_restore(void)
|
|||
{
|
||||
uint32_t cwp;
|
||||
|
||||
cwp = (env->cwp + 1) & (NWINDOWS - 1);
|
||||
cwp = cpu_cwp_inc(env, env->cwp + 1);
|
||||
if (env->canrestore == 0) {
|
||||
raise_exception(TT_FILL | (env->otherwin != 0 ?
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
|
@ -2472,7 +2472,7 @@ void helper_restore(void)
|
|||
|
||||
void helper_flushw(void)
|
||||
{
|
||||
if (env->cansave != NWINDOWS - 2) {
|
||||
if (env->cansave != env->nwindows - 2) {
|
||||
raise_exception(TT_SPILL | (env->otherwin != 0 ?
|
||||
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
|
||||
((env->wstate & 0x7) << 2)));
|
||||
|
@ -2491,7 +2491,7 @@ void helper_saved(void)
|
|||
void helper_restored(void)
|
||||
{
|
||||
env->canrestore++;
|
||||
if (env->cleanwin < NWINDOWS - 1)
|
||||
if (env->cleanwin < env->nwindows - 1)
|
||||
env->cleanwin++;
|
||||
if (env->otherwin == 0)
|
||||
env->cansave--;
|
||||
|
@ -2622,12 +2622,12 @@ void helper_retry(void)
|
|||
void cpu_set_cwp(CPUState *env1, int new_cwp)
|
||||
{
|
||||
/* put the modified wrap registers at their proper location */
|
||||
if (env1->cwp == (NWINDOWS - 1))
|
||||
memcpy32(env1->regbase, env1->regbase + NWINDOWS * 16);
|
||||
if (env1->cwp == env->nwindows - 1)
|
||||
memcpy32(env1->regbase, env1->regbase + env->nwindows * 16);
|
||||
env1->cwp = new_cwp;
|
||||
/* put the wrap registers at their temporary location */
|
||||
if (new_cwp == (NWINDOWS - 1))
|
||||
memcpy32(env1->regbase + NWINDOWS * 16, env1->regbase);
|
||||
if (new_cwp == env->nwindows - 1)
|
||||
memcpy32(env1->regbase + env->nwindows * 16, env1->regbase);
|
||||
env1->regwptr = env1->regbase + (new_cwp * 16);
|
||||
}
|
||||
|
||||
|
|
|
@ -3442,8 +3442,6 @@ static void disas_sparc_insn(DisasContext * dc)
|
|||
goto illegal_insn;
|
||||
}
|
||||
#else
|
||||
tcg_gen_andi_tl(cpu_dst, cpu_dst,
|
||||
((1 << NWINDOWS) - 1));
|
||||
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
|
||||
tcg_gen_st_i32(cpu_tmp32, cpu_env,
|
||||
offsetof(CPUSPARCState, wim));
|
||||
|
|
Loading…
Reference in New Issue