The define_attr
expression is used to define each attribute required
by the target machine. It looks like:
(define_attr name list-of-values default)
name is a string specifying the name of the attribute being
defined. Some attributes are used in a special way by the rest of the
compiler. The enabled
attribute can be used to conditionally
enable or disable insn alternatives (see Disable insn alternatives using the enabled
attribute). The predicable
attribute, together with a
suitable define_cond_exec
(see Conditional Execution), can
be used to automatically generate conditional variants of instruction
patterns. The mnemonic
attribute can be used to check for the
instruction mnemonic (see Mnemonic Attribute). The compiler
internally uses the names ce_enabled
and nonce_enabled
,
so they should not be used elsewhere as alternative names.
list-of-values is either a string that specifies a comma-separated list of values that can be assigned to the attribute, or a null string to indicate that the attribute takes numeric values.
default is an attribute expression that gives the value of this attribute for insns that match patterns whose definition does not include an explicit value for this attribute. See Example of Attribute Specifications, for more information on the handling of defaults. See Constant Attributes, for information on attributes that do not depend on any particular insn.
For each defined attribute, a number of definitions are written to the insn-attr.h file. For cases where an explicit set of values is specified for an attribute, the following are defined:
For example, if the following is present in the md file:
(define_attr "type" "branch,fp,load,store,arith" …)
the following lines will be written to the file insn-attr.h.
#define HAVE_ATTR_type 1 enum attr_type {TYPE_BRANCH, TYPE_FP, TYPE_LOAD, TYPE_STORE, TYPE_ARITH}; extern enum attr_type get_attr_type ();
If the attribute takes numeric values, no enum
type will be
defined and the function to obtain the attribute’s value will return
int
.
There are attributes which are tied to a specific meaning. These attributes are not free to use for other purposes:
length
The length
attribute is used to calculate the length of emitted
code chunks. This is especially important when verifying branch
distances. See Computing the Length of an Insn.
enabled
The enabled
attribute can be defined to prevent certain
alternatives of an insn definition from being used during code
generation. See Disable insn alternatives using the enabled
attribute.
mnemonic
The mnemonic
attribute can be defined to implement instruction
specific checks in e.g. the pipeline description.
See Mnemonic Attribute.
For each of these special attributes, the corresponding ‘HAVE_ATTR_name’ ‘#define’ is also written when the attribute is not defined; in that case, it is defined as ‘0’.
Another way of defining an attribute is to use:
(define_enum_attr "attr" "enum" default)
This works in just the same way as define_attr
, except that
the list of values is taken from a separate enumeration called
enum (see define_enum). This form allows you to use
the same list of values for several attributes without having to
repeat the list each time. For example:
(define_enum "processor" [ model_a model_b … ]) (define_enum_attr "arch" "processor" (const (symbol_ref "target_arch"))) (define_enum_attr "tune" "processor" (const (symbol_ref "target_tune")))
defines the same attributes as:
(define_attr "arch" "model_a,model_b,…" (const (symbol_ref "target_arch"))) (define_attr "tune" "model_a,model_b,…" (const (symbol_ref "target_tune")))
but without duplicating the processor list. The second example defines two
separate C enums (attr_arch
and attr_tune
) whereas the first
defines a single C enum (processor
).