Fix to avoid excessive compiler optimization of vax ROM access spinwait. Found by Craig Berry, fix suggested by Sergey Oboguev

This commit is contained in:
Mark Pizzolato 2012-04-27 13:38:13 -07:00
parent 57008bb8f5
commit ce716f93f6

View file

@ -481,16 +481,17 @@ return ((val << 24) & 0xff000000) | (( val << 8) & 0xff0000) |
((val >> 8) & 0xff00) | ((val >> 24) & 0xff); ((val >> 8) & 0xff00) | ((val >> 24) & 0xff);
} }
volatile int32 rom_loopval = 0;
int32 rom_read_delay (int32 val) int32 rom_read_delay (int32 val)
{ {
uint32 i, l = rom_delay; uint32 i, l = rom_delay;
int32 loopval = 0;
if (rom_unit.flags & UNIT_NODELAY) if (rom_unit.flags & UNIT_NODELAY)
return val; return val;
/* Calibrate the loop delay factor when first used. /* Calibrate the loop delay factor when first used.
Do this 4 times to and use the largest value computed. */ Do this 4 times and use the largest value computed. */
if (rom_delay == 0) { if (rom_delay == 0) {
uint32 ts, te, c = 10000, samples = 0; uint32 ts, te, c = 10000, samples = 0;
@ -503,15 +504,15 @@ if (rom_delay == 0) {
away by a good compiler. loopval always is zero. To avoid smart compilers, away by a good compiler. loopval always is zero. To avoid smart compilers,
the loopval variable is referenced in the function arguments so that the the loopval variable is referenced in the function arguments so that the
function expression is not loop invariant. It also must be referenced function expression is not loop invariant. It also must be referenced
by subsequent code or to avoid the whole computation being eliminated. */ by subsequent code to avoid the whole computation being eliminated. */
for (i = 0; i < c; i++) for (i = 0; i < c; i++)
loopval |= (loopval + ts) ^ rom_swapb (rom_swapb (loopval + ts)); rom_loopval |= (rom_loopval + ts) ^ rom_swapb (rom_swapb (rom_loopval + ts));
te = sim_os_msec (); te = sim_os_msec ();
if ((te - ts) < 50) /* sample big enough? */ if ((te - ts) < 50) /* sample big enough? */
continue; continue;
if (rom_delay < (loopval + (c / (te - ts) / 1000) + 1)) if (rom_delay < (rom_loopval + (c / (te - ts) / 1000) + 1))
rom_delay = loopval + (c / (te - ts) / 1000) + 1; rom_delay = rom_loopval + (c / (te - ts) / 1000) + 1;
if (++samples >= 4) if (++samples >= 4)
break; break;
c = c / 2; c = c / 2;
@ -521,8 +522,8 @@ if (rom_delay == 0) {
} }
for (i = 0; i < l; i++) for (i = 0; i < l; i++)
loopval |= (loopval + val) ^ rom_swapb (rom_swapb (loopval + val)); rom_loopval |= (rom_loopval + val) ^ rom_swapb (rom_swapb (rom_loopval + val));
return val + loopval; return val + rom_loopval;
} }
int32 rom_rd (int32 pa) int32 rom_rd (int32 pa)