;;- Machine description for GNU compiler, Convex Version ;; Copyright (C) 1988, 1994, 1995, 1998, 1999 Free Software Foundation, Inc.

;; 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. ;; Attribute specifications

; Target CPU (define_attr “cpu” “c1,c32,c34,c38” (const (symbol_ref “(enum attr_cpu) target_cpu”)))

;; Instruction classification

(define_attr “type” “alu,xalu,mldw,mldl,mldb,mst,adds,addd,mulw,mull,muls,muld,divw,divl,divs,divd,shfw,shfl,cvts,cvtd” (const_string “alu”))

;; Instruction times

(define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “mldw”)) 2 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “mldl”)) 4 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “mldw,mldl”)) 2 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “mldw,mldl”)) 4 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “mldw,mldl”)) 2 0)

(define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “mldb”)) 9 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “mldb”)) 36 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “mldb”)) 21 0)

(define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “xalu”)) 1 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “xalu”)) 1 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “xalu”)) 5 0) (define_function_unit “mem” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “xalu”)) 2 0)

(define_function_unit “add” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “adds,addd”)) 3 2) (define_function_unit “add” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “adds,addd”)) 2 1) (define_function_unit “add” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “adds,addd”)) 5 2) (define_function_unit “add” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “adds,addd”)) 2 1)

(define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “mulw,muls”)) 3 2) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “mulw,muls”)) 4 2) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “mulw,muls”)) 6 2) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “mulw,muls”)) 3 2)

(define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “mull,muld”)) 4 3) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “mull”)) 10 7) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “muld”)) 5 2) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “mull,muld”)) 7 3) (define_function_unit “mul” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “mull,muld”)) 4 3)

(define_function_unit “div” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “divw”)) 24 24) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “divw”)) 44 6) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “divw”)) 14 10) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “divw”)) 11 10)

(define_function_unit “div” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “divl”)) 41 42) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “divl”)) 76 5) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “divl”)) 22 18) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “divl”)) 19 18)

(define_function_unit “div” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “divs”)) 22 22) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “divs”)) 8 6) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “divs”)) 13 9) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “divs”)) 10 9)

(define_function_unit “div” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “divd”)) 37 38) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “divd”)) 12 8) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “divd”)) 20 16) (define_function_unit “div” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “divd”)) 17 16)

(define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “cvts,cvtd”)) 4 3) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “cvts”)) 9 7) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “cvtd”)) 9 6) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “cvts”)) 6 2) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c34”) (eq_attr “type” “cvtd”)) 6 1) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “cvts,cvtd”)) 3 1)

(define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c1”) (eq_attr “type” “shfw,shfl”)) 3 2) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “shfw”)) 7 5) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c32”) (eq_attr “type” “shfl”)) 7 4) (define_function_unit “misc” 1 0 (and (eq_attr “cpu” “c38”) (eq_attr “type” “shfw,shfl”)) 3 1)

(define_function_unit “mystery_latch” 1 1 (and (eq_attr “type” “!alu,mldw,mldl,adds,addd”) (eq_attr “cpu” “c32”)) 2 2)

;(define_function_unit “ip” 1 1 ; (and (eq_attr “cpu” “c1”) ; (eq_attr “type” “divw,divl,divs,divd,xalu”)) 2 2) ;(define_function_unit “ip” 1 1 ; (and (eq_attr “cpu” “c1”) ; (eq_attr “type” “!divw,divl,divs,divd,xalu”)) 1 1) ;(define_function_unit “ip” 1 1 ; (and (eq_attr “cpu” “c32”) ; (eq_attr “type” “mull,muld,divl,divd,shfl,cvtd,xalu”)) 2 2) ;(define_function_unit “ip” 1 1 ; (and (eq_attr “cpu” “c32”) ; (eq_attr “type” “!mull,muld,divl,divd,shfl,cvtd,xalu”)) 1 1) ;(define_function_unit “ip” 1 1 ; (and (eq_attr “cpu” “c34”) ; (eq_attr “type” “addd,mull,muld,divl,divd,cvtd,xalu”)) 2 2) ;(define_function_unit “ip” 1 1 ; (and (eq_attr “cpu” “c34”) ; (eq_attr “type” “!addd,mull,muld,divl,divd,cvtd,xalu”)) 1 1) ;; Make the first thing a real insn in case of genattrtab bug

(define_insn “nop” [(const_int 0)] "" “nop”) ;; Moves

(define_expand “movdf” [(set (match_operand:DF 0 “general_operand” "") (match_operand:DF 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (DFmode, operands[1]);”)

(define_insn "" [(set (match_operand:DF 0 “general_operand” “=d,d,d,d,d,<,m”) (match_operand:DF 1 “general_operand” “d,Q,m,G,H,d,d”))] “register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)” “@ mov %1,%0 ldb.d %1,%0 ld.d %1,%0 ld.d %u1,%0 ld.l %v1,%0 psh.l %1 st.d %1,%0” [(set_attr “type” “alu,mldb,mldl,alu,alu,alu,mst”)])

;; This is here so we can load any result of RTL constant folding ;; but do not use it on constants that can be loaded from memory. ;; It is never better and can be worse.

(define_insn "" [(set (match_operand:DF 0 “register_operand” “=d”) (match_operand:DF 1 “const_double_operand” “F”))] “CONST_DOUBLE_MEM (operands[1]) == const0_rtx” “ld.u %u1,%0;ld.w %v1,%0” [(set_attr “type” “xalu”)])

(define_expand “movsf” [(set (match_operand:SF 0 “general_operand” "") (match_operand:SF 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (SFmode, operands[1]);”)

(define_insn "" [(set (match_operand:SF 0 “general_operand” “=d,d,d,d,<,m”) (match_operand:SF 1 “general_operand” “d,Q,m,F,d,d”))] “register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)” “@ mov.s %1,%0 ldb.s %1,%0 ld.s %1,%0 ld.s %1,%0 psh.w %1 st.s %1,%0” [(set_attr “type” “alu,mldb,mldw,alu,alu,mst”)])

(define_expand “movdi” [(set (match_operand:DI 0 “general_operand” "") (match_operand:DI 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (DImode, operands[1]);”)

(define_insn "" [(set (match_operand:DI 0 “general_operand” “=d,d,d,d,d,<,m”) (match_operand:DI 1 “general_operand” “d,Q,m,G,HI,d,d”))] “register_operand (operands[0], DImode) || register_operand (operands[1], DImode)” “@ mov %1,%0 ldb.l %1,%0 ld.l %1,%0 ld.d %u1,%0 ld.l %1,%0 psh.l %1 st.l %1,%0” [(set_attr “type” “alu,mldb,mldl,alu,alu,alu,mst”)])

;; This is here so we can load any result of RTL constant folding ;; but do not use it on constants that can be loaded from memory. ;; It is never better and can be worse.

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (match_operand:DI 1 “const_double_operand” “F”))] “CONST_DOUBLE_MEM (operands[1]) == const0_rtx” “ld.u %u1,%0;ld.w %v1,%0” [(set_attr “type” “xalu”)])

(define_expand “movsi” [(set (match_operand:SI 0 “general_operand” "") (match_operand:SI 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (SImode, operands[1]);”)

(define_insn "" [(set (match_operand:SI 0 “push_operand” “=<,<”) (match_operand:SI 1 “nonmemory_operand” “Ad,i”))] "" “@ psh.w %1 pshea %a1”)

(define_insn "" [(set (match_operand:SI 0 “general_operand” “=d,r,d,r,r,m”) (match_operand:SI 1 “general_operand” “d,r,Q,m,i,r”))] “register_operand (operands[0], SImode) || register_operand (operands[1], SImode)” “@ mov.w %1,%0 mov %1,%0 ldb.w %1,%0 ld.w %1,%0 ld.w %1,%0 st.w %1,%0” [(set_attr “type” “alu,alu,mldb,mldw,alu,mst”)])

(define_expand “movstrictsi” [(set (strict_low_part (match_operand:SI 0 “general_operand” "")) (match_operand:SI 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (SImode, operands[1]);”)

(define_insn "" [(set (strict_low_part (match_operand:SI 0 “general_operand” “+d,r,d,r,r,m”)) (match_operand:SI 1 “general_operand” “d,r,Q,m,i,r”))] “register_operand (operands[0], SImode) || register_operand (operands[1], SImode)” “@ mov.w %1,%0 mov %1,%0 ldb.w %1,%0 ld.w %1,%0 ld.w %1,%0 st.w %1,%0” [(set_attr “type” “alu,alu,mldb,mldw,alu,mst”)])

(define_expand “movhi” [(set (match_operand:HI 0 “general_operand” "") (match_operand:HI 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (HImode, operands[1]);”)

(define_insn "" [(set (match_operand:HI 0 “general_operand” “=d,r,d,r,r,<,m”) (match_operand:HI 1 “general_operand” “d,r,Q,m,i,Ad,r”))] “register_operand (operands[0], HImode) || register_operand (operands[1], HImode)” “@ mov.w %1,%0 mov %1,%0 ldb.h %1,%0 ld.h %1,%0 ld.w %1,%0 psh.w %1 st.h %1,%0” [(set_attr “type” “alu,alu,mldb,mldw,alu,alu,mst”)])

(define_expand “movqi” [(set (match_operand:QI 0 “general_operand” "") (match_operand:QI 1 “general_operand” ""))] "" “if (GET_CODE (operands[0]) != REG) operands[1] = force_reg (QImode, operands[1]);”)

(define_insn "" [(set (match_operand:QI 0 “general_operand” “=d,r,d,r,r,<,m”) (match_operand:QI 1 “general_operand” “d,r,Q,m,i,Ad,r”))] “register_operand (operands[0], QImode) || register_operand (operands[1], QImode)” “@ mov.w %1,%0 mov %1,%0 ldb.b %1,%0 ld.b %1,%0 ld.w %1,%0 psh.w %1 st.b %1,%0” [(set_attr “type” “alu,alu,mldb,mldw,alu,alu,mst”)])

;; Expand block moves manually to get code that pipelines the loads.

(define_expand “movstrsi” [(set (match_operand:BLK 0 “memory_operand” “=m”) (match_operand:BLK 1 “memory_operand” “m”)) (use (match_operand:SI 2 “const_int_operand” “i”)) (use (match_operand:SI 3 “const_int_operand” “i”))] "" " expand_movstr (operands); DONE; ") ;; Extension and truncation insns. ;; Those for integer source operand ;; are ordered widest source type first.

(define_insn “truncsiqi2” [(set (match_operand:QI 0 “register_operand” “=d,a”) (truncate:QI (match_operand:SI 1 “register_operand” “d,a”)))] "" “cvtw.b %1,%0”)

(define_insn “truncsihi2” [(set (match_operand:HI 0 “register_operand” “=d,a”) (truncate:HI (match_operand:SI 1 “register_operand” “d,a”)))] "" “cvtw.h %1,%0”)

(define_insn “trunchiqi2” [(set (match_operand:QI 0 “register_operand” “=r”) (truncate:QI (match_operand:HI 1 “register_operand” “0”)))] "" "")

(define_insn “truncdisi2” [(set (match_operand:SI 0 “register_operand” “=d”) (truncate:SI (match_operand:DI 1 “register_operand” “d”)))] "" “cvtl.w %1,%0”)

(define_insn “extendsidi2” [(set (match_operand:DI 0 “register_operand” “=d”) (sign_extend:DI (match_operand:SI 1 “register_operand” “d”)))] "" “cvtw.l %1,%0”)

(define_insn “extendhisi2” [(set (match_operand:SI 0 “register_operand” “=d,a”) (sign_extend:SI (match_operand:HI 1 “register_operand” “d,a”)))] "" “cvth.w %1,%0”)

(define_insn “extendqihi2” [(set (match_operand:HI 0 “register_operand” “=d,a”) (sign_extend:HI (match_operand:QI 1 “register_operand” “d,a”)))] "" “cvtb.w %1,%0”)

(define_insn “extendqisi2” [(set (match_operand:SI 0 “register_operand” “=d,a”) (sign_extend:SI (match_operand:QI 1 “register_operand” “d,a”)))] "" “cvtb.w %1,%0”)

(define_insn “extendsfdf2” [(set (match_operand:DF 0 “register_operand” “=d”) (float_extend:DF (match_operand:SF 1 “register_operand” “d”)))] "" “cvts.d %1,%0” [(set_attr “type” “cvts”)])

(define_insn “truncdfsf2” [(set (match_operand:SF 0 “register_operand” “=d”) (float_truncate:SF (match_operand:DF 1 “register_operand” “d”)))] "" “cvtd.s %1,%0” [(set_attr “type” “cvtd”)])

(define_insn “zero_extendhisi2” [(set (match_operand:SI 0 “register_operand” “=r”) (zero_extend:SI (match_operand:HI 1 “register_operand” “0”)))] "" “and #0xffff,%0”)

(define_insn “zero_extendqihi2” [(set (match_operand:HI 0 “register_operand” “=r”) (zero_extend:HI (match_operand:QI 1 “register_operand” “0”)))] "" “and #0xff,%0”)

(define_insn “zero_extendqisi2” [(set (match_operand:SI 0 “register_operand” “=r”) (zero_extend:SI (match_operand:QI 1 “register_operand” “0”)))] "" “and #0xff,%0”)

(define_insn “zero_extendsidi2” [(set (match_operand:DI 0 “register_operand” “=d”) (zero_extend:DI (match_operand:SI 1 “register_operand” “0”)))] "" “ld.u #0,%0”) ;; Fix-to-float conversion insns. ;; Note that the ones that start with SImode come first. ;; That is so that an operand that is a CONST_INT ;; (and therefore lacks a specific machine mode). ;; will be recognized as SImode (which is always valid) ;; rather than as QImode or HImode.

(define_insn “floatsisf2” [(set (match_operand:SF 0 “register_operand” “=d”) (float:SF (match_operand:SI 1 “register_operand” “d”)))] "" “cvtw.s %1,%0” [(set_attr “type” “cvts”)])

(define_insn “floatdisf2” [(set (match_operand:SF 0 “register_operand” “=d”) (float:SF (match_operand:DI 1 “register_operand” “d”)))] "" “cvtl.s %1,%0” [(set_attr “type” “cvtd”)])

(define_insn “floatsidf2” [(set (match_operand:DF 0 “register_operand” “=d”) (float:DF (match_operand:SI 1 “register_operand” “d”)))] “! TARGET_C1” “cvtw.d %1,%0” [(set_attr “type” “cvts”)])

(define_insn “floatdidf2” [(set (match_operand:DF 0 “register_operand” “=d”) (float:DF (match_operand:DI 1 “register_operand” “d”)))] "" “cvtl.d %1,%0” [(set_attr “type” “cvtd”)])

;; These are a little slower than gcc's normal way of doing unsigned ;; DI floats (if the DI number is “negative”) but they avoid double ;; rounding and they avoid explicit constants.

(define_expand “floatunsdidf2” [(set (match_operand:DF 0 “register_operand” “=d”) (float:DF (match_operand:DI 1 “register_operand” “d”))) (set (cc0) (compare:DI (match_dup 3) (match_dup 1))) (set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_dup 4)) (pc))) (set (match_dup 2) (lshiftrt:DI (match_dup 1) (const_int 1))) (set (match_dup 0) (float:DF (match_dup 2))) (set (match_dup 0) (plus:DF (match_dup 0) (match_dup 0))) (match_dup 4) (set (match_dup 0) (match_dup 0))] "" " { operands[2] = gen_reg_rtx (DImode); operands[3] = force_reg (DImode, const0_rtx); operands[4] = gen_label_rtx (); }")

(define_expand “floatunsdisf2” [(set (match_operand:SF 0 “register_operand” “=d”) (float:SF (match_operand:DI 1 “register_operand” “d”))) (set (cc0) (compare:DI (match_dup 3) (match_dup 1))) (set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_dup 4)) (pc))) (set (match_dup 2) (lshiftrt:DI (match_dup 1) (const_int 1))) (set (match_dup 0) (float:SF (match_dup 2))) (set (match_dup 0) (plus:SF (match_dup 0) (match_dup 0))) (match_dup 4) (set (match_dup 0) (match_dup 0))] "" " { operands[2] = gen_reg_rtx (DImode); operands[3] = force_reg (DImode, const0_rtx); operands[4] = gen_label_rtx (); }")

;; These patterns are identical to gcc's default action ;; if DI->DF and DI->SF are not present. There are here ;; only to prevent SI->*F from promoting to DI->*F.

(define_expand “floatunssidf2” [(set (match_dup 2) (zero_extend:DI (match_operand:SI 1 “register_operand” ""))) (set (match_operand:DF 0 “register_operand” "") (float:DF (match_dup 2)))] "" “operands[2] = gen_reg_rtx (DImode);”)

(define_expand “floatunssisf2” [(set (match_dup 2) (zero_extend:DI (match_operand:SI 1 “register_operand” ""))) (set (match_operand:SF 0 “register_operand” "") (float:SF (match_dup 2)))] "" “operands[2] = gen_reg_rtx (DImode);”) ;; Float-to-fix conversion insns.

(define_insn “fix_truncsfsi2” [(set (match_operand:SI 0 “register_operand” “=d”) (fix:SI (fix:SF (match_operand:SF 1 “register_operand” “d”))))] "" “cvts.w %1,%0” [(set_attr “type” “cvts”)])

(define_insn “fix_truncsfdi2” [(set (match_operand:DI 0 “register_operand” “=d”) (fix:DI (fix:SF (match_operand:SF 1 “register_operand” “d”))))] "" “cvts.l %1,%0” [(set_attr “type” “cvts”)])

(define_insn “fix_truncdfsi2” [(set (match_operand:SI 0 “register_operand” “=d”) (fix:SI (fix:DF (match_operand:DF 1 “register_operand” “d”))))] "" “cvtd.l %1,%0” [(set_attr “type” “cvtd”)])

(define_insn “fix_truncdfdi2” [(set (match_operand:DI 0 “register_operand” “=d”) (fix:DI (fix:DF (match_operand:DF 1 “register_operand” “d”))))] "" “cvtd.l %1,%0” [(set_attr “type” “cvtd”)]) ;;- All kinds of add instructions.

(define_insn “adddf3” [(set (match_operand:DF 0 “register_operand” “=d”) (plus:DF (match_operand:DF 1 “register_operand” “%0”) (match_operand:DF 2 “register_operand” “d”)))] "" “add.d %2,%0” [(set_attr “type” “addd”)])

(define_insn “addsf3” [(set (match_operand:SF 0 “register_operand” “=d”) (plus:SF (match_operand:SF 1 “register_operand” “%0”) (match_operand:SF 2 “nonmemory_operand” “dF”)))] "" “add.s %2,%0” [(set_attr “type” “adds”)])

(define_insn “adddi3” [(set (match_operand:DI 0 “register_operand” “=d”) (plus:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 “register_operand” “d”)))] "" “add.l %2,%0”)

(define_expand “addsi3” [(set (match_operand:SI 0 “register_operand” "") (plus:SI (match_operand:SI 1 “register_operand” "") (match_operand:SI 2 “nonmemory_operand” "")))] "" "")

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a”) (plus:SI (match_operand:SI 1 “register_operand” “%A”) (match_operand:SI 2 “immediate_operand” “i”)))] “operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx” “ldea %a2(%1),%0”)

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a”) (plus:SI (match_operand:SI 1 “register_operand” “%a”) (match_operand:SI 2 “nonmemory_operand” “ri”)))] “operands[1] == stack_pointer_rtx && operands[0] != stack_pointer_rtx” “mov %1,%0;add.w %2,%0”)

(define_insn "" [(set (match_operand:SI 0 “push_operand” “=<”) (plus:SI (match_operand:SI 1 “register_operand” “A”) (match_operand:SI 2 “immediate_operand” “i”)))] “operands[1] != stack_pointer_rtx” “pshea %a2(%1)” [(set_attr “type” “mst”)])

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,a,a”) (plus:SI (match_operand:SI 1 “register_operand” “%0,0,A”) (match_operand:SI 2 “nonmemory_operand” “di,ri,i”)))] “TARGET_C1” “@ add.w %2,%0 add.w %2,%0 ldea %a2(%1),%0”)

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,a,r”) (plus:SI (match_operand:SI 1 “register_operand” “%0,0,A”) (match_operand:SI 2 “nonmemory_operand” “di,ri,i”)))] "" “@ add.w %2,%0 add.w %2,%0 ldea %a2(%1),%0”)

(define_insn “addhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (plus:HI (match_operand:HI 1 “register_operand” “%0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “add.h %2,%0”)

(define_insn “addqi3” [(set (match_operand:QI 0 “register_operand” “=d,d”) (plus:QI (match_operand:QI 1 “register_operand” “%0,0”) (match_operand:QI 2 “nonmemory_operand” “d,i”)))] "" “@ add.b %2,%0 add.w %2,%0”) ;;- All kinds of subtract instructions.

(define_insn “subdf3” [(set (match_operand:DF 0 “register_operand” “=d”) (minus:DF (match_operand:DF 1 “register_operand” “0”) (match_operand:DF 2 “register_operand” “d”)))] "" “sub.d %2,%0” [(set_attr “type” “addd”)])

(define_insn “subsf3” [(set (match_operand:SF 0 “register_operand” “=d”) (minus:SF (match_operand:SF 1 “register_operand” “0”) (match_operand:SF 2 “nonmemory_operand” “dF”)))] "" “sub.s %2,%0” [(set_attr “type” “adds”)])

(define_insn “subdi3” [(set (match_operand:DI 0 “register_operand” “=d”) (minus:DI (match_operand:DI 1 “register_operand” “0”) (match_operand:DI 2 “register_operand” “d”)))] "" “sub.l %2,%0”)

(define_insn “subsi3” [(set (match_operand:SI 0 “register_operand” “=d,a,?d,?a”) (minus:SI (match_operand:SI 1 “nonmemory_operand” “0,0,di,ai”) (match_operand:SI 2 “nonmemory_operand” “di,ai,0,0”)))] "" “@ sub.w %2,%0 sub.w %2,%0 sub.w %1,%0;neg.w %0,%0 sub.w %1,%0;neg.w %0,%0”)

(define_insn “subhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (minus:HI (match_operand:HI 1 “register_operand” “0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “sub.h %2,%0”)

(define_insn “subqi3” [(set (match_operand:QI 0 “register_operand” “=d,d”) (minus:QI (match_operand:QI 1 “register_operand” “0,0”) (match_operand:QI 2 “nonmemory_operand” “d,i”)))] "" “@ sub.b %2,%0 sub.w %2,%0”) ;;- Multiply instructions.

(define_insn “muldf3” [(set (match_operand:DF 0 “register_operand” “=d”) (mult:DF (match_operand:DF 1 “register_operand” “%0”) (match_operand:DF 2 “register_operand” “d”)))] "" “mul.d %2,%0” [(set_attr “type” “muld”)])

(define_insn “mulsf3” [(set (match_operand:SF 0 “register_operand” “=d”) (mult:SF (match_operand:SF 1 “register_operand” “%0”) (match_operand:SF 2 “nonmemory_operand” “dF”)))] "" “mul.s %2,%0” [(set_attr “type” “muls”)])

(define_insn “muldi3” [(set (match_operand:DI 0 “register_operand” “=d”) (mult:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 “register_operand” “d”)))] "" “mul.l %2,%0” [(set_attr “type” “mull”)])

(define_insn “mulsi3” [(set (match_operand:SI 0 “register_operand” “=d,a”) (mult:SI (match_operand:SI 1 “register_operand” “%0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] "" “mul.w %2,%0” [(set_attr “type” “mulw”)])

(define_insn “mulhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (mult:HI (match_operand:HI 1 “register_operand” “%0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “mul.h %2,%0” [(set_attr “type” “mulw”)])

(define_insn “mulqi3” [(set (match_operand:QI 0 “register_operand” “=d,d”) (mult:QI (match_operand:QI 1 “register_operand” “%0,0”) (match_operand:QI 2 “nonmemory_operand” “d,i”)))] "" “@ mul.b %2,%0 mul.w %2,%0” [(set_attr “type” “mulw,mulw”)]) ;;- Divide instructions.

(define_insn “divdf3” [(set (match_operand:DF 0 “register_operand” “=d”) (div:DF (match_operand:DF 1 “register_operand” “0”) (match_operand:DF 2 “register_operand” “d”)))] "" “div.d %2,%0” [(set_attr “type” “divd”)])

(define_insn “divsf3” [(set (match_operand:SF 0 “register_operand” “=d”) (div:SF (match_operand:SF 1 “register_operand” “0”) (match_operand:SF 2 “nonmemory_operand” “dF”)))] "" “div.s %2,%0” [(set_attr “type” “divs”)])

(define_insn “divdi3” [(set (match_operand:DI 0 “register_operand” “=d”) (div:DI (match_operand:DI 1 “register_operand” “0”) (match_operand:DI 2 “register_operand” “d”)))] "" “div.l %2,%0” [(set_attr “type” “divl”)])

(define_expand “udivsi3” [(set (match_dup 3) (zero_extend:DI (match_operand:SI 1 “register_operand” ""))) (set (match_dup 4) (zero_extend:DI (match_operand:SI 2 “register_operand” ""))) (set (match_dup 3) (div:DI (match_dup 3) (match_dup 4))) (set (match_operand:SI 0 “register_operand” "") (subreg:SI (match_dup 3) 0))] "" "operands[3] = gen_reg_rtx (DImode); operands[4] = gen_reg_rtx (DImode); ")

(define_insn “udivdi3” [(set (match_operand:DI 0 “register_operand” “=d”) (udiv:DI (match_operand:DI 1 “register_operand” “d”) (match_operand:DI 2 “register_operand” “d”)))] "" “psh.l %2;psh.l %1;callq udiv64;pop.l %0;add.w #8,sp”)

(define_insn “divsi3” [(set (match_operand:SI 0 “register_operand” “=d,a”) (div:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] "" “div.w %2,%0” [(set_attr “type” “divw”)])

(define_insn “divhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (div:HI (match_operand:HI 1 “register_operand” “0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “div.h %2,%0” [(set_attr “type” “divw”)])

(define_insn “divqi3” [(set (match_operand:QI 0 “register_operand” “=d”) (div:QI (match_operand:QI 1 “register_operand” “0”) (match_operand:QI 2 “register_operand” “d”)))] "" “div.b %2,%0” [(set_attr “type” “divw”)]) ;;- Bit clear instructions.

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (and:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 "" "")))] “(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) || (GET_CODE (operands[2]) == CONST_DOUBLE && CONST_DOUBLE_HIGH (operands[2]) == -1)” “and %2,%0”)

(define_insn “anddi3” [(set (match_operand:DI 0 “register_operand” “=d”) (and:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 “register_operand” “d”)))] "" “and %2,%0”)

(define_insn “andsi3” [(set (match_operand:SI 0 “register_operand” “=d,a”) (and:SI (match_operand:SI 1 “register_operand” “%0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] "" “and %2,%0”)

(define_insn “andhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (and:HI (match_operand:HI 1 “register_operand” “%0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “and %2,%0”)

(define_insn “andqi3” [(set (match_operand:QI 0 “register_operand” “=d,a”) (and:QI (match_operand:QI 1 “register_operand” “%0,0”) (match_operand:QI 2 “nonmemory_operand” “di,ai”)))] "" “and %2,%0”)

;;- Bit set instructions.

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (ior:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 "" "")))] “(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0) || (GET_CODE (operands[2]) == CONST_DOUBLE && CONST_DOUBLE_HIGH (operands[2]) == 0)” “or %2,%0”)

(define_insn “iordi3” [(set (match_operand:DI 0 “register_operand” “=d”) (ior:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 “register_operand” “d”)))] "" “or %2,%0”)

(define_insn “iorsi3” [(set (match_operand:SI 0 “register_operand” “=d,a”) (ior:SI (match_operand:SI 1 “register_operand” “%0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] "" “or %2,%0”)

(define_insn “iorhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (ior:HI (match_operand:HI 1 “register_operand” “%0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “or %2,%0”)

(define_insn “iorqi3” [(set (match_operand:QI 0 “register_operand” “=d,a”) (ior:QI (match_operand:QI 1 “register_operand” “%0,0”) (match_operand:QI 2 “nonmemory_operand” “di,ai”)))] "" “or %2,%0”)

;;- xor instructions.

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (xor:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 "" "")))] “(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0) || (GET_CODE (operands[2]) == CONST_DOUBLE && CONST_DOUBLE_HIGH (operands[2]) == 0)” “xor %2,%0”)

(define_insn “xordi3” [(set (match_operand:DI 0 “register_operand” “=d”) (xor:DI (match_operand:DI 1 “register_operand” “%0”) (match_operand:DI 2 “register_operand” “d”)))] "" “xor %2,%0”)

(define_insn “xorsi3” [(set (match_operand:SI 0 “register_operand” “=d,a”) (xor:SI (match_operand:SI 1 “register_operand” “%0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] "" “xor %2,%0”)

(define_insn “xorhi3” [(set (match_operand:HI 0 “register_operand” “=d,a”) (xor:HI (match_operand:HI 1 “register_operand” “%0,0”) (match_operand:HI 2 “nonmemory_operand” “di,ai”)))] "" “xor %2,%0”)

(define_insn “xorqi3” [(set (match_operand:QI 0 “register_operand” “=d,a”) (xor:QI (match_operand:QI 1 “register_operand” “%0,0”) (match_operand:QI 2 “nonmemory_operand” “di,ai”)))] "" “xor %2,%0”) (define_insn “negdf2” [(set (match_operand:DF 0 “register_operand” “=d”) (neg:DF (match_operand:DF 1 “register_operand” “d”)))] "" “neg.d %1,%0” [(set_attr “type” “addd”)])

(define_insn “negsf2” [(set (match_operand:SF 0 “register_operand” “=d”) (neg:SF (match_operand:SF 1 “register_operand” “d”)))] "" “neg.s %1,%0” [(set_attr “type” “adds”)])

(define_insn “negdi2” [(set (match_operand:DI 0 “register_operand” “=d”) (neg:DI (match_operand:DI 1 “register_operand” “d”)))] "" “neg.l %1,%0”)

(define_insn “negsi2” [(set (match_operand:SI 0 “register_operand” “=d,a”) (neg:SI (match_operand:SI 1 “register_operand” “d,a”)))] "" “neg.w %1,%0”)

(define_insn “neghi2” [(set (match_operand:HI 0 “register_operand” “=d,a”) (neg:HI (match_operand:HI 1 “register_operand” “d,a”)))] "" “neg.h %1,%0”)

(define_insn “negqi2” [(set (match_operand:QI 0 “register_operand” “=d”) (neg:QI (match_operand:QI 1 “register_operand” “d”)))] "" “neg.b %1,%0”) (define_insn “one_cmpldi2” [(set (match_operand:DI 0 “register_operand” “=d”) (not:DI (match_operand:DI 1 “register_operand” “d”)))] "" “not %1,%0”)

(define_insn “one_cmplsi2” [(set (match_operand:SI 0 “register_operand” “=d,a”) (not:SI (match_operand:SI 1 “register_operand” “d,a”)))] "" “not %1,%0”)

(define_insn “one_cmplhi2” [(set (match_operand:HI 0 “register_operand” “=d,a”) (not:HI (match_operand:HI 1 “register_operand” “d,a”)))] "" “not %1,%0”)

(define_insn “one_cmplqi2” [(set (match_operand:QI 0 “register_operand” “=d,a”) (not:QI (match_operand:QI 1 “register_operand” “d,a”)))] "" “not %1,%0”) ;;- Shifts ;; ;; The extreme profusion of patterns here is due to the different-speed ;; shifts on different machines, and the C1's lack of word shift S-register ;; instructions.

;; SImode

;; Arithmetic left 1, 1 cycle on all machines via add

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=r”) (ashift:SI (match_operand:SI 1 “register_operand” “0”) (const_int 1)))] "" “add.w %0,%0”)

;; C34 general shift is 1 cycle

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,a”) (ashift:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] “TARGET_C34” “@ shf.w %2,%0 shf %2,%0” [(set_attr “type” “shfw,shfw”)])

;; else shift left 0..7 is 1 cycle if we use an A register

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a,?d”) (ashift:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “immediate_operand” “ai,di”)))] “TARGET_C1 && INTVAL (operands[2]) < (unsigned) 8” “@ shf %2,%0 shf %2,%0” [(set_attr “type” “alu,shfl”)])

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a,?d”) (ashift:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “immediate_operand” “ai,di”)))] “INTVAL (operands[2]) < (unsigned) 8” “@ shf %2,%0 shf.w %2,%0” [(set_attr “type” “alu,shfw”)])

;; else general left shift

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,a”) (ashift:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] “TARGET_C1” “@ shf %2,%0 shf %2,%0” [(set_attr “type” “shfl,shfw”)])

;; but C2 left shift by a constant is faster via multiply

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=r”) (ashift:SI (match_operand:SI 1 “register_operand” “0”) (match_operand:SI 2 “const_int_operand” “i”)))] “TARGET_C2 && INTVAL (operands[2]) < (unsigned) 32” “mul.w %z2,%0” [(set_attr “type” “mulw”)])

(define_insn “ashlsi3” [(set (match_operand:SI 0 “register_operand” “=d,a”) (ashift:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “nonmemory_operand” “di,ai”)))] "" “@ shf.w %2,%0 shf %2,%0” [(set_attr “type” “shfw,shfw”)])

;; Logical right, general ;; The hardware wants the negative of the shift count

(define_expand “lshrsi3” [(set (match_operand:SI 0 “register_operand” "") (lshiftrt:SI (match_operand:SI 1 “register_operand” "") (neg:SI (match_operand:SI 2 “nonmemory_operand” ""))))] "" “operands[2] = negate_rtx (SImode, operands[2]);”)

;; C1 lacks word shift S reg

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a,?d”) (lshiftrt:SI (match_operand:SI 1 “register_operand” “0,0”) (neg:SI (match_operand:SI 2 “nonmemory_operand” “ai,di”))))] “TARGET_C1” “@ shf %2,%0 ld.u #0,%0;shf %2,%0” [(set_attr “type” “shfw,shfl”)])

;; general case

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,a”) (lshiftrt:SI (match_operand:SI 1 “register_operand” “0,0”) (neg:SI (match_operand:SI 2 “nonmemory_operand” “di,ai”))))] "" “@ shf.w %2,%0 shf %2,%0” [(set_attr “type” “shfw,shfw”)])

;; Patterns without neg produced by constant folding

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a,?d”) (lshiftrt:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “immediate_operand” “i,i”)))] “TARGET_C1” “@ shf #%n2,%0 ld.u #0,%0;shf #%n2,%0” [(set_attr “type” “shfw,shfl”)])

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,a”) (lshiftrt:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “immediate_operand” “i,i”)))] "" “@ shf.w #%n2,%0 shf #%n2,%0” [(set_attr “type” “shfw,shfw”)])

;; Arithmetic right, general ;; Sign-extend to 64 bits, then shift that. Works for 0..32.

(define_expand “ashrsi3” [(set (match_operand:SI 0 “register_operand” "") (ashiftrt:SI (match_operand:SI 1 “register_operand” "") (neg:SI (match_operand:SI 2 “nonmemory_operand” ""))))] "" “operands[2] = negate_rtx (SImode, operands[2]);”)

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d,&d”) (ashiftrt:SI (match_operand:SI 1 “register_operand” “0,d”) (neg:SI (match_operand:SI 2 “nonmemory_operand” “di,di”))))] "" “cvtw.l %1,%0;shf %2,%0” [(set_attr “type” “shfl,shfl”)])

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d”) (ashiftrt:SI (match_operand:SI 1 “register_operand” “d”) (match_operand:SI 2 “immediate_operand” “i”)))] "" “cvtw.l %1,%0;shf #%n2,%0” [(set_attr “type” “shfl”)])

;; DImode ;; Arithmetic left, 1-cycle

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (ashift:DI (match_operand:DI 1 “register_operand” “0”) (const_int 1)))] "" “add.l %0,%0”)

;; Arithmetic left, general

(define_insn “ashldi3” [(set (match_operand:DI 0 “register_operand” “=d”) (ashift:DI (match_operand:DI 1 “register_operand” “0”) (match_operand:SI 2 “nonmemory_operand” “di”)))] "" “shf %2,%0” [(set_attr “type” “shfl”)])

;; Can omit zero- or sign-extend if shift is 32 or more.

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (ashift:DI (zero_extend:DI (match_operand:SI 1 “register_operand” “0”)) (match_operand:SI 2 “const_int_operand” “i”)))] “INTVAL (operands[2]) >= 32” “shf %2,%0” [(set_attr “type” “shfl”)])

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (ashift:DI (sign_extend:DI (match_operand:SI 1 “register_operand” “0”)) (match_operand:SI 2 “const_int_operand” “i”)))] “INTVAL (operands[2]) >= 32” “shf %2,%0” [(set_attr “type” “shfl”)])

;; Logical right, general

(define_expand “lshrdi3” [(set (match_operand:DI 0 “register_operand” "") (lshiftrt:DI (match_operand:DI 1 “register_operand” "") (neg:SI (match_operand:SI 2 “nonmemory_operand” ""))))] "" “operands[2] = negate_rtx (SImode, operands[2]);”)

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (lshiftrt:DI (match_operand:DI 1 “register_operand” “0”) (neg:SI (match_operand:SI 2 “nonmemory_operand” “di”))))] "" “shf %2,%0” [(set_attr “type” “shfl”)])

(define_insn "" [(set (match_operand:DI 0 “register_operand” “=d”) (lshiftrt:DI (match_operand:DI 1 “register_operand” “0”) (match_operand:SI 2 “immediate_operand” “i”)))] "" “shf #%n2,%0” [(set_attr “type” “shfl”)])

;; Arithmetic right, general ;; Use ;; ((a >> b) ^ signbit) - signbit ;; where signbit is (1 << 63) >> b ;; Works for 0..63. Does not work for 64; unfortunate but valid.

(define_expand “ashrdi3” [(set (match_operand:DI 0 “register_operand” "") (lshiftrt:DI (match_operand:DI 1 “register_operand” "") (neg:SI (match_operand:SI 2 “nonmemory_operand” "")))) (set (match_dup 3) (lshiftrt:DI (match_dup 3) (neg:SI (match_dup 2)))) (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 3))) (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))] "" " { if (GET_CODE (operands[2]) == CONST_INT) switch (INTVAL (operands[2])) { case 32: emit_insn (gen_ashrdi3_32 (operands[0], operands[1])); DONE; }

operands[2] = negate_rtx (SImode, operands[2]); operands[3] = force_reg (DImode, immed_double_const (0, 1 << 31, DImode)); }")

;; Arithmetic right 32, a common case that can save a couple of insns.

(define_expand “ashrdi3_32” [(set (match_operand:DI 0 “register_operand” "") (lshiftrt:DI (match_operand:DI 1 “register_operand” "") (const_int 32))) (set (match_dup 0) (sign_extend:DI (subreg:SI (match_dup 0) 0)))] "" "") ;; __builtin instructions

(define_insn “sqrtdf2” [(set (match_operand:DF 0 “register_operand” “=d”) (sqrt:DF (match_operand:DF 1 “register_operand” “0”)))] “! TARGET_C1 && flag_unsafe_math_optimizations” “sqrt.d %0” [(set_attr “type” “divd”)])

(define_insn “sqrtsf2” [(set (match_operand:SF 0 “register_operand” “=d”) (sqrt:SF (match_operand:SF 1 “register_operand” “0”)))] “! TARGET_C1 && flag_unsafe_math_optimizations” “sqrt.s %0” [(set_attr “type” “divs”)])

(define_insn “sindf2” [(set (match_operand:DF 0 “register_operand” “=d”) (unspec:DF [(match_operand:DF 1 “register_operand” “0”)] 1))] “! TARGET_C1 && flag_unsafe_math_optimizations” “sin.d %0”)

(define_insn “sinsf2” [(set (match_operand:SF 0 “register_operand” “=d”) (unspec:SF [(match_operand:SF 1 “register_operand” “0”)] 1))] “! TARGET_C1 && flag_unsafe_math_optimizations” “sin.s %0”)

(define_insn “cosdf2” [(set (match_operand:DF 0 “register_operand” “=d”) (unspec:DF [(match_operand:DF 1 “register_operand” “0”)] 2))] “! TARGET_C1 && flag_unsafe_math_optimizations” “cos.d %0”)

(define_insn “cossf2” [(set (match_operand:SF 0 “register_operand” “=d”) (unspec:SF [(match_operand:SF 1 “register_operand” “0”)] 2))] “! TARGET_C1 && flag_unsafe_math_optimizations” “cos.s %0”)

(define_insn “ftruncdf2” [(set (match_operand:DF 0 “register_operand” “=d”) (fix:DF (match_operand:DF 1 “register_operand” “d”)))] “! TARGET_C1” “frint.d %1,%0” [(set_attr “type” “cvtd”)])

(define_insn “ftruncsf2” [(set (match_operand:SF 0 “register_operand” “=d”) (fix:SF (match_operand:SF 1 “register_operand” “d”)))] “! TARGET_C1” “frint.s %1,%0” [(set_attr “type” “cvts”)])

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=d”) (minus:SI (ffs:SI (match_operand:SI 1 “register_operand” “d”)) (const_int 1)))] "" “tzc %1,%0;le.w #32,%0;jbrs.f L0%=;ld.w #-1,%0\nL0%=:”)

(define_expand “ffssi2” [(set (match_operand:SI 0 “register_operand” “=d”) (minus:SI (ffs:SI (match_operand:SI 1 “register_operand” “d”)) (const_int 1))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "" "")

(define_insn “abssf2” [(set (match_operand:SF 0 “register_operand” “=d”) (abs:SF (match_operand:SF 1 “register_operand” “0”)))] "" “and #0x7fffffff,%0”)

(define_expand “absdf2” [(set (subreg:DI (match_operand:DF 0 “register_operand” “=d”) 0) (and:DI (subreg:DI (match_operand:DF 1 “register_operand” “d”) 0) (match_dup 2)))] "" “operands[2] = force_reg (DImode, immed_double_const (-1, 0x7fffffff, DImode));”) ;;- Compares

(define_insn “cmpdi” [(set (cc0) (compare (match_operand:DI 0 “register_operand” “d”) (match_operand:DI 1 “register_operand” “d”)))] "" “* return output_cmp (operands[0], operands[1], ‘l’);”)

(define_insn "" [(set (cc0) (match_operand:DI 0 “register_operand” “d”)) (clobber (match_scratch:DI 1 “=d”))] “next_insn_tests_no_inequality (insn)” “* return output_cmp (operands[0], operands[1], ‘L’);”)

(define_insn “cmpsi” [(set (cc0) (compare (match_operand:SI 0 “register_operand” “d,a”) (match_operand:SI 1 “nonmemory_operand” “di,ai”)))] "" “* return output_cmp (operands[0], operands[1], ‘w’);”)

(define_insn “cmphi” [(set (cc0) (compare (match_operand:HI 0 “register_operand” “d,a”) (match_operand:HI 1 “nonmemory_operand” “di,ai”)))] "" “* return output_cmp (operands[0], operands[1], ‘h’);”)

; cmpqi is intentionally omitted. ; ; gcc will sign-extend or zero-extend the operands to the next ; wider mode, HImode. ; ; For reg .cmp. constant, we just go with the halfword immediate ; instruction. Perhaps the widening insn can be cse‘d or combined away. ; If not, we’re still as good as loading a byte constant into a register ; to do a reg-reg byte compare. ; ; The following patterns pick up cases that can use reg .cmp. reg after all.

(define_insn "" [(set (cc0) (compare (sign_extend:HI (match_operand:QI 0 “register_operand” “d”)) (sign_extend:HI (match_operand:QI 1 “register_operand” “d”))))] "" “* return output_cmp (operands[0], operands[1], ‘b’);”)

(define_insn "" [(set (cc0) (compare (ashift:HI (subreg:HI (match_operand:QI 0 “register_operand” “d”) 0) (const_int 8)) (ashift:HI (subreg:HI (match_operand:QI 1 “register_operand” “d”) 0) (const_int 8))))] "" “* return output_cmp (operands[0], operands[1], ‘b’);”)

(define_insn "" [(set (cc0) (compare (match_operand:QI 0 “register_operand” “d”) (match_operand:QI 1 “register_operand” “d”)))] "" “* return output_cmp (operands[0], operands[1], ‘b’);”)

(define_insn "" [(set (cc0) (match_operand:QI 0 “register_operand” “d”)) (clobber (match_scratch:QI 1 “=d”))] “next_insn_tests_no_inequality (insn)” “* return output_cmp (operands[0], operands[1], ‘B’);”)

(define_insn "" [(set (cc0) (subreg (match_operand:QI 0 “register_operand” “d”) 0)) (clobber (match_scratch:QI 1 “=d”))] “next_insn_tests_no_inequality (insn)” “* return output_cmp (operands[0], operands[1], ‘B’);”)

(define_insn "" [(set (cc0) (zero_extend (subreg (match_operand:QI 0 “register_operand” “d”) 0))) (clobber (match_scratch:QI 1 “=d”))] “next_insn_tests_no_inequality (insn)” “* return output_cmp (operands[0], operands[1], ‘B’);”)

(define_insn “cmpdf” [(set (cc0) (compare (match_operand:DF 0 “register_operand” “d”) (match_operand:DF 1 “register_operand” “d”)))] "" “* return output_cmp (operands[0], operands[1], ‘d’);”)

(define_insn “cmpsf” [(set (cc0) (compare (match_operand:SF 0 “register_operand” “d”) (match_operand:SF 1 “nonmemory_cmpsf_operand” “dF”)))] "" “* return output_cmp (operands[0], operands[1], ‘s’);”) ;; decrement-and-set-cc0 insns. ;; ;; The most important case where we can use the carry bit from an ;; arithmetic insn to eliminate a redundant compare is the decrement in ;; constructs like while (n--) and while (--n >= 0).
;; ;; We do it with combine patterns instead of NOTICE_UPDATE_CC because ;; the decrement needs to be kept at the end of the block during scheduling. ;; ;; These patterns must have memory alternatives because reload refuses ;; to do output reloads for an insn that sets cc0 (since it does not ;; want to clobber cc0 with its moves). Convex moves do not clobber ;; cc0, but there is no evident way to get reload to know that.

(define_insn "" [(set (cc0) (match_operand:SI 0 “register_operand” “+r,*m”)) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] “next_insn_tests_no_inequality (insn)” “* { if (which_alternative == 0) { output_cmp (operands[0], constm1_rtx, ‘W’); return "add.w #-1,%0"; } else { output_cmp (gen_rtx_REG (SImode, 7), constm1_rtx, ‘W’); return "psh.w s7;ld.w %0,s7;add.w #-1,s7;st.w s7,%0;pop.w s7"; } }”)

(define_insn "" [(set (cc0) (plus:SI (match_operand:SI 0 “register_operand” “+r,*m”) (const_int -1))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] “find_reg_note (next_cc0_user (insn), REG_NONNEG, 0)” “* { if (which_alternative == 0) { output_cmp (operands[0], const0_rtx, ‘W’); return "add.w #-1,%0"; } else { output_cmp (gen_rtx_REG (SImode, 7), const0_rtx, ‘W’); return "psh.w s7;ld.w %0,s7;add.w #-1,s7;st.w s7,%0;pop.w s7"; } }”)

(define_insn "" [(set (cc0) (match_operand:HI 0 “register_operand” “+r,*m”)) (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))] “next_insn_tests_no_inequality (insn)” “* { if (which_alternative == 0) { output_cmp (operands[0], constm1_rtx, ‘H’); return "add.h #-1,%0"; } else { output_cmp (gen_rtx_REG (HImode, 7), constm1_rtx, ‘H’); return "psh.w s7;ld.h %0,s7;add.h #-1,s7;st.h s7,%0;pop.w s7"; } }”)

(define_insn "" [(set (cc0) (plus:HI (match_operand:HI 0 “register_operand” “+r,*m”) (const_int -1))) (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))] “find_reg_note (next_cc0_user (insn), REG_NONNEG, 0)” “* { if (which_alternative == 0) { output_cmp (operands[0], const0_rtx, ‘H’); return "add.h #-1,%0"; } else { output_cmp (gen_rtx_REG (HImode, 7), const0_rtx, ‘H’); return "psh.w s7;ld.h %0,s7;add.h #-1,s7;st.h s7,%0;pop.w s7"; } }”) ;;- Jumps

(define_insn “jump” [(set (pc) (label_ref (match_operand 0 "" "")))] "" “jbr %l0”)

(define_insn “beq” [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "eq", ‘t’); ")

(define_insn “bne” [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "eq", ‘f’); ")

(define_insn “bgt” [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "le", ‘f’); ")

(define_insn “bgtu” [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "leu", ‘f’); ")

(define_insn “blt” [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "lt", ‘t’); ")

(define_insn “bltu” [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "ltu", ‘t’); ")

(define_insn “bge” [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "lt", ‘f’); ")

(define_insn “bgeu” [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "ltu", ‘f’); ")

(define_insn “ble” [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "le", ‘t’); ")

(define_insn “bleu” [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* return output_condjump (operands[0], "leu", ‘t’); ") (define_insn "" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "eq", ‘f’); ")

(define_insn "" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "eq", ‘t’); ")

(define_insn "" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "le", ‘t’); ")

(define_insn "" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "leu", ‘t’); ")

(define_insn "" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "lt", ‘f’); ")

(define_insn "" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "ltu", ‘f’); ")

(define_insn "" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "lt", ‘t’); ")

(define_insn "" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "ltu", ‘t’); ")

(define_insn "" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "le", ‘f’); ")

(define_insn "" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* return output_condjump (operands[0], "leu", ‘f’); ") ;;- Calls

(define_expand “call_pop” [(parallel [(call (match_operand:QI 0 “memory_operand” “m”) (match_operand:SI 1 “const_int_operand” “i”)) (match_operand:SI 2 “const_int_operand” “i”) (match_operand:SI 3 “const_int_operand” “i”) (reg:SI 8)])] "" "")

(define_insn "" [(call (match_operand:QI 0 “memory_operand” “m”) (match_operand:SI 1 “const_int_operand” “i”)) (match_operand:SI 2 “const_int_operand” “i”) (match_operand:SI 3 “const_int_operand” “i”) (match_operand:SI 4 "" "")] "" “* return output_call (insn, &operands[0]);”)

(define_expand “call_value_pop” [(parallel [(set (match_operand 0 "" “=g”) (call (match_operand:QI 1 “memory_operand” “m”) (match_operand:SI 2 “const_int_operand” “i”))) (match_operand:SI 3 “const_int_operand” “i”) (match_operand:SI 4 “const_int_operand” “i”) (reg:SI 8)])] "" "")

(define_insn "" [(set (match_operand 0 "" “=g”) (call (match_operand:QI 1 “memory_operand” “m”) (match_operand:SI 2 “const_int_operand” “i”))) (match_operand:SI 3 “const_int_operand” “i”) (match_operand:SI 4 “const_int_operand” “i”) (match_operand:SI 5 "" "")] "" "* return output_call (insn, &operands[1]); ")

;; Call subroutine returning any type.

(define_expand “untyped_call” [(parallel [(call (match_operand 0 "" "") (const_int 0)) (match_operand 1 "" "") (match_operand 2 "" "")])] "" " { int i;

emit_call_insn (gen_call_pop (operands[0], const0_rtx, const0_rtx, const0_rtx));

for (i = 0; i < XVECLEN (operands[2], 0); i++) { rtx set = XVECEXP (operands[2], 0, i); emit_move_insn (SET_DEST (set), SET_SRC (set)); }

/* The optimizer does not know that the call sets the function value registers we stored in the result block. We avoid problems by claiming that all hard registers are used and clobbered at this point. */ emit_insn (gen_blockage ());

DONE; }")

;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; all of memory. This blocks insns from being moved across this point.

(define_insn “blockage” [(unspec_volatile [(const_int 0)] 0)] "" "")

(define_expand “return” [(return)] "" " replace_arg_pushes (); ")

(define_insn "" [(return)] "" “rtn”)

(define_expand “prologue” [(const_int 0)] "" " { emit_ap_optimizations (); DONE; }")

(define_insn “tablejump” [(set (pc) (match_operand:SI 0 “address_operand” “p”)) (use (label_ref (match_operand 1 "" "")))] "" “jmp %a0”)

(define_insn “indirect_jump” [(set (pc) (match_operand:SI 0 “address_operand” “p”))] "" “jmp %a0”)