]>
Commit | Line | Data |
---|---|---|
55e3ada8 | 1 | ;; ARM VFP instruction patterns |
71e45bc2 | 2 | ;; Copyright (C) 2003, 2005, 2006, 2007, 2008, 2010, 2011, 2012 |
d91f7526 | 3 | ;; Free Software Foundation, Inc. |
55e3ada8 | 4 | ;; Written by CodeSourcery. |
a2cd141b | 5 | ;; |
6 | ;; This file is part of GCC. | |
7 | ;; | |
8 | ;; GCC is free software; you can redistribute it and/or modify it | |
9 | ;; under the terms of the GNU General Public License as published by | |
038d1e19 | 10 | ;; the Free Software Foundation; either version 3, or (at your option) |
a2cd141b | 11 | ;; any later version. |
12 | ;; | |
13 | ;; GCC is distributed in the hope that it will be useful, but | |
14 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | ;; General Public License for more details. | |
17 | ;; | |
18 | ;; You should have received a copy of the GNU General Public License | |
038d1e19 | 19 | ;; along with GCC; see the file COPYING3. If not see |
20 | ;; <http://www.gnu.org/licenses/>. */ | |
a2cd141b | 21 | |
a2cd141b | 22 | ;; The VFP "type" attributes differ from those used in the FPA model. |
e3879fd0 | 23 | ;; fcpys Single precision cpy. |
24 | ;; ffariths Single precision abs, neg. | |
25 | ;; ffarithd Double precision abs, neg, cpy. | |
26 | ;; fadds Single precision add/sub. | |
27 | ;; faddd Double precision add/sub. | |
28 | ;; fconsts Single precision load immediate. | |
29 | ;; fconstd Double precision load immediate. | |
30 | ;; fcmps Single precision comparison. | |
31 | ;; fcmpd Double precision comparison. | |
607978a1 | 32 | ;; fmuls Single precision multiply. |
33 | ;; fmuld Double precision multiply. | |
34 | ;; fmacs Single precision multiply-accumulate. | |
35 | ;; fmacd Double precision multiply-accumulate. | |
a2cd141b | 36 | ;; fdivs Single precision sqrt or division. |
37 | ;; fdivd Double precision sqrt or division. | |
c0e1af52 | 38 | ;; f_flag fmstat operation |
39 | ;; f_load[sd] Floating point load from memory. | |
40 | ;; f_store[sd] Floating point store to memory. | |
a2cd141b | 41 | ;; f_2_r Transfer vfp to arm reg. |
42 | ;; r_2_f Transfer arm to vfp reg. | |
c0e1af52 | 43 | ;; f_cvt Convert floating<->integral |
a2cd141b | 44 | |
a2cd141b | 45 | ;; SImode moves |
46 | ;; ??? For now do not allow loading constants into vfp regs. This causes | |
58552ed0 | 47 | ;; problems because small constants get converted into adds. |
a2cd141b | 48 | (define_insn "*arm_movsi_vfp" |
aaa37ad6 | 49 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv") |
110eae03 | 50 | (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))] |
a2cd141b | 51 | "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT |
52 | && ( s_register_operand (operands[0], SImode) | |
53 | || s_register_operand (operands[1], SImode))" | |
25f905c2 | 54 | "* |
55 | switch (which_alternative) | |
56 | { | |
aaa37ad6 | 57 | case 0: case 1: |
25f905c2 | 58 | return \"mov%?\\t%0, %1\"; |
25f905c2 | 59 | case 2: |
aaa37ad6 | 60 | return \"mvn%?\\t%0, #%B1\"; |
25f905c2 | 61 | case 3: |
aaa37ad6 | 62 | return \"movw%?\\t%0, %1\"; |
25f905c2 | 63 | case 4: |
aaa37ad6 | 64 | return \"ldr%?\\t%0, %1\"; |
25f905c2 | 65 | case 5: |
aaa37ad6 | 66 | return \"str%?\\t%1, %0\"; |
25f905c2 | 67 | case 6: |
aaa37ad6 | 68 | return \"fmsr%?\\t%0, %1\\t%@ int\"; |
25f905c2 | 69 | case 7: |
aaa37ad6 | 70 | return \"fmrs%?\\t%0, %1\\t%@ int\"; |
71 | case 8: | |
25f905c2 | 72 | return \"fcpys%?\\t%0, %1\\t%@ int\"; |
aaa37ad6 | 73 | case 9: case 10: |
25f905c2 | 74 | return output_move_vfp (operands); |
75 | default: | |
76 | gcc_unreachable (); | |
77 | } | |
78 | " | |
79 | [(set_attr "predicable" "yes") | |
65f68e55 | 80 | (set_attr "type" "*,*,simple_alu_imm,simple_alu_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") |
4dfe9a2e | 81 | (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") |
d2a518d1 | 82 | (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*") |
aaa37ad6 | 83 | (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*") |
84 | (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")] | |
25f905c2 | 85 | ) |
86 | ||
93bda833 | 87 | ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split |
88 | ;; high/low register alternatives for loads and stores here. | |
25f905c2 | 89 | (define_insn "*thumb2_movsi_vfp" |
93bda833 | 90 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") |
91 | (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] | |
25f905c2 | 92 | "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT |
93 | && ( s_register_operand (operands[0], SImode) | |
94 | || s_register_operand (operands[1], SImode))" | |
95 | "* | |
96 | switch (which_alternative) | |
97 | { | |
aaa37ad6 | 98 | case 0: case 1: |
25f905c2 | 99 | return \"mov%?\\t%0, %1\"; |
25f905c2 | 100 | case 2: |
aaa37ad6 | 101 | return \"mvn%?\\t%0, #%B1\"; |
25f905c2 | 102 | case 3: |
aaa37ad6 | 103 | return \"movw%?\\t%0, %1\"; |
25f905c2 | 104 | case 4: |
25f905c2 | 105 | case 5: |
93bda833 | 106 | return \"ldr%?\\t%0, %1\"; |
25f905c2 | 107 | case 6: |
25f905c2 | 108 | case 7: |
93bda833 | 109 | return \"str%?\\t%1, %0\"; |
aaa37ad6 | 110 | case 8: |
93bda833 | 111 | return \"fmsr%?\\t%0, %1\\t%@ int\"; |
112 | case 9: | |
113 | return \"fmrs%?\\t%0, %1\\t%@ int\"; | |
114 | case 10: | |
25f905c2 | 115 | return \"fcpys%?\\t%0, %1\\t%@ int\"; |
93bda833 | 116 | case 11: case 12: |
25f905c2 | 117 | return output_move_vfp (operands); |
118 | default: | |
119 | gcc_unreachable (); | |
120 | } | |
121 | " | |
a2cd141b | 122 | [(set_attr "predicable" "yes") |
013b9671 | 123 | (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") |
4dfe9a2e | 124 | (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") |
d2a518d1 | 125 | (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*") |
42e1de19 | 126 | (set_attr "pool_range" "*,*,*,*,1018,4094,*,*,*,*,*,1018,*") |
93bda833 | 127 | (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] |
a2cd141b | 128 | ) |
129 | ||
130 | ||
131 | ;; DImode moves | |
132 | ||
463d6a35 | 133 | (define_insn "*movdi_vfp" |
134 | [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,r,w,w, Uv") | |
135 | (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))] | |
136 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8 | |
a651f34d | 137 | && ( register_operand (operands[0], DImode) |
87f800b2 | 138 | || register_operand (operands[1], DImode)) |
139 | && !(TARGET_NEON && CONST_INT_P (operands[1]) | |
140 | && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))" | |
a651f34d | 141 | "* |
142 | switch (which_alternative) | |
143 | { | |
144 | case 0: | |
a651f34d | 145 | case 1: |
146 | case 2: | |
a651f34d | 147 | case 3: |
463d6a35 | 148 | return \"#\"; |
a651f34d | 149 | case 4: |
a651f34d | 150 | case 5: |
463d6a35 | 151 | case 6: |
26ff80c0 | 152 | return output_move_double (operands, true, NULL); |
463d6a35 | 153 | case 7: |
154 | return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\"; | |
155 | case 8: | |
156 | return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; | |
157 | case 9: | |
a651f34d | 158 | if (TARGET_VFP_SINGLE) |
159 | return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\"; | |
160 | else | |
161 | return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; | |
463d6a35 | 162 | case 10: case 11: |
a651f34d | 163 | return output_move_vfp (operands); |
164 | default: | |
165 | gcc_unreachable (); | |
166 | } | |
167 | " | |
463d6a35 | 168 | [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") |
169 | (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") | |
170 | (set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8) | |
171 | (eq_attr "alternative" "2") (const_int 12) | |
172 | (eq_attr "alternative" "3") (const_int 16) | |
173 | (eq_attr "alternative" "9") | |
174 | (if_then_else | |
0bf497f5 | 175 | (match_test "TARGET_VFP_SINGLE") |
463d6a35 | 176 | (const_int 8) |
177 | (const_int 4))] | |
178 | (const_int 4))) | |
42e1de19 | 179 | (set_attr "arm_pool_range" "*,*,*,*,1020,4096,*,*,*,*,1020,*") |
180 | (set_attr "thumb2_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") | |
8848d797 | 181 | (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*") |
463d6a35 | 182 | (set_attr "arch" "t2,any,any,any,a,t2,any,any,any,any,any,any")] |
a651f34d | 183 | ) |
184 | ||
463d6a35 | 185 | (define_insn "*movdi_vfp_cortexa8" |
186 | [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,!r,w,w, Uv") | |
187 | (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))] | |
188 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune == cortexa8 | |
189 | && ( register_operand (operands[0], DImode) | |
87f800b2 | 190 | || register_operand (operands[1], DImode)) |
191 | && !(TARGET_NEON && CONST_INT_P (operands[1]) | |
192 | && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))" | |
a2cd141b | 193 | "* |
194 | switch (which_alternative) | |
195 | { | |
d51f92df | 196 | case 0: |
d51f92df | 197 | case 1: |
198 | case 2: | |
a2cd141b | 199 | case 3: |
463d6a35 | 200 | return \"#\"; |
a2cd141b | 201 | case 4: |
a2cd141b | 202 | case 5: |
463d6a35 | 203 | case 6: |
26ff80c0 | 204 | return output_move_double (operands, true, NULL); |
463d6a35 | 205 | case 7: |
25f905c2 | 206 | return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\"; |
463d6a35 | 207 | case 8: |
25f905c2 | 208 | return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; |
463d6a35 | 209 | case 9: |
210 | return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; | |
211 | case 10: case 11: | |
25f905c2 | 212 | return output_move_vfp (operands); |
213 | default: | |
463d6a35 | 214 | gcc_unreachable (); |
25f905c2 | 215 | } |
216 | " | |
463d6a35 | 217 | [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") |
4dfe9a2e | 218 | (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") |
26ff80c0 | 219 | (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8) |
220 | (eq_attr "alternative" "2") (const_int 12) | |
221 | (eq_attr "alternative" "3") (const_int 16) | |
222 | (eq_attr "alternative" "4,5,6") | |
223 | (symbol_ref | |
224 | "arm_count_output_move_double_insns (operands) \ | |
225 | * 4")] | |
226 | (const_int 4))) | |
463d6a35 | 227 | (set_attr "predicable" "yes") |
42e1de19 | 228 | (set_attr "arm_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") |
229 | (set_attr "thumb2_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") | |
8848d797 | 230 | (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*") |
26ff80c0 | 231 | (set (attr "ce_count") |
232 | (symbol_ref "get_attr_length (insn) / 4")) | |
463d6a35 | 233 | (set_attr "arch" "t2,any,any,any,a,t2,any,any,any,any,any,any")] |
234 | ) | |
25f905c2 | 235 | |
9b8516be | 236 | ;; HFmode moves |
a50d7267 | 237 | (define_insn "*movhf_vfp_neon" |
9b8516be | 238 | [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r") |
239 | (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))] | |
240 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16 | |
241 | && ( s_register_operand (operands[0], HFmode) | |
242 | || s_register_operand (operands[1], HFmode))" | |
243 | "* | |
244 | switch (which_alternative) | |
245 | { | |
246 | case 0: /* S register from memory */ | |
247 | return \"vld1.16\\t{%z0}, %A1\"; | |
248 | case 1: /* memory from S register */ | |
249 | return \"vst1.16\\t{%z1}, %A0\"; | |
250 | case 2: /* ARM register from memory */ | |
251 | return \"ldrh\\t%0, %1\\t%@ __fp16\"; | |
252 | case 3: /* memory from ARM register */ | |
253 | return \"strh\\t%1, %0\\t%@ __fp16\"; | |
254 | case 4: /* S register from S register */ | |
255 | return \"fcpys\\t%0, %1\"; | |
256 | case 5: /* ARM register from ARM register */ | |
257 | return \"mov\\t%0, %1\\t%@ __fp16\"; | |
258 | case 6: /* S register from ARM register */ | |
259 | return \"fmsr\\t%0, %1\"; | |
260 | case 7: /* ARM register from S register */ | |
261 | return \"fmrs\\t%0, %1\"; | |
262 | case 8: /* ARM register from constant */ | |
263 | { | |
264 | REAL_VALUE_TYPE r; | |
265 | long bits; | |
266 | rtx ops[4]; | |
267 | ||
268 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
269 | bits = real_to_target (NULL, &r, HFmode); | |
270 | ops[0] = operands[0]; | |
271 | ops[1] = GEN_INT (bits); | |
272 | ops[2] = GEN_INT (bits & 0xff00); | |
273 | ops[3] = GEN_INT (bits & 0x00ff); | |
274 | ||
275 | if (arm_arch_thumb2) | |
276 | output_asm_insn (\"movw\\t%0, %1\", ops); | |
277 | else | |
278 | output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); | |
279 | return \"\"; | |
280 | } | |
281 | default: | |
282 | gcc_unreachable (); | |
283 | } | |
284 | " | |
285 | [(set_attr "conds" "unconditional") | |
286 | (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*") | |
287 | (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*") | |
288 | (set_attr "length" "4,4,4,4,4,4,4,4,8")] | |
289 | ) | |
290 | ||
a50d7267 | 291 | ;; FP16 without element load/store instructions. |
292 | (define_insn "*movhf_vfp" | |
293 | [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r") | |
294 | (match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))] | |
295 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16 | |
296 | && ( s_register_operand (operands[0], HFmode) | |
297 | || s_register_operand (operands[1], HFmode))" | |
298 | "* | |
299 | switch (which_alternative) | |
300 | { | |
301 | case 0: /* ARM register from memory */ | |
302 | return \"ldrh\\t%0, %1\\t%@ __fp16\"; | |
303 | case 1: /* memory from ARM register */ | |
304 | return \"strh\\t%1, %0\\t%@ __fp16\"; | |
305 | case 2: /* S register from S register */ | |
306 | return \"fcpys\\t%0, %1\"; | |
307 | case 3: /* ARM register from ARM register */ | |
308 | return \"mov\\t%0, %1\\t%@ __fp16\"; | |
309 | case 4: /* S register from ARM register */ | |
310 | return \"fmsr\\t%0, %1\"; | |
311 | case 5: /* ARM register from S register */ | |
312 | return \"fmrs\\t%0, %1\"; | |
313 | case 6: /* ARM register from constant */ | |
314 | { | |
315 | REAL_VALUE_TYPE r; | |
316 | long bits; | |
317 | rtx ops[4]; | |
318 | ||
319 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
320 | bits = real_to_target (NULL, &r, HFmode); | |
321 | ops[0] = operands[0]; | |
322 | ops[1] = GEN_INT (bits); | |
323 | ops[2] = GEN_INT (bits & 0xff00); | |
324 | ops[3] = GEN_INT (bits & 0x00ff); | |
325 | ||
326 | if (arm_arch_thumb2) | |
327 | output_asm_insn (\"movw\\t%0, %1\", ops); | |
328 | else | |
329 | output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); | |
330 | return \"\"; | |
331 | } | |
332 | default: | |
333 | gcc_unreachable (); | |
334 | } | |
335 | " | |
336 | [(set_attr "conds" "unconditional") | |
337 | (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*") | |
338 | (set_attr "length" "4,4,4,4,4,4,8")] | |
339 | ) | |
340 | ||
a2cd141b | 341 | |
342 | ;; SFmode moves | |
a694a165 | 343 | ;; Disparage the w<->r cases because reloading an invalid address is |
344 | ;; preferable to loading the value via integer registers. | |
a2cd141b | 345 | |
346 | (define_insn "*movsf_vfp" | |
b5a0636d | 347 | [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r") |
348 | (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] | |
a2cd141b | 349 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP |
350 | && ( s_register_operand (operands[0], SFmode) | |
351 | || s_register_operand (operands[1], SFmode))" | |
25f905c2 | 352 | "* |
353 | switch (which_alternative) | |
354 | { | |
355 | case 0: | |
356 | return \"fmsr%?\\t%0, %1\"; | |
357 | case 1: | |
358 | return \"fmrs%?\\t%0, %1\"; | |
b5a0636d | 359 | case 2: |
360 | return \"fconsts%?\\t%0, #%G1\"; | |
361 | case 3: case 4: | |
25f905c2 | 362 | return output_move_vfp (operands); |
25f905c2 | 363 | case 5: |
b5a0636d | 364 | return \"ldr%?\\t%0, %1\\t%@ float\"; |
25f905c2 | 365 | case 6: |
b5a0636d | 366 | return \"str%?\\t%1, %0\\t%@ float\"; |
25f905c2 | 367 | case 7: |
b5a0636d | 368 | return \"fcpys%?\\t%0, %1\"; |
369 | case 8: | |
25f905c2 | 370 | return \"mov%?\\t%0, %1\\t%@ float\"; |
371 | default: | |
372 | gcc_unreachable (); | |
373 | } | |
374 | " | |
a2cd141b | 375 | [(set_attr "predicable" "yes") |
b5a0636d | 376 | (set_attr "type" |
e3879fd0 | 377 | "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") |
4dfe9a2e | 378 | (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") |
d2a518d1 | 379 | (set_attr "insn" "*,*,*,*,*,*,*,*,mov") |
b5a0636d | 380 | (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*") |
381 | (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] | |
a2cd141b | 382 | ) |
383 | ||
25f905c2 | 384 | (define_insn "*thumb2_movsf_vfp" |
b5a0636d | 385 | [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r") |
386 | (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] | |
25f905c2 | 387 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP |
388 | && ( s_register_operand (operands[0], SFmode) | |
389 | || s_register_operand (operands[1], SFmode))" | |
390 | "* | |
391 | switch (which_alternative) | |
392 | { | |
393 | case 0: | |
394 | return \"fmsr%?\\t%0, %1\"; | |
395 | case 1: | |
396 | return \"fmrs%?\\t%0, %1\"; | |
b5a0636d | 397 | case 2: |
398 | return \"fconsts%?\\t%0, #%G1\"; | |
399 | case 3: case 4: | |
25f905c2 | 400 | return output_move_vfp (operands); |
25f905c2 | 401 | case 5: |
b5a0636d | 402 | return \"ldr%?\\t%0, %1\\t%@ float\"; |
25f905c2 | 403 | case 6: |
b5a0636d | 404 | return \"str%?\\t%1, %0\\t%@ float\"; |
25f905c2 | 405 | case 7: |
b5a0636d | 406 | return \"fcpys%?\\t%0, %1\"; |
407 | case 8: | |
25f905c2 | 408 | return \"mov%?\\t%0, %1\\t%@ float\"; |
409 | default: | |
410 | gcc_unreachable (); | |
411 | } | |
412 | " | |
413 | [(set_attr "predicable" "yes") | |
b5a0636d | 414 | (set_attr "type" |
013b9671 | 415 | "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") |
4dfe9a2e | 416 | (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") |
d2a518d1 | 417 | (set_attr "insn" "*,*,*,*,*,*,*,*,mov") |
42e1de19 | 418 | (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*") |
b5a0636d | 419 | (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] |
25f905c2 | 420 | ) |
421 | ||
a2cd141b | 422 | |
423 | ;; DFmode moves | |
424 | ||
425 | (define_insn "*movdf_vfp" | |
c42b1beb | 426 | [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w ,Uv,r, m,w,r") |
427 | (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,UvF,w ,mF,r,w,r"))] | |
b2778788 | 428 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP |
429 | && ( register_operand (operands[0], DFmode) | |
430 | || register_operand (operands[1], DFmode))" | |
a2cd141b | 431 | "* |
432 | { | |
433 | switch (which_alternative) | |
434 | { | |
435 | case 0: | |
436 | return \"fmdrr%?\\t%P0, %Q1, %R1\"; | |
437 | case 1: | |
438 | return \"fmrrd%?\\t%Q0, %R0, %P1\"; | |
b5a0636d | 439 | case 2: |
a50d7267 | 440 | gcc_assert (TARGET_VFP_DOUBLE); |
b5a0636d | 441 | return \"fconstd%?\\t%P0, #%G1\"; |
442 | case 3: case 4: | |
25f905c2 | 443 | return output_move_vfp (operands); |
c42b1beb | 444 | case 5: case 6: |
26ff80c0 | 445 | return output_move_double (operands, true, NULL); |
d51f92df | 446 | case 7: |
a50d7267 | 447 | if (TARGET_VFP_SINGLE) |
448 | return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\"; | |
449 | else | |
450 | return \"fcpyd%?\\t%P0, %P1\"; | |
b5a0636d | 451 | case 8: |
d51f92df | 452 | return \"#\"; |
a2cd141b | 453 | default: |
ed29c566 | 454 | gcc_unreachable (); |
a2cd141b | 455 | } |
456 | } | |
457 | " | |
b5a0636d | 458 | [(set_attr "type" |
e3879fd0 | 459 | "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") |
4dfe9a2e | 460 | (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") |
c42b1beb | 461 | (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8) |
a50d7267 | 462 | (eq_attr "alternative" "7") |
463 | (if_then_else | |
0bf497f5 | 464 | (match_test "TARGET_VFP_SINGLE") |
a50d7267 | 465 | (const_int 8) |
466 | (const_int 4))] | |
467 | (const_int 4))) | |
85393a52 | 468 | (set_attr "predicable" "yes") |
b5a0636d | 469 | (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*") |
8848d797 | 470 | (set_attr "neg_pool_range" "*,*,*,1004,*,1004,*,*,*")] |
a2cd141b | 471 | ) |
472 | ||
25f905c2 | 473 | (define_insn "*thumb2_movdf_vfp" |
c42b1beb | 474 | [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w ,Uv,r ,m,w,r") |
475 | (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,UvF,w, mF,r, w,r"))] | |
91e6eb29 | 476 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP |
477 | && ( register_operand (operands[0], DFmode) | |
478 | || register_operand (operands[1], DFmode))" | |
25f905c2 | 479 | "* |
480 | { | |
481 | switch (which_alternative) | |
482 | { | |
483 | case 0: | |
484 | return \"fmdrr%?\\t%P0, %Q1, %R1\"; | |
485 | case 1: | |
486 | return \"fmrrd%?\\t%Q0, %R0, %P1\"; | |
b5a0636d | 487 | case 2: |
a50d7267 | 488 | gcc_assert (TARGET_VFP_DOUBLE); |
b5a0636d | 489 | return \"fconstd%?\\t%P0, #%G1\"; |
c42b1beb | 490 | case 3: case 4: |
25f905c2 | 491 | return output_move_vfp (operands); |
c42b1beb | 492 | case 5: case 6: case 8: |
26ff80c0 | 493 | return output_move_double (operands, true, NULL); |
b5a0636d | 494 | case 7: |
a50d7267 | 495 | if (TARGET_VFP_SINGLE) |
496 | return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\"; | |
497 | else | |
498 | return \"fcpyd%?\\t%P0, %P1\"; | |
25f905c2 | 499 | default: |
500 | abort (); | |
501 | } | |
502 | } | |
503 | " | |
b5a0636d | 504 | [(set_attr "type" |
c42b1beb | 505 | "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") |
4dfe9a2e | 506 | (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") |
c42b1beb | 507 | (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8) |
a50d7267 | 508 | (eq_attr "alternative" "7") |
509 | (if_then_else | |
0bf497f5 | 510 | (match_test "TARGET_VFP_SINGLE") |
a50d7267 | 511 | (const_int 8) |
512 | (const_int 4))] | |
513 | (const_int 4))) | |
42e1de19 | 514 | (set_attr "pool_range" "*,*,*,1018,*,4094,*,*,*") |
c42b1beb | 515 | (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] |
25f905c2 | 516 | ) |
517 | ||
a2cd141b | 518 | |
519 | ;; Conditional move patterns | |
520 | ||
521 | (define_insn "*movsfcc_vfp" | |
b5a0636d | 522 | [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r") |
a2cd141b | 523 | (if_then_else:SF |
524 | (match_operator 3 "arm_comparison_operator" | |
525 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
b5a0636d | 526 | (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") |
527 | (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] | |
a2cd141b | 528 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP" |
529 | "@ | |
530 | fcpys%D3\\t%0, %2 | |
531 | fcpys%d3\\t%0, %1 | |
532 | fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1 | |
533 | fmsr%D3\\t%0, %2 | |
534 | fmsr%d3\\t%0, %1 | |
535 | fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1 | |
536 | fmrs%D3\\t%0, %2 | |
537 | fmrs%d3\\t%0, %1 | |
538 | fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1" | |
539 | [(set_attr "conds" "use") | |
540 | (set_attr "length" "4,4,8,4,4,8,4,4,8") | |
4dfe9a2e | 541 | (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
542 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")] | |
a2cd141b | 543 | ) |
544 | ||
25f905c2 | 545 | (define_insn "*thumb2_movsfcc_vfp" |
b5a0636d | 546 | [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r") |
25f905c2 | 547 | (if_then_else:SF |
548 | (match_operator 3 "arm_comparison_operator" | |
549 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
b5a0636d | 550 | (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") |
551 | (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] | |
25f905c2 | 552 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP" |
553 | "@ | |
554 | it\\t%D3\;fcpys%D3\\t%0, %2 | |
555 | it\\t%d3\;fcpys%d3\\t%0, %1 | |
556 | ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1 | |
557 | it\\t%D3\;fmsr%D3\\t%0, %2 | |
558 | it\\t%d3\;fmsr%d3\\t%0, %1 | |
559 | ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1 | |
560 | it\\t%D3\;fmrs%D3\\t%0, %2 | |
561 | it\\t%d3\;fmrs%d3\\t%0, %1 | |
562 | ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1" | |
563 | [(set_attr "conds" "use") | |
564 | (set_attr "length" "6,6,10,6,6,10,6,6,10") | |
4dfe9a2e | 565 | (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
566 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")] | |
25f905c2 | 567 | ) |
568 | ||
a2cd141b | 569 | (define_insn "*movdfcc_vfp" |
570 | [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r") | |
571 | (if_then_else:DF | |
572 | (match_operator 3 "arm_comparison_operator" | |
573 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
574 | (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") | |
575 | (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] | |
a50d7267 | 576 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 577 | "@ |
578 | fcpyd%D3\\t%P0, %P2 | |
579 | fcpyd%d3\\t%P0, %P1 | |
580 | fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1 | |
581 | fmdrr%D3\\t%P0, %Q2, %R2 | |
582 | fmdrr%d3\\t%P0, %Q1, %R1 | |
583 | fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1 | |
584 | fmrrd%D3\\t%Q0, %R0, %P2 | |
585 | fmrrd%d3\\t%Q0, %R0, %P1 | |
586 | fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1" | |
587 | [(set_attr "conds" "use") | |
588 | (set_attr "length" "4,4,8,4,4,8,4,4,8") | |
4dfe9a2e | 589 | (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
590 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")] | |
a2cd141b | 591 | ) |
592 | ||
25f905c2 | 593 | (define_insn "*thumb2_movdfcc_vfp" |
594 | [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r") | |
595 | (if_then_else:DF | |
596 | (match_operator 3 "arm_comparison_operator" | |
597 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
598 | (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") | |
599 | (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] | |
a50d7267 | 600 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
25f905c2 | 601 | "@ |
602 | it\\t%D3\;fcpyd%D3\\t%P0, %P2 | |
603 | it\\t%d3\;fcpyd%d3\\t%P0, %P1 | |
604 | ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1 | |
605 | it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2 | |
606 | it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1 | |
607 | ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1 | |
608 | it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2 | |
609 | it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1 | |
610 | ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1" | |
611 | [(set_attr "conds" "use") | |
612 | (set_attr "length" "6,6,10,6,6,10,6,6,10") | |
4dfe9a2e | 613 | (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
614 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")] | |
25f905c2 | 615 | ) |
616 | ||
a2cd141b | 617 | |
618 | ;; Sign manipulation functions | |
619 | ||
620 | (define_insn "*abssf2_vfp" | |
b5a0636d | 621 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
622 | (abs:SF (match_operand:SF 1 "s_register_operand" "t")))] | |
25f905c2 | 623 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 624 | "fabss%?\\t%0, %1" |
625 | [(set_attr "predicable" "yes") | |
e3879fd0 | 626 | (set_attr "type" "ffariths")] |
a2cd141b | 627 | ) |
628 | ||
629 | (define_insn "*absdf2_vfp" | |
630 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
631 | (abs:DF (match_operand:DF 1 "s_register_operand" "w")))] | |
a50d7267 | 632 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 633 | "fabsd%?\\t%P0, %P1" |
634 | [(set_attr "predicable" "yes") | |
e3879fd0 | 635 | (set_attr "type" "ffarithd")] |
a2cd141b | 636 | ) |
637 | ||
638 | (define_insn "*negsf2_vfp" | |
b5a0636d | 639 | [(set (match_operand:SF 0 "s_register_operand" "=t,?r") |
640 | (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))] | |
25f905c2 | 641 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
8bfd8b24 | 642 | "@ |
643 | fnegs%?\\t%0, %1 | |
644 | eor%?\\t%0, %1, #-2147483648" | |
a2cd141b | 645 | [(set_attr "predicable" "yes") |
e3879fd0 | 646 | (set_attr "type" "ffariths")] |
a2cd141b | 647 | ) |
648 | ||
8bfd8b24 | 649 | (define_insn_and_split "*negdf2_vfp" |
650 | [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r") | |
651 | (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))] | |
a50d7267 | 652 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
8bfd8b24 | 653 | "@ |
654 | fnegd%?\\t%P0, %P1 | |
655 | # | |
656 | #" | |
a50d7267 | 657 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed |
8bfd8b24 | 658 | && arm_general_register_operand (operands[0], DFmode)" |
659 | [(set (match_dup 0) (match_dup 1))] | |
660 | " | |
661 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
662 | { | |
663 | operands[0] = gen_highpart (SImode, operands[0]); | |
664 | operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000)); | |
665 | } | |
666 | else | |
667 | { | |
668 | rtx in_hi, in_lo, out_hi, out_lo; | |
669 | ||
670 | in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]), | |
671 | GEN_INT (0x80000000)); | |
672 | in_lo = gen_lowpart (SImode, operands[1]); | |
673 | out_hi = gen_highpart (SImode, operands[0]); | |
674 | out_lo = gen_lowpart (SImode, operands[0]); | |
675 | ||
676 | if (REGNO (in_lo) == REGNO (out_hi)) | |
677 | { | |
678 | emit_insn (gen_rtx_SET (SImode, out_lo, in_lo)); | |
679 | operands[0] = out_hi; | |
680 | operands[1] = in_hi; | |
681 | } | |
682 | else | |
683 | { | |
684 | emit_insn (gen_rtx_SET (SImode, out_hi, in_hi)); | |
685 | operands[0] = out_lo; | |
686 | operands[1] = in_lo; | |
687 | } | |
688 | } | |
689 | " | |
a2cd141b | 690 | [(set_attr "predicable" "yes") |
8bfd8b24 | 691 | (set_attr "length" "4,4,8") |
e3879fd0 | 692 | (set_attr "type" "ffarithd")] |
a2cd141b | 693 | ) |
694 | ||
695 | ||
696 | ;; Arithmetic insns | |
697 | ||
698 | (define_insn "*addsf3_vfp" | |
b5a0636d | 699 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
700 | (plus:SF (match_operand:SF 1 "s_register_operand" "t") | |
701 | (match_operand:SF 2 "s_register_operand" "t")))] | |
25f905c2 | 702 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 703 | "fadds%?\\t%0, %1, %2" |
704 | [(set_attr "predicable" "yes") | |
e3879fd0 | 705 | (set_attr "type" "fadds")] |
a2cd141b | 706 | ) |
707 | ||
708 | (define_insn "*adddf3_vfp" | |
709 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
710 | (plus:DF (match_operand:DF 1 "s_register_operand" "w") | |
711 | (match_operand:DF 2 "s_register_operand" "w")))] | |
a50d7267 | 712 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 713 | "faddd%?\\t%P0, %P1, %P2" |
714 | [(set_attr "predicable" "yes") | |
e3879fd0 | 715 | (set_attr "type" "faddd")] |
a2cd141b | 716 | ) |
717 | ||
718 | ||
719 | (define_insn "*subsf3_vfp" | |
b5a0636d | 720 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
721 | (minus:SF (match_operand:SF 1 "s_register_operand" "t") | |
722 | (match_operand:SF 2 "s_register_operand" "t")))] | |
25f905c2 | 723 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 724 | "fsubs%?\\t%0, %1, %2" |
725 | [(set_attr "predicable" "yes") | |
e3879fd0 | 726 | (set_attr "type" "fadds")] |
a2cd141b | 727 | ) |
728 | ||
729 | (define_insn "*subdf3_vfp" | |
730 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
731 | (minus:DF (match_operand:DF 1 "s_register_operand" "w") | |
732 | (match_operand:DF 2 "s_register_operand" "w")))] | |
a50d7267 | 733 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 734 | "fsubd%?\\t%P0, %P1, %P2" |
735 | [(set_attr "predicable" "yes") | |
e3879fd0 | 736 | (set_attr "type" "faddd")] |
a2cd141b | 737 | ) |
738 | ||
739 | ||
740 | ;; Division insns | |
741 | ||
742 | (define_insn "*divsf3_vfp" | |
9513f46e | 743 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
b5a0636d | 744 | (div:SF (match_operand:SF 1 "s_register_operand" "t") |
745 | (match_operand:SF 2 "s_register_operand" "t")))] | |
25f905c2 | 746 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 747 | "fdivs%?\\t%0, %1, %2" |
748 | [(set_attr "predicable" "yes") | |
749 | (set_attr "type" "fdivs")] | |
750 | ) | |
751 | ||
752 | (define_insn "*divdf3_vfp" | |
9513f46e | 753 | [(set (match_operand:DF 0 "s_register_operand" "=w") |
a2cd141b | 754 | (div:DF (match_operand:DF 1 "s_register_operand" "w") |
755 | (match_operand:DF 2 "s_register_operand" "w")))] | |
a50d7267 | 756 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 757 | "fdivd%?\\t%P0, %P1, %P2" |
758 | [(set_attr "predicable" "yes") | |
759 | (set_attr "type" "fdivd")] | |
760 | ) | |
761 | ||
762 | ||
763 | ;; Multiplication insns | |
764 | ||
765 | (define_insn "*mulsf3_vfp" | |
9513f46e | 766 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
b5a0636d | 767 | (mult:SF (match_operand:SF 1 "s_register_operand" "t") |
768 | (match_operand:SF 2 "s_register_operand" "t")))] | |
25f905c2 | 769 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 770 | "fmuls%?\\t%0, %1, %2" |
771 | [(set_attr "predicable" "yes") | |
607978a1 | 772 | (set_attr "type" "fmuls")] |
a2cd141b | 773 | ) |
774 | ||
775 | (define_insn "*muldf3_vfp" | |
9513f46e | 776 | [(set (match_operand:DF 0 "s_register_operand" "=w") |
a2cd141b | 777 | (mult:DF (match_operand:DF 1 "s_register_operand" "w") |
778 | (match_operand:DF 2 "s_register_operand" "w")))] | |
a50d7267 | 779 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 780 | "fmuld%?\\t%P0, %P1, %P2" |
781 | [(set_attr "predicable" "yes") | |
607978a1 | 782 | (set_attr "type" "fmuld")] |
a2cd141b | 783 | ) |
784 | ||
a2cd141b | 785 | (define_insn "*mulsf3negsf_vfp" |
9513f46e | 786 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
b5a0636d | 787 | (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t")) |
788 | (match_operand:SF 2 "s_register_operand" "t")))] | |
25f905c2 | 789 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 790 | "fnmuls%?\\t%0, %1, %2" |
791 | [(set_attr "predicable" "yes") | |
607978a1 | 792 | (set_attr "type" "fmuls")] |
a2cd141b | 793 | ) |
794 | ||
795 | (define_insn "*muldf3negdf_vfp" | |
9513f46e | 796 | [(set (match_operand:DF 0 "s_register_operand" "=w") |
a2cd141b | 797 | (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w")) |
798 | (match_operand:DF 2 "s_register_operand" "w")))] | |
a50d7267 | 799 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 800 | "fnmuld%?\\t%P0, %P1, %P2" |
801 | [(set_attr "predicable" "yes") | |
607978a1 | 802 | (set_attr "type" "fmuld")] |
a2cd141b | 803 | ) |
804 | ||
805 | ||
806 | ;; Multiply-accumulate insns | |
807 | ||
808 | ;; 0 = 1 * 2 + 0 | |
809 | (define_insn "*mulsf3addsf_vfp" | |
b5a0636d | 810 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
811 | (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
812 | (match_operand:SF 3 "s_register_operand" "t")) | |
a2cd141b | 813 | (match_operand:SF 1 "s_register_operand" "0")))] |
25f905c2 | 814 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 815 | "fmacs%?\\t%0, %2, %3" |
816 | [(set_attr "predicable" "yes") | |
607978a1 | 817 | (set_attr "type" "fmacs")] |
a2cd141b | 818 | ) |
819 | ||
820 | (define_insn "*muldf3adddf_vfp" | |
821 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
822 | (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
823 | (match_operand:DF 3 "s_register_operand" "w")) | |
824 | (match_operand:DF 1 "s_register_operand" "0")))] | |
a50d7267 | 825 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 826 | "fmacd%?\\t%P0, %P2, %P3" |
827 | [(set_attr "predicable" "yes") | |
607978a1 | 828 | (set_attr "type" "fmacd")] |
a2cd141b | 829 | ) |
830 | ||
831 | ;; 0 = 1 * 2 - 0 | |
832 | (define_insn "*mulsf3subsf_vfp" | |
b5a0636d | 833 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
834 | (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
835 | (match_operand:SF 3 "s_register_operand" "t")) | |
a2cd141b | 836 | (match_operand:SF 1 "s_register_operand" "0")))] |
25f905c2 | 837 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 838 | "fmscs%?\\t%0, %2, %3" |
839 | [(set_attr "predicable" "yes") | |
607978a1 | 840 | (set_attr "type" "fmacs")] |
a2cd141b | 841 | ) |
842 | ||
843 | (define_insn "*muldf3subdf_vfp" | |
844 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
845 | (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
846 | (match_operand:DF 3 "s_register_operand" "w")) | |
847 | (match_operand:DF 1 "s_register_operand" "0")))] | |
a50d7267 | 848 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 849 | "fmscd%?\\t%P0, %P2, %P3" |
850 | [(set_attr "predicable" "yes") | |
607978a1 | 851 | (set_attr "type" "fmacd")] |
a2cd141b | 852 | ) |
853 | ||
854 | ;; 0 = -(1 * 2) + 0 | |
855 | (define_insn "*mulsf3negsfaddsf_vfp" | |
b5a0636d | 856 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
a2cd141b | 857 | (minus:SF (match_operand:SF 1 "s_register_operand" "0") |
b5a0636d | 858 | (mult:SF (match_operand:SF 2 "s_register_operand" "t") |
859 | (match_operand:SF 3 "s_register_operand" "t"))))] | |
25f905c2 | 860 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 861 | "fnmacs%?\\t%0, %2, %3" |
862 | [(set_attr "predicable" "yes") | |
607978a1 | 863 | (set_attr "type" "fmacs")] |
a2cd141b | 864 | ) |
865 | ||
866 | (define_insn "*fmuldf3negdfadddf_vfp" | |
867 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
868 | (minus:DF (match_operand:DF 1 "s_register_operand" "0") | |
869 | (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
870 | (match_operand:DF 3 "s_register_operand" "w"))))] | |
a50d7267 | 871 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 872 | "fnmacd%?\\t%P0, %P2, %P3" |
873 | [(set_attr "predicable" "yes") | |
607978a1 | 874 | (set_attr "type" "fmacd")] |
a2cd141b | 875 | ) |
876 | ||
877 | ||
878 | ;; 0 = -(1 * 2) - 0 | |
879 | (define_insn "*mulsf3negsfsubsf_vfp" | |
b5a0636d | 880 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
a2cd141b | 881 | (minus:SF (mult:SF |
b5a0636d | 882 | (neg:SF (match_operand:SF 2 "s_register_operand" "t")) |
883 | (match_operand:SF 3 "s_register_operand" "t")) | |
a2cd141b | 884 | (match_operand:SF 1 "s_register_operand" "0")))] |
25f905c2 | 885 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 886 | "fnmscs%?\\t%0, %2, %3" |
887 | [(set_attr "predicable" "yes") | |
607978a1 | 888 | (set_attr "type" "fmacs")] |
a2cd141b | 889 | ) |
890 | ||
891 | (define_insn "*muldf3negdfsubdf_vfp" | |
892 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
893 | (minus:DF (mult:DF | |
894 | (neg:DF (match_operand:DF 2 "s_register_operand" "w")) | |
895 | (match_operand:DF 3 "s_register_operand" "w")) | |
896 | (match_operand:DF 1 "s_register_operand" "0")))] | |
a50d7267 | 897 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 898 | "fnmscd%?\\t%P0, %P2, %P3" |
899 | [(set_attr "predicable" "yes") | |
607978a1 | 900 | (set_attr "type" "fmacd")] |
a2cd141b | 901 | ) |
902 | ||
7c0baf23 | 903 | ;; Fused-multiply-accumulate |
904 | ||
905 | (define_insn "fma<SDF:mode>4" | |
906 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
907 | (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
908 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
909 | (match_operand:SDF 3 "register_operand" "0")))] | |
910 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
911 | "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
912 | [(set_attr "predicable" "yes") | |
2d391553 | 913 | (set_attr "type" "fmac<vfp_type>")] |
7c0baf23 | 914 | ) |
915 | ||
916 | (define_insn "*fmsub<SDF:mode>4" | |
917 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
918 | (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" | |
919 | "<F_constraint>")) | |
920 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
921 | (match_operand:SDF 3 "register_operand" "0")))] | |
922 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
923 | "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
924 | [(set_attr "predicable" "yes") | |
2d391553 | 925 | (set_attr "type" "fmac<vfp_type>")] |
7c0baf23 | 926 | ) |
927 | ||
928 | (define_insn "*fnmsub<SDF:mode>4" | |
929 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
930 | (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
931 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
932 | (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] | |
933 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
934 | "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
935 | [(set_attr "predicable" "yes") | |
2d391553 | 936 | (set_attr "type" "fmac<vfp_type>")] |
7c0baf23 | 937 | ) |
938 | ||
939 | (define_insn "*fnmadd<SDF:mode>4" | |
940 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
941 | (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" | |
942 | "<F_constraint>")) | |
943 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
944 | (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] | |
945 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
946 | "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
947 | [(set_attr "predicable" "yes") | |
2d391553 | 948 | (set_attr "type" "fmac<vfp_type>")] |
7c0baf23 | 949 | ) |
950 | ||
a2cd141b | 951 | |
952 | ;; Conversion routines | |
953 | ||
954 | (define_insn "*extendsfdf2_vfp" | |
955 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
b5a0636d | 956 | (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))] |
a50d7267 | 957 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 958 | "fcvtds%?\\t%P0, %1" |
959 | [(set_attr "predicable" "yes") | |
c0e1af52 | 960 | (set_attr "type" "f_cvt")] |
a2cd141b | 961 | ) |
962 | ||
963 | (define_insn "*truncdfsf2_vfp" | |
b5a0636d | 964 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
a2cd141b | 965 | (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))] |
a50d7267 | 966 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 967 | "fcvtsd%?\\t%0, %P1" |
968 | [(set_attr "predicable" "yes") | |
c0e1af52 | 969 | (set_attr "type" "f_cvt")] |
a2cd141b | 970 | ) |
971 | ||
9b8516be | 972 | (define_insn "extendhfsf2" |
973 | [(set (match_operand:SF 0 "s_register_operand" "=t") | |
974 | (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))] | |
a50d7267 | 975 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" |
9b8516be | 976 | "vcvtb%?.f32.f16\\t%0, %1" |
977 | [(set_attr "predicable" "yes") | |
978 | (set_attr "type" "f_cvt")] | |
979 | ) | |
980 | ||
981 | (define_insn "truncsfhf2" | |
982 | [(set (match_operand:HF 0 "s_register_operand" "=t") | |
983 | (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))] | |
a50d7267 | 984 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" |
9b8516be | 985 | "vcvtb%?.f16.f32\\t%0, %1" |
986 | [(set_attr "predicable" "yes") | |
987 | (set_attr "type" "f_cvt")] | |
988 | ) | |
989 | ||
a2cd141b | 990 | (define_insn "*truncsisf2_vfp" |
b5a0636d | 991 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
992 | (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))] | |
25f905c2 | 993 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 994 | "ftosizs%?\\t%0, %1" |
995 | [(set_attr "predicable" "yes") | |
c0e1af52 | 996 | (set_attr "type" "f_cvt")] |
a2cd141b | 997 | ) |
998 | ||
999 | (define_insn "*truncsidf2_vfp" | |
b5a0636d | 1000 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
a2cd141b | 1001 | (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))] |
a50d7267 | 1002 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1003 | "ftosizd%?\\t%0, %P1" |
1004 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1005 | (set_attr "type" "f_cvt")] |
a2cd141b | 1006 | ) |
1007 | ||
311139e8 | 1008 | |
1009 | (define_insn "fixuns_truncsfsi2" | |
b5a0636d | 1010 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
1011 | (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))] | |
25f905c2 | 1012 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
311139e8 | 1013 | "ftouizs%?\\t%0, %1" |
1014 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1015 | (set_attr "type" "f_cvt")] |
311139e8 | 1016 | ) |
1017 | ||
1018 | (define_insn "fixuns_truncdfsi2" | |
b5a0636d | 1019 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
1020 | (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))] | |
a50d7267 | 1021 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
311139e8 | 1022 | "ftouizd%?\\t%0, %P1" |
1023 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1024 | (set_attr "type" "f_cvt")] |
311139e8 | 1025 | ) |
1026 | ||
1027 | ||
a2cd141b | 1028 | (define_insn "*floatsisf2_vfp" |
b5a0636d | 1029 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
1030 | (float:SF (match_operand:SI 1 "s_register_operand" "t")))] | |
25f905c2 | 1031 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1032 | "fsitos%?\\t%0, %1" |
1033 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1034 | (set_attr "type" "f_cvt")] |
a2cd141b | 1035 | ) |
1036 | ||
1037 | (define_insn "*floatsidf2_vfp" | |
1038 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
b5a0636d | 1039 | (float:DF (match_operand:SI 1 "s_register_operand" "t")))] |
a50d7267 | 1040 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1041 | "fsitod%?\\t%P0, %1" |
1042 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1043 | (set_attr "type" "f_cvt")] |
a2cd141b | 1044 | ) |
1045 | ||
1046 | ||
311139e8 | 1047 | (define_insn "floatunssisf2" |
b5a0636d | 1048 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
1049 | (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))] | |
25f905c2 | 1050 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
311139e8 | 1051 | "fuitos%?\\t%0, %1" |
1052 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1053 | (set_attr "type" "f_cvt")] |
311139e8 | 1054 | ) |
1055 | ||
1056 | (define_insn "floatunssidf2" | |
1057 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
b5a0636d | 1058 | (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))] |
a50d7267 | 1059 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
311139e8 | 1060 | "fuitod%?\\t%P0, %1" |
1061 | [(set_attr "predicable" "yes") | |
c0e1af52 | 1062 | (set_attr "type" "f_cvt")] |
311139e8 | 1063 | ) |
1064 | ||
1065 | ||
a2cd141b | 1066 | ;; Sqrt insns. |
1067 | ||
1068 | (define_insn "*sqrtsf2_vfp" | |
b5a0636d | 1069 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
1070 | (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))] | |
25f905c2 | 1071 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1072 | "fsqrts%?\\t%0, %1" |
1073 | [(set_attr "predicable" "yes") | |
1074 | (set_attr "type" "fdivs")] | |
1075 | ) | |
1076 | ||
1077 | (define_insn "*sqrtdf2_vfp" | |
1078 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1079 | (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))] | |
a50d7267 | 1080 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1081 | "fsqrtd%?\\t%P0, %P1" |
1082 | [(set_attr "predicable" "yes") | |
1083 | (set_attr "type" "fdivd")] | |
1084 | ) | |
1085 | ||
1086 | ||
1087 | ;; Patterns to split/copy vfp condition flags. | |
1088 | ||
1089 | (define_insn "*movcc_vfp" | |
1090 | [(set (reg CC_REGNUM) | |
1091 | (reg VFPCC_REGNUM))] | |
25f905c2 | 1092 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1093 | "fmstat%?" |
1094 | [(set_attr "conds" "set") | |
c0e1af52 | 1095 | (set_attr "type" "f_flag")] |
a2cd141b | 1096 | ) |
1097 | ||
1098 | (define_insn_and_split "*cmpsf_split_vfp" | |
1099 | [(set (reg:CCFP CC_REGNUM) | |
b5a0636d | 1100 | (compare:CCFP (match_operand:SF 0 "s_register_operand" "t") |
1101 | (match_operand:SF 1 "vfp_compare_operand" "tG")))] | |
25f905c2 | 1102 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1103 | "#" |
25f905c2 | 1104 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1105 | [(set (reg:CCFP VFPCC_REGNUM) |
1106 | (compare:CCFP (match_dup 0) | |
1107 | (match_dup 1))) | |
1108 | (set (reg:CCFP CC_REGNUM) | |
1109 | (reg:CCFP VFPCC_REGNUM))] | |
1110 | "" | |
1111 | ) | |
1112 | ||
1113 | (define_insn_and_split "*cmpsf_trap_split_vfp" | |
1114 | [(set (reg:CCFPE CC_REGNUM) | |
b5a0636d | 1115 | (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t") |
1116 | (match_operand:SF 1 "vfp_compare_operand" "tG")))] | |
25f905c2 | 1117 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1118 | "#" |
25f905c2 | 1119 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1120 | [(set (reg:CCFPE VFPCC_REGNUM) |
1121 | (compare:CCFPE (match_dup 0) | |
1122 | (match_dup 1))) | |
1123 | (set (reg:CCFPE CC_REGNUM) | |
1124 | (reg:CCFPE VFPCC_REGNUM))] | |
1125 | "" | |
1126 | ) | |
1127 | ||
1128 | (define_insn_and_split "*cmpdf_split_vfp" | |
1129 | [(set (reg:CCFP CC_REGNUM) | |
1130 | (compare:CCFP (match_operand:DF 0 "s_register_operand" "w") | |
1131 | (match_operand:DF 1 "vfp_compare_operand" "wG")))] | |
a50d7267 | 1132 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1133 | "#" |
a50d7267 | 1134 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1135 | [(set (reg:CCFP VFPCC_REGNUM) |
1136 | (compare:CCFP (match_dup 0) | |
1137 | (match_dup 1))) | |
1138 | (set (reg:CCFP CC_REGNUM) | |
751b9f65 | 1139 | (reg:CCFP VFPCC_REGNUM))] |
a2cd141b | 1140 | "" |
1141 | ) | |
1142 | ||
1143 | (define_insn_and_split "*cmpdf_trap_split_vfp" | |
1144 | [(set (reg:CCFPE CC_REGNUM) | |
1145 | (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w") | |
1146 | (match_operand:DF 1 "vfp_compare_operand" "wG")))] | |
a50d7267 | 1147 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1148 | "#" |
a50d7267 | 1149 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1150 | [(set (reg:CCFPE VFPCC_REGNUM) |
1151 | (compare:CCFPE (match_dup 0) | |
1152 | (match_dup 1))) | |
1153 | (set (reg:CCFPE CC_REGNUM) | |
1154 | (reg:CCFPE VFPCC_REGNUM))] | |
1155 | "" | |
1156 | ) | |
1157 | ||
1158 | ||
1159 | ;; Comparison patterns | |
1160 | ||
1161 | (define_insn "*cmpsf_vfp" | |
1162 | [(set (reg:CCFP VFPCC_REGNUM) | |
b5a0636d | 1163 | (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t") |
1164 | (match_operand:SF 1 "vfp_compare_operand" "t,G")))] | |
25f905c2 | 1165 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1166 | "@ |
1167 | fcmps%?\\t%0, %1 | |
1168 | fcmpzs%?\\t%0" | |
1169 | [(set_attr "predicable" "yes") | |
e3879fd0 | 1170 | (set_attr "type" "fcmps")] |
a2cd141b | 1171 | ) |
1172 | ||
1173 | (define_insn "*cmpsf_trap_vfp" | |
1174 | [(set (reg:CCFPE VFPCC_REGNUM) | |
b5a0636d | 1175 | (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t") |
1176 | (match_operand:SF 1 "vfp_compare_operand" "t,G")))] | |
25f905c2 | 1177 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
a2cd141b | 1178 | "@ |
1179 | fcmpes%?\\t%0, %1 | |
1180 | fcmpezs%?\\t%0" | |
1181 | [(set_attr "predicable" "yes") | |
641eb3b6 | 1182 | (set_attr "type" "fcmps")] |
a2cd141b | 1183 | ) |
1184 | ||
1185 | (define_insn "*cmpdf_vfp" | |
1186 | [(set (reg:CCFP VFPCC_REGNUM) | |
1187 | (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w") | |
1188 | (match_operand:DF 1 "vfp_compare_operand" "w,G")))] | |
a50d7267 | 1189 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1190 | "@ |
1191 | fcmpd%?\\t%P0, %P1 | |
1192 | fcmpzd%?\\t%P0" | |
1193 | [(set_attr "predicable" "yes") | |
e3879fd0 | 1194 | (set_attr "type" "fcmpd")] |
a2cd141b | 1195 | ) |
1196 | ||
1197 | (define_insn "*cmpdf_trap_vfp" | |
1198 | [(set (reg:CCFPE VFPCC_REGNUM) | |
1199 | (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w") | |
1200 | (match_operand:DF 1 "vfp_compare_operand" "w,G")))] | |
a50d7267 | 1201 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
a2cd141b | 1202 | "@ |
1203 | fcmped%?\\t%P0, %P1 | |
1204 | fcmpezd%?\\t%P0" | |
1205 | [(set_attr "predicable" "yes") | |
e3879fd0 | 1206 | (set_attr "type" "fcmpd")] |
a2cd141b | 1207 | ) |
1208 | ||
4a62aafb | 1209 | ;; Fixed point to floating point conversions. |
1210 | (define_code_iterator FCVT [unsigned_float float]) | |
1211 | (define_code_attr FCVTI32typename [(unsigned_float "u32") (float "s32")]) | |
1212 | ||
1213 | (define_insn "*combine_vcvt_f32_<FCVTI32typename>" | |
1214 | [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1215 | (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0")) | |
1216 | (match_operand 2 | |
1217 | "const_double_vcvt_power_of_two_reciprocal" "Dt")))] | |
1218 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math" | |
1219 | "vcvt.f32.<FCVTI32typename>\\t%0, %1, %v2" | |
1220 | [(set_attr "predicable" "no") | |
1221 | (set_attr "type" "f_cvt")] | |
1222 | ) | |
a2cd141b | 1223 | |
4a62aafb | 1224 | ;; Not the ideal way of implementing this. Ideally we would be able to split |
1225 | ;; this into a move to a DP register and then a vcvt.f64.i32 | |
1226 | (define_insn "*combine_vcvt_f64_<FCVTI32typename>" | |
1227 | [(set (match_operand:DF 0 "s_register_operand" "=x,x,w") | |
1228 | (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r")) | |
1229 | (match_operand 2 | |
1230 | "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))] | |
1231 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math | |
1232 | && !TARGET_VFP_SINGLE" | |
1233 | "@ | |
1234 | vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2 | |
1235 | vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2 | |
6a891380 | 1236 | vmov.f64\\t%P0, %1, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2" |
4a62aafb | 1237 | [(set_attr "predicable" "no") |
1238 | (set_attr "type" "f_cvt") | |
1239 | (set_attr "length" "8")] | |
1240 | ) | |
a2cd141b | 1241 | |
4a62aafb | 1242 | ;; Store multiple insn used in function prologue. |
a2cd141b | 1243 | (define_insn "*push_multi_vfp" |
1244 | [(match_parallel 2 "multi_register_push" | |
1245 | [(set (match_operand:BLK 0 "memory_operand" "=m") | |
3cc80a30 | 1246 | (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")] |
a2cd141b | 1247 | UNSPEC_PUSH_MULT))])] |
25f905c2 | 1248 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
382a2a57 | 1249 | "* return vfp_output_fstmd (operands);" |
c0e1af52 | 1250 | [(set_attr "type" "f_stored")] |
a2cd141b | 1251 | ) |
1252 | ||
2d391553 | 1253 | ;; VRINT round to integral instructions. |
1254 | ;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2, | |
1255 | ;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2, | |
1256 | ;; rintsf2, rintdf2. | |
1257 | (define_insn "<vrint_pattern><SDF:mode>2" | |
1258 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1259 | (unspec:SDF [(match_operand:SDF 1 | |
1260 | "register_operand" "<F_constraint>")] | |
1261 | VRINT))] | |
1262 | "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>" | |
1263 | "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1" | |
1264 | [(set_attr "predicable" "<vrint_predicable>") | |
1265 | (set_attr "type" "f_rint<vfp_type>")] | |
1266 | ) | |
a2cd141b | 1267 | |
2e02749c | 1268 | ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL. |
1269 | ;; The 'smax' and 'smin' RTL standard pattern names do not specify which | |
1270 | ;; operand will be returned when both operands are zero (i.e. they may not | |
1271 | ;; honour signed zeroes), or when either operand is NaN. Therefore GCC | |
1272 | ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring | |
1273 | ;; NaNs. | |
1274 | ||
1275 | (define_insn "smax<mode>3" | |
1276 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1277 | (smax:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1278 | (match_operand:SDF 2 "register_operand" "<F_constraint>")))] | |
1279 | "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>" | |
1280 | "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1281 | [(set_attr "type" "f_minmax<vfp_type>")] | |
1282 | ) | |
1283 | ||
1284 | (define_insn "smin<mode>3" | |
1285 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1286 | (smin:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1287 | (match_operand:SDF 2 "register_operand" "<F_constraint>")))] | |
1288 | "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>" | |
1289 | "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1290 | [(set_attr "type" "f_minmax<vfp_type>")] | |
1291 | ) | |
1292 | ||
a2cd141b | 1293 | ;; Unimplemented insns: |
1294 | ;; fldm* | |
1295 | ;; fstm* | |
1296 | ;; fmdhr et al (VFPv1) | |
58552ed0 | 1297 | ;; Support for xD (single precision only) variants. |
a2cd141b | 1298 | ;; fmrrs, fmsrr |