On Wednesday 12 April 2006 15:43, Rask Ingemann Lambertsen wrote:
> On Wed, Apr 12, 2006 at 07:47:32AM +0200, Frank Riese wrote:
> > On Monday 10 April 2006 19:48, you wrote:
> > > Can it at least add (small) immediates to registers?
> >
> > Nope, sry. The only instructions that take other arguments than registers
> > are the aforementioned LDL/LDH (load low/high), branch instructions (they
> > take a memory address) and four bit operations which can mask, invert,
> > set or delete a bit in a register.
>
> This will increase the probability of reload failures when storing through
> a pointer, because of the need for an extra register to hold the offset in
> some cases. For example
>
> int x, *p;
> p[15] = x;
> /* p not used after this */
>
> LDL R[4], 30
> LDH R[4], 0
> ADD R[3], R[3], R[4]
> STO R[3], R[2]
>
> > > #define GO_IF_LEGITIMATE_ADDRESS(XMODE, X, LABEL) \
> > > if (REG_P (X)) \
> > > goto LABEL;
> >
> > I tried that out today. I wasn't sure about the exact contexts in which
> > this macro is used. It seems to work fine, though.
>
Rask, Dave, thanks for your answers so far!
Sry for not answering for some time but the last two weeks were pretty busy
for me and I wans't able to try out all of your suggestions until yesterday. I
also tried to read up on compilers and GCC internals the best I could before
requesting your help again - hope I don't ask any redundant questions.
I moved my code to mainline and the segmentation faults I had before
disappeared. Not making BP fixed seems to have helped with a lot of code, too.
However, I'm still having problems with reloading/register spilling:
-------------------------------------------------------------------------------------
/usr/local/src/gcc/objdir/./gcc/xgcc -B/usr/local/src/gcc/objdir/./gcc/
-B/usr/local/zykluno-none/bin/ -B/usr/local/zykluno-none/lib/
-isystem /usr/local/zykluno-none/include -isystem
/usr/local/zykluno-none/sys-include
-O2 -O2 -g -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings
-Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition
-isystem ./include -g -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED
-Dinhibit_libc -I. -I. -I../../gcc -I../../gcc/. -I../../gcc/../include
-I../../gcc/../libcpp/include -I../../gcc/../libdecnumber
-I../libdecnumber -DL_muldi3 -c ../../gcc/libgcc2.c -o libgcc/./_muldi3.o
cc1: warning: target system does not support debug output
cc1: warning: target system does not support debug output
../../gcc/libgcc2.c: In function '__muldi3':
../../gcc/libgcc2.c:520: error: unable to find a register to spill in
class 'GENERAL_REGS'
../../gcc/libgcc2.c:520: error: this is the insn:
(insn 436 435 442 6 ../../gcc/libgcc2.c:520 (set (reg/f:HI 5 R[5] [+6 ])
(mem/s/c:HI (reg/f:HI 198) [0+2 S2 A16])) 17 {movhi} (nil)
(expr_list:REG_DEAD (reg/f:HI 198)
(nil)))
../../gcc/libgcc2.c:520: internal compiler error: in spill_failure, at
reload1.c:1912
-------------------------------------------------------------------------------------
I looked at the offending lines in libgcc2.c and it seems to me that the only
problem with that code is that the compiler needs a lot of registers for the
structures and members and thus runs out of registers.
I followed your suggestion and dumped the *.greg of libgcc2.c
(-fdump-rtl-greg-details):
-------------------------------------------------------------------------------------
[...]
Using reg 2 for reload 0
Using reg 3 for reload 1
Spilling for insn 425.
Using reg 2 for reload 0
Using reg 3 for reload 1
Spilling for insn 426.
Using reg 2 for reload 0
Using reg 3 for reload 1
Spilling for insn 433.
Using reg 3 for reload 0
Spilling for insn 434.
Using reg 4 for reload 0
Spilling for insn 435.
Using reg 5 for reload 0
Spilling for insn 436.
reload failure for reload 0
Reloads for insn # 436
Reload 0: reload_in (HI) = (reg/f:HI 198)
GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1)
reload_in_reg: (reg/f:HI 198)
-------------------------------------------------------------------------------------
With my limited experience I would say that this tells me that the compiler
gradually uses up all available registers and then, instead of freeing one,
it complains that it hasn't any left (as a reminder: registers 3-7 are my
GENERAL_REGS with BP being number 6 and SP number 7).
If that helps, here are the last few instructions before the compiler fails:
-------------------------------------------------------------------------------------
[...]
(note 430 426 431 6 NOTE_INSN_FUNCTION_END)
(note 431 430 433 6 ("../../gcc/libgcc2.c") 520)
(insn 433 431 434 6 ../../gcc/libgcc2.c:520 (set (reg:HI 2 R[2] [ <result> ])
(subreg:HI (reg:DI 30 [ <result> ]) 0)) 17 {movhi}
(insn_list:REG_DEP_TRUE 426 (nil))
(nil))
(insn 434 433 435 6 ../../gcc/libgcc2.c:520 (set (reg:HI 3 R[3] [+2 ])
(subreg:HI (reg:DI 30 [ <result> ]) 2)) 17 {movhi} (nil)
(nil))
(insn 435 434 436 6 ../../gcc/libgcc2.c:520 (set (reg:HI 4 R[4] [+4 ])
(subreg:HI (reg:DI 30 [ <result> ]) 4)) 17 {movhi} (nil)
(expr_list:REG_DEAD (reg:DI 30 [ <result> ])
(nil)))
(insn 436 435 442 6 ../../gcc/libgcc2.c:520 (set (reg/f:HI 5 R[5] [+6 ])
(mem/s/c:HI (reg/f:HI 198) [0+2 S2 A16])) 17 {movhi} (nil)
(expr_list:REG_DEAD (reg/f:HI 198)
(nil)))
(insn 442 436 0 6 ../../gcc/libgcc2.c:520 (use (reg/i:DI 2 R[2])) -1
(insn_list:REG_DEP_TRUE 433 (nil))
(nil))
;; End of basic block 6, registers live:
2 [R[2]] 3 [R[3]] 4 [R[4]] 5 [R[5]] 6 [BP] 7 [SP]
-------------------------------------------------------------------------------------
The problem is that he does know how to spill registers (= move the contents
of a register to a temporary storage place to free up a register) in
GENERAL_REGS, right?
So, IMHO I need to provide him with a way to free up a register: e.g. by
pushing the contents of a register onto the stack and restoring it
afterwards - or somewhere else in memory.
Perhaps I'm just missing an instruction in the machine defintion so that he
does not know how to do that? Would he do this with a movm instruction? Or
with a pushm? I tried to provide him with scratch registers via
reload_[in/out] instructions but he does not seem to use those instructions
at all.
I think that my constraints for my move instructions are correct, too:
-------------------------------------------------------------------------------------
(define_insn "movhi"
[(set (match_operand:HI 0 "general_operand" "=r,r,m,r,X")
(match_operand:HI 1 "general_operand" " r,m,r,i,X"))]
""
"@ OR \t%0, R[0], %1
LDD \t%0, %1
STO \t%0, %1
LDH \t%0, %H1\n\tLDL \t%0, %L1
XXX"
)
-------------------------------------------------------------------------------------
I inserted the last pair of constraints to see if the compiler's trying to do
anything he normally can't.
I also provided a push instruction, so I think GCC should be able to save away
a register:
-------------------------------------------------------------------------------------
(define_insn "pushhi1"
[(match_operand:HI 0 "register_operand" "")]
""
{
zykluno_output_push(operands[0]);
}
)
-------------------------------------------------------------------------------------
I read the GCC internals section about target macros for register classes
again (SECONDARY_RELOAD_CLASS, SECONDARY_MEMORY_NEEDED,
CLASS_LIKELY_SPILLED_P, SMALL_REGISTER_CLASSES, etc.), but those don't seem to
help as most of them seem to tell the compiler that he is always supposed to
copy the contents of certain registers in a special way and not how to free
some when he runs out of registers.
I might be wrong, but I guess I'm missing something very basic. To sum up, I
think the problem is that I just didn't provide GCC with a way to save away a
register. However, I've run out of ideas how to enable GCC to do so.
Your suggestions have been very helpful so far and I hope to hear from you
again.
Cheers,
Frank