]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arc/fpx.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arc / fpx.md
1 ;; Machine description of the Synopsys DesignWare ARC cpu Floating Point
2 ;; extensions for GNU C compiler
3 ;; Copyright (C) 2007-2020 Free Software Foundation, Inc.
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
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")])
67
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")])
82
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")])
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")
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")]
159 )
160
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")]
169 )
170
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")]
182 )
183
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")]
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")
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")]
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
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
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
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")])
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)
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}
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)
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 )
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)
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}
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)
517 (unspec_volatile:SI [(match_dup 0)] VUNSPEC_ARC_LR ))
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")
615 (set_attr "length" "4,8,4,8")
616 (set_attr "cpu_facility" "*,*,fpx,fpx")])
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