dfp.md revision 1.12 1 1.1 mrg ;; Decimal Floating Point (DFP) patterns.
2 1.12 mrg ;; Copyright (C) 2007-2020 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.12 mrg ; Either of the two decimal modes.
32 1.12 mrg (define_mode_iterator DDTD [DD TD])
33 1.12 mrg
34 1.12 mrg (define_mode_attr q [(DD "") (TD "q")])
35 1.12 mrg
36 1.1 mrg
37 1.1 mrg (define_insn "movsd_store"
38 1.1 mrg [(set (match_operand:DD 0 "nonimmediate_operand" "=m")
39 1.1 mrg (unspec:DD [(match_operand:SD 1 "input_operand" "d")]
40 1.1 mrg UNSPEC_MOVSD_STORE))]
41 1.1 mrg "(gpc_reg_operand (operands[0], DDmode)
42 1.1 mrg || gpc_reg_operand (operands[1], SDmode))
43 1.10 mrg && TARGET_HARD_FLOAT"
44 1.1 mrg "stfd%U0%X0 %1,%0"
45 1.11 mrg [(set_attr "type" "fpstore")])
46 1.1 mrg
47 1.1 mrg (define_insn "movsd_load"
48 1.1 mrg [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
49 1.1 mrg (unspec:SD [(match_operand:DD 1 "input_operand" "m")]
50 1.1 mrg UNSPEC_MOVSD_LOAD))]
51 1.1 mrg "(gpc_reg_operand (operands[0], SDmode)
52 1.1 mrg || gpc_reg_operand (operands[1], DDmode))
53 1.10 mrg && TARGET_HARD_FLOAT"
54 1.1 mrg "lfd%U1%X1 %0,%1"
55 1.11 mrg [(set_attr "type" "fpload")])
56 1.1 mrg
57 1.1 mrg ;; Hardware support for decimal floating point operations.
58 1.1 mrg
59 1.1 mrg (define_insn "extendsddd2"
60 1.1 mrg [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
61 1.1 mrg (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))]
62 1.1 mrg "TARGET_DFP"
63 1.1 mrg "dctdp %0,%1"
64 1.7 mrg [(set_attr "type" "dfp")])
65 1.1 mrg
66 1.1 mrg (define_expand "extendsdtd2"
67 1.1 mrg [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
68 1.1 mrg (float_extend:TD (match_operand:SD 1 "gpc_reg_operand" "d")))]
69 1.1 mrg "TARGET_DFP"
70 1.1 mrg {
71 1.1 mrg rtx tmp = gen_reg_rtx (DDmode);
72 1.1 mrg emit_insn (gen_extendsddd2 (tmp, operands[1]));
73 1.1 mrg emit_insn (gen_extendddtd2 (operands[0], tmp));
74 1.1 mrg DONE;
75 1.1 mrg })
76 1.1 mrg
77 1.1 mrg (define_insn "truncddsd2"
78 1.1 mrg [(set (match_operand:SD 0 "gpc_reg_operand" "=f")
79 1.1 mrg (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))]
80 1.1 mrg "TARGET_DFP"
81 1.1 mrg "drsp %0,%1"
82 1.7 mrg [(set_attr "type" "dfp")])
83 1.1 mrg
84 1.10 mrg (define_insn "negdd2"
85 1.1 mrg [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
86 1.1 mrg (neg:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
87 1.10 mrg "TARGET_HARD_FLOAT"
88 1.1 mrg "fneg %0,%1"
89 1.7 mrg [(set_attr "type" "fpsimple")])
90 1.1 mrg
91 1.10 mrg (define_insn "absdd2"
92 1.1 mrg [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
93 1.1 mrg (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
94 1.10 mrg "TARGET_HARD_FLOAT"
95 1.1 mrg "fabs %0,%1"
96 1.7 mrg [(set_attr "type" "fpsimple")])
97 1.1 mrg
98 1.1 mrg (define_insn "*nabsdd2_fpr"
99 1.1 mrg [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
100 1.1 mrg (neg:DD (abs:DD (match_operand:DD 1 "gpc_reg_operand" "d"))))]
101 1.10 mrg "TARGET_HARD_FLOAT"
102 1.1 mrg "fnabs %0,%1"
103 1.7 mrg [(set_attr "type" "fpsimple")])
104 1.1 mrg
105 1.10 mrg (define_insn "negtd2"
106 1.3 mrg [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
107 1.3 mrg (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
108 1.10 mrg "TARGET_HARD_FLOAT"
109 1.3 mrg "@
110 1.3 mrg fneg %0,%1
111 1.3 mrg fneg %0,%1\;fmr %L0,%L1"
112 1.7 mrg [(set_attr "type" "fpsimple")
113 1.3 mrg (set_attr "length" "4,8")])
114 1.1 mrg
115 1.10 mrg (define_insn "abstd2"
116 1.3 mrg [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
117 1.3 mrg (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
118 1.10 mrg "TARGET_HARD_FLOAT"
119 1.3 mrg "@
120 1.3 mrg fabs %0,%1
121 1.3 mrg fabs %0,%1\;fmr %L0,%L1"
122 1.7 mrg [(set_attr "type" "fpsimple")
123 1.3 mrg (set_attr "length" "4,8")])
124 1.1 mrg
125 1.1 mrg (define_insn "*nabstd2_fpr"
126 1.3 mrg [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
127 1.3 mrg (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
128 1.10 mrg "TARGET_HARD_FLOAT"
129 1.3 mrg "@
130 1.3 mrg fnabs %0,%1
131 1.3 mrg fnabs %0,%1\;fmr %L0,%L1"
132 1.7 mrg [(set_attr "type" "fpsimple")
133 1.3 mrg (set_attr "length" "4,8")])
134 1.1 mrg
135 1.1 mrg ;; Hardware support for decimal floating point operations.
136 1.1 mrg
137 1.1 mrg (define_insn "extendddtd2"
138 1.1 mrg [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
139 1.1 mrg (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))]
140 1.1 mrg "TARGET_DFP"
141 1.1 mrg "dctqpq %0,%1"
142 1.7 mrg [(set_attr "type" "dfp")])
143 1.1 mrg
144 1.1 mrg ;; The result of drdpq is an even/odd register pair with the converted
145 1.1 mrg ;; value in the even register and zero in the odd register.
146 1.1 mrg ;; FIXME: Avoid the register move by using a reload constraint to ensure
147 1.1 mrg ;; that the result is the first of the pair receiving the result of drdpq.
148 1.1 mrg
149 1.1 mrg (define_insn "trunctddd2"
150 1.1 mrg [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
151 1.1 mrg (float_truncate:DD (match_operand:TD 1 "gpc_reg_operand" "d")))
152 1.1 mrg (clobber (match_scratch:TD 2 "=d"))]
153 1.1 mrg "TARGET_DFP"
154 1.1 mrg "drdpq %2,%1\;fmr %0,%2"
155 1.9 mrg [(set_attr "type" "dfp")
156 1.9 mrg (set_attr "length" "8")])
157 1.1 mrg
158 1.12 mrg (define_insn "add<mode>3"
159 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
160 1.12 mrg (plus:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "%d")
161 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
162 1.1 mrg "TARGET_DFP"
163 1.12 mrg "dadd<q> %0,%1,%2"
164 1.7 mrg [(set_attr "type" "dfp")])
165 1.1 mrg
166 1.12 mrg (define_insn "sub<mode>3"
167 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
168 1.12 mrg (minus:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "d")
169 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
170 1.1 mrg "TARGET_DFP"
171 1.12 mrg "dsub<q> %0,%1,%2"
172 1.7 mrg [(set_attr "type" "dfp")])
173 1.1 mrg
174 1.12 mrg (define_insn "mul<mode>3"
175 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
176 1.12 mrg (mult:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "%d")
177 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
178 1.1 mrg "TARGET_DFP"
179 1.12 mrg "dmul<q> %0,%1,%2"
180 1.7 mrg [(set_attr "type" "dfp")])
181 1.1 mrg
182 1.12 mrg (define_insn "div<mode>3"
183 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
184 1.12 mrg (div:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "d")
185 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
186 1.1 mrg "TARGET_DFP"
187 1.12 mrg "ddiv<q> %0,%1,%2"
188 1.7 mrg [(set_attr "type" "dfp")])
189 1.1 mrg
190 1.12 mrg (define_insn "*cmp<mode>_internal1"
191 1.1 mrg [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
192 1.12 mrg (compare:CCFP (match_operand:DDTD 1 "gpc_reg_operand" "d")
193 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
194 1.1 mrg "TARGET_DFP"
195 1.12 mrg "dcmpu<q> %0,%1,%2"
196 1.7 mrg [(set_attr "type" "dfp")])
197 1.1 mrg
198 1.3 mrg (define_insn "floatdidd2"
199 1.3 mrg [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
200 1.3 mrg (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))]
201 1.3 mrg "TARGET_DFP && TARGET_POPCNTD"
202 1.3 mrg "dcffix %0,%1"
203 1.7 mrg [(set_attr "type" "dfp")])
204 1.3 mrg
205 1.1 mrg (define_insn "floatditd2"
206 1.1 mrg [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
207 1.1 mrg (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))]
208 1.1 mrg "TARGET_DFP"
209 1.1 mrg "dcffixq %0,%1"
210 1.7 mrg [(set_attr "type" "dfp")])
211 1.1 mrg
212 1.12 mrg ;; Convert a decimal64/128 to a decimal64/128 whose value is an integer.
213 1.1 mrg ;; This is the first stage of converting it to an integer type.
214 1.1 mrg
215 1.12 mrg (define_insn "ftrunc<mode>2"
216 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
217 1.12 mrg (fix:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "d")))]
218 1.1 mrg "TARGET_DFP"
219 1.12 mrg "drintn<q>. 0,%0,%1,1"
220 1.7 mrg [(set_attr "type" "dfp")])
221 1.1 mrg
222 1.12 mrg ;; Convert a decimal64/128 whose value is an integer to an actual integer.
223 1.1 mrg ;; This is the second stage of converting decimal float to integer type.
224 1.1 mrg
225 1.12 mrg (define_insn "fix<mode>di2"
226 1.1 mrg [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
227 1.12 mrg (fix:DI (match_operand:DDTD 1 "gpc_reg_operand" "d")))]
228 1.1 mrg "TARGET_DFP"
229 1.12 mrg "dctfix<q> %0,%1"
230 1.7 mrg [(set_attr "type" "dfp")])
231 1.3 mrg
233 1.3 mrg ;; Decimal builtin support
234 1.3 mrg
235 1.3 mrg (define_c_enum "unspec"
236 1.3 mrg [UNSPEC_DDEDPD
237 1.3 mrg UNSPEC_DENBCD
238 1.3 mrg UNSPEC_DXEX
239 1.3 mrg UNSPEC_DIEX
240 1.7 mrg UNSPEC_DSCLI
241 1.3 mrg UNSPEC_DTSTSFI
242 1.3 mrg UNSPEC_DSCRI])
243 1.7 mrg
244 1.7 mrg (define_code_iterator DFP_TEST [eq lt gt unordered])
245 1.3 mrg
246 1.12 mrg (define_insn "dfp_ddedpd_<mode>"
247 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
248 1.12 mrg (unspec:DDTD [(match_operand:QI 1 "const_0_to_3_operand" "i")
249 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")]
250 1.3 mrg UNSPEC_DDEDPD))]
251 1.12 mrg "TARGET_DFP"
252 1.7 mrg "ddedpd<q> %1,%0,%2"
253 1.3 mrg [(set_attr "type" "dfp")])
254 1.3 mrg
255 1.12 mrg (define_insn "dfp_denbcd_<mode>"
256 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
257 1.12 mrg (unspec:DDTD [(match_operand:QI 1 "const_0_to_1_operand" "i")
258 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")]
259 1.3 mrg UNSPEC_DENBCD))]
260 1.12 mrg "TARGET_DFP"
261 1.7 mrg "denbcd<q> %1,%0,%2"
262 1.3 mrg [(set_attr "type" "dfp")])
263 1.3 mrg
264 1.6 mrg (define_insn "dfp_dxex_<mode>"
265 1.12 mrg [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
266 1.6 mrg (unspec:DI [(match_operand:DDTD 1 "gpc_reg_operand" "d")]
267 1.3 mrg UNSPEC_DXEX))]
268 1.12 mrg "TARGET_DFP"
269 1.7 mrg "dxex<q> %0,%1"
270 1.3 mrg [(set_attr "type" "dfp")])
271 1.3 mrg
272 1.12 mrg (define_insn "dfp_diex_<mode>"
273 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
274 1.12 mrg (unspec:DDTD [(match_operand:DI 1 "gpc_reg_operand" "d")
275 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")]
276 1.3 mrg UNSPEC_DXEX))]
277 1.12 mrg "TARGET_DFP"
278 1.7 mrg "diex<q> %0,%1,%2"
279 1.7 mrg [(set_attr "type" "dfp")])
280 1.7 mrg
281 1.7 mrg (define_expand "dfptstsfi_<code>_<mode>"
282 1.12 mrg [(set (match_dup 3)
283 1.12 mrg (compare:CCFP (unspec:DDTD [(match_operand:SI 1 "const_int_operand")
284 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand")]
285 1.12 mrg UNSPEC_DTSTSFI)
286 1.10 mrg (const_int 0)))
287 1.12 mrg (set (match_operand:SI 0 "register_operand")
288 1.7 mrg (DFP_TEST:SI (match_dup 3)
289 1.7 mrg (const_int 0)))
290 1.7 mrg ]
291 1.7 mrg "TARGET_P9_MISC"
292 1.12 mrg {
293 1.12 mrg if (<CODE> == UNORDERED && !HONOR_NANS (<MODE>mode))
294 1.12 mrg {
295 1.12 mrg emit_move_insn (operands[0], const0_rtx);
296 1.12 mrg DONE;
297 1.12 mrg }
298 1.7 mrg
299 1.7 mrg operands[3] = gen_reg_rtx (CCFPmode);
300 1.7 mrg })
301 1.7 mrg
302 1.7 mrg (define_insn "*dfp_sgnfcnc_<mode>"
303 1.12 mrg [(set (match_operand:CCFP 0 "" "=y")
304 1.12 mrg (compare:CCFP
305 1.12 mrg (unspec:DDTD [(match_operand:SI 1 "const_int_operand" "n")
306 1.12 mrg (match_operand:DDTD 2 "gpc_reg_operand" "d")]
307 1.7 mrg UNSPEC_DTSTSFI)
308 1.7 mrg (match_operand:SI 3 "zero_constant" "j")))]
309 1.7 mrg "TARGET_P9_MISC"
310 1.7 mrg {
311 1.7 mrg /* If immediate operand is greater than 63, it will behave as if
312 1.7 mrg the value had been 63. The code generator does not support
313 1.7 mrg immediate operand values greater than 63. */
314 1.7 mrg if (!(IN_RANGE (INTVAL (operands[1]), 0, 63)))
315 1.12 mrg operands[1] = GEN_INT (63);
316 1.7 mrg return "dtstsfi<q> %0,%1,%2";
317 1.3 mrg }
318 1.3 mrg [(set_attr "type" "fp")])
319 1.3 mrg
320 1.12 mrg (define_insn "dfp_dscli_<mode>"
321 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
322 1.12 mrg (unspec:DDTD [(match_operand:DDTD 1 "gpc_reg_operand" "d")
323 1.12 mrg (match_operand:QI 2 "immediate_operand" "i")]
324 1.3 mrg UNSPEC_DSCLI))]
325 1.12 mrg "TARGET_DFP"
326 1.7 mrg "dscli<q> %0,%1,%2"
327 1.3 mrg [(set_attr "type" "dfp")])
328 1.3 mrg
329 1.12 mrg (define_insn "dfp_dscri_<mode>"
330 1.12 mrg [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
331 1.12 mrg (unspec:DDTD [(match_operand:DDTD 1 "gpc_reg_operand" "d")
332 1.12 mrg (match_operand:QI 2 "immediate_operand" "i")]
333 1.3 mrg UNSPEC_DSCRI))]
334 1.12 mrg "TARGET_DFP"
335 1.7 mrg "dscri<q> %0,%1,%2"
336 [(set_attr "type" "dfp")])
337