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")))

For me this means :
If the first operand is a register (that would then either be a
register-register move or a load),
   Then return whether or not operand 1 is a general operand
   Else it's a memory operand (by definition of the
nonimmediate_operand predicate) and
                  return whether or not operand 1 is a register operand

In essence, it seemed to me that this should work as a first draft in
rewriting the whole movdi (and let me test it). However, this makes
the compiler fail on this instruction (unrecognisable)

st4.c:66: error: unrecognizable insn:
(insn 41 40 42 3 st4.c:22 (set (reg/f:DI 119)
        (symbol_ref:DI ("data") <var_decl 0xb7c8ebb0 data>)) -1 (nil))


For me this doesn't make sense since in this set, the predicate should
check the first register. The test of the if should be true, therefore
matching the second operand to a "general_operand" that it is, no?

Thanks for your help,
Jean Christophe Beyler

On Wed, Jul 1, 2009 at 12:23 PM, Richard Henderson<r...@redhat.com> wrote:
> On 07/01/2009 08:36 AM, Jean Christophe Beyler wrote:
>>
>> I tracked it down to the gcse pass. However, I thought I had turned
>> this off in the definition of a movdi in my machine description. But
>> apparently this is not sufficient, any ideas?
>
> You probably just changed the constraint letters, but didn't change
> the operand predicate.  The constraint letters are only used during
> register allocation, and the predicate is used elsewhere.
>
>  (match_operand:MODE N "predicate_function" "constraint_letters")
>
> There are a number of pre-defined predicate functions you can use,
>
>  register_operand
>  nonmemory_operand
>  nonimmediate_operand
>  general_operand
>
> and most ports find they need special ones to exactly match the
> characteristics of some insns.  e.g.
>
> cpu.md:
> (define_insn "*adddi_internal"
>  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
>        (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
>                 (match_operand:DI 2 "add_operand" "r,K,L")))]
>  ""
>  "@
>   addq %1,%2,%0
>   lda %0,%2(%1)
>   ldah %0,%h2(%1)")
>
> predicates.md:
> (define_predicate "add_operand"
>  (if_then_else (match_code "const_int")
>    (match_test "satisfies_constraint_K (op) ||
>                 satisfies_constraint_L (op)")
>    (match_operand 0 "register_operand")))
>
> You should strive to ensure that the predicate function exactly
> matches the constraint letters.  If the predicate function accepts
> more than the constraint letters, the reload pass will fix it up.
> But better code is generated when reload doesn't need to do this.
>
>
> r~
>

Reply via email to