Known GCC bugs/deficiencies

For corresponding project and test setup look at:
".../Vide/projects/GCC 6809 Bugs"
for the project.

Notice:
Changing to different optimization CFLAGS can have a "soothing" effect on these "Bugs".

As of now two "bugs" with the gcc compiler setup or known:

1 gcc6809 bug: division and shift operators with non constant 2nd operand

gcc6809 cannot handle shifts if the right operand is a non-constant int or char gcc6809 cannot handle division if the divisor is a non-constant int or char

all other types, unsigned oned and longs, seem to work

gcc crashes with an error message like:

sourcemain.c: In function "main':
sourcemain.c:68: error: unable to find a register to spill in class "Q REGS'
sourcemain.c:68: error: this is the insn:
  (insn 20 19 21 3 sourcemain.c:59 (set (mem/c/i:QI (plus:HI (reg/f:HI 12 soft fp)
                  (const int -3 [0xfffffffd])) [0 c+0 S1 A8])
          (ashift:QI (const int 123 [0x7b])
              (reg:QI 35))) 60 {ashlqi3 reg} (expr list:REG DEAD (reg:QI 35)
          (nil)))
sourcemain.c:68: confused by earlier errors, bailing out

or an error message like:

sourcemain.c: In function "main':  
sourcemain.c:68: error: insn does not satisfy its constraints:  
(insn 66 28 30 sourcemain.c:59 (set (reg:QI 6 d [44])  
      (reg:QI 1 x)) 16 {movqi} (nil))  
sourcemain.c:68: internal compiler error: in extract constrain insn cached, at recog.c:1918  
Please submit a full bug report,  
with preprocessed source if appropriate.  
See <URL:http:www.oddchange.com/gcc6809> for instructions.  

unfortunately, gcc6809 is not maintained anymore workaround solution: cast operands to (unsigned [long] int)

Work around

Usually, it is not difficult to work around this. In general, it should be considered if a division or shift (with non constant operand) is really needed, as these operations are rather slow on the mc6809 (i.e. the code which is generated). If division can be restricted to powers of two, use shifts instead. If shifts by a non constant bit number are needed, write a loop which repeatedly shifts by 1 bit (the mc6809 does not have an n-bit shift instruction anyway, so this is always done in some kind of loop).

2 gcc6809 bug: expressions

sometimes gcc6809 crashes if an expression is too complex in a sense that too many intermediate values must be kept in memory

error messages look like this:


In file included from sourcemain.c:14:
source/bug expr.h: In function "bug expr':
source/bug expr.h:38: error: unable to find a register to spill in class "Q REGS'
source/bug expr.h:38: error: this is the insn:
 (insn 9 8 10 2 source/bug expr.h:28 (set (reg:QI 31 [ D.1782 ])
         (minus:QI (reg:QI 33 [ D.1780 ])
               (reg:QI 6 d [orig:32 D.1781 ] [32]))) 32 {subqi3} (expr list:REG DEAD (reg:QI 33 [ D.1780 ])
         (expr list:REG DEAD (reg:QI 6 d [orig:32 D.1781 ] [32])
               (nil))))
source/bug expr.h:38: confused by earlier errors, bailing out

unfortunately, gcc6809 is not maintained anymore workaround solution: use temporary variables to store intermediate results

Work around

Usually, it is not difficult to work around this. In general, expressions that get too complex are also very hard to read and to understand, so it might be a good idea to rewrite them anyway. Moreover, performance is usually not affected by this, as the compiler has to store intermediate results in some form anyway.