0
|
1 ;; Machine description for ST Microelectronics Loongson-2E/2F.
|
|
2 ;; Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
|
3 ;; Contributed by CodeSourcery.
|
|
4 ;;
|
|
5 ;; This file is part of GCC.
|
|
6 ;;
|
|
7 ;; GCC is free software; you can redistribute it and/or modify
|
|
8 ;; it under the terms of the GNU General Public License as published by
|
|
9 ;; the Free Software Foundation; either version 3, or (at your option)
|
|
10 ;; any later version.
|
|
11
|
|
12 ;; GCC is distributed in the hope that it will be useful,
|
|
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 ;; GNU General Public License for more details.
|
|
16
|
|
17 ;; You should have received a copy of the GNU General Public License
|
|
18 ;; along with GCC; see the file COPYING3. If not see
|
|
19 ;; <http://www.gnu.org/licenses/>.
|
|
20
|
|
21 ;; Mode iterators and attributes.
|
|
22
|
|
23 ;; 64-bit vectors of bytes.
|
|
24 (define_mode_iterator VB [V8QI])
|
|
25
|
|
26 ;; 64-bit vectors of halfwords.
|
|
27 (define_mode_iterator VH [V4HI])
|
|
28
|
|
29 ;; 64-bit vectors of words.
|
|
30 (define_mode_iterator VW [V2SI])
|
|
31
|
|
32 ;; 64-bit vectors of halfwords and bytes.
|
|
33 (define_mode_iterator VHB [V4HI V8QI])
|
|
34
|
|
35 ;; 64-bit vectors of words and halfwords.
|
|
36 (define_mode_iterator VWH [V2SI V4HI])
|
|
37
|
|
38 ;; 64-bit vectors of words, halfwords and bytes.
|
|
39 (define_mode_iterator VWHB [V2SI V4HI V8QI])
|
|
40
|
|
41 ;; 64-bit vectors of words, halfwords and bytes; and DImode.
|
|
42 (define_mode_iterator VWHBDI [V2SI V4HI V8QI DI])
|
|
43
|
|
44 ;; The Loongson instruction suffixes corresponding to the modes in the
|
|
45 ;; VWHBDI iterator.
|
|
46 (define_mode_attr V_suffix [(V2SI "w") (V4HI "h") (V8QI "b") (DI "d")])
|
|
47
|
|
48 ;; Given a vector type T, the mode of a vector half the size of T
|
|
49 ;; and with the same number of elements.
|
|
50 (define_mode_attr V_squash [(V2SI "V2HI") (V4HI "V4QI")])
|
|
51
|
|
52 ;; Given a vector type T, the mode of a vector the same size as T
|
|
53 ;; but with half as many elements.
|
|
54 (define_mode_attr V_stretch_half [(V2SI "DI") (V4HI "V2SI") (V8QI "V4HI")])
|
|
55
|
|
56 ;; The Loongson instruction suffixes corresponding to the transformation
|
|
57 ;; expressed by V_stretch_half.
|
|
58 (define_mode_attr V_stretch_half_suffix [(V2SI "wd") (V4HI "hw") (V8QI "bh")])
|
|
59
|
|
60 ;; Given a vector type T, the mode of a vector the same size as T
|
|
61 ;; but with twice as many elements.
|
|
62 (define_mode_attr V_squash_double [(V2SI "V4HI") (V4HI "V8QI")])
|
|
63
|
|
64 ;; The Loongson instruction suffixes corresponding to the conversions
|
|
65 ;; specified by V_half_width.
|
|
66 (define_mode_attr V_squash_double_suffix [(V2SI "wh") (V4HI "hb")])
|
|
67
|
|
68 ;; Move patterns.
|
|
69
|
|
70 ;; Expander to legitimize moves involving values of vector modes.
|
|
71 (define_expand "mov<mode>"
|
|
72 [(set (match_operand:VWHB 0)
|
|
73 (match_operand:VWHB 1))]
|
|
74 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
75 {
|
|
76 if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
|
|
77 DONE;
|
|
78 })
|
|
79
|
|
80 ;; Handle legitimized moves between values of vector modes.
|
|
81 (define_insn "mov<mode>_internal"
|
|
82 [(set (match_operand:VWHB 0 "nonimmediate_operand" "=m,f,d,f, d, m, d")
|
|
83 (match_operand:VWHB 1 "move_operand" "f,m,f,dYG,dYG,dYG,m"))]
|
|
84 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
85 { return mips_output_move (operands[0], operands[1]); }
|
|
86 [(set_attr "move_type" "fpstore,fpload,mfc,mtc,move,store,load")
|
|
87 (set_attr "mode" "DI")])
|
|
88
|
|
89 ;; Initialization of a vector.
|
|
90
|
|
91 (define_expand "vec_init<mode>"
|
|
92 [(set (match_operand:VWHB 0 "register_operand")
|
|
93 (match_operand 1 ""))]
|
|
94 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
95 {
|
|
96 mips_expand_vector_init (operands[0], operands[1]);
|
|
97 DONE;
|
|
98 })
|
|
99
|
|
100 ;; Instruction patterns for SIMD instructions.
|
|
101
|
|
102 ;; Pack with signed saturation.
|
|
103 (define_insn "vec_pack_ssat_<mode>"
|
|
104 [(set (match_operand:<V_squash_double> 0 "register_operand" "=f")
|
|
105 (vec_concat:<V_squash_double>
|
|
106 (ss_truncate:<V_squash>
|
|
107 (match_operand:VWH 1 "register_operand" "f"))
|
|
108 (ss_truncate:<V_squash>
|
|
109 (match_operand:VWH 2 "register_operand" "f"))))]
|
|
110 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
111 "packss<V_squash_double_suffix>\t%0,%1,%2"
|
|
112 [(set_attr "type" "fmul")])
|
|
113
|
|
114 ;; Pack with unsigned saturation.
|
|
115 (define_insn "vec_pack_usat_<mode>"
|
|
116 [(set (match_operand:<V_squash_double> 0 "register_operand" "=f")
|
|
117 (vec_concat:<V_squash_double>
|
|
118 (us_truncate:<V_squash>
|
|
119 (match_operand:VH 1 "register_operand" "f"))
|
|
120 (us_truncate:<V_squash>
|
|
121 (match_operand:VH 2 "register_operand" "f"))))]
|
|
122 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
123 "packus<V_squash_double_suffix>\t%0,%1,%2"
|
|
124 [(set_attr "type" "fmul")])
|
|
125
|
|
126 ;; Addition, treating overflow by wraparound.
|
|
127 (define_insn "add<mode>3"
|
|
128 [(set (match_operand:VWHB 0 "register_operand" "=f")
|
|
129 (plus:VWHB (match_operand:VWHB 1 "register_operand" "f")
|
|
130 (match_operand:VWHB 2 "register_operand" "f")))]
|
|
131 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
132 "padd<V_suffix>\t%0,%1,%2"
|
|
133 [(set_attr "type" "fadd")])
|
|
134
|
|
135 ;; Addition of doubleword integers stored in FP registers.
|
|
136 ;; Overflow is treated by wraparound.
|
|
137 ;; We use 'unspec' instead of 'plus' here to avoid clash with
|
|
138 ;; mips.md::add<mode>3. If 'plus' was used, then such instruction
|
|
139 ;; would be recognized as adddi3 and reload would make it use
|
|
140 ;; GPRs instead of FPRs.
|
|
141 (define_insn "loongson_paddd"
|
|
142 [(set (match_operand:DI 0 "register_operand" "=f")
|
|
143 (unspec:DI [(match_operand:DI 1 "register_operand" "f")
|
|
144 (match_operand:DI 2 "register_operand" "f")]
|
|
145 UNSPEC_LOONGSON_PADDD))]
|
|
146 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
147 "paddd\t%0,%1,%2"
|
|
148 [(set_attr "type" "fadd")])
|
|
149
|
|
150 ;; Addition, treating overflow by signed saturation.
|
|
151 (define_insn "ssadd<mode>3"
|
|
152 [(set (match_operand:VHB 0 "register_operand" "=f")
|
|
153 (ss_plus:VHB (match_operand:VHB 1 "register_operand" "f")
|
|
154 (match_operand:VHB 2 "register_operand" "f")))]
|
|
155 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
156 "padds<V_suffix>\t%0,%1,%2"
|
|
157 [(set_attr "type" "fadd")])
|
|
158
|
|
159 ;; Addition, treating overflow by unsigned saturation.
|
|
160 (define_insn "usadd<mode>3"
|
|
161 [(set (match_operand:VHB 0 "register_operand" "=f")
|
|
162 (us_plus:VHB (match_operand:VHB 1 "register_operand" "f")
|
|
163 (match_operand:VHB 2 "register_operand" "f")))]
|
|
164 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
165 "paddus<V_suffix>\t%0,%1,%2"
|
|
166 [(set_attr "type" "fadd")])
|
|
167
|
|
168 ;; Logical AND NOT.
|
|
169 (define_insn "loongson_pandn_<V_suffix>"
|
|
170 [(set (match_operand:VWHBDI 0 "register_operand" "=f")
|
|
171 (and:VWHBDI
|
|
172 (not:VWHBDI (match_operand:VWHBDI 1 "register_operand" "f"))
|
|
173 (match_operand:VWHBDI 2 "register_operand" "f")))]
|
|
174 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
175 "pandn\t%0,%1,%2"
|
|
176 [(set_attr "type" "fmul")])
|
|
177
|
|
178 ;; Average.
|
|
179 (define_insn "loongson_pavg<V_suffix>"
|
|
180 [(set (match_operand:VHB 0 "register_operand" "=f")
|
|
181 (unspec:VHB [(match_operand:VHB 1 "register_operand" "f")
|
|
182 (match_operand:VHB 2 "register_operand" "f")]
|
|
183 UNSPEC_LOONGSON_PAVG))]
|
|
184 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
185 "pavg<V_suffix>\t%0,%1,%2"
|
|
186 [(set_attr "type" "fadd")])
|
|
187
|
|
188 ;; Equality test.
|
|
189 (define_insn "loongson_pcmpeq<V_suffix>"
|
|
190 [(set (match_operand:VWHB 0 "register_operand" "=f")
|
|
191 (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
|
|
192 (match_operand:VWHB 2 "register_operand" "f")]
|
|
193 UNSPEC_LOONGSON_PCMPEQ))]
|
|
194 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
195 "pcmpeq<V_suffix>\t%0,%1,%2"
|
|
196 [(set_attr "type" "fadd")])
|
|
197
|
|
198 ;; Greater-than test.
|
|
199 (define_insn "loongson_pcmpgt<V_suffix>"
|
|
200 [(set (match_operand:VWHB 0 "register_operand" "=f")
|
|
201 (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
|
|
202 (match_operand:VWHB 2 "register_operand" "f")]
|
|
203 UNSPEC_LOONGSON_PCMPGT))]
|
|
204 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
205 "pcmpgt<V_suffix>\t%0,%1,%2"
|
|
206 [(set_attr "type" "fadd")])
|
|
207
|
|
208 ;; Extract halfword.
|
|
209 (define_insn "loongson_pextr<V_suffix>"
|
|
210 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
211 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
212 (match_operand:SI 2 "register_operand" "f")]
|
|
213 UNSPEC_LOONGSON_PEXTR))]
|
|
214 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
215 "pextr<V_suffix>\t%0,%1,%2"
|
|
216 [(set_attr "type" "fmul")])
|
|
217
|
|
218 ;; Insert halfword.
|
|
219 (define_insn "loongson_pinsr<V_suffix>_0"
|
|
220 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
221 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
222 (match_operand:VH 2 "register_operand" "f")]
|
|
223 UNSPEC_LOONGSON_PINSR_0))]
|
|
224 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
225 "pinsr<V_suffix>_0\t%0,%1,%2"
|
|
226 [(set_attr "type" "fdiv")])
|
|
227
|
|
228 (define_insn "loongson_pinsr<V_suffix>_1"
|
|
229 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
230 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
231 (match_operand:VH 2 "register_operand" "f")]
|
|
232 UNSPEC_LOONGSON_PINSR_1))]
|
|
233 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
234 "pinsr<V_suffix>_1\t%0,%1,%2"
|
|
235 [(set_attr "type" "fdiv")])
|
|
236
|
|
237 (define_insn "loongson_pinsr<V_suffix>_2"
|
|
238 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
239 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
240 (match_operand:VH 2 "register_operand" "f")]
|
|
241 UNSPEC_LOONGSON_PINSR_2))]
|
|
242 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
243 "pinsr<V_suffix>_2\t%0,%1,%2"
|
|
244 [(set_attr "type" "fdiv")])
|
|
245
|
|
246 (define_insn "loongson_pinsr<V_suffix>_3"
|
|
247 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
248 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
249 (match_operand:VH 2 "register_operand" "f")]
|
|
250 UNSPEC_LOONGSON_PINSR_3))]
|
|
251 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
252 "pinsr<V_suffix>_3\t%0,%1,%2"
|
|
253 [(set_attr "type" "fdiv")])
|
|
254
|
|
255 ;; Multiply and add packed integers.
|
|
256 (define_insn "loongson_pmadd<V_stretch_half_suffix>"
|
|
257 [(set (match_operand:<V_stretch_half> 0 "register_operand" "=f")
|
|
258 (unspec:<V_stretch_half> [(match_operand:VH 1 "register_operand" "f")
|
|
259 (match_operand:VH 2 "register_operand" "f")]
|
|
260 UNSPEC_LOONGSON_PMADD))]
|
|
261 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
262 "pmadd<V_stretch_half_suffix>\t%0,%1,%2"
|
|
263 [(set_attr "type" "fmul")])
|
|
264
|
|
265 ;; Maximum of signed halfwords.
|
|
266 (define_insn "smax<mode>3"
|
|
267 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
268 (smax:VH (match_operand:VH 1 "register_operand" "f")
|
|
269 (match_operand:VH 2 "register_operand" "f")))]
|
|
270 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
271 "pmaxs<V_suffix>\t%0,%1,%2"
|
|
272 [(set_attr "type" "fadd")])
|
|
273
|
|
274 ;; Maximum of unsigned bytes.
|
|
275 (define_insn "umax<mode>3"
|
|
276 [(set (match_operand:VB 0 "register_operand" "=f")
|
|
277 (umax:VB (match_operand:VB 1 "register_operand" "f")
|
|
278 (match_operand:VB 2 "register_operand" "f")))]
|
|
279 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
280 "pmaxu<V_suffix>\t%0,%1,%2"
|
|
281 [(set_attr "type" "fadd")])
|
|
282
|
|
283 ;; Minimum of signed halfwords.
|
|
284 (define_insn "smin<mode>3"
|
|
285 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
286 (smin:VH (match_operand:VH 1 "register_operand" "f")
|
|
287 (match_operand:VH 2 "register_operand" "f")))]
|
|
288 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
289 "pmins<V_suffix>\t%0,%1,%2"
|
|
290 [(set_attr "type" "fadd")])
|
|
291
|
|
292 ;; Minimum of unsigned bytes.
|
|
293 (define_insn "umin<mode>3"
|
|
294 [(set (match_operand:VB 0 "register_operand" "=f")
|
|
295 (umin:VB (match_operand:VB 1 "register_operand" "f")
|
|
296 (match_operand:VB 2 "register_operand" "f")))]
|
|
297 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
298 "pminu<V_suffix>\t%0,%1,%2"
|
|
299 [(set_attr "type" "fadd")])
|
|
300
|
|
301 ;; Move byte mask.
|
|
302 (define_insn "loongson_pmovmsk<V_suffix>"
|
|
303 [(set (match_operand:VB 0 "register_operand" "=f")
|
|
304 (unspec:VB [(match_operand:VB 1 "register_operand" "f")]
|
|
305 UNSPEC_LOONGSON_PMOVMSK))]
|
|
306 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
307 "pmovmsk<V_suffix>\t%0,%1"
|
|
308 [(set_attr "type" "fabs")])
|
|
309
|
|
310 ;; Multiply unsigned integers and store high result.
|
|
311 (define_insn "umul<mode>3_highpart"
|
|
312 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
313 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
314 (match_operand:VH 2 "register_operand" "f")]
|
|
315 UNSPEC_LOONGSON_PMULHU))]
|
|
316 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
317 "pmulhu<V_suffix>\t%0,%1,%2"
|
|
318 [(set_attr "type" "fmul")])
|
|
319
|
|
320 ;; Multiply signed integers and store high result.
|
|
321 (define_insn "smul<mode>3_highpart"
|
|
322 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
323 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
324 (match_operand:VH 2 "register_operand" "f")]
|
|
325 UNSPEC_LOONGSON_PMULH))]
|
|
326 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
327 "pmulh<V_suffix>\t%0,%1,%2"
|
|
328 [(set_attr "type" "fmul")])
|
|
329
|
|
330 ;; Multiply signed integers and store low result.
|
|
331 (define_insn "loongson_pmull<V_suffix>"
|
|
332 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
333 (unspec:VH [(match_operand:VH 1 "register_operand" "f")
|
|
334 (match_operand:VH 2 "register_operand" "f")]
|
|
335 UNSPEC_LOONGSON_PMULL))]
|
|
336 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
337 "pmull<V_suffix>\t%0,%1,%2"
|
|
338 [(set_attr "type" "fmul")])
|
|
339
|
|
340 ;; Multiply unsigned word integers.
|
|
341 (define_insn "loongson_pmulu<V_suffix>"
|
|
342 [(set (match_operand:DI 0 "register_operand" "=f")
|
|
343 (unspec:DI [(match_operand:VW 1 "register_operand" "f")
|
|
344 (match_operand:VW 2 "register_operand" "f")]
|
|
345 UNSPEC_LOONGSON_PMULU))]
|
|
346 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
347 "pmulu<V_suffix>\t%0,%1,%2"
|
|
348 [(set_attr "type" "fmul")])
|
|
349
|
|
350 ;; Absolute difference.
|
|
351 (define_insn "loongson_pasubub"
|
|
352 [(set (match_operand:VB 0 "register_operand" "=f")
|
|
353 (unspec:VB [(match_operand:VB 1 "register_operand" "f")
|
|
354 (match_operand:VB 2 "register_operand" "f")]
|
|
355 UNSPEC_LOONGSON_PASUBUB))]
|
|
356 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
357 "pasubub\t%0,%1,%2"
|
|
358 [(set_attr "type" "fadd")])
|
|
359
|
|
360 ;; Sum of unsigned byte integers.
|
|
361 (define_insn "loongson_biadd"
|
|
362 [(set (match_operand:<V_stretch_half> 0 "register_operand" "=f")
|
|
363 (unspec:<V_stretch_half> [(match_operand:VB 1 "register_operand" "f")]
|
|
364 UNSPEC_LOONGSON_BIADD))]
|
|
365 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
366 "biadd\t%0,%1"
|
|
367 [(set_attr "type" "fabs")])
|
|
368
|
|
369 ;; Sum of absolute differences.
|
|
370 (define_insn "loongson_psadbh"
|
|
371 [(set (match_operand:<V_stretch_half> 0 "register_operand" "=f")
|
|
372 (unspec:<V_stretch_half> [(match_operand:VB 1 "register_operand" "f")
|
|
373 (match_operand:VB 2 "register_operand" "f")]
|
|
374 UNSPEC_LOONGSON_PSADBH))]
|
|
375 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
376 "pasubub\t%0,%1,%2;biadd\t%0,%0"
|
|
377 [(set_attr "type" "fadd")])
|
|
378
|
|
379 ;; Shuffle halfwords.
|
|
380 (define_insn "loongson_pshufh"
|
|
381 [(set (match_operand:VH 0 "register_operand" "=f")
|
|
382 (unspec:VH [(match_operand:VH 1 "register_operand" "0")
|
|
383 (match_operand:VH 2 "register_operand" "f")
|
|
384 (match_operand:SI 3 "register_operand" "f")]
|
|
385 UNSPEC_LOONGSON_PSHUFH))]
|
|
386 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
387 "pshufh\t%0,%2,%3"
|
|
388 [(set_attr "type" "fmul")])
|
|
389
|
|
390 ;; Shift left logical.
|
|
391 (define_insn "loongson_psll<V_suffix>"
|
|
392 [(set (match_operand:VWH 0 "register_operand" "=f")
|
|
393 (ashift:VWH (match_operand:VWH 1 "register_operand" "f")
|
|
394 (match_operand:SI 2 "register_operand" "f")))]
|
|
395 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
396 "psll<V_suffix>\t%0,%1,%2"
|
|
397 [(set_attr "type" "fmul")])
|
|
398
|
|
399 ;; Shift right arithmetic.
|
|
400 (define_insn "loongson_psra<V_suffix>"
|
|
401 [(set (match_operand:VWH 0 "register_operand" "=f")
|
|
402 (ashiftrt:VWH (match_operand:VWH 1 "register_operand" "f")
|
|
403 (match_operand:SI 2 "register_operand" "f")))]
|
|
404 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
405 "psra<V_suffix>\t%0,%1,%2"
|
|
406 [(set_attr "type" "fdiv")])
|
|
407
|
|
408 ;; Shift right logical.
|
|
409 (define_insn "loongson_psrl<V_suffix>"
|
|
410 [(set (match_operand:VWH 0 "register_operand" "=f")
|
|
411 (lshiftrt:VWH (match_operand:VWH 1 "register_operand" "f")
|
|
412 (match_operand:SI 2 "register_operand" "f")))]
|
|
413 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
414 "psrl<V_suffix>\t%0,%1,%2"
|
|
415 [(set_attr "type" "fdiv")])
|
|
416
|
|
417 ;; Subtraction, treating overflow by wraparound.
|
|
418 (define_insn "sub<mode>3"
|
|
419 [(set (match_operand:VWHB 0 "register_operand" "=f")
|
|
420 (minus:VWHB (match_operand:VWHB 1 "register_operand" "f")
|
|
421 (match_operand:VWHB 2 "register_operand" "f")))]
|
|
422 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
423 "psub<V_suffix>\t%0,%1,%2"
|
|
424 [(set_attr "type" "fadd")])
|
|
425
|
|
426 ;; Subtraction of doubleword integers stored in FP registers.
|
|
427 ;; Overflow is treated by wraparound.
|
|
428 ;; See loongson_paddd for the reason we use 'unspec' rather than
|
|
429 ;; 'minus' here.
|
|
430 (define_insn "loongson_psubd"
|
|
431 [(set (match_operand:DI 0 "register_operand" "=f")
|
|
432 (unspec:DI [(match_operand:DI 1 "register_operand" "f")
|
|
433 (match_operand:DI 2 "register_operand" "f")]
|
|
434 UNSPEC_LOONGSON_PSUBD))]
|
|
435 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
436 "psubd\t%0,%1,%2"
|
|
437 [(set_attr "type" "fadd")])
|
|
438
|
|
439 ;; Subtraction, treating overflow by signed saturation.
|
|
440 (define_insn "sssub<mode>3"
|
|
441 [(set (match_operand:VHB 0 "register_operand" "=f")
|
|
442 (ss_minus:VHB (match_operand:VHB 1 "register_operand" "f")
|
|
443 (match_operand:VHB 2 "register_operand" "f")))]
|
|
444 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
445 "psubs<V_suffix>\t%0,%1,%2"
|
|
446 [(set_attr "type" "fadd")])
|
|
447
|
|
448 ;; Subtraction, treating overflow by unsigned saturation.
|
|
449 (define_insn "ussub<mode>3"
|
|
450 [(set (match_operand:VHB 0 "register_operand" "=f")
|
|
451 (us_minus:VHB (match_operand:VHB 1 "register_operand" "f")
|
|
452 (match_operand:VHB 2 "register_operand" "f")))]
|
|
453 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
454 "psubus<V_suffix>\t%0,%1,%2"
|
|
455 [(set_attr "type" "fadd")])
|
|
456
|
|
457 ;; Unpack high data.
|
|
458 (define_insn "vec_interleave_high<mode>"
|
|
459 [(set (match_operand:VWHB 0 "register_operand" "=f")
|
|
460 (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
|
|
461 (match_operand:VWHB 2 "register_operand" "f")]
|
|
462 UNSPEC_LOONGSON_PUNPCKH))]
|
|
463 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
464 "punpckh<V_stretch_half_suffix>\t%0,%1,%2"
|
|
465 [(set_attr "type" "fdiv")])
|
|
466
|
|
467 ;; Unpack low data.
|
|
468 (define_insn "vec_interleave_low<mode>"
|
|
469 [(set (match_operand:VWHB 0 "register_operand" "=f")
|
|
470 (unspec:VWHB [(match_operand:VWHB 1 "register_operand" "f")
|
|
471 (match_operand:VWHB 2 "register_operand" "f")]
|
|
472 UNSPEC_LOONGSON_PUNPCKL))]
|
|
473 "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS"
|
|
474 "punpckl<V_stretch_half_suffix>\t%0,%1,%2"
|
|
475 [(set_attr "type" "fdiv")])
|
|
476
|
|
477 ;; Integer division and modulus.
|
|
478
|
|
479 (define_insn "<u>div<mode>3"
|
|
480 [(set (match_operand:GPR 0 "register_operand" "=&d")
|
|
481 (any_div:GPR (match_operand:GPR 1 "register_operand" "d")
|
|
482 (match_operand:GPR 2 "register_operand" "d")))]
|
|
483 "TARGET_LOONGSON_2EF"
|
|
484 { return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands); }
|
|
485 [(set_attr "type" "idiv3")
|
|
486 (set_attr "mode" "<MODE>")])
|
|
487
|
|
488 (define_insn "<u>mod<mode>3"
|
|
489 [(set (match_operand:GPR 0 "register_operand" "=&d")
|
|
490 (any_mod:GPR (match_operand:GPR 1 "register_operand" "d")
|
|
491 (match_operand:GPR 2 "register_operand" "d")))]
|
|
492 "TARGET_LOONGSON_2EF"
|
|
493 { return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands); }
|
|
494 [(set_attr "type" "idiv3")
|
|
495 (set_attr "mode" "<MODE>")])
|