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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [config/] [mips/] [loongson.md] - Blame information for rev 753

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

Line No. Rev Author Line
1 709 jeremybenn
;; Machine description for Loongson-specific patterns, such as
2
;; ST Microelectronics Loongson-2E/2F etc.
3
;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
4
;; Contributed by CodeSourcery.
5
;;
6
;; This file is part of GCC.
7
;;
8
;; GCC is free software; you can redistribute it and/or modify
9
;; it 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,
14
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
;; GNU 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
(define_c_enum "unspec" [
23
  UNSPEC_LOONGSON_PAVG
24
  UNSPEC_LOONGSON_PCMPEQ
25
  UNSPEC_LOONGSON_PCMPGT
26
  UNSPEC_LOONGSON_PEXTR
27
  UNSPEC_LOONGSON_PINSRH
28
  UNSPEC_LOONGSON_VINIT
29
  UNSPEC_LOONGSON_PMADD
30
  UNSPEC_LOONGSON_PMOVMSK
31
  UNSPEC_LOONGSON_PMULHU
32
  UNSPEC_LOONGSON_PMULH
33
  UNSPEC_LOONGSON_PMULU
34
  UNSPEC_LOONGSON_PASUBUB
35
  UNSPEC_LOONGSON_BIADD
36
  UNSPEC_LOONGSON_PSADBH
37
  UNSPEC_LOONGSON_PSHUFH
38
  UNSPEC_LOONGSON_PUNPCKH
39
  UNSPEC_LOONGSON_PUNPCKL
40
  UNSPEC_LOONGSON_PADDD
41
  UNSPEC_LOONGSON_PSUBD
42
  UNSPEC_LOONGSON_DSLL
43
  UNSPEC_LOONGSON_DSRL
44
])
45
 
46
;; Mode iterators and attributes.
47
 
48
;; 64-bit vectors of bytes.
49
(define_mode_iterator VB [V8QI])
50
 
51
;; 64-bit vectors of halfwords.
52
(define_mode_iterator VH [V4HI])
53
 
54
;; 64-bit vectors of words.
55
(define_mode_iterator VW [V2SI])
56
 
57
;; 64-bit vectors of halfwords and bytes.
58
(define_mode_iterator VHB [V4HI V8QI])
59
 
60
;; 64-bit vectors of words and halfwords.
61
(define_mode_iterator VWH [V2SI V4HI])
62
 
63
;; 64-bit vectors of words and bytes
64
(define_mode_iterator VWB [V2SI V8QI])
65
 
66
;; 64-bit vectors of words, halfwords and bytes.
67
(define_mode_iterator VWHB [V2SI V4HI V8QI])
68
 
69
;; 64-bit vectors of words, halfwords and bytes; and DImode.
70
(define_mode_iterator VWHBDI [V2SI V4HI V8QI DI])
71
 
72
;; The Loongson instruction suffixes corresponding to the modes in the
73
;; VWHBDI iterator.
74
(define_mode_attr V_suffix [(V2SI "w") (V4HI "h") (V8QI "b") (DI "d")])
75
 
76
;; Given a vector type T, the mode of a vector half the size of T
77
;; and with the same number of elements.
78
(define_mode_attr V_squash [(V2SI "V2HI") (V4HI "V4QI")])
79
 
80
;; Given a vector type T, the mode of a vector the same size as T
81
;; but with half as many elements.
82
(define_mode_attr V_stretch_half [(V2SI "DI") (V4HI "V2SI") (V8QI "V4HI")])
83
 
84
;; The Loongson instruction suffixes corresponding to the transformation
85
;; expressed by V_stretch_half.
86
(define_mode_attr V_stretch_half_suffix [(V2SI "wd") (V4HI "hw") (V8QI "bh")])
87
 
88
;; Given a vector type T, the mode of a vector the same size as T
89
;; but with twice as many elements.
90
(define_mode_attr V_squash_double [(V2SI "V4HI") (V4HI "V8QI")])
91
 
92
;; Given a vector type T, the inner mode.
93
(define_mode_attr V_inner [(V8QI "QI") (V4HI "HI") (V2SI "SI")])
94
 
95
;; The Loongson instruction suffixes corresponding to the conversions
96
;; specified by V_half_width.
97
(define_mode_attr V_squash_double_suffix [(V2SI "wh") (V4HI "hb")])
98
 
99
;; Move patterns.
100
 
101
;; Expander to legitimize moves involving values of vector modes.
102
(define_expand "mov"
103
  [(set (match_operand:VWHB 0)
104
        (match_operand:VWHB 1))]
105
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
106
{
107
  if (mips_legitimize_move (mode, operands[0], operands[1]))
108
    DONE;
109
})
110
 
111
;; Handle legitimized moves between values of vector modes.
112
(define_insn "mov_internal"
113
  [(set (match_operand:VWHB 0 "nonimmediate_operand" "=m,f,d,f,  d,  m,  d")
114
        (match_operand:VWHB 1 "move_operand"          "f,m,f,dYG,dYG,dYG,m"))]
115
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
116
  { return mips_output_move (operands[0], operands[1]); }
117
  [(set_attr "move_type" "fpstore,fpload,mfc,mtc,move,store,load")
118
   (set_attr "mode" "DI")])
119
 
120
;; Initialization of a vector.
121
 
122
(define_expand "vec_init"
123
  [(set (match_operand:VWHB 0 "register_operand")
124
        (match_operand 1 ""))]
125
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
126
{
127
  mips_expand_vector_init (operands[0], operands[1]);
128
  DONE;
129
})
130
 
131
;; Helper for vec_init.  Initialize element 0 of the output from the input.
132
;; All other elements are undefined.
133
(define_insn "loongson_vec_init1_"
134
  [(set (match_operand:VHB 0 "register_operand" "=f")
135
        (unspec:VHB [(truncate:
136
                       (match_operand:DI 1 "reg_or_0_operand" "Jd"))]
137
                    UNSPEC_LOONGSON_VINIT))]
138
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
139
  "dmtc1\t%z1,%0"
140
  [(set_attr "move_type" "mtc")
141
   (set_attr "mode" "DI")])
142
 
143
;; Helper for vec_initv2si.
144
(define_insn "*vec_concatv2si"
145
  [(set (match_operand:V2SI 0 "register_operand" "=f")
146
        (vec_concat:V2SI
147
          (match_operand:SI 1 "register_operand" "f")
148
          (match_operand:SI 2 "register_operand" "f")))]
149
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
150
  "punpcklwd\t%0,%1,%2"
151
  [(set_attr "type" "fcvt")])
152
 
153
;; Instruction patterns for SIMD instructions.
154
 
155
;; Pack with signed saturation.
156
(define_insn "vec_pack_ssat_"
157
  [(set (match_operand: 0 "register_operand" "=f")
158
        (vec_concat:
159
         (ss_truncate:
160
          (match_operand:VWH 1 "register_operand" "f"))
161
         (ss_truncate:
162
          (match_operand:VWH 2 "register_operand" "f"))))]
163
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
164
  "packss\t%0,%1,%2"
165
  [(set_attr "type" "fmul")])
166
 
167
;; Pack with unsigned saturation.
168
(define_insn "vec_pack_usat_"
169
  [(set (match_operand: 0 "register_operand" "=f")
170
        (vec_concat:
171
         (us_truncate:
172
          (match_operand:VH 1 "register_operand" "f"))
173
         (us_truncate:
174
          (match_operand:VH 2 "register_operand" "f"))))]
175
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
176
  "packus\t%0,%1,%2"
177
  [(set_attr "type" "fmul")])
178
 
179
;; Addition, treating overflow by wraparound.
180
(define_insn "add3"
181
  [(set (match_operand:VWHB 0 "register_operand" "=f")
182
        (plus:VWHB (match_operand:VWHB 1 "register_operand" "f")
183
                   (match_operand:VWHB 2 "register_operand" "f")))]
184
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
185
  "padd\t%0,%1,%2"
186
  [(set_attr "type" "fadd")])
187
 
188
;; Addition of doubleword integers stored in FP registers.
189
;; Overflow is treated by wraparound.
190
;; We use 'unspec' instead of 'plus' here to avoid clash with
191
;; mips.md::add3.  If 'plus' was used, then such instruction
192
;; would be recognized as adddi3 and reload would make it use
193
;; GPRs instead of FPRs.
194
(define_insn "loongson_paddd"
195
  [(set (match_operand:DI 0 "register_operand" "=f")
196
        (unspec:DI [(match_operand:DI 1 "register_operand" "f")
197
                    (match_operand:DI 2 "register_operand" "f")]
198
                   UNSPEC_LOONGSON_PADDD))]
199
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
200
  "paddd\t%0,%1,%2"
201
  [(set_attr "type" "fadd")])
202
 
203
;; Addition, treating overflow by signed saturation.
204
(define_insn "ssadd3"
205
  [(set (match_operand:VHB 0 "register_operand" "=f")
206
        (ss_plus:VHB (match_operand:VHB 1 "register_operand" "f")
207
                     (match_operand:VHB 2 "register_operand" "f")))]
208
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
209
  "padds\t%0,%1,%2"
210
  [(set_attr "type" "fadd")])
211
 
212
;; Addition, treating overflow by unsigned saturation.
213
(define_insn "usadd3"
214
  [(set (match_operand:VHB 0 "register_operand" "=f")
215
        (us_plus:VHB (match_operand:VHB 1 "register_operand" "f")
216
                     (match_operand:VHB 2 "register_operand" "f")))]
217
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
218
  "paddus\t%0,%1,%2"
219
  [(set_attr "type" "fadd")])
220
 
221
;; Logical AND NOT.
222
(define_insn "loongson_pandn_"
223
  [(set (match_operand:VWHBDI 0 "register_operand" "=f")
224
        (and:VWHBDI
225
         (not:VWHBDI (match_operand:VWHBDI 1 "register_operand" "f"))
226
         (match_operand:VWHBDI 2 "register_operand" "f")))]
227
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
228
  "pandn\t%0,%1,%2"
229
  [(set_attr "type" "fmul")])
230
 
231
;; Logical AND.
232
(define_insn "and3"
233
  [(set (match_operand:VWHB 0 "register_operand" "=f")
234
        (and:VWHB (match_operand:VWHB 1 "register_operand" "f")
235
                  (match_operand:VWHB 2 "register_operand" "f")))]
236
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
237
  "and\t%0,%1,%2"
238
  [(set_attr "type" "fmul")])
239
 
240
;; Logical OR.
241
(define_insn "ior3"
242
  [(set (match_operand:VWHB 0 "register_operand" "=f")
243
        (ior:VWHB (match_operand:VWHB 1 "register_operand" "f")
244
                  (match_operand:VWHB 2 "register_operand" "f")))]
245
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
246
  "or\t%0,%1,%2"
247
  [(set_attr "type" "fcvt")])
248
 
249
;; Logical XOR.
250
(define_insn "xor3"
251
  [(set (match_operand:VWHB 0 "register_operand" "=f")
252
        (xor:VWHB (match_operand:VWHB 1 "register_operand" "f")
253
                  (match_operand:VWHB 2 "register_operand" "f")))]
254
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
255
  "xor\t%0,%1,%2"
256
  [(set_attr "type" "fmul")])
257
 
258
;; Logical NOR.
259
(define_insn "*loongson_nor"
260
  [(set (match_operand:VWHB 0 "register_operand" "=f")
261
        (and:VWHB
262
          (not:VWHB (match_operand:VWHB 1 "register_operand" "f"))
263
          (not:VWHB (match_operand:VWHB 2 "register_operand" "f"))))]
264
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
265
  "nor\t%0,%1,%2"
266
  [(set_attr "type" "fmul")])
267
 
268
;; Logical NOT.
269
(define_insn "one_cmpl2"
270
  [(set (match_operand:VWHB 0 "register_operand" "=f")
271
        (not:VWHB (match_operand:VWHB 1 "register_operand" "f")))]
272
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
273
  "nor\t%0,%1,%1"
274
  [(set_attr "type" "fmul")])
275
 
276
;; Average.
277
(define_insn "loongson_pavg"
278
  [(set (match_operand:VHB 0 "register_operand" "=f")
279
        (unspec:VHB [(match_operand:VHB 1 "register_operand" "f")
280
                     (match_operand:VHB 2 "register_operand" "f")]
281
                    UNSPEC_LOONGSON_PAVG))]
282
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
283
  "pavg\t%0,%1,%2"
284
  [(set_attr "type" "fadd")])
285
 
286
;; Equality test.
287
(define_insn "loongson_pcmpeq"
288
  [(set (match_operand:VWHB 0 "register_operand" "=f")
289
        (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
290
                      (match_operand:VWHB 2 "register_operand" "f")]
291
                     UNSPEC_LOONGSON_PCMPEQ))]
292
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
293
  "pcmpeq\t%0,%1,%2"
294
  [(set_attr "type" "fadd")])
295
 
296
;; Greater-than test.
297
(define_insn "loongson_pcmpgt"
298
  [(set (match_operand:VWHB 0 "register_operand" "=f")
299
        (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
300
                      (match_operand:VWHB 2 "register_operand" "f")]
301
                     UNSPEC_LOONGSON_PCMPGT))]
302
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
303
  "pcmpgt\t%0,%1,%2"
304
  [(set_attr "type" "fadd")])
305
 
306
;; Extract halfword.
307
(define_insn "loongson_pextrh"
308
  [(set (match_operand:V4HI 0 "register_operand" "=f")
309
        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "f")
310
                      (match_operand:SI 2 "register_operand" "f")]
311
                   UNSPEC_LOONGSON_PEXTR))]
312
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
313
  "pextrh\t%0,%1,%2"
314
  [(set_attr "type" "fcvt")])
315
 
316
;; Insert halfword.
317
(define_insn "loongson_pinsrh_0"
318
  [(set (match_operand:V4HI 0 "register_operand" "=f")
319
        (vec_select:V4HI
320
          (vec_concat:V8HI
321
            (match_operand:V4HI 1 "register_operand" "f")
322
            (match_operand:V4HI 2 "register_operand" "f"))
323
          (parallel [(const_int 4) (const_int 1)
324
                     (const_int 2) (const_int 3)])))]
325
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
326
  "pinsrh_0\t%0,%1,%2"
327
  [(set_attr "type" "fdiv")])
328
 
329
(define_insn "loongson_pinsrh_1"
330
  [(set (match_operand:V4HI 0 "register_operand" "=f")
331
        (vec_select:V4HI
332
          (vec_concat:V8HI
333
            (match_operand:V4HI 1 "register_operand" "f")
334
            (match_operand:V4HI 2 "register_operand" "f"))
335
          (parallel [(const_int 0) (const_int 4)
336
                     (const_int 2) (const_int 3)])))]
337
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
338
  "pinsrh_1\t%0,%1,%2"
339
  [(set_attr "type" "fdiv")])
340
 
341
(define_insn "loongson_pinsrh_2"
342
  [(set (match_operand:V4HI 0 "register_operand" "=f")
343
        (vec_select:V4HI
344
          (vec_concat:V8HI
345
            (match_operand:V4HI 1 "register_operand" "f")
346
            (match_operand:V4HI 2 "register_operand" "f"))
347
          (parallel [(const_int 0) (const_int 1)
348
                     (const_int 4) (const_int 3)])))]
349
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
350
  "pinsrh_2\t%0,%1,%2"
351
  [(set_attr "type" "fdiv")])
352
 
353
(define_insn "loongson_pinsrh_3"
354
  [(set (match_operand:V4HI 0 "register_operand" "=f")
355
        (vec_select:V4HI
356
          (vec_concat:V8HI
357
            (match_operand:V4HI 1 "register_operand" "f")
358
            (match_operand:V4HI 2 "register_operand" "f"))
359
          (parallel [(const_int 0) (const_int 1)
360
                     (const_int 2) (const_int 4)])))]
361
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
362
  "pinsrh_3\t%0,%1,%2"
363
  [(set_attr "type" "fdiv")])
364
 
365
(define_insn "*vec_setv4hi"
366
  [(set (match_operand:V4HI 0 "register_operand" "=f")
367
        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "f")
368
                      (match_operand:SI 2 "register_operand" "f")
369
                      (match_operand:SI 3 "const_0_to_3_operand" "")]
370
                     UNSPEC_LOONGSON_PINSRH))]
371
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
372
  "pinsrh_%3\t%0,%1,%2"
373
  [(set_attr "type" "fdiv")])
374
 
375
(define_expand "vec_setv4hi"
376
  [(set (match_operand:V4HI 0 "register_operand" "=f")
377
        (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "f")
378
                      (match_operand:HI 2 "register_operand" "f")
379
                      (match_operand:SI 3 "const_0_to_3_operand" "")]
380
                     UNSPEC_LOONGSON_PINSRH))]
381
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
382
{
383
  rtx ext = gen_reg_rtx (SImode);
384
  emit_move_insn (ext, gen_lowpart (SImode, operands[1]));
385
  operands[1] = ext;
386
})
387
 
388
;; Multiply and add packed integers.
389
(define_insn "loongson_pmaddhw"
390
  [(set (match_operand:V2SI 0 "register_operand" "=f")
391
        (unspec:V2SI [(match_operand:V4HI 1 "register_operand" "f")
392
                      (match_operand:V4HI 2 "register_operand" "f")]
393
                     UNSPEC_LOONGSON_PMADD))]
394
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
395
  "pmaddhw\t%0,%1,%2"
396
  [(set_attr "type" "fmul")])
397
 
398
(define_expand "sdot_prodv4hi"
399
  [(match_operand:V2SI 0 "register_operand" "")
400
   (match_operand:V4HI 1 "register_operand" "")
401
   (match_operand:V4HI 2 "register_operand" "")
402
   (match_operand:V2SI 3 "register_operand" "")]
403
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
404
{
405
  rtx t = gen_reg_rtx (V2SImode);
406
  emit_insn (gen_loongson_pmaddhw (t, operands[1], operands[2]));
407
  emit_insn (gen_addv2si3 (operands[0], t, operands[3]));
408
  DONE;
409
})
410
 
411
;; Maximum of signed halfwords.
412
(define_insn "smaxv4hi3"
413
  [(set (match_operand:V4HI 0 "register_operand" "=f")
414
        (smax:V4HI (match_operand:V4HI 1 "register_operand" "f")
415
                   (match_operand:V4HI 2 "register_operand" "f")))]
416
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
417
  "pmaxsh\t%0,%1,%2"
418
  [(set_attr "type" "fadd")])
419
 
420
(define_expand "smax3"
421
  [(match_operand:VWB 0 "register_operand" "")
422
   (match_operand:VWB 1 "register_operand" "")
423
   (match_operand:VWB 2 "register_operand" "")]
424
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
425
{
426
  mips_expand_vec_minmax (operands[0], operands[1], operands[2],
427
                          gen_loongson_pcmpgt, false);
428
  DONE;
429
})
430
 
431
;; Maximum of unsigned bytes.
432
(define_insn "umaxv8qi3"
433
  [(set (match_operand:V8QI 0 "register_operand" "=f")
434
        (umax:V8QI (match_operand:V8QI 1 "register_operand" "f")
435
                   (match_operand:V8QI 2 "register_operand" "f")))]
436
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
437
  "pmaxub\t%0,%1,%2"
438
  [(set_attr "type" "fadd")])
439
 
440
;; Minimum of signed halfwords.
441
(define_insn "sminv4hi3"
442
  [(set (match_operand:V4HI 0 "register_operand" "=f")
443
        (smin:V4HI (match_operand:V4HI 1 "register_operand" "f")
444
                   (match_operand:V4HI 2 "register_operand" "f")))]
445
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
446
  "pminsh\t%0,%1,%2"
447
  [(set_attr "type" "fadd")])
448
 
449
(define_expand "smin3"
450
  [(match_operand:VWB 0 "register_operand" "")
451
   (match_operand:VWB 1 "register_operand" "")
452
   (match_operand:VWB 2 "register_operand" "")]
453
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
454
{
455
  mips_expand_vec_minmax (operands[0], operands[1], operands[2],
456
                          gen_loongson_pcmpgt, true);
457
  DONE;
458
})
459
 
460
;; Minimum of unsigned bytes.
461
(define_insn "uminv8qi3"
462
  [(set (match_operand:V8QI 0 "register_operand" "=f")
463
        (umin:V8QI (match_operand:V8QI 1 "register_operand" "f")
464
                   (match_operand:V8QI 2 "register_operand" "f")))]
465
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
466
  "pminub\t%0,%1,%2"
467
  [(set_attr "type" "fadd")])
468
 
469
;; Move byte mask.
470
(define_insn "loongson_pmovmsk"
471
  [(set (match_operand:VB 0 "register_operand" "=f")
472
        (unspec:VB [(match_operand:VB 1 "register_operand" "f")]
473
                   UNSPEC_LOONGSON_PMOVMSK))]
474
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
475
  "pmovmsk\t%0,%1"
476
  [(set_attr "type" "fabs")])
477
 
478
;; Multiply unsigned integers and store high result.
479
(define_insn "umul3_highpart"
480
  [(set (match_operand:VH 0 "register_operand" "=f")
481
        (unspec:VH [(match_operand:VH 1 "register_operand" "f")
482
                    (match_operand:VH 2 "register_operand" "f")]
483
                   UNSPEC_LOONGSON_PMULHU))]
484
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
485
  "pmulhu\t%0,%1,%2"
486
  [(set_attr "type" "fmul")])
487
 
488
;; Multiply signed integers and store high result.
489
(define_insn "smul3_highpart"
490
  [(set (match_operand:VH 0 "register_operand" "=f")
491
        (unspec:VH [(match_operand:VH 1 "register_operand" "f")
492
                    (match_operand:VH 2 "register_operand" "f")]
493
                   UNSPEC_LOONGSON_PMULH))]
494
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
495
  "pmulh\t%0,%1,%2"
496
  [(set_attr "type" "fmul")])
497
 
498
;; Multiply signed integers and store low result.
499
(define_insn "mul3"
500
  [(set (match_operand:VH 0 "register_operand" "=f")
501
        (mult:VH (match_operand:VH 1 "register_operand" "f")
502
                 (match_operand:VH 2 "register_operand" "f")))]
503
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
504
  "pmull\t%0,%1,%2"
505
  [(set_attr "type" "fmul")])
506
 
507
;; Multiply unsigned word integers.
508
(define_insn "loongson_pmulu"
509
  [(set (match_operand:DI 0 "register_operand" "=f")
510
        (unspec:DI [(match_operand:VW 1 "register_operand" "f")
511
                    (match_operand:VW 2 "register_operand" "f")]
512
                   UNSPEC_LOONGSON_PMULU))]
513
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
514
  "pmulu\t%0,%1,%2"
515
  [(set_attr "type" "fmul")])
516
 
517
;; Absolute difference.
518
(define_insn "loongson_pasubub"
519
  [(set (match_operand:VB 0 "register_operand" "=f")
520
        (unspec:VB [(match_operand:VB 1 "register_operand" "f")
521
                    (match_operand:VB 2 "register_operand" "f")]
522
                   UNSPEC_LOONGSON_PASUBUB))]
523
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
524
  "pasubub\t%0,%1,%2"
525
  [(set_attr "type" "fadd")])
526
 
527
;; Sum of unsigned byte integers.
528
(define_insn "loongson_biadd"
529
  [(set (match_operand: 0 "register_operand" "=f")
530
        (unspec: [(match_operand:VB 1 "register_operand" "f")]
531
                                 UNSPEC_LOONGSON_BIADD))]
532
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
533
  "biadd\t%0,%1"
534
  [(set_attr "type" "fabs")])
535
 
536
(define_insn "reduc_uplus_v8qi"
537
  [(set (match_operand:V8QI 0 "register_operand" "=f")
538
        (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "f")]
539
                     UNSPEC_LOONGSON_BIADD))]
540
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
541
  "biadd\t%0,%1"
542
  [(set_attr "type" "fabs")])
543
 
544
;; Sum of absolute differences.
545
(define_insn "loongson_psadbh"
546
  [(set (match_operand: 0 "register_operand" "=f")
547
        (unspec: [(match_operand:VB 1 "register_operand" "f")
548
                                  (match_operand:VB 2 "register_operand" "f")]
549
                                 UNSPEC_LOONGSON_PSADBH))]
550
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
551
  "pasubub\t%0,%1,%2;biadd\t%0,%0"
552
  [(set_attr "type" "fadd")])
553
 
554
;; Shuffle halfwords.
555
(define_insn "loongson_pshufh"
556
  [(set (match_operand:VH 0 "register_operand" "=f")
557
        (unspec:VH [(match_operand:VH 1 "register_operand" "f")
558
                    (match_operand:SI 2 "register_operand" "f")]
559
                   UNSPEC_LOONGSON_PSHUFH))]
560
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
561
  "pshufh\t%0,%1,%2"
562
  [(set_attr "type" "fmul")])
563
 
564
;; Shift left logical.
565
(define_insn "ashl3"
566
  [(set (match_operand:VWH 0 "register_operand" "=f")
567
        (ashift:VWH (match_operand:VWH 1 "register_operand" "f")
568
                    (match_operand:SI 2 "register_operand" "f")))]
569
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
570
  "psll\t%0,%1,%2"
571
  [(set_attr "type" "fcvt")])
572
 
573
;; Shift right arithmetic.
574
(define_insn "ashr3"
575
  [(set (match_operand:VWH 0 "register_operand" "=f")
576
        (ashiftrt:VWH (match_operand:VWH 1 "register_operand" "f")
577
                      (match_operand:SI 2 "register_operand" "f")))]
578
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
579
  "psra\t%0,%1,%2"
580
  [(set_attr "type" "fcvt")])
581
 
582
;; Shift right logical.
583
(define_insn "lshr3"
584
  [(set (match_operand:VWH 0 "register_operand" "=f")
585
        (lshiftrt:VWH (match_operand:VWH 1 "register_operand" "f")
586
                      (match_operand:SI 2 "register_operand" "f")))]
587
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
588
  "psrl\t%0,%1,%2"
589
  [(set_attr "type" "fcvt")])
590
 
591
;; Subtraction, treating overflow by wraparound.
592
(define_insn "sub3"
593
  [(set (match_operand:VWHB 0 "register_operand" "=f")
594
        (minus:VWHB (match_operand:VWHB 1 "register_operand" "f")
595
                    (match_operand:VWHB 2 "register_operand" "f")))]
596
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
597
  "psub\t%0,%1,%2"
598
  [(set_attr "type" "fadd")])
599
 
600
;; Subtraction of doubleword integers stored in FP registers.
601
;; Overflow is treated by wraparound.
602
;; See loongson_paddd for the reason we use 'unspec' rather than
603
;; 'minus' here.
604
(define_insn "loongson_psubd"
605
  [(set (match_operand:DI 0 "register_operand" "=f")
606
        (unspec:DI [(match_operand:DI 1 "register_operand" "f")
607
                    (match_operand:DI 2 "register_operand" "f")]
608
                   UNSPEC_LOONGSON_PSUBD))]
609
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
610
  "psubd\t%0,%1,%2"
611
  [(set_attr "type" "fadd")])
612
 
613
;; Subtraction, treating overflow by signed saturation.
614
(define_insn "sssub3"
615
  [(set (match_operand:VHB 0 "register_operand" "=f")
616
        (ss_minus:VHB (match_operand:VHB 1 "register_operand" "f")
617
                      (match_operand:VHB 2 "register_operand" "f")))]
618
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
619
  "psubs\t%0,%1,%2"
620
  [(set_attr "type" "fadd")])
621
 
622
;; Subtraction, treating overflow by unsigned saturation.
623
(define_insn "ussub3"
624
  [(set (match_operand:VHB 0 "register_operand" "=f")
625
        (us_minus:VHB (match_operand:VHB 1 "register_operand" "f")
626
                      (match_operand:VHB 2 "register_operand" "f")))]
627
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
628
  "psubus\t%0,%1,%2"
629
  [(set_attr "type" "fadd")])
630
 
631
;; Unpack high data.  Recall that Loongson only runs in little-endian.
632
(define_insn "loongson_punpckhbh"
633
  [(set (match_operand:V8QI 0 "register_operand" "=f")
634
        (vec_select:V8QI
635
          (vec_concat:V16QI
636
            (match_operand:V8QI 1 "register_operand" "f")
637
            (match_operand:V8QI 2 "register_operand" "f"))
638
          (parallel [(const_int 4) (const_int 12)
639
                     (const_int 5) (const_int 13)
640
                     (const_int 6) (const_int 14)
641
                     (const_int 7) (const_int 15)])))]
642
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
643
  "punpckhbh\t%0,%1,%2"
644
  [(set_attr "type" "fdiv")])
645
 
646
(define_insn "loongson_punpckhhw"
647
  [(set (match_operand:V4HI 0 "register_operand" "=f")
648
        (vec_select:V4HI
649
          (vec_concat:V8HI
650
            (match_operand:V4HI 1 "register_operand" "f")
651
            (match_operand:V4HI 2 "register_operand" "f"))
652
          (parallel [(const_int 2) (const_int 6)
653
                     (const_int 3) (const_int 7)])))]
654
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
655
  "punpckhhw\t%0,%1,%2"
656
  [(set_attr "type" "fdiv")])
657
 
658
(define_insn "loongson_punpckhhw_qi"
659
  [(set (match_operand:V8QI 0 "register_operand" "=f")
660
        (vec_select:V8QI
661
          (vec_concat:V16QI
662
            (match_operand:V8QI 1 "register_operand" "f")
663
            (match_operand:V8QI 2 "register_operand" "f"))
664
          (parallel [(const_int 4)  (const_int 5)
665
                     (const_int 12) (const_int 13)
666
                     (const_int 6)  (const_int 7)
667
                     (const_int 14) (const_int 15)])))]
668
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
669
  "punpckhhw\t%0,%1,%2"
670
  [(set_attr "type" "fdiv")])
671
 
672
(define_insn "loongson_punpckhwd"
673
  [(set (match_operand:V2SI 0 "register_operand" "=f")
674
        (vec_select:V2SI
675
          (vec_concat:V4SI
676
            (match_operand:V2SI 1 "register_operand" "f")
677
            (match_operand:V2SI 2 "register_operand" "f"))
678
          (parallel [(const_int 1) (const_int 3)])))]
679
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
680
  "punpckhwd\t%0,%1,%2"
681
  [(set_attr "type" "fcvt")])
682
 
683
(define_insn "loongson_punpckhwd_qi"
684
  [(set (match_operand:V8QI 0 "register_operand" "=f")
685
        (vec_select:V8QI
686
          (vec_concat:V16QI
687
            (match_operand:V8QI 1 "register_operand" "f")
688
            (match_operand:V8QI 2 "register_operand" "f"))
689
          (parallel [(const_int 4) (const_int 5)
690
                     (const_int 6) (const_int 7)
691
                     (const_int 12) (const_int 13)
692
                     (const_int 14) (const_int 15)])))]
693
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
694
  "punpckhwd\t%0,%1,%2"
695
  [(set_attr "type" "fcvt")])
696
 
697
(define_insn "loongson_punpckhwd_hi"
698
  [(set (match_operand:V4HI 0 "register_operand" "=f")
699
        (vec_select:V4HI
700
          (vec_concat:V8HI
701
            (match_operand:V4HI 1 "register_operand" "f")
702
            (match_operand:V4HI 2 "register_operand" "f"))
703
          (parallel [(const_int 2) (const_int 3)
704
                     (const_int 6) (const_int 7)])))]
705
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
706
  "punpckhwd\t%0,%1,%2"
707
  [(set_attr "type" "fcvt")])
708
 
709
;; Unpack low data.
710
(define_insn "loongson_punpcklbh"
711
  [(set (match_operand:V8QI 0 "register_operand" "=f")
712
        (vec_select:V8QI
713
          (vec_concat:V16QI
714
            (match_operand:V8QI 1 "register_operand" "f")
715
            (match_operand:V8QI 2 "register_operand" "f"))
716
          (parallel [(const_int 0) (const_int 8)
717
                     (const_int 1) (const_int 9)
718
                     (const_int 2) (const_int 10)
719
                     (const_int 3) (const_int 11)])))]
720
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
721
  "punpcklbh\t%0,%1,%2"
722
  [(set_attr "type" "fdiv")])
723
 
724
(define_insn "loongson_punpcklhw"
725
  [(set (match_operand:V4HI 0 "register_operand" "=f")
726
        (vec_select:V4HI
727
          (vec_concat:V8HI
728
            (match_operand:V4HI 1 "register_operand" "f")
729
            (match_operand:V4HI 2 "register_operand" "f"))
730
          (parallel [(const_int 0) (const_int 4)
731
                     (const_int 1) (const_int 5)])))]
732
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
733
  "punpcklhw\t%0,%1,%2"
734
  [(set_attr "type" "fdiv")])
735
 
736
(define_insn "*loongson_punpcklhw_qi"
737
  [(set (match_operand:V8QI 0 "register_operand" "=f")
738
        (vec_select:V8QI
739
          (vec_concat:V16QI
740
            (match_operand:V8QI 1 "register_operand" "f")
741
            (match_operand:V8QI 2 "register_operand" "f"))
742
          (parallel [(const_int 0)  (const_int 1)
743
                     (const_int 8)  (const_int 9)
744
                     (const_int 2)  (const_int 3)
745
                     (const_int 10) (const_int 11)])))]
746
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
747
  "punpcklhw\t%0,%1,%2"
748
  [(set_attr "type" "fdiv")])
749
 
750
(define_insn "loongson_punpcklwd"
751
  [(set (match_operand:V2SI 0 "register_operand" "=f")
752
        (vec_select:V2SI
753
          (vec_concat:V4SI
754
            (match_operand:V2SI 1 "register_operand" "f")
755
            (match_operand:V2SI 2 "register_operand" "f"))
756
          (parallel [(const_int 0) (const_int 2)])))]
757
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
758
  "punpcklwd\t%0,%1,%2"
759
  [(set_attr "type" "fcvt")])
760
 
761
(define_insn "*loongson_punpcklwd_qi"
762
  [(set (match_operand:V8QI 0 "register_operand" "=f")
763
        (vec_select:V8QI
764
          (vec_concat:V16QI
765
            (match_operand:V8QI 1 "register_operand" "f")
766
            (match_operand:V8QI 2 "register_operand" "f"))
767
          (parallel [(const_int 0) (const_int 1)
768
                     (const_int 2) (const_int 3)
769
                     (const_int 8) (const_int 9)
770
                     (const_int 10) (const_int 11)])))]
771
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
772
  "punpcklwd\t%0,%1,%2"
773
  [(set_attr "type" "fcvt")])
774
 
775
(define_insn "*loongson_punpcklwd_hi"
776
  [(set (match_operand:V4HI 0 "register_operand" "=f")
777
        (vec_select:V4HI
778
          (vec_concat:V8HI
779
            (match_operand:V4HI 1 "register_operand" "f")
780
            (match_operand:V4HI 2 "register_operand" "f"))
781
          (parallel [(const_int 0) (const_int 1)
782
                     (const_int 4) (const_int 5)])))]
783
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
784
  "punpcklwd\t%0,%1,%2"
785
  [(set_attr "type" "fcvt")])
786
 
787
(define_expand "vec_perm_const"
788
  [(match_operand:VWHB 0 "register_operand" "")
789
   (match_operand:VWHB 1 "register_operand" "")
790
   (match_operand:VWHB 2 "register_operand" "")
791
   (match_operand:VWHB 3 "" "")]
792
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
793
{
794
  if (mips_expand_vec_perm_const (operands))
795
    DONE;
796
  else
797
    FAIL;
798
})
799
 
800
(define_expand "vec_unpacks_lo_"
801
  [(match_operand: 0 "register_operand" "")
802
   (match_operand:VHB 1 "register_operand" "")]
803
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
804
{
805
  mips_expand_vec_unpack (operands, false, false);
806
  DONE;
807
})
808
 
809
(define_expand "vec_unpacks_hi_"
810
  [(match_operand: 0 "register_operand" "")
811
   (match_operand:VHB 1 "register_operand" "")]
812
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
813
{
814
  mips_expand_vec_unpack (operands, false, true);
815
  DONE;
816
})
817
 
818
(define_expand "vec_unpacku_lo_"
819
  [(match_operand: 0 "register_operand" "")
820
   (match_operand:VHB 1 "register_operand" "")]
821
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
822
{
823
  mips_expand_vec_unpack (operands, true, false);
824
  DONE;
825
})
826
 
827
(define_expand "vec_unpacku_hi_"
828
  [(match_operand: 0 "register_operand" "")
829
   (match_operand:VHB 1 "register_operand" "")]
830
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
831
{
832
  mips_expand_vec_unpack (operands, true, true);
833
  DONE;
834
})
835
 
836
;; Whole vector shifts, used for reduction epilogues.
837
(define_insn "vec_shl_"
838
  [(set (match_operand:VWHBDI 0 "register_operand" "=f")
839
        (unspec:VWHBDI [(match_operand:VWHBDI 1 "register_operand" "f")
840
                        (match_operand:SI 2 "register_operand" "f")]
841
                       UNSPEC_LOONGSON_DSLL))]
842
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
843
  "dsll\t%0,%1,%2"
844
  [(set_attr "type" "fcvt")])
845
 
846
(define_insn "vec_shr_"
847
  [(set (match_operand:VWHBDI 0 "register_operand" "=f")
848
        (unspec:VWHBDI [(match_operand:VWHBDI 1 "register_operand" "f")
849
                        (match_operand:SI 2 "register_operand" "f")]
850
                       UNSPEC_LOONGSON_DSRL))]
851
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
852
  "dsrl\t%0,%1,%2"
853
  [(set_attr "type" "fcvt")])
854
 
855
(define_expand "reduc_uplus_"
856
  [(match_operand:VWH 0 "register_operand" "")
857
   (match_operand:VWH 1 "register_operand" "")]
858
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
859
{
860
  mips_expand_vec_reduc (operands[0], operands[1], gen_add3);
861
  DONE;
862
})
863
 
864
; ??? Given that we're not describing a widening reduction, we should
865
; not have separate optabs for signed and unsigned.
866
(define_expand "reduc_splus_"
867
  [(match_operand:VWHB 0 "register_operand" "")
868
   (match_operand:VWHB 1 "register_operand" "")]
869
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
870
{
871
  emit_insn (gen_reduc_uplus_(operands[0], operands[1]));
872
  DONE;
873
})
874
 
875
(define_expand "reduc_smax_"
876
  [(match_operand:VWHB 0 "register_operand" "")
877
   (match_operand:VWHB 1 "register_operand" "")]
878
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
879
{
880
  mips_expand_vec_reduc (operands[0], operands[1], gen_smax3);
881
  DONE;
882
})
883
 
884
(define_expand "reduc_smin_"
885
  [(match_operand:VWHB 0 "register_operand" "")
886
   (match_operand:VWHB 1 "register_operand" "")]
887
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
888
{
889
  mips_expand_vec_reduc (operands[0], operands[1], gen_smin3);
890
  DONE;
891
})
892
 
893
(define_expand "reduc_umax_"
894
  [(match_operand:VB 0 "register_operand" "")
895
   (match_operand:VB 1 "register_operand" "")]
896
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
897
{
898
  mips_expand_vec_reduc (operands[0], operands[1], gen_umax3);
899
  DONE;
900
})
901
 
902
(define_expand "reduc_umin_"
903
  [(match_operand:VB 0 "register_operand" "")
904
   (match_operand:VB 1 "register_operand" "")]
905
  "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
906
{
907
  mips_expand_vec_reduc (operands[0], operands[1], gen_umin3);
908
  DONE;
909
})
910
 
911
;; Integer division and modulus.  For integer multiplication, see mips.md.
912
 
913
(define_insn "div3"
914
  [(set (match_operand:GPR 0 "register_operand" "=&d")
915
        (any_div:GPR (match_operand:GPR 1 "register_operand" "d")
916
                     (match_operand:GPR 2 "register_operand" "d")))]
917
  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
918
  {
919
    if (TARGET_LOONGSON_2EF)
920
      return mips_output_division ("div.g\t%0,%1,%2", operands);
921
    else
922
      return mips_output_division ("gsdiv\t%0,%1,%2", operands);
923
  }
924
  [(set_attr "type" "idiv3")
925
   (set_attr "mode" "")])
926
 
927
(define_insn "mod3"
928
  [(set (match_operand:GPR 0 "register_operand" "=&d")
929
        (any_mod:GPR (match_operand:GPR 1 "register_operand" "d")
930
                     (match_operand:GPR 2 "register_operand" "d")))]
931
  "TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A"
932
  {
933
    if (TARGET_LOONGSON_2EF)
934
      return mips_output_division ("mod.g\t%0,%1,%2", operands);
935
    else
936
      return mips_output_division ("gsmod\t%0,%1,%2", operands);
937
  }
938
  [(set_attr "type" "idiv3")
939
   (set_attr "mode" "")])

powered by: WebSVN 2.1.0

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