Control register spilling: Is it possible ?

Petar Penchev ptr@melexis.com
Wed May 19 14:03:00 GMT 2004


Hello all,
I have a problem with "movsi" pattern. The GCC target, I am workin on,  
does not support SImode directly. It is being splited to two "movhi"  
patterns using scratch register, but I experiance problems when I try to  
compile newlib's qsort.c. When I try to do that gcc says :
../../../../../newlib_src/newlib/libc/search/qsort.c:222: error: unable to  
finda register to spill in class `CL_NDX_REGS'

the "movsi" pattern is:

(define_insn_and_split "movsi_internal"
  [(set (match_operand:SI 0 "nonimmediate_nonstack_operand" "=m,m, m,b, b")
	(match_operand:SI 1 "general_operand"      		  "m,i, b,im,b"))
  (clobber (match_scratch:HI 2                   "=&a,&b,X, X,X"))]
  ""
  "#"
  "reload_completed"
  [(const_int 0)]
  "split_move (operands[0], operands[1], operands[2]);
   DONE;"
)
and the error message is related to the first alternative which defines  
move from memory to memory.
I tried to write RTL for alternative 0 , which pushes and pops the  
registers I need but the problem remained.

changed pattern looks like :

(define_insn_and_split "movsi_internal"
  [(set (match_operand:SI 0 "nonimmediate_nonstack_operand" "=m,m, m,b, b")
	(match_operand:SI 1 "general_operand"      		  "m,i, b,im,b"))
  (clobber (match_scratch:HI 2                   "=&a,&b,X, X,X"))]
  ""
  "#"
  "reload_completed"
  [
; push X and Y registers
    (set (mem:HI (post_inc:HI (reg:HI S_HREG)))
          (reg:HI X_HREG))
    (set (mem:HI (post_inc:HI (reg:HI S_HREG)))
          (reg:HI Y_HREG))
; save scratch register just in case
   (set (mem:HI (post_inc:HI (reg:HI S_HREG)))
          (reg:HI A_HREG))
; move values
   (set (reg:HI Y_HREG) (match_dup 0))
   (set (reg:HI X_HREG) (match_dup 1))
   (set (reg:HI A_HREG) (mem:HI (reg:HI X_HREG)))
   (set (mem:HI (reg:HI Y_HREG)) (reg:HI A_HREG))
   (set (reg:HI A_HREG) (mem:HI (plus:HI (reg:HI X_HREG) (const_int 2) )))
  (set (mem:HI (plus:HI (reg:HI Y_HREG) (const_int 2)))  (reg:HI A_HREG))
; restore registers from stack
   (set (reg:HI A_HREG)
	       (mem:HI (pre_dec (reg:HI S_HREG))))
   (set (reg:HI Y_HREG)
	       (mem:HI (pre_dec (reg:HI S_HREG))))
   (set (reg:HI X_HREG)
	       (mem:HI (pre_dec (reg:HI S_HREG))))
  ]
  "
    if (which_alternative!=0)
    {
      split_move (operands[0], operands[1], operands[2]);
      DONE;
    }"
)
X_HREG and Y_HREG are index registers A_HREG is used as scretch register.  
The error I get is related to X and Y regs.
Is it possible to control register splilling in RTL, i.e. when I push X  
reg to mark it as available for further usage ?
I am not so sure that this is the best way to handle this problem, so if  
anybody has any idea about it please let me know.

Regards Petar





More information about the Gcc mailing list