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