Skip to content

Compile Error: "unable to find a register to spill in class 'D_REG

This error only occurs when "-O2" option is specificed. The "complete" compile line I used:

./cc1 -O2 -quiet -fno-gcse -fverbose-asm -W -Wall -Wextra -Wconversion -Werror -fomit-frame-pointer -fno-toplevel-reorder -mint8 -msoft-reg-count=0 -std=gnu99 -fno-time-report ./main.c -o ./main.s

With the main.c file containing:


extern void foo(unsigned long int x, unsigned int b);
static unsigned int v;
 
void bar(void)
{
                foo(v, 0);
}

The gist of the problem with O2 seems to be the building of the parameter list. With O2 enabled, the second parameter (byte 0) is built before the (zeroExtened v).

To be able to zero extend a 8bit variable to a 16bit variable, the compiler needs REG_D (register B of 6809), since this is the only register that can be converted to 16 bit (with the help of register A). But the REG_D is already occupied by the second parameter.

This problem only occurs in later RTL generation. Using the additional parameter -fdump-rtl-all it seems that the reordering of the parameter generation is done in "main.c.175.lreg" (register allocation).

Generated INSN after 171.asmcons:

...
(note 1 0 3 NOTE_INSN_DELETED)

(note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note 2 3 5 2 NOTE_INSN_FUNCTION_BEG)

(insn 5 2 6 2 ./main.c:30 (set (reg:HI 27 [ v+-1 ])
        (zero_extend:HI (mem/u/c/i:QI (symbol_ref:HI ("v") <var_decl 0x7fa9747e0140 v>) [2 v+0 S1 A8]))) 20 {zero_extendqihi2} (nil))

(insn 6 5 7 2 ./main.c:30 (set (reg:QI 6 d)
        (const_int 0 [0x0])) 16 {movqi} (nil))

(insn 7 6 8 2 ./main.c:30 (set (reg:HI 1 x)
        (reg:HI 27 [ v+-1 ])) 9 {*movhi_1} (expr_list:REG_DEAD (reg:HI 27 [ v+-1 ])
        (nil)))
...

Generated INSN after 175.lreg:

...
(note 1 0 3 NOTE_INSN_DELETED)

(note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note 2 3 6 2 NOTE_INSN_FUNCTION_BEG)

(insn 6 2 7 2 ./main.c:30 (set (reg:QI 6 d)
        (const_int 0 [0x0])) 16 {movqi} (nil))

(insn 7 6 8 2 ./main.c:30 (set (reg:HI 1 x)
        (zero_extend:HI (mem/u/c/i:QI (symbol_ref:HI ("v") <var_decl 0x7fa9747e0140 v>) [2 v+0 S1 A8]))) 20 {zero_extendqihi2} (nil))
...

Note the reordering of the "zero_extend" INSN.

I don't know how to change the gcc6809 compiler to circumvent the above behaviour, help would be appreciated!

Thx!

Edited by Christopher Salomon
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information