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