satz@CISCO.COM (02/14/89)
gcc 1.33 on SunOS 3.5 generates incorrect code depending on whether volatiles are assigned to shorts or longs. Consider the following program: ---------------------------------------- extern volatile unsigned long *rand; extern unsigned char *head; typedef struct list_ { struct list_ *next; unsigned short s; } listtype; unsigned short test () { register listtype *p; #ifdef BUG register unsigned short s; #else register unsigned int s; #endif while (1) { #ifdef BUG s = (unsigned short) (*rand & 0xFFFF); #else s = *rand & 0xFFFF; #endif for (p = (listtype *)head; p; p = p->next) { if (p->s == s) break; } if (!p) return(s); } } ---------------------------------------- If you don't define BUG, you get the correct assembler generated. That is I expect rand to be dereferenced everytime through the loop since it is declared volatile. #NO_APP gcc_compiled.: .text .even .globl _test _test: link a6,#0 movel d2,sp@- movel _rand,a1 clrl d2 L2: movel a1@,d0 #dereferencing rand movel d0,d1 andl #65535,d1 movel _head,a0 tstl a0 jeq L5 clrl d0 L8: movew a0@(4),d0 cmpl d0,d1 jeq L5 movel a0@,a0 tstl a0 jne L8 L5: tstl a0 jne L2 movew d1,d2 movel d2,d0 movel a6@(-4),d2 unlk a6 rts However if BUG is defined, we make the temporary variable a short and rand is no longer reloaded through the loop. A surprise follows... #NO_APP gcc_compiled.: .text .even .globl _test _test: link a6,#0 movel _rand,a0 movew a0@(2),d0 #once is not enough clrl d1 L2: movel _head,a0 tstl a0 jeq L5 L8: cmpw a0@(4),d0 jeq L5 movel a0@,a0 tstl a0 jne L8 L5: tstl a0 jne L2 movew d0,d1 movel d1,d0 unlk a6 rts