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