Thursday, March 8, 2012

I've gone through the Rush Hour code, and all the awkward workarounds have been backed out except for a problem with this line:

display_at(0,32-strlen(s),s);

For some reason this is being converted to:

display_at(0,strlen(s)-32,s);

If strlen is defined as an external funciton, or a variable is used instead of a constant, this works properly. So, lets follow the development of this code...

from 128r.expand:
(insn 23 22 24 7 emw_test.c:5 (set (reg:HI 23 [ prephitmp.56 ])
(minus:HI (const_int 32 [0x20])
(reg:HI 26))) -1 (nil))

133r.vregs
(insn 23 22 24 6 emw_test.c:7 (set (reg:HI 23 [ prephitmp.56 ])
(minus:HI (const_int 32 [0x20])
(reg:HI 26))) 62 {subhi3} (nil))

140r.gcse1
(insn 23 22 24 7 emw_test.c:7 (set (reg:HI 23 [ prephitmp.56 ])
(minus:HI (const_int 32 [0x20])
(reg:HI 26))) 62 {subhi3} (expr_list:REG_DEAD (reg:HI 26)
(nil)))

162r.regmove
(insn 23 22 24 6 emw_test.c:7 (set (reg:HI 23 [ prephitmp.56 ])
(minus:HI (const_int 32 [0x20])
(reg:HI 23 [ prephitmp.56 ]))) 62 {subhi3} (nil))

This is correct so far, but something changes in step 172 during register allocation.

from 172r.ira:
(insn 23 22 24 emw_test.c:5 (set (reg:HI 2 r2 [orig:23 prephitmp.56 ] [23])
(minus:HI (reg:HI 2 r2 [orig:23 prephitmp.56 ] [23])
(const_int 32 [0x20]))) 62 {subhi3} (nil))

This same pattern shows up even in this simple example:

int sub_seven_word_r(int a) {return(7-a);}

So it turns out I had a typo in the machine description. I mistakenly told GCC that subtraction is commutative, and that operands can be swapped if that will result in better code. However once I fixed that, I started seeing this for the simple examples:

sub_word_seven_reg
li r2, >7
s r1, r2
mov r2, r1
b *r11

sub_byte_one_reg
li r2, >100
sb r1, r2
movb r2, r1
b *r11

sub_byte_one_mem
li r1, >100
sb @memb_a, r1
movb r1, @memb_a
b *r11

sub_word_mem_mem2
mov @memw_b, r1
s @memw_a, r1
mov r1, @memw_a
b *r11

This could be made better:

sub_word_seven_reg
addi r1, -7
neg r1
b *r11

sub_byte_one_reg
li r2, >100
sb r2, r1
neg r1
b *r11

sub_byte_one_mem
li r2, >100
sb r2, @memb_a
neg @memb_a
b *r11

sub_word_mem_mem2
s @memw_b, @memw_a
neg @memw_a
b *r11

So at this point, all of Lucien's issues have been addressed, and Rush Hour has had all the workarounds replaced with correct code. Well, all except for the VDP code which was the first thing I looked at. I have no idea what's going on here, maybe it's a stack corruption problem.

The problem seen when the VDP workarounds are backed out is that after moving the first piece, any keypress which would move the cursor causes the program to restart. I'll probably need to install Classic99 to examine this stack issue.

No comments:

Post a Comment