2018-11-09 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / config / arc / fpx.md
blob8f65df1ba0f04d29165408e7d4b0b16491a22648
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)
10 ;; any later version.
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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22 ;; TODOs:
23 ;;        dpfp blocks?
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
58   "TARGET_SPFP"
59   "@
60    fadd %0,%1,%2
61    fadd %0,%1,%2
62    fadd   %0,%1,%2
63    fadd   %0,%1,%2
64    fadd%? %0,%1,%2"
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
73   "TARGET_SPFP"
74   "@
75    fsub %0,%1,%2
76    fsub %0,%1,%2
77    fsub   %0,%1,%2
78    fsub   %0,%1,%2
79    fsub%? %0,%1,%2"
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
88   "TARGET_SPFP"
89   "@
90    fmul %0,%1,%2
91    fmul %0,%1,%2
92    fmul   %0,%1,%2
93    fmul   %0,%1,%2
94    fmul%? %0,%1,%2"
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
101 ;; branch insns.
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"
110   "fsub.f 0,%0,%1"
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"
125   "@
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"
136   "cmp.ls pcl,pcl"
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"
145   "rcmp.pnz pcl,0"
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
173         (unspec_volatile:SI
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"))]
178   "TARGET_DPFP"
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")
187         (unspec_volatile:DF
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))
191   ]
192   "TARGET_DPFP"
193   "dexcl%F0 0, %1, %2"
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"))]
203             )
204   ]
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" "")))]
221 ;;  "TARGET_DPFP"
222 ;;  " "
223 ;; )
224 ;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
225 ;; OR
226 ;; daddh{0}{1} 0, reg3, limm2.lo
227 ;; daddh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo  /* operand 4 = 1*/
228 ;; OR
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.
239   (use (match_dup 2))
240   ]
241   "TARGET_DPFP &&
242    !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
243   "@
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
250 ;; OR
251 ;; dmulh{0}{1} 0, reg3, limm2.lo
252 ;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1*/
253 ;; OR
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.
263   (use (match_dup 2))
264   ]
265   "TARGET_DPFP &&
266    !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
267   "@
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
274 ;; OR
275 ;; dsubh{0}{1} 0, reg3, limm2.lo
276 ;; OR
277 ;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo
278 ;; OR
279 ;; drsubh{0}{2} 0, reg3, limm1.lo
280 ;; dsubh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo /* operand 4 = 1 */
281 ;; OR
282 ;; dsubh{0}{1} 0, reg3, limm2.lo /* operand 4 = 0*/
283 ;; OR
284 ;; drsubh{0}{2} 0, {reg_pair}1.hi, {reg_pair}1.lo /* operand 4 = 1 */
285 ;; OR
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.
295   (use (match_dup 2))]
296   "TARGET_DPFP &&
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)"
299   "@
300      dsubh%F0%F1 0,%H2,%L2
301      dsubh%F0%F1 0,%3,%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
313 ;; ;;                            |
314 ;; ;;                            V
315 ;; ;;            _________________________________________________________
316 ;; ;;           / D0             = D2 <op> {regpair3_or_limmreg34}
317 ;; ;;    ---- +   {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
318 ;; ;;   |       \_________________________________________________________
319 ;; ;;   |
320 ;; ;;   |         ________________________________________________________
321 ;; ;;   |      / {reg_pair}5.lo  = ( D2<op>{regpair3_or_limmreg34} ).lo
322 ;; ;;   +-----+  D0              = {reg_pair}6
323 ;; ;;          \ _________________________________________________________
324 ;; ;;                            ||
325 ;; ;;                            ||
326 ;; ;;                            \/
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}
332 ;; ;;
333 ;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
334 ;; ;;       {regpair2_or_limmreg24} and D3
335 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
336 ;; (define_peephole2
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" "")
342 ;;        (match_dup 0))
343 ;;   (set (match_dup 0)
344 ;;        (match_operand:DF 6 "register_operand" ""))
345 ;;   ]
346 ;;   "TARGET_DPFP"
347 ;;   [
348 ;;   (parallel [(set (match_dup 0)
349 ;;                (match_op_dup:DF 1 [(match_dup 2)
350 ;;                                 (match_dup 3)]))
351 ;;          (use (match_dup 4))
352 ;;             (set (match_dup 5)
353 ;;               (match_op_dup:DF  1 [(match_dup 2)
354 ;;                                 (match_dup 3)]))])
355 ;;   (parallel [
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))]
360 ;;          )
361 ;;   ]
362 ;;   "operands[7] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
363 ;;   )
364 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
365 ;; Peephole for following conversion
366 ;;                    D0 = D2<op>{reg_pair}3
367 ;;                    {reg_pair}6 = D0
368 ;;                    D0 = {reg_pair}7
369 ;;                            |
370 ;;                            V
371 ;;            _________________________________________________________
372 ;;           / D0             = D2 <op> {regpair3_or_limmreg34}
373 ;;    ---- +   {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
374 ;;   |       \_________________________________________________________
375 ;;   |
376 ;;   |         ________________________________________________________
377 ;;   |      / {reg_pair}6.lo  = ( D2<op>{regpair3_or_limmreg34} ).lo
378 ;;   +-----+  D0              = {reg_pair}7
379 ;;          \ _________________________________________________________
380 ;;                            ||
381 ;;                            ||
382 ;;                            \/
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 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
392 (define_peephole2
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" "")
400        (match_dup 0))
401   (set (match_dup 0)
402        (match_operand:DF 8 "register_operand" ""))
403   ]
404   "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
405   [
406   (parallel [(set (match_dup 0)
407                   (match_op_dup:DF 1 [(match_dup 2)
408                                    (match_dup 3)]))
409             (use (match_dup 4))
410             (use (match_dup 5))
411             (set (match_dup 7)
412                  (match_op_dup:DF  1 [(match_dup 2)
413                                    (match_dup 3)]))])
414   (parallel [
415 ;;          (set (subreg:SI (match_dup 7) 0)
416             (set (match_dup 9)
417                  (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
418             (set (match_dup 0) (match_dup 8))]
419             )
420   ]
421   "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
422   )
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
428 ;; ;;                            |
429 ;; ;;                            V
430 ;; ;;            __________________________________________
431 ;; ;;           / D0             = D2 <op> {regpair3_or_limmreg34}
432 ;; ;;    ---- +   {reg_pair}5.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
433 ;; ;;   |       \__________________________________________
434 ;; ;;   |
435 ;; ;;   + ---    {reg_pair}5.lo     = ( D2<op>{regpair3_or_limmreg34} ).lo
436 ;; ;;                            ||
437 ;; ;;                            ||
438 ;; ;;                            \/
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}
444 ;; ;;
445 ;; ;; NOTE: For rsub insns D2 and {regpair3_or_limmreg34} get interchanged as
446 ;; ;;       {regpair2_or_limmreg24} and D3
447 ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
448 ;; (define_peephole2
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" "")
454 ;;        (match_dup 0))
455 ;;   ]
456 ;;   "TARGET_DPFP"
457 ;;   [
458 ;;   (parallel [(set (match_dup 0)
459 ;;                (match_op_dup:DF 1 [(match_dup 2)
460 ;;                                 (match_dup 3)]))
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 ))
468 ;;   ]
469 ;;   "operands[6] = simplify_gen_subreg(SImode,operands[5],DFmode,0);"
470 ;;   )
471 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
472 ;; Peephole to generate d<opname>{ij}h a,b,c instructions
473 ;;                    D0 = D2<op>{reg_pair}3
474 ;;                    {reg_pair}6 = D0
475 ;;                            |
476 ;;                            V
477 ;;            __________________________________________
478 ;;           / D0             = D2 <op> {regpair3_or_limmreg34}
479 ;;    ---- +   {reg_pair}6.hi = ( D2<op>{regpair3_or_limmreg34} ).hi
480 ;;   |       \__________________________________________
481 ;;   |
482 ;;   + ---    {reg_pair}6.lo     = ( D2<op>{regpair3_or_limmreg34} ).lo
483 ;;                            ||
484 ;;                            ||
485 ;;                            \/
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 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
495 (define_peephole2
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" "")
503        (match_dup 0))
504   ]
505   "TARGET_DPFP  && !TARGET_DPFP_DISABLE_LRSR"
506   [
507   (parallel [(set (match_dup 0)
508                   (match_op_dup:DF 1 [(match_dup 2)
509                                    (match_dup 3)]))
510             (use (match_dup 4))
511             (use (match_dup 5))
512             (set (match_dup 7)
513                  (match_op_dup:DF  1 [(match_dup 2)
514                                    (match_dup 3)]))])
515 ;  (set (subreg:SI (match_dup 7) 0)
516   (set (match_dup 8)
517        (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
518   ]
519   "operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
520   )
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)))])]
534 ;;  "TARGET_DPFP"
535 ;;  "@
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")]
540 ;; )
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)
554                            (match_dup 2)))])]
555  "TARGET_DPFP &&
556    !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
557  "@
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)
577                                       (match_dup 2)))])]
578  "TARGET_DPFP &&
579    !(GET_CODE(operands[2]) == CONST_DOUBLE && GET_CODE(operands[3]) == CONST_INT)"
580  "@
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 ;;           \_______________________________________________________
591 ;;  OR
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)
605                                       (match_dup 2)))])]
606  "TARGET_DPFP &&
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)"
609  "@
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 ""))])]
626   ""
627   "")
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"))]
634   "TARGET_FPX_QUARK"
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"))]
646   "TARGET_FPX_QUARK"
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"))]
658   "TARGET_FPX_QUARK"
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"))]
670   "TARGET_FPX_QUARK"
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")))]
681   "TARGET_FPX_QUARK"
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")))]
690   "TARGET_FPX_QUARK"
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"))))]
700   "TARGET_FPX_QUARK"
701   "dsp_fp_flt2i\\t%0,%1"
702   [(set_attr "length" "4")
703    (set_attr "predicable" "no")
704    (set_attr "cond" "nocond")])
706 ;; SI->SF
707 (define_insn "*floatsisf2_quark"
708   [(set (match_operand:SF 0 "register_operand"          "=r")
709         (float:SF (match_operand:SI 1 "register_operand" "r")))]
710   "TARGET_FPX_QUARK"
711   "dsp_fp_i2flt\\t%0,%1"
712   [(set_attr "length" "4")
713    (set_attr "predicable" "no")
714    (set_attr "cond" "nocond")])