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