]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/dfp.md
RISC-V: Fix C ABI for flattened struct with 0-length bitfield.
[thirdparty/gcc.git] / gcc / config / rs6000 / dfp.md
CommitLineData
7393f7f8 1;; Decimal Floating Point (DFP) patterns.
a5544970 2;; Copyright (C) 2007-2019 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))
11d8d07e 38 && TARGET_HARD_FLOAT"
e41b2a33 39 "stfd%U0%X0 %1,%0"
b24a46be 40 [(set_attr "type" "fpstore")])
e41b2a33
PB
41
42(define_insn "movsd_load"
43 [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
44 (unspec:SD [(match_operand:DD 1 "input_operand" "m")]
45 UNSPEC_MOVSD_LOAD))]
46 "(gpc_reg_operand (operands[0], SDmode)
47 || gpc_reg_operand (operands[1], DDmode))
11d8d07e 48 && TARGET_HARD_FLOAT"
e41b2a33 49 "lfd%U1%X1 %0,%1"
b24a46be 50 [(set_attr "type" "fpload")])
e41b2a33
PB
51
52;; Hardware support for decimal floating point operations.
53
54(define_insn "extendsddd2"
799dbb0f 55 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
e41b2a33
PB
56 (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
57 "TARGET_DFP"
58 "dctdp %0,%1"
eda328bf 59 [(set_attr "type" "dfp")])
e41b2a33
PB
60
61(define_expand "extendsdtd2"
799dbb0f
ME
62 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
63 (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
e41b2a33
PB
64 "TARGET_DFP"
65{
66 rtx tmp = gen_reg_rtx (DDmode);
67 emit_insn (gen_extendsddd2 (tmp, operands[1]));
68 emit_insn (gen_extendddtd2 (operands[0], tmp));
69 DONE;
70})
71
72(define_insn "truncddsd2"
73 [(set (match_operand:SD 0 "gpc_reg_operand" "=f")
799dbb0f 74 (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
e41b2a33
PB
75 "TARGET_DFP"
76 "drsp %0,%1"
eda328bf 77 [(set_attr "type" "dfp")])
e41b2a33 78
11d8d07e 79(define_insn "negdd2"
799dbb0f
ME
80 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
81 (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
11d8d07e 82 "TARGET_HARD_FLOAT"
c092b045 83 "fneg %0,%1"
7c788ce2 84 [(set_attr "type" "fpsimple")])
c092b045 85
11d8d07e 86(define_insn "absdd2"
799dbb0f
ME
87 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
88 (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
11d8d07e 89 "TARGET_HARD_FLOAT"
c092b045 90 "fabs %0,%1"
7c788ce2 91 [(set_attr "type" "fpsimple")])
c092b045
PB
92
93(define_insn "*nabsdd2_fpr"
799dbb0f
ME
94 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
95 (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
11d8d07e 96 "TARGET_HARD_FLOAT"
c092b045 97 "fnabs %0,%1"
7c788ce2 98 [(set_attr "type" "fpsimple")])
c092b045 99
11d8d07e 100(define_insn "negtd2"
e2323f5b
PB
101 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
102 (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
11d8d07e 103 "TARGET_HARD_FLOAT"
e2323f5b
PB
104 "@
105 fneg %0,%1
106 fneg %0,%1\;fmr %L0,%L1"
7c788ce2 107 [(set_attr "type" "fpsimple")
e2323f5b 108 (set_attr "length" "4,8")])
c092b045 109
11d8d07e 110(define_insn "abstd2"
e2323f5b
PB
111 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
112 (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
11d8d07e 113 "TARGET_HARD_FLOAT"
e2323f5b
PB
114 "@
115 fabs %0,%1
116 fabs %0,%1\;fmr %L0,%L1"
7c788ce2 117 [(set_attr "type" "fpsimple")
e2323f5b 118 (set_attr "length" "4,8")])
c092b045
PB
119
120(define_insn "*nabstd2_fpr"
e2323f5b
PB
121 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
122 (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
11d8d07e 123 "TARGET_HARD_FLOAT"
e2323f5b
PB
124 "@
125 fnabs %0,%1
126 fnabs %0,%1\;fmr %L0,%L1"
7c788ce2 127 [(set_attr "type" "fpsimple")
e2323f5b 128 (set_attr "length" "4,8")])
c092b045 129
6ef9a246
JJ
130;; Hardware support for decimal floating point operations.
131
132(define_insn "extendddtd2"
799dbb0f
ME
133 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
134 (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
135 "TARGET_DFP"
136 "dctqpq %0,%1"
eda328bf 137 [(set_attr "type" "dfp")])
6ef9a246
JJ
138
139;; The result of drdpq is an even/odd register pair with the converted
140;; value in the even register and zero in the odd register.
141;; FIXME: Avoid the register move by using a reload constraint to ensure
142;; that the result is the first of the pair receiving the result of drdpq.
143
144(define_insn "trunctddd2"
799dbb0f
ME
145 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
146 (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d")))
147 (clobber (match_scratch:TD 2 "=d"))]
6ef9a246
JJ
148 "TARGET_DFP"
149 "drdpq %2,%1\;fmr %0,%2"
eda328bf 150 [(set_attr "type" "dfp")
521466e5 151 (set_attr "length" "8")])
6ef9a246
JJ
152
153(define_insn "adddd3"
799dbb0f
ME
154 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
155 (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
156 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
157 "TARGET_DFP"
158 "dadd %0,%1,%2"
eda328bf 159 [(set_attr "type" "dfp")])
6ef9a246
JJ
160
161(define_insn "addtd3"
799dbb0f
ME
162 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
163 (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
164 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
165 "TARGET_DFP"
166 "daddq %0,%1,%2"
eda328bf 167 [(set_attr "type" "dfp")])
6ef9a246
JJ
168
169(define_insn "subdd3"
799dbb0f
ME
170 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
171 (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d")
172 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
173 "TARGET_DFP"
174 "dsub %0,%1,%2"
eda328bf 175 [(set_attr "type" "dfp")])
6ef9a246
JJ
176
177(define_insn "subtd3"
799dbb0f
ME
178 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
179 (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d")
180 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
181 "TARGET_DFP"
182 "dsubq %0,%1,%2"
eda328bf 183 [(set_attr "type" "dfp")])
6ef9a246
JJ
184
185(define_insn "muldd3"
799dbb0f
ME
186 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
187 (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
188 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
189 "TARGET_DFP"
190 "dmul %0,%1,%2"
eda328bf 191 [(set_attr "type" "dfp")])
6ef9a246
JJ
192
193(define_insn "multd3"
799dbb0f
ME
194 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
195 (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
196 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
197 "TARGET_DFP"
198 "dmulq %0,%1,%2"
eda328bf 199 [(set_attr "type" "dfp")])
6ef9a246
JJ
200
201(define_insn "divdd3"
799dbb0f
ME
202 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
203 (div:DD (match_operand:DD 1 "gpc_reg_operand" "d")
204 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
205 "TARGET_DFP"
206 "ddiv %0,%1,%2"
eda328bf 207 [(set_attr "type" "dfp")])
6ef9a246
JJ
208
209(define_insn "divtd3"
799dbb0f
ME
210 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
211 (div:TD (match_operand:TD 1 "gpc_reg_operand" "d")
212 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
213 "TARGET_DFP"
214 "ddivq %0,%1,%2"
eda328bf 215 [(set_attr "type" "dfp")])
6ef9a246
JJ
216
217(define_insn "*cmpdd_internal1"
218 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
799dbb0f
ME
219 (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
220 (match_operand:DD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
221 "TARGET_DFP"
222 "dcmpu %0,%1,%2"
eda328bf 223 [(set_attr "type" "dfp")])
6ef9a246
JJ
224
225(define_insn "*cmptd_internal1"
226 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
799dbb0f
ME
227 (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
228 (match_operand:TD 2 "gpc_reg_operand" "d")))]
6ef9a246
JJ
229 "TARGET_DFP"
230 "dcmpuq %0,%1,%2"
eda328bf 231 [(set_attr "type" "dfp")])
6ef9a246 232
6f975f93
PB
233(define_insn "floatdidd2"
234 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
235 (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
236 "TARGET_DFP && TARGET_POPCNTD"
237 "dcffix %0,%1"
eda328bf 238 [(set_attr "type" "dfp")])
6f975f93 239
6ef9a246 240(define_insn "floatditd2"
799dbb0f
ME
241 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
242 (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
243 "TARGET_DFP"
244 "dcffixq %0,%1"
eda328bf 245 [(set_attr "type" "dfp")])
6ef9a246
JJ
246
247;; Convert a decimal64 to a decimal64 whose value is an integer.
248;; This is the first stage of converting it to an integer type.
249
250(define_insn "ftruncdd2"
799dbb0f
ME
251 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
252 (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
253 "TARGET_DFP"
254 "drintn. 0,%0,%1,1"
eda328bf 255 [(set_attr "type" "dfp")])
6ef9a246
JJ
256
257;; Convert a decimal64 whose value is an integer to an actual integer.
258;; This is the second stage of converting decimal float to integer type.
259
260(define_insn "fixdddi2"
799dbb0f
ME
261 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
262 (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
263 "TARGET_DFP"
264 "dctfix %0,%1"
eda328bf 265 [(set_attr "type" "dfp")])
6ef9a246
JJ
266
267;; Convert a decimal128 to a decimal128 whose value is an integer.
268;; This is the first stage of converting it to an integer type.
269
270(define_insn "ftrunctd2"
799dbb0f
ME
271 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
272 (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
273 "TARGET_DFP"
274 "drintnq. 0,%0,%1,1"
eda328bf 275 [(set_attr "type" "dfp")])
6ef9a246
JJ
276
277;; Convert a decimal128 whose value is an integer to an actual integer.
278;; This is the second stage of converting decimal float to integer type.
279
280(define_insn "fixtddi2"
799dbb0f
ME
281 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
282 (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
6ef9a246
JJ
283 "TARGET_DFP"
284 "dctfixq %0,%1"
eda328bf 285 [(set_attr "type" "dfp")])
06b39289
MM
286
287\f
288;; Decimal builtin support
289
290(define_c_enum "unspec"
291 [UNSPEC_DDEDPD
292 UNSPEC_DENBCD
293 UNSPEC_DXEX
294 UNSPEC_DIEX
295 UNSPEC_DSCLI
5a3a6a5e 296 UNSPEC_DTSTSFI
06b39289
MM
297 UNSPEC_DSCRI])
298
5a3a6a5e
KN
299(define_code_iterator DFP_TEST [eq lt gt unordered])
300
06b39289
MM
301(define_mode_iterator D64_D128 [DD TD])
302
303(define_mode_attr dfp_suffix [(DD "")
304 (TD "q")])
305
306(define_insn "dfp_ddedpd_<mode>"
307 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
308 (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
309 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
310 UNSPEC_DDEDPD))]
311 "TARGET_DFP"
312 "ddedpd<dfp_suffix> %1,%0,%2"
eda328bf 313 [(set_attr "type" "dfp")])
06b39289
MM
314
315(define_insn "dfp_denbcd_<mode>"
316 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
317 (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
318 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
319 UNSPEC_DENBCD))]
320 "TARGET_DFP"
321 "denbcd<dfp_suffix> %1,%0,%2"
eda328bf 322 [(set_attr "type" "dfp")])
06b39289
MM
323
324(define_insn "dfp_dxex_<mode>"
05dc406d
PB
325 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
326 (unspec:DI [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
327 UNSPEC_DXEX))]
06b39289
MM
328 "TARGET_DFP"
329 "dxex<dfp_suffix> %0,%1"
eda328bf 330 [(set_attr "type" "dfp")])
06b39289
MM
331
332(define_insn "dfp_diex_<mode>"
333 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
05dc406d 334 (unspec:D64_D128 [(match_operand:DI 1 "gpc_reg_operand" "d")
06b39289
MM
335 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
336 UNSPEC_DXEX))]
337 "TARGET_DFP"
338 "diex<dfp_suffix> %0,%1,%2"
eda328bf 339 [(set_attr "type" "dfp")])
06b39289 340
5a3a6a5e
KN
341(define_expand "dfptstsfi_<code>_<mode>"
342 [(set (match_dup 3)
343 (compare:CCFP
344 (unspec:D64_D128
ad18eed2
SB
345 [(match_operand:SI 1 "const_int_operand")
346 (match_operand:D64_D128 2 "gpc_reg_operand")]
5a3a6a5e
KN
347 UNSPEC_DTSTSFI)
348 (match_dup 4)))
ad18eed2 349 (set (match_operand:SI 0 "register_operand")
5a3a6a5e
KN
350 (DFP_TEST:SI (match_dup 3)
351 (const_int 0)))
352 ]
353 "TARGET_P9_MISC"
354{
355 operands[3] = gen_reg_rtx (CCFPmode);
356 operands[4] = const0_rtx;
357})
358
359(define_insn "*dfp_sgnfcnc_<mode>"
360 [(set (match_operand:CCFP 0 "" "=y")
361 (compare:CCFP
362 (unspec:D64_D128 [(match_operand:SI 1 "const_int_operand" "n")
363 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
364 UNSPEC_DTSTSFI)
365 (match_operand:SI 3 "zero_constant" "j")))]
366 "TARGET_P9_MISC"
367{
368 /* If immediate operand is greater than 63, it will behave as if
369 the value had been 63. The code generator does not support
370 immediate operand values greater than 63. */
371 if (!(IN_RANGE (INTVAL (operands[1]), 0, 63)))
372 operands[1] = GEN_INT (63);
373 return "dtstsfi<dfp_suffix> %0,%1,%2";
374}
375 [(set_attr "type" "fp")])
376
06b39289
MM
377(define_insn "dfp_dscli_<mode>"
378 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
379 (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
380 (match_operand:QI 2 "immediate_operand" "i")]
381 UNSPEC_DSCLI))]
382 "TARGET_DFP"
383 "dscli<dfp_suffix> %0,%1,%2"
eda328bf 384 [(set_attr "type" "dfp")])
06b39289
MM
385
386(define_insn "dfp_dscri_<mode>"
387 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
388 (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
389 (match_operand:QI 2 "immediate_operand" "i")]
390 UNSPEC_DSCRI))]
391 "TARGET_DFP"
392 "dscri<dfp_suffix> %0,%1,%2"
eda328bf 393 [(set_attr "type" "dfp")])