Convert save, restore, saved, restored, and flushw to TCG

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4092 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2008-03-21 17:57:29 +00:00
parent 44e7757c2a
commit 72a9747b79
4 changed files with 103 additions and 104 deletions

View file

@ -8,6 +8,9 @@ target_ulong TCG_HELPER_PROTO helper_rdpsr(void);
void TCG_HELPER_PROTO helper_wrpstate(target_ulong new_state); void TCG_HELPER_PROTO helper_wrpstate(target_ulong new_state);
void TCG_HELPER_PROTO helper_done(void); void TCG_HELPER_PROTO helper_done(void);
void TCG_HELPER_PROTO helper_retry(void); void TCG_HELPER_PROTO helper_retry(void);
void TCG_HELPER_PROTO helper_flushw(void);
void TCG_HELPER_PROTO helper_saved(void);
void TCG_HELPER_PROTO helper_restored(void);
target_ulong TCG_HELPER_PROTO helper_rdccr(void); target_ulong TCG_HELPER_PROTO helper_rdccr(void);
void TCG_HELPER_PROTO helper_wrccr(target_ulong new_ccr); void TCG_HELPER_PROTO helper_wrccr(target_ulong new_ccr);
target_ulong TCG_HELPER_PROTO helper_rdcwp(void); target_ulong TCG_HELPER_PROTO helper_rdcwp(void);
@ -35,6 +38,8 @@ void TCG_HELPER_PROTO helper_trap(target_ulong nb_trap);
void TCG_HELPER_PROTO helper_trapcc(target_ulong nb_trap, void TCG_HELPER_PROTO helper_trapcc(target_ulong nb_trap,
target_ulong do_trap); target_ulong do_trap);
void TCG_HELPER_PROTO helper_debug(void); void TCG_HELPER_PROTO helper_debug(void);
void TCG_HELPER_PROTO helper_save(void);
void TCG_HELPER_PROTO helper_restore(void);
void TCG_HELPER_PROTO helper_flush(target_ulong addr); void TCG_HELPER_PROTO helper_flush(target_ulong addr);
target_ulong TCG_HELPER_PROTO helper_udiv(target_ulong a, target_ulong b); target_ulong TCG_HELPER_PROTO helper_udiv(target_ulong a, target_ulong b);
target_ulong TCG_HELPER_PROTO helper_sdiv(target_ulong a, target_ulong b); target_ulong TCG_HELPER_PROTO helper_sdiv(target_ulong a, target_ulong b);

View file

@ -37,109 +37,11 @@
#endif #endif
#endif #endif
#ifndef TARGET_SPARC64
/* XXX: use another pointer for %iN registers to avoid slow wrapping
handling ? */
void OPPROTO op_save(void)
{
uint32_t cwp;
cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_OVF);
}
set_cwp(cwp);
FORCE_RET();
}
void OPPROTO op_restore(void)
{
uint32_t cwp;
cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_UNF);
}
set_cwp(cwp);
FORCE_RET();
}
#else
/* XXX: use another pointer for %iN registers to avoid slow wrapping
handling ? */
void OPPROTO op_save(void)
{
uint32_t cwp;
cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->cansave == 0) {
raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
if (env->cleanwin - env->canrestore == 0) {
// XXX Clean windows without trap
raise_exception(TT_CLRWIN);
} else {
env->cansave--;
env->canrestore++;
set_cwp(cwp);
}
}
FORCE_RET();
}
void OPPROTO op_restore(void)
{
uint32_t cwp;
cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->canrestore == 0) {
raise_exception(TT_FILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
env->cansave++;
env->canrestore--;
set_cwp(cwp);
}
FORCE_RET();
}
#endif
void OPPROTO op_jmp_label(void) void OPPROTO op_jmp_label(void)
{ {
GOTO_LABEL_PARAM(1); GOTO_LABEL_PARAM(1);
} }
#ifdef TARGET_SPARC64
void OPPROTO op_flushw(void)
{
if (env->cansave != NWINDOWS - 2) {
raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
}
}
void OPPROTO op_saved(void)
{
env->cansave++;
if (env->otherwin == 0)
env->canrestore--;
else
env->otherwin--;
FORCE_RET();
}
void OPPROTO op_restored(void)
{
env->canrestore++;
if (env->cleanwin < NWINDOWS - 1)
env->cleanwin++;
if (env->otherwin == 0)
env->cansave--;
else
env->otherwin--;
FORCE_RET();
}
#endif
#define CHECK_ALIGN_OP(align) \ #define CHECK_ALIGN_OP(align) \
void OPPROTO op_check_align_T0_ ## align (void) \ void OPPROTO op_check_align_T0_ ## align (void) \
{ \ { \

View file

@ -2246,6 +2246,30 @@ void helper_debug(void)
} }
#ifndef TARGET_SPARC64 #ifndef TARGET_SPARC64
/* XXX: use another pointer for %iN registers to avoid slow wrapping
handling ? */
void helper_save(void)
{
uint32_t cwp;
cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_OVF);
}
set_cwp(cwp);
}
void helper_restore(void)
{
uint32_t cwp;
cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->wim & (1 << cwp)) {
raise_exception(TT_WIN_UNF);
}
set_cwp(cwp);
}
void helper_wrpsr(target_ulong new_psr) void helper_wrpsr(target_ulong new_psr)
{ {
if ((new_psr & PSR_CWP) >= NWINDOWS) if ((new_psr & PSR_CWP) >= NWINDOWS)
@ -2260,6 +2284,74 @@ target_ulong helper_rdpsr(void)
} }
#else #else
/* XXX: use another pointer for %iN registers to avoid slow wrapping
handling ? */
void helper_save(void)
{
uint32_t cwp;
cwp = (env->cwp - 1) & (NWINDOWS - 1);
if (env->cansave == 0) {
raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
if (env->cleanwin - env->canrestore == 0) {
// XXX Clean windows without trap
raise_exception(TT_CLRWIN);
} else {
env->cansave--;
env->canrestore++;
set_cwp(cwp);
}
}
}
void helper_restore(void)
{
uint32_t cwp;
cwp = (env->cwp + 1) & (NWINDOWS - 1);
if (env->canrestore == 0) {
raise_exception(TT_FILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
} else {
env->cansave++;
env->canrestore--;
set_cwp(cwp);
}
}
void helper_flushw(void)
{
if (env->cansave != NWINDOWS - 2) {
raise_exception(TT_SPILL | (env->otherwin != 0 ?
(TT_WOTHER | ((env->wstate & 0x38) >> 1)):
((env->wstate & 0x7) << 2)));
}
}
void helper_saved(void)
{
env->cansave++;
if (env->otherwin == 0)
env->canrestore--;
else
env->otherwin--;
}
void helper_restored(void)
{
env->canrestore++;
if (env->cleanwin < NWINDOWS - 1)
env->cleanwin++;
if (env->otherwin == 0)
env->cansave--;
else
env->otherwin--;
}
target_ulong helper_rdccr(void) target_ulong helper_rdccr(void)
{ {
return GET_CCR(env); return GET_CCR(env);

View file

@ -2280,7 +2280,7 @@ static void disas_sparc_insn(DisasContext * dc)
break; break;
} else if (xop == 0x2b) { /* rdtbr / V9 flushw */ } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
gen_op_flushw(); tcg_gen_helper_0_0(helper_flushw);
#else #else
if (!supervisor(dc)) if (!supervisor(dc))
goto priv_insn; goto priv_insn;
@ -3251,10 +3251,10 @@ static void disas_sparc_insn(DisasContext * dc)
#ifdef TARGET_SPARC64 #ifdef TARGET_SPARC64
switch (rd) { switch (rd) {
case 0: case 0:
gen_op_saved(); tcg_gen_helper_0_0(helper_saved);
break; break;
case 1: case 1:
gen_op_restored(); tcg_gen_helper_0_0(helper_restored);
break; break;
case 2: /* UA2005 allclean */ case 2: /* UA2005 allclean */
case 3: /* UA2005 otherw */ case 3: /* UA2005 otherw */
@ -3954,7 +3954,7 @@ static void disas_sparc_insn(DisasContext * dc)
} }
#endif #endif
} }
gen_op_restore(); tcg_gen_helper_0_0(helper_restore);
gen_mov_pc_npc(dc); gen_mov_pc_npc(dc);
gen_op_check_align_T0_3(); gen_op_check_align_T0_3();
tcg_gen_mov_tl(cpu_npc, cpu_T[0]); tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
@ -4009,12 +4009,12 @@ static void disas_sparc_insn(DisasContext * dc)
break; break;
case 0x3c: /* save */ case 0x3c: /* save */
save_state(dc); save_state(dc);
gen_op_save(); tcg_gen_helper_0_0(helper_save);
gen_movl_T0_reg(rd); gen_movl_T0_reg(rd);
break; break;
case 0x3d: /* restore */ case 0x3d: /* restore */
save_state(dc); save_state(dc);
gen_op_restore(); tcg_gen_helper_0_0(helper_restore);
gen_movl_T0_reg(rd); gen_movl_T0_reg(rd);
break; break;
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64) #if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)