-;; 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.
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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.
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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"))
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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)])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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]);
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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]);
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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]);
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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]);
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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])));
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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)))]
- "")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-
-\f
-
-;; ::::::::::::::::::::
-;; ::
-;; :: 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;
- }
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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);
-}")
-
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: 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")])
-\f
-;; ::::::::::::::::::::
-;; ::
-;; :: Conditional execution
-;; ::
-;; ::::::::::::::::::::
-
-(define_cond_exec
- [(match_operator:CC 0 "condexec_test_operator"
- [(match_operand:CC 1 "br_flag_operand" "b")
- (const_int 0)])]
- ""
- "")