diff options
Diffstat (limited to 'gcc-4.9/gcc/config/arc/fpx.md')
-rw-r--r-- | gcc-4.9/gcc/config/arc/fpx.md | 674 |
1 files changed, 674 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/arc/fpx.md b/gcc-4.9/gcc/config/arc/fpx.md new file mode 100644 index 000000000..4eee6aff9 --- /dev/null +++ b/gcc-4.9/gcc/config/arc/fpx.md @@ -0,0 +1,674 @@ +;; Machine description of the Synopsys DesignWare ARC cpu Floating Point +;; extensions for GNU C compiler +;; Copyright (C) 2007-2014 Free Software Foundation, Inc. + +;; This file is part of GCC. + +;; GCC 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 3, or (at your option) +;; any later version. + +;; GCC 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 GCC; see the file COPYING3. If not see +;; <http://www.gnu.org/licenses/>. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; TODOs: +;; dpfp blocks? +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Scheduler descriptions for the fpx instructions +(define_insn_reservation "spfp_compact" 3 + (and (match_test "TARGET_SPFP_COMPACT_SET") + (eq_attr "type" "spfp")) + "issue+core, nothing*2, write_port") + +(define_insn_reservation "spfp_fast" 6 + (and (match_test "TARGET_SPFP_FAST_SET") + (eq_attr "type" "spfp")) + "issue+core, nothing*5, write_port") + +(define_insn_reservation "dpfp_compact_mult" 7 + (and (match_test "TARGET_DPFP_COMPACT_SET") + (eq_attr "type" "dpfp_mult")) + "issue+core, nothing*6, write_port") + +(define_insn_reservation "dpfp_compact_addsub" 5 + (and (match_test "TARGET_DPFP_COMPACT_SET") + (eq_attr "type" "dpfp_addsub")) + "issue+core, nothing*4, write_port") + +(define_insn_reservation "dpfp_fast" 5 + (and (match_test "TARGET_DPFP_FAST_SET") + (eq_attr "type" "dpfp_mult,dpfp_addsub")) + "issue+core, nothing*4, write_port") + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define_insn "addsf3" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ") + (plus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,GCal,r,0") + (match_operand:SF 2 "nonmemory_operand" "I,rL,r,GCal,LrCal")))] +; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float + "TARGET_SPFP" + "@ + fadd %0,%1,%2 + fadd %0,%1,%2 + fadd %0,%S1,%2 + fadd %0,%1,%S2 + fadd%? %0,%1,%S2" + [(set_attr "type" "spfp") + (set_attr "length" "4,4,8,8,8")]) + +(define_insn "subsf3" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ") + (minus:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0") + (match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))] + ;"(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float + "TARGET_SPFP" + "@ + fsub %0,%1,%2 + fsub %0,%1,%2 + fsub %0,%S1,%2 + fsub %0,%1,%S2 + fsub%? %0,%1,%S2" + [(set_attr "type" "spfp") + (set_attr "length" "4,4,8,8,8")]) + +(define_insn "mulsf3" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ") + (mult:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0") + (match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))] +; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET" ;Add flag for float + "TARGET_SPFP" + "@ + fmul %0,%1,%2 + fmul %0,%1,%2 + fmul %0,%S1,%2 + fmul %0,%1,%S2 + fmul%? %0,%1,%S2" + [(set_attr "type" "spfp") + (set_attr "length" "4,4,8,8,8")]) + + +;; For comparisons, we can avoid storing the top half of the result into +;; a register since '.f' lets us set the Z bit for the conditional +;; branch insns. + +;; ??? FIXME (x-y)==0 is not a correct comparison for floats: +;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm +(define_insn "cmpsfpx_raw" + [(set (reg:CC_FPX 61) + (compare:CC_FPX (match_operand:SF 0 "register_operand" "r") + (match_operand:SF 1 "register_operand" "r")))] + "TARGET_ARGONAUT_SET && TARGET_SPFP" + "fsub.f 0,%0,%1" + [(set_attr "type" "spfp") + (set_attr "length" "4")]) + +;; ??? FIXME (x-y)==0 is not a correct comparison for floats: +;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm +;; ??? FIXME we claim to clobber operand 2, yet the two numbers appended +;; to the actual instructions are incorrect. The result of the d*subh +;; insn is stored in the Dx register specified by that first number. +(define_insn "cmpdfpx_raw" + [(set (reg:CC_FPX 61) + (compare:CC_FPX (match_operand:DF 0 "nonmemory_operand" "D,r") + (match_operand:DF 1 "nonmemory_operand" "r,D"))) + (clobber (match_scratch:DF 2 "=D,D"))] + "TARGET_ARGONAUT_SET && TARGET_DPFP" + "@ + dsubh%F0%F1.f 0,%H2,%L2 + drsubh%F0%F2.f 0,%H1,%L1" + [(set_attr "type" "dpfp_addsub") + (set_attr "length" "4")]) + +;; ??? FIXME subtraction is not a correct comparison for floats: +;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm +(define_insn "*cmpfpx_gt" + [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:CC_FPX 61) (const_int 0)))] + "TARGET_ARGONAUT_SET" + "cmp.ls pcl,pcl" + [(set_attr "type" "compare") + (set_attr "length" "4")]) + +;; ??? FIXME subtraction is not a correct comparison for floats: +;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm +(define_insn "*cmpfpx_ge" + [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:CC_FPX 61) (const_int 0)))] + "TARGET_ARGONAUT_SET" + "rcmp.pnz pcl,0" + [(set_attr "type" "compare") + (set_attr "length" "4")]) + +;; DPFP instructions begin... + +;; op0_reg = D1_reg.low +(define_insn "*lr_double_lower" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_LR ))] + "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" +"lr %0, [%1l] ; *lr_double_lower" +[(set_attr "length" "8") +(set_attr "type" "lr")] +) + +(define_insn "*lr_double_higher" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_LR_HIGH ))] + "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" +"lr %0, [%1h] ; *lr_double_higher" +[(set_attr "length" "8") +(set_attr "type" "lr")] +) + + +(define_insn "*dexcl_3op_peep2_insn" + [(set (match_operand:SI 0 "dest_reg_operand" "=r") ; not register_operand, to accept SUBREG + (unspec_volatile:SI [ + (match_operand:DF 1 "arc_double_register_operand" "D") + (match_operand:SI 2 "shouldbe_register_operand" "r") ; r1 + (match_operand:SI 3 "shouldbe_register_operand" "r") ; r0 + ] VUNSPEC_DEXCL )) + ] + "TARGET_DPFP" + "dexcl%F1 %0, %2, %3" + [(set_attr "type" "move") + (set_attr "length" "4")] +) + +;; version which will not overwrite operand0 +(define_insn "*dexcl_3op_peep2_insn_nores" + [ (unspec_volatile:SI [ + (match_operand:DF 0 "arc_double_register_operand" "D") + (match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 + (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 + ] VUNSPEC_DEXCL_NORES ) + ] + "TARGET_DPFP" + "dexcl%F0 0, %1, %2" + [(set_attr "type" "move") + (set_attr "length" "4")] +) + +;; dexcl a,b,c pattern generated by the peephole2 above +(define_insn "*dexcl_3op_peep2_insn_lr" + [(parallel [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "=D")] VUNSPEC_LR )) + (set (match_dup 1) (match_operand:DF 2 "register_operand" "r"))] + ) + ] + "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" + "dexcl%F1 %0, %H2, %L2" + [(set_attr "type" "move") + (set_attr "length" "4")] +) + + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; doubles support for ARC +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; D0 = D1+{reg_pair}2 +;; (define_expand "adddf3" +;; [(set (match_operand:DF 0 "arc_double_register_operand" "") +;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "") +;; (match_operand:DF 2 "nonmemory_operand" "")))] +;; "TARGET_DPFP" +;; " " +;; ) +;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo +;; OR +;; daddh{0}{1} 0, reg3, limm2.lo +(define_expand "adddf3" + [(set (match_operand:DF 0 "arc_double_register_operand" "") + (plus:DF (match_operand:DF 1 "arc_double_register_operand" "") + (match_operand:DF 2 "nonmemory_operand" ""))) + ] + "TARGET_DPFP" + " if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + rtx high, low, tmp; + split_double (operands[2], &low, &high); + tmp = force_reg (SImode, high); + emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx)); + } + else + emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx)); + DONE; + " +) + +;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/ +;; OR +;; daddh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0 */ +;; +(define_insn "adddf3_insn" + [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") + (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") + (match_operand:DF 2 "nonmemory_operand" "!r,G"))) + (use (match_operand:SI 3 "" "N,r")) + (use (match_operand:SI 4 "" "N,Q")) + ; Prevent can_combine_p from combining muldf3_insn patterns with + ; different USE pairs. + (use (match_dup 2)) + ] + "TARGET_DPFP && + !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" + "@ + daddh%F0%F1 0,%H2,%L2 + daddh%F0%F1 0,%3,%L2" + [(set_attr "type" "dpfp_addsub") + (set_attr "length" "4,8")]) + +;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo +;; OR +;; dmulh{0}{1} 0, reg3, limm2.lo +(define_expand "muldf3" + [(set (match_operand:DF 0 "arc_double_register_operand" "") + (mult:DF (match_operand:DF 1 "arc_double_register_operand" "") + (match_operand:DF 2 "nonmemory_operand" "")))] +"TARGET_DPFP" +" if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + rtx high, low, tmp; + split_double (operands[2], &low, &high); + tmp = force_reg (SImode, high); + emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx)); + } + else + emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx)); + + DONE; + ") + + +;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/ +;; OR +;; dmulh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/ +(define_insn "muldf3_insn" + [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") + (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") + (match_operand:DF 2 "nonmemory_operand" "!r,G"))) + (use (match_operand:SI 3 "" "N,!r")) + (use (match_operand:SI 4 "" "N,Q")) + ; Prevent can_combine_p from combining muldf3_insn patterns with + ; different USE pairs. + (use (match_dup 2)) + ] + "TARGET_DPFP && + !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" + "@ + dmulh%F0%F1 0,%H2,%L2 + dmulh%F0%F1 0,%3, %L2" + [(set_attr "type" "dpfp_mult") + (set_attr "length" "4,8")]) + +;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo +;; OR +;; dsubh{0}{1} 0, reg3, limm2.lo +;; OR +;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo +;; OR +;; drsubh{0}{2} 0, reg3, limm1.lo +(define_expand "subdf3" + [(set (match_operand:DF 0 "arc_double_register_operand" "") + (minus:DF (match_operand:DF 1 "nonmemory_operand" "") + (match_operand:DF 2 "nonmemory_operand" "")))] +"TARGET_DPFP" +" if (GET_CODE (operands[1]) == CONST_DOUBLE || GET_CODE (operands[2]) == CONST_DOUBLE) + { + rtx high, low, tmp; + int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1: 2); + split_double (operands[const_index], &low, &high); + tmp = force_reg (SImode, high); + emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx)); + } + else + emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx)); + + DONE; + " +) + +;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */ +;; OR +;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/ +;; OR +;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo /* operand 4 = 1 */ +;; OR +;; drsubh{0}{2} 0, reg3, limm1.lo /* operand 4 = 0*/ +(define_insn "subdf3_insn" + [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D") + (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,!r,G") + (match_operand:DF 2 "nonmemory_operand" "!r,G,D,D"))) + (use (match_operand:SI 3 "" "N,r,N,r")) + (use (match_operand:SI 4 "" "N,Q,N,Q")) + ; Prevent can_combine_p from combining muldf3_insn patterns with + ; different USE pairs. + (use (match_dup 2))] + "TARGET_DPFP && + !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) && + !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" + "@ + dsubh%F0%F1 0,%H2,%L2 + dsubh%F0%F1 0,%3,%L2 + drsubh%F0%F2 0,%H1,%L1 + drsubh%F0%F2 0,%3,%L1" + [(set_attr "type" "dpfp_addsub") + (set_attr "length" "4,8,4,8")]) + +;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; Peephole for following conversion +;; ;; D0 = D2<op>{reg_pair}3 +;; ;; {reg_pair}5 = D0 +;; ;; D0 = {reg_pair}6 +;; ;; | +;; ;; V +;; ;; _________________________________________________________ +;; ;; / D0 = D2 <op> {regpair3_or_limmreg34} +;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi +;; ;; | \_________________________________________________________ +;; ;; | +;; ;; | ________________________________________________________ +;; ;; | / {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo +;; ;; +-----+ D0 = {reg_pair}6 +;; ;; \ _________________________________________________________ +;; ;; || +;; ;; || +;; ;; \/ +;; ;; d<op>{0}{2}h {reg_pair}5.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi +;; ;; dexcl{0} {reg_pair}5.lo, {reg_pair}6.lo, {reg_pair}6.hi +;; ;; ----------------------------------------------------------------------------------------- +;; ;; where <op> is one of {+,*,-} +;; ;; <opname> is {add,mult,sub} +;; ;; +;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as +;; ;; {regpair2_or_limmreg24} and D3 +;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (define_peephole2 +;; [(parallel [(set (match_operand:DF 0 "register_operand" "") +;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") +;; (match_operand:DF 3 "nonmemory_operand" "")])) +;; (use (match_operand:SI 4 "" ""))]) +;; (set (match_operand:DF 5 "register_operand" "") +;; (match_dup 0)) +;; (set (match_dup 0) +;; (match_operand:DF 6 "register_operand" "")) +;; ] +;; "TARGET_DPFP" +;; [ +;; (parallel [(set (match_dup 0) +;; (match_op_dup:DF 1 [(match_dup 2) +;; (match_dup 3)])) +;; (use (match_dup 4)) +;; (set (match_dup 5) +;; (match_op_dup:DF 1 [(match_dup 2) +;; (match_dup 3)]))]) +;; (parallel [ +;; ;; (set (subreg:SI (match_dup 5) 0) +;; (set (match_dup 7) +;; (unspec_volatile [(match_dup 0)] VUNSPEC_LR )) +;; (set (match_dup 0) (match_dup 6))] +;; ) +;; ] +;; "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);" +;; ) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Peephole for following conversion +;; D0 = D2<op>{reg_pair}3 +;; {reg_pair}6 = D0 +;; D0 = {reg_pair}7 +;; | +;; V +;; _________________________________________________________ +;; / D0 = D2 <op> {regpair3_or_limmreg34} +;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi +;; | \_________________________________________________________ +;; | +;; | ________________________________________________________ +;; | / {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo +;; +-----+ D0 = {reg_pair}7 +;; \ _________________________________________________________ +;; || +;; || +;; \/ +;; d<op>{0}{2}h {reg_pair}6.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi +;; dexcl{0} {reg_pair}6.lo, {reg_pair}7.lo, {reg_pair}7.hi +;; ----------------------------------------------------------------------------------------- +;; where <op> is one of {+,*,-} +;; <opname> is {add,mult,sub} +;; +;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as +;; {regpair2_or_limmreg24} and D3 +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_peephole2 + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") + (match_operand:DF 3 "nonmemory_operand" "")])) + (use (match_operand:SI 4 "" "")) + (use (match_operand:SI 5 "" "")) + (use (match_operand:SI 6 "" ""))]) + (set (match_operand:DF 7 "register_operand" "") + (match_dup 0)) + (set (match_dup 0) + (match_operand:DF 8 "register_operand" "")) + ] + "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" + [ + (parallel [(set (match_dup 0) + (match_op_dup:DF 1 [(match_dup 2) + (match_dup 3)])) + (use (match_dup 4)) + (use (match_dup 5)) + (set (match_dup 7) + (match_op_dup:DF 1 [(match_dup 2) + (match_dup 3)]))]) + (parallel [ +;; (set (subreg:SI (match_dup 7) 0) + (set (match_dup 9) + (unspec_volatile:SI [(match_dup 0)] VUNSPEC_LR )) + (set (match_dup 0) (match_dup 8))] + ) + ] + "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);" + ) + +;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; Peephole to generate d<opname>{ij}h a,b,c instructions +;; ;; D0 = D2<op>{reg_pair}3 +;; ;; {reg_pair}5 = D0 +;; ;; | +;; ;; V +;; ;; __________________________________________ +;; ;; / D0 = D2 <op> {regpair3_or_limmreg34} +;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi +;; ;; | \__________________________________________ +;; ;; | +;; ;; + --- {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo +;; ;; || +;; ;; || +;; ;; \/ +;; ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi +;; ;; lr {reg_pair}4.lo, {D2l} +;; ;; ---------------------------------------------------------------------------------------- +;; ;; where <op> is one of {+,*,-} +;; ;; <opname> is {add,mult,sub} +;; ;; +;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as +;; ;; {regpair2_or_limmreg24} and D3 +;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; (define_peephole2 +;; [(parallel [(set (match_operand:DF 0 "register_operand" "") +;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") +;; (match_operand:DF 3 "nonmemory_operand" "")])) +;; (use (match_operand:SI 4 "" ""))]) +;; (set (match_operand:DF 5 "register_operand" "") +;; (match_dup 0)) +;; ] +;; "TARGET_DPFP" +;; [ +;; (parallel [(set (match_dup 0) +;; (match_op_dup:DF 1 [(match_dup 2) +;; (match_dup 3)])) +;; (use (match_dup 4)) +;; (set (match_dup 5) +;; (match_op_dup:DF 1 [(match_dup 2) +;; (match_dup 3)]))]) +;; ; (set (subreg:SI (match_dup 5) 0) +;; (set (match_dup 6) +;; (unspec_volatile [(match_dup 0)] VUNSPEC_LR )) +;; ] +;; "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);" +;; ) +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Peephole to generate d<opname>{ij}h a,b,c instructions +;; D0 = D2<op>{reg_pair}3 +;; {reg_pair}6 = D0 +;; | +;; V +;; __________________________________________ +;; / D0 = D2 <op> {regpair3_or_limmreg34} +;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi +;; | \__________________________________________ +;; | +;; + --- {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo +;; || +;; || +;; \/ +;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi +;; lr {reg_pair}4.lo, {D2l} +;; ---------------------------------------------------------------------------------------- +;; where <op> is one of {+,*,-} +;; <opname> is {add,mult,sub} +;; +;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as +;; {regpair2_or_limmreg24} and D3 +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define_peephole2 + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "") + (match_operand:DF 3 "nonmemory_operand" "")])) + (use (match_operand:SI 4 "" "")) + (use (match_operand:SI 5 "" "")) + (use (match_operand:SI 6 "" ""))]) + (set (match_operand:DF 7 "register_operand" "") + (match_dup 0)) + ] + "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR" + [ + (parallel [(set (match_dup 0) + (match_op_dup:DF 1 [(match_dup 2) + (match_dup 3)])) + (use (match_dup 4)) + (use (match_dup 5)) + (set (match_dup 7) + (match_op_dup:DF 1 [(match_dup 2) + (match_dup 3)]))]) +; (set (subreg:SI (match_dup 7) 0) + (set (match_dup 8) + (unspec_volatile:SI [(match_dup 0)] VUNSPEC_LR )) + ] + "operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);" + ) + +;; ;; _______________________________________________________ +;; ;; / D0 = D1 + {regpair2_or_limmreg23} +;; ;; + {reg_pair}4.hi = ( D1 + {regpair2_or_limmreg23} ).hi +;; ;; \_______________________________________________________ +;; (define_insn "*daddh_peep2_insn" +;; [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") +;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") +;; (match_operand:DF 2 "nonmemory_operand" "r,G"))) +;; (use (match_operand:SI 3 "" "N,r")) +;; (set (match_operand:DF 4 "register_operand" "=r,r") +;; (plus:DF (match_dup 1) +;; (match_dup 2)))])] +;; "TARGET_DPFP" +;; "@ +;; daddh%F0%F1 %H4, %H2, %L2 +;; daddh%F0%F1 %H4, %3, %L2" +;; [(set_attr "type" "dpfp_addsub") +;; (set_attr "length" "4,8")] +;; ) +;; _______________________________________________________ +;; / D0 = D1 + {regpair2_or_limmreg23} +;; + {reg_pair}5.hi = ( D1 + {regpair2_or_limmreg23} ).hi +;; \_______________________________________________________ +(define_insn "*daddh_peep2_insn" + [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") + (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") + (match_operand:DF 2 "nonmemory_operand" "r,G"))) + (use (match_operand:SI 3 "" "N,r")) + (use (match_operand:SI 4 "" "N,Q")) + (use (match_operand:SI 5 "" "")) + (set (match_operand:DF 6 "register_operand" "=r,r") + (plus:DF (match_dup 1) + (match_dup 2)))])] + "TARGET_DPFP && + !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" + "@ + daddh%F0%F1 %H6, %H2, %L2 + daddh%F0%F1 %H6, %3, %L2" + [(set_attr "type" "dpfp_addsub") + (set_attr "length" "4,8")] +) + +;; _______________________________________________________ +;; / D0 = D1 * {regpair2_or_limmreg23} +;; + {reg_pair}5.hi = ( D1 * {regpair2_or_limmreg23} ).hi +;; \_______________________________________________________ +(define_insn "*dmulh_peep2_insn" + [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D") + (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D") + (match_operand:DF 2 "nonmemory_operand" "r,G"))) + (use (match_operand:SI 3 "" "N,r")) + (use (match_operand:SI 4 "" "N,Q")) + (use (match_operand:SI 5 "" "")) + (set (match_operand:DF 6 "register_operand" "=r,r") + (mult:DF (match_dup 1) + (match_dup 2)))])] + "TARGET_DPFP && + !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" + "@ + dmulh%F0%F1 %H6, %H2, %L2 + dmulh%F0%F1 %H6, %3, %L2" + [(set_attr "type" "dpfp_mult") + (set_attr "length" "4,8")] +) + +;; _______________________________________________________ +;; / D0 = D1 - {regpair2_or_limmreg23} +;; + {reg_pair}5.hi = ( D1 - {regpair2_or_limmreg23} ).hi +;; \_______________________________________________________ +;; OR +;; _______________________________________________________ +;; / D0 = {regpair1_or_limmreg13} - D2 +;; + {reg_pair}5.hi = ( {regpair1_or_limmreg13} ).hi - D2 +;; \_______________________________________________________ +(define_insn "*dsubh_peep2_insn" + [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D") + (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,r,G") + (match_operand:DF 2 "nonmemory_operand" "r,G,D,D"))) + (use (match_operand:SI 3 "" "N,r,N,r")) + (use (match_operand:SI 4 "" "N,Q,N,Q")) + (use (match_operand:SI 5 "" "")) + (set (match_operand:DF 6 "register_operand" "=r,r,r,r") + (minus:DF (match_dup 1) + (match_dup 2)))])] + "TARGET_DPFP && + !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) && + !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)" + "@ + dsubh%F0%F1 %H6, %H2, %L2 + dsubh%F0%F1 %H6, %3, %L2 + drsubh%F0%F2 %H6, %H1, %L1 + drsubh%F0%F2 %H6, %3, %L1" + [(set_attr "type" "dpfp_addsub") + (set_attr "length" "4,8,4,8")] +) |