[PicForth] A program bank switching codegen bug - Christmas special
double whammy
Alex Holden
alex at linuxhacker.org
Fri Dec 17 22:10:07 CET 2004
Ok, here we have two bugs for the price of one. I suspect they're
actually two slightly different manifestations of the same bug.
Basically Picforth sometimes optimises away bank select instructions
when it shouldn't do. I'm not sure if this is specific to the c"
construct but it seemed to be the only reliable way to trigger it (this
has been a particularly difficult one to distill to a minimal example).
The following example causes the PIC to go off into lala land at both
strings (actually it never reaches the second one but you know what I
mean) because pclath is set wrong when it does the 'goto' which is
supposed to skip past the string data.
include libstrings.fs
: type ;
$ffd org
: fred ;
main : test c" hello" type fred c" world" type ;
Changing it to this works around the bug:
include libstrings.fs
: type ;
$ffd org
: fred ;
main : test
forth> no-cbank
c" hello" type
fred
forth> no-cbank
c" world" type
;
Note that the banks which 'test' 'type' and 'fred' are located in seem
to be critical to triggering the bug.
Here's the generated assembly of just the main word from the first
example (without the workaround). When the goto at 0x1000 is executed,
pclath contains 0x8 and it jumps to 0x804 instead of 0x1004. When the
goto at 0x1010 is executed (if the program hadn't already crashed that
is) pclath contains 0x18 and it jumps to 0x1814 instead of 0x1014.
; name: test
; max return-stack depth: 1
0x1000 2804 goto 0x004 ; test + 0x004 (0x1004)
0x1001 3465 data 0x65 ; 0x68 [h] 0x65 [e]
0x1002 366C data 0x6C ; 0x6C [l] 0x6C [l]
0x1003 3780 data 0x80 ; 0x6F [o] 0x00
0x1004 3010 movlw 0x10
0x1005 1703 bsf 0x03,6
0x1006 008F movwf 0x0F
0x1007 3001 movlw 0x01
0x1008 008D movwf 0x0D
0x1009 1303 bcf 0x03,6
0x100A 01A2 clrf 0x22
0x100B 018A clrf 0x0A
0x100C 203E call 0x03E ; type
0x100D 158A bsf 0x0A,3
0x100E 27FD call 0x7FD ; fred (0xFFD)
0x100F 160A bsf 0x0A,4
0x1010 2814 goto 0x014 ; test + 0x014 (0x1014)
0x1011 3BEF data 0xEF ; 0x77 [w] 0x6F [o]
0x1012 396C data 0x6C ; 0x72 [r] 0x6C [l]
0x1013 3200 data 0x00 ; 0x64 [d] 0x00
0x1014 3010 movlw 0x10
0x1015 1703 bsf 0x03,6
0x1016 008F movwf 0x0F
0x1017 3011 movlw 0x11
0x1018 008D movwf 0x0D
0x1019 1303 bcf 0x03,6
0x101A 01A2 clrf 0x22
0x101B 018A clrf 0x0A
0x101C 283E goto 0x03E ; type
--
------------ Alex Holden - http://www.linuxhacker.org ------------
If it doesn't work, you're not hitting it with a big enough hammer
More information about the PicForth
mailing list