Moving on, there is a missing typecast
unsigned char Round;
#define VDPWD *((volatile char*)0x8C00)
void modulo()
{
VDPWD = '0' + Round % 10;
}
This compiles to:
modulo
movb @Round, r1 * get the variable into R1 MSB
srl r1, 8 * move to LSB
mov r1, r2 * copy to R2
clr r1 * zero R1 (32-bit value is now >000000xx)
li r3, >A * load R3 with 10 (divisor)
div r3, r1 * do the division (R1 has dividend, R2 has remainder)
mov r2, r1 * copy R2 to R1 - however, remainder was 16 bit! We are about to treat it like 8-bit.
* Missing "swpb r1" here
ai r1, >3000 * add '0' as an 8-bit byte value - this is wrong <--- br=""> movb r1, @>8C00 * move the result to the video chip
Looking through the RTL, we find this sequence in 131r.initvals:
(insn 9 8 10 3 tursi5.c:6 (set (reg:QI 21 [ D.1197 ])
(plus:QI (subreg:QI (reg:HI 25) 1)
(const_int 48 [0x30]))) -1 (nil))
In assembly, this would be:
swpb r1 * <-- ah="" br="" ha="" instruction="" is="" missing="" our="" this="">ai r1, >3000
Somewhere in step 172, register allocation, the type conversion gets lost
(insn 9 8 11 2 tursi5.c:6 (set (reg:QI 1 r1 [orig:21 D.1197 ] [21])
(plus:QI (reg:QI 1 r1 [orig:21 D.1197 ] [21])
(const_int 48 [0x30]))) 59 {addqi3} (nil))
In assembly, this would just be:
ai r1, >3000
Poop, we've found yet another case where GCC assumes that no effort is required to switch between 8-bit and 16-bit values. In order to fix this, we're going to have to dig deep into the guts.
-->--->
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment