Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/arm/vfp.md @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
rev | line source |
---|---|
0 | 1 ;; ARM VFP instruction patterns |
131 | 2 ;; Copyright (C) 2003-2018 Free Software Foundation, Inc. |
0 | 3 ;; Written by CodeSourcery. |
4 ;; | |
5 ;; This file is part of GCC. | |
6 ;; | |
7 ;; GCC is free software; you can redistribute it and/or modify it | |
8 ;; under the terms of the GNU General Public License as published by | |
9 ;; the Free Software Foundation; either version 3, or (at your option) | |
10 ;; any later version. | |
11 ;; | |
12 ;; GCC is distributed in the hope that it will be useful, but | |
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 ;; General Public License for more details. | |
16 ;; | |
17 ;; You should have received a copy of the GNU General Public License | |
18 ;; along with GCC; see the file COPYING3. If not see | |
19 ;; <http://www.gnu.org/licenses/>. */ | |
20 | |
111 | 21 ;; Patterns for HI moves which provide more data transfer instructions when VFP |
22 ;; support is enabled. | |
23 (define_insn "*arm_movhi_vfp" | |
24 [(set | |
25 (match_operand:HI 0 "nonimmediate_operand" | |
26 "=rk, r, r, m, r, *t, r, *t") | |
27 (match_operand:HI 1 "general_operand" | |
28 "rIk, K, n, r, mi, r, *t, *t"))] | |
29 "TARGET_ARM && TARGET_HARD_FLOAT | |
30 && !TARGET_VFP_FP16INST | |
31 && (register_operand (operands[0], HImode) | |
32 || register_operand (operands[1], HImode))" | |
33 { | |
34 switch (which_alternative) | |
35 { | |
36 case 0: | |
37 return "mov%?\t%0, %1\t%@ movhi"; | |
38 case 1: | |
39 return "mvn%?\t%0, #%B1\t%@ movhi"; | |
40 case 2: | |
41 return "movw%?\t%0, %L1\t%@ movhi"; | |
42 case 3: | |
43 return "strh%?\t%1, %0\t%@ movhi"; | |
44 case 4: | |
45 return "ldrh%?\t%0, %1\t%@ movhi"; | |
46 case 5: | |
47 case 6: | |
48 return "vmov%?\t%0, %1\t%@ int"; | |
49 case 7: | |
50 return "vmov%?.f32\t%0, %1\t%@ int"; | |
51 default: | |
52 gcc_unreachable (); | |
53 } | |
54 } | |
55 [(set_attr "predicable" "yes") | |
56 (set_attr_alternative "type" | |
57 [(if_then_else | |
58 (match_operand 1 "const_int_operand" "") | |
59 (const_string "mov_imm") | |
60 (const_string "mov_reg")) | |
61 (const_string "mvn_imm") | |
62 (const_string "mov_imm") | |
63 (const_string "store_4") | |
64 (const_string "load_4") | |
65 (const_string "f_mcr") | |
66 (const_string "f_mrc") | |
67 (const_string "fmov")]) | |
68 (set_attr "arch" "*, *, v6t2, *, *, *, *, *") | |
69 (set_attr "pool_range" "*, *, *, *, 256, *, *, *") | |
70 (set_attr "neg_pool_range" "*, *, *, *, 244, *, *, *") | |
71 (set_attr "length" "4")] | |
0 | 72 ) |
73 | |
111 | 74 (define_insn "*thumb2_movhi_vfp" |
75 [(set | |
76 (match_operand:HI 0 "nonimmediate_operand" | |
77 "=rk, r, l, r, m, r, *t, r, *t") | |
78 (match_operand:HI 1 "general_operand" | |
79 "rk, I, Py, n, r, m, r, *t, *t"))] | |
80 "TARGET_THUMB2 && TARGET_HARD_FLOAT | |
81 && !TARGET_VFP_FP16INST | |
82 && (register_operand (operands[0], HImode) | |
83 || register_operand (operands[1], HImode))" | |
84 { | |
85 switch (which_alternative) | |
86 { | |
87 case 0: | |
88 case 1: | |
89 case 2: | |
90 return "mov%?\t%0, %1\t%@ movhi"; | |
91 case 3: | |
92 return "movw%?\t%0, %L1\t%@ movhi"; | |
93 case 4: | |
94 return "strh%?\t%1, %0\t%@ movhi"; | |
95 case 5: | |
96 return "ldrh%?\t%0, %1\t%@ movhi"; | |
97 case 6: | |
98 case 7: | |
99 return "vmov%?\t%0, %1\t%@ int"; | |
100 case 8: | |
101 return "vmov%?.f32\t%0, %1\t%@ int"; | |
102 default: | |
103 gcc_unreachable (); | |
104 } | |
105 } | |
106 [(set_attr "predicable" "yes") | |
107 (set_attr "predicable_short_it" | |
108 "yes, no, yes, no, no, no, no, no, no") | |
109 (set_attr "type" | |
110 "mov_reg, mov_imm, mov_imm, mov_imm, store_4, load_4,\ | |
111 f_mcr, f_mrc, fmov") | |
112 (set_attr "arch" "*, *, *, v6t2, *, *, *, *, *") | |
113 (set_attr "pool_range" "*, *, *, *, *, 4094, *, *, *") | |
114 (set_attr "neg_pool_range" "*, *, *, *, *, 250, *, *, *") | |
115 (set_attr "length" "2, 4, 2, 4, 4, 4, 4, 4, 4")] | |
116 ) | |
117 | |
118 ;; Patterns for HI moves which provide more data transfer instructions when FP16 | |
119 ;; instructions are available. | |
120 (define_insn "*arm_movhi_fp16" | |
121 [(set | |
122 (match_operand:HI 0 "nonimmediate_operand" | |
123 "=r, r, r, m, r, *t, r, *t") | |
124 (match_operand:HI 1 "general_operand" | |
125 "rIk, K, n, r, mi, r, *t, *t"))] | |
126 "TARGET_ARM && TARGET_VFP_FP16INST | |
127 && (register_operand (operands[0], HImode) | |
128 || register_operand (operands[1], HImode))" | |
129 { | |
130 switch (which_alternative) | |
131 { | |
132 case 0: | |
133 return "mov%?\t%0, %1\t%@ movhi"; | |
134 case 1: | |
135 return "mvn%?\t%0, #%B1\t%@ movhi"; | |
136 case 2: | |
137 return "movw%?\t%0, %L1\t%@ movhi"; | |
138 case 3: | |
139 return "strh%?\t%1, %0\t%@ movhi"; | |
140 case 4: | |
141 return "ldrh%?\t%0, %1\t%@ movhi"; | |
142 case 5: | |
143 case 6: | |
144 return "vmov.f16\t%0, %1\t%@ int"; | |
145 case 7: | |
146 return "vmov%?.f32\t%0, %1\t%@ int"; | |
147 default: | |
148 gcc_unreachable (); | |
149 } | |
150 } | |
151 [(set_attr "predicable" "yes, yes, yes, yes, yes, no, no, yes") | |
152 (set_attr_alternative "type" | |
153 [(if_then_else | |
154 (match_operand 1 "const_int_operand" "") | |
155 (const_string "mov_imm") | |
156 (const_string "mov_reg")) | |
157 (const_string "mvn_imm") | |
158 (const_string "mov_imm") | |
159 (const_string "store_4") | |
160 (const_string "load_4") | |
161 (const_string "f_mcr") | |
162 (const_string "f_mrc") | |
163 (const_string "fmov")]) | |
164 (set_attr "arch" "*, *, v6t2, *, *, *, *, *") | |
165 (set_attr "pool_range" "*, *, *, *, 256, *, *, *") | |
166 (set_attr "neg_pool_range" "*, *, *, *, 244, *, *, *") | |
167 (set_attr "length" "4")] | |
168 ) | |
169 | |
170 (define_insn "*thumb2_movhi_fp16" | |
171 [(set | |
172 (match_operand:HI 0 "nonimmediate_operand" | |
173 "=rk, r, l, r, m, r, *t, r, *t") | |
174 (match_operand:HI 1 "general_operand" | |
175 "rk, I, Py, n, r, m, r, *t, *t"))] | |
176 "TARGET_THUMB2 && TARGET_VFP_FP16INST | |
177 && (register_operand (operands[0], HImode) | |
178 || register_operand (operands[1], HImode))" | |
179 { | |
180 switch (which_alternative) | |
181 { | |
182 case 0: | |
183 case 1: | |
184 case 2: | |
185 return "mov%?\t%0, %1\t%@ movhi"; | |
186 case 3: | |
187 return "movw%?\t%0, %L1\t%@ movhi"; | |
188 case 4: | |
189 return "strh%?\t%1, %0\t%@ movhi"; | |
190 case 5: | |
191 return "ldrh%?\t%0, %1\t%@ movhi"; | |
192 case 6: | |
193 case 7: | |
194 return "vmov.f16\t%0, %1\t%@ int"; | |
195 case 8: | |
196 return "vmov%?.f32\t%0, %1\t%@ int"; | |
197 default: | |
198 gcc_unreachable (); | |
199 } | |
200 } | |
201 [(set_attr "predicable" | |
202 "yes, yes, yes, yes, yes, yes, no, no, yes") | |
203 (set_attr "predicable_short_it" | |
204 "yes, no, yes, no, no, no, no, no, no") | |
205 (set_attr "type" | |
206 "mov_reg, mov_imm, mov_imm, mov_imm, store_4, load_4,\ | |
207 f_mcr, f_mrc, fmov") | |
208 (set_attr "arch" "*, *, *, v6t2, *, *, *, *, *") | |
209 (set_attr "pool_range" "*, *, *, *, *, 4094, *, *, *") | |
210 (set_attr "neg_pool_range" "*, *, *, *, *, 250, *, *, *") | |
211 (set_attr "length" "2, 4, 2, 4, 4, 4, 4, 4, 4")] | |
212 ) | |
0 | 213 |
214 ;; SImode moves | |
215 ;; ??? For now do not allow loading constants into vfp regs. This causes | |
216 ;; problems because small constants get converted into adds. | |
217 (define_insn "*arm_movsi_vfp" | |
218 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
219 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))] |
111 | 220 "TARGET_ARM && TARGET_HARD_FLOAT |
0 | 221 && ( s_register_operand (operands[0], SImode) |
222 || s_register_operand (operands[1], SImode))" | |
223 "* | |
224 switch (which_alternative) | |
225 { | |
226 case 0: case 1: | |
227 return \"mov%?\\t%0, %1\"; | |
228 case 2: | |
229 return \"mvn%?\\t%0, #%B1\"; | |
230 case 3: | |
231 return \"movw%?\\t%0, %1\"; | |
232 case 4: | |
233 return \"ldr%?\\t%0, %1\"; | |
234 case 5: | |
235 return \"str%?\\t%1, %0\"; | |
236 case 6: | |
111 | 237 return \"vmov%?\\t%0, %1\\t%@ int\"; |
0 | 238 case 7: |
111 | 239 return \"vmov%?\\t%0, %1\\t%@ int\"; |
0 | 240 case 8: |
111 | 241 return \"vmov%?.f32\\t%0, %1\\t%@ int\"; |
0 | 242 case 9: case 10: |
243 return output_move_vfp (operands); | |
244 default: | |
245 gcc_unreachable (); | |
246 } | |
247 " | |
248 [(set_attr "predicable" "yes") | |
111 | 249 (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load_4,store_4, |
250 f_mcr,f_mrc,fmov,f_loads,f_stores") | |
0 | 251 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*") |
252 (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")] | |
253 ) | |
254 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
255 ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
256 ;; high/low register alternatives for loads and stores here. |
111 | 257 ;; The l/Py alternative should come after r/I to ensure that the short variant |
258 ;; is chosen with length 2 when the instruction is predicated for | |
259 ;; arm_restrict_it. | |
0 | 260 (define_insn "*thumb2_movsi_vfp" |
111 | 261 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") |
262 (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] | |
263 "TARGET_THUMB2 && TARGET_HARD_FLOAT | |
0 | 264 && ( s_register_operand (operands[0], SImode) |
265 || s_register_operand (operands[1], SImode))" | |
266 "* | |
267 switch (which_alternative) | |
268 { | |
111 | 269 case 0: |
270 case 1: | |
271 case 2: | |
0 | 272 return \"mov%?\\t%0, %1\"; |
273 case 3: | |
111 | 274 return \"mvn%?\\t%0, #%B1\"; |
0 | 275 case 4: |
111 | 276 return \"movw%?\\t%0, %1\"; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
277 case 5: |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
278 case 6: |
111 | 279 return \"ldr%?\\t%0, %1\"; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
280 case 7: |
111 | 281 case 8: |
0 | 282 return \"str%?\\t%1, %0\"; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
283 case 9: |
111 | 284 return \"vmov%?\\t%0, %1\\t%@ int\"; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
285 case 10: |
111 | 286 return \"vmov%?\\t%0, %1\\t%@ int\"; |
287 case 11: | |
288 return \"vmov%?.f32\\t%0, %1\\t%@ int\"; | |
289 case 12: case 13: | |
0 | 290 return output_move_vfp (operands); |
291 default: | |
292 gcc_unreachable (); | |
293 } | |
294 " | |
295 [(set_attr "predicable" "yes") | |
111 | 296 (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no") |
297 (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_imm,load_4,load_4,store_4,store_4,f_mcr,f_mrc,fmov,f_loads,f_stores") | |
298 (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4") | |
299 (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*") | |
300 (set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] | |
0 | 301 ) |
302 | |
303 | |
304 ;; DImode moves | |
305 | |
111 | 306 (define_insn "*movdi_vfp" |
131 | 307 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,!r,w,w, Uv") |
111 | 308 (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))] |
131 | 309 "TARGET_32BIT && TARGET_HARD_FLOAT |
0 | 310 && ( register_operand (operands[0], DImode) |
111 | 311 || register_operand (operands[1], DImode)) |
312 && !(TARGET_NEON && CONST_INT_P (operands[1]) | |
313 && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))" | |
0 | 314 "* |
315 switch (which_alternative) | |
316 { | |
317 case 0: | |
318 case 1: | |
319 case 2: | |
320 case 3: | |
111 | 321 return \"#\"; |
0 | 322 case 4: |
323 case 5: | |
111 | 324 case 6: |
325 return output_move_double (operands, true, NULL); | |
326 case 7: | |
327 return \"vmov%?\\t%P0, %Q1, %R1\\t%@ int\"; | |
328 case 8: | |
329 return \"vmov%?\\t%Q0, %R0, %P1\\t%@ int\"; | |
330 case 9: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
331 if (TARGET_VFP_SINGLE) |
111 | 332 return \"vmov%?.f32\\t%0, %1\\t%@ int\;vmov%?.f32\\t%p0, %p1\\t%@ int\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
333 else |
111 | 334 return \"vmov%?.f64\\t%P0, %P1\\t%@ int\"; |
335 case 10: case 11: | |
336 return output_move_vfp (operands); | |
337 default: | |
338 gcc_unreachable (); | |
339 } | |
340 " | |
341 [(set_attr "type" "multiple,multiple,multiple,multiple,load_8,load_8,store_8,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored") | |
131 | 342 (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8) |
111 | 343 (eq_attr "alternative" "2") (const_int 12) |
344 (eq_attr "alternative" "3") (const_int 16) | |
131 | 345 (eq_attr "alternative" "4,5,6") |
346 (symbol_ref "arm_count_output_move_double_insns (operands) * 4") | |
111 | 347 (eq_attr "alternative" "9") |
348 (if_then_else | |
349 (match_test "TARGET_VFP_SINGLE") | |
350 (const_int 8) | |
351 (const_int 4))] | |
352 (const_int 4))) | |
131 | 353 (set_attr "predicable" "yes") |
111 | 354 (set_attr "arm_pool_range" "*,*,*,*,1020,4096,*,*,*,*,1020,*") |
355 (set_attr "thumb2_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") | |
356 (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*") | |
131 | 357 (set (attr "ce_count") (symbol_ref "get_attr_length (insn) / 4")) |
111 | 358 (set_attr "arch" "t2,any,any,any,a,t2,any,any,any,any,any,any")] |
359 ) | |
360 | |
361 ;; HFmode moves | |
0 | 362 |
111 | 363 (define_insn "*movhf_vfp_fp16" |
364 [(set (match_operand:HF 0 "nonimmediate_operand" | |
365 "= r,m,t,r,t,r,t,t,Um,r") | |
366 (match_operand:HF 1 "general_operand" | |
367 " m,r,t,r,r,t,Dv,Um,t,F"))] | |
368 "TARGET_32BIT | |
369 && TARGET_VFP_FP16INST | |
370 && (s_register_operand (operands[0], HFmode) | |
371 || s_register_operand (operands[1], HFmode))" | |
372 { | |
0 | 373 switch (which_alternative) |
374 { | |
111 | 375 case 0: /* ARM register from memory. */ |
376 return \"ldrh%?\\t%0, %1\\t%@ __fp16\"; | |
377 case 1: /* Memory from ARM register. */ | |
378 return \"strh%?\\t%1, %0\\t%@ __fp16\"; | |
379 case 2: /* S register from S register. */ | |
380 return \"vmov\\t%0, %1\t%@ __fp16\"; | |
381 case 3: /* ARM register from ARM register. */ | |
382 return \"mov%?\\t%0, %1\\t%@ __fp16\"; | |
383 case 4: /* S register from ARM register. */ | |
384 case 5: /* ARM register from S register. */ | |
385 case 6: /* S register from immediate. */ | |
386 return \"vmov.f16\\t%0, %1\t%@ __fp16\"; | |
387 case 7: /* S register from memory. */ | |
388 return \"vld1.16\\t{%z0}, %A1\"; | |
389 case 8: /* Memory from S register. */ | |
390 return \"vst1.16\\t{%z1}, %A0\"; | |
391 case 9: /* ARM register from constant. */ | |
392 { | |
393 long bits; | |
394 rtx ops[4]; | |
395 | |
396 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), | |
397 HFmode); | |
398 ops[0] = operands[0]; | |
399 ops[1] = GEN_INT (bits); | |
400 ops[2] = GEN_INT (bits & 0xff00); | |
401 ops[3] = GEN_INT (bits & 0x00ff); | |
402 | |
403 if (arm_arch_thumb2) | |
404 output_asm_insn (\"movw\\t%0, %1\", ops); | |
405 else | |
406 output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); | |
407 return \"\"; | |
408 } | |
0 | 409 default: |
111 | 410 gcc_unreachable (); |
0 | 411 } |
111 | 412 } |
131 | 413 [(set_attr "conds" "*, *, unconditional, *, unconditional, unconditional,\ |
414 unconditional, unconditional, unconditional,\ | |
415 unconditional") | |
416 (set_attr "predicable" "yes, yes, no, yes, no, no, no, no, no, no") | |
111 | 417 (set_attr "predicable_short_it" "no, no, no, yes,\ |
418 no, no, no, no,\ | |
419 no, no") | |
420 (set_attr_alternative "type" | |
421 [(const_string "load_4") (const_string "store_4") | |
422 (const_string "fmov") (const_string "mov_reg") | |
423 (const_string "f_mcr") (const_string "f_mrc") | |
424 (const_string "fconsts") (const_string "neon_load1_1reg") | |
425 (const_string "neon_store1_1reg") | |
426 (if_then_else (match_test "arm_arch_thumb2") | |
427 (const_string "mov_imm") | |
428 (const_string "multiple"))]) | |
429 (set_attr_alternative "length" | |
430 [(const_int 4) (const_int 4) | |
431 (const_int 4) (const_int 4) | |
432 (const_int 4) (const_int 4) | |
433 (const_int 4) (const_int 4) | |
434 (const_int 4) | |
435 (if_then_else (match_test "arm_arch_thumb2") | |
436 (const_int 4) | |
437 (const_int 8))])] | |
0 | 438 ) |
439 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
440 (define_insn "*movhf_vfp_neon" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
441 [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
442 (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))] |
111 | 443 "TARGET_32BIT |
444 && TARGET_HARD_FLOAT && TARGET_NEON_FP16 | |
445 && !TARGET_VFP_FP16INST | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
446 && ( s_register_operand (operands[0], HFmode) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
447 || s_register_operand (operands[1], HFmode))" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
448 "* |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
449 switch (which_alternative) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
450 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
451 case 0: /* S register from memory */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
452 return \"vld1.16\\t{%z0}, %A1\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
453 case 1: /* memory from S register */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
454 return \"vst1.16\\t{%z1}, %A0\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
455 case 2: /* ARM register from memory */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
456 return \"ldrh\\t%0, %1\\t%@ __fp16\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
457 case 3: /* memory from ARM register */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
458 return \"strh\\t%1, %0\\t%@ __fp16\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
459 case 4: /* S register from S register */ |
111 | 460 return \"vmov.f32\\t%0, %1\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
461 case 5: /* ARM register from ARM register */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
462 return \"mov\\t%0, %1\\t%@ __fp16\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
463 case 6: /* S register from ARM register */ |
111 | 464 return \"vmov\\t%0, %1\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
465 case 7: /* ARM register from S register */ |
111 | 466 return \"vmov\\t%0, %1\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
467 case 8: /* ARM register from constant */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
468 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
469 long bits; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
470 rtx ops[4]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
471 |
111 | 472 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), |
473 HFmode); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
474 ops[0] = operands[0]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
475 ops[1] = GEN_INT (bits); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
476 ops[2] = GEN_INT (bits & 0xff00); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
477 ops[3] = GEN_INT (bits & 0x00ff); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
478 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
479 if (arm_arch_thumb2) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
480 output_asm_insn (\"movw\\t%0, %1\", ops); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
481 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
482 output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
483 return \"\"; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
484 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
485 default: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
486 gcc_unreachable (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
487 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
488 " |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
489 [(set_attr "conds" "unconditional") |
111 | 490 (set_attr "type" "neon_load1_1reg,neon_store1_1reg,\ |
491 load_4,store_4,fmov,mov_reg,f_mcr,f_mrc,multiple") | |
492 (set_attr "length" "4,4,4,4,4,4,4,4,8")] | |
493 ) | |
494 | |
495 ;; FP16 without element load/store instructions. | |
496 (define_insn "*movhf_vfp" | |
497 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r") | |
498 (match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))] | |
499 "TARGET_32BIT | |
500 && TARGET_HARD_FLOAT | |
501 && !TARGET_NEON_FP16 | |
502 && !TARGET_VFP_FP16INST | |
503 && ( s_register_operand (operands[0], HFmode) | |
504 || s_register_operand (operands[1], HFmode))" | |
505 "* | |
506 switch (which_alternative) | |
507 { | |
508 case 0: /* ARM register from memory */ | |
509 return \"ldrh\\t%0, %1\\t%@ __fp16\"; | |
510 case 1: /* memory from ARM register */ | |
511 return \"strh\\t%1, %0\\t%@ __fp16\"; | |
512 case 2: /* S register from S register */ | |
513 return \"vmov.f32\\t%0, %1\"; | |
514 case 3: /* ARM register from ARM register */ | |
515 return \"mov\\t%0, %1\\t%@ __fp16\"; | |
516 case 4: /* S register from ARM register */ | |
517 return \"vmov\\t%0, %1\"; | |
518 case 5: /* ARM register from S register */ | |
519 return \"vmov\\t%0, %1\"; | |
520 case 6: /* ARM register from constant */ | |
521 { | |
522 long bits; | |
523 rtx ops[4]; | |
524 | |
525 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), | |
526 HFmode); | |
527 ops[0] = operands[0]; | |
528 ops[1] = GEN_INT (bits); | |
529 ops[2] = GEN_INT (bits & 0xff00); | |
530 ops[3] = GEN_INT (bits & 0x00ff); | |
531 | |
532 if (arm_arch_thumb2) | |
533 output_asm_insn (\"movw\\t%0, %1\", ops); | |
534 else | |
535 output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); | |
536 return \"\"; | |
537 } | |
538 default: | |
539 gcc_unreachable (); | |
540 } | |
541 " | |
542 [(set_attr "conds" "unconditional") | |
543 (set_attr "type" "load_4,store_4,fmov,mov_reg,f_mcr,f_mrc,multiple") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
544 (set_attr "length" "4,4,4,4,4,4,8")] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
545 ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
546 |
0 | 547 |
548 ;; SFmode moves | |
549 ;; Disparage the w<->r cases because reloading an invalid address is | |
550 ;; preferable to loading the value via integer registers. | |
551 | |
552 (define_insn "*movsf_vfp" | |
553 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r") | |
111 | 554 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] |
555 "TARGET_ARM && TARGET_HARD_FLOAT | |
0 | 556 && ( s_register_operand (operands[0], SFmode) |
557 || s_register_operand (operands[1], SFmode))" | |
558 "* | |
559 switch (which_alternative) | |
560 { | |
561 case 0: | |
111 | 562 return \"vmov%?\\t%0, %1\"; |
0 | 563 case 1: |
111 | 564 return \"vmov%?\\t%0, %1\"; |
0 | 565 case 2: |
111 | 566 return \"vmov%?.f32\\t%0, %1\"; |
0 | 567 case 3: case 4: |
568 return output_move_vfp (operands); | |
569 case 5: | |
570 return \"ldr%?\\t%0, %1\\t%@ float\"; | |
571 case 6: | |
572 return \"str%?\\t%1, %0\\t%@ float\"; | |
573 case 7: | |
111 | 574 return \"vmov%?.f32\\t%0, %1\"; |
0 | 575 case 8: |
576 return \"mov%?\\t%0, %1\\t%@ float\"; | |
577 default: | |
578 gcc_unreachable (); | |
579 } | |
580 " | |
581 [(set_attr "predicable" "yes") | |
582 (set_attr "type" | |
111 | 583 "f_mcr,f_mrc,fconsts,f_loads,f_stores,load_4,store_4,fmov,mov_reg") |
584 (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*") | |
585 (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] | |
586 ) | |
587 | |
588 (define_insn "*thumb2_movsf_vfp" | |
589 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r") | |
590 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] | |
591 "TARGET_THUMB2 && TARGET_HARD_FLOAT | |
592 && ( s_register_operand (operands[0], SFmode) | |
593 || s_register_operand (operands[1], SFmode))" | |
594 "* | |
595 switch (which_alternative) | |
596 { | |
597 case 0: | |
598 return \"vmov%?\\t%0, %1\"; | |
599 case 1: | |
600 return \"vmov%?\\t%0, %1\"; | |
601 case 2: | |
602 return \"vmov%?.f32\\t%0, %1\"; | |
603 case 3: case 4: | |
604 return output_move_vfp (operands); | |
605 case 5: | |
606 return \"ldr%?\\t%0, %1\\t%@ float\"; | |
607 case 6: | |
608 return \"str%?\\t%1, %0\\t%@ float\"; | |
609 case 7: | |
610 return \"vmov%?.f32\\t%0, %1\"; | |
611 case 8: | |
612 return \"mov%?\\t%0, %1\\t%@ float\"; | |
613 default: | |
614 gcc_unreachable (); | |
615 } | |
616 " | |
617 [(set_attr "predicable" "yes") | |
618 (set_attr "type" | |
619 "f_mcr,f_mrc,fconsts,f_loads,f_stores,load_4,store_4,fmov,mov_reg") | |
620 (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*") | |
0 | 621 (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] |
622 ) | |
623 | |
624 ;; DFmode moves | |
625 | |
626 (define_insn "*movdf_vfp" | |
111 | 627 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w ,Uv,r, m,w,r") |
628 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,G,UvF,w ,mF,r,w,r"))] | |
629 "TARGET_ARM && TARGET_HARD_FLOAT | |
0 | 630 && ( register_operand (operands[0], DFmode) |
631 || register_operand (operands[1], DFmode))" | |
632 "* | |
633 { | |
634 switch (which_alternative) | |
635 { | |
636 case 0: | |
111 | 637 return \"vmov%?\\t%P0, %Q1, %R1\"; |
0 | 638 case 1: |
111 | 639 return \"vmov%?\\t%Q0, %R0, %P1\"; |
0 | 640 case 2: |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
641 gcc_assert (TARGET_VFP_DOUBLE); |
111 | 642 return \"vmov%?.f64\\t%P0, %1\"; |
643 case 3: | |
644 gcc_assert (TARGET_VFP_DOUBLE); | |
645 return \"vmov.i64\\t%P0, #0\\t%@ float\"; | |
646 case 4: case 5: | |
0 | 647 return output_move_vfp (operands); |
111 | 648 case 6: case 7: |
649 return output_move_double (operands, true, NULL); | |
650 case 8: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
651 if (TARGET_VFP_SINGLE) |
111 | 652 return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
653 else |
111 | 654 return \"vmov%?.f64\\t%P0, %P1\"; |
655 case 9: | |
0 | 656 return \"#\"; |
657 default: | |
658 gcc_unreachable (); | |
659 } | |
660 } | |
661 " | |
111 | 662 [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,f_stored,\ |
663 load_8,store_8,ffarithd,multiple") | |
664 (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8) | |
665 (eq_attr "alternative" "8") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
666 (if_then_else |
111 | 667 (match_test "TARGET_VFP_SINGLE") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
668 (const_int 8) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
669 (const_int 4))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
670 (const_int 4))) |
111 | 671 (set_attr "predicable" "yes,yes,yes,no,yes,yes,yes,yes,yes,yes") |
672 (set_attr "pool_range" "*,*,*,*,1020,*,1020,*,*,*") | |
673 (set_attr "neg_pool_range" "*,*,*,*,1004,*,1004,*,*,*") | |
674 (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")] | |
0 | 675 ) |
676 | |
677 (define_insn "*thumb2_movdf_vfp" | |
111 | 678 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w ,Uv,r ,m,w,r") |
679 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,G,UvF,w, mF,r, w,r"))] | |
680 "TARGET_THUMB2 && TARGET_HARD_FLOAT | |
681 && ( register_operand (operands[0], DFmode) | |
682 || register_operand (operands[1], DFmode))" | |
0 | 683 "* |
684 { | |
685 switch (which_alternative) | |
686 { | |
687 case 0: | |
111 | 688 return \"vmov%?\\t%P0, %Q1, %R1\"; |
0 | 689 case 1: |
111 | 690 return \"vmov%?\\t%Q0, %R0, %P1\"; |
0 | 691 case 2: |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
692 gcc_assert (TARGET_VFP_DOUBLE); |
111 | 693 return \"vmov%?.f64\\t%P0, %1\"; |
694 case 3: | |
695 gcc_assert (TARGET_VFP_DOUBLE); | |
696 return \"vmov.i64\\t%P0, #0\\t%@ float\"; | |
697 case 4: case 5: | |
0 | 698 return output_move_vfp (operands); |
111 | 699 case 6: case 7: case 9: |
700 return output_move_double (operands, true, NULL); | |
701 case 8: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
702 if (TARGET_VFP_SINGLE) |
111 | 703 return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\"; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
704 else |
111 | 705 return \"vmov%?.f64\\t%P0, %P1\"; |
0 | 706 default: |
707 abort (); | |
708 } | |
709 } | |
710 " | |
111 | 711 [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,\ |
712 f_stored,load_8,store_8,ffarithd,multiple") | |
713 (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8) | |
714 (eq_attr "alternative" "8") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
715 (if_then_else |
111 | 716 (match_test "TARGET_VFP_SINGLE") |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
717 (const_int 8) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
718 (const_int 4))] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
719 (const_int 4))) |
111 | 720 (set_attr "pool_range" "*,*,*,*,1018,*,4094,*,*,*") |
721 (set_attr "neg_pool_range" "*,*,*,*,1008,*,0,*,*,*") | |
722 (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")] | |
0 | 723 ) |
724 | |
725 | |
726 ;; Conditional move patterns | |
727 | |
728 (define_insn "*movsfcc_vfp" | |
729 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r") | |
730 (if_then_else:SF | |
731 (match_operator 3 "arm_comparison_operator" | |
732 [(match_operand 4 "cc_register" "") (const_int 0)]) | |
733 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") | |
734 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] | |
111 | 735 "TARGET_ARM && TARGET_HARD_FLOAT" |
0 | 736 "@ |
111 | 737 vmov%D3.f32\\t%0, %2 |
738 vmov%d3.f32\\t%0, %1 | |
739 vmov%D3.f32\\t%0, %2\;vmov%d3.f32\\t%0, %1 | |
740 vmov%D3\\t%0, %2 | |
741 vmov%d3\\t%0, %1 | |
742 vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1 | |
743 vmov%D3\\t%0, %2 | |
744 vmov%d3\\t%0, %1 | |
745 vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1" | |
0 | 746 [(set_attr "conds" "use") |
747 (set_attr "length" "4,4,8,4,4,8,4,4,8") | |
111 | 748 (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")] |
0 | 749 ) |
750 | |
751 (define_insn "*thumb2_movsfcc_vfp" | |
752 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r") | |
753 (if_then_else:SF | |
754 (match_operator 3 "arm_comparison_operator" | |
755 [(match_operand 4 "cc_register" "") (const_int 0)]) | |
756 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") | |
757 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] | |
111 | 758 "TARGET_THUMB2 && TARGET_HARD_FLOAT && !arm_restrict_it" |
0 | 759 "@ |
111 | 760 it\\t%D3\;vmov%D3.f32\\t%0, %2 |
761 it\\t%d3\;vmov%d3.f32\\t%0, %1 | |
762 ite\\t%D3\;vmov%D3.f32\\t%0, %2\;vmov%d3.f32\\t%0, %1 | |
763 it\\t%D3\;vmov%D3\\t%0, %2 | |
764 it\\t%d3\;vmov%d3\\t%0, %1 | |
765 ite\\t%D3\;vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1 | |
766 it\\t%D3\;vmov%D3\\t%0, %2 | |
767 it\\t%d3\;vmov%d3\\t%0, %1 | |
768 ite\\t%D3\;vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1" | |
0 | 769 [(set_attr "conds" "use") |
770 (set_attr "length" "6,6,10,6,6,10,6,6,10") | |
111 | 771 (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")] |
0 | 772 ) |
773 | |
774 (define_insn "*movdfcc_vfp" | |
775 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r") | |
776 (if_then_else:DF | |
777 (match_operator 3 "arm_comparison_operator" | |
778 [(match_operand 4 "cc_register" "") (const_int 0)]) | |
779 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") | |
780 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
781 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 782 "@ |
111 | 783 vmov%D3.f64\\t%P0, %P2 |
784 vmov%d3.f64\\t%P0, %P1 | |
785 vmov%D3.f64\\t%P0, %P2\;vmov%d3.f64\\t%P0, %P1 | |
786 vmov%D3\\t%P0, %Q2, %R2 | |
787 vmov%d3\\t%P0, %Q1, %R1 | |
788 vmov%D3\\t%P0, %Q2, %R2\;vmov%d3\\t%P0, %Q1, %R1 | |
789 vmov%D3\\t%Q0, %R0, %P2 | |
790 vmov%d3\\t%Q0, %R0, %P1 | |
791 vmov%D3\\t%Q0, %R0, %P2\;vmov%d3\\t%Q0, %R0, %P1" | |
0 | 792 [(set_attr "conds" "use") |
793 (set_attr "length" "4,4,8,4,4,8,4,4,8") | |
111 | 794 (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcr,f_mrrc,f_mrrc,f_mrrc")] |
0 | 795 ) |
796 | |
797 (define_insn "*thumb2_movdfcc_vfp" | |
798 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r") | |
799 (if_then_else:DF | |
800 (match_operator 3 "arm_comparison_operator" | |
801 [(match_operand 4 "cc_register" "") (const_int 0)]) | |
802 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") | |
803 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] | |
111 | 804 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && !arm_restrict_it" |
0 | 805 "@ |
111 | 806 it\\t%D3\;vmov%D3.f64\\t%P0, %P2 |
807 it\\t%d3\;vmov%d3.f64\\t%P0, %P1 | |
808 ite\\t%D3\;vmov%D3.f64\\t%P0, %P2\;vmov%d3.f64\\t%P0, %P1 | |
809 it\t%D3\;vmov%D3\\t%P0, %Q2, %R2 | |
810 it\t%d3\;vmov%d3\\t%P0, %Q1, %R1 | |
811 ite\\t%D3\;vmov%D3\\t%P0, %Q2, %R2\;vmov%d3\\t%P0, %Q1, %R1 | |
812 it\t%D3\;vmov%D3\\t%Q0, %R0, %P2 | |
813 it\t%d3\;vmov%d3\\t%Q0, %R0, %P1 | |
814 ite\\t%D3\;vmov%D3\\t%Q0, %R0, %P2\;vmov%d3\\t%Q0, %R0, %P1" | |
0 | 815 [(set_attr "conds" "use") |
816 (set_attr "length" "6,6,10,6,6,10,6,6,10") | |
111 | 817 (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcrr,f_mrrc,f_mrrc,f_mrrc")] |
0 | 818 ) |
819 | |
820 | |
821 ;; Sign manipulation functions | |
822 | |
823 (define_insn "*abssf2_vfp" | |
824 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
825 (abs:SF (match_operand:SF 1 "s_register_operand" "t")))] | |
111 | 826 "TARGET_32BIT && TARGET_HARD_FLOAT" |
827 "vabs%?.f32\\t%0, %1" | |
0 | 828 [(set_attr "predicable" "yes") |
829 (set_attr "type" "ffariths")] | |
830 ) | |
831 | |
832 (define_insn "*absdf2_vfp" | |
833 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
834 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
835 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 836 "vabs%?.f64\\t%P0, %P1" |
0 | 837 [(set_attr "predicable" "yes") |
838 (set_attr "type" "ffarithd")] | |
839 ) | |
840 | |
841 (define_insn "*negsf2_vfp" | |
842 [(set (match_operand:SF 0 "s_register_operand" "=t,?r") | |
843 (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))] | |
111 | 844 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 845 "@ |
111 | 846 vneg%?.f32\\t%0, %1 |
0 | 847 eor%?\\t%0, %1, #-2147483648" |
848 [(set_attr "predicable" "yes") | |
849 (set_attr "type" "ffariths")] | |
850 ) | |
851 | |
852 (define_insn_and_split "*negdf2_vfp" | |
853 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r") | |
854 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
855 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 856 "@ |
111 | 857 vneg%?.f64\\t%P0, %P1 |
0 | 858 # |
859 #" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
860 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed |
0 | 861 && arm_general_register_operand (operands[0], DFmode)" |
862 [(set (match_dup 0) (match_dup 1))] | |
863 " | |
864 if (REGNO (operands[0]) == REGNO (operands[1])) | |
865 { | |
866 operands[0] = gen_highpart (SImode, operands[0]); | |
867 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000)); | |
868 } | |
869 else | |
870 { | |
871 rtx in_hi, in_lo, out_hi, out_lo; | |
872 | |
873 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]), | |
874 GEN_INT (0x80000000)); | |
875 in_lo = gen_lowpart (SImode, operands[1]); | |
876 out_hi = gen_highpart (SImode, operands[0]); | |
877 out_lo = gen_lowpart (SImode, operands[0]); | |
878 | |
879 if (REGNO (in_lo) == REGNO (out_hi)) | |
880 { | |
111 | 881 emit_insn (gen_rtx_SET (out_lo, in_lo)); |
0 | 882 operands[0] = out_hi; |
883 operands[1] = in_hi; | |
884 } | |
885 else | |
886 { | |
111 | 887 emit_insn (gen_rtx_SET (out_hi, in_hi)); |
0 | 888 operands[0] = out_lo; |
889 operands[1] = in_lo; | |
890 } | |
891 } | |
892 " | |
893 [(set_attr "predicable" "yes") | |
894 (set_attr "length" "4,4,8") | |
895 (set_attr "type" "ffarithd")] | |
896 ) | |
897 | |
111 | 898 ;; ABS and NEG for FP16. |
899 (define_insn "<absneg_str>hf2" | |
900 [(set (match_operand:HF 0 "s_register_operand" "=w") | |
901 (ABSNEG:HF (match_operand:HF 1 "s_register_operand" "w")))] | |
902 "TARGET_VFP_FP16INST" | |
903 "v<absneg_str>.f16\t%0, %1" | |
904 [(set_attr "conds" "unconditional") | |
905 (set_attr "type" "ffariths")] | |
906 ) | |
907 | |
908 (define_expand "neon_vabshf" | |
909 [(set | |
910 (match_operand:HF 0 "s_register_operand") | |
911 (abs:HF (match_operand:HF 1 "s_register_operand")))] | |
912 "TARGET_VFP_FP16INST" | |
913 { | |
914 emit_insn (gen_abshf2 (operands[0], operands[1])); | |
915 DONE; | |
916 }) | |
917 | |
918 ;; VRND for FP16. | |
919 (define_insn "neon_v<fp16_rnd_str>hf" | |
920 [(set (match_operand:HF 0 "s_register_operand" "=w") | |
921 (unspec:HF | |
922 [(match_operand:HF 1 "s_register_operand" "w")] | |
923 FP16_RND))] | |
924 "TARGET_VFP_FP16INST" | |
925 "<fp16_rnd_insn>.f16\t%0, %1" | |
926 [(set_attr "conds" "unconditional") | |
927 (set_attr "type" "neon_fp_round_s")] | |
928 ) | |
929 | |
930 (define_insn "neon_vrndihf" | |
931 [(set (match_operand:HF 0 "s_register_operand" "=w") | |
932 (unspec:HF | |
933 [(match_operand:HF 1 "s_register_operand" "w")] | |
934 UNSPEC_VRNDI))] | |
935 "TARGET_VFP_FP16INST" | |
936 "vrintr.f16\t%0, %1" | |
937 [(set_attr "conds" "unconditional") | |
938 (set_attr "type" "neon_fp_round_s")] | |
939 ) | |
0 | 940 |
941 ;; Arithmetic insns | |
942 | |
111 | 943 (define_insn "addhf3" |
944 [(set | |
945 (match_operand:HF 0 "s_register_operand" "=w") | |
946 (plus:HF | |
947 (match_operand:HF 1 "s_register_operand" "w") | |
948 (match_operand:HF 2 "s_register_operand" "w")))] | |
949 "TARGET_VFP_FP16INST" | |
950 "vadd.f16\t%0, %1, %2" | |
951 [(set_attr "conds" "unconditional") | |
952 (set_attr "type" "fadds")] | |
953 ) | |
954 | |
0 | 955 (define_insn "*addsf3_vfp" |
956 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
957 (plus:SF (match_operand:SF 1 "s_register_operand" "t") | |
958 (match_operand:SF 2 "s_register_operand" "t")))] | |
111 | 959 "TARGET_32BIT && TARGET_HARD_FLOAT" |
960 "vadd%?.f32\\t%0, %1, %2" | |
0 | 961 [(set_attr "predicable" "yes") |
962 (set_attr "type" "fadds")] | |
963 ) | |
964 | |
965 (define_insn "*adddf3_vfp" | |
966 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
967 (plus:DF (match_operand:DF 1 "s_register_operand" "w") | |
968 (match_operand:DF 2 "s_register_operand" "w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
969 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 970 "vadd%?.f64\\t%P0, %P1, %P2" |
0 | 971 [(set_attr "predicable" "yes") |
972 (set_attr "type" "faddd")] | |
973 ) | |
974 | |
111 | 975 (define_insn "subhf3" |
976 [(set | |
977 (match_operand:HF 0 "s_register_operand" "=w") | |
978 (minus:HF | |
979 (match_operand:HF 1 "s_register_operand" "w") | |
980 (match_operand:HF 2 "s_register_operand" "w")))] | |
981 "TARGET_VFP_FP16INST" | |
982 "vsub.f16\t%0, %1, %2" | |
983 [(set_attr "conds" "unconditional") | |
984 (set_attr "type" "fadds")] | |
985 ) | |
0 | 986 |
987 (define_insn "*subsf3_vfp" | |
988 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
989 (minus:SF (match_operand:SF 1 "s_register_operand" "t") | |
990 (match_operand:SF 2 "s_register_operand" "t")))] | |
111 | 991 "TARGET_32BIT && TARGET_HARD_FLOAT" |
992 "vsub%?.f32\\t%0, %1, %2" | |
0 | 993 [(set_attr "predicable" "yes") |
994 (set_attr "type" "fadds")] | |
995 ) | |
996 | |
997 (define_insn "*subdf3_vfp" | |
998 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
999 (minus:DF (match_operand:DF 1 "s_register_operand" "w") | |
1000 (match_operand:DF 2 "s_register_operand" "w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1001 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1002 "vsub%?.f64\\t%P0, %P1, %P2" |
0 | 1003 [(set_attr "predicable" "yes") |
1004 (set_attr "type" "faddd")] | |
1005 ) | |
1006 | |
1007 | |
1008 ;; Division insns | |
1009 | |
111 | 1010 ;; FP16 Division. |
1011 (define_insn "divhf3" | |
1012 [(set | |
1013 (match_operand:HF 0 "s_register_operand" "=w") | |
1014 (div:HF | |
1015 (match_operand:HF 1 "s_register_operand" "w") | |
1016 (match_operand:HF 2 "s_register_operand" "w")))] | |
1017 "TARGET_VFP_FP16INST" | |
1018 "vdiv.f16\t%0, %1, %2" | |
1019 [(set_attr "conds" "unconditional") | |
1020 (set_attr "type" "fdivs")] | |
1021 ) | |
1022 | |
1023 ; VFP9 Erratum 760019: It's potentially unsafe to overwrite the input | |
1024 ; operands, so mark the output as early clobber for VFPv2 on ARMv5 or | |
1025 ; earlier. | |
0 | 1026 (define_insn "*divsf3_vfp" |
111 | 1027 [(set (match_operand:SF 0 "s_register_operand" "=&t,t") |
1028 (div:SF (match_operand:SF 1 "s_register_operand" "t,t") | |
1029 (match_operand:SF 2 "s_register_operand" "t,t")))] | |
1030 "TARGET_32BIT && TARGET_HARD_FLOAT" | |
1031 "vdiv%?.f32\\t%0, %1, %2" | |
0 | 1032 [(set_attr "predicable" "yes") |
111 | 1033 (set_attr "arch" "*,armv6_or_vfpv3") |
0 | 1034 (set_attr "type" "fdivs")] |
1035 ) | |
1036 | |
1037 (define_insn "*divdf3_vfp" | |
111 | 1038 [(set (match_operand:DF 0 "s_register_operand" "=&w,w") |
1039 (div:DF (match_operand:DF 1 "s_register_operand" "w,w") | |
1040 (match_operand:DF 2 "s_register_operand" "w,w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1041 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1042 "vdiv%?.f64\\t%P0, %P1, %P2" |
0 | 1043 [(set_attr "predicable" "yes") |
111 | 1044 (set_attr "arch" "*,armv6_or_vfpv3") |
0 | 1045 (set_attr "type" "fdivd")] |
1046 ) | |
1047 | |
1048 | |
1049 ;; Multiplication insns | |
1050 | |
111 | 1051 (define_insn "mulhf3" |
1052 [(set | |
1053 (match_operand:HF 0 "s_register_operand" "=w") | |
1054 (mult:HF (match_operand:HF 1 "s_register_operand" "w") | |
1055 (match_operand:HF 2 "s_register_operand" "w")))] | |
1056 "TARGET_VFP_FP16INST" | |
1057 "vmul.f16\t%0, %1, %2" | |
1058 [(set_attr "conds" "unconditional") | |
1059 (set_attr "type" "fmuls")] | |
1060 ) | |
1061 | |
0 | 1062 (define_insn "*mulsf3_vfp" |
111 | 1063 [(set (match_operand:SF 0 "s_register_operand" "=t") |
0 | 1064 (mult:SF (match_operand:SF 1 "s_register_operand" "t") |
1065 (match_operand:SF 2 "s_register_operand" "t")))] | |
111 | 1066 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1067 "vmul%?.f32\\t%0, %1, %2" | |
0 | 1068 [(set_attr "predicable" "yes") |
1069 (set_attr "type" "fmuls")] | |
1070 ) | |
1071 | |
1072 (define_insn "*muldf3_vfp" | |
111 | 1073 [(set (match_operand:DF 0 "s_register_operand" "=w") |
0 | 1074 (mult:DF (match_operand:DF 1 "s_register_operand" "w") |
1075 (match_operand:DF 2 "s_register_operand" "w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1076 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1077 "vmul%?.f64\\t%P0, %P1, %P2" |
0 | 1078 [(set_attr "predicable" "yes") |
1079 (set_attr "type" "fmuld")] | |
1080 ) | |
1081 | |
111 | 1082 (define_insn "*mulsf3neghf_vfp" |
1083 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1084 (mult:HF (neg:HF (match_operand:HF 1 "s_register_operand" "t")) | |
1085 (match_operand:HF 2 "s_register_operand" "t")))] | |
1086 "TARGET_VFP_FP16INST && !flag_rounding_math" | |
1087 "vnmul.f16\\t%0, %1, %2" | |
1088 [(set_attr "conds" "unconditional") | |
1089 (set_attr "type" "fmuls")] | |
1090 ) | |
1091 | |
1092 (define_insn "*negmulhf3_vfp" | |
1093 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1094 (neg:HF (mult:HF (match_operand:HF 1 "s_register_operand" "t") | |
1095 (match_operand:HF 2 "s_register_operand" "t"))))] | |
1096 "TARGET_VFP_FP16INST" | |
1097 "vnmul.f16\\t%0, %1, %2" | |
1098 [(set_attr "conds" "unconditional") | |
1099 (set_attr "type" "fmuls")] | |
1100 ) | |
0 | 1101 |
1102 (define_insn "*mulsf3negsf_vfp" | |
111 | 1103 [(set (match_operand:SF 0 "s_register_operand" "=t") |
0 | 1104 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t")) |
1105 (match_operand:SF 2 "s_register_operand" "t")))] | |
111 | 1106 "TARGET_32BIT && TARGET_HARD_FLOAT && !flag_rounding_math" |
1107 "vnmul%?.f32\\t%0, %1, %2" | |
0 | 1108 [(set_attr "predicable" "yes") |
111 | 1109 (set_attr "type" "fmuls")] |
1110 ) | |
1111 | |
1112 (define_insn "*negmulsf3_vfp" | |
1113 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1114 (neg:SF (mult:SF (match_operand:SF 1 "s_register_operand" "t") | |
1115 (match_operand:SF 2 "s_register_operand" "t"))))] | |
1116 "TARGET_32BIT && TARGET_HARD_FLOAT" | |
1117 "vnmul%?.f32\\t%0, %1, %2" | |
1118 [(set_attr "predicable" "yes") | |
0 | 1119 (set_attr "type" "fmuls")] |
1120 ) | |
1121 | |
1122 (define_insn "*muldf3negdf_vfp" | |
111 | 1123 [(set (match_operand:DF 0 "s_register_operand" "=w") |
0 | 1124 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w")) |
1125 (match_operand:DF 2 "s_register_operand" "w")))] | |
111 | 1126 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE |
1127 && !flag_rounding_math" | |
1128 "vnmul%?.f64\\t%P0, %P1, %P2" | |
1129 [(set_attr "predicable" "yes") | |
1130 (set_attr "type" "fmuld")] | |
1131 ) | |
1132 | |
1133 (define_insn "*negmuldf3_vfp" | |
1134 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1135 (neg:DF (mult:DF (match_operand:DF 1 "s_register_operand" "w") | |
1136 (match_operand:DF 2 "s_register_operand" "w"))))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1137 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1138 "vnmul%?.f64\\t%P0, %P1, %P2" |
0 | 1139 [(set_attr "predicable" "yes") |
1140 (set_attr "type" "fmuld")] | |
1141 ) | |
1142 | |
1143 | |
1144 ;; Multiply-accumulate insns | |
1145 | |
1146 ;; 0 = 1 * 2 + 0 | |
111 | 1147 (define_insn "*mulsf3addhf_vfp" |
1148 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1149 (plus:HF | |
1150 (mult:HF (match_operand:HF 2 "s_register_operand" "t") | |
1151 (match_operand:HF 3 "s_register_operand" "t")) | |
1152 (match_operand:HF 1 "s_register_operand" "0")))] | |
1153 "TARGET_VFP_FP16INST" | |
1154 "vmla.f16\\t%0, %2, %3" | |
1155 [(set_attr "conds" "unconditional") | |
1156 (set_attr "type" "fmacs")] | |
1157 ) | |
1158 | |
0 | 1159 (define_insn "*mulsf3addsf_vfp" |
1160 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1161 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
1162 (match_operand:SF 3 "s_register_operand" "t")) | |
1163 (match_operand:SF 1 "s_register_operand" "0")))] | |
111 | 1164 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1165 "vmla%?.f32\\t%0, %2, %3" | |
0 | 1166 [(set_attr "predicable" "yes") |
1167 (set_attr "type" "fmacs")] | |
1168 ) | |
1169 | |
1170 (define_insn "*muldf3adddf_vfp" | |
1171 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1172 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
1173 (match_operand:DF 3 "s_register_operand" "w")) | |
1174 (match_operand:DF 1 "s_register_operand" "0")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1175 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1176 "vmla%?.f64\\t%P0, %P2, %P3" |
0 | 1177 [(set_attr "predicable" "yes") |
1178 (set_attr "type" "fmacd")] | |
1179 ) | |
1180 | |
1181 ;; 0 = 1 * 2 - 0 | |
111 | 1182 (define_insn "*mulhf3subhf_vfp" |
1183 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1184 (minus:HF (mult:HF (match_operand:HF 2 "s_register_operand" "t") | |
1185 (match_operand:HF 3 "s_register_operand" "t")) | |
1186 (match_operand:HF 1 "s_register_operand" "0")))] | |
1187 "TARGET_VFP_FP16INST" | |
1188 "vnmls.f16\\t%0, %2, %3" | |
1189 [(set_attr "conds" "unconditional") | |
1190 (set_attr "type" "fmacs")] | |
1191 ) | |
1192 | |
0 | 1193 (define_insn "*mulsf3subsf_vfp" |
1194 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1195 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
1196 (match_operand:SF 3 "s_register_operand" "t")) | |
1197 (match_operand:SF 1 "s_register_operand" "0")))] | |
111 | 1198 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1199 "vnmls%?.f32\\t%0, %2, %3" | |
0 | 1200 [(set_attr "predicable" "yes") |
1201 (set_attr "type" "fmacs")] | |
1202 ) | |
1203 | |
1204 (define_insn "*muldf3subdf_vfp" | |
1205 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1206 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
1207 (match_operand:DF 3 "s_register_operand" "w")) | |
1208 (match_operand:DF 1 "s_register_operand" "0")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1209 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1210 "vnmls%?.f64\\t%P0, %P2, %P3" |
0 | 1211 [(set_attr "predicable" "yes") |
1212 (set_attr "type" "fmacd")] | |
1213 ) | |
1214 | |
1215 ;; 0 = -(1 * 2) + 0 | |
111 | 1216 (define_insn "*mulhf3neghfaddhf_vfp" |
1217 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1218 (minus:HF (match_operand:HF 1 "s_register_operand" "0") | |
1219 (mult:HF (match_operand:HF 2 "s_register_operand" "t") | |
1220 (match_operand:HF 3 "s_register_operand" "t"))))] | |
1221 "TARGET_VFP_FP16INST" | |
1222 "vmls.f16\\t%0, %2, %3" | |
1223 [(set_attr "conds" "unconditional") | |
1224 (set_attr "type" "fmacs")] | |
1225 ) | |
1226 | |
0 | 1227 (define_insn "*mulsf3negsfaddsf_vfp" |
1228 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1229 (minus:SF (match_operand:SF 1 "s_register_operand" "0") | |
1230 (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
1231 (match_operand:SF 3 "s_register_operand" "t"))))] | |
111 | 1232 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1233 "vmls%?.f32\\t%0, %2, %3" | |
0 | 1234 [(set_attr "predicable" "yes") |
1235 (set_attr "type" "fmacs")] | |
1236 ) | |
1237 | |
1238 (define_insn "*fmuldf3negdfadddf_vfp" | |
1239 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1240 (minus:DF (match_operand:DF 1 "s_register_operand" "0") | |
1241 (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
1242 (match_operand:DF 3 "s_register_operand" "w"))))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1243 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1244 "vmls%?.f64\\t%P0, %P2, %P3" |
0 | 1245 [(set_attr "predicable" "yes") |
1246 (set_attr "type" "fmacd")] | |
1247 ) | |
1248 | |
1249 | |
1250 ;; 0 = -(1 * 2) - 0 | |
111 | 1251 (define_insn "*mulhf3neghfsubhf_vfp" |
1252 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1253 (minus:HF (mult:HF | |
1254 (neg:HF (match_operand:HF 2 "s_register_operand" "t")) | |
1255 (match_operand:HF 3 "s_register_operand" "t")) | |
1256 (match_operand:HF 1 "s_register_operand" "0")))] | |
1257 "TARGET_VFP_FP16INST" | |
1258 "vnmla.f16\\t%0, %2, %3" | |
1259 [(set_attr "conds" "unconditional") | |
1260 (set_attr "type" "fmacs")] | |
1261 ) | |
1262 | |
0 | 1263 (define_insn "*mulsf3negsfsubsf_vfp" |
1264 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1265 (minus:SF (mult:SF | |
1266 (neg:SF (match_operand:SF 2 "s_register_operand" "t")) | |
1267 (match_operand:SF 3 "s_register_operand" "t")) | |
1268 (match_operand:SF 1 "s_register_operand" "0")))] | |
111 | 1269 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1270 "vnmla%?.f32\\t%0, %2, %3" | |
0 | 1271 [(set_attr "predicable" "yes") |
1272 (set_attr "type" "fmacs")] | |
1273 ) | |
1274 | |
1275 (define_insn "*muldf3negdfsubdf_vfp" | |
1276 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1277 (minus:DF (mult:DF | |
1278 (neg:DF (match_operand:DF 2 "s_register_operand" "w")) | |
1279 (match_operand:DF 3 "s_register_operand" "w")) | |
1280 (match_operand:DF 1 "s_register_operand" "0")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1281 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1282 "vnmla%?.f64\\t%P0, %P2, %P3" |
1283 [(set_attr "predicable" "yes") | |
1284 (set_attr "type" "fmacd")] | |
1285 ) | |
1286 | |
1287 ;; Fused-multiply-accumulate | |
1288 | |
1289 (define_insn "fmahf4" | |
1290 [(set (match_operand:HF 0 "register_operand" "=w") | |
1291 (fma:HF | |
1292 (match_operand:HF 1 "register_operand" "w") | |
1293 (match_operand:HF 2 "register_operand" "w") | |
1294 (match_operand:HF 3 "register_operand" "0")))] | |
1295 "TARGET_VFP_FP16INST" | |
1296 "vfma.f16\\t%0, %1, %2" | |
1297 [(set_attr "conds" "unconditional") | |
1298 (set_attr "type" "ffmas")] | |
1299 ) | |
1300 | |
1301 (define_expand "neon_vfmahf" | |
1302 [(match_operand:HF 0 "s_register_operand") | |
1303 (match_operand:HF 1 "s_register_operand") | |
1304 (match_operand:HF 2 "s_register_operand") | |
1305 (match_operand:HF 3 "s_register_operand")] | |
1306 "TARGET_VFP_FP16INST" | |
1307 { | |
1308 emit_insn (gen_fmahf4 (operands[0], operands[2], operands[3], | |
1309 operands[1])); | |
1310 DONE; | |
1311 }) | |
1312 | |
1313 (define_insn "fma<SDF:mode>4" | |
1314 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1315 (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1316 (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
1317 (match_operand:SDF 3 "register_operand" "0")))] | |
1318 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
1319 "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
0 | 1320 [(set_attr "predicable" "yes") |
111 | 1321 (set_attr "type" "ffma<vfp_type>")] |
1322 ) | |
1323 | |
1324 (define_insn "fmsubhf4_fp16" | |
1325 [(set (match_operand:HF 0 "register_operand" "=w") | |
1326 (fma:HF | |
1327 (neg:HF (match_operand:HF 1 "register_operand" "w")) | |
1328 (match_operand:HF 2 "register_operand" "w") | |
1329 (match_operand:HF 3 "register_operand" "0")))] | |
1330 "TARGET_VFP_FP16INST" | |
1331 "vfms.f16\\t%0, %1, %2" | |
1332 [(set_attr "conds" "unconditional") | |
1333 (set_attr "type" "ffmas")] | |
1334 ) | |
1335 | |
1336 (define_expand "neon_vfmshf" | |
1337 [(match_operand:HF 0 "s_register_operand") | |
1338 (match_operand:HF 1 "s_register_operand") | |
1339 (match_operand:HF 2 "s_register_operand") | |
1340 (match_operand:HF 3 "s_register_operand")] | |
1341 "TARGET_VFP_FP16INST" | |
1342 { | |
1343 emit_insn (gen_fmsubhf4_fp16 (operands[0], operands[2], operands[3], | |
1344 operands[1])); | |
1345 DONE; | |
1346 }) | |
1347 | |
1348 (define_insn "*fmsub<SDF:mode>4" | |
1349 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1350 (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" | |
1351 "<F_constraint>")) | |
1352 (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
1353 (match_operand:SDF 3 "register_operand" "0")))] | |
1354 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
1355 "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1356 [(set_attr "predicable" "yes") | |
1357 (set_attr "type" "ffma<vfp_type>")] | |
1358 ) | |
1359 | |
1360 (define_insn "*fnmsubhf4" | |
1361 [(set (match_operand:HF 0 "register_operand" "=w") | |
1362 (fma:HF (match_operand:HF 1 "register_operand" "w") | |
1363 (match_operand:HF 2 "register_operand" "w") | |
1364 (neg:HF (match_operand:HF 3 "register_operand" "0"))))] | |
1365 "TARGET_VFP_FP16INST" | |
1366 "vfnms.f16\\t%0, %1, %2" | |
1367 [(set_attr "conds" "unconditional") | |
1368 (set_attr "type" "ffmas")] | |
1369 ) | |
1370 | |
1371 (define_insn "*fnmsub<SDF:mode>4" | |
1372 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1373 (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1374 (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
1375 (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] | |
1376 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
1377 "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1378 [(set_attr "predicable" "yes") | |
1379 (set_attr "type" "ffma<vfp_type>")] | |
1380 ) | |
1381 | |
1382 (define_insn "*fnmaddhf4" | |
1383 [(set (match_operand:HF 0 "register_operand" "=w") | |
1384 (fma:HF (neg:HF (match_operand:HF 1 "register_operand" "w")) | |
1385 (match_operand:HF 2 "register_operand" "w") | |
1386 (neg:HF (match_operand:HF 3 "register_operand" "0"))))] | |
1387 "TARGET_VFP_FP16INST" | |
1388 "vfnma.f16\\t%0, %1, %2" | |
1389 [(set_attr "conds" "unconditional") | |
1390 (set_attr "type" "ffmas")] | |
1391 ) | |
1392 | |
1393 (define_insn "*fnmadd<SDF:mode>4" | |
1394 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1395 (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" | |
1396 "<F_constraint>")) | |
1397 (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
1398 (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] | |
1399 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
1400 "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1401 [(set_attr "predicable" "yes") | |
1402 (set_attr "type" "ffma<vfp_type>")] | |
0 | 1403 ) |
1404 | |
1405 | |
1406 ;; Conversion routines | |
1407 | |
1408 (define_insn "*extendsfdf2_vfp" | |
1409 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1410 (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1411 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1412 "vcvt%?.f64.f32\\t%P0, %1" |
0 | 1413 [(set_attr "predicable" "yes") |
1414 (set_attr "type" "f_cvt")] | |
1415 ) | |
1416 | |
1417 (define_insn "*truncdfsf2_vfp" | |
1418 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1419 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1420 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1421 "vcvt%?.f32.f64\\t%0, %P1" |
0 | 1422 [(set_attr "predicable" "yes") |
1423 (set_attr "type" "f_cvt")] | |
1424 ) | |
1425 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1426 (define_insn "extendhfsf2" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1427 [(set (match_operand:SF 0 "s_register_operand" "=t") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1428 (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))] |
111 | 1429 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FP16 || TARGET_VFP_FP16INST)" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1430 "vcvtb%?.f32.f16\\t%0, %1" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1431 [(set_attr "predicable" "yes") |
111 | 1432 (set_attr "type" "f_cvt")] |
1433 ) | |
1434 | |
1435 (define_insn "*truncdfhf2" | |
1436 [(set (match_operand:HF 0 "s_register_operand" "=t") | |
1437 (float_truncate:HF (match_operand:DF 1 "s_register_operand" "w")))] | |
1438 "TARGET_32BIT && TARGET_FP16_TO_DOUBLE" | |
1439 "vcvtb%?.f16.f64\\t%0, %P1" | |
1440 [(set_attr "predicable" "yes") | |
1441 (set_attr "type" "f_cvt")] | |
1442 ) | |
1443 | |
1444 (define_insn "*extendhfdf2" | |
1445 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1446 (float_extend:DF (match_operand:HF 1 "s_register_operand" "t")))] | |
1447 "TARGET_32BIT && TARGET_FP16_TO_DOUBLE" | |
1448 "vcvtb%?.f64.f16\\t%P0, %1" | |
1449 [(set_attr "predicable" "yes") | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1450 (set_attr "type" "f_cvt")] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1451 ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1452 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1453 (define_insn "truncsfhf2" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1454 [(set (match_operand:HF 0 "s_register_operand" "=t") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1455 (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))] |
111 | 1456 "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FP16 || TARGET_VFP_FP16INST)" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1457 "vcvtb%?.f16.f32\\t%0, %1" |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1458 [(set_attr "predicable" "yes") |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1459 (set_attr "type" "f_cvt")] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1460 ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1461 |
0 | 1462 (define_insn "*truncsisf2_vfp" |
1463 [(set (match_operand:SI 0 "s_register_operand" "=t") | |
1464 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))] | |
111 | 1465 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1466 "vcvt%?.s32.f32\\t%0, %1" | |
0 | 1467 [(set_attr "predicable" "yes") |
111 | 1468 (set_attr "type" "f_cvtf2i")] |
0 | 1469 ) |
1470 | |
1471 (define_insn "*truncsidf2_vfp" | |
1472 [(set (match_operand:SI 0 "s_register_operand" "=t") | |
1473 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1474 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1475 "vcvt%?.s32.f64\\t%0, %P1" |
0 | 1476 [(set_attr "predicable" "yes") |
111 | 1477 (set_attr "type" "f_cvtf2i")] |
0 | 1478 ) |
1479 | |
1480 | |
1481 (define_insn "fixuns_truncsfsi2" | |
1482 [(set (match_operand:SI 0 "s_register_operand" "=t") | |
1483 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))] | |
111 | 1484 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1485 "vcvt%?.u32.f32\\t%0, %1" | |
0 | 1486 [(set_attr "predicable" "yes") |
111 | 1487 (set_attr "type" "f_cvtf2i")] |
0 | 1488 ) |
1489 | |
1490 (define_insn "fixuns_truncdfsi2" | |
1491 [(set (match_operand:SI 0 "s_register_operand" "=t") | |
1492 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1493 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1494 "vcvt%?.u32.f64\\t%0, %P1" |
0 | 1495 [(set_attr "predicable" "yes") |
111 | 1496 (set_attr "type" "f_cvtf2i")] |
0 | 1497 ) |
1498 | |
1499 | |
1500 (define_insn "*floatsisf2_vfp" | |
1501 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1502 (float:SF (match_operand:SI 1 "s_register_operand" "t")))] | |
111 | 1503 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1504 "vcvt%?.f32.s32\\t%0, %1" | |
0 | 1505 [(set_attr "predicable" "yes") |
111 | 1506 (set_attr "type" "f_cvti2f")] |
0 | 1507 ) |
1508 | |
1509 (define_insn "*floatsidf2_vfp" | |
1510 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1511 (float:DF (match_operand:SI 1 "s_register_operand" "t")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1512 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1513 "vcvt%?.f64.s32\\t%P0, %1" |
0 | 1514 [(set_attr "predicable" "yes") |
111 | 1515 (set_attr "type" "f_cvti2f")] |
0 | 1516 ) |
1517 | |
1518 | |
1519 (define_insn "floatunssisf2" | |
1520 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1521 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))] | |
111 | 1522 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1523 "vcvt%?.f32.u32\\t%0, %1" | |
0 | 1524 [(set_attr "predicable" "yes") |
111 | 1525 (set_attr "type" "f_cvti2f")] |
0 | 1526 ) |
1527 | |
1528 (define_insn "floatunssidf2" | |
1529 [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1530 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1531 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1532 "vcvt%?.f64.u32\\t%P0, %1" |
0 | 1533 [(set_attr "predicable" "yes") |
111 | 1534 (set_attr "type" "f_cvti2f")] |
0 | 1535 ) |
1536 | |
1537 | |
1538 ;; Sqrt insns. | |
1539 | |
111 | 1540 (define_insn "neon_vsqrthf" |
1541 [(set (match_operand:HF 0 "s_register_operand" "=w") | |
1542 (sqrt:HF (match_operand:HF 1 "s_register_operand" "w")))] | |
1543 "TARGET_VFP_FP16INST" | |
1544 "vsqrt.f16\t%0, %1" | |
1545 [(set_attr "conds" "unconditional") | |
1546 (set_attr "type" "fsqrts")] | |
1547 ) | |
1548 | |
1549 (define_insn "neon_vrsqrtshf" | |
1550 [(set | |
1551 (match_operand:HF 0 "s_register_operand" "=w") | |
1552 (unspec:HF [(match_operand:HF 1 "s_register_operand" "w") | |
1553 (match_operand:HF 2 "s_register_operand" "w")] | |
1554 UNSPEC_VRSQRTS))] | |
1555 "TARGET_VFP_FP16INST" | |
1556 "vrsqrts.f16\t%0, %1, %2" | |
1557 [(set_attr "conds" "unconditional") | |
1558 (set_attr "type" "fsqrts")] | |
1559 ) | |
1560 | |
1561 ; VFP9 Erratum 760019: It's potentially unsafe to overwrite the input | |
1562 ; operands, so mark the output as early clobber for VFPv2 on ARMv5 or | |
1563 ; earlier. | |
0 | 1564 (define_insn "*sqrtsf2_vfp" |
111 | 1565 [(set (match_operand:SF 0 "s_register_operand" "=&t,t") |
1566 (sqrt:SF (match_operand:SF 1 "s_register_operand" "t,t")))] | |
1567 "TARGET_32BIT && TARGET_HARD_FLOAT" | |
1568 "vsqrt%?.f32\\t%0, %1" | |
0 | 1569 [(set_attr "predicable" "yes") |
111 | 1570 (set_attr "arch" "*,armv6_or_vfpv3") |
1571 (set_attr "type" "fsqrts")] | |
0 | 1572 ) |
1573 | |
1574 (define_insn "*sqrtdf2_vfp" | |
111 | 1575 [(set (match_operand:DF 0 "s_register_operand" "=&w,w") |
1576 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w,w")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1577 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
111 | 1578 "vsqrt%?.f64\\t%P0, %P1" |
0 | 1579 [(set_attr "predicable" "yes") |
111 | 1580 (set_attr "arch" "*,armv6_or_vfpv3") |
1581 (set_attr "type" "fsqrtd")] | |
0 | 1582 ) |
1583 | |
1584 | |
1585 ;; Patterns to split/copy vfp condition flags. | |
1586 | |
1587 (define_insn "*movcc_vfp" | |
1588 [(set (reg CC_REGNUM) | |
1589 (reg VFPCC_REGNUM))] | |
111 | 1590 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1591 "vmrs%?\\tAPSR_nzcv, FPSCR" | |
0 | 1592 [(set_attr "conds" "set") |
1593 (set_attr "type" "f_flag")] | |
1594 ) | |
1595 | |
1596 (define_insn_and_split "*cmpsf_split_vfp" | |
1597 [(set (reg:CCFP CC_REGNUM) | |
1598 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t") | |
1599 (match_operand:SF 1 "vfp_compare_operand" "tG")))] | |
111 | 1600 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 1601 "#" |
111 | 1602 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 1603 [(set (reg:CCFP VFPCC_REGNUM) |
1604 (compare:CCFP (match_dup 0) | |
1605 (match_dup 1))) | |
1606 (set (reg:CCFP CC_REGNUM) | |
1607 (reg:CCFP VFPCC_REGNUM))] | |
1608 "" | |
1609 ) | |
1610 | |
1611 (define_insn_and_split "*cmpsf_trap_split_vfp" | |
1612 [(set (reg:CCFPE CC_REGNUM) | |
1613 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t") | |
1614 (match_operand:SF 1 "vfp_compare_operand" "tG")))] | |
111 | 1615 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 1616 "#" |
111 | 1617 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 1618 [(set (reg:CCFPE VFPCC_REGNUM) |
1619 (compare:CCFPE (match_dup 0) | |
1620 (match_dup 1))) | |
1621 (set (reg:CCFPE CC_REGNUM) | |
1622 (reg:CCFPE VFPCC_REGNUM))] | |
1623 "" | |
1624 ) | |
1625 | |
1626 (define_insn_and_split "*cmpdf_split_vfp" | |
1627 [(set (reg:CCFP CC_REGNUM) | |
1628 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w") | |
1629 (match_operand:DF 1 "vfp_compare_operand" "wG")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1630 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 1631 "#" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1632 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 1633 [(set (reg:CCFP VFPCC_REGNUM) |
1634 (compare:CCFP (match_dup 0) | |
1635 (match_dup 1))) | |
1636 (set (reg:CCFP CC_REGNUM) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1637 (reg:CCFP VFPCC_REGNUM))] |
0 | 1638 "" |
1639 ) | |
1640 | |
1641 (define_insn_and_split "*cmpdf_trap_split_vfp" | |
1642 [(set (reg:CCFPE CC_REGNUM) | |
1643 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w") | |
1644 (match_operand:DF 1 "vfp_compare_operand" "wG")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1645 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 1646 "#" |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1647 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 1648 [(set (reg:CCFPE VFPCC_REGNUM) |
1649 (compare:CCFPE (match_dup 0) | |
1650 (match_dup 1))) | |
1651 (set (reg:CCFPE CC_REGNUM) | |
1652 (reg:CCFPE VFPCC_REGNUM))] | |
1653 "" | |
1654 ) | |
1655 | |
1656 | |
1657 ;; Comparison patterns | |
1658 | |
111 | 1659 ;; In the compare with FP zero case the ARM Architecture Reference Manual |
1660 ;; specifies the immediate to be #0.0. However, some buggy assemblers only | |
1661 ;; accept #0. We don't want to autodetect broken assemblers, so output #0. | |
0 | 1662 (define_insn "*cmpsf_vfp" |
1663 [(set (reg:CCFP VFPCC_REGNUM) | |
1664 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t") | |
1665 (match_operand:SF 1 "vfp_compare_operand" "t,G")))] | |
111 | 1666 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 1667 "@ |
111 | 1668 vcmp%?.f32\\t%0, %1 |
1669 vcmp%?.f32\\t%0, #0" | |
0 | 1670 [(set_attr "predicable" "yes") |
1671 (set_attr "type" "fcmps")] | |
1672 ) | |
1673 | |
1674 (define_insn "*cmpsf_trap_vfp" | |
1675 [(set (reg:CCFPE VFPCC_REGNUM) | |
1676 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t") | |
1677 (match_operand:SF 1 "vfp_compare_operand" "t,G")))] | |
111 | 1678 "TARGET_32BIT && TARGET_HARD_FLOAT" |
0 | 1679 "@ |
111 | 1680 vcmpe%?.f32\\t%0, %1 |
1681 vcmpe%?.f32\\t%0, #0" | |
0 | 1682 [(set_attr "predicable" "yes") |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1683 (set_attr "type" "fcmps")] |
0 | 1684 ) |
1685 | |
1686 (define_insn "*cmpdf_vfp" | |
1687 [(set (reg:CCFP VFPCC_REGNUM) | |
1688 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w") | |
1689 (match_operand:DF 1 "vfp_compare_operand" "w,G")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1690 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 1691 "@ |
111 | 1692 vcmp%?.f64\\t%P0, %P1 |
1693 vcmp%?.f64\\t%P0, #0" | |
0 | 1694 [(set_attr "predicable" "yes") |
1695 (set_attr "type" "fcmpd")] | |
1696 ) | |
1697 | |
1698 (define_insn "*cmpdf_trap_vfp" | |
1699 [(set (reg:CCFPE VFPCC_REGNUM) | |
1700 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w") | |
1701 (match_operand:DF 1 "vfp_compare_operand" "w,G")))] | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1702 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
0 | 1703 "@ |
111 | 1704 vcmpe%?.f64\\t%P0, %P1 |
1705 vcmpe%?.f64\\t%P0, #0" | |
0 | 1706 [(set_attr "predicable" "yes") |
1707 (set_attr "type" "fcmpd")] | |
1708 ) | |
1709 | |
111 | 1710 ;; Fixed point to floating point conversions. |
1711 (define_insn "*combine_vcvt_f32_<FCVTI32typename>" | |
1712 [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1713 (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0")) | |
1714 (match_operand 2 | |
1715 "const_double_vcvt_power_of_two_reciprocal" "Dt")))] | |
1716 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math" | |
1717 "vcvt%?.f32.<FCVTI32typename>\\t%0, %1, %v2" | |
1718 [(set_attr "predicable" "yes") | |
1719 (set_attr "type" "f_cvti2f")] | |
1720 ) | |
1721 | |
1722 ;; Not the ideal way of implementing this. Ideally we would be able to split | |
1723 ;; this into a move to a DP register and then a vcvt.f64.i32 | |
1724 (define_insn "*combine_vcvt_f64_<FCVTI32typename>" | |
1725 [(set (match_operand:DF 0 "s_register_operand" "=x,x,w") | |
1726 (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r")) | |
1727 (match_operand 2 | |
1728 "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))] | |
1729 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math | |
1730 && !TARGET_VFP_SINGLE" | |
1731 "@ | |
1732 vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2 | |
1733 vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2 | |
1734 vmov%?.f64\\t%P0, %1, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2" | |
1735 [(set_attr "predicable" "yes") | |
1736 (set_attr "ce_count" "2") | |
1737 (set_attr "type" "f_cvti2f") | |
1738 (set_attr "length" "8")] | |
1739 ) | |
1740 | |
1741 (define_insn "*combine_vcvtf2i" | |
1742 [(set (match_operand:SI 0 "s_register_operand" "=t") | |
1743 (fix:SI (fix:SF (mult:SF (match_operand:SF 1 "s_register_operand" "0") | |
1744 (match_operand 2 | |
1745 "const_double_vcvt_power_of_two" "Dp")))))] | |
1746 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math" | |
1747 "vcvt%?.s32.f32\\t%0, %1, %v2" | |
1748 [(set_attr "predicable" "yes") | |
1749 (set_attr "type" "f_cvtf2i")] | |
1750 ) | |
1751 | |
1752 ;; FP16 conversions. | |
1753 (define_insn "neon_vcvth<sup>hf" | |
1754 [(set (match_operand:HF 0 "s_register_operand" "=w") | |
1755 (unspec:HF | |
1756 [(match_operand:SI 1 "s_register_operand" "w")] | |
1757 VCVTH_US))] | |
1758 "TARGET_VFP_FP16INST" | |
1759 "vcvt.f16.<sup>%#32\t%0, %1" | |
1760 [(set_attr "conds" "unconditional") | |
1761 (set_attr "type" "f_cvti2f")] | |
1762 ) | |
1763 | |
1764 (define_insn "neon_vcvth<sup>si" | |
1765 [(set (match_operand:SI 0 "s_register_operand" "=w") | |
1766 (unspec:SI | |
1767 [(match_operand:HF 1 "s_register_operand" "w")] | |
1768 VCVTH_US))] | |
1769 "TARGET_VFP_FP16INST" | |
1770 "vcvt.<sup>%#32.f16\t%0, %1" | |
1771 [(set_attr "conds" "unconditional") | |
1772 (set_attr "type" "f_cvtf2i")] | |
1773 ) | |
1774 | |
1775 ;; The neon_vcvth<sup>_nhf patterns are used to generate the instruction for the | |
1776 ;; vcvth_n_f16_<sup>32 arm_fp16 intrinsics. They are complicated by the | |
1777 ;; hardware requirement that the source and destination registers are the same | |
1778 ;; despite having different machine modes. The approach is to use a temporary | |
1779 ;; register for the conversion and move that to the correct destination. | |
1780 | |
1781 ;; Generate an unspec pattern for the intrinsic. | |
1782 (define_insn "neon_vcvth<sup>_nhf_unspec" | |
1783 [(set | |
1784 (match_operand:SI 0 "s_register_operand" "=w") | |
1785 (unspec:SI | |
1786 [(match_operand:SI 1 "s_register_operand" "0") | |
1787 (match_operand:SI 2 "immediate_operand" "i")] | |
1788 VCVT_HF_US_N)) | |
1789 (set | |
1790 (match_operand:HF 3 "s_register_operand" "=w") | |
1791 (float_truncate:HF (float:SF (match_dup 0))))] | |
1792 "TARGET_VFP_FP16INST" | |
1793 { | |
1794 arm_const_bounds (operands[2], 1, 33); | |
1795 return "vcvt.f16.<sup>32\t%0, %0, %2\;vmov.f32\t%3, %0"; | |
1796 } | |
1797 [(set_attr "conds" "unconditional") | |
1798 (set_attr "type" "f_cvti2f")] | |
1799 ) | |
1800 | |
1801 ;; Generate the instruction patterns needed for vcvth_n_f16_s32 neon intrinsics. | |
1802 (define_expand "neon_vcvth<sup>_nhf" | |
1803 [(match_operand:HF 0 "s_register_operand") | |
1804 (unspec:HF [(match_operand:SI 1 "s_register_operand") | |
1805 (match_operand:SI 2 "immediate_operand")] | |
1806 VCVT_HF_US_N)] | |
1807 "TARGET_VFP_FP16INST" | |
1808 { | |
1809 rtx op1 = gen_reg_rtx (SImode); | |
1810 | |
1811 arm_const_bounds (operands[2], 1, 33); | |
1812 | |
1813 emit_move_insn (op1, operands[1]); | |
1814 emit_insn (gen_neon_vcvth<sup>_nhf_unspec (op1, op1, operands[2], | |
1815 operands[0])); | |
1816 DONE; | |
1817 }) | |
1818 | |
1819 ;; The neon_vcvth<sup>_nsi patterns are used to generate the instruction for the | |
1820 ;; vcvth_n_<sup>32_f16 arm_fp16 intrinsics. They have the same restrictions and | |
1821 ;; are implemented in the same way as the neon_vcvth<sup>_nhf patterns. | |
1822 | |
1823 ;; Generate an unspec pattern, constraining the registers. | |
1824 (define_insn "neon_vcvth<sup>_nsi_unspec" | |
1825 [(set (match_operand:SI 0 "s_register_operand" "=w") | |
1826 (unspec:SI | |
1827 [(fix:SI | |
1828 (fix:SF | |
1829 (float_extend:SF | |
1830 (match_operand:HF 1 "s_register_operand" "w")))) | |
1831 (match_operand:SI 2 "immediate_operand" "i")] | |
1832 VCVT_SI_US_N))] | |
1833 "TARGET_VFP_FP16INST" | |
1834 { | |
1835 arm_const_bounds (operands[2], 1, 33); | |
1836 return "vmov.f32\t%0, %1\;vcvt.<sup>%#32.f16\t%0, %0, %2"; | |
1837 } | |
1838 [(set_attr "conds" "unconditional") | |
1839 (set_attr "type" "f_cvtf2i")] | |
1840 ) | |
1841 | |
1842 ;; Generate the instruction patterns needed for vcvth_n_f16_s32 neon intrinsics. | |
1843 (define_expand "neon_vcvth<sup>_nsi" | |
1844 [(match_operand:SI 0 "s_register_operand") | |
1845 (unspec:SI | |
1846 [(match_operand:HF 1 "s_register_operand") | |
1847 (match_operand:SI 2 "immediate_operand")] | |
1848 VCVT_SI_US_N)] | |
1849 "TARGET_VFP_FP16INST" | |
1850 { | |
1851 rtx op1 = gen_reg_rtx (SImode); | |
1852 | |
1853 arm_const_bounds (operands[2], 1, 33); | |
1854 emit_insn (gen_neon_vcvth<sup>_nsi_unspec (op1, operands[1], operands[2])); | |
1855 emit_move_insn (operands[0], op1); | |
1856 DONE; | |
1857 }) | |
1858 | |
1859 (define_insn "neon_vcvt<vcvth_op>h<sup>si" | |
1860 [(set | |
1861 (match_operand:SI 0 "s_register_operand" "=w") | |
1862 (unspec:SI | |
1863 [(match_operand:HF 1 "s_register_operand" "w")] | |
1864 VCVT_HF_US))] | |
1865 "TARGET_VFP_FP16INST" | |
1866 "vcvt<vcvth_op>.<sup>%#32.f16\t%0, %1" | |
1867 [(set_attr "conds" "unconditional") | |
1868 (set_attr "type" "f_cvtf2i")] | |
1869 ) | |
0 | 1870 |
1871 ;; Store multiple insn used in function prologue. | |
1872 (define_insn "*push_multi_vfp" | |
1873 [(match_parallel 2 "multi_register_push" | |
1874 [(set (match_operand:BLK 0 "memory_operand" "=m") | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
1875 (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")] |
0 | 1876 UNSPEC_PUSH_MULT))])] |
111 | 1877 "TARGET_32BIT && TARGET_HARD_FLOAT" |
1878 "* return vfp_output_vstmd (operands);" | |
0 | 1879 [(set_attr "type" "f_stored")] |
1880 ) | |
1881 | |
111 | 1882 ;; VRINT round to integral instructions. |
1883 ;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2, | |
1884 ;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2, | |
1885 ;; rintsf2, rintdf2. | |
1886 (define_insn "<vrint_pattern><SDF:mode>2" | |
1887 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1888 (unspec:SDF [(match_operand:SDF 1 | |
1889 "register_operand" "<F_constraint>")] | |
1890 VRINT))] | |
1891 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" | |
1892 "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1" | |
1893 [(set_attr "predicable" "<vrint_predicable>") | |
1894 (set_attr "type" "f_rint<vfp_type>") | |
1895 (set_attr "conds" "<vrint_conds>")] | |
1896 ) | |
1897 | |
1898 ;; Implements the lround, lfloor and lceil optabs. | |
1899 (define_insn "l<vrint_pattern><su_optab><mode>si2" | |
1900 [(set (match_operand:SI 0 "register_operand" "=t") | |
1901 (FIXUORS:SI (unspec:SDF | |
1902 [(match_operand:SDF 1 | |
1903 "register_operand" "<F_constraint>")] VCVT)))] | |
1904 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" | |
1905 "vcvt<vrint_variant>.<su>32.<V_if_elem>\\t%0, %<V_reg>1" | |
131 | 1906 [(set_attr "conds" "unconditional") |
111 | 1907 (set_attr "type" "f_cvtf2i")] |
1908 ) | |
1909 | |
1910 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL. | |
1911 ;; The 'smax' and 'smin' RTL standard pattern names do not specify which | |
1912 ;; operand will be returned when both operands are zero (i.e. they may not | |
1913 ;; honour signed zeroes), or when either operand is NaN. Therefore GCC | |
1914 ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring | |
1915 ;; NaNs. | |
1916 | |
1917 (define_insn "smax<mode>3" | |
1918 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1919 (smax:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1920 (match_operand:SDF 2 "register_operand" "<F_constraint>")))] | |
1921 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" | |
1922 "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1923 [(set_attr "type" "f_minmax<vfp_type>") | |
1924 (set_attr "conds" "unconditional")] | |
1925 ) | |
1926 | |
1927 (define_insn "smin<mode>3" | |
1928 [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1929 (smin:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1930 (match_operand:SDF 2 "register_operand" "<F_constraint>")))] | |
1931 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" | |
1932 "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1933 [(set_attr "type" "f_minmax<vfp_type>") | |
1934 (set_attr "conds" "unconditional")] | |
1935 ) | |
1936 | |
1937 ;; Scalar forms for the IEEE-754 fmax()/fmin() functions | |
1938 | |
1939 (define_insn "neon_<fmaxmin_op>hf" | |
1940 [(set | |
1941 (match_operand:HF 0 "s_register_operand" "=w") | |
1942 (unspec:HF | |
1943 [(match_operand:HF 1 "s_register_operand" "w") | |
1944 (match_operand:HF 2 "s_register_operand" "w")] | |
1945 VMAXMINFNM))] | |
1946 "TARGET_VFP_FP16INST" | |
1947 "<fmaxmin_op>.f16\t%0, %1, %2" | |
1948 [(set_attr "conds" "unconditional") | |
1949 (set_attr "type" "f_minmaxs")] | |
1950 ) | |
1951 | |
1952 (define_insn "<fmaxmin><mode>3" | |
1953 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>") | |
1954 (unspec:SDF [(match_operand:SDF 1 "s_register_operand" "<F_constraint>") | |
1955 (match_operand:SDF 2 "s_register_operand" "<F_constraint>")] | |
1956 VMAXMINFNM))] | |
1957 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" | |
1958 "<fmaxmin_op>.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1959 [(set_attr "type" "f_minmax<vfp_type>") | |
1960 (set_attr "conds" "unconditional")] | |
1961 ) | |
1962 | |
1963 ;; Write Floating-point Status and Control Register. | |
1964 (define_insn "set_fpscr" | |
1965 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FPSCR)] | |
1966 "TARGET_HARD_FLOAT" | |
1967 "mcr\\tp10, 7, %0, cr1, cr0, 0\\t @SET_FPSCR" | |
1968 [(set_attr "type" "mrs")]) | |
1969 | |
1970 ;; Read Floating-point Status and Control Register. | |
1971 (define_insn "get_fpscr" | |
1972 [(set (match_operand:SI 0 "register_operand" "=r") | |
1973 (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FPSCR))] | |
1974 "TARGET_HARD_FLOAT" | |
1975 "mrc\\tp10, 7, %0, cr1, cr0, 0\\t @GET_FPSCR" | |
1976 [(set_attr "type" "mrs")]) | |
1977 | |
0 | 1978 |
1979 ;; Unimplemented insns: | |
1980 ;; fldm* | |
1981 ;; fstm* | |
1982 ;; fmdhr et al (VFPv1) | |
1983 ;; Support for xD (single precision only) variants. | |
1984 ;; fmrrs, fmsrr | |
111 | 1985 |
1986 ;; Split an immediate DF move to two immediate SI moves. | |
1987 (define_insn_and_split "no_literal_pool_df_immediate" | |
1988 [(set (match_operand:DF 0 "s_register_operand" "") | |
1989 (match_operand:DF 1 "const_double_operand" ""))] | |
1990 "TARGET_THUMB2 && arm_disable_literal_pool | |
1991 && !(TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE | |
1992 && vfp3_const_double_rtx (operands[1]))" | |
1993 "#" | |
1994 "&& !reload_completed" | |
1995 [(set (subreg:SI (match_dup 1) 0) (match_dup 2)) | |
1996 (set (subreg:SI (match_dup 1) 4) (match_dup 3)) | |
1997 (set (match_dup 0) (match_dup 1))] | |
1998 " | |
1999 long buf[2]; | |
2000 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode); | |
2001 operands[2] = GEN_INT ((int) buf[0]); | |
2002 operands[3] = GEN_INT ((int) buf[1]); | |
2003 operands[1] = gen_reg_rtx (DFmode); | |
2004 ") | |
2005 | |
2006 ;; Split an immediate SF move to one immediate SI move. | |
2007 (define_insn_and_split "no_literal_pool_sf_immediate" | |
2008 [(set (match_operand:SF 0 "s_register_operand" "") | |
2009 (match_operand:SF 1 "const_double_operand" ""))] | |
2010 "TARGET_THUMB2 && arm_disable_literal_pool | |
2011 && !(TARGET_HARD_FLOAT && vfp3_const_double_rtx (operands[1]))" | |
2012 "#" | |
2013 "&& !reload_completed" | |
2014 [(set (subreg:SI (match_dup 1) 0) (match_dup 2)) | |
2015 (set (match_dup 0) (match_dup 1))] | |
2016 " | |
2017 long buf; | |
2018 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode); | |
2019 operands[2] = GEN_INT ((int) buf); | |
2020 operands[1] = gen_reg_rtx (SFmode); | |
2021 ") |