;; Machine description of the Synopsys DesignWare ARC cpu Floating Point ;; extensions for GNU C compiler ;; Copyright (C) 2007-2017 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 ;; . ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 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_fpx" [(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_fpx" [(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_fpx" [(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_ARC_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_ARC_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:SI 1 "shouldbe_register_operand" "r") ; r1 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 ] VUNSPEC_ARC_DEXCL )) (clobber (match_operand:DF 3 "arc_double_register_operand" "=&D"))] "TARGET_DPFP" "dexcl%F3 %0, %1, %2" [(set_attr "type" "move") (set_attr "length" "4")] ) ;; version which will not overwrite operand0 (define_insn "dexcl_2op" [(set (match_operand:DF 0 "arc_double_register_operand" "=D") (unspec_volatile:DF [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 ] VUNSPEC_ARC_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_ARC_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 ;; 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 ;; 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 ;; 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") (set_attr "cpu_facility" "*,*,fpx,fpx")]) ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Peephole for following conversion ;; ;; D0 = D2{reg_pair}3 ;; ;; {reg_pair}5 = D0 ;; ;; D0 = {reg_pair}6 ;; ;; | ;; ;; V ;; ;; _________________________________________________________ ;; ;; / D0 = D2 {regpair3_or_limmreg34} ;; ;; ---- + {reg_pair}5.hi = ( D2{regpair3_or_limmreg34} ).hi ;; ;; | \_________________________________________________________ ;; ;; | ;; ;; | ________________________________________________________ ;; ;; | / {reg_pair}5.lo = ( D2{regpair3_or_limmreg34} ).lo ;; ;; +-----+ D0 = {reg_pair}6 ;; ;; \ _________________________________________________________ ;; ;; || ;; ;; || ;; ;; \/ ;; ;; d{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 is one of {+,*,-} ;; ;; 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_ARC_LR )) ;; (set (match_dup 0) (match_dup 6))] ;; ) ;; ] ;; "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);" ;; ) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Peephole for following conversion ;; D0 = D2{reg_pair}3 ;; {reg_pair}6 = D0 ;; D0 = {reg_pair}7 ;; | ;; V ;; _________________________________________________________ ;; / D0 = D2 {regpair3_or_limmreg34} ;; ---- + {reg_pair}6.hi = ( D2{regpair3_or_limmreg34} ).hi ;; | \_________________________________________________________ ;; | ;; | ________________________________________________________ ;; | / {reg_pair}6.lo = ( D2{regpair3_or_limmreg34} ).lo ;; +-----+ D0 = {reg_pair}7 ;; \ _________________________________________________________ ;; || ;; || ;; \/ ;; d{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 is one of {+,*,-} ;; 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_ARC_LR )) (set (match_dup 0) (match_dup 8))] ) ] "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);" ) ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Peephole to generate d{ij}h a,b,c instructions ;; ;; D0 = D2{reg_pair}3 ;; ;; {reg_pair}5 = D0 ;; ;; | ;; ;; V ;; ;; __________________________________________ ;; ;; / D0 = D2 {regpair3_or_limmreg34} ;; ;; ---- + {reg_pair}5.hi = ( D2{regpair3_or_limmreg34} ).hi ;; ;; | \__________________________________________ ;; ;; | ;; ;; + --- {reg_pair}5.lo = ( D2{regpair3_or_limmreg34} ).lo ;; ;; || ;; ;; || ;; ;; \/ ;; ;; d{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi ;; ;; lr {reg_pair}4.lo, {D2l} ;; ;; ---------------------------------------------------------------------------------------- ;; ;; where is one of {+,*,-} ;; ;; 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_ARC_LR )) ;; ] ;; "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);" ;; ) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Peephole to generate d{ij}h a,b,c instructions ;; D0 = D2{reg_pair}3 ;; {reg_pair}6 = D0 ;; | ;; V ;; __________________________________________ ;; / D0 = D2 {regpair3_or_limmreg34} ;; ---- + {reg_pair}6.hi = ( D2{regpair3_or_limmreg34} ).hi ;; | \__________________________________________ ;; | ;; + --- {reg_pair}6.lo = ( D2{regpair3_or_limmreg34} ).lo ;; || ;; || ;; \/ ;; d{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi ;; lr {reg_pair}4.lo, {D2l} ;; ---------------------------------------------------------------------------------------- ;; where is one of {+,*,-} ;; 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_ARC_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") (set_attr "cpu_facility" "*,*,fpx,fpx")]) ;; Intel QUARK SE extensions (define_mode_iterator QUARK_CMP [CC_FP_GT CC_FP_GE]) (define_mode_attr quark_cmp [(CC_FP_GT "gt") (CC_FP_GE "ge")]) (define_expand "cmp_quark" [(parallel [(set (match_operand 0 "") (match_operand 1 "")) (clobber (match_scratch:SI 2 ""))])] "" "") (define_insn "*cmpsf_quark_" [(set (reg:QUARK_CMP CC_REG) (compare:QUARK_CMP (match_operand:SF 0 "register_operand" "r") (match_operand:SF 1 "register_operand" "r"))) (clobber (match_scratch:SI 2 "=&r"))] "TARGET_FPX_QUARK" "dsp_fp_cmp\\t%2,%0,%1\\n\\trsub.f\\t0,%2,7\\n\\tcmp.nc\\t%2,1\\n\\tcmp.hi\\t%2,3" [(set_attr "length" "16") (set_attr "cond" "set") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) (define_insn "*cmpsf_quark_ord" [(set (reg:CC_FP_ORD CC_REG) (compare:CC_FP_ORD (match_operand:SF 0 "register_operand" "r") (match_operand:SF 1 "register_operand" "r"))) (clobber (match_scratch:SI 2 "=&r"))] "TARGET_FPX_QUARK" "dsp_fp_cmp\\t%2,%0,%1\\n\\tadd.f\\t%2,%2,-8" [(set_attr "length" "8") (set_attr "cond" "set") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) (define_insn "*cmpsf_quark_uneq" [(set (reg:CC_FP_UNEQ CC_REG) (compare:CC_FP_UNEQ (match_operand:SF 0 "register_operand" "r") (match_operand:SF 1 "register_operand" "r"))) (clobber (match_scratch:SI 2 "=&r"))] "TARGET_FPX_QUARK" "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,6" [(set_attr "length" "8") (set_attr "cond" "set") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) (define_insn "*cmpsf_quark_eq" [(set (reg:CC_Z CC_REG) (compare:CC_Z (match_operand:SF 0 "register_operand" "r") (match_operand:SF 1 "register_operand" "r"))) (clobber (match_scratch:SI 2 "=&r"))] "TARGET_FPX_QUARK" "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,0x0E" [(set_attr "length" "8") (set_attr "cond" "set") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) (define_insn "*divsf3_quark" [(set (match_operand:SF 0 "register_operand" "=r") (div:SF (match_operand:SF 1 "register_operand" "r") (match_operand:SF 2 "register_operand" "r")))] "TARGET_FPX_QUARK" "dsp_fp_div\\t%0,%1,%2" [(set_attr "length" "4") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) (define_insn "*sqrtsf2_quark" [(set (match_operand:SF 0 "register_operand" "=r") (sqrt:SF (match_operand:SF 1 "register_operand" "r")))] "TARGET_FPX_QUARK" "dsp_fp_sqrt\\t%0,%1" [(set_attr "length" "4") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) ;; SF->SI (using rounding towards zero) (define_insn "*fix_truncsfsi2_quark" [(set (match_operand:SI 0 "register_operand" "=r") (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))] "TARGET_FPX_QUARK" "dsp_fp_flt2i\\t%0,%1" [(set_attr "length" "4") (set_attr "predicable" "no") (set_attr "cond" "nocond")]) ;; SI->SF (define_insn "*floatsisf2_quark" [(set (match_operand:SF 0 "register_operand" "=r") (float:SF (match_operand:SI 1 "register_operand" "r")))] "TARGET_FPX_QUARK" "dsp_fp_i2flt\\t%0,%1" [(set_attr "length" "4") (set_attr "predicable" "no") (set_attr "cond" "nocond")])