Code iterators operate in a similar way to mode iterators. See Mode Iterators.
The construct:
(define_code_iterator name [(code1 "cond1") ... (coden "condn")])
defines a pseudo rtx code name that can be instantiated as codei if condition condi is true. Each codei must have the same rtx format. See RTL Classes.
As with mode iterators, each pattern that uses name will be expanded n times, once with all uses of name replaced by code1, once with all uses replaced by code2, and so on. See Defining Mode Iterators.
It is possible to define attributes for codes as well as for modes.
There are two standard code attributes: code
, the name of the
code in lower case, and CODE
, the name of the code in upper case.
Other attributes are defined using:
(define_code_attr name [(code1 "value1") ... (coden "valuen")])
Here's an example of code iterators in action, taken from the MIPS port:
(define_code_iterator any_cond [unordered ordered unlt unge uneq ltgt unle ungt eq ne gt ge lt le gtu geu ltu leu]) (define_expand "b<code>" [(set (pc) (if_then_else (any_cond:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "")) (pc)))] "" { gen_conditional_branch (operands, <CODE>); DONE; })
This is equivalent to:
(define_expand "bunordered" [(set (pc) (if_then_else (unordered:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "")) (pc)))] "" { gen_conditional_branch (operands, UNORDERED); DONE; }) (define_expand "bordered" [(set (pc) (if_then_else (ordered:CC (cc0) (const_int 0)) (label_ref (match_operand 0 "")) (pc)))] "" { gen_conditional_branch (operands, ORDERED); DONE; }) ...