X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=gcc%2Fconfig%2Fd30v%2Fd30v.md;fp=gcc%2Fconfig%2Fd30v%2Fd30v.md;h=0000000000000000000000000000000000000000;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=c8832ee5cb238f58f984110e713a13b21344f76b;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/d30v/d30v.md b/gcc/config/d30v/d30v.md deleted file mode 100644 index c8832ee5..00000000 --- a/gcc/config/d30v/d30v.md +++ /dev/null @@ -1,3361 +0,0 @@ -;; Mitsubishi D30V Machine description template -;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. -;; Contributed by Cygnus Solutions. -;; -;; This file is part of GNU CC. -;; -;; GNU CC is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. -;; -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. -;; -;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. - - -;; :::::::::::::::::::: -;; :: -;; :: Constraints -;; :: -;; :::::::::::::::::::: - -;; Standard Constraints -;; -;; `m' A memory operand is allowed, with any kind of address that the -;; machine supports in general. -;; -;; `o' A memory operand is allowed, but only if the address is -;; "offsettable". This means that adding a small integer (actually, the -;; width in bytes of the operand, as determined by its machine mode) may be -;; added to the address and the result is also a valid memory address. -;; -;; `V' A memory operand that is not offsettable. In other words, -;; anything that would fit the `m' constraint but not the `o' constraint. -;; -;; `<' A memory operand with autodecrement addressing (either -;; predecrement or postdecrement) is allowed. -;; -;; `>' A memory operand with autoincrement addressing (either -;; preincrement or postincrement) is allowed. -;; -;; `r' A register operand is allowed provided that it is in a general -;; register. -;; -;; `d', `a', `f', ... -;; Other letters can be defined in machine-dependent fashion to stand for -;; particular classes of registers. `d', `a' and `f' are defined on the -;; 68000/68020 to stand for data, address and floating point registers. -;; -;; `i' An immediate integer operand (one with constant value) is allowed. -;; This includes symbolic constants whose values will be known only at -;; assembly time. -;; -;; `n' An immediate integer operand with a known numeric value is allowed. -;; Many systems cannot support assembly-time constants for operands less -;; than a word wide. Constraints for these operands should use `n' rather -;; than `i'. -;; -;; 'I' First machine-dependent integer constant. -;; 'J' Second machine-dependent integer constant. -;; 'K' Third machine-dependent integer constant. -;; 'L' Fourth machine-dependent integer constant. -;; 'M' Fifth machine-dependent integer constant. -;; 'N' Sixth machine-dependent integer constant. -;; 'O' Seventh machine-dependent integer constant. -;; 'P' Eighth machine-dependent integer constant. -;; -;; Other letters in the range `I' through `P' may be defined in a -;; machine-dependent fashion to permit immediate integer operands with -;; explicit integer values in specified ranges. For example, on the 68000, -;; `I' is defined to stand for the range of values 1 to 8. This is the -;; range permitted as a shift count in the shift instructions. -;; -;; `E' An immediate floating operand (expression code `const_double') is -;; allowed, but only if the target floating point format is the same as -;; that of the host machine (on which the compiler is running). -;; -;; `F' An immediate floating operand (expression code `const_double') is -;; allowed. -;; -;; 'G' First machine-dependent const_double. -;; 'H' Second machine-dependent const_double. -;; -;; `s' An immediate integer operand whose value is not an explicit -;; integer is allowed. -;; -;; This might appear strange; if an insn allows a constant operand with a -;; value not known at compile time, it certainly must allow any known -;; value. So why use `s' instead of `i'? Sometimes it allows better code -;; to be generated. -;; -;; For example, on the 68000 in a fullword instruction it is possible to -;; use an immediate operand; but if the immediate value is between -128 and -;; 127, better code results from loading the value into a register and -;; using the register. This is because the load into the register can be -;; done with a `moveq' instruction. We arrange for this to happen by -;; defining the letter `K' to mean "any integer outside the range -128 to -;; 127", and then specifying `Ks' in the operand constraints. -;; -;; `g' Any register, memory or immediate integer operand is allowed, -;; except for registers that are not general registers. -;; -;; `X' Any operand whatsoever is allowed, even if it does not satisfy -;; `general_operand'. This is normally used in the constraint of a -;; `match_scratch' when certain alternatives will not actually require a -;; scratch register. -;; -;; `0' Match operand 0. -;; `1' Match operand 1. -;; `2' Match operand 2. -;; `3' Match operand 3. -;; `4' Match operand 4. -;; `5' Match operand 5. -;; `6' Match operand 6. -;; `7' Match operand 7. -;; `8' Match operand 8. -;; `9' Match operand 9. -;; -;; An operand that matches the specified operand number is allowed. If a -;; digit is used together with letters within the same alternative, the -;; digit should come last. -;; -;; This is called a "matching constraint" and what it really means is that -;; the assembler has only a single operand that fills two roles considered -;; separate in the RTL insn. For example, an add insn has two input -;; operands and one output operand in the RTL, but on most CISC machines an -;; add instruction really has only two operands, one of them an -;; input-output operand: -;; -;; addl #35,r12 -;; -;; Matching constraints are used in these circumstances. More precisely, -;; the two operands that match must include one input-only operand and one -;; output-only operand. Moreover, the digit must be a smaller number than -;; the number of the operand that uses it in the constraint. -;; -;; For operands to match in a particular case usually means that they are -;; identical-looking RTL expressions. But in a few special cases specific -;; kinds of dissimilarity are allowed. For example, `*x' as an input -;; operand will match `*x++' as an output operand. For proper results in -;; such cases, the output template should always use the output-operand's -;; number when printing the operand. -;; -;; `p' An operand that is a valid memory address is allowed. This is for -;; "load address" and "push address" instructions. -;; -;; `p' in the constraint must be accompanied by `address_operand' as the -;; predicate in the `match_operand'. This predicate interprets the mode -;; specified in the `match_operand' as the mode of the memory reference for -;; which the address would be valid. -;; -;; `Q` First non constant, non register machine-dependent insns -;; `R` Second non constant, non register machine-dependent insns -;; `S` Third non constant, non register machine-dependent insns -;; `T` Fourth non constant, non register machine-dependent insns -;; `U` Fifth non constant, non register machine-dependent insns -;; -;; Letters in the range `Q' through `U' may be defined in a -;; machine-dependent fashion to stand for arbitrary operand types. The -;; machine description macro `EXTRA_CONSTRAINT' is passed the operand as -;; its first argument and the constraint letter as its second operand. -;; -;; A typical use for this would be to distinguish certain types of memory -;; references that affect other insn operands. -;; -;; Do not define these constraint letters to accept register references -;; (`reg'); the reload pass does not expect this and would not handle it -;; properly. - -;; Multiple Alternative Constraints -;; `?' Disparage slightly the alternative that the `?' appears in, as a -;; choice when no alternative applies exactly. The compiler regards this -;; alternative as one unit more costly for each `?' that appears in it. -;; -;; `!' Disparage severely the alternative that the `!' appears in. This -;; alternative can still be used if it fits without reloading, but if -;; reloading is needed, some other alternative will be used. - -;; Constraint modifiers -;; `=' Means that this operand is write-only for this instruction: the -;; previous value is discarded and replaced by output data. -;; -;; `+' Means that this operand is both read and written by the -;; instruction. -;; -;; When the compiler fixes up the operands to satisfy the constraints, it -;; needs to know which operands are inputs to the instruction and which are -;; outputs from it. `=' identifies an output; `+' identifies an operand -;; that is both input and output; all other operands are assumed to be -;; input only. -;; -;; `&' Means (in a particular alternative) that this operand is written -;; before the instruction is finished using the input operands. Therefore, -;; this operand may not lie in a register that is used as an input operand -;; or as part of any memory address. -;; -;; `&' applies only to the alternative in which it is written. In -;; constraints with multiple alternatives, sometimes one alternative -;; requires `&' while others do not. -;; -;; `&' does not obviate the need to write `='. -;; -;; `%' Declares the instruction to be commutative for this operand and the -;; following operand. This means that the compiler may interchange the two -;; operands if that is the cheapest way to make all operands fit the -;; constraints. This is often used in patterns for addition instructions -;; that really have only two operands: the result must go in one of the -;; arguments. -;; -;; `#' Says that all following characters, up to the next comma, are to be -;; ignored as a constraint. They are significant only for choosing -;; register preferences. -;; -;; `*' Says that the following character should be ignored when choosing -;; register preferences. `*' has no effect on the meaning of the -;; constraint as a constraint, and no effect on reloading. - -;; :::::::::::::::::::: -;; :: -;; :: D30V register classes -;; :: -;; :::::::::::::::::::: - -;; `a' Accumulator registers (a0, a1) -;; `b' Flag registers for speculative execution (f0, f1) -;; `c' CR registers -;; `d' GPR registers -;; `e' Even GPR registers -;; `f' Any flag registers (f0, f1, ..., c) -;; `l' CR7, the repeat count -;; `x' F0 -;; `y' F1 -;; `z' Flag registers other than F0 and F1. - -;; :::::::::::::::::::: -;; :: -;; :: D30V special constraints -;; :: -;; :::::::::::::::::::: - -;; `G' Const double with 0 in both low & high part. -;; `H' Unused. -;; `I' Signed 6 bit integer constant (>= -32 && <= 31). -;; `J' Unsigned 5 bit integer constant (>= 0 && <= 31). -;; `K' Integer constant with 1 bit set (for bset). -;; `L' Integer constant with 1 bit clear (for bclr). -;; `M' Integer constant 32. -;; `N' Integer constant 1. -;; `O' Integer constant 0. -;; `P' Integer constant >= 32 && <= 63. -;; `Q' Short memory operand (can be done in small insn). -;; `R' Memory operand using a single register for address. -;; `S' Memory operand to constant address. -;; `T' Unused. -;; `U' Unused. - -;; :::::::::::::::::::: -;; :: -;; :: Standard operand flags -;; :: -;; :::::::::::::::::::: - -;; `=' Output a number unique to each instruction in the compilation. -;; `a' Substitute an operand as if it were a memory reference. -;; `c' Omit the syntax that indicates an immediate operand. -;; `l' Substitute a LABEL_REF into a jump instruction. -;; `n' Like %cDIGIT, except negate the value before printing. - -;; :::::::::::::::::::: -;; :: -;; :: D30V print_operand flags -;; :: -;; :::::::::::::::::::: - -;; `.' Print r0 -;; `f' Print a SF constant as an int. -;; `s' Subtract 32 and negate. -;; `A' Print accumulator number without an `a' in front of it. -;; `B' Print bit offset for BSET, etc. instructions. -;; `E' Print u if this is zero extend, nothing if this is sign extend. -;; `F' Emit /{f,t,x}{f,t,x} for executing a false condition. -;; `L' Print the lower half of a 64 bit item. -;; `M' Print a memory reference for ld/st instructions. -;; `R' Return appropriate cmp instruction for relational test. -;; `S' Subtract 32. -;; `T' Emit /{f,t,x}{f,t,x} for executing a true condition. -;; `U' Print the upper half of a 64 bit item. - - -;; :::::::::::::::::::: -;; :: -;; :: Attributes -;; :: -;; :::::::::::::::::::: - -;; 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. - -;; 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'. - -;; Note, we lie a little bit here to make it simpler to optimize. We pretend there -;; is a separate long functional unit for long instructions that uses both the IU & MU. - -(define_attr "type" "iu,mu,br,br2,either,scarry,lcarry,scmp,lcmp,sload,lload,mul,long,multi,unknown" - (const_string "unknown")) - -;; Length in word units -(define_attr "length" "" - (cond [(eq_attr "type" "iu,mu,either,scmp,sload,mul,scarry,") - (const_int 4) - (eq_attr "type" "long,lcmp,lload,lcarry") - (const_int 8) - (eq_attr "type" "multi,unknown") - (const_int 64) ;; set higher to give a fudge factor - (eq_attr "type" "br") - (if_then_else (and (ge (minus (pc) (match_dup 0)) - (const_int -1048576)) - (lt (minus (pc) (match_dup 0)) - (const_int 1048575))) - (const_int 4) - (const_int 8)) - (eq_attr "type" "br2") - (if_then_else (and (ge (minus (pc) (match_dup 0)) - (const_int -16384)) - (lt (minus (pc) (match_dup 0)) - (const_int 16383))) - (const_int 4) - (const_int 8)) - ] - (const_int 8))) - -(define_attr "predicable" "no,yes" - (const_string "yes")) - -;; :::::::::::::::::::: -;; :: -;; :: Function Units -;; :: -;; :::::::::::::::::::: - -;; 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. - -(define_function_unit "iu" 1 0 - (eq_attr "type" "iu,either") - 1 1 - [(eq_attr "type" "long,lcmp,lload,multi,unknown")]) - -(define_function_unit "iu" 1 0 - (eq_attr "type" "scmp,mul,scarry") - 2 1 - [(eq_attr "type" "long,lcmp,lload,multi,unknown")]) - -(define_function_unit "mu" 1 0 - (eq_attr "type" "mu,br,br2,either") - 1 1 - [(eq_attr "type" "long,lcmp,lload,multi,unknown")]) - -(define_function_unit "mu" 1 0 - (eq_attr "type" "scarry,scmp,sload") - 2 1 - [(eq_attr "type" "long,lcmp,lload,multi,unknown")]) - -(define_function_unit "long" 1 0 - (eq_attr "type" "long,multi,unknown") - 1 1 - [(eq_attr "type" "iu,mu,scarry,scmp,sload,mul,br,br2,either")]) - -(define_function_unit "long" 1 0 - (eq_attr "type" "lcmp,lload,lcarry") - 2 1 - [(eq_attr "type" "iu,mu,scarry,scmp,sload,mul,br,br2,either")]) - - -;; :::::::::::::::::::: -;; :: -;; :: Delay Slots -;; :: -;; :::::::::::::::::::: - -;; 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)]) - - -;; :::::::::::::::::::: -;; :: -;; :: Moves -;; :: -;; :::::::::::::::::::: - -;; Wrap moves in define_expand to prevent memory->memory moves from being -;; generated at the RTL level, which generates better code for most machines -;; which can't do mem->mem moves. - -;; 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. - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && !register_operand (operands[0], QImode) - && !reg_or_0_operand (operands[1], QImode)) - operands[1] = copy_to_mode_reg (QImode, operands[1]); -}") - -(define_insn "*movqi_internal" - [(set (match_operand:QI 0 "move_output_operand" "=d,d,d,d,Q,m,Q,m,d,c") - (match_operand:QI 1 "move_input_operand" "dI,i,Q,m,d,d,O,O,c,d"))] - "register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode)" - "@ - or%: %0,%.,%1 - or%: %0,%.,%1 - ldb%: %0,%M1 - ldb%: %0,%M1 - stb%: %1,%M0 - stb%: %1,%M0 - stb%: %.,%M0 - stb%: %.,%M0 - mvfsys%: %0,%1 - mvtsys%: %0,%1" - [(set_attr "length" "4,8,4,8,4,8,4,8,4,4") - (set_attr "type" "either,long,sload,lload,mu,long,mu,long,mu,mu")]) - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && !register_operand (operands[0], HImode) - && !reg_or_0_operand (operands[1], HImode)) - operands[1] = copy_to_mode_reg (HImode, operands[1]); -}") - -(define_insn "*movhi_internal" - [(set (match_operand:HI 0 "move_output_operand" "=d,d,d,d,Q,m,Q,m,d,c") - (match_operand:HI 1 "move_input_operand" "dI,i,Q,m,d,d,O,O,c,d"))] - "register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode)" - "@ - or%: %0,%.,%1 - or%: %0,%.,%1 - ldh%: %0,%M1 - ldh%: %0,%M1 - sth%: %1,%M0 - sth%: %1,%M0 - sth%: %.,%M0 - sth%: %.,%M0 - mvfsys%: %0,%1 - mvtsys%: %0,%1" - [(set_attr "length" "4,8,4,8,4,8,4,8,4,4") - (set_attr "type" "either,long,sload,lload,mu,long,mu,long,mu,mu")]) - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && !register_operand (operands[0], SImode) - && !reg_or_0_operand (operands[1], SImode)) - operands[1] = copy_to_mode_reg (SImode, operands[1]); - - /* Convert addressing modes into the appropriate add/sub with the clobbers - needed. This is generated by builtin_setjmp in the exception handling. */ - if (GET_CODE (operands[1]) == PLUS) - { - emit_insn (gen_addsi3 (operands[0], XEXP (operands[1], 0), - XEXP (operands[1], 1))); - DONE; - } - - else if (GET_CODE (operands[1]) == MINUS) - { - emit_insn (gen_subsi3 (operands[0], XEXP (operands[1], 0), - XEXP (operands[1], 1))); - DONE; - } -}") - -(define_insn "*movsi_internal" - [(set (match_operand:SI 0 "move_output_operand" "=d,d,d,d,d,Q,m,Q,m,d,c") - (match_operand:SI 1 "move_input_operand" "dI,F,i,Q,m,d,d,O,O,c,d"))] - "register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode)" - "@ - or%: %0,%.,%1 - or%: %0,%.,%L1 - or%: %0,%.,%1 - ldw%: %0,%M1 - ldw%: %0,%M1 - stw%: %1,%M0 - stw%: %1,%M0 - stw%: %.,%M0 - stw%: %.,%M0 - mvfsys%: %0,%1 - mvtsys%: %0,%1" - [(set_attr "length" "4,8,8,4,8,4,8,4,8,4,4") - (set_attr "type" "either,long,long,sload,lload,mu,long,mu,long,mu,mu")]) - -(define_expand "movdi" - [(set (match_operand:DI 0 "general_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && !register_operand (operands[0], DImode) - && !register_operand (operands[1], DImode)) - operands[1] = copy_to_mode_reg (DImode, operands[1]); -}") - -(define_insn "*movdi_internal" - [(set (match_operand:DI 0 "move_output_operand" "=e,e,e,e,Q,m,e,a,a") - (match_operand:DI 1 "move_input_operand" "eI,iF,Q,m,e,e,a,e,O"))] - "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)" - "* return d30v_move_2words (operands, insn);" - [(set_attr "length" "8,16,4,8,4,8,8,4,4") - (set_attr "type" "multi,multi,sload,lload,mu,long,multi,iu,iu")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (match_operand:DI 1 "gpr_or_dbl_const_operand" ""))] - "reload_completed" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - " -{ - d30v_split_double (operands[0], &operands[2], &operands[4]); - d30v_split_double (operands[1], &operands[3], &operands[5]); -}") - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && !register_operand (operands[0], SFmode) - && !reg_or_0_operand (operands[1], SFmode)) - operands[1] = copy_to_mode_reg (SFmode, operands[1]); -}") - -(define_insn "*movsf_internal" - [(set (match_operand:SF 0 "move_output_operand" "=d,d,d,d,d,Q,m,Q,m") - (match_operand:SF 1 "move_input_operand" "d,G,F,Q,m,d,d,G,G"))] - "register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)" - "@ - or%: %0,%.,%1 - or%: %0,%.,0 - or%: %0,%.,%f1 - ldw%: %0,%M1 - ldw%: %0,%M1 - stw%: %1,%M0 - stw%: %1,%M0 - stw%: %.,%M0 - stw%: %.,%M0" - [(set_attr "length" "4,4,8,4,8,4,8,4,8") - (set_attr "type" "either,either,long,sload,lload,mu,long,mu,long")]) - -(define_expand "movdf" - [(set (match_operand:DF 0 "general_operand" "") - (match_operand:DF 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && !register_operand (operands[0], DFmode) - && !register_operand (operands[1], DFmode)) - operands[1] = copy_to_mode_reg (DFmode, operands[1]); -}") - -(define_insn "*movdf_internal" - [(set (match_operand:DF 0 "move_output_operand" "=e,e,e,e,Q,m,!*e,!*a") - (match_operand:DF 1 "move_input_operand" "eG,F,Q,m,e,e,!*a,!*e"))] - "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)" - "* return d30v_move_2words (operands, insn);" - [(set_attr "length" "8,16,4,8,4,8,8,4") - (set_attr "type" "multi,multi,sload,lload,mu,long,multi,iu")]) - -(define_split - [(set (match_operand:DF 0 "gpr_operand" "") - (match_operand:DF 1 "gpr_or_dbl_const_operand" ""))] - "reload_completed" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - " -{ - d30v_split_double (operands[0], &operands[2], &operands[4]); - d30v_split_double (operands[1], &operands[3], &operands[5]); -}") - -(define_expand "movcc" - [(set (match_operand:CC 0 "general_operand" "") - (match_operand:CC 1 "general_operand" ""))] - "" - " -{ - if (!reload_in_progress && !reload_completed - && GET_CODE (operands[0]) == MEM - && GET_CODE (operands[1]) == MEM) - operands[1] = copy_to_mode_reg (CCmode, operands[1]); -}") - -(define_insn "*movcc_internal" - [(set (match_operand:CC 0 "move_output_operand" "=f,f,f,d,?d,f,d,*d,*d,*Q,*m") - (match_operand:CC 1 "move_input_operand" "f,O,N,b,f,d,dON,*Q,*m,*d,*d"))] - "!memory_operand (operands[0], CCmode) || !memory_operand (operands[1], CCmode)" - "@ - orfg%: %0,%1,%1 - andfg%: %0,%0,0 - orfg%: %0,%0,1 - # - mvfsys%: %0,%1 - cmpne%: %0,%1,0 - or%: %0,%.,%1 - ldb%: %0,%M1 - ldb%: %0,%M1 - stb%: %1,%M0 - stb%: %1,%M0" - [(set_attr "length" "4,4,4,8,4,4,4,4,8,4,8") - (set_attr "type" "either,either,either,multi,mu,mu,either,sload,lload,mu,long")]) - -(define_split - [(set (match_operand:CC 0 "gpr_operand" "") - (match_operand:CC 1 "br_flag_operand" ""))] - "reload_completed" - [(set (match_dup 2) - (const_int 0)) - (set (match_dup 2) - (if_then_else:SI (ne:CC (match_dup 1) - (const_int 0)) - (const_int 1) - (match_dup 2)))] - " -{ - operands[2] = gen_lowpart (SImode, operands[0]); -}") - - -;; :::::::::::::::::::: -;; :: -;; :: Conversions -;; :: -;; :::::::::::::::::::: - -;; Signed conversions from a smaller integer to a larger integer -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "gpr_operand" "=d,d,d") - (sign_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "@ - # - ldb%: %0,%M1 - ldb%: %0,%M1" - [(set_attr "type" "multi,sload,lload") - (set_attr "length" "16,4,8")]) - -(define_split - [(set (match_operand:HI 0 "gpr_operand" "") - (sign_extend:HI (match_operand:QI 1 "gpr_operand" "")))] - "reload_completed" - [(match_dup 2) - (match_dup 3)] - " -{ - rtx op0 = gen_lowpart (SImode, operands[0]); - rtx op1 = gen_lowpart (SImode, operands[1]); - rtx shift = gen_rtx (CONST_INT, VOIDmode, 24); - - operands[2] = gen_ashlsi3 (op0, op1, shift); - operands[3] = gen_ashrsi3 (op0, op0, shift); -}") - -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d") - (sign_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "@ - # - ldb%: %0,%M1 - ldb%: %0,%M1" - [(set_attr "type" "multi,sload,lload") - (set_attr "length" "16,4,8")]) - -(define_split - [(set (match_operand:SI 0 "gpr_operand" "") - (sign_extend:SI (match_operand:QI 1 "gpr_operand" "")))] - "reload_completed" - [(match_dup 2) - (match_dup 3)] - " -{ - rtx op0 = gen_lowpart (SImode, operands[0]); - rtx op1 = gen_lowpart (SImode, operands[1]); - rtx shift = gen_rtx (CONST_INT, VOIDmode, 24); - - operands[2] = gen_ashlsi3 (op0, op1, shift); - operands[3] = gen_ashrsi3 (op0, op0, shift); -}") - -(define_insn "extendhisi2" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d") - (sign_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "@ - # - ldh%: %0,%M1 - ldh%: %0,%M1" - [(set_attr "type" "multi,sload,lload") - (set_attr "length" "16,4,8")]) - -(define_split - [(set (match_operand:SI 0 "gpr_operand" "") - (sign_extend:SI (match_operand:HI 1 "gpr_operand" "")))] - "reload_completed" - [(match_dup 2) - (match_dup 3)] - " -{ - rtx op0 = gen_lowpart (SImode, operands[0]); - rtx op1 = gen_lowpart (SImode, operands[1]); - rtx shift = gen_rtx (CONST_INT, VOIDmode, 16); - - operands[2] = gen_ashlsi3 (op0, op1, shift); - operands[3] = gen_ashrsi3 (op0, op0, shift); -}") - -(define_insn "extendqidi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (sign_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "#" - [(set_attr "length" "12,8,12") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (sign_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "")))] - "reload_completed" - [(set (match_dup 2) (sign_extend:SI (match_dup 1))) - (set (match_dup 3) (ashiftrt:SI (match_dup 2) (const_int 31)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[2]); -}") - -(define_insn "extendhidi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (sign_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "#" - [(set_attr "length" "12,8,12") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (sign_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "")))] - "reload_completed" - [(set (match_dup 2) (sign_extend:SI (match_dup 1))) - (set (match_dup 3) (ashiftrt:SI (match_dup 2) (const_int 31)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[2]); -}") - -(define_insn "extendsidi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (sign_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "#" - [(set_attr "length" "8,8,12") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (sign_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "")))] - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (ashiftrt:SI (match_dup 2) (const_int 31)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[2]); -}") - -;; Unsigned conversions from a smaller integer to a larger integer - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "gpr_operand" "=d,d,d") - (zero_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "@ - and%: %0,%1,0xff - ldbu%: %0,%M1 - ldbu%: %0,%M1" - [(set_attr "length" "8,4,8") - (set_attr "type" "long,sload,lload")]) - -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d") - (zero_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "@ - and%: %0,%1,0xff - ldbu%: %0,%M1 - ldbu%: %0,%M1" - [(set_attr "length" "8,4,8") - (set_attr "type" "long,sload,lload")]) - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d") - (zero_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "@ - and%: %0,%1,0xffff - ldhu%: %0,%M1 - ldhu%: %0,%M1" - [(set_attr "length" "8,4,8") - (set_attr "type" "long,sload,lload")]) - -(define_insn "zero_extendqidi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (zero_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "#" - [(set_attr "length" "12,8,12") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (zero_extend:DI (match_operand:QI 1 "gpr_or_memory_operand" "")))] - "reload_completed" - [(set (match_dup 2) (zero_extend:SI (match_dup 1))) - (set (match_dup 3) (const_int 0))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[2]); -}") - -(define_insn "zero_extendhidi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (zero_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "#" - [(set_attr "length" "8,8,12") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (zero_extend:DI (match_operand:HI 1 "gpr_or_memory_operand" "")))] - "reload_completed" - [(set (match_dup 2) (zero_extend:SI (match_dup 1))) - (set (match_dup 3) (const_int 0))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[2]); -}") - -(define_insn "zero_extendsidi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (zero_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "d,Q,m")))] - "" - "#" - [(set_attr "length" "8,8,12") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (zero_extend:DI (match_operand:SI 1 "gpr_or_memory_operand" "")))] - "reload_completed" - [(set (match_dup 2) (match_dup 1)) - (set (match_dup 3) (const_int 0))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[2]); -}") - - -;; :::::::::::::::::::: -;; :: -;; :: 32 bit Integer arithmetic -;; :: -;; :::::::::::::::::::: - -;; Addition -(define_expand "addsi3" - [(parallel [(set (match_operand:SI 0 "gpr_operand" "") - (plus:SI (match_operand:SI 1 "gpr_operand" "") - (match_operand:SI 2 "gpr_or_constant_operand" ""))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5))])] - "" - " -{ - operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY); - operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW); - operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER); -}") - -(define_insn "*addsi3_internal" - [(set (match_operand:SI 0 "gpr_operand" "=d,d") - (plus:SI (match_operand:SI 1 "gpr_operand" "%d,d") - (match_operand:SI 2 "gpr_or_constant_operand" "dI,i"))) - (clobber (match_operand:CC 3 "flag_operand" "=f,f")) - (clobber (match_operand:CC 4 "flag_operand" "=f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f"))] - "" - "add%: %0,%1,%2" - [(set_attr "length" "4,8") - (set_attr "type" "either,long")]) - -;; Subtraction -(define_expand "subsi3" - [(parallel [(set (match_operand:SI 0 "gpr_operand" "") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") - (match_operand:SI 2 "gpr_or_constant_operand" ""))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5))])] - "" - " -{ - operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY); - operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW); - operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER); -}") - -(define_insn "*subsi3_internal" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "d,d,O,O") - (match_operand:SI 2 "gpr_or_constant_operand" "dI,i,dI,i"))) - (clobber (match_operand:CC 3 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))] - "" - "@ - sub%: %0,%1,%2 - sub%: %0,%1,%2 - sub%: %0,%.,%2 - sub%: %0,%.,%2" - [(set_attr "length" "4,8,4,8") - (set_attr "type" "either,long,either,long")]) - -;; Multiplication (same size) -(define_insn "mulsi3" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (mult:SI (match_operand:SI 1 "gpr_operand" "%d") - (match_operand:SI 2 "gpr_or_signed6_operand" "dI")))] - "" - "mul%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -;; Signed multiplication producing 64 bit results from 32 bit inputs -(define_insn "mulsidi3" - [(set (match_operand:DI 0 "accum_operand" "=a") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d")) - (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d"))))] - "" - "mulx%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*mulsidi3_const" - [(set (match_operand:DI 0 "accum_operand" "=a") - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d")) - (match_operand:DI 2 "signed6_operand" "I")))] - "" - "mulx%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -;; Signed multiplication producing just the upper 32 bits from a 32x32->64 -;; bit multiply. We specifically allow any integer constant here so -;; allow division by constants to be done by multiplying by a large constant. - -(define_expand "smulsi3_highpart" - [(set (match_dup 3) - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "")) - (match_operand:SI 2 "gpr_or_constant_operand" ""))) - (set (match_operand:SI 0 "gpr_operand" "") - (truncate:SI (lshiftrt:DI (match_dup 3) - (const_int 32))))] - "" - " -{ - operands[3] = gen_reg_rtx (DImode); - - if (GET_CODE (operands[2]) == CONST_INT && - !IN_RANGE_P (INTVAL (operands[2]), -32, 31)) - operands[2] = force_reg (SImode, operands[2]); - - if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG) - operands[2] = gen_rtx (SIGN_EXTEND, DImode, operands[2]); -}") - -(define_insn "*di_highpart" - [(set (match_operand:SI 0 "gpr_operand" "=d,d") - (truncate:SI (lshiftrt:DI (match_operand:DI 1 "gpr_or_accum_operand" "e,a") - (const_int 32))))] - "" - "@ - or%: %0,%.,%U1 - mvfacc%: %0,%1,32" - [(set_attr "length" "4") - (set_attr "type" "either,iu")]) - -;; Negation -(define_expand "negsi2" - [(parallel [(set (match_operand:SI 0 "gpr_operand" "") - (neg:SI (match_operand:SI 1 "gpr_operand" ""))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4))])] - "" - " -{ - operands[2] = gen_rtx (REG, CCmode, FLAG_CARRY); - operands[3] = gen_rtx (REG, CCmode, FLAG_OVERFLOW); - operands[4] = gen_rtx (REG, CCmode, FLAG_ACC_OVER); -}") - -(define_insn "*negsi2_internal" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (neg:SI (match_operand:SI 1 "gpr_operand" "d"))) - (clobber (match_operand:CC 2 "flag_operand" "=f")) - (clobber (match_operand:CC 3 "flag_operand" "=f")) - (clobber (match_operand:CC 4 "flag_operand" "=f"))] - "" - "sub%: %0,%.,%1" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -;; Absolute value -(define_insn "abssi2" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (abs:SI (match_operand:SI 1 "gpr_operand" "d")))] - "" - "abs%: %0,%1" - [(set_attr "length" "4") - (set_attr "type" "either")]) - - -;; :::::::::::::::::::: -;; :: -;; :: 64 bit Integer arithmetic -;; :: -;; :::::::::::::::::::: - -;; Addition -(define_expand "adddi3" - [(parallel [(set (match_operand:DI 0 "gpr_operand" "") - (plus:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_constant_operand" ""))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5))])] - "" - " -{ - operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY); - operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW); - operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER); -}") - -(define_insn "*adddi3_internal" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e,e") - (plus:DI (match_operand:DI 1 "gpr_operand" "%e,e,e,e") - (match_operand:DI 2 "gpr_or_constant_operand" "I,i,e,F"))) - (clobber (match_operand:CC 3 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))] - "" - "#" - [(set_attr "length" "8,12,8,16") - (set_attr "type" "multi")]) - -(define_insn "addsi3_set_carry" - [(set (match_operand:SI 0 "gpr_operand" "=d,d") - (plus:SI (match_operand:SI 1 "gpr_operand" "%d,d") - (match_operand:SI 2 "gpr_or_constant_operand" "dI,i"))) - (set (match_operand:CC 3 "carry_operand" "=f,f") - (unspec:CC [(match_dup 1) - (match_dup 2)] 1)) - (clobber (match_operand:CC 4 "flag_operand" "=f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f"))] - "" - "add%: %0,%1,%2" - [(set_attr "length" "4,8") - (set_attr "type" "scarry,lcarry")]) - -(define_insn "addsi3_use_carry" - [(set (match_operand:SI 0 "gpr_operand" "=d,d") - (unspec:SI [(match_operand:SI 1 "gpr_operand" "%d,d") - (match_operand:SI 2 "gpr_or_constant_operand" "dI,i") - (match_operand:CC 3 "carry_operand" "+f,f")] 2)) - (clobber (match_operand:CC 4 "flag_operand" "=f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f"))] - "" - "addc%: %0,%1,%2" - [(set_attr "length" "4,8") - (set_attr "type" "scarry,lcarry")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (plus:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_constant_operand" ""))) - (clobber (match_operand:CC 3 "flag_operand" "")) - (clobber (match_operand:CC 4 "flag_operand" "")) - (clobber (match_operand:CC 5 "flag_operand" ""))] - "reload_completed" - [(match_dup 6) - (match_dup 7)] - " -{ - rtx high[3]; - rtx low[3]; - - d30v_split_double (operands[0], &high[0], &low[0]); - d30v_split_double (operands[1], &high[1], &low[1]); - d30v_split_double (operands[2], &high[2], &low[2]); - - operands[6] = gen_addsi3_set_carry (low[0], low[1], low[2], operands[3], - operands[4], operands[5]); - - operands[7] = gen_addsi3_use_carry (high[0], high[1], high[2], operands[3], - operands[4], operands[5]); -}") - -;; Subtraction -(define_expand "subdi3" - [(parallel [(set (match_operand:DI 0 "gpr_operand" "") - (minus:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_constant_operand" ""))) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_dup 5))])] - "" - " -{ - operands[3] = gen_rtx (REG, CCmode, FLAG_CARRY); - operands[4] = gen_rtx (REG, CCmode, FLAG_OVERFLOW); - operands[5] = gen_rtx (REG, CCmode, FLAG_ACC_OVER); -}") - -(define_insn "*subdi3_internal" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e,e") - (minus:DI (match_operand:DI 1 "gpr_operand" "e,e,e,e") - (match_operand:DI 2 "gpr_or_constant_operand" "I,i,e,F"))) - (clobber (match_operand:CC 3 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))] - "" - "#" - [(set_attr "length" "8,12,8,16") - (set_attr "type" "multi")]) - -(define_insn "subsi3_set_carry" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "d,d,O,O") - (match_operand:SI 2 "gpr_or_constant_operand" "dI,i,dI,i"))) - (set (match_operand:CC 3 "carry_operand" "=f,f,f,f") - (unspec:CC [(match_dup 1) - (match_dup 2)] 3)) - (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))] - "" - "@ - sub%: %0,%1,%2 - sub%: %0,%1,%2 - sub%: %0,%.,%2 - sub%: %0,%.,%2" - [(set_attr "length" "4,8,4,8") - (set_attr "type" "scarry,lcarry,scarry,lcarry")]) - -(define_insn "subsi3_use_carry" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d") - (unspec:SI [(match_operand:SI 1 "reg_or_0_operand" "d,d,O,O") - (match_operand:SI 2 "gpr_operand" "dI,i,dI,i") - (match_operand:CC 3 "carry_operand" "+f,f,f,f")] 4)) - (clobber (match_operand:CC 4 "flag_operand" "=f,f,f,f")) - (clobber (match_operand:CC 5 "flag_operand" "=f,f,f,f"))] - "" - "@ - subb%: %0,%1,%2 - subb%: %0,%1,%2 - subb%: %0,%.,%2 - subb%: %0,%.,%2" - [(set_attr "length" "4,8,4,8") - (set_attr "type" "scarry,lcarry,scarry,lcarry")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (minus:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_constant_operand" ""))) - (clobber (match_operand:CC 3 "flag_operand" "")) - (clobber (match_operand:CC 4 "flag_operand" "")) - (clobber (match_operand:CC 5 "flag_operand" ""))] - "reload_completed" - [(match_dup 6) - (match_dup 7)] - " -{ - rtx high[3]; - rtx low[3]; - - d30v_split_double (operands[0], &high[0], &low[0]); - d30v_split_double (operands[1], &high[1], &low[1]); - d30v_split_double (operands[2], &high[2], &low[2]); - - operands[6] = gen_subsi3_set_carry (low[0], low[1], low[2], operands[3], - operands[4], operands[5]); - - operands[7] = gen_subsi3_use_carry (high[0], high[1], high[2], operands[3], - operands[4], operands[5]); -}") - -;; Negation -(define_expand "negdi2" - [(parallel [(set (match_operand:DI 0 "gpr_operand" "") - (neg:DI (match_operand:DI 1 "gpr_operand" ""))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4))])] - "" - " -{ - operands[2] = gen_rtx (REG, CCmode, FLAG_CARRY); - operands[3] = gen_rtx (REG, CCmode, FLAG_OVERFLOW); - operands[4] = gen_rtx (REG, CCmode, FLAG_ACC_OVER); -}") - -(define_insn "*negdi2_internal" - [(set (match_operand:DI 0 "gpr_operand" "=e") - (neg:DI (match_operand:DI 1 "gpr_operand" "e"))) - (clobber (match_operand:CC 2 "flag_operand" "=f")) - (clobber (match_operand:CC 3 "flag_operand" "=f")) - (clobber (match_operand:CC 4 "flag_operand" "=f"))] - "" - "#" - [(set_attr "length" "8") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "=e") - (neg:DI (match_operand:DI 1 "gpr_operand" "e"))) - (clobber (match_operand:CC 2 "flag_operand" "=f")) - (clobber (match_operand:CC 3 "flag_operand" "=f")) - (clobber (match_operand:CC 4 "flag_operand" "=f"))] - "reload_completed" - [(match_dup 5) - (match_dup 6)] - " -{ - rtx high[2]; - rtx low[2]; - rtx r0 = const0_rtx; - - d30v_split_double (operands[0], &high[0], &low[0]); - d30v_split_double (operands[1], &high[1], &low[1]); - - operands[5] = gen_subsi3_set_carry (low[0], r0, low[1], operands[2], - operands[3], operands[4]); - - operands[6] = gen_subsi3_use_carry (high[0], r0, high[1], operands[2], - operands[3], operands[4]); -}") - - -;; :::::::::::::::::::: -;; :: -;; :: 32 bit Integer Shifts and Rotates -;; :: -;; :::::::::::::::::::: - -;; Arithmetic Shift Left (negate the shift value and use shift right) -(define_expand "ashlsi3" - [(set (match_operand:SI 0 "gpr_operand" "") - (ashift:SI (match_operand:SI 1 "gpr_operand" "") - (match_operand:SI 2 "gpr_or_unsigned5_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "*ashlsi3_constant" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (ashift:SI (match_operand:SI 1 "gpr_operand" "d") - (match_operand:SI 2 "unsigned5_operand" "J")))] - "" - "sra%: %0,%1,%n2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -(define_insn "*ashlsi3_register" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (ashift:SI (match_operand:SI 1 "gpr_operand" "d") - (neg:SI (match_operand:SI 2 "gpr_operand" "d"))))] - "" - "sra%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -;; Arithmetic Shift Right -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "gpr_operand" "d") - (match_operand:SI 2 "gpr_or_unsigned5_operand" "dJ")))] - "" - "sra%: %0,%1,%2" - [(set_attr "length" "4")]) - -;; Logical Shift Right -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "gpr_operand" "d") - (match_operand:SI 2 "gpr_or_unsigned5_operand" "dJ")))] - "" - "srl%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -;; Rotate Left (negate the shift value and use rotate right) -(define_expand "rotlsi3" - [(set (match_operand:SI 0 "gpr_operand" "") - (rotate:SI (match_operand:SI 1 "gpr_operand" "") - (match_operand:SI 2 "gpr_or_unsigned5_operand" "")))] - "" - " -{ - if (GET_CODE (operands[2]) != CONST_INT) - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "*rotlsi3_constant" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (rotate:SI (match_operand:SI 1 "gpr_operand" "d") - (match_operand:SI 2 "unsigned5_operand" "J")))] - "" - "rot%: %0,%1,%n2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -(define_insn "*rotlsi3_register" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (rotate:SI (match_operand:SI 1 "gpr_operand" "d") - (neg:SI (match_operand:SI 2 "gpr_operand" "d"))))] - "" - "rot%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -;; Rotate Right -(define_insn "rotrsi3" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (rotatert:SI (match_operand:SI 1 "gpr_operand" "d") - (match_operand:SI 2 "gpr_or_unsigned5_operand" "dJ")))] - "" - "rot%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - - -;; :::::::::::::::::::: -;; :: -;; :: 64 bit Integer Shifts and Rotates -;; :: -;; :::::::::::::::::::: - -;; Arithmetic Shift Left -(define_expand "ashldi3" - [(parallel [(set (match_operand:DI 0 "gpr_operand" "") - (ashift:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:SI 2 "gpr_or_unsigned6_operand" ""))) - (clobber (match_scratch:CC 3 ""))])] - "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - if (IN_RANGE_P (INTVAL (operands[2]), 0, 63)) - { - emit_insn (gen_ashldi3_constant (operands[0], operands[1], operands[2])); - DONE; - } - else - operands[2] = copy_to_mode_reg (SImode, operands[2]); - } - - operands[2] = gen_rtx (NEG, SImode, negate_rtx (SImode, operands[2])); -}") - -(define_insn "ashldi3_constant" - [(set (match_operand:DI 0 "gpr_operand" "=e,e") - (ashift:DI (match_operand:DI 1 "gpr_operand" "0,e") - (match_operand:SI 2 "unsigned6_operand" "J,P")))] - "" - "@ - src%: %U0,%L0,%n2\;sra%: %L0,%L0,%n2 - sra%: %U0,%L1,%s2\;or%: %L0,%.,0" - [(set_attr "length" "8") - (set_attr "type" "multi")]) - -(define_insn "*ashldi3_register" - [(set (match_operand:DI 0 "gpr_operand" "=e") - (ashift:DI (match_operand:DI 1 "gpr_operand" "0") - (neg:SI (match_operand:SI 2 "gpr_operand" "d")))) - (clobber (match_scratch:CC 3 "=b"))] - "" - "cmpge %3,%2,-31\;src%T3 %U0,%L0,%2\;sra%T3 %L0,%L0,%2\;sub%F3 %U0,%2,-32\;sra%F3 %U0,%L0,%U0\;or%F3 %L0,%.,0" - [(set_attr "length" "32") - (set_attr "type" "multi") - ;; Not strictly true, since we ought to be able to combine conditions, - (set_attr "predicable" "no")]) - -;; Arithmetic Shift Right -(define_insn "ashrdi3" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (ashiftrt:DI (match_operand:DI 1 "gpr_operand" "0,e,0") - (match_operand:SI 2 "gpr_or_unsigned6_operand" "J,P,d"))) - (clobber (match_scratch:CC 3 "=X,X,b"))] - "" - "@ - src %L0,%U0,%2\;sra %U0,%U0,%2 - sra %L0,%U1,%S2\;sra %U0,%L0,31 - cmple %3,%2,31\;src%T3 %L0,%U0,%2\;sra%T3 %U0,%U0,%2\;add%F3 %L0,%2,-32\;sra%F3 %L0,%U0,%L0\;sra%F3 %U0,%U0,31" - [(set_attr "length" "8,8,28") - (set_attr "type" "multi") - ;; Not strictly true, since we ought to be able to combine conditions, - (set_attr "predicable" "no")]) - -;; Logical Shift Right - -(define_insn "lshrdi3" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,e") - (lshiftrt:DI (match_operand:DI 1 "gpr_operand" "0,e,0") - (match_operand:SI 2 "gpr_or_unsigned6_operand" "J,P,d"))) - (clobber (match_scratch:CC 3 "=X,X,b"))] - "" - "@ - src %L0,%U0,%2\;srl %U0,%U0,%2 - srl %L0,%U1,%S2\;or %U0,%.,0 - cmple %3,%2,31\;src%T3 %L0,%U0,%2\;srl%T3 %U0,%U0,%2\;add%F3 %L0,%2,-32\;srl%F3 %L0,%U0,%L0\;or%F3 %U0,%.,0" - [(set_attr "length" "8,8,28") - (set_attr "type" "multi") - ;; Not strictly true, since we ought to be able to combine conditions, - (set_attr "predicable" "no")]) - - -;; :::::::::::::::::::: -;; :: -;; :: 32 Bit Integer Logical operations -;; :: -;; :::::::::::::::::::: - -;; Logical AND, 32 bit integers - -(define_insn "andsi3" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d") - (and:SI (match_operand:SI 1 "gpr_operand" "%d,d,d,d") - (match_operand:SI 2 "gpr_or_constant_operand" "L,I,i,d")))] - "" - "@ - bclr%: %0,%1,%B2 - and%: %0,%1,%2 - and%: %0,%1,%2 - and%: %0,%1,%2" - [(set_attr "length" "4,4,8,4") - (set_attr "type" "either,either,long,either")]) - -;; Inclusive OR, 32 bit integers - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d") - (ior:SI (match_operand:SI 1 "gpr_operand" "%d,d,d,d") - (match_operand:SI 2 "gpr_or_constant_operand" "K,I,i,d")))] - "" - "@ - bset%: %0,%1,%B2 - or%: %0,%1,%2 - or%: %0,%1,%2 - or%: %0,%1,%2" - [(set_attr "length" "4,4,8,4") - (set_attr "type" "either,either,long,either")]) - -;; Exclusive OR, 32 bit integers - -(define_insn "*xorsi3_constant" - [(set (match_operand:SI 0 "gpr_operand" "=d,d,d,d") - (xor:SI (match_operand:SI 1 "gpr_operand" "%d,d,d,d") - (match_operand:SI 2 "gpr_or_constant_operand" "K,I,i,d")))] - "" - "@ - bnot%: %0,%1,%B2 - xor%: %0,%1,%2 - xor%: %0,%1,%2 - xor%: %0,%1,%2" - [(set_attr "length" "4,4,8,4") - (set_attr "type" "either,either,long,either")]) - -;; One's complement, 32 bit integers -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (not:SI (match_operand:SI 1 "gpr_operand" "d")))] - "" - "not%: %0,%1" - [(set_attr "length" "4") - (set_attr "type" "either")]) - - -;; :::::::::::::::::::: -;; :: -;; :: 64 Bit Integer Logical operations -;; :: -;; :::::::::::::::::::: - -;; Logical AND, 64 bit integers -(define_insn "anddi3" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,&e,e,e,e") - (and:DI (match_operand:DI 1 "gpr_operand" "%e,0,e,e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "0,e,e,I,i,F")))] - "" - "#" - [(set_attr "length" "8,8,8,8,12,16") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (and:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))] - "reload_completed" - [(set (match_dup 3) (and:SI (match_dup 4) (match_dup 5))) - (set (match_dup 6) (and:SI (match_dup 7) (match_dup 8)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[6]); - d30v_split_double (operands[1], &operands[4], &operands[7]); - d30v_split_double (operands[2], &operands[5], &operands[8]); -}") - -;; Includive OR, 64 bit integers -(define_insn "iordi3" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,&e,e,e,e") - (ior:DI (match_operand:DI 1 "gpr_operand" "%e,0,e,e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "0,e,e,I,i,F")))] - "" - "#" - [(set_attr "length" "8,8,8,8,12,16") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (ior:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))] - "reload_completed" - [(set (match_dup 3) (ior:SI (match_dup 4) (match_dup 5))) - (set (match_dup 6) (ior:SI (match_dup 7) (match_dup 8)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[6]); - d30v_split_double (operands[1], &operands[4], &operands[7]); - d30v_split_double (operands[2], &operands[5], &operands[8]); -}") - -;; Excludive OR, 64 bit integers -(define_insn "xordi3" - [(set (match_operand:DI 0 "gpr_operand" "=e,e,&e,e,e,e") - (xor:DI (match_operand:DI 1 "gpr_operand" "%e,0,e,e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "0,e,e,I,i,F")))] - "" - "#" - [(set_attr "length" "8,8,8,8,12,16") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (xor:DI (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))] - "reload_completed" - [(set (match_dup 3) (xor:SI (match_dup 4) (match_dup 5))) - (set (match_dup 6) (xor:SI (match_dup 7) (match_dup 8)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[6]); - d30v_split_double (operands[1], &operands[4], &operands[7]); - d30v_split_double (operands[2], &operands[5], &operands[8]); -}") - -;; One's complement, 64 bit integers -(define_insn "one_cmpldi2" - [(set (match_operand:DI 0 "gpr_operand" "=e,&e") - (not:DI (match_operand:DI 1 "gpr_operand" "0,e")))] - "" - "#" - [(set_attr "length" "8") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:DI 0 "gpr_operand" "") - (not:DI (match_operand:DI 1 "gpr_operand" "")))] - "reload_completed" - [(set (match_dup 3) (not:SI (match_dup 4))) - (set (match_dup 5) (not:SI (match_dup 6)))] - " -{ - d30v_split_double (operands[0], &operands[3], &operands[5]); - d30v_split_double (operands[1], &operands[4], &operands[6]); -}") - - -;; :::::::::::::::::::: -;; :: -;; :: Multiply and accumulate instructions -;; :: -;; :::::::::::::::::::: - -(define_insn "*mac_reg" - [(set (match_operand:DI 0 "accum_operand" "+a") - (plus:DI (match_dup 0) - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d")) - (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d")))))] - "" - "mac%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*mac_const" - [(set (match_operand:DI 0 "accum_operand" "+a") - (plus:DI (match_dup 0) - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d")) - (match_operand:DI 2 "signed6_operand" "I"))))] - "" - "mac%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*macs_reg" - [(set (match_operand:DI 0 "accum_operand" "+a") - (plus:DI (match_dup 0) - (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d")) - (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d"))) - (const_int 1))))] - "" - "macs%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*macs_const" - [(set (match_operand:DI 0 "accum_operand" "+a") - (plus:DI (match_dup 0) - (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "%d")) - (match_operand:DI 2 "signed6_operand" "I")) - (const_int 1))))] - "" - "macs%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*msub_reg" - [(set (match_operand:DI 0 "accum_operand" "+a") - (minus:DI (match_dup 0) - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d")) - (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d")))))] - "" - "msub%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*msub_const" - [(set (match_operand:DI 0 "accum_operand" "+a") - (minus:DI (match_dup 0) - (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d")) - (match_operand:DI 2 "signed6_operand" "I"))))] - "" - "msub%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*msubs_reg" - [(set (match_operand:DI 0 "accum_operand" "+a") - (minus:DI (match_dup 0) - (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d")) - (sign_extend:DI (match_operand:SI 2 "gpr_operand" "d"))) - (const_int 1))))] - "" - "msubs%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - -(define_insn "*msubs_const" - [(set (match_operand:DI 0 "accum_operand" "+a") - (minus:DI (match_dup 0) - (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "gpr_operand" "d")) - (match_operand:DI 2 "signed6_operand" "I")) - (const_int 1))))] - "" - "msubs%A0%: %.,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "mul")]) - - -;; :::::::::::::::::::: -;; :: -;; :: Comparisons -;; :: -;; :::::::::::::::::::: - -;; Note, we store the operands in the comparison insns, and use them later -;; when generating the branch or scc operation. - -;; First the routines called by the machine independent part of the compiler -(define_expand "cmpsi" - [(set (cc0) - (compare (match_operand:SI 0 "gpr_operand" "") - (match_operand:SI 1 "gpr_or_constant_operand" "")))] - "" - " -{ - d30v_compare_op0 = operands[0]; - d30v_compare_op1 = operands[1]; - DONE; -}") - -(define_expand "cmpdi" - [(set (cc0) - (compare (match_operand:DI 0 "gpr_operand" "") - (match_operand:DI 1 "nonmemory_operand" "")))] - "" - " -{ - d30v_compare_op0 = operands[0]; - d30v_compare_op1 = operands[1]; - DONE; -}") - -;; Now, the actual comparisons, generated by the branch and/or scc operations - -;; 32 bit integer tests -(define_insn "*srelational" - [(set (match_operand:CC 0 "flag_operand" "=f,f") - (match_operator:CC 1 "srelational_si_operator" - [(match_operand:SI 2 "gpr_operand" "d,d") - (match_operand:SI 3 "gpr_or_constant_operand" "dI,i")]))] - "" - "%R1%: %0,%2,%3" - [(set_attr "length" "4,8") - (set_attr "type" "scmp,lcmp")]) - -(define_insn "*urelational" - [(set (match_operand:CC 0 "flag_operand" "=f,f") - (match_operator:CC 1 "urelational_si_operator" - [(match_operand:SI 2 "gpr_operand" "d,d") - (match_operand:SI 3 "gpr_or_constant_operand" "dJP,i")]))] - "" - "%R1%: %0,%2,%3" - [(set_attr "length" "4,8") - (set_attr "type" "scmp,lcmp")]) - -;; 64 bit integer tests -(define_insn "*eqdi_internal" - [(set (match_operand:CC 0 "br_flag_operand" "=b,b,b") - (eq:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eI,i,F")))] - "" - "#" - [(set_attr "length" "8,12,16") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:CC 0 "br_flag_operand" "") - (eq:CC (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))] - "reload_completed" - [(set (match_dup 0) - (eq:CC (match_dup 3) - (match_dup 4))) - (cond_exec - (eq:CC (match_dup 0) - (const_int 0)) - (set (match_dup 0) - (eq:CC (match_dup 5) - (match_dup 6))))] - " -{ - d30v_split_double (operands[1], &operands[3], &operands[5]); - d30v_split_double (operands[2], &operands[4], &operands[6]); -}") - -(define_insn "*nedi_internal" - [(set (match_operand:CC 0 "br_flag_operand" "=b,b,b") - (ne:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eI,i,F")))] - "" - "#" - [(set_attr "length" "8,12,16") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:CC 0 "br_flag_operand" "") - (ne:CC (match_operand:DI 1 "gpr_operand" "") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "")))] - "reload_completed" - [(set (match_dup 0) - (ne:CC (match_dup 3) - (match_dup 4))) - (cond_exec - (ne:CC (match_dup 0) - (const_int 0)) - (set (match_dup 0) - (ne:CC (match_dup 5) - (match_dup 6))))] - " -{ - d30v_split_double (operands[1], &operands[3], &operands[5]); - d30v_split_double (operands[2], &operands[4], &operands[6]); -}") - -(define_insn "*ltdi_zero" - [(set (match_operand:CC 0 "flag_operand" "=f") - (lt:CC (match_operand:DI 1 "gpr_operand" "e") - (const_int 0)))] - "" - "cmplt%: %0,%U1,0" - [(set_attr "length" "4") - (set_attr "type" "scmp")]) - -(define_insn "*ltdi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (lt:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*ledi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (le:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*gtdi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (gt:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*gedi_zero" - [(set (match_operand:CC 0 "flag_operand" "=f") - (ge:CC (match_operand:DI 1 "gpr_operand" "e") - (const_int 0)))] - "" - "cmpge%: %0,%U1,0" - [(set_attr "length" "4") - (set_attr "type" "scmp")]) - -(define_insn "*gedi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (ge:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*ltudi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (ltu:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*leudi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (leu:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*gtudi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (gtu:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_insn "*geudi_internal" - [(set (match_operand:CC 0 "flag_operand" "=&f,&f,&f") - (geu:CC (match_operand:DI 1 "gpr_operand" "e,e,e") - (match_operand:DI 2 "gpr_or_dbl_const_operand" "eJP,i,F"))) - (clobber (match_operand:CC 3 "br_flag_operand" "=&b,&b,&b"))] - "" - "#" - [(set_attr "length" "12,16,24") - (set_attr "type" "multi")]) - -(define_split - [(set (match_operand:CC 0 "flag_operand" "") - (match_operator:CC 1 "relational_di_operator" - [(match_operand:DI 2 "gpr_operand" "") - (match_operand:DI 3 "gpr_or_dbl_const_operand" "")])) - (clobber (match_operand:CC 4 "br_flag_operand" ""))] - "reload_completed" - [(match_dup 5) - (match_dup 6) - (match_dup 7)] - " -{ - enum rtx_code cond = GET_CODE (operands[1]); - enum rtx_code ucond = unsigned_condition (cond); - rtx tmpflag = operands[4]; - rtx outflag = operands[0]; - rtx high[2]; - rtx low[2]; - - d30v_split_double (operands[2], &high[0], &low[0]); - d30v_split_double (operands[3], &high[1], &low[1]); - - operands[5] = gen_rtx_SET (VOIDmode, - tmpflag, - gen_rtx_EQ (CCmode, high[0], high[1])); - - operands[6] = gen_rtx_COND_EXEC (VOIDmode, - gen_rtx_NE (CCmode, tmpflag, const0_rtx), - gen_rtx_SET (VOIDmode, outflag, - gen_rtx_fmt_ee (cond, CCmode, - high[0], - high[1]))); - - operands[7] = gen_rtx_COND_EXEC (VOIDmode, - gen_rtx_EQ (CCmode, tmpflag, const0_rtx), - gen_rtx_SET (VOIDmode, outflag, - gen_rtx_fmt_ee (ucond, CCmode, - low[0], - low[1]))); -}") - - -;; :::::::::::::::::::: -;; :: -;; :: Branches -;; :: -;; :::::::::::::::::::: - -;; Define_expands called by the machine independent part of the compiler -;; to allocate a new comparison register - -(define_expand "beq" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (EQ, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bne" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (NE, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bgt" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GT, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bge" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GE, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "blt" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LT, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "ble" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LE, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bgtu" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GTU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bgeu" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GEU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bltu" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LTU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "bleu" - [(match_dup 2) - (set (pc) - (if_then_else (ne:CC (match_dup 1) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LEU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -;; Actual branches. We must allow for the (label_ref) and the (pc) to be -;; swapped. If they are swapped, it reverses the sense of the branch. -;; Also handle changing the ne to eq. -;; In order for the length calculations to be correct, the label must be -;; operand 0. - -;; We used to handle branches against 0 to be folded directly into -;; bratnz/bratzr instruction, but this dimisses the possibility of doing -;; conditional execution. Instead handle these via peepholes. - -;; Branches based off of the flag bits -(define_insn "*bra_true" - [(set (pc) - (if_then_else (match_operator:CC 1 "condexec_branch_operator" - [(match_operand:CC 2 "br_flag_or_constant_operand" "b,I,N") - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG) - return \"bra%F1 %l0\"; - - if (GET_CODE (operands[2]) != CONST_INT) - fatal_insn (\"bad jump\", insn); - - if ((GET_CODE (operands[1]) == EQ && INTVAL (operands[2]) == 0) - || (GET_CODE (operands[1]) == NE && INTVAL (operands[2]) != 0)) - return \"bra %l0\"; - - return \"; jump to %l0 optimized away\"; -}" - [(set_attr "type" "br") - (set_attr "predicable" "no")]) - -(define_insn "*bra_false" - [(set (pc) - (if_then_else (match_operator:CC 1 "condexec_branch_operator" - [(match_operand:CC 2 "br_flag_or_constant_operand" "b,I,N") - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG) - return \"bra%T1 %l0\"; - - if (GET_CODE (operands[2]) != CONST_INT) - fatal_insn (\"bad jump\", insn); - - if ((GET_CODE (operands[1]) == EQ && INTVAL (operands[2]) != 0) - || (GET_CODE (operands[1]) == NE && INTVAL (operands[2]) == 0)) - return \"bra %l0\"; - - return \"; jump to %l0 optimized away\"; -}" - [(set_attr "type" "br") - (set_attr "predicable" "no")]) - -;; Peephole to turn set flag, cond. jumps into branch if register ==/!= 0. - -(define_peephole2 - [(set (match_operand:CC 0 "br_flag_operand" "=b") - (match_operator:CC 1 "branch_zero_operator" - [(match_operand:SI 2 "gpr_operand" "d") - (const_int 0)])) - (set (pc) - (if_then_else (match_operator:CC 3 "condexec_test_operator" - [(match_dup 0) - (const_int 0)]) - (match_operand 4 "" "") - (match_operand 5 "" "")))] - "peep2_reg_dead_p (2, operands[0]) - && GET_CODE (operands[4]) != RETURN - && GET_CODE (operands[5]) != RETURN" - [(set (pc) - (if_then_else (match_dup 6) - (match_dup 4) - (match_dup 5)))] - " -{ - int true_false = 1; - if (GET_CODE (operands[1]) == EQ) - true_false = !true_false; - if (GET_CODE (operands[3]) == EQ) - true_false = !true_false; - operands[6] = gen_rtx_fmt_ee ((true_false ? NE : EQ), CCmode, - operands[2], const0_rtx); -}") - -(define_insn "*bra_reg_true" - [(set (pc) (if_then_else (match_operator:CC 1 "branch_zero_operator" - [(match_operand:SI 2 "gpr_operand" "d") - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "reload_completed" - "* -{ - return GET_CODE (operands[1]) == NE ? \"bratnz %2,%l0\" : \"bratzr %2,%l0\"; -}" - [(set_attr "type" "br2") - (set_attr "predicable" "no")]) - -(define_insn "*bra_reg_false" - [(set (pc) (if_then_else (match_operator:CC 1 "branch_zero_operator" - [(match_operand:SI 2 "gpr_operand" "d") - (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "reload_completed" - "* -{ - return GET_CODE (operands[1]) == EQ ? \"bratnz %2,%l0\" : \"bratzr %2,%l0\"; -}" - [(set_attr "type" "br2") - (set_attr "predicable" "no")]) - -;; :::::::::::::::::::: -;; :: -;; :: Set flag operations -;; :: -;; :::::::::::::::::::: - -;; Define_expands called by the machine independent part of the compiler -;; to allocate a new comparison register - -;; ??? These patterns should all probably use (ne:SI ... (const_int 0)) instead -;; of (eq:SI ... (const_int 1)), because the former is the canonical form. -;; The non-canonical form was used here because I was just trying to get the -;; port working again after it broke, and the non-canonical form was the -;; safer faster way to fix this. - - -(define_expand "seq" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (EQ, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sne" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (NE, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sgt" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GT, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sge" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GE, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "slt" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LT, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sle" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LE, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sgtu" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GTU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sgeu" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (GEU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sltu" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LTU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -(define_expand "sleu" - [(match_dup 2) - (set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_dup 1) (const_int 0)))] - "" - " -{ - operands[1] = gen_reg_rtx (CCmode); - operands[2] = d30v_emit_comparison (LEU, operands[1], - d30v_compare_op0, - d30v_compare_op1); -}") - -;; Set flag operations. We prefer to use conditional execution instead of -;; mvfsys, since it is faster, but allow the use of mvfsys to offload some -;; register pressure. -(define_insn "*setcc_internal" - [(set (match_operand:SI 0 "gpr_operand" "=d,?d,?*d") - (ne:SI (match_operand:CC 1 "flag_operand" "b,z,*d") - (const_int 0)))] - "" - "@ - # - mvfsys%: %0,%1 - or%: %0,%.,%1" - [(set_attr "length" "8,4,4") - (set_attr "type" "multi,either,either")]) - -(define_split - [(set (match_operand:SI 0 "gpr_operand" "") - (ne:SI (match_operand:CC 1 "br_flag_operand" "") - (const_int 0)))] - "reload_completed" - [(set (match_dup 0) - (const_int 0)) - (set (match_dup 0) - (if_then_else:SI (ne:CC (match_dup 1) - (const_int 0)) - (const_int 1) - (match_dup 0)))] - "") - - -;; :::::::::::::::::::: -;; :: -;; :: Operations on flags -;; :: -;; :::::::::::::::::::: - -(define_insn "andcc3" - [(set (match_operand:CC 0 "flag_operand" "=f") - (and:CC (match_operand:CC 1 "flag_operand" "f") - (match_operand:CC 2 "flag_operand" "f")))] - "" - "andfg%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -(define_insn "iorcc3" - [(set (match_operand:CC 0 "flag_operand" "=f") - (ior:CC (match_operand:CC 1 "flag_operand" "f") - (match_operand:CC 2 "flag_operand" "f")))] - "" - "orfg%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -(define_insn "xorcc3" - [(set (match_operand:CC 0 "flag_operand" "=f") - (xor:CC (match_operand:CC 1 "flag_operand" "f") - (match_operand:CC 2 "flag_operand" "f")))] - "" - "xorfg%: %0,%1,%2" - [(set_attr "length" "4") - (set_attr "type" "either")]) - -;; This is the canonical form produced by combine. - -(define_insn "incscc" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (plus:SI (eq:SI (match_operand:CC 1 "br_flag_operand" "b") - (const_int 1)) - (match_operand:SI 2 "gpr_operand" "0")))] - "" - "add%T1 %0,%2,1" - [(set_attr "length" "4") - (set_attr "type" "either") - ;; Not strictly true -- we could combine conditions. - (set_attr "predicable" "no")]) - -(define_insn "decscc" - [(set (match_operand:SI 0 "gpr_operand" "=d") - (minus:SI (match_operand:SI 1 "gpr_operand" "0") - (eq:SI (match_operand:CC 2 "br_flag_operand" "b") - (const_int 1))))] - "" - "sub%T2 %0,%1,1" - [(set_attr "length" "4") - (set_attr "type" "either") - ;; Not strictly true -- we could combine conditions. - (set_attr "predicable" "no")]) - -;; :::::::::::::::::::: -;; :: -;; :: Call and branch instructions -;; :: -;; :::::::::::::::::::: - -;; 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. - -(define_expand "call" - [(parallel [(call (match_operand 0 "call_operand" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (match_dup 3))])] - "" - " -{ - if (GET_CODE (XEXP (operands[0], 0)) == SUBREG) - XEXP (operands[0], 0) = copy_addr_to_reg (XEXP (operands[0], 0)); - - if (!operands[2]) - operands[2] = const0_rtx; - - operands[3] = gen_rtx (REG, Pmode, GPR_LINK); -}") - -(define_insn "*call_internal" - [(call (match_operand:QI 0 "call_operand" "R,S") - (match_operand 1 "" "")) - (use (match_operand 2 "" "")) - (clobber (match_operand 3 "" "=d,d"))] - "" - "@ - jsr%: %0 - bsr%: %0" - [(set_attr "length" "4,8") - (set_attr "type" "mu,long")]) - -;; 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. - -(define_expand "call_value" - [(parallel [(set (match_operand 0 "gpr_operand" "") - (call (match_operand 1 "call_operand" "") - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (match_dup 4))])] - "" - " -{ - if (GET_CODE (XEXP (operands[1], 0)) == SUBREG) - XEXP (operands[1], 0) = copy_addr_to_reg (XEXP (operands[1], 0)); - - if (!operands[3]) - operands[3] = const0_rtx; - - operands[4] = gen_rtx (REG, Pmode, GPR_LINK); -}") - -(define_insn "*call_value_internal" - [(set (match_operand 0 "gpr_operand" "=d,d") - (call (match_operand:QI 1 "call_operand" "R,S") - (match_operand 2 "" ""))) - (use (match_operand 3 "" "")) - (clobber (match_operand 4 "" "=d,d"))] - "" - "@ - jsr%: %1 - bsr%: %1" - [(set_attr "length" "4,8") - (set_attr "type" "mu,long")]) - -;; Subroutine return -(define_expand "return" - [(return)] - "direct_return ()" - "") - -(define_insn "*return_internal" - [(return)] - "reload_completed" - "jmp link" - [(set_attr "length" "4") - (set_attr "type" "mu") - (set_attr "predicable" "no")]) - -(define_insn "*cond_return_true" - [(set (pc) - (if_then_else (match_operator:CC 0 "condexec_branch_operator" - [(match_operand:CC 1 "br_flag_operand" "b") - (const_int 0)]) - (return) - (pc)))] - "reload_completed" - "jmp%F0 link" - [(set_attr "length" "4") - (set_attr "type" "mu") - (set_attr "predicable" "no")]) - -(define_insn "*cond_return_false" - [(set (pc) - (if_then_else (match_operator:CC 0 "condexec_branch_operator" - [(match_operand:CC 1 "br_flag_operand" "b") - (const_int 0)]) - (pc) - (return)))] - "reload_completed" - "jmp%T0 link" - [(set_attr "length" "4") - (set_attr "type" "mu") - (set_attr "predicable" "no")]) - -;; Normal unconditional jump -(define_insn "jump" - [(set (pc) (label_ref (match_operand 0 "" "")))] - "" - "bra %l0" - [(set_attr "type" "br") - (set_attr "predicable" "no")]) - -;; Indirect jump through a register -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "gpr_operand" "d"))] - "" - "jmp %0" - [(set_attr "length" "4") - (set_attr "type" "mu") - (set_attr "predicable" "no")]) - -;; 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. - -(define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "gpr_operand" "d")) - (use (label_ref (match_operand 1 "" "")))] - "" - "jmp %0" - [(set_attr "length" "4") - (set_attr "type" "mu") - (set_attr "predicable" "no")]) - - - -;; :::::::::::::::::::: -;; :: -;; :: Prologue and Epilogue instructions -;; :: -;; :::::::::::::::::::: - -;; Called after register allocation to add any instructions needed for the -;; prologue. Using a prologue insn is favored compared to putting all of the -;; instructions in output_function_prologue (), since it allows the scheduler -;; to intermix instructions with the saves of the caller saved registers. In -;; some cases, it might be necessary to emit a barrier instruction as the last -;; insn to prevent such scheduling. - -(define_expand "prologue" - [(const_int 1)] - "" - " -{ - d30v_expand_prologue (); - DONE; -}") - -;; Called after register allocation to add any instructions needed for the -;; epilogue. Using an epilogue insn is favored compared to putting all of the -;; instructions in output_function_epilogue (), since it allows the scheduler -;; to intermix instructions with the saves of the caller saved registers. In -;; some cases, it might be necessary to emit a barrier instruction as the last -;; insn to prevent such scheduling. - -(define_expand "epilogue" - [(const_int 2)] - "" - " -{ - d30v_expand_epilogue (); - DONE; -}") - -(define_expand "eh_epilogue" - [(use (match_operand:DI 0 "register_operand" "r")) - (use (match_operand:DI 1 "register_operand" "r")) - (use (match_operand:DI 2 "register_operand" "r"))] - "" - " -{ - cfun->machine->eh_epilogue_sp_ofs = operands[1]; - if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != GPR_LINK) - { - rtx ra = gen_rtx_REG (Pmode, GPR_LINK); - emit_move_insn (ra, operands[2]); - operands[2] = ra; - } -}") - - -;; :::::::::::::::::::: -;; :: -;; :: Conditional move instructions -;; :: -;; :::::::::::::::::::: - -;; Conditionally move operand 2 or operand 3 into operand 0 according to the -;; comparison in operand 1. If the comparison is true, operand 2 is moved into -;; operand 0, otherwise operand 3 is moved. - -;; The mode of the operands being compared need not be the same as the operands -;; being moved. Some machines, sparc64 for example, have instructions that -;; conditionally move an integer value based on the floating point condition -;; codes and vice versa. - -;; If the machine does not have conditional move instructions, do not -;; define these patterns. - -;; Note we don't allow the general form of conditional store to be generated -- -;; we always generate two separate if_then_elses's -(define_expand "movqicc" - [(set (match_operand:QI 0 "move_output_operand" "") - (if_then_else:QI (match_operand 1 "" "") - (match_operand:QI 2 "move_input_operand" "") - (match_operand:QI 3 "move_input_operand" "")))] - "TARGET_COND_MOVE" - " -{ - if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) - FAIL; - - DONE; -}") - -(define_insn "*movqicc_internal" - [(set (match_operand:QI 0 "gpr_operand" "=d,d,d,d,d,c,d,d,d,d,d,c,?&d") - (if_then_else:QI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b,b,b") - (const_int 0)]) - (match_operand:QI 3 "move_input_operand" "dI,i,Q,m,c,d,0,0,0,0,0,0,dim") - (match_operand:QI 4 "move_input_operand" "0,0,0,0,0,0,dI,i,Q,m,c,d,dim")))] - "" - "#" - [(set_attr "length" "4,8,4,8,4,4,4,8,4,8,4,4,16") - (set_attr "type" "either,long,sload,lload,mu,mu,either,long,sload,lload,mu,mu,multi") - (set_attr "predicable" "no")]) - -;; If we have: a = (test) ? a : b, or a = (test) ? b : a, we can split it -;; before reload to allow combine to substitute in early. -;; ??? Not until we teach reload how to do conditional spills, we can't. -(define_split - [(set (match_operand:QI 0 "move_output_operand" "") - (if_then_else:QI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:QI 3 "move_input_operand" "") - (match_dup 0)))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3)))] - "") - -(define_split - [(set (match_operand:QI 0 "move_output_operand" "") - (if_then_else:QI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_dup 0) - (match_operand:QI 3 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 4) - (set (match_dup 0) (match_dup 3)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_split - [(set (match_operand:QI 0 "move_output_operand" "") - (if_then_else:QI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:QI 3 "move_input_operand" "") - (match_operand:QI 4 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3))) - (cond_exec (match_dup 5) - (set (match_dup 0) (match_dup 4)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_expand "movhicc" - [(set (match_operand:HI 0 "move_output_operand" "") - (if_then_else:HI (match_operand 1 "" "") - (match_operand:HI 2 "move_input_operand" "") - (match_operand:HI 3 "move_input_operand" "")))] - "TARGET_COND_MOVE" - " -{ - if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) - FAIL; - - DONE; -}") - -(define_insn "*movhicc_internal" - [(set (match_operand:HI 0 "gpr_operand" "=d,d,d,d,d,c,d,d,d,d,d,c,?&d") - (if_then_else:HI - (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b,b,b") - (const_int 0)]) - (match_operand:HI 3 "move_input_operand" "dI,i,Q,m,c,d,0,0,0,0,0,0,dim") - (match_operand:HI 4 "move_input_operand" "0,0,0,0,0,0,dI,i,Q,m,c,d,dim")))] - "" - "#" - [(set_attr "length" "4,8,4,8,4,4,4,8,4,8,4,4,16") - (set_attr "type" "either,long,sload,lload,mu,mu,either,long,sload,lload,mu,mu,multi") - (set_attr "predicable" "no")]) - -;; If we have: a = (test) ? a : b, or a = (test) ? b : a, we can split it -;; before reload to allow combine to substitute in early. -;; ??? Not until we teach reload how to do conditional spills, we can't. -(define_split - [(set (match_operand:HI 0 "move_output_operand" "") - (if_then_else:HI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:HI 3 "move_input_operand" "") - (match_dup 0)))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3)))] - "") - -(define_split - [(set (match_operand:HI 0 "move_output_operand" "") - (if_then_else:HI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_dup 0) - (match_operand:HI 3 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 4) - (set (match_dup 0) (match_dup 3)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_split - [(set (match_operand:HI 0 "move_output_operand" "") - (if_then_else:HI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:HI 3 "move_input_operand" "") - (match_operand:HI 4 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3))) - (cond_exec (match_dup 5) - (set (match_dup 0) (match_dup 4)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_expand "movsicc" - [(set (match_operand:SI 0 "move_output_operand" "") - (if_then_else:SI (match_operand 1 "" "") - (match_operand:SI 2 "move_input_operand" "") - (match_operand:SI 3 "move_input_operand" "")))] - "TARGET_COND_MOVE" - " -{ - if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) - FAIL; - - DONE; -}") - -(define_insn "*movsicc_internal" - [(set (match_operand:SI 0 "move_output_operand" "=d,d,d,d,d,c,d,d,d,d,d,c,?&d") - (if_then_else:SI - (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b,b,b,b,b") - (const_int 0)]) - (match_operand:SI 3 "move_input_operand" "dI,i,Q,m,c,d,0,0,0,0,0,0,dim") - (match_operand:SI 4 "move_input_operand" "0,0,0,0,0,0,dI,i,Q,m,c,d,dim")))] - "" - "#" - [(set_attr "length" "4,8,4,8,4,4,4,8,4,8,4,4,16") - (set_attr "type" "either,long,sload,lload,mu,mu,either,long,sload,lload,mu,mu,multi") - (set_attr "predicable" "no")]) - -;; If we have: a = (test) ? a : b, or a = (test) ? b : a, we can split it -;; before reload to allow combine to substitute in early. -;; ??? Not until we teach reload how to do conditional spills, we can't. -(define_split - [(set (match_operand:SI 0 "move_output_operand" "") - (if_then_else:SI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:SI 3 "move_input_operand" "") - (match_dup 0)))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3)))] - "") - -(define_split - [(set (match_operand:SI 0 "move_output_operand" "") - (if_then_else:SI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_dup 0) - (match_operand:SI 3 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 4) - (set (match_dup 0) (match_dup 3)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_split - [(set (match_operand:SI 0 "move_output_operand" "") - (if_then_else:SI (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:SI 3 "move_input_operand" "") - (match_operand:SI 4 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3))) - (cond_exec (match_dup 5) - (set (match_dup 0) (match_dup 4)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_expand "movsfcc" - [(set (match_operand:SF 0 "move_output_operand" "") - (if_then_else:SF (match_operand 1 "" "") - (match_operand:SF 2 "move_input_operand" "") - (match_operand:SF 3 "move_input_operand" "")))] - "TARGET_COND_MOVE" - " -{ - if (!d30v_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) - FAIL; - - DONE; -}") - -(define_insn "*movsfcc_internal" - [(set (match_operand:SF 0 "gpr_operand" "=d,d,d,d,d,d,d,d,?&d") - (if_then_else:SF - (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "b,b,b,b,b,b,b,b,b") - (const_int 0)]) - (match_operand:SF 3 "move_input_operand" "dG,F,Q,m,0,0,0,0,dim") - (match_operand:SF 4 "move_input_operand" "0,0,0,0,dG,F,Q,m,dim")))] - "" - "#" - [(set_attr "length" "4,8,4,8,4,8,4,8,16") - (set_attr "type" "either,long,sload,lload,either,long,sload,lload,multi") - (set_attr "predicable" "no")]) - -(define_split - [(set (match_operand:SF 0 "move_output_operand" "") - (if_then_else:SF (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:SF 3 "move_input_operand" "") - (match_dup 0)))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3)))] - "") - -(define_split - [(set (match_operand:SF 0 "move_output_operand" "") - (if_then_else:SF (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_dup 0) - (match_operand:SF 3 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 4) - (set (match_dup 0) (match_dup 3)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[4] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[4] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - -(define_split - [(set (match_operand:SF 0 "move_output_operand" "") - (if_then_else:SF (match_operator:CC 1 "condexec_test_operator" - [(match_operand:CC 2 "br_flag_operand" "") - (const_int 0)]) - (match_operand:SF 3 "move_input_operand" "") - (match_operand:SF 4 "move_input_operand" "")))] - "reload_completed" - [(cond_exec (match_dup 1) - (set (match_dup 0) (match_dup 3))) - (cond_exec (match_dup 5) - (set (match_dup 0) (match_dup 4)))] - " -{ - if (GET_CODE (operands[1]) == EQ) - operands[5] = gen_rtx_NE (CCmode, operands[2], const0_rtx); - else - operands[5] = gen_rtx_EQ (CCmode, operands[2], const0_rtx); -}") - - -;; :::::::::::::::::::: -;; :: -;; :: Miscellaneous instructions -;; :: -;; :::::::::::::::::::: - -;; No operation, needed in case the user uses -g but not -O. -(define_insn "nop" - [(const_int 0)] - "" - "nop || nop" - [(set_attr "length" "8") - (set_attr "type" "long") - (set_attr "predicable" "no")]) - -;; Pseudo instruction that prevents the scheduler from moving code above this -;; point. -(define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] - "" - "" - [(set_attr "length" "0") - (set_attr "type" "unknown") - (set_attr "predicable" "no")]) - -;; :::::::::::::::::::: -;; :: -;; :: Conditional execution -;; :: -;; :::::::::::::::::::: - -(define_cond_exec - [(match_operator:CC 0 "condexec_test_operator" - [(match_operand:CC 1 "br_flag_operand" "b") - (const_int 0)])] - "" - "")