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]

Re: cross gcc port problem d,y ; 65 movhi/1


> 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]