OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [arm/] [vfp.md] - Blame information for rev 709

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.