diff options
Diffstat (limited to 'target-ppc/op_helper.c')
-rw-r--r-- | target-ppc/op_helper.c | 181 |
1 files changed, 99 insertions, 82 deletions
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index 28bbc98a3b..ad52e0d679 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -119,9 +119,9 @@ void do_adde (void) T0 += T1 + xer_ca; if (likely(!((uint32_t)T0 < (uint32_t)T2 || (xer_ca == 1 && (uint32_t)T0 == (uint32_t)T2)))) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } @@ -132,32 +132,42 @@ void do_adde_64 (void) T0 += T1 + xer_ca; if (likely(!((uint64_t)T0 < (uint64_t)T2 || (xer_ca == 1 && (uint64_t)T0 == (uint64_t)T2)))) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } #endif void do_addmeo (void) { + int ov; T1 = T0; T0 += xer_ca + (-1); - xer_ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31; - xer_so |= xer_ov; + ov = ((uint32_t)T1 & ((uint32_t)T1 ^ (uint32_t)T0)) >> 31; + if (ov) { + env->xer |= (1 << XER_OV) | (1 << XER_SO); + } else { + env->xer &= ~(1 << XER_OV); + } if (likely((uint32_t)T1 != 0)) - xer_ca = 1; + env->xer |= (1 << XER_CA); } #if defined(TARGET_PPC64) void do_addmeo_64 (void) { + int ov; T1 = T0; T0 += xer_ca + (-1); - xer_ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63; - xer_so |= xer_ov; + ov = ((uint64_t)T1 & ((uint64_t)T1 ^ (uint64_t)T0)) >> 63; + if (ov) { + env->xer |= (1 << XER_OV) | (1 << XER_SO); + } else { + env->xer &= ~(1 << XER_OV); + } if (likely((uint64_t)T1 != 0)) - xer_ca = 1; + env->xer |= (1 << XER_CA); } #endif @@ -165,13 +175,12 @@ void do_divwo (void) { if (likely(!(((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) || (int32_t)T1 == 0))) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); T0 = (int32_t)T0 / (int32_t)T1; } else { - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); T0 = UINT32_MAX * ((uint32_t)T0 >> 31); } - xer_so |= xer_ov; } #if defined(TARGET_PPC64) @@ -179,24 +188,22 @@ void do_divdo (void) { if (likely(!(((int64_t)T0 == INT64_MIN && (int64_t)T1 == (int64_t)-1LL) || (int64_t)T1 == 0))) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); T0 = (int64_t)T0 / (int64_t)T1; } else { - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); T0 = UINT64_MAX * ((uint64_t)T0 >> 63); } - xer_so |= xer_ov; } #endif void do_divwuo (void) { if (likely((uint32_t)T1 != 0)) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); T0 = (uint32_t)T0 / (uint32_t)T1; } else { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); T0 = 0; } } @@ -205,11 +212,10 @@ void do_divwuo (void) void do_divduo (void) { if (likely((uint64_t)T1 != 0)) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); T0 = (uint64_t)T0 / (uint64_t)T1; } else { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); T0 = 0; } } @@ -220,10 +226,9 @@ void do_mullwo (void) int64_t res = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1; if (likely((int32_t)res == res)) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } else { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } T0 = (int32_t)res; } @@ -238,22 +243,20 @@ void do_mulldo (void) T0 = (int64_t)tl; /* If th != 0 && th != -1, then we had an overflow */ if (likely((uint64_t)(th + 1) <= 1)) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } else { - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } - xer_so |= xer_ov; } #endif void do_nego (void) { if (likely((int32_t)T0 != INT32_MIN)) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); T0 = -(int32_t)T0; } else { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } } @@ -261,11 +264,10 @@ void do_nego (void) void do_nego_64 (void) { if (likely((int64_t)T0 != INT64_MIN)) { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); T0 = -(int64_t)T0; } else { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } } #endif @@ -275,9 +277,9 @@ void do_subfe (void) T0 = T1 + ~T0 + xer_ca; if (likely((uint32_t)T0 >= (uint32_t)T1 && (xer_ca == 0 || (uint32_t)T0 != (uint32_t)T1))) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } @@ -287,61 +289,81 @@ void do_subfe_64 (void) T0 = T1 + ~T0 + xer_ca; if (likely((uint64_t)T0 >= (uint64_t)T1 && (xer_ca == 0 || (uint64_t)T0 != (uint64_t)T1))) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } #endif void do_subfmeo (void) { + int ov; T1 = T0; T0 = ~T0 + xer_ca - 1; - xer_ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31; - xer_so |= xer_ov; + ov = ((uint32_t)~T1 & ((uint32_t)~T1 ^ (uint32_t)T0)) >> 31; + if (ov) { + env->xer |= (1 << XER_OV) | (1 << XER_SO); + } else { + env->xer &= ~(1 << XER_OV); + } if (likely((uint32_t)T1 != UINT32_MAX)) - xer_ca = 1; + env->xer |= (1 << XER_CA); } #if defined(TARGET_PPC64) void do_subfmeo_64 (void) { + int ov; T1 = T0; T0 = ~T0 + xer_ca - 1; - xer_ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63; - xer_so |= xer_ov; + ov = ((uint64_t)~T1 & ((uint64_t)~T1 ^ (uint64_t)T0)) >> 63; + if (ov) { + env->xer |= (1 << XER_OV) | (1 << XER_SO); + } else { + env->xer &= ~(1 << XER_OV); + } if (likely((uint64_t)T1 != UINT64_MAX)) - xer_ca = 1; + env->xer |= (1 << XER_CA); } #endif void do_subfzeo (void) { + int ov; T1 = T0; T0 = ~T0 + xer_ca; - xer_ov = (((uint32_t)~T1 ^ UINT32_MAX) & - ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31; - xer_so |= xer_ov; + ov = (((uint32_t)~T1 ^ UINT32_MAX) & + ((uint32_t)(~T1) ^ (uint32_t)T0)) >> 31; + if (ov) { + env->xer |= (1 << XER_OV) | (1 << XER_SO); + } else { + env->xer &= ~(1 << XER_OV); + } if (likely((uint32_t)T0 >= (uint32_t)~T1)) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } #if defined(TARGET_PPC64) void do_subfzeo_64 (void) { + int ov; T1 = T0; T0 = ~T0 + xer_ca; - xer_ov = (((uint64_t)~T1 ^ UINT64_MAX) & - ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63; - xer_so |= xer_ov; + ov = (((uint64_t)~T1 ^ UINT64_MAX) & + ((uint64_t)(~T1) ^ (uint64_t)T0)) >> 63; + if (ov) { + env->xer |= (1 << XER_OV) | (1 << XER_SO); + } else { + env->xer &= ~(1 << XER_OV); + } if (likely((uint64_t)T0 >= (uint64_t)~T1)) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } #endif @@ -367,20 +389,20 @@ void do_sraw (void) if (likely((uint32_t)T1 != 0)) { ret = (int32_t)T0 >> (T1 & 0x1fUL); if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } else { ret = T0; - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } } else { ret = UINT32_MAX * ((uint32_t)T0 >> 31); if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } T0 = ret; @@ -395,20 +417,20 @@ void do_srad (void) if (likely((uint64_t)T1 != 0)) { ret = (int64_t)T0 >> (T1 & 0x3FUL); if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } else { ret = T0; - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } } else { ret = UINT64_MAX * ((uint64_t)T0 >> 63); if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) { - xer_ca = 0; + env->xer &= ~(1 << XER_CA); } else { - xer_ca = 1; + env->xer |= (1 << XER_CA); } } T0 = ret; @@ -1478,14 +1500,13 @@ void do_POWER_abso (void) { if ((int32_t)T0 == INT32_MIN) { T0 = INT32_MAX; - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } else if ((int32_t)T0 < 0) { T0 = -T0; - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } else { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } - xer_so |= xer_ov; } void do_POWER_clcs (void) @@ -1538,19 +1559,18 @@ void do_POWER_divo (void) (int32_t)T1 == 0) { T0 = UINT32_MAX * ((uint32_t)T0 >> 31); env->spr[SPR_MQ] = 0; - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } else { tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ]; env->spr[SPR_MQ] = tmp % T1; tmp /= (int32_t)T1; if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) { - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } else { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } T0 = tmp; } - xer_so |= xer_ov; } void do_POWER_divs (void) @@ -1571,13 +1591,12 @@ void do_POWER_divso (void) (int32_t)T1 == 0) { T0 = UINT32_MAX * ((uint32_t)T0 >> 31); env->spr[SPR_MQ] = 0; - xer_ov = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } else { T0 = (int32_t)T0 / (int32_t)T1; env->spr[SPR_MQ] = (int32_t)T0 % (int32_t)T1; - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } - xer_so |= xer_ov; } void do_POWER_dozo (void) @@ -1587,14 +1606,13 @@ void do_POWER_dozo (void) T0 = T1 - T0; if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) & ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } else { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } } else { T0 = 0; - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } } @@ -1621,10 +1639,9 @@ void do_POWER_mulo (void) env->spr[SPR_MQ] = tmp >> 32; T0 = tmp; if (tmp >> 32 != ((uint64_t)T0 >> 16) * ((uint64_t)T1 >> 16)) { - xer_ov = 1; - xer_so = 1; + env->xer |= (1 << XER_OV) | (1 << XER_SO); } else { - xer_ov = 0; + env->xer &= ~(1 << XER_OV); } } |