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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [mips/] [mips-ps-3d.md] - Blame information for rev 747

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 709 jeremybenn
;; MIPS Paired-Single Floating and MIPS-3D Instructions.
2
;; Copyright (C) 2004, 2007, 2010 Free Software Foundation, Inc.
3
;;
4
;; This file is part of GCC.
5
;;
6
;; GCC is free software; you can redistribute it and/or modify
7
;; it under the terms of the GNU General Public License as published by
8
;; the Free Software Foundation; either version 3, or (at your option)
9
;; any later version.
10
;;
11
;; GCC is distributed in the hope that it will be useful,
12
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
;; GNU General Public License for more details.
15
;;
16
;; You should have received a copy of the GNU General Public License
17
;; along with GCC; see the file COPYING3.  If not see
18
;; .
19
 
20
(define_c_enum "unspec" [
21
  UNSPEC_MOVE_TF_PS
22
  UNSPEC_C
23
 
24
  ;; MIPS64/MIPS32R2 alnv.ps
25
  UNSPEC_ALNV_PS
26
 
27
  ;; MIPS-3D instructions
28
  UNSPEC_CABS
29
 
30
  UNSPEC_ADDR_PS
31
  UNSPEC_CVT_PW_PS
32
  UNSPEC_CVT_PS_PW
33
  UNSPEC_MULR_PS
34
  UNSPEC_ABS_PS
35
 
36
  UNSPEC_RSQRT1
37
  UNSPEC_RSQRT2
38
  UNSPEC_RECIP1
39
  UNSPEC_RECIP2
40
  UNSPEC_SINGLE_CC
41
  UNSPEC_SCC
42
])
43
 
44
(define_insn "*movcc_v2sf_"
45
  [(set (match_operand:V2SF 0 "register_operand" "=f,f")
46
        (if_then_else:V2SF
47
         (match_operator:GPR 4 "equality_operator"
48
                         [(match_operand:GPR 1 "register_operand" "d,d")
49
                          (const_int 0)])
50
         (match_operand:V2SF 2 "register_operand" "f,0")
51
         (match_operand:V2SF 3 "register_operand" "0,f")))]
52
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
53
  "@
54
    mov%T4.ps\t%0,%2,%1
55
    mov%t4.ps\t%0,%3,%1"
56
  [(set_attr "type" "condmove")
57
   (set_attr "mode" "SF")])
58
 
59
(define_insn "mips_cond_move_tf_ps"
60
  [(set (match_operand:V2SF 0 "register_operand" "=f,f")
61
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f,0")
62
                      (match_operand:V2SF 2 "register_operand" "0,f")
63
                      (match_operand:CCV2 3 "register_operand" "z,z")]
64
                     UNSPEC_MOVE_TF_PS))]
65
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
66
  "@
67
    movt.ps\t%0,%1,%3
68
    movf.ps\t%0,%2,%3"
69
  [(set_attr "type" "condmove")
70
   (set_attr "mode" "SF")])
71
 
72
(define_expand "movv2sfcc"
73
  [(set (match_dup 4) (match_operand 1 "comparison_operator"))
74
   (set (match_operand:V2SF 0 "register_operand")
75
        (if_then_else:V2SF (match_dup 5)
76
                           (match_operand:V2SF 2 "register_operand")
77
                           (match_operand:V2SF 3 "register_operand")))]
78
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
79
{
80
  /* We can only support MOVN.PS and MOVZ.PS.
81
     NOTE: MOVT.PS and MOVF.PS have different semantics from MOVN.PS and
82
           MOVZ.PS.  MOVT.PS and MOVF.PS depend on two CC values and move
83
           each item independently.  */
84
 
85
  if (GET_MODE_CLASS (GET_MODE (XEXP (operands[1], 0))) != MODE_INT)
86
    FAIL;
87
 
88
  mips_expand_conditional_move (operands);
89
  DONE;
90
})
91
 
92
(define_insn "vec_perm_const_ps"
93
  [(set (match_operand:V2SF 0 "register_operand" "=f")
94
        (vec_select:V2SF
95
          (vec_concat:V4SF
96
            (match_operand:V2SF 1 "register_operand" "f")
97
            (match_operand:V2SF 2 "register_operand" "f"))
98
          (parallel [(match_operand:SI 3 "const_0_or_1_operand" "")
99
                     (match_operand:SI 4 "const_2_or_3_operand" "")])))]
100
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
101
{
102
  /* Let L be the lower part of operand  and U be the upper part.
103
     The P[UL][UL].PS instruction always specifies the upper part of the
104
     result first, so the instruction is:
105
 
106
        P.PS %0,,
107
 
108
     where 0U ==  and 0L == .
109
 
110
     GCC's vector indices are specified in memory order, which means
111
     that vector element 0 is the lower part (L) on little-endian targets
112
     and the upper part (U) on big-endian targets.  vec_concat likewise
113
     concatenates in memory order, which means that operand 3 (being
114
 
115
     selects part of operand 2.
116
 
117
     Let:
118
 
119
        I3 = INTVAL (operands[3])
120
        I4 = INTVAL (operands[4]) - 2
121
 
122
     Taking the two endiannesses in turn:
123
 
124
     Little-endian:
125
 
126
        The semantics of the RTL pattern are:
127
 
128
        { 0L, 0U } = { X[I3], X[I4 + 2] }, where X = { 1L, 1U, 2L, 2U }
129
 
130
        so: 0L = { 1L, 1U }[I3] (= )
131
            0U = { 2L, 2U }[I4] (= )
132
 
133
             = 2,  = I4 ? U : L
134
             = 1,  = I3 ? U : L
135
 
136
            [LL] !I4 && !I3   [UL] I4 && !I3
137
            [LU] !I4 && I3    [UU] I4 && I3
138
 
139
     Big-endian:
140
 
141
        The semantics of the RTL pattern are:
142
 
143
        { 0U, 0L } = { X[I3], X[I4 + 2] }, where X = { 1U, 1L, 2U, 2L }
144
 
145
        so: 0U = { 1U, 1L }[I3] (= )
146
            0L = { 2U, 2L }[I4] (= )
147
 
148
             = 1,  = I3 ? L : U
149
             = 2,  = I4 ? L : U
150
 
151
            [UU] !I3 && !I4   [UL] !I3 && I4
152
            [LU] I3 && !I4    [LL] I3 && I4.  */
153
 
154
  static const char * const mnemonics[2][4] = {
155
    /* LE */ { "pll.ps\t%0,%2,%1", "pul.ps\t%0,%2,%1",
156
               "plu.ps\t%0,%2,%1", "puu.ps\t%0,%2,%1" },
157
    /* BE */ { "puu.ps\t%0,%1,%2", "pul.ps\t%0,%1,%2",
158
               "plu.ps\t%0,%1,%2", "pll.ps\t%0,%1,%2" },
159
  };
160
 
161
  unsigned mask = INTVAL (operands[3]) * 2 + (INTVAL (operands[4]) - 2);
162
  return mnemonics[BYTES_BIG_ENDIAN][mask];
163
}
164
  [(set_attr "type" "fmove")
165
   (set_attr "mode" "SF")])
166
 
167
(define_expand "vec_perm_constv2sf"
168
  [(match_operand:V2SF 0 "register_operand" "")
169
   (match_operand:V2SF 1 "register_operand" "")
170
   (match_operand:V2SF 2 "register_operand" "")
171
   (match_operand:V2SI 3 "" "")]
172
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
173
{
174
  if (mips_expand_vec_perm_const (operands))
175
    DONE;
176
  else
177
    FAIL;
178
})
179
 
180
;; Expanders for builtins.  The instruction:
181
;;
182
;;     P[UL][UL].PS , , 
183
;;
184
;; says that the upper part of  is taken from half of  and
185
;; the lower part of  is taken from half of .  This means
186
;; that the P[UL][UL].PS operand order matches memory order on big-endian
187
;; targets;  is element 0 of the V2SF result while  is element 1.
188
;; However, the P[UL][UL].PS operand order is the reverse of memory order
189
;; on little-endian targets;  is element 1 of the V2SF result while
190
;;  is element 0.  The arguments to vec_perm_const_ps are always in
191
;; memory order.
192
;;
193
;; Similarly, "U" corresponds to element 0 on big-endian targets but
194
;; to element 1 on little-endian targets.
195
 
196
(define_expand "mips_puu_ps"
197
  [(match_operand:V2SF 0 "register_operand" "")
198
   (match_operand:V2SF 1 "register_operand" "")
199
   (match_operand:V2SF 2 "register_operand" "")]
200
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
201
{
202
  if (BYTES_BIG_ENDIAN)
203
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
204
                                      const0_rtx, const2_rtx));
205
  else
206
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
207
                                      const1_rtx, GEN_INT (3)));
208
  DONE;
209
})
210
 
211
(define_expand "mips_pul_ps"
212
  [(match_operand:V2SF 0 "register_operand" "")
213
   (match_operand:V2SF 1 "register_operand" "")
214
   (match_operand:V2SF 2 "register_operand" "")]
215
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
216
{
217
  if (BYTES_BIG_ENDIAN)
218
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
219
                                      const0_rtx, GEN_INT (3)));
220
  else
221
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
222
                                      const0_rtx, GEN_INT (3)));
223
  DONE;
224
})
225
 
226
(define_expand "mips_plu_ps"
227
  [(match_operand:V2SF 0 "register_operand" "")
228
   (match_operand:V2SF 1 "register_operand" "")
229
   (match_operand:V2SF 2 "register_operand" "")]
230
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
231
{
232
  if (BYTES_BIG_ENDIAN)
233
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
234
                                      const1_rtx, const2_rtx));
235
  else
236
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
237
                                      const1_rtx, const2_rtx));
238
  DONE;
239
})
240
 
241
(define_expand "mips_pll_ps"
242
  [(match_operand:V2SF 0 "register_operand" "")
243
   (match_operand:V2SF 1 "register_operand" "")
244
   (match_operand:V2SF 2 "register_operand" "")]
245
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
246
{
247
  if (BYTES_BIG_ENDIAN)
248
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
249
                                      const1_rtx, GEN_INT (3)));
250
  else
251
    emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
252
                                      const0_rtx, const2_rtx));
253
  DONE;
254
})
255
 
256
; vec_init
257
(define_expand "vec_initv2sf"
258
  [(match_operand:V2SF 0 "register_operand")
259
   (match_operand:V2SF 1 "")]
260
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
261
{
262
  mips_expand_vector_init (operands[0], operands[1]);
263
  DONE;
264
})
265
 
266
(define_insn "vec_concatv2sf"
267
  [(set (match_operand:V2SF 0 "register_operand" "=f")
268
        (vec_concat:V2SF
269
         (match_operand:SF 1 "register_operand" "f")
270
         (match_operand:SF 2 "register_operand" "f")))]
271
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
272
{
273
  if (BYTES_BIG_ENDIAN)
274
    return "cvt.ps.s\t%0,%1,%2";
275
  else
276
    return "cvt.ps.s\t%0,%2,%1";
277
}
278
  [(set_attr "type" "fcvt")
279
   (set_attr "mode" "SF")])
280
 
281
;; ??? This is only generated if we perform a vector operation that has to be
282
;; emulated.  There is no other way to get a vector mode bitfield extract
283
;; currently.
284
 
285
(define_insn "vec_extractv2sf"
286
  [(set (match_operand:SF 0 "register_operand" "=f")
287
        (vec_select:SF (match_operand:V2SF 1 "register_operand" "f")
288
                       (parallel
289
                        [(match_operand 2 "const_0_or_1_operand" "")])))]
290
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
291
{
292
  if (INTVAL (operands[2]) == !BYTES_BIG_ENDIAN)
293
    return "cvt.s.pu\t%0,%1";
294
  else
295
    return "cvt.s.pl\t%0,%1";
296
}
297
  [(set_attr "type" "fcvt")
298
   (set_attr "mode" "SF")])
299
 
300
;; ??? This is only generated if we disable the vec_init pattern.  There is
301
;; no other way to get a vector mode bitfield store currently.
302
 
303
(define_expand "vec_setv2sf"
304
  [(set (match_operand:V2SF 0 "register_operand" "")
305
        (vec_select:V2SF
306
          (vec_concat:V4SF
307
            (match_operand:SF 1 "register_operand" "")
308
            (match_dup 0))
309
          (parallel [(match_operand 2 "const_0_or_1_operand" "")
310
                     (match_dup 3)])))]
311
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
312
{
313
  /* We don't have an insert instruction, so we duplicate the float, and
314
     then use a PUL instruction.  */
315
  rtx temp = gen_reg_rtx (V2SFmode);
316
  emit_insn (gen_vec_concatv2sf (temp, operands[1], operands[1]));
317
  operands[1] = temp;
318
  operands[3] = GEN_INT (1 - INTVAL (operands[2]) + 2);
319
})
320
 
321
; cvt.ps.s - Floating Point Convert Pair to Paired Single
322
(define_expand "mips_cvt_ps_s"
323
  [(match_operand:V2SF 0 "register_operand")
324
   (match_operand:SF 1 "register_operand")
325
   (match_operand:SF 2 "register_operand")]
326
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
327
{
328
  if (BYTES_BIG_ENDIAN)
329
    emit_insn (gen_vec_concatv2sf (operands[0], operands[1], operands[2]));
330
  else
331
    emit_insn (gen_vec_concatv2sf (operands[0], operands[2], operands[1]));
332
  DONE;
333
})
334
 
335
; cvt.s.pl - Floating Point Convert Pair Lower to Single Floating Point
336
(define_expand "mips_cvt_s_pl"
337
  [(set (match_operand:SF 0 "register_operand")
338
        (vec_select:SF (match_operand:V2SF 1 "register_operand")
339
                       (parallel [(match_dup 2)])))]
340
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
341
  { operands[2] = GEN_INT (BYTES_BIG_ENDIAN); })
342
 
343
; cvt.s.pu - Floating Point Convert Pair Upper to Single Floating Point
344
(define_expand "mips_cvt_s_pu"
345
  [(set (match_operand:SF 0 "register_operand")
346
        (vec_select:SF (match_operand:V2SF 1 "register_operand")
347
                       (parallel [(match_dup 2)])))]
348
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
349
  { operands[2] = GEN_INT (!BYTES_BIG_ENDIAN); })
350
 
351
; alnv.ps - Floating Point Align Variable
352
(define_insn "mips_alnv_ps"
353
  [(set (match_operand:V2SF 0 "register_operand" "=f")
354
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
355
                      (match_operand:V2SF 2 "register_operand" "f")
356
                      (match_operand:SI 3 "register_operand" "d")]
357
                     UNSPEC_ALNV_PS))]
358
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
359
  "alnv.ps\t%0,%1,%2,%3"
360
  [(set_attr "type" "fmove")
361
   (set_attr "mode" "SF")])
362
 
363
; addr.ps - Floating Point Reduction Add
364
(define_insn "mips_addr_ps"
365
  [(set (match_operand:V2SF 0 "register_operand" "=f")
366
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
367
                      (match_operand:V2SF 2 "register_operand" "f")]
368
                     UNSPEC_ADDR_PS))]
369
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
370
  "addr.ps\t%0,%1,%2"
371
  [(set_attr "type" "fadd")
372
   (set_attr "mode" "SF")])
373
 
374
(define_insn "reduc_splus_v2sf"
375
  [(set (match_operand:V2SF 0 "register_operand" "=f")
376
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
377
                      (match_dup 1)]
378
                     UNSPEC_ADDR_PS))]
379
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
380
  "")
381
 
382
; cvt.pw.ps - Floating Point Convert Paired Single to Paired Word
383
(define_insn "mips_cvt_pw_ps"
384
  [(set (match_operand:V2SF 0 "register_operand" "=f")
385
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
386
                     UNSPEC_CVT_PW_PS))]
387
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
388
  "cvt.pw.ps\t%0,%1"
389
  [(set_attr "type" "fcvt")
390
   (set_attr "mode" "SF")])
391
 
392
; cvt.ps.pw - Floating Point Convert Paired Word to Paired Single
393
(define_insn "mips_cvt_ps_pw"
394
  [(set (match_operand:V2SF 0 "register_operand" "=f")
395
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
396
                     UNSPEC_CVT_PS_PW))]
397
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
398
  "cvt.ps.pw\t%0,%1"
399
  [(set_attr "type" "fcvt")
400
   (set_attr "mode" "SF")])
401
 
402
; mulr.ps - Floating Point Reduction Multiply
403
(define_insn "mips_mulr_ps"
404
  [(set (match_operand:V2SF 0 "register_operand" "=f")
405
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
406
                      (match_operand:V2SF 2 "register_operand" "f")]
407
                     UNSPEC_MULR_PS))]
408
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
409
  "mulr.ps\t%0,%1,%2"
410
  [(set_attr "type" "fmul")
411
   (set_attr "mode" "SF")])
412
 
413
; abs.ps
414
(define_expand "mips_abs_ps"
415
  [(set (match_operand:V2SF 0 "register_operand")
416
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand")]
417
                     UNSPEC_ABS_PS))]
418
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
419
{
420
  /* If we can ignore NaNs, this operation is equivalent to the
421
     rtl ABS code.  */
422
  if (!HONOR_NANS (V2SFmode))
423
    {
424
      emit_insn (gen_absv2sf2 (operands[0], operands[1]));
425
      DONE;
426
    }
427
})
428
 
429
(define_insn "*mips_abs_ps"
430
  [(set (match_operand:V2SF 0 "register_operand" "=f")
431
        (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
432
                     UNSPEC_ABS_PS))]
433
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
434
  "abs.ps\t%0,%1"
435
  [(set_attr "type" "fabs")
436
   (set_attr "mode" "SF")])
437
 
438
;----------------------------------------------------------------------------
439
; Floating Point Comparisons for Scalars
440
;----------------------------------------------------------------------------
441
 
442
(define_insn "mips_cabs_cond_"
443
  [(set (match_operand:CC 0 "register_operand" "=z")
444
        (unspec:CC [(match_operand:SCALARF 1 "register_operand" "f")
445
                    (match_operand:SCALARF 2 "register_operand" "f")
446
                    (match_operand 3 "const_int_operand" "")]
447
                   UNSPEC_CABS))]
448
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
449
  "cabs.%Y3.\t%0,%1,%2"
450
  [(set_attr "type" "fcmp")
451
   (set_attr "mode" "FPSW")])
452
 
453
 
454
;----------------------------------------------------------------------------
455
; Floating Point Comparisons for Four Singles
456
;----------------------------------------------------------------------------
457
 
458
(define_insn_and_split "mips_c_cond_4s"
459
  [(set (match_operand:CCV4 0 "register_operand" "=z")
460
        (unspec:CCV4 [(match_operand:V2SF 1 "register_operand" "f")
461
                      (match_operand:V2SF 2 "register_operand" "f")
462
                      (match_operand:V2SF 3 "register_operand" "f")
463
                      (match_operand:V2SF 4 "register_operand" "f")
464
                      (match_operand 5 "const_int_operand" "")]
465
                     UNSPEC_C))]
466
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
467
  "#"
468
  "&& reload_completed"
469
  [(set (match_dup 6)
470
        (unspec:CCV2 [(match_dup 1)
471
                      (match_dup 2)
472
                      (match_dup 5)]
473
                     UNSPEC_C))
474
   (set (match_dup 7)
475
        (unspec:CCV2 [(match_dup 3)
476
                      (match_dup 4)
477
                      (match_dup 5)]
478
                     UNSPEC_C))]
479
{
480
  operands[6] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 0);
481
  operands[7] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 8);
482
}
483
  [(set_attr "type" "fcmp")
484
   (set_attr "length" "8")
485
   (set_attr "mode" "FPSW")])
486
 
487
(define_insn_and_split "mips_cabs_cond_4s"
488
  [(set (match_operand:CCV4 0 "register_operand" "=z")
489
        (unspec:CCV4 [(match_operand:V2SF 1 "register_operand" "f")
490
                      (match_operand:V2SF 2 "register_operand" "f")
491
                      (match_operand:V2SF 3 "register_operand" "f")
492
                      (match_operand:V2SF 4 "register_operand" "f")
493
                      (match_operand 5 "const_int_operand" "")]
494
                     UNSPEC_CABS))]
495
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
496
  "#"
497
  "&& reload_completed"
498
  [(set (match_dup 6)
499
        (unspec:CCV2 [(match_dup 1)
500
                      (match_dup 2)
501
                      (match_dup 5)]
502
                     UNSPEC_CABS))
503
   (set (match_dup 7)
504
        (unspec:CCV2 [(match_dup 3)
505
                      (match_dup 4)
506
                      (match_dup 5)]
507
                     UNSPEC_CABS))]
508
{
509
  operands[6] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 0);
510
  operands[7] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 8);
511
}
512
  [(set_attr "type" "fcmp")
513
   (set_attr "length" "8")
514
   (set_attr "mode" "FPSW")])
515
 
516
 
517
;----------------------------------------------------------------------------
518
; Floating Point Comparisons for Paired Singles
519
;----------------------------------------------------------------------------
520
 
521
(define_insn "mips_c_cond_ps"
522
  [(set (match_operand:CCV2 0 "register_operand" "=z")
523
        (unspec:CCV2 [(match_operand:V2SF 1 "register_operand" "f")
524
                      (match_operand:V2SF 2 "register_operand" "f")
525
                      (match_operand 3 "const_int_operand" "")]
526
                     UNSPEC_C))]
527
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
528
  "c.%Y3.ps\t%0,%1,%2"
529
  [(set_attr "type" "fcmp")
530
   (set_attr "mode" "FPSW")])
531
 
532
(define_insn "mips_cabs_cond_ps"
533
  [(set (match_operand:CCV2 0 "register_operand" "=z")
534
        (unspec:CCV2 [(match_operand:V2SF 1 "register_operand" "f")
535
                      (match_operand:V2SF 2 "register_operand" "f")
536
                      (match_operand 3 "const_int_operand" "")]
537
                     UNSPEC_CABS))]
538
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
539
  "cabs.%Y3.ps\t%0,%1,%2"
540
  [(set_attr "type" "fcmp")
541
   (set_attr "mode" "FPSW")])
542
 
543
;; An expander for generating an scc operation.
544
(define_expand "scc_ps"
545
  [(set (match_operand:CCV2 0)
546
        (unspec:CCV2 [(match_operand 1)] UNSPEC_SCC))])
547
 
548
(define_insn "s_ps"
549
  [(set (match_operand:CCV2 0 "register_operand" "=z")
550
        (unspec:CCV2
551
           [(fcond (match_operand:V2SF 1 "register_operand" "f")
552
                   (match_operand:V2SF 2 "register_operand" "f"))]
553
           UNSPEC_SCC))]
554
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
555
  "c..ps\t%0,%1,%2"
556
  [(set_attr "type" "fcmp")
557
   (set_attr "mode" "FPSW")])
558
 
559
(define_insn "s_ps"
560
  [(set (match_operand:CCV2 0 "register_operand" "=z")
561
        (unspec:CCV2
562
           [(swapped_fcond (match_operand:V2SF 1 "register_operand" "f")
563
                           (match_operand:V2SF 2 "register_operand" "f"))]
564
           UNSPEC_SCC))]
565
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
566
  "c..ps\t%0,%2,%1"
567
  [(set_attr "type" "fcmp")
568
   (set_attr "mode" "FPSW")])
569
 
570
;----------------------------------------------------------------------------
571
; Floating Point Branch Instructions.
572
;----------------------------------------------------------------------------
573
 
574
; Branch on Any of Four Floating Point Condition Codes True
575
(define_insn "bc1any4t"
576
  [(set (pc)
577
        (if_then_else (ne (match_operand:CCV4 1 "register_operand" "z")
578
                          (const_int 0))
579
                      (label_ref (match_operand 0 "" ""))
580
                      (pc)))]
581
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
582
  "%*bc1any4t\t%1,%0%/"
583
  [(set_attr "type" "branch")])
584
 
585
; Branch on Any of Four Floating Point Condition Codes False
586
(define_insn "bc1any4f"
587
  [(set (pc)
588
        (if_then_else (ne (match_operand:CCV4 1 "register_operand" "z")
589
                          (const_int -1))
590
                      (label_ref (match_operand 0 "" ""))
591
                      (pc)))]
592
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
593
  "%*bc1any4f\t%1,%0%/"
594
  [(set_attr "type" "branch")])
595
 
596
; Branch on Any of Two Floating Point Condition Codes True
597
(define_insn "bc1any2t"
598
  [(set (pc)
599
        (if_then_else (ne (match_operand:CCV2 1 "register_operand" "z")
600
                          (const_int 0))
601
                      (label_ref (match_operand 0 "" ""))
602
                      (pc)))]
603
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
604
  "%*bc1any2t\t%1,%0%/"
605
  [(set_attr "type" "branch")])
606
 
607
; Branch on Any of Two Floating Point Condition Codes False
608
(define_insn "bc1any2f"
609
  [(set (pc)
610
        (if_then_else (ne (match_operand:CCV2 1 "register_operand" "z")
611
                          (const_int -1))
612
                      (label_ref (match_operand 0 "" ""))
613
                      (pc)))]
614
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
615
  "%*bc1any2f\t%1,%0%/"
616
  [(set_attr "type" "branch")])
617
 
618
; Used to access one register in a CCV2 pair.  Operand 0 is the register
619
; pair and operand 1 is the index of the register we want (a CONST_INT).
620
(define_expand "single_cc"
621
  [(ne (unspec:CC [(match_operand 0) (match_operand 1)] UNSPEC_SINGLE_CC)
622
       (const_int 0))])
623
 
624
; This is a normal floating-point branch pattern, but rather than check
625
; a single CCmode register, it checks one register in a CCV2 pair.
626
; Operand 2 is the register pair and operand 3 is the index of the
627
; register we want.
628
(define_insn "*branch_upper_lower"
629
  [(set (pc)
630
        (if_then_else
631
         (match_operator 1 "equality_operator"
632
            [(unspec:CC [(match_operand:CCV2 2 "register_operand" "z")
633
                         (match_operand 3 "const_int_operand")]
634
                        UNSPEC_SINGLE_CC)
635
             (const_int 0)])
636
         (label_ref (match_operand 0 "" ""))
637
         (pc)))]
638
  "TARGET_HARD_FLOAT"
639
{
640
  operands[2]
641
    = gen_rtx_REG (CCmode, REGNO (operands[2]) + INTVAL (operands[3]));
642
  return mips_output_conditional_branch (insn, operands,
643
                                         MIPS_BRANCH ("b%F1", "%2,%0"),
644
                                         MIPS_BRANCH ("b%W1", "%2,%0"));
645
}
646
  [(set_attr "type" "branch")])
647
 
648
; As above, but with the sense of the condition reversed.
649
(define_insn "*branch_upper_lower_inverted"
650
  [(set (pc)
651
        (if_then_else
652
         (match_operator 1 "equality_operator"
653
            [(unspec:CC [(match_operand:CCV2 2 "register_operand" "z")
654
                         (match_operand 3 "const_int_operand")]
655
                        UNSPEC_SINGLE_CC)
656
             (const_int 0)])
657
         (pc)
658
         (label_ref (match_operand 0 "" ""))))]
659
  "TARGET_HARD_FLOAT"
660
{
661
  operands[2]
662
    = gen_rtx_REG (CCmode, REGNO (operands[2]) + INTVAL (operands[3]));
663
  return mips_output_conditional_branch (insn, operands,
664
                                         MIPS_BRANCH ("b%W1", "%2,%0"),
665
                                         MIPS_BRANCH ("b%F1", "%2,%0"));
666
}
667
  [(set_attr "type" "branch")])
668
 
669
;----------------------------------------------------------------------------
670
; Floating Point Reduced Precision Reciprocal Square Root Instructions.
671
;----------------------------------------------------------------------------
672
 
673
(define_insn "mips_rsqrt1_"
674
  [(set (match_operand:ANYF 0 "register_operand" "=f")
675
        (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
676
                     UNSPEC_RSQRT1))]
677
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
678
  "rsqrt1.\t%0,%1"
679
  [(set_attr "type" "frsqrt1")
680
   (set_attr "mode" "")])
681
 
682
(define_insn "mips_rsqrt2_"
683
  [(set (match_operand:ANYF 0 "register_operand" "=f")
684
        (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
685
                      (match_operand:ANYF 2 "register_operand" "f")]
686
                     UNSPEC_RSQRT2))]
687
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
688
  "rsqrt2.\t%0,%1,%2"
689
  [(set_attr "type" "frsqrt2")
690
   (set_attr "mode" "")])
691
 
692
(define_insn "mips_recip1_"
693
  [(set (match_operand:ANYF 0 "register_operand" "=f")
694
        (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
695
                     UNSPEC_RECIP1))]
696
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
697
  "recip1.\t%0,%1"
698
  [(set_attr "type" "frdiv1")
699
   (set_attr "mode" "")])
700
 
701
(define_insn "mips_recip2_"
702
  [(set (match_operand:ANYF 0 "register_operand" "=f")
703
        (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
704
                      (match_operand:ANYF 2 "register_operand" "f")]
705
                     UNSPEC_RECIP2))]
706
  "TARGET_HARD_FLOAT && TARGET_MIPS3D"
707
  "recip2.\t%0,%1,%2"
708
  [(set_attr "type" "frdiv2")
709
   (set_attr "mode" "")])
710
 
711
(define_expand "vcondv2sfv2sf"
712
  [(set (match_operand:V2SF 0 "register_operand")
713
        (if_then_else:V2SF
714
          (match_operator 3 ""
715
            [(match_operand:V2SF 4 "register_operand")
716
             (match_operand:V2SF 5 "register_operand")])
717
          (match_operand:V2SF 1 "register_operand")
718
          (match_operand:V2SF 2 "register_operand")))]
719
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
720
{
721
  mips_expand_vcondv2sf (operands[0], operands[1], operands[2],
722
                         GET_CODE (operands[3]), operands[4], operands[5]);
723
  DONE;
724
})
725
 
726
(define_expand "sminv2sf3"
727
  [(set (match_operand:V2SF 0 "register_operand")
728
        (smin:V2SF (match_operand:V2SF 1 "register_operand")
729
                   (match_operand:V2SF 2 "register_operand")))]
730
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
731
{
732
  mips_expand_vcondv2sf (operands[0], operands[1], operands[2],
733
                         LE, operands[1], operands[2]);
734
  DONE;
735
})
736
 
737
(define_expand "smaxv2sf3"
738
  [(set (match_operand:V2SF 0 "register_operand")
739
        (smax:V2SF (match_operand:V2SF 1 "register_operand")
740
                   (match_operand:V2SF 2 "register_operand")))]
741
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
742
{
743
  mips_expand_vcondv2sf (operands[0], operands[1], operands[2],
744
                         LE, operands[2], operands[1]);
745
  DONE;
746
})
747
 
748
(define_expand "reduc_smin_v2sf"
749
  [(match_operand:V2SF 0 "register_operand")
750
   (match_operand:V2SF 1 "register_operand")]
751
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
752
{
753
  mips_expand_vec_reduc (operands[0], operands[1], gen_sminv2sf3);
754
  DONE;
755
})
756
 
757
(define_expand "reduc_smax_v2sf"
758
  [(match_operand:V2SF 0 "register_operand")
759
   (match_operand:V2SF 1 "register_operand")]
760
  "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
761
{
762
  mips_expand_vec_reduc (operands[0], operands[1], gen_smaxv2sf3);
763
  DONE;
764
})

powered by: WebSVN 2.1.0

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