]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/rs6000/dfp.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / rs6000 / dfp.md
1 ;; Decimal Floating Point (DFP) patterns.
2 ;; Copyright (C) 2007-2019 Free Software Foundation, Inc.
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
10 ;; by the Free Software Foundation; either version 3, or (at your
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
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>.
21
22 ;;
23 ;; UNSPEC usage
24 ;;
25
26 (define_c_enum "unspec"
27 [UNSPEC_MOVSD_LOAD
28 UNSPEC_MOVSD_STORE
29 ])
30
31
32 (define_insn "movsd_store"
33 [(set (match_operand:DD 0 "nonimmediate_operand" "=m")
34 (unspec:DD [(match_operand:SD 1 "input_operand" "d")]
35 UNSPEC_MOVSD_STORE))]
36 "(gpc_reg_operand (operands[0], DDmode)
37 || gpc_reg_operand (operands[1], SDmode))
38 && TARGET_HARD_FLOAT"
39 "stfd%U0%X0 %1,%0"
40 [(set_attr "type" "fpstore")])
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))
48 && TARGET_HARD_FLOAT"
49 "lfd%U1%X1 %0,%1"
50 [(set_attr "type" "fpload")])
51
52 ;; Hardware support for decimal floating point operations.
53
54 (define_insn "extendsddd2"
55 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
56 (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
57 "TARGET_DFP"
58 "dctdp %0,%1"
59 [(set_attr "type" "dfp")])
60
61 (define_expand "extendsdtd2"
62 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
63 (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
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")
74 (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
75 "TARGET_DFP"
76 "drsp %0,%1"
77 [(set_attr "type" "dfp")])
78
79 (define_insn "negdd2"
80 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
81 (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
82 "TARGET_HARD_FLOAT"
83 "fneg %0,%1"
84 [(set_attr "type" "fpsimple")])
85
86 (define_insn "absdd2"
87 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
88 (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
89 "TARGET_HARD_FLOAT"
90 "fabs %0,%1"
91 [(set_attr "type" "fpsimple")])
92
93 (define_insn "*nabsdd2_fpr"
94 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
95 (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
96 "TARGET_HARD_FLOAT"
97 "fnabs %0,%1"
98 [(set_attr "type" "fpsimple")])
99
100 (define_insn "negtd2"
101 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
102 (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
103 "TARGET_HARD_FLOAT"
104 "@
105 fneg %0,%1
106 fneg %0,%1\;fmr %L0,%L1"
107 [(set_attr "type" "fpsimple")
108 (set_attr "length" "4,8")])
109
110 (define_insn "abstd2"
111 [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
112 (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
113 "TARGET_HARD_FLOAT"
114 "@
115 fabs %0,%1
116 fabs %0,%1\;fmr %L0,%L1"
117 [(set_attr "type" "fpsimple")
118 (set_attr "length" "4,8")])
119
120 (define_insn "*nabstd2_fpr"
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"))))]
123 "TARGET_HARD_FLOAT"
124 "@
125 fnabs %0,%1
126 fnabs %0,%1\;fmr %L0,%L1"
127 [(set_attr "type" "fpsimple")
128 (set_attr "length" "4,8")])
129
130 ;; Hardware support for decimal floating point operations.
131
132 (define_insn "extendddtd2"
133 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
134 (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
135 "TARGET_DFP"
136 "dctqpq %0,%1"
137 [(set_attr "type" "dfp")])
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"
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"))]
148 "TARGET_DFP"
149 "drdpq %2,%1\;fmr %0,%2"
150 [(set_attr "type" "dfp")
151 (set_attr "length" "8")])
152
153 (define_insn "adddd3"
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")))]
157 "TARGET_DFP"
158 "dadd %0,%1,%2"
159 [(set_attr "type" "dfp")])
160
161 (define_insn "addtd3"
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")))]
165 "TARGET_DFP"
166 "daddq %0,%1,%2"
167 [(set_attr "type" "dfp")])
168
169 (define_insn "subdd3"
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")))]
173 "TARGET_DFP"
174 "dsub %0,%1,%2"
175 [(set_attr "type" "dfp")])
176
177 (define_insn "subtd3"
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")))]
181 "TARGET_DFP"
182 "dsubq %0,%1,%2"
183 [(set_attr "type" "dfp")])
184
185 (define_insn "muldd3"
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")))]
189 "TARGET_DFP"
190 "dmul %0,%1,%2"
191 [(set_attr "type" "dfp")])
192
193 (define_insn "multd3"
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")))]
197 "TARGET_DFP"
198 "dmulq %0,%1,%2"
199 [(set_attr "type" "dfp")])
200
201 (define_insn "divdd3"
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")))]
205 "TARGET_DFP"
206 "ddiv %0,%1,%2"
207 [(set_attr "type" "dfp")])
208
209 (define_insn "divtd3"
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")))]
213 "TARGET_DFP"
214 "ddivq %0,%1,%2"
215 [(set_attr "type" "dfp")])
216
217 (define_insn "*cmpdd_internal1"
218 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
219 (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
220 (match_operand:DD 2 "gpc_reg_operand" "d")))]
221 "TARGET_DFP"
222 "dcmpu %0,%1,%2"
223 [(set_attr "type" "dfp")])
224
225 (define_insn "*cmptd_internal1"
226 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
227 (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
228 (match_operand:TD 2 "gpc_reg_operand" "d")))]
229 "TARGET_DFP"
230 "dcmpuq %0,%1,%2"
231 [(set_attr "type" "dfp")])
232
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"
238 [(set_attr "type" "dfp")])
239
240 (define_insn "floatditd2"
241 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
242 (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
243 "TARGET_DFP"
244 "dcffixq %0,%1"
245 [(set_attr "type" "dfp")])
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"
251 [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
252 (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
253 "TARGET_DFP"
254 "drintn. 0,%0,%1,1"
255 [(set_attr "type" "dfp")])
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"
261 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
262 (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
263 "TARGET_DFP"
264 "dctfix %0,%1"
265 [(set_attr "type" "dfp")])
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"
271 [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
272 (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
273 "TARGET_DFP"
274 "drintnq. 0,%0,%1,1"
275 [(set_attr "type" "dfp")])
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"
281 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
282 (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
283 "TARGET_DFP"
284 "dctfixq %0,%1"
285 [(set_attr "type" "dfp")])
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
296 UNSPEC_DTSTSFI
297 UNSPEC_DSCRI])
298
299 (define_code_iterator DFP_TEST [eq lt gt unordered])
300
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"
313 [(set_attr "type" "dfp")])
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"
322 [(set_attr "type" "dfp")])
323
324 (define_insn "dfp_dxex_<mode>"
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))]
328 "TARGET_DFP"
329 "dxex<dfp_suffix> %0,%1"
330 [(set_attr "type" "dfp")])
331
332 (define_insn "dfp_diex_<mode>"
333 [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
334 (unspec:D64_D128 [(match_operand:DI 1 "gpc_reg_operand" "d")
335 (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
336 UNSPEC_DXEX))]
337 "TARGET_DFP"
338 "diex<dfp_suffix> %0,%1,%2"
339 [(set_attr "type" "dfp")])
340
341 (define_expand "dfptstsfi_<code>_<mode>"
342 [(set (match_dup 3)
343 (compare:CCFP
344 (unspec:D64_D128
345 [(match_operand:SI 1 "const_int_operand")
346 (match_operand:D64_D128 2 "gpc_reg_operand")]
347 UNSPEC_DTSTSFI)
348 (match_dup 4)))
349 (set (match_operand:SI 0 "register_operand")
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
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"
384 [(set_attr "type" "dfp")])
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"
393 [(set_attr "type" "dfp")])