17.24.1.1 Defining Mode Iterators

The syntax for defining a mode iterator is:

(define_mode_iterator name [(mode1 "cond1") … (moden "condn")])

This allows subsequent .md file constructs to use the mode suffix :name. Every construct that does so will be expanded n times, once with every use of :name replaced by :mode1, once with every use replaced by :mode2, and so on. In the expansion for a particular modei, every C condition will also require that condi be true.

For example:

(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])

defines a new mode suffix :P. Every construct that uses :P will be expanded twice, once with every :P replaced by :SI and once with every :P replaced by :DI. The :SI version will only apply if Pmode == SImode and the :DI version will only apply if Pmode == DImode.

As with other .md conditions, an empty string is treated as “always true”. (mode "") can also be abbreviated to mode. For example:

(define_mode_iterator GPR [SI (DI "TARGET_64BIT")])

means that the :DI expansion only applies if TARGET_64BIT but that the :SI expansion has no such constraint.

It is also possible to include iterators in other iterators. For example:

(define_mode_iterator VI [V16QI V8HI V4SI V2DI])
(define_mode_iterator VF [V8HF V4SF (V2DF "TARGET_DOUBLE")])
(define_mode_iterator V [VI (VF "TARGET_FLOAT")])

makes ‘:V’ iterate over the modes in VI and the modes in VF. When a construct uses ‘:V’, the V8HF and V4SF expansions require ‘TARGET_FLOAT’ while the V2DF expansion requires ‘TARGET_DOUBLE && TARGET_FLOAT’.

Iterators are applied in the order they are defined. This can be significant if two iterators are used in a construct that requires substitutions. See Substitution in Mode Iterators.