gccint: Insn Lengths

1 
1 17.19.5 Computing the Length of an Insn
1 ---------------------------------------
1 
1 For many machines, multiple types of branch instructions are provided,
1 each for different length branch displacements.  In most cases, the
1 assembler will choose the correct instruction to use.  However, when the
1 assembler cannot do so, GCC can when a special attribute, the 'length'
1 attribute, is defined.  This attribute must be defined to have numeric
1 values by specifying a null string in its 'define_attr'.
1 
1  In the case of the 'length' attribute, two additional forms of
1 arithmetic terms are allowed in test expressions:
1 
1 '(match_dup N)'
1      This refers to the address of operand N of the current insn, which
1      must be a 'label_ref'.
1 
1 '(pc)'
1      For non-branch instructions and backward branch instructions, this
1      refers to the address of the current insn.  But for forward branch
1      instructions, this refers to the address of the next insn, because
1      the length of the current insn is to be computed.
1 
1  For normal insns, the length will be determined by value of the
1 'length' attribute.  In the case of 'addr_vec' and 'addr_diff_vec' insn
1 patterns, the length is computed as the number of vectors multiplied by
1 the size of each vector.
1 
1  Lengths are measured in addressable storage units (bytes).
1 
1  Note that it is possible to call functions via the 'symbol_ref'
1 mechanism to compute the length of an insn.  However, if you use this
1 mechanism you must provide dummy clauses to express the maximum length
1 without using the function call.  You can an example of this in the 'pa'
1 machine description for the 'call_symref' pattern.
1 
1  The following macros can be used to refine the length computation:
1 
1 'ADJUST_INSN_LENGTH (INSN, LENGTH)'
1      If defined, modifies the length assigned to instruction INSN as a
1      function of the context in which it is used.  LENGTH is an lvalue
1      that contains the initially computed length of the insn and should
1      be updated with the correct length of the insn.
1 
1      This macro will normally not be required.  A case in which it is
1      required is the ROMP.  On this machine, the size of an 'addr_vec'
1      insn must be increased by two to compensate for the fact that
1      alignment may be required.
1 
1  The routine that returns 'get_attr_length' (the value of the 'length'
1 attribute) can be used by the output routine to determine the form of
1 the branch instruction to be written, as the example below illustrates.
1 
1  As an example of the specification of variable-length branches,
1 consider the IBM 360.  If we adopt the convention that a register will
1 be set to the starting address of a function, we can jump to labels
1 within 4k of the start using a four-byte instruction.  Otherwise, we
1 need a six-byte sequence to load the address from memory and then branch
1 to it.
1 
1  On such a machine, a pattern for a branch instruction might be
1 specified as follows:
1 
1      (define_insn "jump"
1        [(set (pc)
1              (label_ref (match_operand 0 "" "")))]
1        ""
1      {
1         return (get_attr_length (insn) == 4
1                 ? "b %l0" : "l r15,=a(%l0); br r15");
1      }
1        [(set (attr "length")
1              (if_then_else (lt (match_dup 0) (const_int 4096))
1                            (const_int 4)
1                            (const_int 6)))])
1