Skip to content

Commit

Permalink
or32: Fix overflow detection on -O2 compilation
Browse files Browse the repository at this point in the history
The check for overflow assumes that the compiler will allow us to detect
when a value overflows to a negative number.  When running GCC with -O2
and above this overflow cannot be detected.  The C standard explains
that overflow behavior is undefined meaning this expected overflow
causing a negative number cannot be guaranteed and it is not.

Multiple overflow flag tests were failing.

Fix the detection buy just using the compiler builtins for detecting
overflow conditions.
  • Loading branch information
stffrdhrn authored and jeremybennett committed Aug 17, 2023
1 parent b735ef8 commit 0386f2b
Showing 1 changed file with 7 additions and 31 deletions.
38 changes: 7 additions & 31 deletions cpu/or32/insnset.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,15 @@
INSTRUCTION (l_add) {
orreg_t temp1, temp2, temp3;
int8_t temp4;

temp2 = (orreg_t)PARAM2;
temp3 = (orreg_t)PARAM1;
temp1 = temp2 + temp3;
SET_PARAM0 (temp1);

/* Set overflow if two negative values gave a positive sum, or if two
positive values gave a negative sum. Otherwise clear it */
if ((((long int) temp2 < 0) &&
((long int) temp3 < 0) &&
((long int) temp1 >= 0)) ||
(((long int) temp2 >= 0) &&
((long int) temp3 >= 0) &&
((long int) temp1 < 0)))
if (__builtin_add_overflow_p (temp2, temp3, temp1))
{
cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
}
Expand Down Expand Up @@ -119,12 +114,8 @@ INSTRUCTION (l_addc) {
positive values gave a negative sum. Otherwise clear it. There are no
corner cases with the extra bit carried in (unlike the carry flag - see
below). */
if ((((long int) temp2 < 0) &&
((long int) temp3 < 0) &&
((long int) temp1 >= 0)) ||
(((long int) temp2 >= 0) &&
((long int) temp3 >= 0) &&
((long int) temp1 < 0)))
if (((temp2 < 0) && (temp3 < 0) && (temp1 >= 0)) ||
((temp2 >= 0) && (temp3 >= 0) && (temp1 < 0)))
{
cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
}
Expand Down Expand Up @@ -336,12 +327,7 @@ INSTRUCTION (l_sub) {
/* Set overflow if a negative value minus a positive value gave a positive
sum, or if a positive value minus a negative value gave a negative
sum. Otherwise clear it */
if ((((long int) temp2 < 0) &&
((long int) temp3 >= 0) &&
((long int) temp1 >= 0)) ||
(((long int) temp2 >= 0) &&
((long int) temp3 < 0) &&
((long int) temp1 < 0)))
if (__builtin_sub_overflow_p (temp2, temp3, temp1))
{
cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
}
Expand Down Expand Up @@ -974,12 +960,7 @@ INSTRUCTION (l_mac) {

/* Set overflow if two negative values gave a positive sum, or if two
positive values gave a negative sum. Otherwise clear it */
if (((acc < 0) &&
(prod < 0) &&
(tmp >= 0)) ||
((acc >= 0) &&
(prod >= 0) &&
(tmp < 0)))
if (__builtin_add_overflow_p (acc, prod, tmp))
{
cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
}
Expand Down Expand Up @@ -1042,12 +1023,7 @@ INSTRUCTION (l_msb) {
/* Set overflow if a negative value minus a positive value gave a positive
sum, or if a positive value minus a negative value gave a negative
sum. Otherwise clear it */
if (((acc < 0) &&
(prod >= 0) &&
(tmp >= 0)) ||
((acc >= 0) &&
(prod < 0) &&
(tmp < 0)))
if (__builtin_sub_overflow_p (acc, prod, tmp))
{
cpu_state.sprs[SPR_SR] |= SPR_SR_OV;
}
Expand Down

0 comments on commit 0386f2b

Please sign in to comment.