I'm currently developing a gameboy emulator and to test the correctness of my emulator I'm using GBDK to compile c programs for my emulator.
I noticed that the compiler (as expected) optimizes multiplications with constants that are a power of two by doing rotates. However it appears that it does not generate the correct amount of rotates for a given power.
For example the following very simple program:
#include <gb/gb.h>
unsigned char one() { return 1; }
void main()
{
unsigned char r;
// Force compiler to generate muliplication by deferring the '1'
r = one() * 32;
// Store result somewhere
*((unsigned char*)(0xFFFE)) = r;
}
Generates the following assembly:
___main_start:
_main:
push bc
; reproduce.c 14
; genCall
call _one
ld c,e
; genLeftShift
ld a,c
rr a
rr a
rr a
and a,#0xE0
ld c,a
; reproduce.c 16
; genAssign
ld de,#0xFFFE
; genAssign (pointer)
ld a,c
ld (de),a
; genLabel
00101$:
; genEndFunction
pop bc
ret
___main_end:
.area _CODE
Which to me appears to be incorrect as the RR instruction actually rotates through the carry flag, effectively making it a 9-bit rotate. This means that there should be an additional rotate to produce the correct result instead of the current (0x40) wrong result.
Visualization:
Start: A = 00000001 Carry = 0
RR A: A = 00000000 Carry = 1
RR A: A = 10000000 Carry = 0
RR A: A = 01000000 Carry = 0 <- WRONG!
Can anyone verify that this is indeed a bug in the SDCC compiler that comes with GBDK? I'm also interested in the use of the and instruction following the rotates.
Using the latest (3-2.93) version of GBDK for windows from sourceforge.