--- gcc/gcc.info-15 2018/04/24 18:09:07 1.1.1.5 +++ gcc/gcc.info-15 2018/04/24 18:42:40 1.1.1.9 @@ -1,12 +1,13 @@ -This is Info file gcc.info, produced by Makeinfo-1.54 from the input -file gcc.texi. +This is Info file gcc.info, produced by Makeinfo version 1.67 from the +input file gcc.texi. This file documents the use and the internals of the GNU compiler. - Published by the Free Software Foundation 675 Massachusetts Avenue -Cambridge, MA 02139 USA + Published by the Free Software Foundation 59 Temple Place - Suite 330 +Boston, MA 02111-1307 USA - Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995 Free Software +Foundation, Inc. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -14,1038 +15,1094 @@ preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also -that the sections entitled "GNU General Public License" and "Protect -Your Freedom--Fight `Look And Feel'" are included exactly as in the -original, and provided that the entire resulting derived work is -distributed under the terms of a permission notice identical to this -one. +that the sections entitled "GNU General Public License," "Funding for +Free Software," and "Protect Your Freedom--Fight `Look And Feel'" are +included exactly as in the original, and provided that the entire +resulting derived work is distributed under the terms of a permission +notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that the sections entitled "GNU General Public -License" and "Protect Your Freedom--Fight `Look And Feel'", and this -permission notice, may be included in translations approved by the Free -Software Foundation instead of in the original English. +License," "Funding for Free Software," and "Protect Your Freedom--Fight +`Look And Feel'", and this permission notice, may be included in +translations approved by the Free Software Foundation instead of in the +original English.  -File: gcc.info, Node: Expander Definitions, Next: Insn Splitting, Prev: Peephole Definitions, Up: Machine Desc +File: gcc.info, Node: Side Effects, Next: Incdec, Prev: RTL Declarations, Up: RTL -Defining RTL Sequences for Code Generation -========================================== +Side Effect Expressions +======================= - On some target machines, some standard pattern names for RTL -generation cannot be handled with single insn, but a sequence of RTL -insns can represent them. For these target machines, you can write a -`define_expand' to specify how to generate the sequence of RTL. - - A `define_expand' is an RTL expression that looks almost like a -`define_insn'; but, unlike the latter, a `define_expand' is used only -for RTL generation and it can produce more than one RTL insn. - - A `define_expand' RTX has four operands: - - * The name. Each `define_expand' must have a name, since the only - use for it is to refer to it by name. - - * The RTL template. This is just like the RTL template for a - `define_peephole' in that it is a vector of RTL expressions each - being one insn. - - * The condition, a string containing a C expression. This - expression is used to express how the availability of this pattern - depends on subclasses of target machine, selected by command-line - options when GNU CC is run. This is just like the condition of a - `define_insn' that has a standard name. - - * The preparation statements, a string containing zero or more C - statements which are to be executed before RTL code is generated - from the RTL template. - - Usually these statements prepare temporary registers for use as - internal operands in the RTL template, but they can also generate - RTL insns directly by calling routines such as `emit_insn', etc. - Any such insns precede the ones that come from the RTL template. - - Every RTL insn emitted by a `define_expand' must match some -`define_insn' in the machine description. Otherwise, the compiler will -crash when trying to generate code for the insn or trying to optimize -it. - - The RTL template, in addition to controlling generation of RTL insns, -also describes the operands that need to be specified when this pattern -is used. In particular, it gives a predicate for each operand. - - A true operand, which needs to be specified in order to generate RTL -from the pattern, should be described with a `match_operand' in its -first occurrence in the RTL template. This enters information on the -operand's predicate into the tables that record such things. GNU CC -uses the information to preload the operand into a register if that is -required for valid RTL code. If the operand is referred to more than -once, subsequent references should use `match_dup'. - - The RTL template may also refer to internal "operands" which are -temporary registers or labels used only within the sequence made by the -`define_expand'. Internal operands are substituted into the RTL -template with `match_dup', never with `match_operand'. The values of -the internal operands are not passed in as arguments by the compiler -when it requests use of this pattern. Instead, they are computed -within the pattern, in the preparation statements. These statements -compute the values and store them into the appropriate elements of -`operands' so that `match_dup' can find them. - - There are two special macros defined for use in the preparation -statements: `DONE' and `FAIL'. Use them with a following semicolon, as -a statement. - -`DONE' - Use the `DONE' macro to end RTL generation for the pattern. The - only RTL insns resulting from the pattern on this occasion will be - those already emitted by explicit calls to `emit_insn' within the - preparation statements; the RTL template will not be generated. - -`FAIL' - Make the pattern fail on this occasion. When a pattern fails, it - means that the pattern was not truly available. The calling - routines in the compiler will try other strategies for code - generation using other patterns. - - Failure is currently supported only for binary (addition, - multiplication, shifting, etc.) and bitfield (`extv', `extzv', and - `insv') operations. - - Here is an example, the definition of left-shift for the SPUR chip: - - (define_expand "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashift:SI - - (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - " - - { - if (GET_CODE (operands[2]) != CONST_INT - || (unsigned) INTVAL (operands[2]) > 3) - FAIL; - }") - -This example uses `define_expand' so that it can generate an RTL insn -for shifting when the shift-count is in the supported range of 0 to 3 -but fail in other cases where machine insns aren't available. When it -fails, the compiler tries another strategy using different patterns -(such as, a library call). - - If the compiler were able to handle nontrivial condition-strings in -patterns with names, then it would be possible to use a `define_insn' -in that case. Here is another case (zero-extension on the 68000) which -makes more use of the power of `define_expand': - - (define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "") - (const_int 0)) - (set (strict_low_part - (subreg:HI - (match_dup 0) - 0)) - (match_operand:HI 1 "general_operand" ""))] - "" - "operands[1] = make_safe_from (operands[1], operands[0]);") - -Here two RTL insns are generated, one to clear the entire output operand -and the other to copy the input operand into its low half. This -sequence is incorrect if the input operand refers to [the old value of] -the output operand, so the preparation statement makes sure this isn't -so. The function `make_safe_from' copies the `operands[1]' into a -temporary register if it refers to `operands[0]'. It does this by -emitting another RTL insn. - - Finally, a third example shows the use of an internal operand. -Zero-extension on the SPUR chip is done by `and'-ing the result against -a halfword mask. But this mask cannot be represented by a `const_int' -because the constant value is too large to be legitimate on this -machine. So it must be copied into a register with `force_reg' and -then the register used in the `and'. - - (define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (and:SI (subreg:SI - (match_operand:HI 1 "register_operand" "") - 0) - (match_dup 2)))] - "" - "operands[2] - = force_reg (SImode, gen_rtx (CONST_INT, - VOIDmode, 65535)); ") - - *Note:* If the `define_expand' is used to serve a standard binary or -unary arithmetic operation or a bitfield operation, then the last insn -it generates must not be a `code_label', `barrier' or `note'. It must -be an `insn', `jump_insn' or `call_insn'. If you don't need a real insn -at the end, emit an insn to copy the result of the operation into -itself. Such an insn will generate no code, but it can avoid problems -in the compiler. + The expression codes described so far represent values, not actions. +But machine instructions never produce values; they are meaningful only +for their side effects on the state of the machine. Special expression +codes are used to represent side effects. + + The body of an instruction is always one of these side effect codes; +the codes described above, which represent values, appear only as the +operands of these. + +`(set LVAL X)' + Represents the action of storing the value of X into the place + represented by LVAL. LVAL must be an expression representing a + place that can be stored in: `reg' (or `subreg' or + `strict_low_part'), `mem', `pc' or `cc0'. + + If LVAL is a `reg', `subreg' or `mem', it has a machine mode; then + X must be valid for that mode. + + If LVAL is a `reg' whose machine mode is less than the full width + of the register, then it means that the part of the register + specified by the machine mode is given the specified value and the + rest of the register receives an undefined value. Likewise, if + LVAL is a `subreg' whose machine mode is narrower than the mode of + the register, the rest of the register can be changed in an + undefined way. + + If LVAL is a `strict_low_part' of a `subreg', then the part of the + register specified by the machine mode of the `subreg' is given + the value X and the rest of the register is not changed. + + If LVAL is `(cc0)', it has no machine mode, and X may be either a + `compare' expression or a value that may have any mode. The + latter case represents a "test" instruction. The expression `(set + (cc0) (reg:M N))' is equivalent to `(set (cc0) (compare (reg:M N) + (const_int 0)))'. Use the former expression to save space during + the compilation. + + If LVAL is `(pc)', we have a jump instruction, and the + possibilities for X are very limited. It may be a `label_ref' + expression (unconditional jump). It may be an `if_then_else' + (conditional jump), in which case either the second or the third + operand must be `(pc)' (for the case which does not jump) and the + other of the two must be a `label_ref' (for the case which does + jump). X may also be a `mem' or `(plus:SI (pc) Y)', where Y may + be a `reg' or a `mem'; these unusual patterns are used to + represent jumps through branch tables. + + If LVAL is neither `(cc0)' nor `(pc)', the mode of LVAL must not + be `VOIDmode' and the mode of X must be valid for the mode of LVAL. + + LVAL is customarily accessed with the `SET_DEST' macro and X with + the `SET_SRC' macro. + +`(return)' + As the sole expression in a pattern, represents a return from the + current function, on machines where this can be done with one + instruction, such as Vaxes. On machines where a multi-instruction + "epilogue" must be executed in order to return from the function, + returning is done by jumping to a label which precedes the + epilogue, and the `return' expression code is never used. + + Inside an `if_then_else' expression, represents the value to be + placed in `pc' to return to the caller. + + Note that an insn pattern of `(return)' is logically equivalent to + `(set (pc) (return))', but the latter form is never used. + +`(call FUNCTION NARGS)' + Represents a function call. FUNCTION is a `mem' expression whose + address is the address of the function to be called. NARGS is an + expression which can be used for two purposes: on some machines it + represents the number of bytes of stack argument; on others, it + represents the number of argument registers. + + Each machine has a standard machine mode which FUNCTION must have. + The machine description defines macro `FUNCTION_MODE' to expand + into the requisite mode name. The purpose of this mode is to + specify what kind of addressing is allowed, on machines where the + allowed kinds of addressing depend on the machine mode being + addressed. + +`(clobber X)' + Represents the storing or possible storing of an unpredictable, + undescribed value into X, which must be a `reg', `scratch' or + `mem' expression. + + One place this is used is in string instructions that store + standard values into particular hard registers. It may not be + worth the trouble to describe the values that are stored, but it + is essential to inform the compiler that the registers will be + altered, lest it attempt to keep data in them across the string + instruction. + + If X is `(mem:BLK (const_int 0))', it means that all memory + locations must be presumed clobbered. + + Note that the machine description classifies certain hard + registers as "call-clobbered". All function call instructions are + assumed by default to clobber these registers, so there is no need + to use `clobber' expressions to indicate this fact. Also, each + function call is assumed to have the potential to alter any memory + location, unless the function is declared `const'. + + If the last group of expressions in a `parallel' are each a + `clobber' expression whose arguments are `reg' or `match_scratch' + (*note RTL Template::.) expressions, the combiner phase can add + the appropriate `clobber' expressions to an insn it has + constructed when doing so will cause a pattern to be matched. + + This feature can be used, for example, on a machine that whose + multiply and add instructions don't use an MQ register but which + has an add-accumulate instruction that does clobber the MQ + register. Similarly, a combined instruction might require a + temporary register while the constituent instructions might not. + + When a `clobber' expression for a register appears inside a + `parallel' with other side effects, the register allocator + guarantees that the register is unoccupied both before and after + that insn. However, the reload phase may allocate a register used + for one of the inputs unless the `&' constraint is specified for + the selected alternative (*note Modifiers::.). You can clobber + either a specific hard register, a pseudo register, or a `scratch' + expression; in the latter two cases, GNU CC will allocate a hard + register that is available there for use as a temporary. + + For instructions that require a temporary register, you should use + `scratch' instead of a pseudo-register because this will allow the + combiner phase to add the `clobber' when required. You do this by + coding (`clobber' (`match_scratch' ...)). If you do clobber a + pseudo register, use one which appears nowhere else--generate a + new one each time. Otherwise, you may confuse CSE. + + There is one other known use for clobbering a pseudo register in a + `parallel': when one of the input operands of the insn is also + clobbered by the insn. In this case, using the same pseudo + register in the clobber and elsewhere in the insn produces the + expected results. + +`(use X)' + Represents the use of the value of X. It indicates that the value + in X at this point in the program is needed, even though it may + not be apparent why this is so. Therefore, the compiler will not + attempt to delete previous instructions whose only effect is to + store a value in X. X must be a `reg' expression. + + During the delayed branch scheduling phase, X may be an insn. + This indicates that X previously was located at this place in the + code and its data dependencies need to be taken into account. + These `use' insns will be deleted before the delayed branch + scheduling phase exits. + +`(parallel [X0 X1 ...])' + Represents several side effects performed in parallel. The square + brackets stand for a vector; the operand of `parallel' is a vector + of expressions. X0, X1 and so on are individual side effect + expressions--expressions of code `set', `call', `return', + `clobber' or `use'. + + "In parallel" means that first all the values used in the + individual side-effects are computed, and second all the actual + side-effects are performed. For example, + + (parallel [(set (reg:SI 1) (mem:SI (reg:SI 1))) + (set (mem:SI (reg:SI 1)) (reg:SI 1))]) + + says unambiguously that the values of hard register 1 and the + memory location addressed by it are interchanged. In both places + where `(reg:SI 1)' appears as a memory address it refers to the + value in register 1 *before* the execution of the insn. + + It follows that it is *incorrect* to use `parallel' and expect the + result of one `set' to be available for the next one. For + example, people sometimes attempt to represent a jump-if-zero + instruction this way: + + (parallel [(set (cc0) (reg:SI 34)) + (set (pc) (if_then_else + (eq (cc0) (const_int 0)) + (label_ref ...) + (pc)))]) + + But this is incorrect, because it says that the jump condition + depends on the condition code value *before* this instruction, not + on the new value that is set by this instruction. + + Peephole optimization, which takes place together with final + assembly code output, can produce insns whose patterns consist of + a `parallel' whose elements are the operands needed to output the + resulting assembler code--often `reg', `mem' or constant + expressions. This would not be well-formed RTL at any other stage + in compilation, but it is ok then because no further optimization + remains to be done. However, the definition of the macro + `NOTICE_UPDATE_CC', if any, must deal with such insns if you + define any peephole optimizations. + +`(sequence [INSNS ...])' + Represents a sequence of insns. Each of the INSNS that appears in + the vector is suitable for appearing in the chain of insns, so it + must be an `insn', `jump_insn', `call_insn', `code_label', + `barrier' or `note'. + + A `sequence' RTX is never placed in an actual insn during RTL + generation. It represents the sequence of insns that result from a + `define_expand' *before* those insns are passed to `emit_insn' to + insert them in the chain of insns. When actually inserted, the + individual sub-insns are separated out and the `sequence' is + forgotten. + + After delay-slot scheduling is completed, an insn and all the + insns that reside in its delay slots are grouped together into a + `sequence'. The insn requiring the delay slot is the first insn + in the vector; subsequent insns are to be placed in the delay slot. + + `INSN_ANNULLED_BRANCH_P' is set on an insn in a delay slot to + indicate that a branch insn should be used that will conditionally + annul the effect of the insns in the delay slots. In such a case, + `INSN_FROM_TARGET_P' indicates that the insn is from the target of + the branch and should be executed only if the branch is taken; + otherwise the insn should be executed only if the branch is not + taken. *Note Delay Slots::. + + These expression codes appear in place of a side effect, as the body +of an insn, though strictly speaking they do not always describe side +effects as such: + +`(asm_input S)' + Represents literal assembler code as described by the string S. + +`(unspec [OPERANDS ...] INDEX)' +`(unspec_volatile [OPERANDS ...] INDEX)' + Represents a machine-specific operation on OPERANDS. INDEX + selects between multiple machine-specific operations. + `unspec_volatile' is used for volatile operations and operations + that may trap; `unspec' is used for other operations. + + These codes may appear inside a `pattern' of an insn, inside a + `parallel', or inside an expression. + +`(addr_vec:M [LR0 LR1 ...])' + Represents a table of jump addresses. The vector elements LR0, + etc., are `label_ref' expressions. The mode M specifies how much + space is given to each address; normally M would be `Pmode'. + +`(addr_diff_vec:M BASE [LR0 LR1 ...])' + Represents a table of jump addresses expressed as offsets from + BASE. The vector elements LR0, etc., are `label_ref' expressions + and so is BASE. The mode M specifies how much space is given to + each address-difference.  -File: gcc.info, Node: Insn Splitting, Next: Insn Attributes, Prev: Expander Definitions, Up: Machine Desc +File: gcc.info, Node: Incdec, Next: Assembler, Prev: Side Effects, Up: RTL -Defining How to Split Instructions +Embedded Side-Effects on Addresses ================================== - There are two cases where you should specify how to split a pattern -into multiple insns. On machines that have instructions requiring delay -slots (*note Delay Slots::.) or that have instructions whose output is -not available for multiple cycles (*note Function Units::.), the -compiler phases that optimize these cases need to be able to move insns -into one-cycle delay slots. However, some insns may generate more than -one machine instruction. These insns cannot be placed into a delay -slot. - - Often you can rewrite the single insn as a list of individual insns, -each corresponding to one machine instruction. The disadvantage of -doing so is that it will cause the compilation to be slower and require -more space. If the resulting insns are too complex, it may also -suppress some optimizations. The compiler splits the insn if there is a -reason to believe that it might improve instruction or delay slot -scheduling. - - The insn combiner phase also splits putative insns. If three insns -are merged into one insn with a complex expression that cannot be -matched by some `define_insn' pattern, the combiner phase attempts to -split the complex pattern into two insns that are recognized. Usually -it can break the complex pattern into two patterns by splitting out some -subexpression. However, in some other cases, such as performing an -addition of a large constant in two insns on a RISC machine, the way to -split the addition into two insns is machine-dependent. - - The `define_split' definition tells the compiler how to split a -complex insn into several simpler insns. It looks like this: - - (define_split - [INSN-PATTERN] - "CONDITION" - [NEW-INSN-PATTERN-1 - NEW-INSN-PATTERN-2 - ...] - "PREPARATION STATEMENTS") - - INSN-PATTERN is a pattern that needs to be split and CONDITION is -the final condition to be tested, as in a `define_insn'. When an insn -matching INSN-PATTERN and satisfying CONDITION is found, it is replaced -in the insn list with the insns given by NEW-INSN-PATTERN-1, -NEW-INSN-PATTERN-2, etc. - - The PREPARATION STATEMENTS are similar to those statements that are -specified for `define_expand' (*note Expander Definitions::.) and are -executed before the new RTL is generated to prepare for the generated -code or emit some insns whose pattern is not fixed. Unlike those in -`define_expand', however, these statements must not generate any new -pseudo-registers. Once reload has completed, they also must not -allocate any space in the stack frame. - - Patterns are matched against INSN-PATTERN in two different -circumstances. If an insn needs to be split for delay slot scheduling -or insn scheduling, the insn is already known to be valid, which means -that it must have been matched by some `define_insn' and, if -`reload_completed' is non-zero, is known to satisfy the constraints of -that `define_insn'. In that case, the new insn patterns must also be -insns that are matched by some `define_insn' and, if `reload_completed' -is non-zero, must also satisfy the constraints of those definitions. - - As an example of this usage of `define_split', consider the following -example from `a29k.md', which splits a `sign_extend' from `HImode' to -`SImode' into a pair of shift insns: - - (define_split - [(set (match_operand:SI 0 "gen_reg_operand" "") - (sign_extend:SI (match_operand:HI 1 "gen_reg_operand" "")))] - "" - [(set (match_dup 0) - (ashift:SI (match_dup 1) - (const_int 16))) - (set (match_dup 0) - (ashiftrt:SI (match_dup 0) - (const_int 16)))] - " - { operands[1] = gen_lowpart (SImode, operands[1]); }") - - When the combiner phase tries to split an insn pattern, it is always -the case that the pattern is *not* matched by any `define_insn'. The -combiner pass first tries to split a single `set' expression and then -the same `set' expression inside a `parallel', but followed by a -`clobber' of a pseudo-reg to use as a scratch register. In these -cases, the combiner expects exactly two new insn patterns to be -generated. It will verify that these patterns match some `define_insn' -definitions, so you need not do this test in the `define_split' (of -course, there is no point in writing a `define_split' that will never -produce insns that match). - - Here is an example of this use of `define_split', taken from -`rs6000.md': - - (define_split - [(set (match_operand:SI 0 "gen_reg_operand" "") - (plus:SI (match_operand:SI 1 "gen_reg_operand" "") - (match_operand:SI 2 "non_add_cint_operand" "")))] - "" - [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3))) - (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] - " - { - int low = INTVAL (operands[2]) & 0xffff; - int high = (unsigned) INTVAL (operands[2]) >> 16; - - if (low & 0x8000) - high++, low |= 0xffff0000; - - operands[3] = gen_rtx (CONST_INT, VOIDmode, high << 16); - operands[4] = gen_rtx (CONST_INT, VOIDmode, low); - }") - - Here the predicate `non_add_cint_operand' matches any `const_int' -that is *not* a valid operand of a single add insn. Write the add with -the smaller displacement is written so that it can be substituted into -the address of a subsequent operation. - - An example that uses a scratch register, from the same file, -generates an equality comparison of a register and a large constant: - - (define_split - [(set (match_operand:CC 0 "cc_reg_operand" "") - (compare:CC (match_operand:SI 1 "gen_reg_operand" "") - (match_operand:SI 2 "non_short_cint_operand" ""))) - (clobber (match_operand:SI 3 "gen_reg_operand" ""))] - "find_single_use (operands[0], insn, 0) - && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ - || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)" - [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4))) - (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))] - " - { - /* Get the constant we are comparing against, C, and see what it - looks like sign-extended to 16 bits. Then see what constant - could be XOR'ed with C to get the sign-extended value. */ - - int c = INTVAL (operands[2]); - int sextc = (c << 16) >> 16; - int xorv = c ^ sextc; - - operands[4] = gen_rtx (CONST_INT, VOIDmode, xorv); - operands[5] = gen_rtx (CONST_INT, VOIDmode, sextc); - }") - - To avoid confusion, don't write a single `define_split' that accepts -some insns that match some `define_insn' as well as some insns that -don't. Instead, write two separate `define_split' definitions, one for -the insns that are valid and one for the insns that are not valid. - - -File: gcc.info, Node: Insn Attributes, Prev: Insn Splitting, Up: Machine Desc - -Instruction Attributes -====================== - - In addition to describing the instruction supported by the target -machine, the `md' file also defines a group of "attributes" and a set of -values for each. Every generated insn is assigned a value for each -attribute. One possible attribute would be the effect that the insn -has on the machine's condition code. This attribute can then be used -by `NOTICE_UPDATE_CC' to track the condition codes. - -* Menu: + Four special side-effect expression codes appear as memory addresses. -* Defining Attributes:: Specifying attributes and their values. -* Expressions:: Valid expressions for attribute values. -* Tagging Insns:: Assigning attribute values to insns. -* Attr Example:: An example of assigning attributes. -* Insn Lengths:: Computing the length of insns. -* Constant Attributes:: Defining attributes that are constant. -* Delay Slots:: Defining delay slots required for a machine. -* Function Units:: Specifying information for insn scheduling. +`(pre_dec:M X)' + Represents the side effect of decrementing X by a standard amount + and represents also the value that X has after being decremented. + X must be a `reg' or `mem', but most machines allow only a `reg'. + M must be the machine mode for pointers on the machine in use. + The amount X is decremented by is the length in bytes of the + machine mode of the containing memory reference of which this + expression serves as the address. Here is an example of its use: + + (mem:DF (pre_dec:SI (reg:SI 39))) + + This says to decrement pseudo register 39 by the length of a + `DFmode' value and use the result to address a `DFmode' value. + +`(pre_inc:M X)' + Similar, but specifies incrementing X instead of decrementing it. + +`(post_dec:M X)' + Represents the same side effect as `pre_dec' but a different + value. The value represented here is the value X has before being + decremented. + +`(post_inc:M X)' + Similar, but specifies incrementing X instead of decrementing it. + + These embedded side effect expressions must be used with care. +Instruction patterns may not use them. Until the `flow' pass of the +compiler, they may occur only to represent pushes onto the stack. The +`flow' pass finds cases where registers are incremented or decremented +in one instruction and used as an address shortly before or after; +these cases are then transformed to use pre- or post-increment or +-decrement. + + If a register used as the operand of these expressions is used in +another address in an insn, the original value of the register is used. +Uses of the register outside of an address are not permitted within the +same insn as a use in an embedded side effect expression because such +insns behave differently on different machines and hence must be treated +as ambiguous and disallowed. + + An instruction that can be represented with an embedded side effect +could also be represented using `parallel' containing an additional +`set' to describe how the address register is altered. This is not +done because machines that allow these operations at all typically +allow them wherever a memory address is called for. Describing them as +additional parallel stores would require doubling the number of entries +in the machine description.  -File: gcc.info, Node: Defining Attributes, Next: Expressions, Up: Insn Attributes - -Defining Attributes and their Values ------------------------------------- - - 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. +File: gcc.info, Node: Assembler, Next: Insns, Prev: Incdec, Up: RTL - 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. +Assembler Instructions as Expressions +===================================== - 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. *Note Attr Example::, -for more information on the handling of defaults. *Note Constant -Attributes::, for information on attributes that do not depend on any -particular insn. + The RTX code `asm_operands' represents a value produced by a +user-specified assembler instruction. It is used to represent an `asm' +statement with arguments. An `asm' statement with a single output +operand, like this: + + asm ("foo %1,%2,%0" : "=a" (outputvar) : "g" (x + y), "di" (*z)); + +is represented using a single `asm_operands' RTX which represents the +value that is stored in `outputvar': + + (set RTX-FOR-OUTPUTVAR + (asm_operands "foo %1,%2,%0" "a" 0 + [RTX-FOR-ADDITION-RESULT RTX-FOR-*Z] + [(asm_input:M1 "g") + (asm_input:M2 "di")])) + +Here the operands of the `asm_operands' RTX are the assembler template +string, the output-operand's constraint, the index-number of the output +operand among the output operands specified, a vector of input operand +RTX's, and a vector of input-operand modes and constraints. The mode +M1 is the mode of the sum `x+y'; M2 is that of `*z'. + + When an `asm' statement has multiple output values, its insn has +several such `set' RTX's inside of a `parallel'. Each `set' contains a +`asm_operands'; all of these share the same assembler template and +vectors, but each contains the constraint for the respective output +operand. They are also distinguished by the output-operand index +number, which is 0, 1, ... for successive output operands. - 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: + +File: gcc.info, Node: Insns, Next: Calls, Prev: Assembler, Up: RTL - * A `#define' is written for the symbol `HAVE_ATTR_NAME'. +Insns +===== - * An enumeral class is defined for `attr_NAME' with elements of the - form `UPPER-NAME_UPPER-VALUE' where the attribute name and value - are first converted to upper case. + The RTL representation of the code for a function is a doubly-linked +chain of objects called "insns". Insns are expressions with special +codes that are used for no other purpose. Some insns are actual +instructions; others represent dispatch tables for `switch' statements; +others represent labels to jump to or various sorts of declarative +information. + + In addition to its own specific data, each insn must have a unique +id-number that distinguishes it from all other insns in the current +function (after delayed branch scheduling, copies of an insn with the +same id-number may be present in multiple places in a function, but +these copies will always be identical and will only appear inside a +`sequence'), and chain pointers to the preceding and following insns. +These three fields occupy the same position in every insn, independent +of the expression code of the insn. They could be accessed with `XEXP' +and `XINT', but instead three special macros are always used: + +`INSN_UID (I)' + Accesses the unique id of insn I. + +`PREV_INSN (I)' + Accesses the chain pointer to the insn preceding I. If I is the + first insn, this is a null pointer. + +`NEXT_INSN (I)' + Accesses the chain pointer to the insn following I. If I is the + last insn, this is a null pointer. + + The first insn in the chain is obtained by calling `get_insns'; the +last insn is the result of calling `get_last_insn'. Within the chain +delimited by these insns, the `NEXT_INSN' and `PREV_INSN' pointers must +always correspond: if INSN is not the first insn, + + NEXT_INSN (PREV_INSN (INSN)) == INSN + +is always true and if INSN is not the last insn, + + PREV_INSN (NEXT_INSN (INSN)) == INSN + +is always true. + + After delay slot scheduling, some of the insns in the chain might be +`sequence' expressions, which contain a vector of insns. The value of +`NEXT_INSN' in all but the last of these insns is the next insn in the +vector; the value of `NEXT_INSN' of the last insn in the vector is the +same as the value of `NEXT_INSN' for the `sequence' in which it is +contained. Similar rules apply for `PREV_INSN'. + + This means that the above invariants are not necessarily true for +insns inside `sequence' expressions. Specifically, if INSN is the +first insn in a `sequence', `NEXT_INSN (PREV_INSN (INSN))' is the insn +containing the `sequence' expression, as is the value of `PREV_INSN +(NEXT_INSN (INSN))' is INSN is the last insn in the `sequence' +expression. You can use these expressions to find the containing +`sequence' expression. + + Every insn has one of the following six expression codes: + +`insn' + The expression code `insn' is used for instructions that do not + jump and do not do function calls. `sequence' expressions are + always contained in insns with code `insn' even if one of those + insns should jump or do function calls. + + Insns with code `insn' have four additional fields beyond the three + mandatory ones listed above. These four are described in a table + below. + +`jump_insn' + The expression code `jump_insn' is used for instructions that may + jump (or, more generally, may contain `label_ref' expressions). If + there is an instruction to return from the current function, it is + recorded as a `jump_insn'. + + `jump_insn' insns have the same extra fields as `insn' insns, + accessed in the same way and in addition contain a field + `JUMP_LABEL' which is defined once jump optimization has completed. + + For simple conditional and unconditional jumps, this field + contains the `code_label' to which this insn will (possibly + conditionally) branch. In a more complex jump, `JUMP_LABEL' + records one of the labels that the insn refers to; the only way to + find the others is to scan the entire body of the insn. + + Return insns count as jumps, but since they do not refer to any + labels, they have zero in the `JUMP_LABEL' field. + +`call_insn' + The expression code `call_insn' is used for instructions that may + do function calls. It is important to distinguish these + instructions because they imply that certain registers and memory + locations may be altered unpredictably. + + `call_insn' insns have the same extra fields as `insn' insns, + accessed in the same way and in addition contain a field + `CALL_INSN_FUNCTION_USAGE', which contains a list (chain of + `expr_list' expressions) containing `use' and `clobber' + expressions that denote hard registers used or clobbered by the + called function. A register specified in a `clobber' in this list + is modified *after* the execution of the `call_insn', while a + register in a `clobber' in the body of the `call_insn' is + clobbered before the insn completes execution. `clobber' + expressions in this list augment registers specified in + `CALL_USED_REGISTERS' (*note Register Basics::.). + +`code_label' + A `code_label' insn represents a label that a jump insn can jump + to. It contains two special fields of data in addition to the + three standard ones. `CODE_LABEL_NUMBER' is used to hold the + "label number", a number that identifies this label uniquely among + all the labels in the compilation (not just in the current + function). Ultimately, the label is represented in the assembler + output as an assembler label, usually of the form `LN' where N is + the label number. + + When a `code_label' appears in an RTL expression, it normally + appears within a `label_ref' which represents the address of the + label, as a number. + + The field `LABEL_NUSES' is only defined once the jump optimization + phase is completed and contains the number of times this label is + referenced in the current function. + +`barrier' + Barriers are placed in the instruction stream when control cannot + flow past them. They are placed after unconditional jump + instructions to indicate that the jumps are unconditional and + after calls to `volatile' functions, which do not return (e.g., + `exit'). They contain no information beyond the three standard + fields. + +`note' + `note' insns are used to represent additional debugging and + declarative information. They contain two nonstandard fields, an + integer which is accessed with the macro `NOTE_LINE_NUMBER' and a + string accessed with `NOTE_SOURCE_FILE'. + + If `NOTE_LINE_NUMBER' is positive, the note represents the + position of a source line and `NOTE_SOURCE_FILE' is the source + file name that the line came from. These notes control generation + of line number data in the assembler output. + + Otherwise, `NOTE_LINE_NUMBER' is not really a line number but a + code with one of the following values (and `NOTE_SOURCE_FILE' must + contain a null pointer): + + `NOTE_INSN_DELETED' + Such a note is completely ignorable. Some passes of the + compiler delete insns by altering them into notes of this + kind. + + `NOTE_INSN_BLOCK_BEG' + `NOTE_INSN_BLOCK_END' + These types of notes indicate the position of the beginning + and end of a level of scoping of variable names. They + control the output of debugging information. + + `NOTE_INSN_LOOP_BEG' + `NOTE_INSN_LOOP_END' + These types of notes indicate the position of the beginning + and end of a `while' or `for' loop. They enable the loop + optimizer to find loops quickly. + + `NOTE_INSN_LOOP_CONT' + Appears at the place in a loop that `continue' statements + jump to. + + `NOTE_INSN_LOOP_VTOP' + This note indicates the place in a loop where the exit test + begins for those loops in which the exit test has been + duplicated. This position becomes another virtual start of + the loop when considering loop invariants. + + `NOTE_INSN_FUNCTION_END' + Appears near the end of the function body, just before the + label that `return' statements jump to (on machine where a + single instruction does not suffice for returning). This + note may be deleted by jump optimization. + + `NOTE_INSN_SETJMP' + Appears following each call to `setjmp' or a related function. + + These codes are printed symbolically when they appear in debugging + dumps. + + The machine mode of an insn is normally `VOIDmode', but some phases +use the mode for various purposes; for example, the reload pass sets it +to `HImode' if the insn needs reloading but not register elimination +and `QImode' if both are required. The common subexpression +elimination pass sets the mode of an insn to `QImode' when it is the +first insn in a block that has already been processed. + + Here is a table of the extra fields of `insn', `jump_insn' and +`call_insn' insns: + +`PATTERN (I)' + An expression for the side effect performed by this insn. This + must be one of the following codes: `set', `call', `use', + `clobber', `return', `asm_input', `asm_output', `addr_vec', + `addr_diff_vec', `trap_if', `unspec', `unspec_volatile', + `parallel', or `sequence'. If it is a `parallel', each element of + the `parallel' must be one these codes, except that `parallel' + expressions cannot be nested and `addr_vec' and `addr_diff_vec' + are not permitted inside a `parallel' expression. + +`INSN_CODE (I)' + An integer that says which pattern in the machine description + matches this insn, or -1 if the matching has not yet been + attempted. + + Such matching is never attempted and this field remains -1 on an + insn whose pattern consists of a single `use', `clobber', + `asm_input', `addr_vec' or `addr_diff_vec' expression. + + Matching is also never attempted on insns that result from an `asm' + statement. These contain at least one `asm_operands' expression. + The function `asm_noperands' returns a non-negative value for such + insns. + + In the debugging output, this field is printed as a number + followed by a symbolic representation that locates the pattern in + the `md' file as some small positive or negative offset from a + named pattern. + +`LOG_LINKS (I)' + A list (chain of `insn_list' expressions) giving information about + dependencies between instructions within a basic block. Neither a + jump nor a label may come between the related insns. + +`REG_NOTES (I)' + A list (chain of `expr_list' and `insn_list' expressions) giving + miscellaneous information about the insn. It is often information + pertaining to the registers used in this insn. + + The `LOG_LINKS' field of an insn is a chain of `insn_list' +expressions. Each of these has two operands: the first is an insn, and +the second is another `insn_list' expression (the next one in the +chain). The last `insn_list' in the chain has a null pointer as second +operand. The significant thing about the chain is which insns appear +in it (as first operands of `insn_list' expressions). Their order is +not significant. + + This list is originally set up by the flow analysis pass; it is a +null pointer until then. Flow only adds links for those data +dependencies which can be used for instruction combination. For each +insn, the flow analysis pass adds a link to insns which store into +registers values that are used for the first time in this insn. The +instruction scheduling pass adds extra links so that every dependence +will be represented. Links represent data dependencies, +antidependencies and output dependencies; the machine mode of the link +distinguishes these three types: antidependencies have mode +`REG_DEP_ANTI', output dependencies have mode `REG_DEP_OUTPUT', and +data dependencies have mode `VOIDmode'. + + The `REG_NOTES' field of an insn is a chain similar to the +`LOG_LINKS' field but it includes `expr_list' expressions in addition +to `insn_list' expressions. There are several kinds of register notes, +which are distinguished by the machine mode, which in a register note +is really understood as being an `enum reg_note'. The first operand OP +of the note is data whose meaning depends on the kind of note. + + The macro `REG_NOTE_KIND (X)' returns the kind of register note. +Its counterpart, the macro `PUT_REG_NOTE_KIND (X, NEWKIND)' sets the +register note type of X to be NEWKIND. + + Register notes are of three classes: They may say something about an +input to an insn, they may say something about an output of an insn, or +they may create a linkage between two insns. There are also a set of +values that are only used in `LOG_LINKS'. + + These register notes annotate inputs to an insn: + +`REG_DEAD' + The value in OP dies in this insn; that is to say, altering the + value immediately after this insn would not affect the future + behavior of the program. + + This does not necessarily mean that the register OP has no useful + value after this insn since it may also be an output of the insn. + In such a case, however, a `REG_DEAD' note would be redundant and + is usually not present until after the reload pass, but no code + relies on this fact. + +`REG_INC' + The register OP is incremented (or decremented; at this level + there is no distinction) by an embedded side effect inside this + insn. This means it appears in a `post_inc', `pre_inc', + `post_dec' or `pre_dec' expression. + +`REG_NONNEG' + The register OP is known to have a nonnegative value when this + insn is reached. This is used so that decrement and branch until + zero instructions, such as the m68k dbra, can be matched. + + The `REG_NONNEG' note is added to insns only if the machine + description has a `decrement_and_branch_until_zero' pattern. + +`REG_NO_CONFLICT' + This insn does not cause a conflict between OP and the item being + set by this insn even though it might appear that it does. In + other words, if the destination register and OP could otherwise be + assigned the same register, this insn does not prevent that + assignment. + + Insns with this note are usually part of a block that begins with a + `clobber' insn specifying a multi-word pseudo register (which will + be the output of the block), a group of insns that each set one + word of the value and have the `REG_NO_CONFLICT' note attached, + and a final insn that copies the output to itself with an attached + `REG_EQUAL' note giving the expression being computed. This block + is encapsulated with `REG_LIBCALL' and `REG_RETVAL' notes on the + first and last insns, respectively. + +`REG_LABEL' + This insn uses OP, a `code_label', but is not a `jump_insn'. The + presence of this note allows jump optimization to be aware that OP + is, in fact, being used. + + The following notes describe attributes of outputs of an insn: + +`REG_EQUIV' +`REG_EQUAL' + This note is only valid on an insn that sets only one register and + indicates that that register will be equal to OP at run time; the + scope of this equivalence differs between the two types of notes. + The value which the insn explicitly copies into the register may + look different from OP, but they will be equal at run time. If the + output of the single `set' is a `strict_low_part' expression, the + note refers to the register that is contained in `SUBREG_REG' of + the `subreg' expression. + + For `REG_EQUIV', the register is equivalent to OP throughout the + entire function, and could validly be replaced in all its + occurrences by OP. ("Validly" here refers to the data flow of the + program; simple replacement may make some insns invalid.) For + example, when a constant is loaded into a register that is never + assigned any other value, this kind of note is used. + + When a parameter is copied into a pseudo-register at entry to a + function, a note of this kind records that the register is + equivalent to the stack slot where the parameter was passed. + Although in this case the register may be set by other insns, it + is still valid to replace the register by the stack slot + throughout the function. + + In the case of `REG_EQUAL', the register that is set by this insn + will be equal to OP at run time at the end of this insn but not + necessarily elsewhere in the function. In this case, OP is + typically an arithmetic expression. For example, when a sequence + of insns such as a library call is used to perform an arithmetic + operation, this kind of note is attached to the insn that produces + or copies the final value. + + These two notes are used in different ways by the compiler passes. + `REG_EQUAL' is used by passes prior to register allocation (such as + common subexpression elimination and loop optimization) to tell + them how to think of that value. `REG_EQUIV' notes are used by + register allocation to indicate that there is an available + substitute expression (either a constant or a `mem' expression for + the location of a parameter on the stack) that may be used in + place of a register if insufficient registers are available. + + Except for stack homes for parameters, which are indicated by a + `REG_EQUIV' note and are not useful to the early optimization + passes and pseudo registers that are equivalent to a memory + location throughout there entire life, which is not detected until + later in the compilation, all equivalences are initially indicated + by an attached `REG_EQUAL' note. In the early stages of register + allocation, a `REG_EQUAL' note is changed into a `REG_EQUIV' note + if OP is a constant and the insn represents the only set of its + destination register. + + Thus, compiler passes prior to register allocation need only check + for `REG_EQUAL' notes and passes subsequent to register allocation + need only check for `REG_EQUIV' notes. + +`REG_UNUSED' + The register OP being set by this insn will not be used in a + subsequent insn. This differs from a `REG_DEAD' note, which + indicates that the value in an input will not be used subsequently. + These two notes are independent; both may be present for the same + register. + +`REG_WAS_0' + The single output of this insn contained zero before this insn. + OP is the insn that set it to zero. You can rely on this note if + it is present and OP has not been deleted or turned into a `note'; + its absence implies nothing. + + These notes describe linkages between insns. They occur in pairs: +one insn has one of a pair of notes that points to a second insn, which +has the inverse note pointing back to the first insn. + +`REG_RETVAL' + This insn copies the value of a multi-insn sequence (for example, a + library call), and OP is the first insn of the sequence (for a + library call, the first insn that was generated to set up the + arguments for the library call). + + Loop optimization uses this note to treat such a sequence as a + single operation for code motion purposes and flow analysis uses + this note to delete such sequences whose results are dead. + + A `REG_EQUAL' note will also usually be attached to this insn to + provide the expression being computed by the sequence. + +`REG_LIBCALL' + This is the inverse of `REG_RETVAL': it is placed on the first + insn of a multi-insn sequence, and it points to the last one. + +`REG_CC_SETTER' +`REG_CC_USER' + On machines that use `cc0', the insns which set and use `cc0' set + and use `cc0' are adjacent. However, when branch delay slot + filling is done, this may no longer be true. In this case a + `REG_CC_USER' note will be placed on the insn setting `cc0' to + point to the insn using `cc0' and a `REG_CC_SETTER' note will be + placed on the insn using `cc0' to point to the insn setting `cc0'. + + These values are only used in the `LOG_LINKS' field, and indicate +the type of dependency that each link represents. Links which indicate +a data dependence (a read after write dependence) do not use any code, +they simply have mode `VOIDmode', and are printed without any +descriptive text. + +`REG_DEP_ANTI' + This indicates an anti dependence (a write after read dependence). + +`REG_DEP_OUTPUT' + This indicates an output dependence (a write after write + dependence). + + For convenience, the machine mode in an `insn_list' or `expr_list' +is printed using these symbolic codes in debugging dumps. + + The only difference between the expression codes `insn_list' and +`expr_list' is that the first operand of an `insn_list' is assumed to +be an insn and is printed in debugging dumps as the insn's unique id; +the first operand of an `expr_list' is printed in the ordinary way as +an expression. - * A function `get_attr_NAME' is defined that is passed an insn and - returns the attribute value for that insn. + +File: gcc.info, Node: Calls, Next: Sharing, Prev: Insns, Up: RTL - For example, if the following is present in the `md' file: +RTL Representation of Function-Call Insns +========================================= - (define_attr "type" "branch,fp,load,store,arith" ...) + Insns that call subroutines have the RTL expression code `call_insn'. +These insns must satisfy special rules, and their bodies must use a +special RTL expression code, `call'. + + A `call' expression has two operands, as follows: + + (call (mem:FM ADDR) NBYTES) + +Here NBYTES is an operand that represents the number of bytes of +argument data being passed to the subroutine, FM is a machine mode +(which must equal as the definition of the `FUNCTION_MODE' macro in the +machine description) and ADDR represents the address of the subroutine. + + For a subroutine that returns no value, the `call' expression as +shown above is the entire body of the insn, except that the insn might +also contain `use' or `clobber' expressions. + + For a subroutine that returns a value whose mode is not `BLKmode', +the value is returned in a hard register. If this register's number is +R, then the body of the call insn looks like this: + + (set (reg:M R) + (call (mem:FM ADDR) NBYTES)) + +This RTL expression makes it clear (to the optimizer passes) that the +appropriate register receives a useful value in this insn. + + When a subroutine returns a `BLKmode' value, it is handled by +passing to the subroutine the address of a place to store the value. +So the call insn itself does not "return" any value, and it has the +same RTL form as a call that returns nothing. + + On some machines, the call instruction itself clobbers some register, +for example to contain the return address. `call_insn' insns on these +machines should have a body which is a `parallel' that contains both +the `call' expression and `clobber' expressions that indicate which +registers are destroyed. Similarly, if the call instruction requires +some register other than the stack pointer that is not explicitly +mentioned it its RTL, a `use' subexpression should mention that +register. + + Functions that are called are assumed to modify all registers listed +in the configuration macro `CALL_USED_REGISTERS' (*note Register +Basics::.) and, with the exception of `const' functions and library +calls, to modify all of memory. + + Insns containing just `use' expressions directly precede the +`call_insn' insn to indicate which registers contain inputs to the +function. Similarly, if registers other than those in +`CALL_USED_REGISTERS' are clobbered by the called function, insns +containing a single `clobber' follow immediately after the call to +indicate which registers. -the following lines will be written to the file `insn-attr.h'. + +File: gcc.info, Node: Sharing, Next: Reading RTL, Prev: Calls, Up: RTL - #define HAVE_ATTR_type - enum attr_type {TYPE_BRANCH, TYPE_FP, TYPE_LOAD, - TYPE_STORE, TYPE_ARITH}; - extern enum attr_type get_attr_type (); +Structure Sharing Assumptions +============================= - If the attribute takes numeric values, no `enum' type will be -defined and the function to obtain the attribute's value will return -`int'. + The compiler assumes that certain kinds of RTL expressions are +unique; there do not exist two distinct objects representing the same +value. In other cases, it makes an opposite assumption: that no RTL +expression object of a certain kind appears in more than one place in +the containing structure. + + These assumptions refer to a single function; except for the RTL +objects that describe global variables and external functions, and a +few standard objects such as small integer constants, no RTL objects +are common to two functions. + + * Each pseudo-register has only a single `reg' object to represent + it, and therefore only a single machine mode. + + * For any symbolic label, there is only one `symbol_ref' object + referring to it. + + * There is only one `const_int' expression with value 0, only one + with value 1, and only one with value -1. Some other integer + values are also stored uniquely. + + * There is only one `pc' expression. + + * There is only one `cc0' expression. + + * There is only one `const_double' expression with value 0 for each + floating point mode. Likewise for values 1 and 2. + + * No `label_ref' or `scratch' appears in more than one place in the + RTL structure; in other words, it is safe to do a tree-walk of all + the insns in the function and assume that each time a `label_ref' + or `scratch' is seen it is distinct from all others that are seen. + + * Only one `mem' object is normally created for each static variable + or stack slot, so these objects are frequently shared in all the + places they appear. However, separate but equal objects for these + variables are occasionally made. + + * When a single `asm' statement has multiple output operands, a + distinct `asm_operands' expression is made for each output operand. + However, these all share the vector which contains the sequence of + input operands. This sharing is used later on to test whether two + `asm_operands' expressions come from the same statement, so all + optimizations must carefully preserve the sharing if they copy the + vector at all. + + * No RTL object appears in more than one place in the RTL structure + except as described above. Many passes of the compiler rely on + this by assuming that they can modify RTL objects in place without + unwanted side-effects on other insns. + + * During initial RTL generation, shared structure is freely + introduced. After all the RTL for a function has been generated, + all shared structure is copied by `unshare_all_rtl' in + `emit-rtl.c', after which the above rules are guaranteed to be + followed. + + * During the combiner pass, shared structure within an insn can exist + temporarily. However, the shared structure is copied before the + combiner is finished with the insn. This is done by calling + `copy_rtx_if_shared', which is a subroutine of `unshare_all_rtl'.  -File: gcc.info, Node: Expressions, Next: Tagging Insns, Prev: Defining Attributes, Up: Insn Attributes +File: gcc.info, Node: Reading RTL, Prev: Sharing, Up: RTL -Attribute Expressions ---------------------- +Reading RTL +=========== - RTL expressions used to define attributes use the codes described -above plus a few specific to attribute definitions, to be discussed -below. Attribute value expressions must have one of the following -forms: - -`(const_int I)' - The integer I specifies the value of a numeric attribute. I must - be non-negative. - - The value of a numeric attribute can be specified either with a - `const_int' or as an integer represented as a string in - `const_string', `eq_attr' (see below), and `set_attr' (*note - Tagging Insns::.) expressions. - -`(const_string VALUE)' - The string VALUE specifies a constant attribute value. If VALUE - is specified as `"*"', it means that the default value of the - attribute is to be used for the insn containing this expression. - `"*"' obviously cannot be used in the DEFAULT expression of a - `define_attr'. - - If the attribute whose value is being specified is numeric, VALUE - must be a string containing a non-negative integer (normally - `const_int' would be used in this case). Otherwise, it must - contain one of the valid values for the attribute. - -`(if_then_else TEST TRUE-VALUE FALSE-VALUE)' - TEST specifies an attribute test, whose format is defined below. - The value of this expression is TRUE-VALUE if TEST is true, - otherwise it is FALSE-VALUE. - -`(cond [TEST1 VALUE1 ...] DEFAULT)' - The first operand of this expression is a vector containing an even - number of expressions and consisting of pairs of TEST and VALUE - expressions. The value of the `cond' expression is that of the - VALUE corresponding to the first true TEST expression. If none of - the TEST expressions are true, the value of the `cond' expression - is that of the DEFAULT expression. - - TEST expressions can have one of the following forms: - -`(const_int I)' - This test is true if I is non-zero and false otherwise. - -`(not TEST)' -`(ior TEST1 TEST2)' -`(and TEST1 TEST2)' - These tests are true if the indicated logical function is true. - -`(match_operand:M N PRED CONSTRAINTS)' - This test is true if operand N of the insn whose attribute value - is being determined has mode M (this part of the test is ignored - if M is `VOIDmode') and the function specified by the string PRED - returns a non-zero value when passed operand N and mode M (this - part of the test is ignored if PRED is the null string). - - The CONSTRAINTS operand is ignored and should be the null string. - -`(le ARITH1 ARITH2)' -`(leu ARITH1 ARITH2)' -`(lt ARITH1 ARITH2)' -`(ltu ARITH1 ARITH2)' -`(gt ARITH1 ARITH2)' -`(gtu ARITH1 ARITH2)' -`(ge ARITH1 ARITH2)' -`(geu ARITH1 ARITH2)' -`(ne ARITH1 ARITH2)' -`(eq ARITH1 ARITH2)' - These tests are true if the indicated comparison of the two - arithmetic expressions is true. Arithmetic expressions are formed - with `plus', `minus', `mult', `div', `mod', `abs', `neg', `and', - `ior', `xor', `not', `lshift', `ashift', `lshiftrt', and `ashiftrt' - expressions. - - `const_int' and `symbol_ref' are always valid terms (*note Insn - Lengths::.,for additional forms). `symbol_ref' is a string - denoting a C expression that yields an `int' when evaluated by the - `get_attr_...' routine. It should normally be a global variable. - -`(eq_attr NAME VALUE)' - NAME is a string specifying the name of an attribute. - - VALUE is a string that is either a valid value for attribute NAME, - a comma-separated list of values, or `!' followed by a value or - list. If VALUE does not begin with a `!', this test is true if - the value of the NAME attribute of the current insn is in the list - specified by VALUE. If VALUE begins with a `!', this test is true - if the attribute's value is *not* in the specified list. - - For example, - - (eq_attr "type" "load,store") - - is equivalent to - - (ior (eq_attr "type" "load") (eq_attr "type" "store")) - - If NAME specifies an attribute of `alternative', it refers to the - value of the compiler variable `which_alternative' (*note Output - Statement::.) and the values must be small integers. For example, - - (eq_attr "alternative" "2,3") - - is equivalent to - - (ior (eq (symbol_ref "which_alternative") (const_int 2)) - (eq (symbol_ref "which_alternative") (const_int 3))) - - Note that, for most attributes, an `eq_attr' test is simplified in - cases where the value of the attribute being tested is known for - all insns matching a particular pattern. This is by far the most - common case. - -`(attr_flag NAME)' - The value of an `attr_flag' expression is true if the flag - specified by NAME is true for the `insn' currently being scheduled. - - NAME is a string specifying one of a fixed set of flags to test. - Test the flags `forward' and `backward' to determine the direction - of a conditional branch. Test the flags `very_likely', `likely', - `very_unlikely', and `unlikely' to determine if a conditional - branch is expected to be taken. - - If the `very_likely' flag is true, then the `likely' flag is also - true. Likewise for the `very_unlikely' and `unlikely' flags. - - This example describes a conditional branch delay slot which can - be nullified for forward branches that are taken (annul-true) or - for backward branches which are not taken (annul-false). - - (define_delay (eq_attr "type" "cbranch") - [(eq_attr "in_branch_delay" "true") - (and (eq_attr "in_branch_delay" "true") - (attr_flag "forward")) - (and (eq_attr "in_branch_delay" "true") - (attr_flag "backward"))]) - - The `forward' and `backward' flags are false if the current `insn' - being scheduled is not a conditional branch. - - The `very_likely' and `likely' flags are true if the `insn' being - scheduled is not a conditional branch. The The `very_unlikely' - and `unlikely' flags are false if the `insn' being scheduled is - not a conditional branch. + To read an RTL object from a file, call `read_rtx'. It takes one +argument, a stdio stream, and returns a single RTL object. - `attr_flag' is only used during delay slot scheduling and has no - meaning to other passes of the compiler. + Reading RTL from a file is very slow. This is not currently a +problem since reading RTL occurs only as part of building the compiler. - -File: gcc.info, Node: Tagging Insns, Next: Attr Example, Prev: Expressions, Up: Insn Attributes + People frequently have the idea of using RTL stored as text in a +file as an interface between a language front end and the bulk of GNU +CC. This idea is not feasible. -Assigning Attribute Values to Insns ------------------------------------ + GNU CC was designed to use RTL internally only. Correct RTL for a +given program is very dependent on the particular target machine. And +the RTL does not contain all the information about the program. - The value assigned to an attribute of an insn is primarily -determined by which pattern is matched by that insn (or which -`define_peephole' generated it). Every `define_insn' and -`define_peephole' can have an optional last argument to specify the -values of attributes for matching insns. The value of any attribute -not specified in a particular insn is set to the default value for that -attribute, as specified in its `define_attr'. Extensive use of default -values for attributes permits the specification of the values for only -one or two attributes in the definition of most insn patterns, as seen -in the example in the next section. - - The optional last argument of `define_insn' and `define_peephole' is -a vector of expressions, each of which defines the value for a single -attribute. The most general way of assigning an attribute's value is -to use a `set' expression whose first operand is an `attr' expression -giving the name of the attribute being set. The second operand of the -`set' is an attribute expression (*note Expressions::.) giving the -value of the attribute. - - When the attribute value depends on the `alternative' attribute -(i.e., which is the applicable alternative in the constraint of the -insn), the `set_attr_alternative' expression can be used. It allows -the specification of a vector of attribute expressions, one for each -alternative. - - When the generality of arbitrary attribute expressions is not -required, the simpler `set_attr' expression can be used, which allows -specifying a string giving either a single attribute value or a list of -attribute values, one for each alternative. - - The form of each of the above specifications is shown below. In -each case, NAME is a string specifying the attribute to be set. - -`(set_attr NAME VALUE-STRING)' - VALUE-STRING is either a string giving the desired attribute value, - or a string containing a comma-separated list giving the values for - succeeding alternatives. The number of elements must match the - number of alternatives in the constraint of the insn pattern. - - Note that it may be useful to specify `*' for some alternative, in - which case the attribute will assume its default value for insns - matching that alternative. - -`(set_attr_alternative NAME [VALUE1 VALUE2 ...])' - Depending on the alternative of the insn, the value will be one of - the specified values. This is a shorthand for using a `cond' with - tests on the `alternative' attribute. - -`(set (attr NAME) VALUE)' - The first operand of this `set' must be the special RTL expression - `attr', whose sole operand is a string giving the name of the - attribute being set. VALUE is the value of the attribute. - - The following shows three different ways of representing the same -attribute value specification: - - (set_attr "type" "load,store,arith") - - (set_attr_alternative "type" - [(const_string "load") (const_string "store") - (const_string "arith")]) - - (set (attr "type") - (cond [(eq_attr "alternative" "1") (const_string "load") - (eq_attr "alternative" "2") (const_string "store")] - (const_string "arith"))) - - The `define_asm_attributes' expression provides a mechanism to -specify the attributes assigned to insns produced from an `asm' -statement. It has the form: - - (define_asm_attributes [ATTR-SETS]) - -where ATTR-SETS is specified the same as for both the `define_insn' and -the `define_peephole' expressions. - - These values will typically be the "worst case" attribute values. -For example, they might indicate that the condition code will be -clobbered. - - A specification for a `length' attribute is handled specially. The -way to compute the length of an `asm' insn is to multiply the length -specified in the expression `define_asm_attributes' by the number of -machine instructions specified in the `asm' statement, determined by -counting the number of semicolons and newlines in the string. -Therefore, the value of the `length' attribute specified in a -`define_asm_attributes' should be the maximum possible length of a -single machine instruction. + The proper way to interface GNU CC to a new language front end is +with the "tree" data structure. There is no manual for this data +structure, but it is described in the files `tree.h' and `tree.def'.  -File: gcc.info, Node: Attr Example, Next: Insn Lengths, Prev: Tagging Insns, Up: Insn Attributes +File: gcc.info, Node: Machine Desc, Next: Target Macros, Prev: RTL, Up: Top -Example of Attribute Specifications ------------------------------------ +Machine Descriptions +******************** - The judicious use of defaulting is important in the efficient use of -insn attributes. Typically, insns are divided into "types" and an -attribute, customarily called `type', is used to represent this value. -This attribute is normally used only to define the default value for -other attributes. An example will clarify this usage. - - Assume we have a RISC machine with a condition code and in which only -full-word operations are performed in registers. Let us assume that we -can divide all insns into loads, stores, (integer) arithmetic -operations, floating point operations, and branches. - - Here we will concern ourselves with determining the effect of an -insn on the condition code and will limit ourselves to the following -possible effects: The condition code can be set unpredictably -(clobbered), not be changed, be set to agree with the results of the -operation, or only changed if the item previously set into the -condition code has been modified. - - Here is part of a sample `md' file for such a machine: - - (define_attr "type" "load,store,arith,fp,branch" (const_string "arith")) - - (define_attr "cc" "clobber,unchanged,set,change0" - (cond [(eq_attr "type" "load") - (const_string "change0") - (eq_attr "type" "store,branch") - (const_string "unchanged") - (eq_attr "type" "arith") - (if_then_else (match_operand:SI 0 "" "") - (const_string "set") - (const_string "clobber"))] - (const_string "clobber"))) - - (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=r,r,m") - (match_operand:SI 1 "general_operand" "r,m,r"))] - "" - "@ - move %0,%1 - load %0,%1 - store %0,%1" - [(set_attr "type" "arith,load,store")]) - - Note that we assume in the above example that arithmetic operations -performed on quantities smaller than a machine word clobber the -condition code since they will set the condition code to a value -corresponding to the full-word result. + A machine description has two parts: a file of instruction patterns +(`.md' file) and a C header file of macro definitions. - -File: gcc.info, Node: Insn Lengths, Next: Constant Attributes, Prev: Attr Example, Up: Insn Attributes - -Computing the Length of an Insn -------------------------------- + The `.md' file for a target machine contains a pattern for each +instruction that the target machine supports (or at least each +instruction that is worth telling the compiler about). It may also +contain comments. A semicolon causes the rest of the line to be a +comment, unless the semicolon is inside a quoted string. - For many machines, multiple types of branch instructions are -provided, each for different length branch displacements. In most -cases, the assembler will choose the correct instruction to use. -However, when the assembler cannot do so, GCC can when a special -attribute, the `length' attribute, is defined. This attribute must be -defined to have numeric values by specifying a null string in its -`define_attr'. - - In the case of the `length' attribute, two additional forms of -arithmetic terms are allowed in test expressions: - -`(match_dup N)' - This refers to the address of operand N of the current insn, which - must be a `label_ref'. - -`(pc)' - This refers to the address of the *current* insn. It might have - been more consistent with other usage to make this the address of - the *next* insn but this would be confusing because the length of - the current insn is to be computed. - - For normal insns, the length will be determined by value of the -`length' attribute. In the case of `addr_vec' and `addr_diff_vec' insn -patterns, the length is computed as the number of vectors multiplied by -the size of each vector. - - Lengths are measured in addressable storage units (bytes). - - The following macros can be used to refine the length computation: - -`FIRST_INSN_ADDRESS' - When the `length' insn attribute is used, this macro specifies the - value to be assigned to the address of the first insn in a - function. If not specified, 0 is used. - -`ADJUST_INSN_LENGTH (INSN, LENGTH)' - If defined, modifies the length assigned to instruction INSN as a - function of the context in which it is used. LENGTH is an lvalue - that contains the initially computed length of the insn and should - be updated with the correct length of the insn. If updating is - required, INSN must not be a varying-length insn. - - This macro will normally not be required. A case in which it is - required is the ROMP. On this machine, the size of an `addr_vec' - insn must be increased by two to compensate for the fact that - alignment may be required. - - The routine that returns `get_attr_length' (the value of the -`length' attribute) can be used by the output routine to determine the -form of the branch instruction to be written, as the example below -illustrates. - - As an example of the specification of variable-length branches, -consider the IBM 360. If we adopt the convention that a register will -be set to the starting address of a function, we can jump to labels -within 4k of the start using a four-byte instruction. Otherwise, we -need a six-byte sequence to load the address from memory and then -branch to it. - - On such a machine, a pattern for a branch instruction might be -specified as follows: - - (define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "* - { - return (get_attr_length (insn) == 4 - ? \"b %l0\" : \"l r15,=a(%l0); br r15\"); - }" - [(set (attr "length") (if_then_else (lt (match_dup 0) (const_int 4096)) - (const_int 4) - (const_int 6)))]) + See the next chapter for information on the C header file. - -File: gcc.info, Node: Constant Attributes, Next: Delay Slots, Prev: Insn Lengths, Up: Insn Attributes - -Constant Attributes -------------------- +* Menu: - A special form of `define_attr', where the expression for the -default value is a `const' expression, indicates an attribute that is -constant for a given run of the compiler. Constant attributes may be -used to specify which variety of processor is used. For example, - - (define_attr "cpu" "m88100,m88110,m88000" - (const - (cond [(symbol_ref "TARGET_88100") (const_string "m88100") - (symbol_ref "TARGET_88110") (const_string "m88110")] - (const_string "m88000")))) - - (define_attr "memory" "fast,slow" - (const - (if_then_else (symbol_ref "TARGET_FAST_MEM") - (const_string "fast") - (const_string "slow")))) - - The routine generated for constant attributes has no parameters as it -does not depend on any particular insn. RTL expressions used to define -the value of a constant attribute may use the `symbol_ref' form, but -may not use either the `match_operand' form or `eq_attr' forms -involving insn attributes. +* Patterns:: How to write instruction patterns. +* Example:: An explained example of a `define_insn' pattern. +* RTL Template:: The RTL template defines what insns match a pattern. +* Output Template:: The output template says how to make assembler code + from such an insn. +* Output Statement:: For more generality, write C code to output + the assembler code. +* Constraints:: When not all operands are general operands. +* Standard Names:: Names mark patterns to use for code generation. +* Pattern Ordering:: When the order of patterns makes a difference. +* Dependent Patterns:: Having one pattern may make you need another. +* Jump Patterns:: Special considerations for patterns for jump insns. +* Insn Canonicalizations::Canonicalization of Instructions +* Peephole Definitions::Defining machine-specific peephole optimizations. +* Expander Definitions::Generating a sequence of several RTL insns + for a standard operation. +* Insn Splitting:: Splitting Instructions into Multiple Instructions +* Insn Attributes:: Specifying the value of attributes for generated insns.  -File: gcc.info, Node: Delay Slots, Next: Function Units, Prev: Constant Attributes, Up: Insn Attributes - -Delay Slot Scheduling ---------------------- +File: gcc.info, Node: Patterns, Next: Example, Up: Machine Desc - The insn attribute mechanism can be used to specify the requirements -for delay slots, if any, on a target machine. An instruction is said to -require a "delay slot" if some instructions that are physically after -the instruction are executed as if they were located before it. -Classic examples are branch and call instructions, which often execute -the following instruction before the branch or call is performed. - - On some machines, conditional branch instructions can optionally -"annul" instructions in the delay slot. This means that the -instruction will not be executed for certain branch outcomes. Both -instructions that annul if the branch is true and instructions that -annul if the branch is false are supported. - - Delay slot scheduling differs from instruction scheduling in that -determining whether an instruction needs a delay slot is dependent only -on the type of instruction being generated, not on data flow between the -instructions. See the next section for a discussion of data-dependent -instruction scheduling. - - The requirement of an insn needing one or more delay slots is -indicated via the `define_delay' expression. It has the following form: - - (define_delay TEST - [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1 - DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2 - ...]) - - TEST is an attribute test that indicates whether this `define_delay' -applies to a particular insn. If so, the number of required delay -slots is determined by the length of the vector specified as the second -argument. An insn placed in delay slot N must satisfy attribute test -DELAY-N. ANNUL-TRUE-N is an attribute test that specifies which insns -may be annulled if the branch is true. Similarly, ANNUL-FALSE-N -specifies which insns in the delay slot may be annulled if the branch -is false. If annulling is not supported for that delay slot, `(nil)' -should be coded. - - For example, in the common case where branch and call insns require -a single delay slot, which may contain any insn other than a branch or -call, the following would be placed in the `md' file: - - (define_delay (eq_attr "type" "branch,call") - [(eq_attr "type" "!branch,call") (nil) (nil)]) - - Multiple `define_delay' expressions may be specified. In this case, -each such expression specifies different delay slot requirements and -there must be no insn for which tests in two `define_delay' expressions -are both true. - - For example, if we have a machine that requires one delay slot for -branches but two for calls, no delay slot can contain a branch or call -insn, and any valid insn in the delay slot for the branch can be -annulled if the branch is true, we might represent this as follows: - - (define_delay (eq_attr "type" "branch") - [(eq_attr "type" "!branch,call") - (eq_attr "type" "!branch,call") - (nil)]) - - (define_delay (eq_attr "type" "call") - [(eq_attr "type" "!branch,call") (nil) (nil) - (eq_attr "type" "!branch,call") (nil) (nil)]) +Everything about Instruction Patterns +===================================== - -File: gcc.info, Node: Function Units, Prev: Delay Slots, Up: Insn Attributes + Each instruction pattern contains an incomplete RTL expression, with +pieces to be filled in later, operand constraints that restrict how the +pieces can be filled in, and an output pattern or C code to generate +the assembler output, all wrapped up in a `define_insn' expression. + + A `define_insn' is an RTL expression containing four or five +operands: + + 1. An optional name. The presence of a name indicate that this + instruction pattern can perform a certain standard job for the + RTL-generation pass of the compiler. This pass knows certain + names and will use the instruction patterns with those names, if + the names are defined in the machine description. + + The absence of a name is indicated by writing an empty string + where the name should go. Nameless instruction patterns are never + used for generating RTL code, but they may permit several simpler + insns to be combined later on. + + Names that are not thus known and used in RTL-generation have no + effect; they are equivalent to no name at all. + + 2. The "RTL template" (*note RTL Template::.) is a vector of + incomplete RTL expressions which show what the instruction should + look like. It is incomplete because it may contain + `match_operand', `match_operator', and `match_dup' expressions + that stand for operands of the instruction. + + If the vector has only one element, that element is the template + for the instruction pattern. If the vector has multiple elements, + then the instruction pattern is a `parallel' expression containing + the elements described. + + 3. A condition. This is a string which contains a C expression that + is the final test to decide whether an insn body matches this + pattern. + + For a named pattern, the condition (if present) may not depend on + the data in the insn being matched, but only the + target-machine-type flags. The compiler needs to test these + conditions during initialization in order to learn exactly which + named instructions are available in a particular run. + + For nameless patterns, the condition is applied only when matching + an individual insn, and only after the insn has matched the + pattern's recognition template. The insn's operands may be found + in the vector `operands'. + + 4. The "output template": a string that says how to output matching + insns as assembler code. `%' in this string specifies where to + substitute the value of an operand. *Note Output Template::. -Specifying Function Units -------------------------- + When simple substitution isn't general enough, you can specify a + piece of C code to compute the output. *Note Output Statement::. - On most RISC machines, there are instructions whose results are not -available for a specific number of cycles. Common cases are -instructions that load data from memory. On many machines, a pipeline -stall will result if the data is referenced too soon after the load -instruction. - - In addition, many newer microprocessors have multiple function -units, usually one for integer and one for floating point, and often -will incur pipeline stalls when a result that is needed is not yet -ready. - - The descriptions in this section allow the specification of how much -time must elapse between the execution of an instruction and the time -when its result is used. It also allows specification of when the -execution of an instruction will delay execution of similar instructions -due to function unit conflicts. - - For the purposes of the specifications in this section, a machine is -divided into "function units", each of which execute a specific class -of instructions in first-in-first-out order. Function units that -accept one instruction each cycle and allow a result to be used in the -succeeding instruction (usually via forwarding) need not be specified. -Classic RISC microprocessors will normally have a single function unit, -which we can call `memory'. The newer "superscalar" processors will -often have function units for floating point operations, usually at -least a floating point adder and multiplier. - - Each usage of a function units by a class of insns is specified with -a `define_function_unit' expression, which looks like this: - - (define_function_unit NAME MULTIPLICITY SIMULTANEITY - TEST READY-DELAY ISSUE-DELAY - [CONFLICT-LIST]) - - NAME is a string giving the name of the function unit. - - MULTIPLICITY is an integer specifying the number of identical units -in the processor. If more than one unit is specified, they will be -scheduled independently. Only truly independent units should be -counted; a pipelined unit should be specified as a single unit. (The -only common example of a machine that has multiple function units for a -single instruction class that are truly independent and not pipelined -are the two multiply and two increment units of the CDC 6600.) - - SIMULTANEITY specifies the maximum number of insns that can be -executing in each instance of the function unit simultaneously or zero -if the unit is pipelined and has no limit. - - All `define_function_unit' definitions referring to function unit -NAME must have the same name and values for MULTIPLICITY and -SIMULTANEITY. - - TEST is an attribute test that selects the insns we are describing -in this definition. Note that an insn may use more than one function -unit and a function unit may be specified in more than one -`define_function_unit'. - - READY-DELAY is an integer that specifies the number of cycles after -which the result of the instruction can be used without introducing any -stalls. - - ISSUE-DELAY is an integer that specifies the number of cycles after -the instruction matching the TEST expression begins using this unit -until a subsequent instruction can begin. A cost of N indicates an N-1 -cycle delay. A subsequent instruction may also be delayed if an -earlier instruction has a longer READY-DELAY value. This blocking -effect is computed using the SIMULTANEITY, READY-DELAY, ISSUE-DELAY, -and CONFLICT-LIST terms. For a normal non-pipelined function unit, -SIMULTANEITY is one, the unit is taken to block for the READY-DELAY -cycles of the executing insn, and smaller values of ISSUE-DELAY are -ignored. - - CONFLICT-LIST is an optional list giving detailed conflict costs for -this unit. If specified, it is a list of condition test expressions to -be applied to insns chosen to execute in NAME following the particular -insn matching TEST that is already executing in NAME. For each insn in -the list, ISSUE-DELAY specifies the conflict cost; for insns not in the -list, the cost is zero. If not specified, CONFLICT-LIST defaults to -all instructions that use the function unit. - - Typical uses of this vector are where a floating point function unit -can pipeline either single- or double-precision operations, but not -both, or where a memory unit can pipeline loads, but not stores, etc. - - As an example, consider a classic RISC machine where the result of a -load instruction is not available for two cycles (a single "delay" -instruction is required) and where only one load instruction can be -executed simultaneously. This would be specified as: - - (define_function_unit "memory" 1 1 (eq_attr "type" "load") 2 0) - - For the case of a floating point function unit that can pipeline -either single or double precision, but not both, the following could be -specified: - - (define_function_unit - "fp" 1 0 (eq_attr "type" "sp_fp") 4 4 [(eq_attr "type" "dp_fp")]) - (define_function_unit - "fp" 1 0 (eq_attr "type" "dp_fp") 4 4 [(eq_attr "type" "sp_fp")]) - - *Note:* The scheduler attempts to avoid function unit conflicts and -uses all the specifications in the `define_function_unit' expression. -It has recently come to our attention that these specifications may not -allow modeling of some of the newer "superscalar" processors that have -insns using multiple pipelined units. These insns will cause a -potential conflict for the second unit used during their execution and -there is no way of representing that conflict. We welcome any examples -of how function unit conflicts work in such processors and suggestions -for their representation. + 5. Optionally, a vector containing the values of attributes for insns + matching this pattern. *Note Insn Attributes::.  -File: gcc.info, Node: Target Macros, Next: Config, Prev: Machine Desc, Up: Top +File: gcc.info, Node: Example, Next: RTL Template, Prev: Patterns, Up: Machine Desc -Target Description Macros -************************* +Example of `define_insn' +======================== - In addition to the file `MACHINE.md', a machine description includes -a C header file conventionally given the name `MACHINE.h'. This header -file defines numerous macros that convey the information about the -target machine that does not fit into the scheme of the `.md' file. -The file `tm.h' should be a link to `MACHINE.h'. The header file -`config.h' includes `tm.h' and most compiler source files include -`config.h'. + Here is an actual example of an instruction pattern, for the +68000/68020. -* Menu: + (define_insn "tstsi" + [(set (cc0) + (match_operand:SI 0 "general_operand" "rm"))] + "" + "* + { if (TARGET_68020 || ! ADDRESS_REG_P (operands[0])) + return \"tstl %0\"; + return \"cmpl #0,%0\"; }") + + This is an instruction that sets the condition codes based on the +value of a general operand. It has no condition, so any insn whose RTL +description has the form shown may be handled according to this +pattern. The name `tstsi' means "test a `SImode' value" and tells the +RTL generation pass that, when it is necessary to test such a value, an +insn to do so can be constructed using this pattern. + + The output control string is a piece of C code which chooses which +output template to return based on the kind of operand and the specific +type of CPU for which code is being generated. -* Driver:: Controlling how the driver runs the compilation passes. -* Run-time Target:: Defining `-m' options like `-m68000' and `-m68020'. -* Storage Layout:: Defining sizes and alignments of data. -* Type Layout:: Defining sizes and properties of basic user data types. -* Registers:: Naming and describing the hardware registers. -* Register Classes:: Defining the classes of hardware registers. -* Stack and Calling:: Defining which way the stack grows and by how much. -* Varargs:: Defining the varargs macros. -* Trampolines:: Code set up at run time to enter a nested function. -* Library Calls:: Controlling how library routines are implicitly called. -* Addressing Modes:: Defining addressing modes valid for memory operands. -* Condition Code:: Defining how insns update the condition code. -* Costs:: Defining relative costs of different operations. -* Sections:: Dividing storage into text, data, and other sections. -* PIC:: Macros for position independent code. -* Assembler Format:: Defining how to write insns and pseudo-ops to output. -* Debugging Info:: Defining the format of debugging output. -* Cross-compilation:: Handling floating point for cross-compilers. -* Misc:: Everything else. + `"rm"' is an operand constraint. Its meaning is explained below.