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