8sa1-gcc/gcc/config/convex/convex.md
Richard Kenner dbefdf4a8c Reapply last patch to convex.md which somehow got lost:
Tue Nov  6 09:21:34 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* config/convex/convex.md (movdf): Use it.

From-SVN: r46920
2001-11-11 01:48:55 +00:00

1886 lines
54 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;- 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"))]
"mem_for_const_double (operands[1]) == 0"
"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"))]
"mem_for_const_double (operands[1]) == 0"
"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")