Define Constraints (GNU Compiler Collection (GCC) Internals)

#### 18.9.7 Defining Machine-Specific Constraints ¶

Machine-specific constraints fall into two categories: register and non-register constraints. Within the latter category, constraints which allow subsets of all possible memory or address operands should be specially marked, to give `reload` more information.

Machine-specific constraints can be given names of arbitrary length, but they must be entirely composed of letters, digits, underscores (‘`_`’), and angle brackets (‘`< >`’). Like C identifiers, they must begin with a letter or underscore.

In order to avoid ambiguity in operand constraint strings, no constraint can have a name that begins with any other constraint’s name. For example, if `x` is defined as a constraint name, `xy` may not be, and vice versa. As a consequence of this rule, no constraint may begin with one of the generic constraint letters: ‘`E F V X g i m n o p r s`’.

Register constraints correspond directly to register classes. See Register Classes. There is thus not much flexibility in their definitions.

MD Expression: define_register_constraint name regclass docstring [filter] [opno] ¶

  All arguments are string constants. name is the name of the constraint, as it will appear in `match_operand` expressions. If name is a multi-letter constraint its length shall be the same for all constraints starting with the same letter. regclass can be either the name of the corresponding register class (see Register Classes), or a C expression which evaluates to the appropriate register class. If it is an expression, it must have no side effects, and it cannot look at the operand. The usual use of expressions is to map some register constraints to `NO_REGS` when the register class is not available on a given subarchitecture.

  If an operand occupies multiple hard registers, the constraint requires all of those registers to belong to regclass. For example, if regclass is `GENERAL_REGS` and `GENERAL_REGS` contains registers `r0` to `r15`, the constraint does not allow r15 to be used for modes that occupy more than one register.

  The choice of register is also constrained by `TARGET_HARD_REGNO_MODE_OK`. For example, if `TARGET_HARD_REGNO_MODE_OK` disallows ‘`(reg:DI r1)`’, that requirement applies to all constraints whose classes include `r1`.

  However, it is sometimes useful to impose extra operand-specific requirements on the register number. For example, a target might not want to prevent all odd-even pairs from holding `DImode` values, but it might still need to prevent specific operands from having an odd-numbered register. The optional filter argument exists for such cases. When given, filter is a C++ expression that evaluates to true if `regno` is a valid register for the operand. If an operand occupies multiple registers, the condition applies only to the first register.

  For example:

      (define_register_constraint "e" "GENERAL_REGS" "..." "regno % 2 == 0")

  defines a constraint that requires an even-numbered general register.

  Filter conditions that impose an alignment are encouraged to test the alignment of `regno` itself, as in the example, rather than calculate an offset relative to the start of the class. If it is sometimes necessary for a register of class c to be aligned to n, the first register in c should itself by divisible by n.

  If even more fine-grained control is needed, the optional opno can be specified. It indicates that the constraint is dependent on another operand (a “referenced” operand) indicated by opno. When it is specified, a filter must be specified as well. The filter function will then be called with the current regno and mode of the operand the constraint refers to, as well as ref_regno and ref_mode of the operand opno the filter depends on additionally.

  Note that either of the regnos can be INVALID_REGNUM to indicate that the register allocator hasn’t yet allocated a hard reg. For certain kinds of filters it is still possible to reject regnos, even if the ref_regno is unknown.

  As such dependent filters are dynamic and cannot be precomputed, it is advisable to use them very sparingly. Register allocation is a very compile-time sensitive part of GCC, and too many, or too complicated dynamic filters may increase the compile time significantly.

  An example for dependent filter usage is the riscv port. It must ensure that for widening vector instructions, the destination register group either does not overlap the source or only overlaps specific parts it. A dynamic register constraint would then be:

      (define_register_constraint "Wtt" "V_REGS" "..." "riscv_widen_overlap_ok (regno, mode, ref_regno, ref_mode)" "0")

  and the accompanying target-code function riscv_widen_overlap_ok might do:

      unsigned int wide_nregs = riscv_hard_regno_nregs (wide_regno, wide_mode);
      unsigned int nregs = riscv_hard_regno_nregs (regno, mode);

      /* Overlap is only allowed in the highest-numbered part of the wider
         destination.  */
      if (regno == wide_regno)
        return false;

      if (regno >= wide_regno + (wide_nregs - nregs))
        return true;

      /* No overlap is OK.  */
      if (regno < wide_regno)
        return true;

      return false;

  docstring is a sentence documenting the meaning of the constraint. Docstrings are explained further below.

Non-register constraints are more like predicates: the constraint definition gives a boolean expression which indicates whether the constraint matches.

MD Expression: define_constraint name docstring exp ¶

  The name and docstring arguments are the same as for `define_register_constraint`, but note that the docstring comes immediately after the name for these expressions. exp is an RTL expression, obeying the same rules as the RTL expressions in predicate definitions. See Defining Machine-Specific Predicates, for details. If it evaluates true, the constraint matches; if it evaluates false, it doesn’t. Constraint expressions should indicate which RTL codes they might match, just like predicate expressions.

  `match_test` C expressions have access to the following variables:

  op

    The RTL object defining the operand.

  mode

    The machine mode of op.

  ival

    ‘`INTVAL (op)`’, if op is a `const_int`.

  hval

    ‘`CONST_DOUBLE_HIGH (op)`’, if op is an integer `const_double`.

  lval

    ‘`CONST_DOUBLE_LOW (op)`’, if op is an integer `const_double`.

  rval

    ‘`CONST_DOUBLE_REAL_VALUE (op)`’, if op is a floating-point `const_double`.

  The *val variables should only be used once another piece of the expression has verified that op is the appropriate kind of RTL object.

Most non-register constraints should be defined with `define_constraint`. The remaining two definition expressions are only appropriate for constraints that should be handled specially by `reload` if they fail to match.

MD Expression: define_memory_constraint name docstring exp ¶

  Use this expression for constraints that match a subset of all memory operands: that is, `reload` can make them match by converting the operand to the form ‘`(mem (reg X))`’, where X is a base register (from the register class specified by `BASE_REG_CLASS`, see Register Classes).

  For example, on the S/390, some instructions do not accept arbitrary memory references, but only those that do not make use of an index register. The constraint letter ‘`Q`’ is defined to represent a memory address of this type. If ‘`Q`’ is defined with `define_memory_constraint`, a ‘`Q`’ constraint can handle any memory operand, because `reload` knows it can simply copy the memory address into a base register if required. This is analogous to the way an ‘`o`’ constraint can handle any memory operand.

  The syntax and semantics are otherwise identical to `define_constraint`.

MD Expression: define_special_memory_constraint name docstring exp ¶

  Use this expression for constraints that match a subset of all memory operands: that is, `reload` cannot make them match by reloading the address as it is described for `define_memory_constraint` or such address reload is undesirable with the performance point of view.

  For example, `define_special_memory_constraint` can be useful if specifically aligned memory is necessary or desirable for some insn operand.

  The syntax and semantics are otherwise identical to `define_memory_constraint`.

MD Expression: define_relaxed_memory_constraint name docstring exp ¶

  The test expression in a `define_memory_constraint` can assume that `TARGET_LEGITIMATE_ADDRESS_P` holds for the address inside a `mem` rtx and so it does not need to test this condition itself. In other words, a `define_memory_constraint` test of the form:

      (match_test "mem")

  is enough to test whether an rtx is a `mem` and whether its address satisfies `TARGET_MEM_CONSTRAINT` (which is usually ‘`'m'`’). Thus the conditions imposed by a `define_memory_constraint` always apply on top of the conditions imposed by `TARGET_MEM_CONSTRAINT`.

  However, it is sometimes useful to define memory constraints that allow addresses beyond those accepted by `TARGET_LEGITIMATE_ADDRESS_P`. `define_relaxed_memory_constraint` exists for this case. The test expression in a `define_relaxed_memory_constraint` is applied with no preconditions, so that the expression can determine “from scratch” exactly which addresses are valid and which are not.

  The syntax and semantics are otherwise identical to `define_memory_constraint`.

MD Expression: define_address_constraint name docstring exp ¶

  Use this expression for constraints that match a subset of all address operands: that is, `reload` can make the constraint match by converting the operand to the form ‘`(reg X)`’, again with X a base register.

  Constraints defined with `define_address_constraint` can only be used with the `address_operand` predicate, or machine-specific predicates that work the same way. They are treated analogously to the generic ‘`p`’ constraint.

  The syntax and semantics are otherwise identical to `define_constraint`.

For historical reasons, names beginning with the letters ‘`G H`’ are reserved for constraints that match only `const_double`s, and names beginning with the letters ‘`I J K L M N O P`’ are reserved for constraints that match only `const_int`s. This may change in the future. For the time being, constraints with these names must be written in a stylized form, so that `genpreds` can tell you did it correctly:

    (define_constraint "[GHIJKLMNOP]..."
      "doc..."
      (and (match_code "const_int")  ; const_double for G/H
           condition...))            ; usually a match_test

It is fine to use names beginning with other letters for constraints that match `const_double`s or `const_int`s.

Each docstring in a constraint definition should be one or more complete sentences, marked up in Texinfo format. They are currently unused. In the future they will be copied into the GCC manual, in Constraints for Particular Machines, replacing the hand-maintained tables currently found in that section. Also, in the future the compiler may use this to give more helpful diagnostics when poor choice of `asm` constraints causes a reload failure.

If you put the pseudo-Texinfo directive ‘`@internal`’ at the beginning of a docstring, then (in the future) it will appear only in the internals manual’s version of the machine-specific constraint tables. Use this for constraints that should not appear in `asm` statements.