1 ;; Machine description of the Synopsys DesignWare ARC cpu Floating Point
2 ;; extensions for GNU C compiler
3 ;; Copyright (C) 2007-2018 Free Software Foundation, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
24 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25 ;; Scheduler descriptions for the fpx instructions
26 (define_insn_reservation "spfp_compact" 3
27 (and (match_test "TARGET_SPFP_COMPACT_SET")
28 (eq_attr "type" "spfp"))
29 "issue+core, nothing*2, write_port")
31 (define_insn_reservation "spfp_fast" 6
32 (and (match_test "TARGET_SPFP_FAST_SET")
33 (eq_attr "type" "spfp"))
34 "issue+core, nothing*5, write_port")
36 (define_insn_reservation "dpfp_compact_mult" 7
37 (and (match_test "TARGET_DPFP_COMPACT_SET")
38 (eq_attr "type" "dpfp_mult"))
39 "issue+core, nothing*6, write_port")
41 (define_insn_reservation "dpfp_compact_addsub" 5
42 (and (match_test "TARGET_DPFP_COMPACT_SET")
43 (eq_attr "type" "dpfp_addsub"))
44 "issue+core, nothing*4, write_port")
46 (define_insn_reservation "dpfp_fast" 5
47 (and (match_test "TARGET_DPFP_FAST_SET")
48 (eq_attr "type" "dpfp_mult,dpfp_addsub"))
49 "issue+core, nothing*4, write_port")
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53 (define_insn "*addsf3_fpx"
54 [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
55 (plus:SF (match_operand:SF 1 "nonmemory_operand" "0,r,GCal,r,0")
56 (match_operand:SF 2 "nonmemory_operand" "I,rL,r,GCal,LrCal")))]
57 ; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float
65 [(set_attr "type" "spfp")
66 (set_attr "length" "4,4,8,8,8")])
68 (define_insn "*subsf3_fpx"
69 [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
70 (minus:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0")
71 (match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))]
72 ;"(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET";Add flag for float
80 [(set_attr "type" "spfp")
81 (set_attr "length" "4,4,8,8,8")])
83 (define_insn "*mulsf3_fpx"
84 [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r ")
85 (mult:SF (match_operand:SF 1 "nonmemory_operand" "r,0,GCal,r,0")
86 (match_operand:SF 2 "nonmemory_operand" "rL,I,r,GCal,LrCal")))]
87 ; "(TARGET_ARC700 || TARGET_ARC600) && TARGET_SPFP_SET" ;Add flag for float
95 [(set_attr "type" "spfp")
96 (set_attr "length" "4,4,8,8,8")])
99 ;; For comparisons, we can avoid storing the top half of the result into
100 ;; a register since '.f' lets us set the Z bit for the conditional
103 ;; ??? FIXME (x-y)==0 is not a correct comparison for floats:
104 ;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
105 (define_insn "cmpsfpx_raw"
106 [(set (reg:CC_FPX 61)
107 (compare:CC_FPX (match_operand:SF 0 "register_operand" "r")
108 (match_operand:SF 1 "register_operand" "r")))]
109 "TARGET_ARGONAUT_SET && TARGET_SPFP"
111 [(set_attr "type" "spfp")
112 (set_attr "length" "4")])
114 ;; ??? FIXME (x-y)==0 is not a correct comparison for floats:
115 ;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
116 ;; ??? FIXME we claim to clobber operand 2, yet the two numbers appended
117 ;; to the actual instructions are incorrect. The result of the d*subh
118 ;; insn is stored in the Dx register specified by that first number.
119 (define_insn "cmpdfpx_raw"
120 [(set (reg:CC_FPX 61)
121 (compare:CC_FPX (match_operand:DF 0 "nonmemory_operand" "D,r")
122 (match_operand:DF 1 "nonmemory_operand" "r,D")))
123 (clobber (match_scratch:DF 2 "=D,D"))]
124 "TARGET_ARGONAUT_SET && TARGET_DPFP"
126 dsubh%F0%F1.f 0,%H2,%L2
127 drsubh%F0%F2.f 0,%H1,%L1"
128 [(set_attr "type" "dpfp_addsub")
129 (set_attr "length" "4")])
131 ;; ??? FIXME subtraction is not a correct comparison for floats:
132 ;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
133 (define_insn "*cmpfpx_gt"
134 [(set (reg:CC_FP_GT 61) (compare:CC_FP_GT (reg:CC_FPX 61) (const_int 0)))]
135 "TARGET_ARGONAUT_SET"
137 [(set_attr "type" "compare")
138 (set_attr "length" "4")])
140 ;; ??? FIXME subtraction is not a correct comparison for floats:
141 ;; http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
142 (define_insn "*cmpfpx_ge"
143 [(set (reg:CC_FP_GE 61) (compare:CC_FP_GE (reg:CC_FPX 61) (const_int 0)))]
144 "TARGET_ARGONAUT_SET"
146 [(set_attr "type" "compare")
147 (set_attr "length" "4")])
149 ;; DPFP instructions begin...
151 ;; op0_reg = D1_reg.low
152 (define_insn "*lr_double_lower"
153 [(set (match_operand:SI 0 "register_operand" "=r")
154 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_ARC_LR ))]
155 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
156 "lr %0, [%1l] ; *lr_double_lower"
157 [(set_attr "length" "8")
158 (set_attr "type" "lr")]
161 (define_insn "*lr_double_higher"
162 [(set (match_operand:SI 0 "register_operand" "=r")
163 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")]
164 VUNSPEC_ARC_LR_HIGH ))]
165 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
166 "lr %0, [%1h] ; *lr_double_higher"
167 [(set_attr "length" "8")
168 (set_attr "type" "lr")]
171 (define_insn "*dexcl_3op_peep2_insn"
172 [(set (match_operand:SI 0 "dest_reg_operand" "=r") ; not register_operand, to accept SUBREG
174 [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1
175 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0
176 ] VUNSPEC_ARC_DEXCL ))
177 (clobber (match_operand:DF 3 "arc_double_register_operand" "=&D"))]
179 "dexcl%F3 %0, %1, %2"
180 [(set_attr "type" "move")
181 (set_attr "length" "4")]
184 ;; version which will not overwrite operand0
185 (define_insn "dexcl_2op"
186 [(set (match_operand:DF 0 "arc_double_register_operand" "=D")
188 [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1
189 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0
190 ] VUNSPEC_ARC_DEXCL_NORES))
194 [(set_attr "type" "move")
195 (set_attr "length" "4")]
198 ;; dexcl a,b,c pattern generated by the peephole2 above
199 (define_insn "*dexcl_3op_peep2_insn_lr"
200 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
201 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "=D")] VUNSPEC_ARC_LR ))
202 (set (match_dup 1) (match_operand:DF 2 "register_operand" "r"))]
205 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
206 "dexcl%F1 %0, %H2, %L2"
207 [(set_attr "type" "move")
208 (set_attr "length" "4")]
212 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213 ;; doubles support for ARC
214 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
216 ;; D0 = D1+{reg_pair}2
217 ;; (define_expand "adddf3"
218 ;; [(set (match_operand:DF 0 "arc_double_register_operand" "")
219 ;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "")
220 ;; (match_operand:DF 2 "nonmemory_operand" "")))]
224 ;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
226 ;; daddh{0}{1} 0, reg3, limm2.lo
227 ;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
229 ;; daddh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0 */
231 (define_insn "adddf3_insn"
232 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
233 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
234 (match_operand:DF 2 "nonmemory_operand" "!r,G")))
235 (use (match_operand:SI 3 "" "N,r"))
236 (use (match_operand:SI 4 "" "N,Q"))
237 ; Prevent can_combine_p from combining muldf3_insn patterns with
238 ; different USE pairs.
242 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
244 daddh%F0%F1 0,%H2,%L2
245 daddh%F0%F1 0,%3,%L2"
246 [(set_attr "type" "dpfp_addsub")
247 (set_attr "length" "4,8")])
249 ;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
251 ;; dmulh{0}{1} 0, reg3, limm2.lo
252 ;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
254 ;; dmulh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
255 (define_insn "muldf3_insn"
256 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
257 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
258 (match_operand:DF 2 "nonmemory_operand" "!r,G")))
259 (use (match_operand:SI 3 "" "N,!r"))
260 (use (match_operand:SI 4 "" "N,Q"))
261 ; Prevent can_combine_p from combining muldf3_insn patterns with
262 ; different USE pairs.
266 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
268 dmulh%F0%F1 0,%H2,%L2
269 dmulh%F0%F1 0,%3, %L2"
270 [(set_attr "type" "dpfp_mult")
271 (set_attr "length" "4,8")])
273 ;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
275 ;; dsubh{0}{1} 0, reg3, limm2.lo
277 ;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo
279 ;; drsubh{0}{2} 0, reg3, limm1.lo
280 ;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */
282 ;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
284 ;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo /* operand 4 = 1 */
286 ;; drsubh{0}{2} 0, reg3, limm1.lo /* operand 4 = 0*/
287 (define_insn "subdf3_insn"
288 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D")
289 (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,!r,G")
290 (match_operand:DF 2 "nonmemory_operand" "!r,G,D,D")))
291 (use (match_operand:SI 3 "" "N,r,N,r"))
292 (use (match_operand:SI 4 "" "N,Q,N,Q"))
293 ; Prevent can_combine_p from combining muldf3_insn patterns with
294 ; different USE pairs.
297 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) &&
298 !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
300 dsubh%F0%F1 0,%H2,%L2
302 drsubh%F0%F2 0,%H1,%L1
303 drsubh%F0%F2 0,%3,%L1"
304 [(set_attr "type" "dpfp_addsub")
305 (set_attr "length" "4,8,4,8")
306 (set_attr "cpu_facility" "*,*,fpx,fpx")])
308 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
309 ;; ;; Peephole for following conversion
310 ;; ;; D0 = D2<op>{reg_pair}3
311 ;; ;; {reg_pair}5 = D0
312 ;; ;; D0 = {reg_pair}6
315 ;; ;; _________________________________________________________
316 ;; ;; / D0 = D2 <op> {regpair3_or_limmreg34}
317 ;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
318 ;; ;; | \_________________________________________________________
320 ;; ;; | ________________________________________________________
321 ;; ;; | / {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
322 ;; ;; +-----+ D0 = {reg_pair}6
323 ;; ;; \ _________________________________________________________
327 ;; ;; d<op>{0}{2}h {reg_pair}5.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
328 ;; ;; dexcl{0} {reg_pair}5.lo, {reg_pair}6.lo, {reg_pair}6.hi
329 ;; ;; -----------------------------------------------------------------------------------------
330 ;; ;; where <op> is one of {+,*,-}
331 ;; ;; <opname> is {add,mult,sub}
333 ;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
334 ;; ;; {regpair2_or_limmreg24} and D3
335 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
337 ;; [(parallel [(set (match_operand:DF 0 "register_operand" "")
338 ;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
339 ;; (match_operand:DF 3 "nonmemory_operand" "")]))
340 ;; (use (match_operand:SI 4 "" ""))])
341 ;; (set (match_operand:DF 5 "register_operand" "")
343 ;; (set (match_dup 0)
344 ;; (match_operand:DF 6 "register_operand" ""))
348 ;; (parallel [(set (match_dup 0)
349 ;; (match_op_dup:DF 1 [(match_dup 2)
351 ;; (use (match_dup 4))
352 ;; (set (match_dup 5)
353 ;; (match_op_dup:DF 1 [(match_dup 2)
354 ;; (match_dup 3)]))])
356 ;; ;; (set (subreg:SI (match_dup 5) 0)
357 ;; (set (match_dup 7)
358 ;; (unspec_volatile [(match_dup 0)] VUNSPEC_ARC_LR ))
359 ;; (set (match_dup 0) (match_dup 6))]
362 ;; "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
364 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
365 ;; Peephole for following conversion
366 ;; D0 = D2<op>{reg_pair}3
371 ;; _________________________________________________________
372 ;; / D0 = D2 <op> {regpair3_or_limmreg34}
373 ;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
374 ;; | \_________________________________________________________
376 ;; | ________________________________________________________
377 ;; | / {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
378 ;; +-----+ D0 = {reg_pair}7
379 ;; \ _________________________________________________________
383 ;; d<op>{0}{2}h {reg_pair}6.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
384 ;; dexcl{0} {reg_pair}6.lo, {reg_pair}7.lo, {reg_pair}7.hi
385 ;; -----------------------------------------------------------------------------------------
386 ;; where <op> is one of {+,*,-}
387 ;; <opname> is {add,mult,sub}
389 ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
390 ;; {regpair2_or_limmreg24} and D3
391 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
393 [(parallel [(set (match_operand:DF 0 "register_operand" "")
394 (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
395 (match_operand:DF 3 "nonmemory_operand" "")]))
396 (use (match_operand:SI 4 "" ""))
397 (use (match_operand:SI 5 "" ""))
398 (use (match_operand:SI 6 "" ""))])
399 (set (match_operand:DF 7 "register_operand" "")
402 (match_operand:DF 8 "register_operand" ""))
404 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
406 (parallel [(set (match_dup 0)
407 (match_op_dup:DF 1 [(match_dup 2)
412 (match_op_dup:DF 1 [(match_dup 2)
415 ;; (set (subreg:SI (match_dup 7) 0)
417 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
418 (set (match_dup 0) (match_dup 8))]
421 "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
424 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
425 ;; ;; Peephole to generate d<opname>{ij}h a,b,c instructions
426 ;; ;; D0 = D2<op>{reg_pair}3
427 ;; ;; {reg_pair}5 = D0
430 ;; ;; __________________________________________
431 ;; ;; / D0 = D2 <op> {regpair3_or_limmreg34}
432 ;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
433 ;; ;; | \__________________________________________
435 ;; ;; + --- {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
439 ;; ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
440 ;; ;; lr {reg_pair}4.lo, {D2l}
441 ;; ;; ----------------------------------------------------------------------------------------
442 ;; ;; where <op> is one of {+,*,-}
443 ;; ;; <opname> is {add,mult,sub}
445 ;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
446 ;; ;; {regpair2_or_limmreg24} and D3
447 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
449 ;; [(parallel [(set (match_operand:DF 0 "register_operand" "")
450 ;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
451 ;; (match_operand:DF 3 "nonmemory_operand" "")]))
452 ;; (use (match_operand:SI 4 "" ""))])
453 ;; (set (match_operand:DF 5 "register_operand" "")
458 ;; (parallel [(set (match_dup 0)
459 ;; (match_op_dup:DF 1 [(match_dup 2)
461 ;; (use (match_dup 4))
462 ;; (set (match_dup 5)
463 ;; (match_op_dup:DF 1 [(match_dup 2)
464 ;; (match_dup 3)]))])
465 ;; ; (set (subreg:SI (match_dup 5) 0)
466 ;; (set (match_dup 6)
467 ;; (unspec_volatile [(match_dup 0)] VUNSPEC_ARC_LR ))
469 ;; "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
471 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
472 ;; Peephole to generate d<opname>{ij}h a,b,c instructions
473 ;; D0 = D2<op>{reg_pair}3
477 ;; __________________________________________
478 ;; / D0 = D2 <op> {regpair3_or_limmreg34}
479 ;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
480 ;; | \__________________________________________
482 ;; + --- {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
486 ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
487 ;; lr {reg_pair}4.lo, {D2l}
488 ;; ----------------------------------------------------------------------------------------
489 ;; where <op> is one of {+,*,-}
490 ;; <opname> is {add,mult,sub}
492 ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
493 ;; {regpair2_or_limmreg24} and D3
494 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
496 [(parallel [(set (match_operand:DF 0 "register_operand" "")
497 (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
498 (match_operand:DF 3 "nonmemory_operand" "")]))
499 (use (match_operand:SI 4 "" ""))
500 (use (match_operand:SI 5 "" ""))
501 (use (match_operand:SI 6 "" ""))])
502 (set (match_operand:DF 7 "register_operand" "")
505 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
507 (parallel [(set (match_dup 0)
508 (match_op_dup:DF 1 [(match_dup 2)
513 (match_op_dup:DF 1 [(match_dup 2)
515 ; (set (subreg:SI (match_dup 7) 0)
517 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
519 "operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
522 ;; ;; _______________________________________________________
523 ;; ;; / D0 = D1 + {regpair2_or_limmreg23}
524 ;; ;; + {reg_pair}4.hi = ( D1 + {regpair2_or_limmreg23} ).hi
525 ;; ;; \_______________________________________________________
526 ;; (define_insn "*daddh_peep2_insn"
527 ;; [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
528 ;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
529 ;; (match_operand:DF 2 "nonmemory_operand" "r,G")))
530 ;; (use (match_operand:SI 3 "" "N,r"))
531 ;; (set (match_operand:DF 4 "register_operand" "=r,r")
532 ;; (plus:DF (match_dup 1)
533 ;; (match_dup 2)))])]
536 ;; daddh%F0%F1 %H4, %H2, %L2
537 ;; daddh%F0%F1 %H4, %3, %L2"
538 ;; [(set_attr "type" "dpfp_addsub")
539 ;; (set_attr "length" "4,8")]
541 ;; _______________________________________________________
542 ;; / D0 = D1 + {regpair2_or_limmreg23}
543 ;; + {reg_pair}5.hi = ( D1 + {regpair2_or_limmreg23} ).hi
544 ;; \_______________________________________________________
545 (define_insn "*daddh_peep2_insn"
546 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
547 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
548 (match_operand:DF 2 "nonmemory_operand" "r,G")))
549 (use (match_operand:SI 3 "" "N,r"))
550 (use (match_operand:SI 4 "" "N,Q"))
551 (use (match_operand:SI 5 "" ""))
552 (set (match_operand:DF 6 "register_operand" "=r,r")
553 (plus:DF (match_dup 1)
556 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
558 daddh%F0%F1 %H6, %H2, %L2
559 daddh%F0%F1 %H6, %3, %L2"
560 [(set_attr "type" "dpfp_addsub")
561 (set_attr "length" "4,8")]
564 ;; _______________________________________________________
565 ;; / D0 = D1 * {regpair2_or_limmreg23}
566 ;; + {reg_pair}5.hi = ( D1 * {regpair2_or_limmreg23} ).hi
567 ;; \_______________________________________________________
568 (define_insn "*dmulh_peep2_insn"
569 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
570 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
571 (match_operand:DF 2 "nonmemory_operand" "r,G")))
572 (use (match_operand:SI 3 "" "N,r"))
573 (use (match_operand:SI 4 "" "N,Q"))
574 (use (match_operand:SI 5 "" ""))
575 (set (match_operand:DF 6 "register_operand" "=r,r")
576 (mult:DF (match_dup 1)
579 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
581 dmulh%F0%F1 %H6, %H2, %L2
582 dmulh%F0%F1 %H6, %3, %L2"
583 [(set_attr "type" "dpfp_mult")
584 (set_attr "length" "4,8")]
587 ;; _______________________________________________________
588 ;; / D0 = D1 - {regpair2_or_limmreg23}
589 ;; + {reg_pair}5.hi = ( D1 - {regpair2_or_limmreg23} ).hi
590 ;; \_______________________________________________________
592 ;; _______________________________________________________
593 ;; / D0 = {regpair1_or_limmreg13} - D2
594 ;; + {reg_pair}5.hi = ( {regpair1_or_limmreg13} ).hi - D2
595 ;; \_______________________________________________________
596 (define_insn "*dsubh_peep2_insn"
597 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D")
598 (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,r,G")
599 (match_operand:DF 2 "nonmemory_operand" "r,G,D,D")))
600 (use (match_operand:SI 3 "" "N,r,N,r"))
601 (use (match_operand:SI 4 "" "N,Q,N,Q"))
602 (use (match_operand:SI 5 "" ""))
603 (set (match_operand:DF 6 "register_operand" "=r,r,r,r")
604 (minus:DF (match_dup 1)
607 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) &&
608 !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
610 dsubh%F0%F1 %H6, %H2, %L2
611 dsubh%F0%F1 %H6, %3, %L2
612 drsubh%F0%F2 %H6, %H1, %L1
613 drsubh%F0%F2 %H6, %3, %L1"
614 [(set_attr "type" "dpfp_addsub")
615 (set_attr "length" "4,8,4,8")
616 (set_attr "cpu_facility" "*,*,fpx,fpx")])
618 ;; Intel QUARK SE extensions
619 (define_mode_iterator QUARK_CMP [CC_FP_GT CC_FP_GE])
620 (define_mode_attr quark_cmp [(CC_FP_GT "gt") (CC_FP_GE "ge")])
622 (define_expand "cmp_quark"
623 [(parallel [(set (match_operand 0 "")
624 (match_operand 1 ""))
625 (clobber (match_scratch:SI 2 ""))])]
629 (define_insn "*cmpsf_quark_<quark_cmp>"
630 [(set (reg:QUARK_CMP CC_REG)
631 (compare:QUARK_CMP (match_operand:SF 0 "register_operand" "r")
632 (match_operand:SF 1 "register_operand" "r")))
633 (clobber (match_scratch:SI 2 "=&r"))]
635 "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"
636 [(set_attr "length" "16")
637 (set_attr "cond" "set")
638 (set_attr "predicable" "no")
639 (set_attr "cond" "nocond")])
641 (define_insn "*cmpsf_quark_ord"
642 [(set (reg:CC_FP_ORD CC_REG)
643 (compare:CC_FP_ORD (match_operand:SF 0 "register_operand" "r")
644 (match_operand:SF 1 "register_operand" "r")))
645 (clobber (match_scratch:SI 2 "=&r"))]
647 "dsp_fp_cmp\\t%2,%0,%1\\n\\tadd.f\\t%2,%2,-8"
648 [(set_attr "length" "8")
649 (set_attr "cond" "set")
650 (set_attr "predicable" "no")
651 (set_attr "cond" "nocond")])
653 (define_insn "*cmpsf_quark_uneq"
654 [(set (reg:CC_FP_UNEQ CC_REG)
655 (compare:CC_FP_UNEQ (match_operand:SF 0 "register_operand" "r")
656 (match_operand:SF 1 "register_operand" "r")))
657 (clobber (match_scratch:SI 2 "=&r"))]
659 "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,6"
660 [(set_attr "length" "8")
661 (set_attr "cond" "set")
662 (set_attr "predicable" "no")
663 (set_attr "cond" "nocond")])
665 (define_insn "*cmpsf_quark_eq"
666 [(set (reg:CC_Z CC_REG)
667 (compare:CC_Z (match_operand:SF 0 "register_operand" "r")
668 (match_operand:SF 1 "register_operand" "r")))
669 (clobber (match_scratch:SI 2 "=&r"))]
671 "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,0x0E"
672 [(set_attr "length" "8")
673 (set_attr "cond" "set")
674 (set_attr "predicable" "no")
675 (set_attr "cond" "nocond")])
677 (define_insn "*divsf3_quark"
678 [(set (match_operand:SF 0 "register_operand" "=r")
679 (div:SF (match_operand:SF 1 "register_operand" "r")
680 (match_operand:SF 2 "register_operand" "r")))]
682 "dsp_fp_div\\t%0,%1,%2"
683 [(set_attr "length" "4")
684 (set_attr "predicable" "no")
685 (set_attr "cond" "nocond")])
687 (define_insn "*sqrtsf2_quark"
688 [(set (match_operand:SF 0 "register_operand" "=r")
689 (sqrt:SF (match_operand:SF 1 "register_operand" "r")))]
691 "dsp_fp_sqrt\\t%0,%1"
692 [(set_attr "length" "4")
693 (set_attr "predicable" "no")
694 (set_attr "cond" "nocond")])
696 ;; SF->SI (using rounding towards zero)
697 (define_insn "*fix_truncsfsi2_quark"
698 [(set (match_operand:SI 0 "register_operand" "=r")
699 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))]
701 "dsp_fp_flt2i\\t%0,%1"
702 [(set_attr "length" "4")
703 (set_attr "predicable" "no")
704 (set_attr "cond" "nocond")])
707 (define_insn "*floatsisf2_quark"
708 [(set (match_operand:SF 0 "register_operand" "=r")
709 (float:SF (match_operand:SI 1 "register_operand" "r")))]
711 "dsp_fp_i2flt\\t%0,%1"
712 [(set_attr "length" "4")
713 (set_attr "predicable" "no")
714 (set_attr "cond" "nocond")])