home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-12 | 83.5 KB | 2,889 lines |
- ;;- Machine description for AMD Am29000 for GNU C compiler
- ;; Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
- ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-
- ;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-
- ;; The insns in this file are presented in the same order as the AMD 29000
- ;; User's Manual (i.e., alphabetical by machine op-code).
- ;;
- ;; DEFINE_EXPAND's are located near the first occurrence of the major insn
- ;; that they generate.
-
- ;; The only attribute we have is the type. We only care about calls, branches,
- ;; loads, stores, floating-point operations, and multi-word insns.
- ;; Everything else is miscellaneous.
-
- (define_attr "type"
- "call,branch,load,store,fadd,fmul,fam,fdiv,fsqrt,dmul,dam,ddiv,dsqrt,multi,misc"
- (const_string "misc"))
-
- ;; ASM insns cannot go into a delay slot, so call them "multi".
- (define_asm_attributes [(set_attr "type" "multi")])
-
- (define_attr "in_delay_slot" "yes,no"
- (if_then_else (eq_attr "type" "call,branch,multi") (const_string "no")
- (const_string "yes")))
-
- ;; Branch and call insns require a single delay slot. Annulling is not
- ;; supported.
- (define_delay (eq_attr "type" "call,branch")
- [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
-
- ;; Define the function unit usages. We first define memory as a unit.
- (define_function_unit "memory" 1 0 (eq_attr "type" "load") 6 5
- [(eq_attr "type" "load")])
- (define_function_unit "memory" 1 0 (eq_attr "type" "load") 6 6
- [(eq_attr "type" "store")])
- (define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
-
- ;; Now define the function units for the floating-point support. Most
- ;; units are pipelined and can accept an input every cycle.
- ;;
- ;; Note that we have an inaccuracy here. If a fmac insn is issued, followed
- ;; 2 cycles later by a fadd, there will be a conflict for the floating
- ;; adder that we can't represent. Also, all insns will conflict for the
- ;; floating-point rounder. It isn't clear how to represent this.
-
- (define_function_unit "multiplier" 1 0 (eq_attr "type" "fmul") 3 0)
- (define_function_unit "multiplier" 1 0 (eq_attr "type" "dmul") 6 4)
- (define_function_unit "multiplier" 1 0 (eq_attr "type" "fam") 6 0)
- (define_function_unit "multiplier" 1 0 (eq_attr "type" "dam") 9 4)
-
- (define_function_unit "adder" 1 0 (eq_attr "type" "fadd,fam,dam") 3 0)
-
- (define_function_unit "divider" 1 0 (eq_attr "type" "fdiv") 11 10)
- (define_function_unit "divider" 1 0 (eq_attr "type" "fsqrt") 28 27)
- (define_function_unit "divider" 1 0 (eq_attr "type" "ddiv") 18 17)
- (define_function_unit "divider" 1 0 (eq_attr "type" "dsqrt") 57 56)
-
- ;; ADD
- (define_insn "addsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
- (match_operand:SI 2 "add_operand" "rI,N")))]
- ""
- "@
- add %0,%1,%2
- sub %0,%1,%n2")
-
- (define_insn "adddi3"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r")
- (match_operand:DI 2 "gpc_reg_operand" "r")))]
- ""
- "add %L0,%L1,%L2\;addc %0,%1,%2"
- [(set_attr "type" "multi")])
-
- ;; AND/ANDN
- (define_insn "andsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
- (match_operand:SI 2 "and_operand" "rI,K")))]
- ""
- "@
- and %0,%1,%2
- andn %0,%1,%C2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
- (match_operand:SI 2 "cmplsrcb_operand" "r,K")))]
- ""
- "@
- andn %0,%2,%1
- nor %0,%1,%C2")
-
- ;; CALLI
- ;;
- ;; Each call pattern is duplicated so that we can add CLOBBERs to the
- ;; resulting insn.
- ;;
- ;; We indicate that LR0 is clobbered in the CALL_INSN itself. Otherwise,
- ;; reorg will think it is just clobbered by the called function.
-
- (define_expand "call"
- [(use (match_operand:SI 0 "" ""))
- (use (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
- ""
- "
- { rtx insn = emit_call_insn (gen_call_internal (operands[0], operands[1]));
- a29k_clobbers_to (insn, operands[2]);
-
- DONE;
- }")
-
- (define_expand "call_internal"
- [(parallel [(call (match_operand:SI 0 "" "")
- (match_operand 1 "" ""))
- (clobber (scratch:SI))])]
- ""
- "
- {
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
- /* We tell here whether this is a recursive call, since this insn may
- later be inlined into another function. */
- if (! TARGET_SMALL_MEMORY
- && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
- operands[0] = gen_rtx (MEM, SImode,
- force_reg (Pmode, XEXP (operands[0], 0)));
- }")
-
- (define_expand "call_value"
- [(use (match_operand:SI 0 "gpc_reg_operand" ""))
- (use (match_operand:SI 1 "" ""))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))]
- ""
- "
- { rtx insn = emit_call_insn (gen_call_value_internal (operands[0], operands[1],
- operands[2]));
-
- a29k_clobbers_to (insn, operands[3]);
- DONE;
- }")
-
- (define_expand "call_value_internal"
- [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (call (match_operand:SI 1 "" "")
- (match_operand 2 "" "")))
- (clobber (scratch:SI))])]
- ""
- "
- {
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
- /* We tell here whether this is a recursive call, since this insn may
- later be inlined into another function. */
- if (! TARGET_SMALL_MEMORY
- && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
- operands[1] = gen_rtx (MEM, SImode,
- force_reg (Pmode, XEXP (operands[1], 0)));
-
- }")
-
- (define_insn ""
- [(call (match_operand:SI 0 "memory_operand" "m")
- (match_operand 1 "" ""))
- (clobber (match_scratch:SI 2 "=&l"))]
- "GET_CODE (XEXP (operands[0], 0)) != CONST_INT"
- "calli lr0,%0%#"
- [(set_attr "type" "call")])
-
- (define_insn ""
- [(call (mem:SI (match_operand:SI 0 "call_operand" "i"))
- (match_operand:SI 1 "general_operand" "g"))
- (clobber (match_scratch:SI 2 "=&l"))]
- ""
- "call lr0,%F0"
- [(set_attr "type" "call")])
-
- (define_insn ""
- [(set (match_operand 0 "gpc_reg_operand" "=r")
- (call (match_operand:SI 1 "memory_operand" "m")
- (match_operand 2 "" "")))
- (clobber (match_scratch:SI 3 "=&l"))]
- "GET_CODE (XEXP (operands[1], 0)) != CONST_INT"
- "calli lr0,%1%#"
- [(set_attr "type" "call")])
-
- (define_insn ""
- [(set (match_operand 0 "gpc_reg_operand" "=r")
- (call (mem:SI (match_operand:SI 1 "call_operand" "i"))
- (match_operand:SI 2 "general_operand" "g")))
- (clobber (match_scratch:SI 3 "=&l"))]
- ""
- "call lr0,%F1"
- [(set_attr "type" "call")])
-
- (define_expand "probe"
- [(call (mem:SI (symbol_ref:SI "_msp_check"))
- (const_int 1))]
- "TARGET_STACK_CHECK"
- "")
-
- ;; This is used for internal routine calls via TPC. Currently used only
- ;; in probe, above.
- (define_insn ""
- [(call (mem:SI (match_operand:SI 0 "immediate_operand" "s"))
- (const_int 1))]
- ""
- "call %*,%0"
- [(set_attr "type" "call")])
-
- ;; CONST, CONSTH, CONSTN
- ;;
- ;; Many of these are generated from move insns.
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (and:SI (match_operand:SI 1 "immediate_operand" "i")
- (const_int 65535)))]
- ""
- "const %0,%1")
-
- (define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
- (const_int 16)
- (match_operand:SI 1 "const_0_operand" ""))
- (ashiftrt:SI (match_operand:SI 2 "immediate_operand" "i")
- (const_int 16)))]
- ""
- "consth %0,%2")
-
- (define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
- (const_int 16)
- (match_operand:SI 1 "const_0_operand" ""))
- (match_operand:SI 2 "cint_16_operand" "J"))]
- ""
- "consth %0,%m2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0"))
- (match_operand:SI 2 "const_int_operand" "n")))]
- "(INTVAL (operands[2]) & 0xffff) == 0"
- "consth %0,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0"))
- (and:SI (match_operand:SI 2 "immediate_operand" "i")
- (const_int -65536))))]
- ""
- "consth %0,%2")
-
- ;; CONVERT
- (define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (fix:SI (match_operand:SF 1 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,0,3,0,1")
-
- (define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (fix:SI (match_operand:DF 1 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,0,3,0,2")
-
- (define_insn "fixuns_truncsfsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,1,3,0,1")
-
- (define_insn "fixuns_truncdfsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unsigned_fix:SI (match_operand:DF 1 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,1,3,0,2")
-
- (define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "register_operand" "=r")
- (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,0,4,1,2")
-
- (define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "=r")
- (float_extend:DF (match_operand:SF 1 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,0,4,2,1")
-
- (define_insn "floatsisf2"
- [(set (match_operand:SF 0 "register_operand" "=r")
- (float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,0,4,1,0")
-
- (define_insn "floatsidf2"
- [(set (match_operand:DF 0 "register_operand" "=r")
- (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,0,4,2,0")
-
- (define_insn "floatunssisf2"
- [(set (match_operand:SF 0 "register_operand" "=r")
- (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,1,4,1,0")
-
- (define_insn "floatunssidf2"
- [(set (match_operand:DF 0 "register_operand" "=r")
- (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "convert %0,%1,1,4,2,0")
-
- ;; CPxxx, DEQ, DGT, DGE, FEQ, FGT, FGE
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (match_operator 3 "comparison_operator"
- [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "srcb_operand" "rI")]))]
- ""
- "cp%J3 %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (match_operator 3 "fp_comparison_operator"
- [(match_operand:SF 1 "register_operand" "r")
- (match_operand:SF 2 "register_operand" "r")]))]
- "! TARGET_SOFT_FLOAT"
- "f%J3 %0,%1,%2"
- [(set_attr "type" "fadd")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (match_operator 3 "fp_comparison_operator"
- [(match_operand:DF 1 "register_operand" "r")
- (match_operand:DF 2 "register_operand" "r")]))]
- "! TARGET_SOFT_FLOAT"
- "d%J3 %0,%1,%2"
- [(set_attr "type" "fadd")])
-
- ;; DADD
- (define_expand "adddf3"
- [(set (match_operand:DF 0 "register_operand" "")
- (plus:DF (match_operand:DF 1 "register_operand" "")
- (match_operand:DF 2 "register_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "")
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r")
- (plus:DF (match_operand:DF 1 "register_operand" "%r")
- (match_operand:DF 2 "register_operand" "r")))]
- "! TARGET_29050 "
- "dadd %0,%1,%2"
- [(set_attr "type" "fadd")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r,a")
- (plus:DF (match_operand:DF 1 "register_operand" "%r,r")
- (match_operand:DF 2 "register_operand" "r,0")))]
- "TARGET_29050"
- "@
- dadd %0,%1,%2
- dmac 8,%0,%1,%1"
- [(set_attr "type" "fadd,dam")])
-
- ;; DDIV
- (define_insn "divdf3"
- [(set (match_operand:DF 0 "register_operand" "=r")
- (div:DF (match_operand:DF 1 "register_operand" "=r")
- (match_operand:DF 2 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "ddiv %0,%1,%2"
- [(set_attr "type" "ddiv")])
-
- ;; DIVIDE
- ;;
- ;; We must set Q to the sign extension of the dividend first. For MOD, we
- ;; must get the remainder from Q.
- ;;
- ;; For divmod: operand 1 is divided by operand 2; quotient goes to operand
- ;; 0 and remainder to operand 3.
- (define_expand "divmodsi4"
- [(set (match_dup 4)
- (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (const_int 31)))
- (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (div:SI (match_dup 1)
- (match_operand:SI 2 "gpc_reg_operand" "")))
- (set (match_operand:SI 3 "gpc_reg_operand" "")
- (mod:SI (match_dup 1)
- (match_dup 2)))
- (use (match_dup 4))])]
- ""
- "
- {
- operands[4] = gen_reg_rtx (SImode);
- }")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "gpc_reg_operand" "r")))
- (set (match_operand:SI 3 "register_operand" "=q")
- (mod:SI (match_dup 1)
- (match_dup 2)))
- (use (match_operand:SI 4 "register_operand" "3"))]
- ""
- "divide %0,%1,%2")
-
- ;; DIVIDU
- ;;
- ;; Similar to DIVIDE.
- (define_expand "udivmodsi4"
- [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "gpc_reg_operand" "")))
- (set (match_operand:SI 3 "gpc_reg_operand" "")
- (umod:SI (match_dup 1)
- (match_dup 2)))
- (use (const_int 0))])]
- ""
- "")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:SI 2 "gpc_reg_operand" "r")))
- (set (match_operand:SI 3 "register_operand" "=q")
- (umod:SI (match_dup 1)
- (match_dup 2)))
- (use (match_operand:SI 4 "const_int_operand" "3"))]
- ""
- "dividu %0,%1,%2")
-
- ;; DMAC/DMSM
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a,*r")
- (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "%r,A")
- (match_operand:DF 2 "register_operand" "r,r"))
- (match_operand:DF 3 "register_operand" "0,*r")))]
- "TARGET_29050"
- "@
- dmac 0,%0,%1,%2
- dmsm %0,%2,%3"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a")
- (plus:DF (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "r"))
- (match_operand:DF 2 "register_operand" "r"))
- (match_operand:DF 3 "register_operand" "0")))]
- "TARGET_29050"
- "dmac 1,%0,%2,%1"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a")
- (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "%r")
- (match_operand:DF 2 "register_operand" "r"))
- (match_operand:DF 3 "register_operand" "0")))]
- "TARGET_29050"
- "dmac 2,%0,%1,%2"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a")
- (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "r")
- (neg:DF (match_operand:DF 2 "register_operand" "r")))
- (match_operand:DF 3 "register_operand" "0")))]
- "TARGET_29050"
- "dmac 3,%0,%1,%2"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a")
- (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "r"))
- (match_operand:DF 2 "register_operand" "r")))]
- "TARGET_29050"
- "dmac 5,%0,%2,%1"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a")
- (minus:DF (neg:DF (match_operand:DF 1 "register_operand" "r"))
- (match_operand:DF 2 "register_operand" "0")))]
- "TARGET_29050"
- "dmac 11,%0,%1,%1"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=a")
- (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "%r")
- (match_operand:DF 2 "register_operand" "0"))))]
- "TARGET_29050"
- "dmac 11,%0,%1,%1"
- [(set_attr "type" "dam")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r,r,a")
- (neg:DF (match_operand:DF 1 "register_operand" "0,r,r")))
- (clobber (match_scratch:SI 2 "=&r,&r,X"))]
- "TARGET_29050"
- "@
- cpeq %2,gr1,gr1\;xor %0,%1,%2
- cpeq %2,gr1,gr1\;xor %0,%1,%2\;sll %L0,%L1,0
- dmac 13,%0,%1,%1"
- [(set_attr "type" "multi,multi,dam")])
-
- ;; DMUL
- (define_expand "muldf3"
- [(set (match_operand:DF 0 "register_operand" "")
- (mult:DF (match_operand:DF 1 "register_operand" "")
- (match_operand:DF 2 "register_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "")
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r")
- (mult:DF (match_operand:DF 1 "register_operand" "%r")
- (match_operand:DF 2 "register_operand" "r")))]
- "! TARGET_29050"
- "dmul %0,%1,%2"
- [(set_attr "type" "dmul")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r,a")
- (mult:DF (match_operand:DF 1 "register_operand" "%r,r")
- (match_operand:DF 2 "register_operand" "r,r")))]
- "TARGET_29050"
- "@
- dmul %0,%1,%2
- dmac 4,%0,%1,%2"
- [(set_attr "type" "dmul,dam")])
-
- ;; DSUB
- (define_expand "subdf3"
- [(set (match_operand:DF 0 "register_operand" "=r")
- (minus:DF (match_operand:DF 1 "register_operand" "r")
- (match_operand:DF 2 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "")
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r")
- (minus:DF (match_operand:DF 1 "register_operand" "r")
- (match_operand:DF 2 "register_operand" "r")))]
- "! TARGET_29050"
- "dsub %0,%1,%2"
- [(set_attr "type" "fadd")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r,a,a")
- (minus:DF (match_operand:DF 1 "register_operand" "r,0,r")
- (match_operand:DF 2 "register_operand" "r,r,0")))]
- "TARGET_29050"
- "@
- dsub %0,%1,%2
- dmac 9,%0,%2,%2
- dmac 10,%0,%1,%1"
- [(set_attr "type" "fadd,dam,dam")])
-
- ;; EXBYTE
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (and:SI (match_operand:SI 1 "srcb_operand" "rI")
- (const_int -256))
- (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
- (const_int 8)
- (ashift:PSI
- (match_operand:PSI 3 "register_operand" "b")
- (const_int 3)))))]
- ""
- "exbyte %0,%2,%1")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 8)
- (ashift:PSI
- (match_operand:PSI 2 "register_operand" "b")
- (const_int 3))))]
- ""
- "exbyte %0,%1,0")
-
- (define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
- (const_int 8)
- (match_operand:PSI 1 "const_24_operand" ""))
- (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
- (const_int 8)
- (ashift:PSI
- (match_operand:PSI 3 "register_operand" "b")
- (const_int 3))))]
- ""
- "exbyte %0,%2,%0")
-
- (define_expand "extzv"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "general_operand" "")
- (match_operand:SI 3 "general_operand" "")))]
- ""
- "
- {
- int size, pos;
-
- if (GET_CODE (operands[2]) != CONST_INT
- || GET_CODE (operands[3]) != CONST_INT)
- FAIL;
-
- size = INTVAL (operands[2]);
- pos = INTVAL (operands[3]);
-
- /* Can't do this unless a byte extraction. If extracting the high
- or low byte, don't do this because a shift or AND is shorter.
- Don't do 16-bit extracts, since the only two are the high and low
- ends, and it is faster to do them with CONSTH and SRL. */
-
- if (size != 8 || (pos != 8 && pos != 16))
- FAIL;
-
- operands[3] = gen_rtx (ASHIFT, PSImode,
- force_reg (PSImode, GEN_INT (pos / 8)),
- GEN_INT (3));
-
- }")
-
- ;; EXHW
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (and:SI (match_operand:SI 1 "srcb_operand" "rI")
- (const_int -65536))
- (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
- (const_int 16)
- (ashift:PSI
- (match_operand:PSI 3 "register_operand" "b")
- (const_int 3)))))]
- ""
- "exhw %0,%2,%1")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 16)
- (ashift:PSI
- (match_operand:PSI 2 "register_operand" "b")
- (const_int 3))))]
- ""
- "exhw %0,%1,0")
-
- (define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
- (const_int 16)
- (match_operand:PSI 1 "const_16_operand" ""))
- (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
- (const_int 16)
- (ashift:PSI
- (match_operand:PSI 3 "register_operand" "b")
- (const_int 3))))]
- ""
- "exhw %0,%2,%0")
-
- ;; EXHWS
- ;;
- ;; This is probably unused. The high-order 16-bits are obtained with an SRA
- ;; insn. The low-order 16 bits are a sign-extend, which is a pair of
- ;; shifts. Setting BP followed by the insn is equivalent, so we don't
- ;; bother going to any trouble to generate this insn.
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (sign_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 16)
- (ashift:PSI
- (match_operand:PSI 2 "register_operand" "b")
- (const_int 3))))]
- ""
- "exhws %0,%1")
-
- ;; EXTRACT
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:PSI 2 "register_operand" "f")))]
- ""
- "extract %0,%1,%1")
-
- (define_expand "rotlsi3"
- [(set (match_dup 3)
- (match_operand:SI 2 "gpc_reg_or_immediate_operand" ""))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (match_dup 3)))]
- ""
- "
- { operands[2] = gen_lowpart (PSImode, operands[2]);
- operands[3] = gen_reg_rtx (PSImode);
- }")
-
- ;; It would be nice to be able to have a define_split corresponding to the
- ;; above, but there is no way to tell combine we need a PSImode temporary.
- ;; If we put a (clobber (scratch:PSI)) there, combine would merge the above
- ;; two insns. This is bad because it then thinks only one insn is needed.
-
- ;; FADD
- (define_expand "addsf3"
- [(set (match_operand:SF 0 "register_operand" "")
- (plus:SF (match_operand:SF 1 "register_operand" "")
- (match_operand:SF 2 "register_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "")
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r")
- (plus:SF (match_operand:SF 1 "register_operand" "%r")
- (match_operand:SF 2 "register_operand" "r")))]
- "! TARGET_29050"
- "fadd %0,%1,%2"
- [(set_attr "type" "fadd")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r,a")
- (plus:SF (match_operand:SF 1 "register_operand" "%r,r")
- (match_operand:SF 2 "register_operand" "r,0")))]
- "TARGET_29050"
- "@
- fadd %0,%1,%2
- fmac 8,%0,%1,%1"
- [(set_attr "type" "fadd,fam")])
-
- ;; FDIV
- (define_insn "divsf3"
- [(set (match_operand:SF 0 "register_operand" "=r")
- (div:SF (match_operand:SF 1 "register_operand" "=r")
- (match_operand:SF 2 "register_operand" "r")))]
- "! TARGET_SOFT_FLOAT"
- "fdiv %0,%1,%2"
- [(set_attr "type" "fdiv")])
-
- ;; FDMUL
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=r")
- (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "%r"))
- (float_extend:DF (match_operand:SF 2 "register_operand" "r"))))]
- "! TARGET_SOFT_FLOAT"
- "fdmul %0,%1,%2")
-
- ;; FMAC/FMSM
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a,*r")
- (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%r,A")
- (match_operand:SF 2 "register_operand" "r,r"))
- (match_operand:SF 3 "register_operand" "0,*r")))]
- "TARGET_29050"
- "@
- fmac 0,%0,%1,%2
- fmsm %0,%2,%3"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a")
- (plus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
- (match_operand:SF 2 "register_operand" "r"))
- (match_operand:SF 3 "register_operand" "0")))]
- "TARGET_29050"
- "fmac 1,%0,%2,%1"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a")
- (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "%r")
- (match_operand:SF 2 "register_operand" "r"))
- (match_operand:SF 3 "register_operand" "0")))]
- "TARGET_29050"
- "fmac 2,%0,%1,%2"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a")
- (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
- (match_operand:SF 2 "register_operand" "r"))
- (match_operand:SF 3 "register_operand" "0")))]
- "TARGET_29050"
- "fmac 3,%0,%2,%1"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a")
- (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "r"))
- (match_operand:SF 2 "register_operand" "r")))]
- "TARGET_29050"
- "fmac 5,%0,%2,%1"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a")
- (minus:SF (neg:SF (match_operand:SF 1 "register_operand" "%r"))
- (match_operand:SF 2 "register_operand" "0")))]
- "TARGET_29050"
- "fmac 11,%0,%1,%1"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=a")
- (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "%r")
- (match_operand:SF 2 "register_operand" "0"))))]
- "TARGET_29050"
- "fmac 11,%0,%1,%1"
- [(set_attr "type" "fam")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r,a")
- (neg:SF (match_operand:SF 1 "register_operand" "r,r")))
- (clobber (match_scratch:SI 2 "=&r,X"))]
- "TARGET_29050"
- "@
- cpeq %2,gr1,gr1\;xor %0,%1,%2
- fmac 13,%0,%1,%1"
- [(set_attr "type" "multi,fam")])
-
- ;; FMUL
- (define_expand "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "")
- (mult:SF (match_operand:SF 1 "register_operand" "")
- (match_operand:SF 2 "register_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "")
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r")
- (mult:SF (match_operand:SF 1 "register_operand" "%r")
- (match_operand:SF 2 "register_operand" "r")))]
- "! TARGET_29050"
- "fmul %0,%1,%2"
- [(set_attr "type" "fmul")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r,a")
- (mult:SF (match_operand:SF 1 "register_operand" "%r,r")
- (match_operand:SF 2 "register_operand" "r,r")))]
- "TARGET_29050"
- "@
- fmul %0,%1,%2
- fmac 4,%0,%1,%2"
- [(set_attr "type" "fmul,fam")])
-
- ;; FSUB
- (define_expand "subsf3"
- [(set (match_operand:SF 0 "register_operand" "")
- (minus:SF (match_operand:SF 1 "register_operand" "")
- (match_operand:SF 2 "register_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "")
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r")
- (minus:SF (match_operand:SF 1 "register_operand" "r")
- (match_operand:SF 2 "register_operand" "r")))]
- "! TARGET_29050"
- "fsub %0,%1,%2"
- [(set_attr "type" "fadd")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=r,a,a")
- (minus:SF (match_operand:SF 1 "register_operand" "r,0,r")
- (match_operand:SF 2 "register_operand" "r,r,0")))]
- "TARGET_29050"
- "@
- fsub %0,%1,%2
- fmac 9,%0,%2,%2
- fmac 10,%0,%1,%1"
- [(set_attr "type" "fadd,fam,fam")])
-
- ;; INBYTE
- (define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
- (const_int 8)
- (ashift:PSI
- (match_operand:PSI 2 "register_operand" "b")
- (const_int 3)))
- (match_operand:SI 1 "srcb_operand" "rI"))]
- ""
- "inbyte %0,%0,%1")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (and:SI
- (not:SI
- (ashift:SI (const_int 255)
- (ashift:PSI
- (match_operand:PSI 3 "register_operand" "b")
- (const_int 3))))
- (match_operand:SI 1 "gpc_reg_operand" "r"))
- (ashift:SI (zero_extend:SI
- (match_operand:QI 2 "srcb_operand" "rI"))
- (ashift:PSI (match_dup 3) (const_int 3)))))]
- ""
- "inbyte %0,%1,%2")
-
- ;; INHW
- (define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
- (const_int 16)
- (ashift:PSI
- (match_operand:PSI 2 "register_operand" "b")
- (const_int 3)))
- (match_operand:SI 1 "srcb_operand" "rI"))]
- ""
- "inhw %0,%0,%1")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (and:SI
- (not:SI
- (ashift:SI (const_int 65535)
- (ashift:PSI
- (match_operand:PSI 3 "register_operand" "b")
- (const_int 3))))
- (match_operand:SI 1 "gpc_reg_operand" "r"))
- (ashift:SI (zero_extend:SI
- (match_operand:HI 2 "srcb_operand" "rI"))
- (ashift:PSI (match_dup 3) (const_int 3)))))]
- ""
- "inhw %0,%1,%2")
-
- (define_expand "insv"
- [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "")
- (match_operand:SI 1 "general_operand" "")
- (match_operand:SI 2 "general_operand" ""))
- (match_operand:SI 3 "srcb_operand" ""))]
- ""
- "
- {
- int size, pos;
-
- if (GET_CODE (operands[1]) != CONST_INT
- || GET_CODE (operands[2]) != CONST_INT)
- FAIL;
-
- size = INTVAL (operands[1]);
- pos = INTVAL (operands[2]);
- if ((size != 8 && size != 16) || pos % size != 0)
- FAIL;
-
- operands[2] = gen_rtx (ASHIFT, PSImode,
- force_reg (PSImode, GEN_INT (pos / 8)),
- GEN_INT (3));
- }")
-
- ;; LOAD (also used by move insn).
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int -4))))
- (set (match_operand:PSI 2 "register_operand" "=b")
- (truncate:PSI (match_dup 1)))]
- "! TARGET_DW_ENABLE"
- "load 0,16,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_DW_ENABLE"
- "load 0,1,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
- (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_DW_ENABLE"
- "load 0,1,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
- "TARGET_DW_ENABLE"
- "load 0,2,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))
- (clobber (match_scratch:PSI 2 "=&b"))]
- "TARGET_DW_ENABLE"
- "load 0,17,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
- (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))
- (clobber (match_scratch:PSI 2 "=&b"))]
- "TARGET_DW_ENABLE"
- "load 0,17,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))
- (clobber (match_scratch:PSI 2 "=&b"))]
- "TARGET_DW_ENABLE"
- "load 0,18,%0,%1"
- [(set_attr "type" "load")])
-
- ;; LOADM
- (define_expand "load_multiple"
- [(set (match_dup 4)
- (match_operand:PSI 2 "const_int_operand" ""))
- (match_par_dup 3 [(set (match_operand:SI 0 "" "")
- (match_operand:SI 1 "" ""))])]
- ""
- "
- {
- int regno;
- int count;
- rtx from;
- int i;
-
- /* Support only loading a constant number of hard registers from memory. */
- if (GET_CODE (operands[2]) != CONST_INT
- || operands[2] == const1_rtx
- || GET_CODE (operands[1]) != MEM
- || GET_CODE (operands[0]) != REG
- || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
- FAIL;
-
- count = INTVAL (operands[2]);
- regno = REGNO (operands[0]);
-
- /* CR gets set to the number of registers minus one. */
- operands[2] = GEN_INT(count - 1);
-
- operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 2));
- from = memory_address (SImode, XEXP (operands[1], 0));
- XVECEXP (operands[3], 0, 0) = gen_rtx (SET, VOIDmode,
- gen_rtx (REG, SImode, regno),
- gen_rtx (MEM, SImode, from));
- operands[4] = gen_reg_rtx (PSImode);
-
- XVECEXP (operands[3], 0, 1) = gen_rtx (USE, VOIDmode, operands[4]);
- XVECEXP (operands[3], 0, 2) = gen_rtx (CLOBBER, VOIDmode, operands[4]);
-
- for (i = 1; i < count; i++)
- XVECEXP (operands[3], 0, i + 2)
- = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno + i),
- gen_rtx (MEM, SImode, plus_constant (from, i * 4)));
- }")
-
- ;; Indicate that CR is used and is then clobbered.
- (define_insn ""
- [(set (match_operand 0 "gpc_reg_operand" "=r")
- (match_operand 1 "memory_operand" "m"))
- (use (match_operand:PSI 2 "register_operand" "+c"))
- (clobber (match_dup 2))]
- "GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD"
- "loadm 0,0,%0,%1"
- [(set_attr "type" "load")])
-
- (define_insn ""
- [(match_parallel 0 "load_multiple_operation"
- [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
- (match_operand:SI 2 "memory_operand" "m"))
- (use (match_operand:PSI 3 "register_operand" "+c"))
- (clobber (match_dup 3))])]
- ""
- "loadm 0,0,%1,%2"
- [(set_attr "type" "load")])
-
- ;; MTSR (used also by move insn)
- (define_insn ""
- [(set (match_operand:SI 0 "spec_reg_operand" "=*h,*h")
- (and:SI (match_operand:SI 1 "gpc_reg_or_immediate_operand" "r,i")
- (match_operand:SI 2 "const_int_operand" "n,n")))]
- "masks_bits_for_special (operands[0], operands[2])"
- "@
- mtsr %0,%1
- mtsrim %0,%1")
-
- (define_insn ""
- [(set (match_operand:PSI 0 "register_operand" "=h,h")
- (truncate:PSI
- (match_operand:SI 1 "gpc_reg_or_immediate_operand" "r,i")))]
- ""
- "@
- mtsr %0,%1
- mtsrim %0,%1")
-
- ;; MULTIPLY, MULTM, MULTMU
- (define_insn "mulsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r")))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multiply %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (subreg:SI
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))) 0))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multm %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (subreg:SI
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))) 0))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multmu %0,%1,%2")
-
- (define_insn "mulsidi3"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multiply %L0,%1,%2\;multm %0,%1,%2"
- [(set_attr "type" "multi")])
-
- (define_split
- [(set (match_operand:DI 0 "gpc_reg_operand" "")
- (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))
- (clobber (reg:SI 180))]
- "reload_completed"
- [(parallel [(set (match_dup 3)
- (mult:SI (match_dup 1) (match_dup 2)))
- (clobber (reg:SI 180))])
- (parallel [(set (match_dup 4)
- (subreg:SI (mult:DI
- (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2))) 0))
- (clobber (reg:SI 180))])]
- "
- { operands[3] = operand_subword (operands[0], 1, 1, DImode);
- operands[4] = operand_subword (operands[1], 0, 1, DImode); } ")
-
- (define_insn "umulsidi3"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multiplu %L0,%1,%2\;multmu %0,%1,%2"
- [(set_attr "type" "multi")])
-
- (define_split
- [(set (match_operand:DI 0 "gpc_reg_operand" "")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
- (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))
- (clobber (reg:SI 180))]
- "reload_completed"
- [(parallel [(set (match_dup 3)
- (mult:SI (match_dup 1) (match_dup 2)))
- (clobber (reg:SI 180))])
- (parallel [(set (match_dup 4)
- (subreg:SI (mult:DI (zero_extend:DI (match_dup 1))
- (zero_extend:DI (match_dup 2))) 0))
- (clobber (reg:SI 180))])]
- "
- { operands[3] = operand_subword (operands[0], 1, 1, DImode);
- operands[4] = operand_subword (operands[1], 0, 1, DImode); } ")
-
- (define_insn "smulsi3_highpart"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))
- (const_int 32))))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multm %0,%1,%2")
-
- (define_insn "umulsi3_highpart"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (truncate:SI
- (lshiftrt:DI
- (mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r")))
- (const_int 32))))
- (clobber (match_scratch:SI 3 "=&q"))]
- ""
- "multmu %0,%1,%2")
-
- ;; NAND
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
- ""
- "nand %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
- (match_operand:SI 2 "const_int_operand" "K")))]
- ; Match TARGET_29050 in "orn" pattern for slightly better reload.
- "! TARGET_29050 && ((unsigned) ~ INTVAL (operands[2])) < 256"
- "nand %0,%1,%C2")
-
- ;; NOR
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (and:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "%r"))
- (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
- ""
- "nor %0,%1,%2")
-
- (define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (not:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
- ""
- "nor %0,%1,0")
-
- ;; OR/ORN
- (define_expand "iorsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (match_operand:SI 2 "srcb_operand" "")))]
- ""
- "")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "srcb_operand" "rI")))]
- "! TARGET_29050"
- "or %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
- (match_operand:SI 2 "and_operand" "rI,K")))]
- "TARGET_29050"
- "@
- or %0,%1,%2
- orn %0,%1,%C2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (ior:SI (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
- (match_operand:SI 2 "cmplsrcb_operand" "r,K")))]
- "TARGET_29050"
- "@
- orn %0,%2,%1
- nand %0,%1,%C2")
-
-
- ;; SLL (also used by move insn)
- (define_insn "nop"
- [(const_int 0)]
- ""
- "aseq 0x40,gr1,gr1")
-
- (define_insn "ashlsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:QI 2 "srcb_operand" "rn")))]
- ""
- "sll %0,%1,%Q2")
-
- ;; SQRT
- (define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
- (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
- "TARGET_29050"
- "sqrt %0,%1,1"
- [(set_attr "type" "fsqrt")])
-
- (define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "gpc_reg_operand" "=r")
- (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "r")))]
- "TARGET_29050"
- "sqrt %0,%1,2"
- [(set_attr "type" "dsqrt")])
-
- ;; SRA
- (define_insn "ashrsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:QI 2 "srcb_operand" "rn")))]
- ""
- "sra %0,%1,%Q2")
-
- ;; SRL
- (define_insn "lshrsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand:QI 2 "srcb_operand" "rn")))]
- ""
- "srl %0,%1,%Q2")
-
- ;; STORE
- ;;
- ;; These somewhat bogus patterns exist to set OPT = 001/010 for partial-word
- ;; stores on systems with DW not set.
- (define_insn ""
- [(set (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "r")
- (const_int -4)))
- (match_operand:SI 1 "gpc_reg_operand" "r"))]
- "! TARGET_DW_ENABLE"
- "store 0,1,%1,%0"
- [(set_attr "type" "store")])
-
- (define_insn ""
- [(set (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "r")
- (const_int -3)))
- (match_operand:SI 1 "gpc_reg_operand" "r"))]
- "! TARGET_DW_ENABLE"
- "store 0,2,%1,%0"
- [(set_attr "type" "store")])
-
- ;; STOREM
- (define_expand "store_multiple"
- [(use (match_operand 0 "" ""))
- (use (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))]
- ""
- "
- { rtx pat;
-
- if (TARGET_NO_STOREM_BUG)
- pat = gen_store_multiple_no_bug (operands[0], operands[1], operands[2]);
- else
- pat = gen_store_multiple_bug (operands[0], operands[1], operands[2]);
-
- if (pat)
- emit_insn (pat);
- else
- FAIL;
-
- DONE;
- }")
-
- (define_expand "store_multiple_no_bug"
- [(set (match_dup 4)
- (match_operand:PSI 2 "const_int_operand" ""))
- (match_par_dup 3 [(set (match_operand:SI 0 "" "")
- (match_operand:SI 1 "" ""))])]
- ""
- "
- {
- int regno;
- int count;
- rtx from;
- int i;
-
- /* Support only storing a constant number of hard registers to memory. */
- if (GET_CODE (operands[2]) != CONST_INT
- || operands[2] == const1_rtx
- || GET_CODE (operands[0]) != MEM
- || GET_CODE (operands[1]) != REG
- || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
- FAIL;
-
- count = INTVAL (operands[2]);
- regno = REGNO (operands[1]);
-
- /* CR gets set to the number of registers minus one. */
- operands[2] = GEN_INT(count - 1);
-
- operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 2));
- from = memory_address (SImode, XEXP (operands[0], 0));
- XVECEXP (operands[3], 0, 0) = gen_rtx (SET, VOIDmode,
- gen_rtx (MEM, SImode, from),
- gen_rtx (REG, SImode, regno));
- operands[4] = gen_reg_rtx (PSImode);
- XVECEXP (operands[3], 0, 1) = gen_rtx (USE, VOIDmode, operands[4]);
- XVECEXP (operands[3], 0, 2) = gen_rtx (CLOBBER, VOIDmode, operands[4]);
-
- for (i = 1; i < count; i++)
- XVECEXP (operands[3], 0, i + 2)
- = gen_rtx (SET, VOIDmode,
- gen_rtx (MEM, SImode, plus_constant (from, i * 4)),
- gen_rtx (REG, SImode, regno + i));
- }")
-
- (define_expand "store_multiple_bug"
- [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
- (match_operand:SI 1 "" ""))
- (use (match_operand:SI 2 "" ""))])]
- ""
- "
- {
- int regno;
- int count;
- rtx from;
- int i;
-
- /* Support only storing a constant number of hard registers to memory. */
- if (GET_CODE (operands[2]) != CONST_INT
- || operands[2] == const1_rtx
- || GET_CODE (operands[0]) != MEM
- || GET_CODE (operands[1]) != REG
- || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
- FAIL;
-
- count = INTVAL (operands[2]);
- regno = REGNO (operands[1]);
-
- operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 1));
- from = memory_address (SImode, XEXP (operands[0], 0));
- XVECEXP (operands[3], 0, 0) = gen_rtx (SET, VOIDmode,
- gen_rtx (MEM, SImode, from),
- gen_rtx (REG, SImode, regno));
- XVECEXP (operands[3], 0, 1)
- = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, PSImode));
-
- for (i = 1; i < count; i++)
- XVECEXP (operands[3], 0, i + 1)
- = gen_rtx (SET, VOIDmode,
- gen_rtx (MEM, SImode, plus_constant (from, i * 4)),
- gen_rtx (REG, SImode, regno + i));
- }")
-
- (define_insn ""
- [(set (match_operand 0 "memory_operand" "=m")
- (match_operand 1 "gpc_reg_operand" "r"))
- (clobber (match_scratch:PSI 2 "=&c"))]
- "!TARGET_NO_STOREM_BUG
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD"
- "mtsrim cr,%S1\;storem 0,0,%1,%0"
- [(set_attr "type" "multi")])
-
- (define_insn ""
- [(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:SI 1 "memory_operand" "=m")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
- (clobber (match_scratch:PSI 3 "=&c"))])]
- "!TARGET_NO_STOREM_BUG"
- "mtsrim cr,%V0\;storem 0,0,%2,%1"
- [(set_attr "type" "multi")])
-
- (define_insn ""
- [(set (match_operand 0 "memory_operand" "=m")
- (match_operand 1 "gpc_reg_operand" "r"))
- (use (match_operand:PSI 2 "register_operand" "+c"))
- (clobber (match_dup 2))]
- "TARGET_NO_STOREM_BUG
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD"
- "storem 0,0,%1,%0"
- [(set_attr "type" "store")])
-
- (define_insn ""
- [(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:SI 1 "memory_operand" "=m")
- (match_operand:SI 2 "gpc_reg_operand" "r"))
- (use (match_operand:PSI 3 "register_operand" "+c"))
- (clobber (match_dup 3))])]
- "TARGET_NO_STOREM_BUG"
- "storem 0,0,%2,%1"
- [(set_attr "type" "store")])
-
- ;; SUB
- ;;
- ;; Either operand can be a register or an 8-bit constant, but both cannot be
- ;; constants (can't usually occur anyway).
- (define_expand "subsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (minus:SI (match_operand:SI 1 "srcb_operand" "")
- (match_operand:SI 2 "srcb_operand" "")))]
- ""
- "
- {
- if (GET_CODE (operands[0]) == CONST_INT
- && GET_CODE (operands[1]) == CONST_INT)
- operands[1] = force_reg (SImode, operands[1]);
- }")
-
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "srcb_operand" "r,I")
- (match_operand:SI 2 "srcb_operand" "rI,r")))]
- "register_operand (operands[1], SImode)
- || register_operand (operands[2], SImode)"
- "@
- sub %0,%1,%2
- subr %0,%2,%1")
-
- (define_insn "subdi3"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (minus:DI (match_operand:DI 1 "gpc_reg_operand" "r")
- (match_operand:DI 2 "gpc_reg_operand" "r")))]
- ""
- "sub %L0,%L1,%L2\;subc %0,%1,%2"
- [(set_attr "type" "multi")])
-
- ;; SUBR (also used above in SUB)
- (define_insn "negdi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
- ""
- "subr %L0,%L1,0\;subrc %0,%1,0"
- [(set_attr "type" "multi")])
-
- (define_insn "negsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
- ""
- "subr %0,%1,0")
-
- ;; XNOR
- (define_insn ""
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (not:SI (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
- (match_operand:SI 2 "gpc_reg_operand" "r"))))]
- ""
- "xnor %0,%1,%2")
-
- ;; XOR
-
- (define_insn "xorsi3"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
- (match_operand:SI 2 "and_operand" "rI,K")))]
- ""
- "@
- xor %0,%1,%2
- xnor %0,%1,%C2")
-
- ;; Can use XOR to negate floating-point values, but we are better off not doing
- ;; it that way on the 29050 so it can combine with the fmac insns.
- (define_expand "negsf2"
- [(parallel [(set (match_operand:SF 0 "register_operand" "")
- (neg:SF (match_operand:SF 1 "register_operand" "")))
- (clobber (match_scratch:SI 2 ""))])]
- "! TARGET_SOFT_FLOAT"
- "
- {
- rtx result;
- rtx target;
-
- if (! TARGET_29050)
- {
- target = operand_subword_force (operands[0], 0, SFmode);
- result = expand_binop (SImode, xor_optab,
- operand_subword_force (operands[1], 0, SFmode),
- GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
- if (result == 0)
- abort ();
-
- if (result != target)
- emit_move_insn (result, target);
-
- /* Make a place for REG_EQUAL. */
- emit_move_insn (operands[0], operands[0]);
- DONE;
- }
- }")
-
- (define_expand "negdf2"
- [(parallel [(set (match_operand:DF 0 "register_operand" "")
- (neg:DF (match_operand:DF 1 "register_operand" "")))
- (clobber (match_scratch:SI 2 ""))])]
- "! TARGET_SOFT_FLOAT"
- "
- {
- rtx result;
- rtx target;
- rtx insns;
-
- if (! TARGET_29050)
- {
- start_sequence ();
- target = operand_subword (operands[0], 0, 1, DFmode);
- result = expand_binop (SImode, xor_optab,
- operand_subword_force (operands[1], 0, DFmode),
- GEN_INT(0x80000000), target, 0, OPTAB_WIDEN);
- if (result == 0)
- abort ();
-
- if (result != target)
- emit_move_insn (result, target);
-
- emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
- operand_subword_force (operands[1], 1, DFmode));
-
- insns = get_insns ();
- end_sequence ();
-
- emit_no_conflict_block (insns, operands[0], operands[1], 0, 0);
- DONE;
- }
- }")
-
- ;; Sign extend and truncation operations.
- (define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
- (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
- ""
- "and %0,%1,255")
-
- (define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
- ""
- "and %0,%1,255")
-
- (define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0")))]
- ""
- "consth %0,0")
-
- (define_expand "extendqihi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
- (const_int 24)))
- (set (match_operand:HI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))]
- ""
- "
- { operands[0] = gen_lowpart (SImode, operands[0]);
- operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- (define_expand "extendqisi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
- (const_int 24)))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 24)))]
- ""
- "
- { operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- (define_expand "extendhisi2"
- [(set (match_dup 2)
- (ashift:SI (match_operand:HI 1 "gpc_reg_operand" "")
- (const_int 16)))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (ashiftrt:SI (match_dup 2)
- (const_int 16)))]
- ""
- "
- { operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_reg_rtx (SImode); }")
-
- ;; Define the methods used to move data around.
- ;;
- ;; movsi:
- ;;
- ;; If storing into memory, force source into register.
- (define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
- ""
- "
- {
- if (GET_CODE (operands[0]) == MEM && ! gpc_reg_operand (operands[1], SImode))
- operands[1] = copy_to_mode_reg (SImode, operands[1]);
- else if (spec_reg_operand (operands[0], SImode)
- && ! (register_operand (operands[1], SImode)
- || cint_16_operand (operands[1], SImode)))
- operands[1] = force_reg (SImode, operands[1]);
- }")
-
- (define_expand "movpsi"
- [(set (match_operand:PSI 0 "general_operand" "")
- (match_operand:PSI 1 "general_operand" ""))]
- ""
- "
- {
- if (GET_CODE (operands[0]) == MEM
- && ! gpc_reg_operand (operands[1], PSImode))
- operands[1] = copy_to_mode_reg (PSImode, operands[1]);
- else if (spec_reg_operand (operands[0], PSImode)
- && ! (register_operand (operands[1], PSImode)
- || cint_16_operand (operands[1], PSImode)))
- operands[1] = force_reg (PSImode, operands[1]);
- }")
-
- (define_split
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (match_operand:SI 1 "long_const_operand" ""))]
- ""
- [(set (match_dup 0)
- (and:SI (match_dup 1)
- (const_int 65535)))
- (set (match_dup 0)
- (ior:SI (zero_extend:SI (match_dup 2))
- (and:SI (match_dup 1)
- (const_int -65536))))]
- " operands[2] = gen_lowpart (HImode, operands[0]); ")
-
- ;; Subroutines to load/store halfwords. Operands 0 and 1 are the output and
- ;; input, respectively, except that the address is passed for a MEM instead
- ;; of the MEM itself and the short item is passed in QImode.
- ;;
- ;; Operand 2 is a scratch general register and operand 3 is a scratch register
- ;; used for BP. When called before reload, pseudos are passed for both
- ;; operands. During reload, R_TAV is used for the general register, and
- ;; a reload register of class BR_REGS (R_VP) for BP.
- ;;
- ;; We have two versions of the store operations, for when halfword writes are
- ;; supported and when they are not.
- (define_expand "loadhi"
- [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
- (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (const_int -4))))
- (set (match_operand:PSI 3 "register_operand" "")
- (truncate:PSI (match_dup 1)))])
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (zero_extract:SI (match_dup 2)
- (const_int 16)
- (ashift:PSI (match_dup 3) (const_int 3))))]
- ""
- "")
-
- (define_expand "storehinhww"
- [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
- (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "")
- (const_int -4))))
- (set (match_operand:PSI 3 "register_operand" "")
- (truncate:PSI (match_dup 0)))])
- (set (zero_extract:SI (match_dup 2)
- (const_int 16)
- (ashift:PSI (match_dup 3) (const_int 3)))
- (match_operand:SI 1 "gpc_reg_operand" ""))
- (set (mem:SI (match_dup 0))
- (match_dup 2))]
- ""
- "")
-
- (define_expand "storehihww"
- [(set (match_operand:PSI 3 "register_operand" "")
- (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" "")))
- (set (match_operand:SI 2 "gpc_reg_operand" "")
- (ior:SI (and:SI (not:SI (ashift:SI (const_int 65535)
- (ashift:PSI (match_dup 3)
- (const_int 3))))
- (match_operand:SI 1 "gpc_reg_operand" ""))
- (ashift:SI (zero_extend:SI (match_dup 4))
- (ashift:PSI (match_dup 3) (const_int 3)))))
- (set (mem:SI (and:SI (match_dup 0)
- (const_int -3)))
- (match_dup 2))]
- ""
- "
- { operands[4] = gen_lowpart (HImode, operands[1]); }")
-
- (define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
- "
- { if (GET_CODE (operands[0]) == MEM)
- {
- if (! gpc_reg_operand (operands[1], HImode))
- operands[1] = copy_to_mode_reg (HImode, operands[1]);
- if (! TARGET_DW_ENABLE)
- {
- rtx general = gen_reg_rtx (SImode);
- rtx bp = gen_reg_rtx (PSImode);
- rtx (*fcn) ()
- = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww;
- rtx seq = (*fcn) (XEXP (operands[0], 0),
- gen_lowpart (SImode, operands[1]),
- general, bp);
-
- a29k_set_memflags (seq, operands[0]);
- emit_insn (seq);
- DONE;
- }
- }
- else if (GET_CODE (operands[1]) == MEM)
- {
- if (! TARGET_DW_ENABLE)
- {
- rtx general = gen_reg_rtx (SImode);
- rtx bp = gen_reg_rtx (PSImode);
- rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]),
- XEXP (operands[1], 0), general, bp);
-
- a29k_set_memflags (seq, operands[1]);
- emit_insn (seq);
- DONE;
- }
- }
- }")
-
- (define_expand "reload_inhi"
- [(parallel [(match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "reload_memory_operand" "m")
- (match_operand:PSI 2 "register_operand" "=b")])]
- "! TARGET_DW_ENABLE"
- "
- { rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]),
- a29k_get_reloaded_address (operands[1]),
- gen_rtx (REG, SImode, R_TAV),
- operands[2]);
-
- a29k_set_memflags (seq, operands[1]);
- emit_insn (seq);
- DONE;
- }")
-
- (define_expand "reload_outhi"
- [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m")
- (match_operand:SI 1 "register_operand" "m")
- (match_operand:PSI 2 "register_operand" "=b")])]
- "! TARGET_DW_ENABLE"
- "
- { rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww;
- rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]),
- gen_lowpart (SImode, operands[1]),
- gen_rtx (REG, SImode, R_TAV), operands[2]);
-
- a29k_set_memflags (seq, operands[0]);
- emit_insn (seq);
- DONE;
- }")
-
- ;; Subroutines to load/store bytes. Operands 0 and 1 are the output and
- ;; input, respectively, except that the address is passed for a MEM instead
- ;; of the MEM itself and the short item is passed in QImode.
- ;;
- ;; Operand 2 is a scratch general register and operand 3 is a scratch register
- ;; used for BP. When called before reload, pseudos are passed for both
- ;; operands. During reload, R_TAV is used for the general register, and
- ;; a reload register of class BR_REGS (R_VP) for BP.
- ;;
- ;; We have two versions of the store operations, for when byte writes are
- ;; supported and when they are not.
- (define_expand "loadqi"
- [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
- (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
- (const_int -4))))
- (set (match_operand:PSI 3 "register_operand" "")
- (truncate:PSI (match_dup 1)))])
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (zero_extract:SI (match_dup 2)
- (const_int 8)
- (ashift:PSI (match_dup 3) (const_int 3))))]
- ""
- "")
-
- (define_expand "storeqinhww"
- [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "")
- (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "")
- (const_int -4))))
- (set (match_operand:PSI 3 "register_operand" "")
- (truncate:PSI (match_dup 0)))])
- (set (zero_extract:SI (match_dup 2)
- (const_int 8)
- (ashift:PSI (match_dup 3)
- (const_int 3)))
- (match_operand:SI 1 "gpc_reg_operand" ""))
- (set (mem:SI (match_dup 0))
- (match_dup 2))]
- ""
- "")
-
- (define_expand "storeqihww"
- [(set (match_operand:PSI 3 "register_operand" "")
- (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" "")))
- (set (match_operand:SI 2 "gpc_reg_operand" "")
- (ior:SI (and:SI (not:SI (ashift:SI (const_int 255)
- (ashift:PSI (match_dup 3)
- (const_int 3))))
- (match_operand:SI 1 "gpc_reg_operand" ""))
- (ashift:SI (zero_extend:SI (match_dup 4))
- (ashift:PSI (match_dup 3)
- (const_int 3)))))
- (set (mem:SI (and:SI (match_dup 0)
- (const_int -4)))
- (match_dup 2))]
- ""
- "
- { operands[4] = gen_lowpart (QImode, operands[1]); }")
-
- (define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
- ""
- "
- { if (GET_CODE (operands[0]) == MEM)
- {
- if (! gpc_reg_operand (operands[1], QImode))
- operands[1] = copy_to_mode_reg (QImode, operands[1]);
- if (! TARGET_DW_ENABLE)
- {
- rtx general = gen_reg_rtx (SImode);
- rtx bp = gen_reg_rtx (PSImode);
- rtx (*fcn) ()
- = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww;
- rtx seq = (*fcn) (XEXP (operands[0], 0),
- gen_lowpart (SImode, operands[1]),
- general, bp);
-
- a29k_set_memflags (seq, operands[0]);
- emit_insn (seq);
- DONE;
- }
- }
- else if (GET_CODE (operands[1]) == MEM)
- {
- if (! TARGET_DW_ENABLE)
- {
- rtx general = gen_reg_rtx (SImode);
- rtx bp = gen_reg_rtx (PSImode);
- rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]),
- XEXP (operands[1], 0), general, bp);
-
- a29k_set_memflags (seq, operands[1]);
- emit_insn (seq);
- DONE;
- }
- }
- }")
-
- (define_expand "reload_inqi"
- [(parallel [(match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "reload_memory_operand" "m")
- (match_operand:PSI 2 "register_operand" "=b")])]
- "! TARGET_DW_ENABLE"
- "
- { rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]),
- a29k_get_reloaded_address (operands[1]),
- gen_rtx (REG, SImode, R_TAV),
- operands[2]);
-
- a29k_set_memflags (seq, operands[1]);
- emit_insn (seq);
- DONE;
- }")
-
- (define_expand "reload_outqi"
- [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m")
- (match_operand:SI 1 "register_operand" "m")
- (match_operand:PSI 2 "register_operand" "=b")])]
- "! TARGET_DW_ENABLE"
- "
- { rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww;
- rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]),
- gen_lowpart (SImode, operands[1]),
- gen_rtx (REG, SImode, R_TAV), operands[2]);
-
- a29k_set_memflags (seq, operands[0]);
- emit_insn (seq);
- DONE;
- }")
-
- ;; Now the actual insns used to move data around. We include here the
- ;; DEFINE_SPLITs that may be needed. In some cases these will be
- ;; split again. For floating-point, if we can look inside the constant,
- ;; always split it. This can eliminate unnecessary insns.
- (define_insn ""
- [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m")
- (match_operand:SF 1 "in_operand" "r,E,F,m,r"))]
- "(gpc_reg_operand (operands[0], SFmode)
- || gpc_reg_operand (operands[1], SFmode))
- && ! TARGET_29050"
- "@
- sll %0,%1,0
- #
- const %0,%1\;consth %0,%1
- load 0,0,%0,%1
- store 0,0,%1,%0"
- [(set_attr "type" "misc,multi,multi,load,store")])
-
- (define_insn ""
- [(set (match_operand:SF 0 "out_operand" "=r,r,r,r,m,*a,r")
- (match_operand:SF 1 "in_operand" "r,E,F,m,r,r,*a"))]
- "(gpc_reg_operand (operands[0], SFmode)
- || gpc_reg_operand (operands[1], SFmode))
- && TARGET_29050"
- "@
- sll %0,%1,0
- #
- const %0,%1\;consth %0,%1
- load 0,0,%0,%1
- store 0,0,%1,%0
- mtacc %1,1,%0
- mfacc %0,1,%1"
- [(set_attr "type" "misc,multi,multi,load,store,fadd,fadd")])
-
- ;; Turn this into SImode. It will then be split up that way.
- (define_split
- [(set (match_operand:SF 0 "register_operand" "")
- (match_operand:SF 1 "float_const_operand" ""))]
- "HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT"
- [(set (match_dup 0)
- (match_dup 1))]
- "
- { operands[0] = operand_subword (operands[0], 0, 0, SFmode);
- operands[1] = operand_subword (operands[1], 0, 0, SFmode);
-
- if (operands[0] == 0 || operands[1] == 0)
- FAIL;
- }")
-
- (define_insn ""
- [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m")
- (match_operand:DF 1 "in_operand" "rE,F,m,r"))
- (clobber (match_scratch:PSI 2 "=X,X,&c,&c"))]
- "(gpc_reg_operand (operands[0], DFmode)
- || gpc_reg_operand (operands[1], DFmode))
- && ! TARGET_29050"
- "@
- #
- const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1
- mtsrim cr,1\;loadm 0,0,%0,%1
- mtsrim cr,1\;storem 0,0,%1,%0"
- [(set_attr "type" "multi")])
-
- (define_insn ""
- [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m,?*a,?r")
- (match_operand:DF 1 "in_operand" "rE,F,m,r,r,*a"))
- (clobber (match_scratch:PSI 2 "=X,X,&c,&c,X,X"))]
- "(gpc_reg_operand (operands[0], DFmode)
- || gpc_reg_operand (operands[1], DFmode))
- && TARGET_29050"
- "@
- #
- const %0,%1\;consth %0,%1\;const %L0,%L1\;consth %L0,%L1
- mtsrim cr,1\;loadm 0,0,%0,%1
- mtsrim cr,1\;storem 0,0,%1,%0
- mtacc %1,2,%0
- mfacc %0,2,%1"
- [(set_attr "type" "multi,multi,multi,multi,fadd,fadd")])
-
- ;; Split register-register copies and constant loads into two SImode loads,
- ;; one for each word. In the constant case, they will get further split.
- ;; Don't so this until register allocation, though, since it will
- ;; interfere with register allocation. Normally copy the lowest-addressed
- ;; word first; the exception is if we are copying register to register and
- ;; the lowest register of the first operand is the highest register of the
- ;; second operand.
- (define_split
- [(set (match_operand:DF 0 "gpc_reg_operand" "")
- (match_operand:DF 1 "gpc_reg_or_float_constant_operand" ""))
- (clobber (match_scratch:PSI 2 ""))]
- "reload_completed"
- [(set (match_dup 3) (match_dup 4))
- (set (match_dup 5) (match_dup 6))]
- "
- { if (GET_CODE (operands[1]) == REG
- && REGNO (operands[0]) == REGNO (operands[1]) + 1)
- {
- operands[3] = operand_subword (operands[0], 1, 1, DFmode);
- operands[4] = operand_subword (operands[1], 1, 1, DFmode);
- operands[5] = operand_subword (operands[0], 0, 1, DFmode);
- operands[6] = operand_subword (operands[1], 0, 1, DFmode);
- }
- else
- {
- operands[3] = operand_subword (operands[0], 0, 1, DFmode);
- operands[4] = operand_subword (operands[1], 0, 1, DFmode);
- operands[5] = operand_subword (operands[0], 1, 1, DFmode);
- operands[6] = operand_subword (operands[1], 1, 1, DFmode);
- }
-
- if (operands[3] == 0 || operands[4] == 0
- || operands[5] == 0 || operands[6] == 0)
- FAIL;
- }")
-
- ;; Split memory loads and stores into the MTSR and LOADM/STOREM.
- (define_split
- [(set (match_operand:DF 0 "out_operand" "")
- (match_operand:DF 1 "in_operand" ""))
- (clobber (reg:PSI 179))]
- "TARGET_NO_STOREM_BUG
- && (memory_operand (operands[0], DFmode)
- || memory_operand (operands[1], DFmode))"
- [(set (reg:PSI 179) (const_int 1))
- (parallel [(set (match_dup 0) (match_dup 1))
- (use (reg:PSI 179))
- (clobber (reg:PSI 179))])]
- "")
-
- ;; DI move is similar to DF move.
- (define_insn ""
- [(set (match_operand:DI 0 "out_operand" "=?r,r,m")
- (match_operand:DI 1 "in_operand" "rn,m,r"))
- (clobber (match_scratch:PSI 2 "=X,&c,&c"))]
- "(gpc_reg_operand (operands[0], DImode)
- || gpc_reg_operand (operands[1], DImode))"
- "@
- #
- mtsrim cr,1\;loadm 0,0,%0,%1
- mtsrim cr,1\;storem 0,0,%1,%0"
- [(set_attr "type" "multi")])
-
- (define_split
- [(set (match_operand:DI 0 "gpc_reg_operand" "")
- (match_operand:DI 1 "gpc_reg_or_integer_constant_operand" ""))
- (clobber (match_scratch:PSI 2 ""))]
- "reload_completed"
- [(set (match_dup 3) (match_dup 4))
- (set (match_dup 5) (match_dup 6))]
- "
- { if (GET_CODE (operands[1]) == REG
- && REGNO (operands[0]) == REGNO (operands[1]) + 1)
- {
- operands[3] = operand_subword (operands[0], 1, 1, DImode);
- operands[4] = operand_subword (operands[1], 1, 1, DImode);
- operands[5] = operand_subword (operands[0], 0, 1, DImode);
- operands[6] = operand_subword (operands[1], 0, 1, DImode);
- }
- else
- {
- operands[3] = operand_subword (operands[0], 0, 1, DImode);
- operands[4] = operand_subword (operands[1], 0, 1, DImode);
- operands[5] = operand_subword (operands[0], 1, 1, DImode);
- operands[6] = operand_subword (operands[1], 1, 1, DImode);
- }
- }")
-
- (define_split
- [(set (match_operand:DI 0 "out_operand" "")
- (match_operand:DI 1 "in_operand" ""))
- (clobber (reg:PSI 179))]
- "TARGET_NO_STOREM_BUG
- && (memory_operand (operands[0], DImode)
- || memory_operand (operands[1], DImode))"
- [(set (reg:PSI 179) (const_int 1))
- (parallel [(set (match_dup 0) (match_dup 1))
- (use (reg:PSI 179))
- (clobber (reg:PSI 179))])]
- "")
-
- ;; TImode moves are very similar to DImode moves, except that we can't
- ;; have constants.
- (define_insn ""
- [(set (match_operand:TI 0 "out_operand" "=?r,r,m")
- (match_operand:TI 1 "in_operand" "r,m,r"))
- (clobber (match_scratch:PSI 2 "=X,&c,&c"))]
- "(gpc_reg_operand (operands[0], TImode)
- || gpc_reg_operand (operands[1], TImode))"
- "@
- #
- mtsrim cr,3\;loadm 0,0,%0,%1
- mtsrim cr,3\;storem 0,0,%1,%0"
- [(set_attr "type" "multi,multi,multi")])
-
- (define_split
- [(set (match_operand:TI 0 "gpc_reg_operand" "")
- (match_operand:TI 1 "gpc_reg_operand" ""))
- (clobber (match_scratch:PSI 2 ""))]
- "reload_completed"
- [(set (match_dup 3) (match_dup 4))
- (set (match_dup 5) (match_dup 6))
- (set (match_dup 7) (match_dup 8))
- (set (match_dup 9) (match_dup 10))]
- "
- {
- if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
- && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
- {
- operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 3);
- operands[4] = gen_rtx (REG, SImode, REGNO (operands[1]) + 3);
- operands[5] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
- operands[6] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
- operands[7] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- operands[8] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
- operands[9] = gen_rtx (REG, SImode, REGNO (operands[0]));
- operands[10] = gen_rtx (REG, SImode, REGNO (operands[1]));
- }
- else
- {
- operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]));
- operands[4] = gen_rtx (REG, SImode, REGNO (operands[1]));
- operands[5] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
- operands[6] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
- operands[7] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2);
- operands[8] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2);
- operands[9] = gen_rtx (REG, SImode, REGNO (operands[0]) + 3);
- operands[10] = gen_rtx (REG, SImode, REGNO (operands[1]) + 3);
- }
- }")
-
- (define_split
- [(set (match_operand:TI 0 "out_operand" "")
- (match_operand:TI 1 "in_operand" ""))
- (clobber (reg:PSI 179))]
- "TARGET_NO_STOREM_BUG
- && (memory_operand (operands[0], TImode)
- || memory_operand (operands[1], TImode))"
- [(set (reg:PSI 179) (const_int 3))
- (parallel [(set (match_dup 0) (match_dup 1))
- (use (reg:PSI 179))
- (clobber (reg:PSI 179))])]
- "")
-
- (define_insn ""
- [(set (match_operand:SI 0 "out_operand" "=r,r,r,r,r,r,r,m,*h,*h")
- (match_operand:SI 1 "in_operand" "r,J,M,O,i,m,*h,r,r,J"))]
- "(gpc_reg_operand (operands[0], SImode)
- || gpc_reg_operand (operands[1], SImode)
- || (spec_reg_operand (operands[0], SImode)
- && cint_16_operand (operands[1], SImode)))
- && ! TARGET_29050"
- "@
- sll %0,%1,0
- const %0,%1
- constn %0,%M1
- cpeq %0,gr1,gr1
- #
- load 0,0,%0,%1
- mfsr %0,%1
- store 0,0,%1,%0
- mtsr %0,%1
- mtsrim %0,%1"
- [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")])
-
- (define_insn ""
- [(set (match_operand:SI 0 "out_operand" "=r,r,r,r,r,r,r,m,*h,*h")
- (match_operand:SI 1 "in_operand" "r,J,M,O,i,m,*h,r,r,J"))]
- "(gpc_reg_operand (operands[0], SImode)
- || gpc_reg_operand (operands[1], SImode)
- || (spec_reg_operand (operands[0], SImode)
- && cint_16_operand (operands[1], SImode)))
- && TARGET_29050"
- "@
- sll %0,%1,0
- const %0,%1
- constn %0,%M1
- consthz %0,%1
- #
- load 0,0,%0,%1
- mfsr %0,%1
- store 0,0,%1,%0
- mtsr %0,%1
- mtsrim %0,%1"
- [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")])
-
- (define_insn ""
- [(set (match_operand:PSI 0 "out_operand" "=*r,*r,*r,*r,m,h,h")
- (match_operand:PSI 1 "in_operand" "r,i,m,h,r,r,J"))]
- "(gpc_reg_operand (operands[0], PSImode)
- || gpc_reg_operand (operands[1], PSImode)
- || (spec_reg_operand (operands[0], PSImode)
- && cint_16_operand (operands[1], PSImode)))"
- "@
- sll %0,%1,0
- const %0,%1
- load 0,0,%0,%1
- mfsr %0,%1
- store 0,0,%1,%0
- mtsr %0,%1
- mtsrim %0,%1"
- [(set_attr "type" "misc,multi,load,misc,store,misc,misc")])
-
- (define_insn ""
- [(set (match_operand:HI 0 "out_operand" "=r,r,r,m,r,*h,*h")
- (match_operand:HI 1 "in_operand" "r,i,m,r,*h,r,i"))]
- "gpc_reg_operand (operands[0], HImode)
- || gpc_reg_operand (operands[1], HImode)
- || (spec_reg_operand (operands[0], HImode)
- && cint_16_operand (operands[1], HImode))"
- "@
- sll %0,%1,0
- const %0,%1
- load 0,2,%0,%1
- store 0,2,%1,%0
- mfsr %0,%1
- mtsr %0,%1
- mtsrim %0,%1"
- [(set_attr "type" "misc,misc,load,store,misc,misc,misc")])
-
- (define_insn ""
- [(set (match_operand:QI 0 "out_operand" "=r,r,r,m,r,*h,*h")
- (match_operand:QI 1 "in_operand" "r,i,m,r,*h,r,i"))]
- "gpc_reg_operand (operands[0], QImode)
- || gpc_reg_operand (operands[1], QImode)
- || (spec_reg_operand (operands[0], HImode)
- && cint_16_operand (operands[1], HImode))"
- "@
- sll %0,%1,0
- const %0,%1
- load 0,1,%0,%1
- store 0,1,%1,%0
- mfsr %0,%1
- mtsr %0,%1
- mtsrim %0,%1"
- [(set_attr "type" "misc,misc,load,store,misc,misc,misc")])
-
- ;; Define move insns for DI, TI, SF, and DF.
- ;;
- ;; In no case do we support mem->mem directly.
- ;;
- ;; For DI move of constant to register, split apart at this time since these
- ;; can require anywhere from 2 to 4 insns and determining which is complex.
- ;;
- ;; In other cases, handle similarly to SImode moves.
- ;;
- ;; However, indicate that DI, TI, and DF moves may clobber CR (reg 179).
- (define_expand "movdi"
- [(parallel [(set (match_operand:DI 0 "general_operand" "")
- (match_operand:DI 1 "general_operand" ""))
- (clobber (scratch:PSI))])]
- ""
- "
- {
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (DImode, operands[1]);
- }")
-
- (define_expand "movsf"
- [(set (match_operand:SF 0 "general_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
- ""
- "
- { if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (SFmode, operands[1]);
- }")
-
- (define_expand "movdf"
- [(parallel [(set (match_operand:DF 0 "general_operand" "")
- (match_operand:DF 1 "general_operand" ""))
- (clobber (scratch:PSI))])]
- ""
- "
- { if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (DFmode, operands[1]);
- }")
-
- (define_expand "movti"
- [(parallel [(set (match_operand:TI 0 "general_operand" "")
- (match_operand:TI 1 "general_operand" ""))
- (clobber (scratch:PSI))])]
- ""
- "
- {
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (TImode, operands[1]);
-
- /* We can't handle constants in general because there is no rtl to represent
- 128 bit constants. Splitting happens to work for CONST_INTs so we split
- them for good code. Other constants will get forced to memory. */
-
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- rtx part0, part1, part2, part3;
-
- part0 = operand_subword (operands[0], 0, 1, TImode);
- part1 = operand_subword (operands[0], 1, 1, TImode);
- part2 = operand_subword (operands[0], 2, 1, TImode);
- part3 = operand_subword (operands[0], 3, 1, TImode);
-
- emit_move_insn (part0, const0_rtx);
- emit_move_insn (part1, const0_rtx);
- emit_move_insn (part2, const0_rtx);
- emit_move_insn (part3, const0_rtx);
-
- DONE;
- }
- else if (CONSTANT_P (operands[1]))
- {
- operands[1] = force_const_mem (TImode, operands[1]);
- if (! memory_address_p (TImode, XEXP (operands[1], 0))
- && ! reload_in_progress)
- operands[1] = change_address (operands[1], TImode,
- XEXP (operands[1], 0));
- }
- }")
-
- ;; Here are the variants of the above for use during reload.
-
- (define_expand "reload_indf"
- [(parallel [(set (match_operand:DF 0 "register_operand" "=r")
- (match_operand:DF 1 "reload_memory_operand" "m"))
- (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
- ""
- "")
-
- (define_expand "reload_outdf"
- [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=m")
- (match_operand:DF 1 "register_operand" "r"))
- (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
- ""
- "")
-
- (define_expand "reload_indi"
- [(parallel [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "reload_memory_operand" "m"))
- (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
- ""
- "")
-
- (define_expand "reload_outdi"
- [(parallel [(set (match_operand:DI 0 "reload_memory_operand" "=m")
- (match_operand:DI 1 "register_operand" "r"))
- (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
- ""
- "")
-
- (define_expand "reload_inti"
- [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
- (match_operand:TI 1 "reload_memory_operand" "m"))
- (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
- ""
- "")
-
- (define_expand "reload_outti"
- [(parallel [(set (match_operand:TI 0 "reload_memory_operand" "=m")
- (match_operand:TI 1 "register_operand" "r"))
- (clobber (match_operand:PSI 2 "register_operand" "=&c"))])]
- ""
- "")
-
- ;; For compare operations, we simply store the comparison operands and
- ;; do nothing else. The following branch or scc insn will output whatever
- ;; is needed.
- (define_expand "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "gpc_reg_operand" "")
- (match_operand:SI 1 "srcb_operand" "")))]
- ""
- "
- {
- a29k_compare_op0 = operands[0];
- a29k_compare_op1 = operands[1];
- a29k_compare_fp_p = 0;
- DONE;
- }")
-
- (define_expand "cmpsf"
- [(set (cc0)
- (compare (match_operand:SF 0 "gpc_reg_operand" "")
- (match_operand:SF 1 "gpc_reg_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "
- {
- a29k_compare_op0 = operands[0];
- a29k_compare_op1 = operands[1];
- a29k_compare_fp_p = 1;
- DONE;
- }")
-
- (define_expand "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "gpc_reg_operand" "")
- (match_operand:DF 1 "gpc_reg_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "
- {
- a29k_compare_op0 = operands[0];
- a29k_compare_op1 = operands[1];
- a29k_compare_fp_p = 1;
- DONE;
- }")
-
- ;; We can generate bit-tests better if we use NE instead of EQ, but we
- ;; don't have an NE for floating-point. So we have to have two patterns
- ;; for EQ and two for NE.
-
- (define_expand "beq"
- [(set (match_dup 1) (ne:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- if (GET_MODE_CLASS (GET_MODE (a29k_compare_op0)) == MODE_FLOAT)
- {
- emit_insn (gen_beq_fp (operands[0]));
- DONE;
- }
-
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "beq_fp"
- [(set (match_dup 1) (eq:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bne"
- [(set (match_dup 1) (ne:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- if (GET_MODE_CLASS (GET_MODE (a29k_compare_op0)) == MODE_FLOAT)
- {
- emit_insn (gen_bne_fp (operands[0]));
- DONE;
- }
-
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bne_fp"
- [(set (match_dup 1) (eq:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (ge (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- ;; We don't have a floating-point "lt" insn, so we have to use "gt" in that
- ;; case with the operands swapped. The operands must both be registers in
- ;; the floating-point case, so we know that swapping them is OK.
- (define_expand "blt"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- if (a29k_compare_fp_p)
- operands[2] = gen_rtx (GT, SImode, a29k_compare_op1, a29k_compare_op0);
- else
- operands[2] = gen_rtx (LT, SImode, a29k_compare_op0, a29k_compare_op1);
- }")
-
- ;; Similarly for "le".
- (define_expand "ble"
- [(set (match_dup 1) (match_dup 2))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- if (a29k_compare_fp_p)
- operands[2] = gen_rtx (GE, SImode, a29k_compare_op1, a29k_compare_op0);
- else
- operands[2] = gen_rtx (LE, SImode, a29k_compare_op0, a29k_compare_op1);
- }")
-
- (define_expand "bltu"
- [(set (match_dup 1) (ltu:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bleu"
- [(set (match_dup 1) (leu:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bgt"
- [(set (match_dup 1) (gt:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bge"
- [(set (match_dup 1) (ge:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bgtu"
- [(set (match_dup 1) (gtu:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "bgeu"
- [(set (match_dup 1) (geu:SI (match_dup 2) (match_dup 3)))
- (set (pc)
- (if_then_else (lt (match_dup 1) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
- {
- operands[1] = gen_reg_rtx (SImode);
- operands[2] = a29k_compare_op0;
- operands[3] = a29k_compare_op1;
- }")
-
- (define_expand "seq"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (eq:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- ;; This is the most complicated case, because we don't have a floating-point
- ;; "ne" insn. If integer, handle normally. If floating-point, write the
- ;; compare and then write an insn to reverse the test.
- (define_expand "sne_fp"
- [(set (match_dup 3)
- (eq:SI (match_operand 1 "gpc_reg_operand" "")
- (match_operand 2 "gpc_reg_operand" "")))
- (set (match_operand:SI 0 "gpc_reg_operand" "")
- (ge:SI (match_dup 3) (const_int 0)))]
- "! TARGET_SOFT_FLOAT"
- "
- { operands[3] = gen_reg_rtx (SImode);
- }");
-
- (define_expand "sne"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (ne:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
-
- if (a29k_compare_fp_p)
- {
- emit_insn (gen_sne_fp (operands[0], operands[1], operands[2]));
- DONE;
- }
- }")
-
- ;; We don't have a floating-point "lt" insn, so use "gt" and swap the
- ;; operands, the same as we do "blt".
- (define_expand "slt"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (match_dup 1))]
- ""
- "
- {
- if (a29k_compare_fp_p)
- operands[1] = gen_rtx (GT, SImode, a29k_compare_op1, a29k_compare_op0);
- else
- operands[1] = gen_rtx (LT, SImode, a29k_compare_op0, a29k_compare_op1);
- }")
-
- ;; Similarly for "le"
- (define_expand "sle"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (match_dup 1))]
- ""
- "
- {
- if (a29k_compare_fp_p)
- operands[1] = gen_rtx (GE, SImode, a29k_compare_op1, a29k_compare_op0);
- else
- operands[1] = gen_rtx (LE, SImode, a29k_compare_op0, a29k_compare_op1);
- }")
-
- (define_expand "sltu"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (ltu:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- (define_expand "sleu"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (leu:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- (define_expand "sgt"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (gt:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- (define_expand "sge"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (ge:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- (define_expand "sgtu"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (gtu:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- (define_expand "sgeu"
- [(set (match_operand:SI 0 "gpc_reg_operand" "")
- (geu:SI (match_dup 1) (match_dup 2)))]
- ""
- "
- {
- operands[1] = a29k_compare_op0;
- operands[2] = a29k_compare_op1;
- }")
-
- ;; Now define the actual jump insns.
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "branch_operator"
- [(match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 0)])
- (label_ref (match_operand 2 "" ""))
- (pc)))]
- ""
- "jmp%b0 %1,%l2%#"
- [(set_attr "type" "branch")])
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "branch_operator"
- [(match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 0)])
- (return)
- (pc)))]
- "null_epilogue ()"
- "jmp%b0i %1,lr0%#"
- [(set_attr "type" "branch")])
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "branch_operator"
- [(match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 0)])
- (pc)
- (label_ref (match_operand 2 "" ""))))]
- ""
- "jmp%B0 %1,%l2%#"
- [(set_attr "type" "branch")])
-
- (define_insn ""
- [(set (pc)
- (if_then_else (match_operator 0 "branch_operator"
- [(match_operand:SI 1 "gpc_reg_operand" "r")
- (const_int 0)])
- (pc)
- (return)))]
- "null_epilogue ()"
- "jmp%B0i %1,lr0%#"
- [(set_attr "type" "branch")])
-
- (define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0 "" "")))]
- ""
- "jmp %e0%E0"
- [(set_attr "type" "branch")])
-
- (define_insn "return"
- [(return)]
- "null_epilogue ()"
- "jmpi lr0%#"
- [(set_attr "type" "branch")])
-
- (define_insn "indirect_jump"
- [(set (pc)
- (match_operand:SI 0 "gpc_reg_operand" "r"))]
- ""
- "jmpi %0%#"
- [(set_attr "type" "branch")])
-
- (define_insn "tablejump"
- [(set (pc)
- (match_operand:SI 0 "gpc_reg_operand" "r"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- "jmpi %0%#"
- [(set_attr "type" "branch")])
-
- ;; JMPFDEC
- (define_insn ""
- [(set (pc)
- (if_then_else (ge (match_operand:SI 0 "gpc_reg_operand" "r")
- (const_int 0))
- (label_ref (match_operand 1 "" ""))
- (pc)))
- (set (match_dup 0)
- (plus:SI (match_dup 0)
- (const_int -1)))]
- ""
- "jmpfdec %0,%l1%#"
- [(set_attr "type" "branch")])
-