The problem seems to always be related to stuff in show_score. I've changed that function to just do this:
void show_score() {
char s[7];
if(score) {
itoa(score,s);
itoa(score,s);}
}
show_score
ai r10, >FFF2 allocate 14 bytes
mov r10, r0
mov r11, *r0+ sp[0]=r11
mov r9, *r0+ sp[2]=r9
mov r13, *r0+ sp[4]=r13
mov @score, r1 r1=score
jeq L193 if score==0 goto L193
li r9, itoa r9=itoa
mov r10, r13 r13=sp
inct r13
mov r13, r2 r2=&sp[2] (should be &sp[6], r9, r13 lost)
bl *r9
mov @score, r1
mov r13, r2
bl *r9
L193
mov *r10+, r11
mov *r10+, r9
mov *r10+, r13
ai r10, >8
b *r11
It looks like the location of the stack variables is being calculated wrongly. Time to dig into that.
The problem is that the stack code replaced the local frame with the stack pointer plus offset, the offset was incorrectly calculated. The size of he saved registers were not taken into consideration. Now that's taken care of, things are much better.
I'm a terrible liar. Building from scratch resulted in this mess:
main.o: In function `show_score':
(.text+0x9e5): relocation truncated to fit: R_TMS9900_PC8 against `.text'
make: *** [all] Error 1
000009d0
9d0: 02 2a ff f4 ai r10, >FFF4
9d4: c6 8b mov r11, *r10
9d6: ca 89 00 02 mov r9, @>0002(r10)
9da: c0 60 00 28 mov @>0028, r1
9de: 13 00 jeq 0
9e0: d1 6a 00 04 movb @>0004(r10), r5
9e4: 13 00 jeq 0
9e6: c2 4a mov r10, r9
9e8: 02 29 00 04 ai r9, >0004
9ec: c0 49 mov r9, r1
Here's that relocation:
000009e5 00000101 R_TMS9900_PC8 00000000 .text + ae6
This results in a displacement of 0x101, which won't fit in the JEQ instruction. This is disappointing. I'll have to find some way to distinguish short and long jumps and stick that in the compiler.
check out s390_shorten_branches for possible ideas also look for "branch" and "range" in the other machine config files.
No comments:
Post a Comment