]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/dfp.md
[PR 77333] Fixup fntypes of gimple calls of clones
[thirdparty/gcc.git] / gcc / config / rs6000 / dfp.md
CommitLineData
7393f7f8 1;; Decimal Floating Point (DFP) patterns.
cbe34bb5 2;; Copyright (C) 2007-2017 Free Software Foundation, Inc.
7393f7f8
BE
3;; Contributed by Ben Elliston (bje@au.ibm.com) and Peter Bergner
4;; (bergner@vnet.ibm.com).
5
6;; This file is part of GCC.
7
8;; GCC is free software; you can redistribute it and/or modify it
9;; under the terms of the GNU General Public License as published
2f83c7d6 10;; by the Free Software Foundation; either version 3, or (at your
7393f7f8
BE
11;; option) any later version.
12
13;; GCC is distributed in the hope that it will be useful, but WITHOUT
14;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16;; License for more details.
17
18;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
19;; along with GCC; see the file COPYING3. If not see
20;; <http://www.gnu.org/licenses/>.
7393f7f8 21
e41b2a33
PB
22;;
23;; UNSPEC usage
24;;
25
f3c33d9d
MM
26(define_c_enum "unspec"
27 [UNSPEC_MOVSD_LOAD
28 UNSPEC_MOVSD_STORE
e41b2a33
PB
29 ])
30
31
e41b2a33
PB
32(define_insn "movsd_store"
33 [(set (match_operand:DD 0 "nonimmediate_operand" "=m")
799dbb0f 34 (unspec:DD [(match_operand:SD 1 "input_operand" "d")]
e41b2a33
PB
35 UNSPEC_MOVSD_STORE))]
36 "(gpc_reg_operand (operands[0], DDmode)
37 || gpc_reg_operand (operands[1], SDmode))
38 && TARGET_HARD_FLOAT && TARGET_FPRS"
39 "stfd%U0%X0 %1,%0"
d839f53b 40 [(set_attr "type" "fpstore")
e41b2a33
PB
41 (set_attr "length" "4")])
42
43(define_insn "movsd_load"
44 [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
45 (unspec:SD [(match_operand:DD 1 "input_operand" "m")]
46 UNSPEC_MOVSD_LOAD))]
47 "(gpc_reg_operand (operands[0], SDmode)
48 || gpc_reg_operand (operands[1], DDmode))
49 && TARGET_HARD_FLOAT && TARGET_FPRS"
50 "lfd%U1%X1 %0,%1"
d839f53b 51 [(set_attr "type" "fpload")
e41b2a33
PB
52 (set_attr "length" "4")])
53
54;; Hardware support for decimal floating point operations.
55
56(define_insn "extendsddd2"
799dbb0f 57 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
e41b2a33
PB
58 (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
59 "TARGET_DFP"
60 "dctdp %0,%1"
eda328bf 61 [(set_attr "type" "dfp")])
e41b2a33
PB
62
63(define_expand "extendsdtd2"
799dbb0f
ME
64 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
65 (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
e41b2a33
PB
66 "TARGET_DFP"
67{
68 rtx tmp = gen_reg_rtx (DDmode);
69 emit_insn (gen_extendsddd2 (tmp, operands[1]));
70 emit_insn (gen_extendddtd2 (operands[0], tmp));
71 DONE;
72})
73
74(define_insn "truncddsd2"
75 [(set (match_operand:SD 0 "gpc_reg_operand" "=f")
799dbb0f 76 (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
e41b2a33
PB
77 "TARGET_DFP"
78 "drsp %0,%1"
eda328bf 79 [(set_attr "type" "dfp")])
e41b2a33 80
c092b045
PB
81(define_expand "negdd2"
82 [(set (match_operand:DD 0 "gpc_reg_operand" "")
83 (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
4f011e1e 84 "TARGET_HARD_FLOAT && TARGET_FPRS"
c092b045
PB
85 "")
86
87(define_insn "*negdd2_fpr"
799dbb0f
ME
88 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
89 (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
c092b045
PB
90 "TARGET_HARD_FLOAT && TARGET_FPRS"
91 "fneg %0,%1"
7c788ce2 92 [(set_attr "type" "fpsimple")])
c092b045
PB
93
94(define_expand "absdd2"
95 [(set (match_operand:DD 0 "gpc_reg_operand" "")
96 (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
4f011e1e 97 "TARGET_HARD_FLOAT && TARGET_FPRS"
c092b045
PB
98 "")
99
100(define_insn "*absdd2_fpr"
799dbb0f
ME
101 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
102 (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
c092b045
PB
103 "TARGET_HARD_FLOAT && TARGET_FPRS"
104 "fabs %0,%1"
7c788ce2 105 [(set_attr "type" "fpsimple")])
c092b045
PB
106
107(define_insn "*nabsdd2_fpr"
799dbb0f
ME
108 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
109 (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
c092b045
PB
110 "TARGET_HARD_FLOAT && TARGET_FPRS"
111 "fnabs %0,%1"
7c788ce2 112 [(set_attr "type" "fpsimple")])
c092b045 113
c092b045
PB
114(define_expand "negtd2"
115 [(set (match_operand:TD 0 "gpc_reg_operand" "")
116 (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
4f011e1e 117 "TARGET_HARD_FLOAT && TARGET_FPRS"
c092b045
PB
118 "")
119
120(define_insn "*negtd2_fpr"
e2323f5b
PB
121 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
122 (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
c092b045 123 "TARGET_HARD_FLOAT && TARGET_FPRS"
e2323f5b
PB
124 "@
125 fneg %0,%1
126 fneg %0,%1\;fmr %L0,%L1"
7c788ce2 127 [(set_attr "type" "fpsimple")
e2323f5b 128 (set_attr "length" "4,8")])
c092b045
PB
129
130(define_expand "abstd2"
131 [(set (match_operand:TD 0 "gpc_reg_operand" "")
132 (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))]
4f011e1e 133 "TARGET_HARD_FLOAT && TARGET_FPRS"
c092b045
PB
134 "")
135
136(define_insn "*abstd2_fpr"
e2323f5b
PB
137 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
138 (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
c092b045 139 "TARGET_HARD_FLOAT && TARGET_FPRS"
e2323f5b
PB
140 "@
141 fabs %0,%1
142 fabs %0,%1\;fmr %L0,%L1"
7c788ce2 143 [(set_attr "type" "fpsimple")
e2323f5b 144 (set_attr "length" "4,8")])
c092b045
PB
145
146(define_insn "*nabstd2_fpr"
e2323f5b
PB
147 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
148 (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
c092b045 149 "TARGET_HARD_FLOAT && TARGET_FPRS"
e2323f5b
PB
150 "@
151 fnabs %0,%1
152 fnabs %0,%1\;fmr %L0,%L1"
7c788ce2 153 [(set_attr "type" "fpsimple")
e2323f5b 154 (set_attr "length" "4,8")])
c092b045 155
6ef9a246
JJ
156;; Hardware support for decimal floating point operations.
157
158(define_insn "extendddtd2"
799dbb0f
ME
159 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
160 (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
161 "TARGET_DFP"
162 "dctqpq %0,%1"
eda328bf 163 [(set_attr "type" "dfp")])
6ef9a246
JJ
164
165;; The result of drdpq is an even/odd register pair with the converted
166;; value in the even register and zero in the odd register.
167;; FIXME: Avoid the register move by using a reload constraint to ensure
168;; that the result is the first of the pair receiving the result of drdpq.
169
170(define_insn "trunctddd2"
799dbb0f
ME
171 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
172 (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d")))
173 (clobber (match_scratch:TD 2 "=d"))]
6ef9a246
JJ
174 "TARGET_DFP"
175 "drdpq %2,%1\;fmr %0,%2"
eda328bf 176 [(set_attr "type" "dfp")
521466e5 177 (set_attr "length" "8")])
6ef9a246
JJ
178
179(define_insn "adddd3"
799dbb0f
ME
180 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
181 (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
182 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
183 "TARGET_DFP"
184 "dadd %0,%1,%2"
eda328bf 185 [(set_attr "type" "dfp")])
6ef9a246
JJ
186
187(define_insn "addtd3"
799dbb0f
ME
188 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
189 (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
190 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
191 "TARGET_DFP"
192 "daddq %0,%1,%2"
eda328bf 193 [(set_attr "type" "dfp")])
6ef9a246
JJ
194
195(define_insn "subdd3"
799dbb0f
ME
196 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
197 (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d")
198 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
199 "TARGET_DFP"
200 "dsub %0,%1,%2"
eda328bf 201 [(set_attr "type" "dfp")])
6ef9a246
JJ
202
203(define_insn "subtd3"
799dbb0f
ME
204 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
205 (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d")
206 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
207 "TARGET_DFP"
208 "dsubq %0,%1,%2"
eda328bf 209 [(set_attr "type" "dfp")])
6ef9a246
JJ
210
211(define_insn "muldd3"
799dbb0f
ME
212 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
213 (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
214 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
215 "TARGET_DFP"
216 "dmul %0,%1,%2"
eda328bf 217 [(set_attr "type" "dfp")])
6ef9a246
JJ
218
219(define_insn "multd3"
799dbb0f
ME
220 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
221 (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
222 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
223 "TARGET_DFP"
224 "dmulq %0,%1,%2"
eda328bf 225 [(set_attr "type" "dfp")])
6ef9a246
JJ
226
227(define_insn "divdd3"
799dbb0f
ME
228 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
229 (div:DD (match_operand:DD 1 "gpc_reg_operand" "d")
230 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
231 "TARGET_DFP"
232 "ddiv %0,%1,%2"
eda328bf 233 [(set_attr "type" "dfp")])
6ef9a246
JJ
234
235(define_insn "divtd3"
799dbb0f
ME
236 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
237 (div:TD (match_operand:TD 1 "gpc_reg_operand" "d")
238 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
239 "TARGET_DFP"
240 "ddivq %0,%1,%2"
eda328bf 241 [(set_attr "type" "dfp")])
6ef9a246
JJ
242
243(define_insn "*cmpdd_internal1"
244 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
799dbb0f
ME
245 (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
246 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
247 "TARGET_DFP"
248 "dcmpu %0,%1,%2"
eda328bf 249 [(set_attr "type" "dfp")])
6ef9a246
JJ
250
251(define_insn "*cmptd_internal1"
252 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
799dbb0f
ME
253 (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
254 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
255 "TARGET_DFP"
256 "dcmpuq %0,%1,%2"
eda328bf 257 [(set_attr "type" "dfp")])
6ef9a246 258
6f975f93
PB
259(define_insn "floatdidd2"
260 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
261 (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
262 "TARGET_DFP && TARGET_POPCNTD"
263 "dcffix %0,%1"
eda328bf 264 [(set_attr "type" "dfp")])
6f975f93 265
6ef9a246 266(define_insn "floatditd2"
799dbb0f
ME
267 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
268 (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
269 "TARGET_DFP"
270 "dcffixq %0,%1"
eda328bf 271 [(set_attr "type" "dfp")])
6ef9a246
JJ
272
273;; Convert a decimal64 to a decimal64 whose value is an integer.
274;; This is the first stage of converting it to an integer type.
275
276(define_insn "ftruncdd2"
799dbb0f
ME
277 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
278 (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
279 "TARGET_DFP"
280 "drintn. 0,%0,%1,1"
eda328bf 281 [(set_attr "type" "dfp")])
6ef9a246
JJ
282
283;; Convert a decimal64 whose value is an integer to an actual integer.
284;; This is the second stage of converting decimal float to integer type.
285
286(define_insn "fixdddi2"
799dbb0f
ME
287 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
288 (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
289 "TARGET_DFP"
290 "dctfix %0,%1"
eda328bf 291 [(set_attr "type" "dfp")])
6ef9a246
JJ
292
293;; Convert a decimal128 to a decimal128 whose value is an integer.
294;; This is the first stage of converting it to an integer type.
295
296(define_insn "ftrunctd2"
799dbb0f
ME
297 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
298 (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
299 "TARGET_DFP"
300 "drintnq. 0,%0,%1,1"
eda328bf 301 [(set_attr "type" "dfp")])
6ef9a246
JJ
302
303;; Convert a decimal128 whose value is an integer to an actual integer.
304;; This is the second stage of converting decimal float to integer type.
305
306(define_insn "fixtddi2"
799dbb0f
ME
307 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
308 (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
309 "TARGET_DFP"
310 "dctfixq %0,%1"
eda328bf 311 [(set_attr "type" "dfp")])
06b39289
MM
312
313\f
314;; Decimal builtin support
315
316(define_c_enum "unspec"
317 [UNSPEC_DDEDPD
318 UNSPEC_DENBCD
319 UNSPEC_DXEX
320 UNSPEC_DIEX
321 UNSPEC_DSCLI
5a3a6a5e 322 UNSPEC_DTSTSFI
06b39289
MM
323 UNSPEC_DSCRI])
324
5a3a6a5e
KN
325(define_code_iterator DFP_TEST [eq lt gt unordered])
326
06b39289
MM
327(define_mode_iterator D64_D128 [DD TD])
328
329(define_mode_attr dfp_suffix [(DD "")
330 (TD "q")])
331
332(define_insn "dfp_ddedpd_<mode>"
333 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
334 (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
335 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
336 UNSPEC_DDEDPD))]
337 "TARGET_DFP"
338 "ddedpd<dfp_suffix> %1,%0,%2"
eda328bf 339 [(set_attr "type" "dfp")])
06b39289
MM
340
341(define_insn "dfp_denbcd_<mode>"
342 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
343 (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
344 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
345 UNSPEC_DENBCD))]
346 "TARGET_DFP"
347 "denbcd<dfp_suffix> %1,%0,%2"
eda328bf 348 [(set_attr "type" "dfp")])
06b39289
MM
349
350(define_insn "dfp_dxex_<mode>"
351 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
352 (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
353 UNSPEC_DXEX))]
354 "TARGET_DFP"
355 "dxex<dfp_suffix> %0,%1"
eda328bf 356 [(set_attr "type" "dfp")])
06b39289
MM
357
358(define_insn "dfp_diex_<mode>"
359 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
360 (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
361 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
362 UNSPEC_DXEX))]
363 "TARGET_DFP"
364 "diex<dfp_suffix> %0,%1,%2"
eda328bf 365 [(set_attr "type" "dfp")])
06b39289 366
5a3a6a5e
KN
367(define_expand "dfptstsfi_<code>_<mode>"
368 [(set (match_dup 3)
369 (compare:CCFP
370 (unspec:D64_D128
371 [(match_operand:SI 1 "const_int_operand" "n")
372 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
373 UNSPEC_DTSTSFI)
374 (match_dup 4)))
375 (set (match_operand:SI 0 "register_operand" "")
376 (DFP_TEST:SI (match_dup 3)
377 (const_int 0)))
378 ]
379 "TARGET_P9_MISC"
380{
381 operands[3] = gen_reg_rtx (CCFPmode);
382 operands[4] = const0_rtx;
383})
384
385(define_insn "*dfp_sgnfcnc_<mode>"
386 [(set (match_operand:CCFP 0 "" "=y")
387 (compare:CCFP
388 (unspec:D64_D128 [(match_operand:SI 1 "const_int_operand" "n")
389 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
390 UNSPEC_DTSTSFI)
391 (match_operand:SI 3 "zero_constant" "j")))]
392 "TARGET_P9_MISC"
393{
394 /* If immediate operand is greater than 63, it will behave as if
395 the value had been 63. The code generator does not support
396 immediate operand values greater than 63. */
397 if (!(IN_RANGE (INTVAL (operands[1]), 0, 63)))
398 operands[1] = GEN_INT (63);
399 return "dtstsfi<dfp_suffix> %0,%1,%2";
400}
401 [(set_attr "type" "fp")])
402
06b39289
MM
403(define_insn "dfp_dscli_<mode>"
404 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
405 (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
406 (match_operand:QI 2 "immediate_operand" "i")]
407 UNSPEC_DSCLI))]
408 "TARGET_DFP"
409 "dscli<dfp_suffix> %0,%1,%2"
eda328bf 410 [(set_attr "type" "dfp")])
06b39289
MM
411
412(define_insn "dfp_dscri_<mode>"
413 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
414 (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
415 (match_operand:QI 2 "immediate_operand" "i")]
416 UNSPEC_DSCRI))]
417 "TARGET_DFP"
418 "dscri<dfp_suffix> %0,%1,%2"
eda328bf 419 [(set_attr "type" "dfp")])