PowerPC flags update/use fixes:

- fix confusion between overflow/summary overflow, as reported by S Bansal.
- reset carry in addic. optimized case (as it was already done in addic).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3179 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
j_mayer 2007-09-17 09:51:40 +00:00
parent 3608160206
commit 966439a678
4 changed files with 41 additions and 31 deletions

View File

@ -131,7 +131,7 @@ void OPPROTO op_print_mem_EA (void)
/* set_Rc0 */ /* set_Rc0 */
void OPPROTO op_set_Rc0 (void) void OPPROTO op_set_Rc0 (void)
{ {
env->crf[0] = T0 | xer_ov; env->crf[0] = T0 | xer_so;
RETURN(); RETURN();
} }
@ -731,8 +731,8 @@ void OPPROTO op_check_addo (void)
((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) { ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
RETURN(); RETURN();
} }
@ -744,8 +744,8 @@ void OPPROTO op_check_addo_64 (void)
((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) { ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
RETURN(); RETURN();
} }
@ -1028,8 +1028,8 @@ void OPPROTO op_check_subfo (void)
((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) { ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
RETURN(); RETURN();
} }
@ -1041,8 +1041,8 @@ void OPPROTO op_check_subfo_64 (void)
((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) { ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
RETURN(); RETURN();
} }
@ -1196,6 +1196,7 @@ void OPPROTO op_cmp (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
@ -1209,6 +1210,7 @@ void OPPROTO op_cmp_64 (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
#endif #endif
@ -1223,6 +1225,7 @@ void OPPROTO op_cmpi (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
@ -1236,6 +1239,7 @@ void OPPROTO op_cmpi_64 (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
#endif #endif
@ -1250,6 +1254,7 @@ void OPPROTO op_cmpl (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
@ -1263,6 +1268,7 @@ void OPPROTO op_cmpl_64 (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
#endif #endif
@ -1277,6 +1283,7 @@ void OPPROTO op_cmpli (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
@ -1290,6 +1297,7 @@ void OPPROTO op_cmpli_64 (void)
} else { } else {
T0 = 0x02; T0 = 0x02;
} }
T0 |= xer_so;
RETURN(); RETURN();
} }
#endif #endif

View File

@ -311,8 +311,8 @@ void do_addmeo (void)
((uint32_t)T1 ^ (uint32_t)T0) & (1UL << 31)))) { ((uint32_t)T1 ^ (uint32_t)T0) & (1UL << 31)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
if (likely(T1 != 0)) if (likely(T1 != 0))
xer_ca = 1; xer_ca = 1;
@ -327,8 +327,8 @@ void do_addmeo_64 (void)
((uint64_t)T1 ^ (uint64_t)T0) & (1ULL << 63)))) { ((uint64_t)T1 ^ (uint64_t)T0) & (1ULL << 63)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
if (likely(T1 != 0)) if (likely(T1 != 0))
xer_ca = 1; xer_ca = 1;
@ -342,8 +342,8 @@ void do_divwo (void)
xer_ov = 0; xer_ov = 0;
T0 = (int32_t)T0 / (int32_t)T1; T0 = (int32_t)T0 / (int32_t)T1;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
T0 = (-1) * ((uint32_t)T0 >> 31); T0 = (-1) * ((uint32_t)T0 >> 31);
} }
} }
@ -356,8 +356,8 @@ void do_divdo (void)
xer_ov = 0; xer_ov = 0;
T0 = (int64_t)T0 / (int64_t)T1; T0 = (int64_t)T0 / (int64_t)T1;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
T0 = (-1ULL) * ((uint64_t)T0 >> 63); T0 = (-1ULL) * ((uint64_t)T0 >> 63);
} }
} }
@ -369,8 +369,8 @@ void do_divwuo (void)
xer_ov = 0; xer_ov = 0;
T0 = (uint32_t)T0 / (uint32_t)T1; T0 = (uint32_t)T0 / (uint32_t)T1;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
T0 = 0; T0 = 0;
} }
} }
@ -382,8 +382,8 @@ void do_divduo (void)
xer_ov = 0; xer_ov = 0;
T0 = (uint64_t)T0 / (uint64_t)T1; T0 = (uint64_t)T0 / (uint64_t)T1;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
T0 = 0; T0 = 0;
} }
} }
@ -475,8 +475,8 @@ void do_subfmeo (void)
(1UL << 31)))) { (1UL << 31)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
if (likely((uint32_t)T1 != UINT32_MAX)) if (likely((uint32_t)T1 != UINT32_MAX))
xer_ca = 1; xer_ca = 1;
@ -491,8 +491,8 @@ void do_subfmeo_64 (void)
(1ULL << 63)))) { (1ULL << 63)))) {
xer_ov = 0; xer_ov = 0;
} else { } else {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} }
if (likely((uint64_t)T1 != UINT64_MAX)) if (likely((uint64_t)T1 != UINT64_MAX))
xer_ca = 1; xer_ca = 1;
@ -1073,8 +1073,8 @@ void do_POWER_dozo (void)
T0 = T1 - T0; T0 = T1 - T0;
if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) & if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) { ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) {
xer_so = 1;
xer_ov = 1; xer_ov = 1;
xer_so = 1;
} else { } else {
xer_ov = 0; xer_ov = 0;
} }
@ -2499,7 +2499,7 @@ void do_4xx_tlbsx (void)
void do_4xx_tlbsx_ (void) void do_4xx_tlbsx_ (void)
{ {
int tmp = xer_ov; int tmp = xer_so;
T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);
if (T0 != -1) if (T0 != -1)

View File

@ -610,10 +610,10 @@ void OPPROTO glue(op_stwcx, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint32_t)T0)) { if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(stl, MEMSUFFIX)((uint32_t)T0, T1); glue(stl, MEMSUFFIX)((uint32_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -627,10 +627,10 @@ void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint64_t)T0)) { if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(stl, MEMSUFFIX)((uint64_t)T0, T1); glue(stl, MEMSUFFIX)((uint64_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -643,10 +643,10 @@ void OPPROTO glue(op_stdcx, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint32_t)T0)) { if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(stq, MEMSUFFIX)((uint32_t)T0, T1); glue(stq, MEMSUFFIX)((uint32_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -659,10 +659,10 @@ void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint64_t)T0)) { if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(stq, MEMSUFFIX)((uint64_t)T0, T1); glue(stq, MEMSUFFIX)((uint64_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -676,10 +676,10 @@ void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint32_t)T0)) { if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(st32r, MEMSUFFIX)((uint32_t)T0, T1); glue(st32r, MEMSUFFIX)((uint32_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -693,10 +693,10 @@ void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint64_t)T0)) { if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(st32r, MEMSUFFIX)((uint64_t)T0, T1); glue(st32r, MEMSUFFIX)((uint64_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -709,10 +709,10 @@ void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint32_t)T0)) { if (unlikely(env->reserve != (uint32_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(st64r, MEMSUFFIX)((uint32_t)T0, T1); glue(st64r, MEMSUFFIX)((uint32_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;
@ -725,10 +725,10 @@ void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void)
do_raise_exception(EXCP_ALIGN); do_raise_exception(EXCP_ALIGN);
} else { } else {
if (unlikely(env->reserve != (uint64_t)T0)) { if (unlikely(env->reserve != (uint64_t)T0)) {
env->crf[0] = xer_ov; env->crf[0] = xer_so;
} else { } else {
glue(st64r, MEMSUFFIX)((uint64_t)T0, T1); glue(st64r, MEMSUFFIX)((uint64_t)T0, T1);
env->crf[0] = xer_ov | 0x02; env->crf[0] = xer_so | 0x02;
} }
} }
env->reserve = -1; env->reserve = -1;

View File

@ -802,6 +802,8 @@ GEN_HANDLER(addic_, 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
else else
#endif #endif
gen_op_check_addc(); gen_op_check_addc();
} else {
gen_op_clear_xer_ca();
} }
gen_op_store_T0_gpr(rD(ctx->opcode)); gen_op_store_T0_gpr(rD(ctx->opcode));
gen_set_Rc0(ctx); gen_set_Rc0(ctx);