1 ;; Machine description of the Synopsys DesignWare ARC cpu Floating Point
2 ;; extensions for GNU C compiler
3 ;; Copyright (C) 2007-2013 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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")])
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")])
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_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")] VUNSPEC_LR_HIGH ))]
164 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
165 "lr %0, [%1h] ; *lr_double_higher"
166 [(set_attr "length" "8")
167 (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
173 (unspec_volatile:SI [
174 (match_operand:DF 1 "arc_double_register_operand" "D")
175 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r1
176 (match_operand:SI 3 "shouldbe_register_operand" "r") ; r0
180 "dexcl%F1 %0, %2, %3"
181 [(set_attr "type" "move")
182 (set_attr "length" "4")]
185 ;; version which will not overwrite operand0
186 (define_insn "*dexcl_3op_peep2_insn_nores"
187 [ (unspec_volatile:SI [
188 (match_operand:DF 0 "arc_double_register_operand" "D")
189 (match_operand:SI 1 "shouldbe_register_operand" "r") ; r1
190 (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0
191 ] VUNSPEC_DEXCL_NORES )
195 [(set_attr "type" "move")
196 (set_attr "length" "4")]
199 ;; dexcl a,b,c pattern generated by the peephole2 above
200 (define_insn "*dexcl_3op_peep2_insn_lr"
201 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
202 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "=D")] VUNSPEC_LR ))
203 (set (match_dup 1) (match_operand:DF 2 "register_operand" "r"))]
206 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
207 "dexcl%F1 %0, %H2, %L2"
208 [(set_attr "type" "move")
209 (set_attr "length" "4")]
213 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
214 ;; doubles support for ARC
215 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
217 ;; D0 = D1+{reg_pair}2
218 ;; (define_expand "adddf3"
219 ;; [(set (match_operand:DF 0 "arc_double_register_operand" "")
220 ;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "")
221 ;; (match_operand:DF 2 "nonmemory_operand" "")))]
225 ;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
227 ;; daddh{0}{1} 0, reg3, limm2.lo
228 (define_expand "adddf3"
229 [(set (match_operand:DF 0 "arc_double_register_operand" "")
230 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "")
231 (match_operand:DF 2 "nonmemory_operand" "")))
234 " if (GET_CODE (operands[2]) == CONST_DOUBLE)
237 split_double (operands[2], &low, &high);
238 tmp = force_reg (SImode, high);
239 emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
242 emit_insn(gen_adddf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
247 ;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
249 ;; daddh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0 */
251 (define_insn "adddf3_insn"
252 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
253 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
254 (match_operand:DF 2 "nonmemory_operand" "!r,G")))
255 (use (match_operand:SI 3 "" "N,r"))
256 (use (match_operand:SI 4 "" "N,Q"))
257 ; Prevent can_combine_p from combining muldf3_insn patterns with
258 ; different USE pairs.
262 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
264 daddh%F0%F1 0,%H2,%L2
265 daddh%F0%F1 0,%3,%L2"
266 [(set_attr "type" "dpfp_addsub")
267 (set_attr "length" "4,8")])
269 ;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
271 ;; dmulh{0}{1} 0, reg3, limm2.lo
272 (define_expand "muldf3"
273 [(set (match_operand:DF 0 "arc_double_register_operand" "")
274 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "")
275 (match_operand:DF 2 "nonmemory_operand" "")))]
277 " if (GET_CODE (operands[2]) == CONST_DOUBLE)
280 split_double (operands[2], &low, &high);
281 tmp = force_reg (SImode, high);
282 emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
285 emit_insn(gen_muldf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
291 ;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
293 ;; dmulh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
294 (define_insn "muldf3_insn"
295 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
296 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
297 (match_operand:DF 2 "nonmemory_operand" "!r,G")))
298 (use (match_operand:SI 3 "" "N,!r"))
299 (use (match_operand:SI 4 "" "N,Q"))
300 ; Prevent can_combine_p from combining muldf3_insn patterns with
301 ; different USE pairs.
305 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
307 dmulh%F0%F1 0,%H2,%L2
308 dmulh%F0%F1 0,%3, %L2"
309 [(set_attr "type" "dpfp_mult")
310 (set_attr "length" "4,8")])
312 ;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
314 ;; dsubh{0}{1} 0, reg3, limm2.lo
316 ;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo
318 ;; drsubh{0}{2} 0, reg3, limm1.lo
319 (define_expand "subdf3"
320 [(set (match_operand:DF 0 "arc_double_register_operand" "")
321 (minus:DF (match_operand:DF 1 "nonmemory_operand" "")
322 (match_operand:DF 2 "nonmemory_operand" "")))]
324 " if (GET_CODE (operands[1]) == CONST_DOUBLE || GET_CODE (operands[2]) == CONST_DOUBLE)
327 int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1: 2);
328 split_double (operands[const_index], &low, &high);
329 tmp = force_reg (SImode, high);
330 emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],tmp,const0_rtx));
333 emit_insn(gen_subdf3_insn(operands[0], operands[1], operands[2],const1_rtx,const1_rtx));
339 ;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */
341 ;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
343 ;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo /* operand 4 = 1 */
345 ;; drsubh{0}{2} 0, reg3, limm1.lo /* operand 4 = 0*/
346 (define_insn "subdf3_insn"
347 [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D")
348 (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,!r,G")
349 (match_operand:DF 2 "nonmemory_operand" "!r,G,D,D")))
350 (use (match_operand:SI 3 "" "N,r,N,r"))
351 (use (match_operand:SI 4 "" "N,Q,N,Q"))
352 ; Prevent can_combine_p from combining muldf3_insn patterns with
353 ; different USE pairs.
356 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) &&
357 !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
359 dsubh%F0%F1 0,%H2,%L2
361 drsubh%F0%F2 0,%H1,%L1
362 drsubh%F0%F2 0,%3,%L1"
363 [(set_attr "type" "dpfp_addsub")
364 (set_attr "length" "4,8,4,8")])
366 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
367 ;; ;; Peephole for following conversion
368 ;; ;; D0 = D2<op>{reg_pair}3
369 ;; ;; {reg_pair}5 = D0
370 ;; ;; D0 = {reg_pair}6
373 ;; ;; _________________________________________________________
374 ;; ;; / D0 = D2 <op> {regpair3_or_limmreg34}
375 ;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
376 ;; ;; | \_________________________________________________________
378 ;; ;; | ________________________________________________________
379 ;; ;; | / {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
380 ;; ;; +-----+ D0 = {reg_pair}6
381 ;; ;; \ _________________________________________________________
385 ;; ;; d<op>{0}{2}h {reg_pair}5.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
386 ;; ;; dexcl{0} {reg_pair}5.lo, {reg_pair}6.lo, {reg_pair}6.hi
387 ;; ;; -----------------------------------------------------------------------------------------
388 ;; ;; where <op> is one of {+,*,-}
389 ;; ;; <opname> is {add,mult,sub}
391 ;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
392 ;; ;; {regpair2_or_limmreg24} and D3
393 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
395 ;; [(parallel [(set (match_operand:DF 0 "register_operand" "")
396 ;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
397 ;; (match_operand:DF 3 "nonmemory_operand" "")]))
398 ;; (use (match_operand:SI 4 "" ""))])
399 ;; (set (match_operand:DF 5 "register_operand" "")
401 ;; (set (match_dup 0)
402 ;; (match_operand:DF 6 "register_operand" ""))
406 ;; (parallel [(set (match_dup 0)
407 ;; (match_op_dup:DF 1 [(match_dup 2)
409 ;; (use (match_dup 4))
410 ;; (set (match_dup 5)
411 ;; (match_op_dup:DF 1 [(match_dup 2)
412 ;; (match_dup 3)]))])
414 ;; ;; (set (subreg:SI (match_dup 5) 0)
415 ;; (set (match_dup 7)
416 ;; (unspec_volatile [(match_dup 0)] VUNSPEC_LR ))
417 ;; (set (match_dup 0) (match_dup 6))]
420 ;; "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
422 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
423 ;; Peephole for following conversion
424 ;; D0 = D2<op>{reg_pair}3
429 ;; _________________________________________________________
430 ;; / D0 = D2 <op> {regpair3_or_limmreg34}
431 ;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
432 ;; | \_________________________________________________________
434 ;; | ________________________________________________________
435 ;; | / {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
436 ;; +-----+ D0 = {reg_pair}7
437 ;; \ _________________________________________________________
441 ;; d<op>{0}{2}h {reg_pair}6.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
442 ;; dexcl{0} {reg_pair}6.lo, {reg_pair}7.lo, {reg_pair}7.hi
443 ;; -----------------------------------------------------------------------------------------
444 ;; where <op> is one of {+,*,-}
445 ;; <opname> is {add,mult,sub}
447 ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
448 ;; {regpair2_or_limmreg24} and D3
449 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
451 [(parallel [(set (match_operand:DF 0 "register_operand" "")
452 (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
453 (match_operand:DF 3 "nonmemory_operand" "")]))
454 (use (match_operand:SI 4 "" ""))
455 (use (match_operand:SI 5 "" ""))
456 (use (match_operand:SI 6 "" ""))])
457 (set (match_operand:DF 7 "register_operand" "")
460 (match_operand:DF 8 "register_operand" ""))
462 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
464 (parallel [(set (match_dup 0)
465 (match_op_dup:DF 1 [(match_dup 2)
470 (match_op_dup:DF 1 [(match_dup 2)
473 ;; (set (subreg:SI (match_dup 7) 0)
475 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_LR ))
476 (set (match_dup 0) (match_dup 8))]
479 "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
482 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
483 ;; ;; Peephole to generate d<opname>{ij}h a,b,c instructions
484 ;; ;; D0 = D2<op>{reg_pair}3
485 ;; ;; {reg_pair}5 = D0
488 ;; ;; __________________________________________
489 ;; ;; / D0 = D2 <op> {regpair3_or_limmreg34}
490 ;; ;; ---- + {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
491 ;; ;; | \__________________________________________
493 ;; ;; + --- {reg_pair}5.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
497 ;; ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
498 ;; ;; lr {reg_pair}4.lo, {D2l}
499 ;; ;; ----------------------------------------------------------------------------------------
500 ;; ;; where <op> is one of {+,*,-}
501 ;; ;; <opname> is {add,mult,sub}
503 ;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
504 ;; ;; {regpair2_or_limmreg24} and D3
505 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
507 ;; [(parallel [(set (match_operand:DF 0 "register_operand" "")
508 ;; (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
509 ;; (match_operand:DF 3 "nonmemory_operand" "")]))
510 ;; (use (match_operand:SI 4 "" ""))])
511 ;; (set (match_operand:DF 5 "register_operand" "")
516 ;; (parallel [(set (match_dup 0)
517 ;; (match_op_dup:DF 1 [(match_dup 2)
519 ;; (use (match_dup 4))
520 ;; (set (match_dup 5)
521 ;; (match_op_dup:DF 1 [(match_dup 2)
522 ;; (match_dup 3)]))])
523 ;; ; (set (subreg:SI (match_dup 5) 0)
524 ;; (set (match_dup 6)
525 ;; (unspec_volatile [(match_dup 0)] VUNSPEC_LR ))
527 ;; "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
529 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
530 ;; Peephole to generate d<opname>{ij}h a,b,c instructions
531 ;; D0 = D2<op>{reg_pair}3
535 ;; __________________________________________
536 ;; / D0 = D2 <op> {regpair3_or_limmreg34}
537 ;; ---- + {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
538 ;; | \__________________________________________
540 ;; + --- {reg_pair}6.lo = ( D2<op>{regpair3_or_limmreg34} ).lo
544 ;; d<op>{0}{2}h {reg_pair}4.hi, {regpair3_or_limmreg34}.lo, {regpair3_or_limmreg34}.hi
545 ;; lr {reg_pair}4.lo, {D2l}
546 ;; ----------------------------------------------------------------------------------------
547 ;; where <op> is one of {+,*,-}
548 ;; <opname> is {add,mult,sub}
550 ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
551 ;; {regpair2_or_limmreg24} and D3
552 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
554 [(parallel [(set (match_operand:DF 0 "register_operand" "")
555 (match_operator:DF 1 "arc_dpfp_operator" [(match_operand:DF 2 "nonmemory_operand" "")
556 (match_operand:DF 3 "nonmemory_operand" "")]))
557 (use (match_operand:SI 4 "" ""))
558 (use (match_operand:SI 5 "" ""))
559 (use (match_operand:SI 6 "" ""))])
560 (set (match_operand:DF 7 "register_operand" "")
563 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
565 (parallel [(set (match_dup 0)
566 (match_op_dup:DF 1 [(match_dup 2)
571 (match_op_dup:DF 1 [(match_dup 2)
573 ; (set (subreg:SI (match_dup 7) 0)
575 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_LR ))
577 "operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
580 ;; ;; _______________________________________________________
581 ;; ;; / D0 = D1 + {regpair2_or_limmreg23}
582 ;; ;; + {reg_pair}4.hi = ( D1 + {regpair2_or_limmreg23} ).hi
583 ;; ;; \_______________________________________________________
584 ;; (define_insn "*daddh_peep2_insn"
585 ;; [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
586 ;; (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
587 ;; (match_operand:DF 2 "nonmemory_operand" "r,G")))
588 ;; (use (match_operand:SI 3 "" "N,r"))
589 ;; (set (match_operand:DF 4 "register_operand" "=r,r")
590 ;; (plus:DF (match_dup 1)
591 ;; (match_dup 2)))])]
594 ;; daddh%F0%F1 %H4, %H2, %L2
595 ;; daddh%F0%F1 %H4, %3, %L2"
596 ;; [(set_attr "type" "dpfp_addsub")
597 ;; (set_attr "length" "4,8")]
599 ;; _______________________________________________________
600 ;; / D0 = D1 + {regpair2_or_limmreg23}
601 ;; + {reg_pair}5.hi = ( D1 + {regpair2_or_limmreg23} ).hi
602 ;; \_______________________________________________________
603 (define_insn "*daddh_peep2_insn"
604 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
605 (plus:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
606 (match_operand:DF 2 "nonmemory_operand" "r,G")))
607 (use (match_operand:SI 3 "" "N,r"))
608 (use (match_operand:SI 4 "" "N,Q"))
609 (use (match_operand:SI 5 "" ""))
610 (set (match_operand:DF 6 "register_operand" "=r,r")
611 (plus:DF (match_dup 1)
614 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
616 daddh%F0%F1 %H6, %H2, %L2
617 daddh%F0%F1 %H6, %3, %L2"
618 [(set_attr "type" "dpfp_addsub")
619 (set_attr "length" "4,8")]
622 ;; _______________________________________________________
623 ;; / D0 = D1 * {regpair2_or_limmreg23}
624 ;; + {reg_pair}5.hi = ( D1 * {regpair2_or_limmreg23} ).hi
625 ;; \_______________________________________________________
626 (define_insn "*dmulh_peep2_insn"
627 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D")
628 (mult:DF (match_operand:DF 1 "arc_double_register_operand" "D,D")
629 (match_operand:DF 2 "nonmemory_operand" "r,G")))
630 (use (match_operand:SI 3 "" "N,r"))
631 (use (match_operand:SI 4 "" "N,Q"))
632 (use (match_operand:SI 5 "" ""))
633 (set (match_operand:DF 6 "register_operand" "=r,r")
634 (mult:DF (match_dup 1)
637 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
639 dmulh%F0%F1 %H6, %H2, %L2
640 dmulh%F0%F1 %H6, %3, %L2"
641 [(set_attr "type" "dpfp_mult")
642 (set_attr "length" "4,8")]
645 ;; _______________________________________________________
646 ;; / D0 = D1 - {regpair2_or_limmreg23}
647 ;; + {reg_pair}5.hi = ( D1 - {regpair2_or_limmreg23} ).hi
648 ;; \_______________________________________________________
650 ;; _______________________________________________________
651 ;; / D0 = {regpair1_or_limmreg13} - D2
652 ;; + {reg_pair}5.hi = ( {regpair1_or_limmreg13} ).hi - D2
653 ;; \_______________________________________________________
654 (define_insn "*dsubh_peep2_insn"
655 [(parallel [(set (match_operand:DF 0 "arc_double_register_operand" "=D,D,D,D")
656 (minus:DF (match_operand:DF 1 "nonmemory_operand" "D,D,r,G")
657 (match_operand:DF 2 "nonmemory_operand" "r,G,D,D")))
658 (use (match_operand:SI 3 "" "N,r,N,r"))
659 (use (match_operand:SI 4 "" "N,Q,N,Q"))
660 (use (match_operand:SI 5 "" ""))
661 (set (match_operand:DF 6 "register_operand" "=r,r,r,r")
662 (minus:DF (match_dup 1)
665 !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT) &&
666 !(GET_CODE(operands[1]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
668 dsubh%F0%F1 %H6, %H2, %L2
669 dsubh%F0%F1 %H6, %3, %L2
670 drsubh%F0%F2 %H6, %H1, %L1
671 drsubh%F0%F2 %H6, %3, %L1"
672 [(set_attr "type" "dpfp_addsub")
673 (set_attr "length" "4,8,4,8")]