Closed sy2002 closed 3 years ago
There appears to be a bug in the compiler backend. This can be shown by the following test code:
#include <stdio.h>
// This program should print (according to gcc):
// a=12345678, b=05678000
//
// However, instead it prints:
// a=12345678, b=00008000
int main()
{
unsigned long a = 0x12345678;
unsigned long b = (a & 0xffff) << 12;
printf("a=%08lx, b=%08lx\n", a, b);
}
The line with the shift operation gets compiled to the following assembly code:
move R2,R8
and 65535,R8
and 0xFFFD,R14
shl 12,R8
xor R1,R1
move R8,R0
However, the QNICE instruction "SHL" is only a 16-bit shift, not a 32-bit shift.
Furthermore, if the constant 12
in the example code is changed to a 16
, then the compiler emits the warning:
warning 367 in line 12 of "test.c": shift count too large for data type
This could perhaps suggest that the compiler incorrectly interprets (a & 0xffff)
as generating a 16-bit number.
@sy2002 : Is this something we can fix ourselves, or should we report this to Volker ?
@MJoergen Since this worked with the 4-year old compiler and now does not any more, I suggest that you do the following:
Hi Michael, here is an interessting observation: If I change the shift-left line to read like this:
unsigned long b = ((unsigned long) a & (unsigned long) 0xffff) << (unsigned long) 12;
Then it does work.
That means it looks like this has nothing to do with our very specific QNICE implementation but more with the way how Volker does precedence of operators?
I assume that GCC is doing it right. I will write him an email now.
Fixed and verified.
I used the emulator in mode
switch 3
, so I loaded using the load commandload ../qbin/maze2d.out
and thenswitch 3
and thenrun 0
and then in the VGA screenC
andR
and8000
and then this is the result:No idea if this has to do with the new VBCC (issue #100) or the new emulator (or anything else. Please investigate.