GCC generates Buggy Code II.
Hehe... sorry - but since "we" used gcc 6809 quite a lot in the last 2 years... some things have come up: main.c
In the example code (compiled with options: -O2 -quiet -fverbose-asm -W -Wall -Wextra -Wconversion -fomit-frame-pointer -mint8 -msoft-reg-count=0 -std=gnu99 -fno-time-report ) (I have produced similar buggy code with other options, but it is difficult to reproduce)
GCC produces buggy code. When calculating "16bit values" / "the address of a pointer" it mixes "d" and "x" registers so thorowly, that the resulting d register contains the wrong value.
The example seems rather exotic - the bug occured in "real life" but the example is a bit far fetched, since in order to produce the bug, it seems gcc has to be "stressed".
Generated code (somehwere in the middle, my source at about line 90):
addb _tmp+9 ; , <variable>.count1
stb 2,s ; , D.1214
stb _tmp+9 ; , <variable>.count1
sex ;extendqihi2: R:b -> R:d ; ,
! tfr d,x ; , D.1214
! exg d,x ; , D.1217
! addd ,s ; ,
! exg d,x ; , D.1217
std _tmp+3 ; D.1217, <variable>.count3
ldb 2,s ; , D.1214
sex ;extendqihi2: R:b -> R:d ; ,
The "!" code is wrong. After the sex the value is to be calculated in "D". The tfr "doubles" the value in D to the X register, the following exg is "nonsense", than the addd actually calculates the correct value in D, the following exg is not only nonsense but defenitly a bug, since the register D ist reset with its former value from register X.
following would be Ok:
addb _tmp+9 ; , <variable>.count1
stb 2,s ; , D.1214
stb _tmp+9 ; , <variable>.count1
sex ;extendqihi2: R:b -> R:d ; ,
! addd ,s ; ,
! tfr d,x ; , D.1214
std _tmp+3 ; D.1217, <variable>.count3
ldb 2,s ; , D.1214
sex ;extendqihi2: R:b -> R:d ; ,
This would result in the correct value in D and in "X", when it is needed. (I have seen same code generated, where this section needs to calculate "X" instead of "D", so X should probably be kept).