;;- Machine description for AMD Am29000 for GNU C compiler ;; Copyright (C) 1991, 1992, 1994, 1998, 1999, 2001 ;; 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, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, 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:SI 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:SI 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:SI 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 “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”))] “TARGET_MULTM” “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) (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1)) (sign_extend:DI (match_dup 2))) (const_int 32)))) (clobber (reg:SI 180))])] " { operands[3] = operand_subword (operands[0], 1, 1, DImode); operands[4] = operand_subword (operands[0], 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”))] “TARGET_MULTM” “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) (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1)) (zero_extend:DI (match_dup 2))) (const_int 32)))) (clobber (reg:SI 180))])] " { operands[3] = operand_subword (operands[0], 1, 1, DImode); operands[4] = operand_subword (operands[0], 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”))] “TARGET_MULTM” “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”))] “TARGET_MULTM” “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) PARAMS ((rtx, rtx, rtx, rtx)) = 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) PARAMS ((rtx, rtx, rtx, rtx)) = 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) PARAMS ((rtx, rtx, rtx, rtx)) = 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) PARAMS ((rtx, rtx, rtx, rtx)) = 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] = adjust_address (operands[1], TImode, 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”)])