This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.
See the CrossGCC FAQ for lots more information.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
> I'm now porting gcc to the embeded processor, which in short has 1 > accumulator register and 3 index registers (BASE_REGS in gcc sence). > > Instruction set of this processor is poor enough. ;-)) Most of the > arithmetic operations deals with accumulator register and memory operand > which can be addressed with index regs only. One of this index regs I'm > using as stack pointer, so the only 2 remaining index regs can be used for > gcc needs. This sounds just like our Motorola 68HC12 port. > The first one is the "Unable to find a register to spill" problem. > This occures when gcc tries to occupy too many index registers in most > cases. The simplest example for this problems is the following > function: > > void rstrcpy(int * src, int * dst) > { > while (*dst++ = *src++); > } > > When my gcc port compiles this code with just "xgcc test3.c -S" I've > no luck. I've got "Unable to find a register to spill". But when I > simply add -fomit-frame-pointer everything is OK, and the resulting > asm file looks fine (r1 is the stack pointer, r2, r3 is the index > registers and the rr is the accumulator register): > > mov r1:2,rr > mov rr,r3 > mov r1:3,rr > mov rr,r2 > L5: > mov r3:0,rr > mov rr,r2:0 > inci r3,1 > inci r2,1 > ; tstqi > bnea 0,L5 > So, as seems "Unable to find a register to spill" occures when gcc did > not find index registers enough for this sequence. So, when I've used > "-fomit-frame-pointer" r2 (my frame pointer) was freed and gcc > compiles successfully. Do you really need a frame pointer? If not, your emitted code will be somewhat more efficient due to the extra index register. > But why gcc tries to place both pointers on to the regs? Unfortunatly > my gcc port can't handle at all the following function: > > void rstrcpy(int * src, int * dst, int * dst2) > { > while (*dst2++ = *dst++ = *src++); > } > > Theoreticaly gcc should pro > duc > e something like this: > > mov r1:2,rr > mov rr,r3 > L5: > mov r1:3,rr > mov rr,r2 > mov r3:0,rr > mov rr,r2:0 > inci r2,1 > mov r2,rr > mov rr,r1:3 > > mov r1:4,rr > mov rr,r2 > mov r3:0,rr > mov rr,r2:0 > inci r2,1 > mov r2,rr > mov rr,r1:4 > > inci r3,1 > ; tstqi > bnea 0,L5 > > So, what to do? I'm already make the following defines > #define SMALL_REGISTER_CLASSES 1 > #define CLASS_LIKELY_SPILLED_P(CLASS) 1 First, I don't think you should define CLASS_LIKELY_SPILLED_P(CLASS). The manual says not to define this unless necessary. Second, my guess is that you need to loosen up the constraints on some of your instruction patterns. To find out which ones, dump out all of the intermediate stages with "-da". Study the result and try to understand what is happening to your code as it progresses through the optimizer. We often found that we had to supply extra instruction alternatives for register-to-register operations. Of course, these could only be emulated with multi-instruction sequences, but in practice, the compiler would use them rarely, if at all. Third, make sure you have enough movXX alternatives. The movXX insns are specal cases, in that unlike other insns, they can be generated in the reload pass. You will probably need "rr" to/from "rN" alternatives, even if these are inefficient. > but has no luck in the spills. Any one can help me with this problem? > > And the second problem is the absence of the "compare" instructions in > this processor. So I've defined this operation with substraction > instructions, but as side effect my compare instruction alters the > accumulator register, so I've tried to write something like: > (define_insn "cmpqi" > [(set (cc0) > (compare (match_operand:QI 0 "register_operand" "r") > (match_operand:QI 1 "general_operand" "m"))) > (clobber (reg:QI 0))] > but again has no luck. :-(( Because gcc "performs" this insn in parallel > and the only valid operand also comes in reg:QI 0, gcc aborts. Where does it abort? Have a look at the code there and try to understand why. Often you will find that someone else has had a similar problem and that you can apply their solution if you know about it. > So, can anyone advise me how to specify clobbering correctly? I'm not sure what to tell you here. You can obviously work around this problem by saving and restoring rr within the instruction pattern. As a bit of encouragement, your target is very similiar to the Motorola HC1x, and your approach is similar to ours, in that you are not using "pseudo-registers" in RAM. Have a look at our port, (at www.realtime.bc.ca), especially the HC12 port. For example, our HC12 port gives: 5 _rstrcpy__FPiN20 6 0000 1B9E leas -2,s 7 8 0002 6C80 std 0,s ; 4 movhi/4 9 0004 EE84 ldx 4,s ; 5 movhi/3 10 0006 B746 tfr d,y ; 65 movhi/1 11 0008 2002 bra L7 ; 59 jump 12 13 14 000a ED80 L2 ldy 0,s ; 73 movhi/3 15 16 000c EC71 L7 ldd 2,y+ ; 19 movhi/3 17 000e 6D80 sty 0,s ; 75 movhi/4 18 0010 6C31 std 2,x+ ; 20 movhi/4 19 0012 ED86 ldy 6,s ; 77 movhi/3 20 0014 6C71 std 2,y+ ; 22 movhi/4 21 0016 6D86 sty 6,s ; 79 movhi/4 22 0018 8C0000 tstd ; 26 tsthi 23 001b 26ED bne L2 ; 27 branch_true 24 25 26 001d 1B82 leas 2,s 27 001f 3D rts for your second example. In the HC12, "d" is the accumulator, "x" and "y" are the index registers, and "s" is the stack pointer. The above code is with -fomit-frame-pointer. Note that x gets a stable value, but y is spilled as necessary to use it for two different pointers. With -no-omit-frame-poitner, we get 5 _rstrcpy__FPiN20 6 0000 34 pshx 7 0001 B775 tfr s,x 8 0003 1B9E leas -2,s 9 10 0005 6C1E std -2,x ; 4 movhi/4 11 0007 B746 tfr d,y ; 65 movhi/1 12 0009 2002 bra L7 ; 59 jump 13 14 15 000b ED1E L2 ldy -2,x ; 77 movhi/3 16 17 000d EC71 L7 ldd 2,y+ ; 19 movhi/3 18 000f 6D1E sty -2,x ; 79 movhi/4 19 0011 ED04 ldy 4,x ; 81 movhi/3 20 0013 6C71 std 2,y+ ; 20 movhi/4 21 0015 6D04 sty 4,x ; 83 movhi/4 22 0017 ED06 ldy 6,x ; 85 movhi/3 23 0019 6C71 std 2,y+ ; 22 movhi/4 24 001b 6D06 sty 6,x ; 87 movhi/4 25 001d 8C0000 tstd ; 26 tsthi 26 0020 26E9 bne L2 ; 27 branch_true where x has become the frame pointer. Note the continual spilling of the y register and the reloading of it with each pointer value in turn. Good luck, and keep us posted on your progress. Regards, David Querbach Real-Time Systems Inc. ------ Want more information? See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/ Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |