]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arc/fpx.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arc / fpx.md
CommitLineData
526b7aee
SV
1;; Machine description of the Synopsys DesignWare ARC cpu Floating Point
2;; extensions for GNU C compiler
8d9254fc 3;; Copyright (C) 2007-2020 Free Software Foundation, Inc.
526b7aee
SV
4
5;; This file is part of GCC.
6
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.
11
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.
16
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/>.
20
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")
30
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")
35
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")
40
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")
45
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")
50
51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
52
8f3304d0 53(define_insn "*addsf3_fpx"
526b7aee
SV
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
6b55f8c9
CZ
62 fadd %0,%1,%2
63 fadd %0,%1,%2
64 fadd%? %0,%1,%2"
526b7aee
SV
65 [(set_attr "type" "spfp")
66 (set_attr "length" "4,4,8,8,8")])
67
8f3304d0 68(define_insn "*subsf3_fpx"
526b7aee
SV
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
6b55f8c9
CZ
77 fsub %0,%1,%2
78 fsub %0,%1,%2
79 fsub%? %0,%1,%2"
526b7aee
SV
80 [(set_attr "type" "spfp")
81 (set_attr "length" "4,4,8,8,8")])
82
8f3304d0 83(define_insn "*mulsf3_fpx"
526b7aee
SV
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
6b55f8c9
CZ
92 fmul %0,%1,%2
93 fmul %0,%1,%2
94 fmul%? %0,%1,%2"
526b7aee
SV
95 [(set_attr "type" "spfp")
96 (set_attr "length" "4,4,8,8,8")])
97
98
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.
102
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")])
113
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")])
130
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")])
139
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")])
148
149;; DPFP instructions begin...
150
151;; op0_reg = D1_reg.low
152(define_insn "*lr_double_lower"
153 [(set (match_operand:SI 0 "register_operand" "=r")
c69899f0 154 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")] VUNSPEC_ARC_LR ))]
526b7aee
SV
155 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
156"lr %0, [%1l] ; *lr_double_lower"
157[(set_attr "length" "8")
158(set_attr "type" "lr")]
159)
160
161(define_insn "*lr_double_higher"
162 [(set (match_operand:SI 0 "register_operand" "=r")
c69899f0
CZ
163 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "D")]
164 VUNSPEC_ARC_LR_HIGH ))]
526b7aee
SV
165 "TARGET_DPFP && !TARGET_DPFP_DISABLE_LRSR"
166"lr %0, [%1h] ; *lr_double_higher"
167[(set_attr "length" "8")
168(set_attr "type" "lr")]
169)
170
526b7aee
SV
171(define_insn "*dexcl_3op_peep2_insn"
172 [(set (match_operand:SI 0 "dest_reg_operand" "=r") ; not register_operand, to accept SUBREG
491483b0
CZ
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"))]
526b7aee 178 "TARGET_DPFP"
491483b0 179 "dexcl%F3 %0, %1, %2"
526b7aee
SV
180 [(set_attr "type" "move")
181 (set_attr "length" "4")]
182)
183
184;; version which will not overwrite operand0
491483b0
CZ
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))
526b7aee
SV
191 ]
192 "TARGET_DPFP"
193 "dexcl%F0 0, %1, %2"
194 [(set_attr "type" "move")
195 (set_attr "length" "4")]
196)
197
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")
c69899f0 201 (unspec_volatile:SI [(match_operand:DF 1 "arc_double_register_operand" "=D")] VUNSPEC_ARC_LR ))
526b7aee
SV
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")]
209)
210
211
212;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213;; doubles support for ARC
214;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
215
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
526b7aee
SV
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 */
230;;
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")])
248
249;; dmulh{0}{1} 0, {reg_pair}2.hi, {reg_pair}2.lo
250;; OR
251;; dmulh{0}{1} 0, reg3, limm2.lo
526b7aee
SV
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")])
272
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
526b7aee
SV
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")
4ac2f36e
CZ
305 (set_attr "length" "4,8,4,8")
306 (set_attr "cpu_facility" "*,*,fpx,fpx")])
526b7aee
SV
307
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)
c69899f0 358;; (unspec_volatile [(match_dup 0)] VUNSPEC_ARC_LR ))
526b7aee
SV
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}
388;;
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)
c69899f0 417 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
526b7aee
SV
418 (set (match_dup 0) (match_dup 8))]
419 )
420 ]
421 "operands[9] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
422 )
423
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)
c69899f0 467;; (unspec_volatile [(match_dup 0)] VUNSPEC_ARC_LR ))
526b7aee
SV
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}
491;;
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)
c69899f0 517 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
526b7aee
SV
518 ]
519 "operands[8] = simplify_gen_subreg(SImode,operands[7],DFmode,0);"
520 )
521
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")]
562)
563
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")]
585)
586
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")
4ac2f36e
CZ
615 (set_attr "length" "4,8,4,8")
616 (set_attr "cpu_facility" "*,*,fpx,fpx")])
c4014855
CZ
617
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")])
621
622(define_expand "cmp_quark"
623 [(parallel [(set (match_operand 0 "")
624 (match_operand 1 ""))
625 (clobber (match_scratch:SI 2 ""))])]
626 ""
627 "")
628
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")])
640
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")])
652
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")])
664
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")])
676
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")])
686
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")])
695
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")])
705
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")])
715