]>
Commit | Line | Data |
---|---|---|
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 |