Documentation Archive Developer
Search

Previous: Machine-Independent Predicates, Up: Predicates


14.7.2 Defining Machine-Specific Predicates

Many machines have requirements for their operands that cannot be expressed precisely using the generic predicates. You can define additional predicates using define_predicate and define_special_predicate expressions. These expressions have three operands:

The program genrecog scans define_predicate and define_special_predicate expressions to determine which RTX codes are possibly allowed. You should always make this explicit in the RTL predicate expression, using MATCH_OPERAND and MATCH_CODE.

Here is an example of a simple predicate definition, from the IA64 machine description:

     ;; True if op is a SYMBOL_REF which refers to the sdata section.
     (define_predicate "small_addr_symbolic_operand"
       (and (match_code "symbol_ref")
            (match_test "SYMBOL_REF_SMALL_ADDR_P (op)")))

And here is another, showing the use of the C block.

     ;; True if op is a register operand that is (or could be) a GR reg.
     (define_predicate "gr_register_operand"
       (match_operand 0 "register_operand")
     {
       unsigned int regno;
       if (GET_CODE (op) == SUBREG)
         op = SUBREG_REG (op);
     
       regno = REGNO (op);
       return (regno >= FIRST_PSEUDO_REGISTER || GENERAL_REGNO_P (regno));
     })

Predicates written with define_predicate automatically include a test that mode is VOIDmode, or op has the same mode as mode, or op is a CONST_INT or CONST_DOUBLE. They do not check specifically for integer CONST_DOUBLE, nor do they test that the value of either kind of constant fits in the requested mode. This is because target-specific predicates that take constants usually have to do more stringent value checks anyway. If you need the exact same treatment of CONST_INT or CONST_DOUBLE that the generic predicates provide, use a MATCH_OPERAND subexpression to call const_int_operand, const_double_operand, or immediate_operand.

Predicates written with define_special_predicate do not get any automatic mode checks, and are treated as having special mode handling by genrecog.

The program genpreds is responsible for generating code to test predicates. It also writes a header file containing function declarations for all machine-specific predicates. It is not necessary to declare these predicates in cpu-protos.h.