I tried something similar: (define_expand "movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "") (match_operand:DI 1 "general_operand" ""))] "" " if(my_expand_move (operands[0], operands[1])) DONE; ")
(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"))] "my_move_ok (operands[0], operands[1])" "* return my_move_2words (operands, insn); " [(set_attr "type" "move,arith,load,store,store,load,store,store") (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,DI") (set_attr "length" "1,1,1,1,1,1,1,1")]) int my_expand_move (rtx op0, rtx op1) { /* Removed PIC, etc. for the moment */ if ( ((reload_in_progress | reload_completed) == 0 && MEM_P (op0) && !REG_P (op1))) { op1 = force_reg (GET_MODE (op0), op1); emit_move_insn (op0, op1); return 1; } return 0; } bool my_move_ok(rtx op0, rtx op1) { if (MEM_P (op0)) return register_operand (op1, VOIDmode); return true; } This seems to do what I want, now I'm going to clean up all those constraints and see if they are compatible and work on from there. Thanks for your help, tell me if my solution seems very bad, Jc On Wed, Jul 1, 2009 at 3:26 PM, Richard Henderson<r...@redhat.com> wrote: > 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~ >