1 ;; MIPS Paired-Single Floating and MIPS-3D Instructions.
2 ;; Copyright (C) 2004 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
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 2, or (at your option)
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.
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING. If not, write to
18 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 ;; Boston, MA 02110-1301, USA.
21 (define_insn "*movcc_v2sf_<mode>"
22 [(set (match_operand:V2SF 0 "register_operand" "=f,f")
24 (match_operator:GPR 4 "equality_operator"
25 [(match_operand:GPR 1 "register_operand" "d,d")
27 (match_operand:V2SF 2 "register_operand" "f,0")
28 (match_operand:V2SF 3 "register_operand" "0,f")))]
29 "TARGET_PAIRED_SINGLE_FLOAT"
33 [(set_attr "type" "condmove")
34 (set_attr "mode" "SF")])
36 (define_insn "mips_cond_move_tf_ps"
37 [(set (match_operand:V2SF 0 "register_operand" "=f,f")
38 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f,0")
39 (match_operand:V2SF 2 "register_operand" "0,f")
40 (match_operand:CCV2 3 "register_operand" "z,z")]
42 "TARGET_PAIRED_SINGLE_FLOAT"
46 [(set_attr "type" "condmove")
47 (set_attr "mode" "SF")])
49 (define_expand "movv2sfcc"
50 [(set (match_dup 4) (match_operand 1 "comparison_operator"))
51 (set (match_operand:V2SF 0 "register_operand")
52 (if_then_else:V2SF (match_dup 5)
53 (match_operand:V2SF 2 "register_operand")
54 (match_operand:V2SF 3 "register_operand")))]
55 "TARGET_PAIRED_SINGLE_FLOAT"
57 /* We can only support MOVN.PS and MOVZ.PS.
58 NOTE: MOVT.PS and MOVF.PS have different semantics from MOVN.PS and
59 MOVZ.PS. MOVT.PS and MOVF.PS depend on two CC values and move
60 each item independently. */
62 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
65 gen_conditional_move (operands);
69 ; pul.ps - Pair Upper Lower
70 (define_insn "mips_pul_ps"
71 [(set (match_operand:V2SF 0 "register_operand" "=f")
73 (match_operand:V2SF 1 "register_operand" "f")
74 (match_operand:V2SF 2 "register_operand" "f")
76 "TARGET_PAIRED_SINGLE_FLOAT"
78 [(set_attr "type" "fmove")
79 (set_attr "mode" "SF")])
81 ; puu.ps - Pair upper upper
82 (define_insn "mips_puu_ps"
83 [(set (match_operand:V2SF 0 "register_operand" "=f")
85 (match_operand:V2SF 1 "register_operand" "f")
86 (vec_select:V2SF (match_operand:V2SF 2 "register_operand" "f")
87 (parallel [(const_int 1)
90 "TARGET_PAIRED_SINGLE_FLOAT"
92 [(set_attr "type" "fmove")
93 (set_attr "mode" "SF")])
95 ; pll.ps - Pair Lower Lower
96 (define_insn "mips_pll_ps"
97 [(set (match_operand:V2SF 0 "register_operand" "=f")
99 (vec_select:V2SF (match_operand:V2SF 1 "register_operand" "f")
100 (parallel [(const_int 1)
102 (match_operand:V2SF 2 "register_operand" "f")
104 "TARGET_PAIRED_SINGLE_FLOAT"
106 [(set_attr "type" "fmove")
107 (set_attr "mode" "SF")])
109 ; plu.ps - Pair Lower Upper
110 (define_insn "mips_plu_ps"
111 [(set (match_operand:V2SF 0 "register_operand" "=f")
113 (vec_select:V2SF (match_operand:V2SF 1 "register_operand" "f")
114 (parallel [(const_int 1)
116 (vec_select:V2SF (match_operand:V2SF 2 "register_operand" "f")
117 (parallel [(const_int 1)
120 "TARGET_PAIRED_SINGLE_FLOAT"
122 [(set_attr "type" "fmove")
123 (set_attr "mode" "SF")])
126 (define_expand "vec_initv2sf"
127 [(match_operand:V2SF 0 "register_operand")
128 (match_operand:V2SF 1 "")]
129 "TARGET_PAIRED_SINGLE_FLOAT"
131 rtx op0 = force_reg (SFmode, XVECEXP (operands[1], 0, 0));
132 rtx op1 = force_reg (SFmode, XVECEXP (operands[1], 0, 1));
133 emit_insn (gen_vec_initv2sf_internal (operands[0], op0, op1));
137 (define_insn "vec_initv2sf_internal"
138 [(set (match_operand:V2SF 0 "register_operand" "=f")
140 (match_operand:SF 1 "register_operand" "f")
141 (match_operand:SF 2 "register_operand" "f")))]
142 "TARGET_PAIRED_SINGLE_FLOAT"
144 if (BYTES_BIG_ENDIAN)
145 return "cvt.ps.s\t%0,%1,%2";
147 return "cvt.ps.s\t%0,%2,%1";
149 [(set_attr "type" "fcvt")
150 (set_attr "mode" "SF")])
152 ;; ??? This is only generated if we perform a vector operation that has to be
153 ;; emulated. There is no other way to get a vector mode bitfield extract
156 (define_insn "vec_extractv2sf"
157 [(set (match_operand:SF 0 "register_operand" "=f")
158 (vec_select:SF (match_operand:V2SF 1 "register_operand" "f")
160 [(match_operand 2 "const_0_or_1_operand" "")])))]
161 "TARGET_PAIRED_SINGLE_FLOAT"
163 if (INTVAL (operands[2]) == !BYTES_BIG_ENDIAN)
164 return "cvt.s.pu\t%0,%1";
166 return "cvt.s.pl\t%0,%1";
168 [(set_attr "type" "fcvt")
169 (set_attr "mode" "SF")])
171 ;; ??? This is only generated if we disable the vec_init pattern. There is
172 ;; no other way to get a vector mode bitfield store currently.
174 (define_expand "vec_setv2sf"
175 [(match_operand:V2SF 0 "register_operand")
176 (match_operand:SF 1 "register_operand")
177 (match_operand 2 "const_0_or_1_operand")]
178 "TARGET_PAIRED_SINGLE_FLOAT"
182 /* We don't have an insert instruction, so we duplicate the float, and
183 then use a PUL instruction. */
184 temp = gen_reg_rtx (V2SFmode);
185 emit_insn (gen_mips_cvt_ps_s (temp, operands[1], operands[1]));
186 if (INTVAL (operands[2]) == !BYTES_BIG_ENDIAN)
187 emit_insn (gen_mips_pul_ps (operands[0], temp, operands[0]));
189 emit_insn (gen_mips_pul_ps (operands[0], operands[0], temp));
193 ; cvt.ps.s - Floating Point Convert Pair to Paired Single
194 (define_expand "mips_cvt_ps_s"
195 [(match_operand:V2SF 0 "register_operand")
196 (match_operand:SF 1 "register_operand")
197 (match_operand:SF 2 "register_operand")]
198 "TARGET_PAIRED_SINGLE_FLOAT"
200 if (BYTES_BIG_ENDIAN)
201 emit_insn (gen_vec_initv2sf_internal (operands[0], operands[1],
204 emit_insn (gen_vec_initv2sf_internal (operands[0], operands[2],
209 ; cvt.s.pl - Floating Point Convert Pair Lower to Single Floating Point
210 (define_expand "mips_cvt_s_pl"
211 [(set (match_operand:SF 0 "register_operand")
212 (vec_select:SF (match_operand:V2SF 1 "register_operand")
213 (parallel [(match_dup 2)])))]
214 "TARGET_PAIRED_SINGLE_FLOAT"
215 { operands[2] = GEN_INT (BYTES_BIG_ENDIAN); })
217 ; cvt.s.pu - Floating Point Convert Pair Upper to Single Floating Point
218 (define_expand "mips_cvt_s_pu"
219 [(set (match_operand:SF 0 "register_operand")
220 (vec_select:SF (match_operand:V2SF 1 "register_operand")
221 (parallel [(match_dup 2)])))]
222 "TARGET_PAIRED_SINGLE_FLOAT"
223 { operands[2] = GEN_INT (!BYTES_BIG_ENDIAN); })
225 ; alnv.ps - Floating Point Align Variable
226 (define_insn "mips_alnv_ps"
227 [(set (match_operand:V2SF 0 "register_operand" "=f")
228 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
229 (match_operand:V2SF 2 "register_operand" "f")
230 (match_operand:SI 3 "register_operand" "d")]
232 "TARGET_PAIRED_SINGLE_FLOAT"
233 "alnv.ps\t%0,%1,%2,%3"
234 [(set_attr "type" "fmove")
235 (set_attr "mode" "SF")])
237 ; addr.ps - Floating Point Reduction Add
238 (define_insn "mips_addr_ps"
239 [(set (match_operand:V2SF 0 "register_operand" "=f")
240 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
241 (match_operand:V2SF 2 "register_operand" "f")]
245 [(set_attr "type" "fadd")
246 (set_attr "mode" "SF")])
248 ; cvt.pw.ps - Floating Point Convert Paired Single to Paired Word
249 (define_insn "mips_cvt_pw_ps"
250 [(set (match_operand:V2SF 0 "register_operand" "=f")
251 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
255 [(set_attr "type" "fcvt")
256 (set_attr "mode" "SF")])
258 ; cvt.ps.pw - Floating Point Convert Paired Word to Paired Single
259 (define_insn "mips_cvt_ps_pw"
260 [(set (match_operand:V2SF 0 "register_operand" "=f")
261 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
265 [(set_attr "type" "fcvt")
266 (set_attr "mode" "SF")])
268 ; mulr.ps - Floating Point Reduction Multiply
269 (define_insn "mips_mulr_ps"
270 [(set (match_operand:V2SF 0 "register_operand" "=f")
271 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
272 (match_operand:V2SF 2 "register_operand" "f")]
276 [(set_attr "type" "fmul")
277 (set_attr "mode" "SF")])
279 ;----------------------------------------------------------------------------
280 ; Floating Point Comparisons for Scalars
281 ;----------------------------------------------------------------------------
283 (define_insn "mips_cabs_cond_<fmt>"
284 [(set (match_operand:CC 0 "register_operand" "=z")
285 (unspec:CC [(match_operand:SCALARF 1 "register_operand" "f")
286 (match_operand:SCALARF 2 "register_operand" "f")
287 (match_operand 3 "const_int_operand" "")]
290 "cabs.%Y3.<fmt>\t%0,%1,%2"
291 [(set_attr "type" "fcmp")
292 (set_attr "mode" "FPSW")])
295 ;----------------------------------------------------------------------------
296 ; Floating Point Comparisons for Four Singles
297 ;----------------------------------------------------------------------------
299 (define_insn_and_split "mips_c_cond_4s"
300 [(set (match_operand:CCV4 0 "register_operand" "=z")
301 (unspec:CCV4 [(match_operand:V2SF 1 "register_operand" "f")
302 (match_operand:V2SF 2 "register_operand" "f")
303 (match_operand:V2SF 3 "register_operand" "f")
304 (match_operand:V2SF 4 "register_operand" "f")
305 (match_operand 5 "const_int_operand" "")]
307 "TARGET_PAIRED_SINGLE_FLOAT"
309 "&& reload_completed"
311 (unspec:CCV2 [(match_dup 1)
316 (unspec:CCV2 [(match_dup 3)
321 operands[6] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 0);
322 operands[7] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 8);
324 [(set_attr "type" "fcmp")
325 (set_attr "length" "8")
326 (set_attr "mode" "FPSW")])
328 (define_insn_and_split "mips_cabs_cond_4s"
329 [(set (match_operand:CCV4 0 "register_operand" "=z")
330 (unspec:CCV4 [(match_operand:V2SF 1 "register_operand" "f")
331 (match_operand:V2SF 2 "register_operand" "f")
332 (match_operand:V2SF 3 "register_operand" "f")
333 (match_operand:V2SF 4 "register_operand" "f")
334 (match_operand 5 "const_int_operand" "")]
338 "&& reload_completed"
340 (unspec:CCV2 [(match_dup 1)
345 (unspec:CCV2 [(match_dup 3)
350 operands[6] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 0);
351 operands[7] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 8);
353 [(set_attr "type" "fcmp")
354 (set_attr "length" "8")
355 (set_attr "mode" "FPSW")])
358 ;----------------------------------------------------------------------------
359 ; Floating Point Comparisons for Paired Singles
360 ;----------------------------------------------------------------------------
362 (define_insn "mips_c_cond_ps"
363 [(set (match_operand:CCV2 0 "register_operand" "=z")
364 (unspec:CCV2 [(match_operand:V2SF 1 "register_operand" "f")
365 (match_operand:V2SF 2 "register_operand" "f")
366 (match_operand 3 "const_int_operand" "")]
368 "TARGET_PAIRED_SINGLE_FLOAT"
370 [(set_attr "type" "fcmp")
371 (set_attr "mode" "FPSW")])
373 (define_insn "mips_cabs_cond_ps"
374 [(set (match_operand:CCV2 0 "register_operand" "=z")
375 (unspec:CCV2 [(match_operand:V2SF 1 "register_operand" "f")
376 (match_operand:V2SF 2 "register_operand" "f")
377 (match_operand 3 "const_int_operand" "")]
380 "cabs.%Y3.ps\t%0,%1,%2"
381 [(set_attr "type" "fcmp")
382 (set_attr "mode" "FPSW")])
385 ;----------------------------------------------------------------------------
386 ; Floating Point Branch Instructions.
387 ;----------------------------------------------------------------------------
389 ; Branch on Any of Four Floating Point Condition Codes True
390 (define_insn "bc1any4t"
392 (if_then_else (ne:CCV4 (match_operand:CCV4 0 "register_operand" "z")
394 (label_ref (match_operand 1 "" ""))
397 "%*bc1any4t\t%0,%1%/"
398 [(set_attr "type" "branch")
399 (set_attr "mode" "none")])
401 ; Branch on Any of Four Floating Point Condition Codes False
402 (define_insn "bc1any4f"
404 (if_then_else (ne:CCV4 (match_operand:CCV4 0 "register_operand" "z")
406 (label_ref (match_operand 1 "" ""))
409 "%*bc1any4f\t%0,%1%/"
410 [(set_attr "type" "branch")
411 (set_attr "mode" "none")])
413 ; Branch on Any of Two Floating Point Condition Codes True
414 (define_insn "bc1any2t"
416 (if_then_else (ne:CCV2 (match_operand:CCV2 0 "register_operand" "z")
418 (label_ref (match_operand 1 "" ""))
421 "%*bc1any2t\t%0,%1%/"
422 [(set_attr "type" "branch")
423 (set_attr "mode" "none")])
425 ; Branch on Any of Two Floating Point Condition Codes False
426 (define_insn "bc1any2f"
428 (if_then_else (ne:CCV2 (match_operand:CCV2 0 "register_operand" "z")
430 (label_ref (match_operand 1 "" ""))
433 "%*bc1any2f\t%0,%1%/"
434 [(set_attr "type" "branch")
435 (set_attr "mode" "none")])
437 ;----------------------------------------------------------------------------
438 ; Floating Point Reduced Precision Reciprocal Square Root Instructions.
439 ;----------------------------------------------------------------------------
441 (define_insn "mips_rsqrt1_<fmt>"
442 [(set (match_operand:ANYF 0 "register_operand" "=f")
443 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
446 "rsqrt1.<fmt>\t%0,%1"
447 [(set_attr "type" "frsqrt1")
448 (set_attr "mode" "<UNITMODE>")])
450 (define_insn "mips_rsqrt2_<fmt>"
451 [(set (match_operand:ANYF 0 "register_operand" "=f")
452 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
453 (match_operand:ANYF 2 "register_operand" "f")]
456 "rsqrt2.<fmt>\t%0,%1,%2"
457 [(set_attr "type" "frsqrt2")
458 (set_attr "mode" "<UNITMODE>")])
460 (define_insn "mips_recip1_<fmt>"
461 [(set (match_operand:ANYF 0 "register_operand" "=f")
462 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
465 "recip1.<fmt>\t%0,%1"
466 [(set_attr "type" "frdiv1")
467 (set_attr "mode" "<UNITMODE>")])
469 (define_insn "mips_recip2_<fmt>"
470 [(set (match_operand:ANYF 0 "register_operand" "=f")
471 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
472 (match_operand:ANYF 2 "register_operand" "f")]
475 "recip2.<fmt>\t%0,%1,%2"
476 [(set_attr "type" "frdiv2")
477 (set_attr "mode" "<UNITMODE>")])