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~

Reply via email to