On 07/01/2009 11:28 AM, Jean Christophe Beyler wrote:
Ok, I think I understand, I've been therefore playing with this. I
initially had:
(define_insn "movdi_internal1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,R,T,r,R,o")
(match_operand:DI 1 "general_operand" "r,iF,R,J,J,o,r,r"))]
For my movdi. I therefore first wanted to handle the fact that I won't
allow stores to use immediates so I thought of changing the above
into:
(define_insn "movdi_internal1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,R,T,r,R,o")
(match_operand:DI 1 "move_operand" "r,iF,R,J,J,o,r,r"))]
And then defining a simple predicate:
(define_predicate "move_operand"
(if_then_else (match_operand 0 "register_operand")
(match_operand 1 "general_operand")
(match_operand 1 "register_operand")))
Predicates can only examine one operand, not two.
However, you can write
(define_expand "movdi"
[(set (match_operand:DI "nonimmediate_operand" "")
(match_operand:DI "general_operand" ""))]
""
"my_expand_move (operands[0], operands[1]); DONE;")
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand" "...")
(match_operand:DI 1 "general_operand" "..."))]
"my_move_ok (operands[0], operands[1])"
...)
void my_expand_move (rtx op0, rtx op1)
{
// Handle TLS, PIC and other special cases...
if (MEM_P (op0))
op1 = force_reg (mode, op1);
emit_insn (gen_rtx_SET (VOIDmode, op0, op1));
}
bool my_move_ok(rtx op0, rtx op1)
{
if (MEM_P (op0))
return register_operand (op1, VOIDmode);
return true;
}
Compare this with similar code in other ports.
r~