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