--- gcc/gcc.info-15 2018/04/24 18:09:07 1.1.1.5 +++ gcc/gcc.info-15 2018/04/24 18:12:34 1.1.1.6 @@ -28,1024 +28,1065 @@ permission notice, may be included in tr 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: Standard Names, Next: Pattern Ordering, Prev: Constraints, Up: Machine Desc -Defining RTL Sequences for Code Generation -========================================== +Standard Pattern Names For Generation +===================================== - 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. + Here is a table of the instruction names that are meaningful in the +RTL generation pass of the compiler. Giving one of these names to an +instruction pattern tells the RTL generation pass that it can use the +pattern in to accomplish a certain task. + +`movM' + Here M stands for a two-letter machine mode name, in lower case. + This instruction pattern moves data with that machine mode from + operand 1 to operand 0. For example, `movsi' moves full-word data. + + If operand 0 is a `subreg' with mode M of a register whose own + mode is wider than M, the effect of this instruction is to store + the specified value in the part of the register that corresponds + to mode M. The effect on the rest of the register is undefined. + + This class of patterns is special in several ways. First of all, + each of these names *must* be defined, because there is no other + way to copy a datum from one place to another. + + Second, these patterns are not used solely in the RTL generation + pass. Even the reload pass can generate move insns to copy values + from stack slots into temporary registers. When it does so, one + of the operands is a hard register and the other is an operand + that can need to be reloaded into a register. + + Therefore, when given such a pair of operands, the pattern must + generate RTL which needs no reloading and needs no temporary + registers--no registers other than the operands. For example, if + you support the pattern with a `define_expand', then in such a + case the `define_expand' mustn't call `force_reg' or any other such + function which might generate new pseudo registers. + + This requirement exists even for subword modes on a RISC machine + where fetching those modes from memory normally requires several + insns and some temporary registers. Look in `spur.md' to see how + the requirement can be satisfied. + + During reload a memory reference with an invalid address may be + passed as an operand. Such an address will be replaced with a + valid address later in the reload pass. In this case, nothing may + be done with the address except to use it as it stands. If it is + copied, it will not be replaced with a valid address. No attempt + should be made to make such an address into a valid address and no + routine (such as `change_address') that will do so may be called. + Note that `general_operand' will fail when applied to such an + address. + + The global variable `reload_in_progress' (which must be explicitly + declared if required) can be used to determine whether such special + handling is required. + + The variety of operands that have reloads depends on the rest of + the machine description, but typically on a RISC machine these can + only be pseudo registers that did not get hard registers, while on + other machines explicit memory references will get optional + reloads. + + If a scratch register is required to move an object to or from + memory, it can be allocated using `gen_reg_rtx' prior to reload. + But this is impossible during and after reload. If there are + cases needing scratch registers after reload, you must define + `SECONDARY_INPUT_RELOAD_CLASS' and perhaps also + `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide + patterns `reload_inM' or `reload_outM' to handle them. *Note + Register Classes::. + + The constraints on a `moveM' must permit moving any hard register + to any other hard register provided that `HARD_REGNO_MODE_OK' + permits mode M in both registers and `REGISTER_MOVE_COST' applied + to their classes returns a value of 2. + + It is obligatory to support floating point `moveM' instructions + into and out of any registers that can hold fixed point values, + because unions and structures (which have modes `SImode' or + `DImode') can be in those registers and they may have floating + point members. + + There may also be a need to support fixed point `moveM' + instructions in and out of floating point registers. + Unfortunately, I have forgotten why this was so, and I don't know + whether it is still true. If `HARD_REGNO_MODE_OK' rejects fixed + point values in floating point registers, then the constraints of + the fixed point `moveM' instructions must be designed to avoid + ever trying to reload into a floating point register. + +`reload_inM' +`reload_outM' + Like `movM', but used when a scratch register is required to move + between operand 0 and operand 1. Operand 2 describes the scratch + register. See the discussion of the `SECONDARY_RELOAD_CLASS' + macro in *note Register Classes::.. + +`movstrictM' + Like `movM' except that if operand 0 is a `subreg' with mode M of + a register whose natural mode is wider, the `movstrictM' + instruction is guaranteed not to alter any of the register except + the part which belongs to mode M. + +`load_multiple' + Load several consecutive memory locations into consecutive + registers. Operand 0 is the first of the consecutive registers, + operand 1 is the first memory location, and operand 2 is a + constant: the number of consecutive registers. + + Define this only if the target machine really has such an + instruction; do not define this if the most efficient way of + loading consecutive registers from memory is to do them one at a + time. + + On some machines, there are restrictions as to which consecutive + registers can be stored into memory, such as particular starting or + ending register numbers or only a range of valid counts. For those + machines, use a `define_expand' (*note Expander Definitions::.) + and make the pattern fail if the restrictions are not met. + + Write the generated insn as a `parallel' with elements being a + `set' of one register from the appropriate memory location (you may + also need `use' or `clobber' elements). Use a `match_parallel' + (*note RTL Template::.) to recognize the insn. See `a29k.md' and + `rs6000.md' for examples of the use of this insn pattern. + +`store_multiple' + Similar to `load_multiple', but store several consecutive registers + into consecutive memory locations. Operand 0 is the first of the + consecutive memory locations, operand 1 is the first register, and + operand 2 is a constant: the number of consecutive registers. + +`addM3' + Add operand 2 and operand 1, storing the result in operand 0. All + operands must have mode M. This can be used even on two-address + machines, by means of constraints requiring operands 1 and 0 to be + the same location. + +`subM3', `mulM3' +`divM3', `udivM3', `modM3', `umodM3' +`sminM3', `smaxM3', `uminM3', `umaxM3' +`andM3', `iorM3', `xorM3' + Similar, for other arithmetic operations. + +`mulhisi3' + Multiply operands 1 and 2, which have mode `HImode', and store a + `SImode' product in operand 0. + +`mulqihi3', `mulsidi3' + Similar widening-multiplication instructions of other widths. + +`umulqihi3', `umulhisi3', `umulsidi3' + Similar widening-multiplication instructions that do unsigned + multiplication. + +`divmodM4' + Signed division that produces both a quotient and a remainder. + Operand 1 is divided by operand 2 to produce a quotient stored in + operand 0 and a remainder stored in operand 3. + + For machines with an instruction that produces both a quotient and + a remainder, provide a pattern for `divmodM4' but do not provide + patterns for `divM3' and `modM3'. This allows optimization in the + relatively common case when both the quotient and remainder are + computed. + + If an instruction that just produces a quotient or just a remainder + exists and is more efficient than the instruction that produces + both, write the output routine of `divmodM4' to call + `find_reg_note' and look for a `REG_UNUSED' note on the quotient + or remainder and generate the appropriate instruction. + +`udivmodM4' + Similar, but does unsigned division. + +`ashlM3' + Arithmetic-shift operand 1 left by a number of bits specified by + operand 2, and store the result in operand 0. Here M is the mode + of operand 0 and operand 1; operand 2's mode is specified by the + instruction pattern, and the compiler will convert the operand to + that mode before generating the instruction. + +`ashrM3', `lshlM3', `lshrM3', `rotlM3', `rotrM3' + Other shift and rotate instructions, analogous to the `ashlM3' + instructions. + + Logical and arithmetic left shift are the same. Machines that do + not allow negative shift counts often have only one instruction for + shifting left. On such machines, you should define a pattern named + `ashlM3' and leave `lshlM3' undefined. + +`negM2' + Negate operand 1 and store the result in operand 0. + +`absM2' + Store the absolute value of operand 1 into operand 0. + +`sqrtM2' + Store the square root of operand 1 into operand 0. + + The `sqrt' built-in function of C always uses the mode which + corresponds to the C data type `double'. + +`ffsM2' + Store into operand 0 one plus the index of the least significant + 1-bit of operand 1. If operand 1 is zero, store zero. M is the + mode of operand 0; operand 1's mode is specified by the instruction + pattern, and the compiler will convert the operand to that mode + before generating the instruction. + + The `ffs' built-in function of C always uses the mode which + corresponds to the C data type `int'. + +`one_cmplM2' + Store the bitwise-complement of operand 1 into operand 0. + +`cmpM' + Compare operand 0 and operand 1, and set the condition codes. The + RTL pattern should look like this: + + (set (cc0) (compare (match_operand:M 0 ...) + (match_operand:M 1 ...))) + +`tstM' + Compare operand 0 against zero, and set the condition codes. The + RTL pattern should look like this: + + (set (cc0) (match_operand:M 0 ...)) + + `tstM' patterns should not be defined for machines that do not use + `(cc0)'. Doing so would confuse the optimizer since it would no + longer be clear which `set' operations were comparisons. The + `cmpM' patterns should be used instead. + +`movstrM' + Block move instruction. The addresses of the destination and + source strings are the first two operands, and both are in mode + `Pmode'. The number of bytes to move is the third operand, in + mode M. + + The fourth operand is the known shared alignment of the source and + destination, in the form of a `const_int' rtx. Thus, if the + compiler knows that both source and destination are word-aligned, + it may provide the value 4 for this operand. + + These patterns need not give special consideration to the + possibility that the source and destination strings might overlap. + +`cmpstrM' + Block compare instruction, with five operands. Operand 0 is the + output; it has mode M. The remaining four operands are like the + operands of `movstrM'. The two memory blocks specified are + compared byte by byte in lexicographic order. The effect of the + instruction is to store a value in operand 0 whose sign indicates + the result of the comparison. + + Compute the length of a string, with three operands. Operand 0 is + the result (of mode M), operand 1 is a `mem' referring to the + first character of the string, operand 2 is the character to + search for (normally zero), and operand 3 is a constant describing + the known alignment of the beginning of the string. + +`floatMN2' + Convert signed integer operand 1 (valid for fixed point mode M) to + floating point mode N and store in operand 0 (which has mode N). + +`floatunsMN2' + Convert unsigned integer operand 1 (valid for fixed point mode M) + to floating point mode N and store in operand 0 (which has mode N). + +`fixMN2' + Convert operand 1 (valid for floating point mode M) to fixed point + mode N as a signed number and store in operand 0 (which has mode + N). This instruction's result is defined only when the value of + operand 1 is an integer. + +`fixunsMN2' + Convert operand 1 (valid for floating point mode M) to fixed point + mode N as an unsigned number and store in operand 0 (which has + mode N). This instruction's result is defined only when the value + of operand 1 is an integer. + +`ftruncM2' + Convert operand 1 (valid for floating point mode M) to an integer + value, still represented in floating point mode M, and store it in + operand 0 (valid for floating point mode M). + +`fix_truncMN2' + Like `fixMN2' but works for any floating point value of mode M by + converting the value to an integer. + +`fixuns_truncMN2' + Like `fixunsMN2' but works for any floating point value of mode M + by converting the value to an integer. + +`truncMN' + Truncate operand 1 (valid for mode M) to mode N and store in + operand 0 (which has mode N). Both modes must be fixed point or + both floating point. + +`extendMN' + Sign-extend operand 1 (valid for mode M) to mode N and store in + operand 0 (which has mode N). Both modes must be fixed point or + both floating point. + +`zero_extendMN' + Zero-extend operand 1 (valid for mode M) to mode N and store in + operand 0 (which has mode N). Both modes must be fixed point. + +`extv' + Extract a bit field from operand 1 (a register or memory operand), + where operand 2 specifies the width in bits and operand 3 the + starting bit, and store it in operand 0. Operand 0 must have mode + `word_mode'. Operand 1 may have mode `byte_mode' or `word_mode'; + often `word_mode' is allowed only for registers. Operands 2 and 3 + must be valid for `word_mode'. + + The RTL generation pass generates this instruction only with + constants for operands 2 and 3. + + The bit-field value is sign-extended to a full word integer before + it is stored in operand 0. + +`extzv' + Like `extv' except that the bit-field value is zero-extended. + +`insv' + Store operand 3 (which must be valid for `word_mode') into a bit + field in operand 0, where operand 1 specifies the width in bits and + operand 2 the starting bit. Operand 0 may have mode `byte_mode' or + `word_mode'; often `word_mode' is allowed only for registers. + Operands 1 and 2 must be valid for `word_mode'. + + The RTL generation pass generates this instruction only with + constants for operands 1 and 2. + +`sCOND' + Store zero or nonzero in the operand according to the condition + codes. Value stored is nonzero iff the condition COND is true. + cOND is the name of a comparison operation expression code, such + as `eq', `lt' or `leu'. + + You specify the mode that the operand must have when you write the + `match_operand' expression. The compiler automatically sees which + mode you have used and supplies an operand of that mode. + + The value stored for a true condition must have 1 as its low bit, + or else must be negative. Otherwise the instruction is not + suitable and you should omit it from the machine description. You + describe to the compiler exactly which value is stored by defining + the macro `STORE_FLAG_VALUE' (*note Misc::.). If a description + cannot be found that can be used for all the `sCOND' patterns, you + should omit those operations from the machine description. + + These operations may fail, but should do so only in relatively + uncommon cases; if they would fail for common cases involving + integer comparisons, it is best to omit these patterns. + + If these operations are omitted, the compiler will usually + generate code that copies the constant one to the target and + branches around an assignment of zero to the target. If this code + is more efficient than the potential instructions used for the + `sCOND' pattern followed by those required to convert the result + into a 1 or a zero in `SImode', you should omit the `sCOND' + operations from the machine description. + +`bCOND' + Conditional branch instruction. Operand 0 is a `label_ref' that + refers to the label to jump to. Jump if the condition codes meet + condition COND. + + Some machines do not follow the model assumed here where a + comparison instruction is followed by a conditional branch + instruction. In that case, the `cmpM' (and `tstM') patterns should + simply store the operands away and generate all the required insns + in a `define_expand' (*note Expander Definitions::.) for the + conditional branch operations. All calls to expand `bCOND' + patterns are immediately preceded by calls to expand either a + `cmpM' pattern or a `tstM' pattern. + + Machines that use a pseudo register for the condition code value, + or where the mode used for the comparison depends on the condition + being tested, should also use the above mechanism. *Note Jump + Patterns:: + + The above discussion also applies to `sCOND' patterns. + +`call' + Subroutine call instruction returning no value. Operand 0 is the + function to call; operand 1 is the number of bytes of arguments + pushed (in mode `SImode', except it is normally a `const_int'); + operand 2 is the number of registers used as operands. + + On most machines, operand 2 is not actually stored into the RTL + pattern. It is supplied for the sake of some RISC machines which + need to put this information into the assembler code; they can put + it in the RTL instead of operand 1. + + Operand 0 should be a `mem' RTX whose address is the address of the + function. Note, however, that this address can be a `symbol_ref' + expression even if it would not be a legitimate memory address on + the target machine. If it is also not a valid argument for a call + instruction, the pattern for this operation should be a + `define_expand' (*note Expander Definitions::.) that places the + address into a register and uses that register in the call + instruction. + +`call_value' + Subroutine call instruction returning a value. Operand 0 is the + hard register in which the value is returned. There are three more + operands, the same as the three operands of the `call' instruction + (but with numbers increased by one). + + Subroutines that return `BLKmode' objects use the `call' insn. + +`call_pop', `call_value_pop' + Similar to `call' and `call_value', except used if defined and if + `RETURN_POPS_ARGS' is non-zero. They should emit a `parallel' + that contains both the function call and a `set' to indicate the + adjustment made to the frame pointer. + + For machines where `RETURN_POPS_ARGS' can be non-zero, the use of + these patterns increases the number of functions for which the + frame pointer can be eliminated, if desired. + +`untyped_call' + Subroutine call instruction returning a value of any type. + Operand 0 is the function to call; operand 1 is a memory location + where the result of calling the function is to be stored; operand + 2 is a `parallel' expression where each element is a `set' + expression that indicates the saving of a function return value + into the result block. + + This instruction pattern should be defined to support + `__builtin_apply' on machines where special instructions are needed + to call a subroutine with arbitrary arguments or to save the value + returned. This instruction pattern is required on machines that + have multiple registers that can hold a return value (i.e. + `FUNCTION_VALUE_REGNO_P' is true for more than one register). + +`return' + Subroutine return instruction. This instruction pattern name + should be defined only if a single instruction can do all the work + of returning from a function. + + Like the `movM' patterns, this pattern is also used after the RTL + generation phase. In this case it is to support machines where + multiple instructions are usually needed to return from a + function, but some class of functions only requires one + instruction to implement a return. Normally, the applicable + functions are those which do not need to save any registers or + allocate stack space. + + For such machines, the condition specified in this pattern should + only be true when `reload_completed' is non-zero and the function's + epilogue would only be a single instruction. For machines with + register windows, the routine `leaf_function_p' may be used to + determine if a register window push is required. + + Machines that have conditional return instructions should define + patterns such as + + (define_insn "" + [(set (pc) + (if_then_else (match_operator + 0 "comparison_operator" + [(cc0) (const_int 0)]) + (return) + (pc)))] + "CONDITION" + "...") + + where CONDITION would normally be the same condition specified on + the named `return' pattern. + +`untyped_return' + Untyped subroutine return instruction. This instruction pattern + should be defined to support `__builtin_return' on machines where + special instructions are needed to return a value of any type. + + Operand 0 is a memory location where the result of calling a + function with `__builtin_apply' is stored; operand 1 is a + `parallel' expression where each element is a `set' expression + that indicates the restoring of a function return value from the + result block. + +`nop' + No-op instruction. This instruction pattern name should always be + defined to output a no-op in assembler code. `(const_int 0)' will + do as an RTL pattern. + +`indirect_jump' + An instruction to jump to an address which is operand zero. This + pattern name is mandatory on all machines. + +`casesi' + Instruction to jump through a dispatch table, including bounds + checking. This instruction takes five operands: + + 1. The index to dispatch on, which has mode `SImode'. + + 2. The lower bound for indices in the table, an integer constant. + + 3. The total range of indices in the table--the largest index + minus the smallest one (both inclusive). + + 4. A label that precedes the table itself. + + 5. A label to jump to if the index has a value outside the + bounds. (If the machine-description macro + `CASE_DROPS_THROUGH' is defined, then an out-of-bounds index + drops through to the code following the jump table instead of + jumping to this label. In that case, this label is not + actually used by the `casesi' instruction, but it is always + provided as an operand.) + + The table is a `addr_vec' or `addr_diff_vec' inside of a + `jump_insn'. The number of elements in the table is one plus the + difference between the upper bound and the lower bound. + +`tablejump' + Instruction to jump to a variable address. This is a low-level + capability which can be used to implement a dispatch table when + there is no `casesi' pattern. + + This pattern requires two operands: the address or offset, and a + label which should immediately precede the jump table. If the + macro `CASE_VECTOR_PC_RELATIVE' is defined then the first operand + is an offset which counts from the address of the table; + otherwise, it is an absolute address to jump to. In either case, + the first operand has mode `Pmode'. + + The `tablejump' insn is always the last insn before the jump table + it uses. Its assembler code normally has no need to use the + second operand, but you should incorporate it in the RTL pattern so + that the jump optimizer will not delete the table as unreachable + code. + +`save_stack_block' +`save_stack_function' +`save_stack_nonlocal' +`restore_stack_block' +`restore_stack_function' +`restore_stack_nonlocal' + Most machines save and restore the stack pointer by copying it to + or from an object of mode `Pmode'. Do not define these patterns on + such machines. + + Some machines require special handling for stack pointer saves and + restores. On those machines, define the patterns corresponding to + the non-standard cases by using a `define_expand' (*note Expander + Definitions::.) that produces the required insns. The three types + of saves and restores are: + + 1. `save_stack_block' saves the stack pointer at the start of a + block that allocates a variable-sized object, and + `restore_stack_block' restores the stack pointer when the + block is exited. + + 2. `save_stack_function' and `restore_stack_function' do a + similar job for the outermost block of a function and are + used when the function allocates variable-sized objects or + calls `alloca'. Only the epilogue uses the restored stack + pointer, allowing a simpler save or restore sequence on some + machines. + + 3. `save_stack_nonlocal' is used in functions that contain labels + branched to by nested functions. It saves the stack pointer + in such a way that the inner function can use + `restore_stack_nonlocal' to restore the stack pointer. The + compiler generates code to restore the frame and argument + pointer registers, but some machines require saving and + restoring additional data such as register window information + or stack backchains. Place insns in these patterns to save + and restore any such required data. + + When saving the stack pointer, operand 0 is the save area and + operand 1 is the stack pointer. The mode used to allocate the + save area is the mode of operand 0. You must specify an integral + mode, or `VOIDmode' if no save area is needed for a particular + type of save (either because no save is needed or because a + machine-specific save area can be used). Operand 0 is the stack + pointer and operand 1 is the save area for restore operations. If + `save_stack_block' is defined, operand 0 must not be `VOIDmode' + since these saves can be arbitrarily nested. + + A save area is a `mem' that is at a constant offset from + `virtual_stack_vars_rtx' when the stack pointer is saved for use by + nonlocal gotos and a `reg' in the other two cases. + +`allocate_stack' + Subtract (or add if `STACK_GROWS_DOWNWARD' is undefined) operand 0 + from the stack pointer to create space for dynamically allocated + data. + + Do not define this pattern if all that must be done is the + subtraction. Some machines require other operations such as stack + probes or maintaining the back chain. Define this pattern to emit + those operations in addition to updating the stack pointer.  -File: gcc.info, Node: Insn Splitting, Next: Insn Attributes, Prev: Expander Definitions, Up: Machine Desc +File: gcc.info, Node: Pattern Ordering, Next: Dependent Patterns, Prev: Standard Names, Up: Machine Desc -Defining How to Split Instructions +When the Order of Patterns Matters ================================== - 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: - -* 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. - - -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. - - LIST-OF-VALUES is either a string that specifies a comma-separated -list of values that can be assigned to the attribute, or a null string -to indicate that the attribute takes numeric values. - - DEFAULT is an attribute expression that gives the value of this -attribute for insns that match patterns whose definition does not -include an explicit value for this attribute. *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. - - 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: - - * A `#define' is written for the symbol `HAVE_ATTR_NAME'. - - * 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. - - * A function `get_attr_NAME' is defined that is passed an insn and - returns the attribute value for that insn. - - For example, if the following is present in the `md' file: - - (define_attr "type" "branch,fp,load,store,arith" ...) - -the following lines will be written to the file `insn-attr.h'. - - #define HAVE_ATTR_type - enum attr_type {TYPE_BRANCH, TYPE_FP, TYPE_LOAD, - TYPE_STORE, TYPE_ARITH}; - extern enum attr_type get_attr_type (); - - If the attribute takes numeric values, no `enum' type will be -defined and the function to obtain the attribute's value will return -`int'. + Sometimes an insn can match more than one instruction pattern. Then +the pattern that appears first in the machine description is the one +used. Therefore, more specific patterns (patterns that will match +fewer things) and faster instructions (those that will produce better +code when they do match) should usually go first in the description. + + In some cases the effect of ordering the patterns can be used to hide +a pattern when it is not valid. For example, the 68000 has an +instruction for converting a fullword to floating point and another for +converting a byte to floating point. An instruction converting an +integer to floating point could match either one. We put the pattern +to convert the fullword first to make sure that one will be used rather +than the other. (Otherwise a large integer might be generated as a +single-byte immediate quantity, which would not work.) Instead of using +this pattern ordering it would be possible to make the pattern for +convert-a-byte smart enough to deal properly with any constant value.  -File: gcc.info, Node: Expressions, Next: Tagging Insns, Prev: Defining Attributes, Up: Insn Attributes - -Attribute Expressions ---------------------- - - 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. +File: gcc.info, Node: Dependent Patterns, Next: Jump Patterns, Prev: Pattern Ordering, Up: Machine Desc - `attr_flag' is only used during delay slot scheduling and has no - meaning to other passes of the compiler. +Interdependence of Patterns +=========================== - -File: gcc.info, Node: Tagging Insns, Next: Attr Example, Prev: Expressions, Up: Insn Attributes - -Assigning Attribute Values to Insns ------------------------------------ + Every machine description must have a named pattern for each of the +conditional branch names `bCOND'. The recognition template must always +have the form + + (set (pc) + (if_then_else (COND (cc0) (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc))) + +In addition, every machine description must have an anonymous pattern +for each of the possible reverse-conditional branches. Their templates +look like + + (set (pc) + (if_then_else (COND (cc0) (const_int 0)) + (pc) + (label_ref (match_operand 0 "" "")))) + +They are necessary because jump optimization can turn direct-conditional +branches into reverse-conditional branches. + + It is often convenient to use the `match_operator' construct to +reduce the number of patterns that must be specified for branches. For +example, - 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. + (define_insn "" + [(set (pc) + (if_then_else (match_operator 0 "comparison_operator" + [(cc0) (const_int 0)]) + (pc) + (label_ref (match_operand 1 "" ""))))] + "CONDITION" + "...") - The following shows three different ways of representing the same -attribute value specification: + In some cases machines support instructions identical except for the +machine mode of one or more operands. For example, there may be +"sign-extend halfword" and "sign-extend byte" instructions whose +patterns are - (set_attr "type" "load,store,arith") + (set (match_operand:SI 0 ...) + (extend:SI (match_operand:HI 1 ...))) - (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. - - -File: gcc.info, Node: Attr Example, Next: Insn Lengths, Prev: Tagging Insns, Up: Insn Attributes - -Example of Attribute Specifications ------------------------------------ - - 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. + (set (match_operand:SI 0 ...) + (extend:SI (match_operand:QI 1 ...))) - 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. +Constant integers do not specify a machine mode, so an instruction to +extend a constant value could match either pattern. The pattern it +actually will match is the one that appears first in the file. For +correct results, this must be the one for the widest possible mode +(`HImode', here). If the pattern matches the `QImode' instruction, the +results will be incorrect if the constant value does not actually fit +that mode. + + Such instructions to extend constants are rarely generated because +they are optimized away, but they do occasionally happen in nonoptimized +compilations. + + If a constraint in a pattern allows a constant, the reload pass may +replace a register with a constant permitted by the constraint in some +cases. Similarly for memory references. You must ensure that the +predicate permits all objects allowed by the constraints to prevent the +compiler from crashing. + + Because of this substitution, you should not provide separate +patterns for increment and decrement instructions. Instead, they +should be generated from the same pattern that supports +register-register add insns by examining the operands and generating +the appropriate machine instruction.  -File: gcc.info, Node: Insn Lengths, Next: Constant Attributes, Prev: Attr Example, Up: Insn Attributes - -Computing the Length of an Insn -------------------------------- +File: gcc.info, Node: Jump Patterns, Next: Insn Canonicalizations, Prev: Dependent Patterns, Up: Machine Desc - 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. +Defining Jump Instruction Patterns +================================== - On such a machine, a pattern for a branch instruction might be -specified as follows: + For most machines, GNU CC assumes that the machine has a condition +code. A comparison insn sets the condition code, recording the results +of both signed and unsigned comparison of the given operands. A +separate branch insn tests the condition code and branches or not +according its value. The branch insns come in distinct signed and +unsigned flavors. Many common machines, such as the Vax, the 68000 and +the 32000, work this way. + + Some machines have distinct signed and unsigned compare +instructions, and only one set of conditional branch instructions. The +easiest way to handle these machines is to treat them just like the +others until the final stage where assembly code is written. At this +time, when outputting code for the compare instruction, peek ahead at +the following branch using `next_cc0_user (insn)'. (The variable +`insn' refers to the insn being output, in the output-writing code in +an instruction pattern.) If the RTL says that is an unsigned branch, +output an unsigned compare; otherwise output a signed compare. When +the branch itself is output, you can treat signed and unsigned branches +identically. + + The reason you can do this is that GNU CC always generates a pair of +consecutive RTL insns, possibly separated by `note' insns, one to set +the condition code and one to test it, and keeps the pair inviolate +until the end. + + To go with this technique, you must define the machine-description +macro `NOTICE_UPDATE_CC' to do `CC_STATUS_INIT'; in other words, no +compare instruction is superfluous. + + Some machines have compare-and-branch instructions and no condition +code. A similar technique works for them. When it is time to "output" +a compare instruction, record its operands in two static variables. +When outputting the branch-on-condition-code instruction that follows, +actually output a compare-and-branch instruction that uses the +remembered operands. + + It also works to define patterns for compare-and-branch instructions. +In optimizing compilation, the pair of compare and branch instructions +will be combined according to these patterns. But this does not happen +if optimization is not requested. So you must use one of the solutions +above in addition to any special patterns you define. + + In many RISC machines, most instructions do not affect the condition +code and there may not even be a separate condition code register. On +these machines, the restriction that the definition and use of the +condition code be adjacent insns is not necessary and can prevent +important optimizations. For example, on the IBM RS/6000, there is a +delay for taken branches unless the condition code register is set three +instructions earlier than the conditional branch. The instruction +scheduler cannot perform this optimization if it is not permitted to +separate the definition and use of the condition code register. + + On these machines, do not use `(cc0)', but instead use a register to +represent the condition code. If there is a specific condition code +register in the machine, use a hard register. If the condition code or +comparison result can be placed in any general register, or if there are +multiple condition registers, use a pseudo register. + + On some machines, the type of branch instruction generated may +depend on the way the condition code was produced; for example, on the +68k and Sparc, setting the condition code directly from an add or +subtract instruction does not clear the overflow bit the way that a test +instruction does, so a different branch instruction must be used for +some conditional branches. For machines that use `(cc0)', the set and +use of the condition code must be adjacent (separated only by `note' +insns) allowing flags in `cc_status' to be used. (*Note Condition +Code::.) Also, the comparison and branch insns can be located from +each other by using the functions `prev_cc0_setter' and `next_cc0_user'. + + However, this is not true on machines that do not use `(cc0)'. On +those machines, no assumptions can be made about the adjacency of the +compare and branch insns and the above methods cannot be used. Instead, +we use the machine mode of the condition code register to record +different formats of the condition code register. + + Registers used to store the condition code value should have a mode +that is in class `MODE_CC'. Normally, it will be `CCmode'. If +additional modes are required (as for the add example mentioned above in +the Sparc), define the macro `EXTRA_CC_MODES' to list the additional +modes required (*note Condition Code::.). Also define `EXTRA_CC_NAMES' +to list the names of those modes and `SELECT_CC_MODE' to choose a mode +given an operand of a compare. + + If it is known during RTL generation that a different mode will be +required (for example, if the machine has separate compare instructions +for signed and unsigned quantities, like most IBM processors), they can +be specified at that time. + + If the cases that require different modes would be made by +instruction combination, the macro `SELECT_CC_MODE' determines which +machine mode should be used for the comparison result. The patterns +should be written using that mode. To support the case of the add on +the Sparc discussed above, we have the pattern - (define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] + (define_insn "" + [(set (reg:CC_NOOV 0) + (compare:CC_NOOV + (plus:SI (match_operand:SI 0 "register_operand" "%r") + (match_operand:SI 1 "arith_operand" "rI")) + (const_int 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)))]) + "...") - -File: gcc.info, Node: Constant Attributes, Next: Delay Slots, Prev: Insn Lengths, Up: Insn Attributes - -Constant Attributes -------------------- - - 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. + The `SELECT_CC_MODE' macro on the Sparc returns `CC_NOOVmode' for +comparisons whose argument is a `plus'.  -File: gcc.info, Node: Delay Slots, Next: Function Units, Prev: Constant Attributes, Up: Insn Attributes +File: gcc.info, Node: Insn Canonicalizations, Next: Peephole Definitions, Prev: Jump Patterns, Up: Machine Desc -Delay Slot Scheduling ---------------------- +Canonicalization of Instructions +================================ - 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)]) + There are often cases where multiple RTL expressions could represent +an operation performed by a single machine instruction. This situation +is most commonly encountered with logical, branch, and +multiply-accumulate instructions. In such cases, the compiler attempts +to convert these multiple RTL expressions into a single canonical form +to reduce the number of insn patterns required. + + In addition to algebraic simplifications, following canonicalizations +are performed: + + * For commutative and comparison operators, a constant is always + made the second operand. If a machine only supports a constant as + the second operand, only patterns that match a constant in the + second operand need be supplied. + + For these operators, if only one operand is a `neg', `not', + `mult', `plus', or `minus' expression, it will be the first + operand. + + * For the `compare' operator, a constant is always the second operand + on machines where `cc0' is used (*note Jump Patterns::.). On other + machines, there are rare cases where the compiler might want to + construct a `compare' with a constant as the first operand. + However, these cases are not common enough for it to be worthwhile + to provide a pattern matching a constant as the first operand + unless the machine actually has such an instruction. + + An operand of `neg', `not', `mult', `plus', or `minus' is made the + first operand under the same conditions as above. + + * `(minus X (const_int N))' is converted to `(plus X (const_int + -N))'. + + * Within address computations (i.e., inside `mem'), a left shift is + converted into the appropriate multiplication by a power of two. + + De`Morgan's Law is used to move bitwise negation inside a bitwise + logical-and or logical-or operation. If this results in only one + operand being a `not' expression, it will be the first one. + + A machine that has an instruction that performs a bitwise + logical-and of one operand with the bitwise negation of the other + should specify the pattern for that instruction as + + (define_insn "" + [(set (match_operand:M 0 ...) + (and:M (not:M (match_operand:M 1 ...)) + (match_operand:M 2 ...)))] + "..." + "...") + + Similarly, a pattern for a "NAND" instruction should be written + + (define_insn "" + [(set (match_operand:M 0 ...) + (ior:M (not:M (match_operand:M 1 ...)) + (not:M (match_operand:M 2 ...))))] + "..." + "...") + + In both cases, it is not necessary to include patterns for the many + logically equivalent RTL expressions. + + * The only possible RTL expressions involving both bitwise + exclusive-or and bitwise negation are `(xor:M X Y)' and `(not:M + (xor:M X Y))'. + + * The sum of three items, one of which is a constant, will only + appear in the form + + (plus:M (plus:M X Y) CONSTANT) + + * On machines that do not use `cc0', `(compare X (const_int 0))' + will be converted to X. + + * Equality comparisons of a group of bits (usually a single bit) + with zero will be written using `zero_extract' rather than the + equivalent `and' or `sign_extract' operations.  -File: gcc.info, Node: Function Units, Prev: Delay Slots, Up: Insn Attributes +File: gcc.info, Node: Peephole Definitions, Next: Expander Definitions, Prev: Insn Canonicalizations, Up: Machine Desc -Specifying Function Units -------------------------- +Machine-Specific Peephole Optimizers +==================================== - 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. + In addition to instruction patterns the `md' file may contain +definitions of machine-specific peephole optimizations. - -File: gcc.info, Node: Target Macros, Next: Config, Prev: Machine Desc, Up: Top - -Target Description Macros -************************* + The combiner does not notice certain peephole optimizations when the +data flow in the program does not suggest that it should try them. For +example, sometimes two consecutive insns related in purpose can be +combined even though the second one does not appear to use a register +computed in the first one. A machine-specific peephole optimizer can +detect such opportunities. + + A definition looks like this: + + (define_peephole + [INSN-PATTERN-1 + INSN-PATTERN-2 + ...] + "CONDITION" + "TEMPLATE" + "OPTIONAL INSN-ATTRIBUTES") - 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'. - -* Menu: - -* 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. +The last string operand may be omitted if you are not using any +machine-specific information in this machine description. If present, +it must obey the same rules as in a `define_insn'. + + In this skeleton, INSN-PATTERN-1 and so on are patterns to match +consecutive insns. The optimization applies to a sequence of insns when +INSN-PATTERN-1 matches the first one, INSN-PATTERN-2 matches the next, +and so on. + + Each of the insns matched by a peephole must also match a +`define_insn'. Peepholes are checked only at the last stage just +before code generation, and only optionally. Therefore, any insn which +would match a peephole but no `define_insn' will cause a crash in code +generation in an unoptimized compilation, or at various optimization +stages. + + The operands of the insns are matched with `match_operands', +`match_operator', and `match_dup', as usual. What is not usual is that +the operand numbers apply to all the insn patterns in the definition. +So, you can check for identical operands in two insns by using +`match_operand' in one insn and `match_dup' in the other. + + The operand constraints used in `match_operand' patterns do not have +any direct effect on the applicability of the peephole, but they will +be validated afterward, so make sure your constraints are general enough +to apply whenever the peephole matches. If the peephole matches but +the constraints are not satisfied, the compiler will crash. + + It is safe to omit constraints in all the operands of the peephole; +or you can write constraints which serve as a double-check on the +criteria previously tested. + + Once a sequence of insns matches the patterns, the CONDITION is +checked. This is a C expression which makes the final decision whether +to perform the optimization (we do so if the expression is nonzero). If +CONDITION is omitted (in other words, the string is empty) then the +optimization is applied to every sequence of insns that matches the +patterns. + + The defined peephole optimizations are applied after register +allocation is complete. Therefore, the peephole definition can check +which operands have ended up in which kinds of registers, just by +looking at the operands. + + The way to refer to the operands in CONDITION is to write +`operands[I]' for operand number I (as matched by `(match_operand I +...)'). Use the variable `insn' to refer to the last of the insns +being matched; use `prev_nonnote_insn' to find the preceding insns. + + When optimizing computations with intermediate results, you can use +CONDITION to match only when the intermediate results are not used +elsewhere. Use the C expression `dead_or_set_p (INSN, OP)', where INSN +is the insn in which you expect the value to be used for the last time +(from the value of `insn', together with use of `prev_nonnote_insn'), +and OP is the intermediate value (from `operands[I]'). + + Applying the optimization means replacing the sequence of insns with +one new insn. The TEMPLATE controls ultimate output of assembler code +for this combined insn. It works exactly like the template of a +`define_insn'. Operand numbers in this template are the same ones used +in matching the original sequence of insns. + + The result of a defined peephole optimizer does not need to match +any of the insn patterns in the machine description; it does not even +have an opportunity to match them. The peephole optimizer definition +itself serves as the insn pattern to control how the insn is output. + + Defined peephole optimizers are run as assembler code is being +output, so the insns they produce are never combined or rearranged in +any way. + + Here is an example, taken from the 68000 machine description: + + (define_peephole + [(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4))) + (set (match_operand:DF 0 "register_operand" "=f") + (match_operand:DF 1 "register_operand" "ad"))] + "FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" + "* + { + rtx xoperands[2]; + xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); + #ifdef MOTOROLA + output_asm_insn (\"move.l %1,(sp)\", xoperands); + output_asm_insn (\"move.l %1,-(sp)\", operands); + return \"fmove.d (sp)+,%0\"; + #else + output_asm_insn (\"movel %1,sp@\", xoperands); + output_asm_insn (\"movel %1,sp@-\", operands); + return \"fmoved sp@+,%0\"; + #endif + } + ") + + The effect of this optimization is to change + + jbsr _foobar + addql #4,sp + movel d1,sp@- + movel d0,sp@- + fmoved sp@+,fp0 + +into + + jbsr _foobar + movel d1,sp@ + movel d0,sp@- + fmoved sp@+,fp0 + + INSN-PATTERN-1 and so on look *almost* like the second operand of +`define_insn'. There is one important difference: the second operand +of `define_insn' consists of one or more RTX's enclosed in square +brackets. Usually, there is only one: then the same action can be +written as an element of a `define_peephole'. But when there are +multiple actions in a `define_insn', they are implicitly enclosed in a +`parallel'. Then you must explicitly write the `parallel', and the +square brackets within it, in the `define_peephole'. Thus, if an insn +pattern looks like this, + + (define_insn "divmodsi4" + [(set (match_operand:SI 0 "general_operand" "=d") + (div:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "dmsK"))) + (set (match_operand:SI 3 "general_operand" "=d") + (mod:SI (match_dup 1) (match_dup 2)))] + "TARGET_68020" + "divsl%.l %2,%3:%0") + +then the way to mention this insn in a peephole is as follows: + + (define_peephole + [... + (parallel + [(set (match_operand:SI 0 "general_operand" "=d") + (div:SI (match_operand:SI 1 "general_operand" "0") + (match_operand:SI 2 "general_operand" "dmsK"))) + (set (match_operand:SI 3 "general_operand" "=d") + (mod:SI (match_dup 1) (match_dup 2)))]) + ...] + ...)