1 ;; MIPS Paired-Single Floating and MIPS-3D Instructions.
2 ;; Copyright (C) 2004-2018 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 3, 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 COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
20 (define_c_enum "unspec" [
24 ;; MIPS64/MIPS32R2 alnv.ps
27 ;; MIPS-3D instructions
44 (define_insn "*movcc_v2sf_<mode>"
45 [(set (match_operand:V2SF 0 "register_operand" "=f,f")
47 (match_operator:GPR 4 "equality_operator"
48 [(match_operand:GPR 1 "register_operand" "d,d")
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"
56 [(set_attr "type" "condmove")
57 (set_attr "mode" "SF")])
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")]
65 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
69 [(set_attr "type" "condmove")
70 (set_attr "mode" "SF")])
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"
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. */
85 if (GET_MODE_CLASS (GET_MODE (XEXP (operands[1], 0))) != MODE_INT)
88 mips_expand_conditional_move (operands);
92 (define_insn "vec_perm_const_ps"
93 [(set (match_operand:V2SF 0 "register_operand" "=f")
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"
102 /* Let <op>L be the lower part of operand <op> and <op>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:
106 P<aUL><bUL>.PS %0,<aop>,<bop>
108 where 0U == <aop><aUL> and 0L == <bop><bUL>.
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 0 or 1) selects part of operand 1 and operand 4 (being 2 or 3)
115 selects part of operand 2.
119 I3 = INTVAL (operands[3])
120 I4 = INTVAL (operands[4]) - 2
122 Taking the two endiannesses in turn:
126 The semantics of the RTL pattern are:
128 { 0L, 0U } = { X[I3], X[I4 + 2] }, where X = { 1L, 1U, 2L, 2U }
130 so: 0L = { 1L, 1U }[I3] (= <bop><bUL>)
131 0U = { 2L, 2U }[I4] (= <aop><aUL>)
133 <aop> = 2, <aUL> = I4 ? U : L
134 <bop> = 1, <bUL> = I3 ? U : L
136 [LL] !I4 && !I3 [UL] I4 && !I3
137 [LU] !I4 && I3 [UU] I4 && I3
141 The semantics of the RTL pattern are:
143 { 0U, 0L } = { X[I3], X[I4 + 2] }, where X = { 1U, 1L, 2U, 2L }
145 so: 0U = { 1U, 1L }[I3] (= <aop><aUL>)
146 0L = { 2U, 2L }[I4] (= <bop><bUL>)
148 <aop> = 1, <aUL> = I3 ? L : U
149 <bop> = 2, <bUL> = I4 ? L : U
151 [UU] !I3 && !I4 [UL] !I3 && I4
152 [LU] I3 && !I4 [LL] I3 && I4. */
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" },
161 unsigned mask = INTVAL (operands[3]) * 2 + (INTVAL (operands[4]) - 2);
162 return mnemonics[BYTES_BIG_ENDIAN][mask];
164 [(set_attr "type" "fmove")
165 (set_attr "mode" "SF")])
167 ;; Expanders for builtins. The instruction:
169 ;; P[UL][UL].PS <result>, <a>, <b>
171 ;; says that the upper part of <result> is taken from half of <a> and
172 ;; the lower part of <result> is taken from half of <b>. This means
173 ;; that the P[UL][UL].PS operand order matches memory order on big-endian
174 ;; targets; <a> is element 0 of the V2SF result while <b> is element 1.
175 ;; However, the P[UL][UL].PS operand order is the reverse of memory order
176 ;; on little-endian targets; <a> is element 1 of the V2SF result while
177 ;; <b> is element 0. The arguments to vec_perm_const_ps are always in
180 ;; Similarly, "U" corresponds to element 0 on big-endian targets but
181 ;; to element 1 on little-endian targets.
183 (define_expand "mips_puu_ps"
184 [(match_operand:V2SF 0 "register_operand" "")
185 (match_operand:V2SF 1 "register_operand" "")
186 (match_operand:V2SF 2 "register_operand" "")]
187 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
189 if (BYTES_BIG_ENDIAN)
190 emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
191 const0_rtx, const2_rtx));
193 emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
194 const1_rtx, GEN_INT (3)));
198 (define_expand "mips_pul_ps"
199 [(match_operand:V2SF 0 "register_operand" "")
200 (match_operand:V2SF 1 "register_operand" "")
201 (match_operand:V2SF 2 "register_operand" "")]
202 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
204 if (BYTES_BIG_ENDIAN)
205 emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
206 const0_rtx, GEN_INT (3)));
208 emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
209 const0_rtx, GEN_INT (3)));
213 (define_expand "mips_plu_ps"
214 [(match_operand:V2SF 0 "register_operand" "")
215 (match_operand:V2SF 1 "register_operand" "")
216 (match_operand:V2SF 2 "register_operand" "")]
217 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
219 if (BYTES_BIG_ENDIAN)
220 emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
221 const1_rtx, const2_rtx));
223 emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
224 const1_rtx, const2_rtx));
228 (define_expand "mips_pll_ps"
229 [(match_operand:V2SF 0 "register_operand" "")
230 (match_operand:V2SF 1 "register_operand" "")
231 (match_operand:V2SF 2 "register_operand" "")]
232 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
234 if (BYTES_BIG_ENDIAN)
235 emit_insn (gen_vec_perm_const_ps (operands[0], operands[1], operands[2],
236 const1_rtx, GEN_INT (3)));
238 emit_insn (gen_vec_perm_const_ps (operands[0], operands[2], operands[1],
239 const0_rtx, const2_rtx));
244 (define_expand "vec_initv2sfsf"
245 [(match_operand:V2SF 0 "register_operand")
246 (match_operand:V2SF 1 "")]
247 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
249 mips_expand_vector_init (operands[0], operands[1]);
253 (define_insn "vec_concatv2sf"
254 [(set (match_operand:V2SF 0 "register_operand" "=f")
256 (match_operand:SF 1 "register_operand" "f")
257 (match_operand:SF 2 "register_operand" "f")))]
258 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
260 if (BYTES_BIG_ENDIAN)
261 return "cvt.ps.s\t%0,%1,%2";
263 return "cvt.ps.s\t%0,%2,%1";
265 [(set_attr "type" "fcvt")
266 (set_attr "mode" "SF")])
268 ;; ??? This is only generated if we perform a vector operation that has to be
269 ;; emulated. There is no other way to get a vector mode bitfield extract
272 (define_insn "vec_extractv2sfsf"
273 [(set (match_operand:SF 0 "register_operand" "=f")
274 (vec_select:SF (match_operand:V2SF 1 "register_operand" "f")
276 [(match_operand 2 "const_0_or_1_operand" "")])))]
277 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
279 if (INTVAL (operands[2]) == !BYTES_BIG_ENDIAN)
280 return "cvt.s.pu\t%0,%1";
282 return "cvt.s.pl\t%0,%1";
284 [(set_attr "type" "fcvt")
285 (set_attr "mode" "SF")])
287 ;; ??? This is only generated if we disable the vec_init pattern. There is
288 ;; no other way to get a vector mode bitfield store currently.
290 (define_expand "vec_setv2sf"
291 [(set (match_operand:V2SF 0 "register_operand" "")
294 (match_operand:SF 1 "register_operand" "")
296 (parallel [(match_operand 2 "const_0_or_1_operand" "")
298 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
300 /* We don't have an insert instruction, so we duplicate the float, and
301 then use a PUL instruction. */
302 rtx temp = gen_reg_rtx (V2SFmode);
303 emit_insn (gen_vec_concatv2sf (temp, operands[1], operands[1]));
305 operands[3] = GEN_INT (1 - INTVAL (operands[2]) + 2);
308 ; cvt.ps.s - Floating Point Convert Pair to Paired Single
309 (define_expand "mips_cvt_ps_s"
310 [(match_operand:V2SF 0 "register_operand")
311 (match_operand:SF 1 "register_operand")
312 (match_operand:SF 2 "register_operand")]
313 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
315 if (BYTES_BIG_ENDIAN)
316 emit_insn (gen_vec_concatv2sf (operands[0], operands[1], operands[2]));
318 emit_insn (gen_vec_concatv2sf (operands[0], operands[2], operands[1]));
322 ; cvt.s.pl - Floating Point Convert Pair Lower to Single Floating Point
323 (define_expand "mips_cvt_s_pl"
324 [(set (match_operand:SF 0 "register_operand")
325 (vec_select:SF (match_operand:V2SF 1 "register_operand")
326 (parallel [(match_dup 2)])))]
327 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
328 { operands[2] = GEN_INT (BYTES_BIG_ENDIAN); })
330 ; cvt.s.pu - Floating Point Convert Pair Upper to Single Floating Point
331 (define_expand "mips_cvt_s_pu"
332 [(set (match_operand:SF 0 "register_operand")
333 (vec_select:SF (match_operand:V2SF 1 "register_operand")
334 (parallel [(match_dup 2)])))]
335 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
336 { operands[2] = GEN_INT (!BYTES_BIG_ENDIAN); })
338 ; alnv.ps - Floating Point Align Variable
339 (define_insn "mips_alnv_ps"
340 [(set (match_operand:V2SF 0 "register_operand" "=f")
341 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
342 (match_operand:V2SF 2 "register_operand" "f")
343 (match_operand:SI 3 "register_operand" "d")]
345 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
346 "alnv.ps\t%0,%1,%2,%3"
347 [(set_attr "type" "fmove")
348 (set_attr "mode" "SF")])
350 ; addr.ps - Floating Point Reduction Add
351 (define_insn "mips_addr_ps"
352 [(set (match_operand:V2SF 0 "register_operand" "=f")
353 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
354 (match_operand:V2SF 2 "register_operand" "f")]
356 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
358 [(set_attr "type" "fadd")
359 (set_attr "mode" "SF")])
361 (define_expand "reduc_plus_scal_v2sf"
362 [(match_operand:SF 0 "register_operand" "=f")
363 (match_operand:V2SF 1 "register_operand" "f")]
364 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
366 rtx temp = gen_reg_rtx (V2SFmode);
367 emit_insn (gen_mips_addr_ps (temp, operands[1], operands[1]));
368 rtx lane = BYTES_BIG_ENDIAN ? const1_rtx : const0_rtx;
369 emit_insn (gen_vec_extractv2sfsf (operands[0], temp, lane));
373 ; cvt.pw.ps - Floating Point Convert Paired Single to Paired Word
374 (define_insn "mips_cvt_pw_ps"
375 [(set (match_operand:V2SF 0 "register_operand" "=f")
376 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
378 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
380 [(set_attr "type" "fcvt")
381 (set_attr "mode" "SF")])
383 ; cvt.ps.pw - Floating Point Convert Paired Word to Paired Single
384 (define_insn "mips_cvt_ps_pw"
385 [(set (match_operand:V2SF 0 "register_operand" "=f")
386 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
388 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
390 [(set_attr "type" "fcvt")
391 (set_attr "mode" "SF")])
393 ; mulr.ps - Floating Point Reduction Multiply
394 (define_insn "mips_mulr_ps"
395 [(set (match_operand:V2SF 0 "register_operand" "=f")
396 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")
397 (match_operand:V2SF 2 "register_operand" "f")]
399 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
401 [(set_attr "type" "fmul")
402 (set_attr "mode" "SF")])
405 (define_expand "mips_abs_ps"
406 [(set (match_operand:V2SF 0 "register_operand")
407 (unspec:V2SF [(match_operand:V2SF 1 "register_operand")]
409 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
411 /* If we can ignore NaNs, this operation is equivalent to the
413 if (!HONOR_NANS (V2SFmode))
415 emit_insn (gen_absv2sf2 (operands[0], operands[1]));
420 (define_insn "*mips_abs_ps"
421 [(set (match_operand:V2SF 0 "register_operand" "=f")
422 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f")]
424 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
426 [(set_attr "type" "fabs")
427 (set_attr "mode" "SF")])
429 ;----------------------------------------------------------------------------
430 ; Floating Point Comparisons for Scalars
431 ;----------------------------------------------------------------------------
433 (define_insn "mips_cabs_cond_<fmt>"
434 [(set (match_operand:CC 0 "register_operand" "=z")
435 (unspec:CC [(match_operand:SCALARF 1 "register_operand" "f")
436 (match_operand:SCALARF 2 "register_operand" "f")
437 (match_operand 3 "const_int_operand" "")]
439 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
440 "cabs.%Y3.<fmt>\t%0,%1,%2"
441 [(set_attr "type" "fcmp")
442 (set_attr "mode" "FPSW")])
445 ;----------------------------------------------------------------------------
446 ; Floating Point Comparisons for Four Singles
447 ;----------------------------------------------------------------------------
449 (define_insn_and_split "mips_c_cond_4s"
450 [(set (match_operand:CCV4 0 "register_operand" "=z")
451 (unspec:CCV4 [(match_operand:V2SF 1 "register_operand" "f")
452 (match_operand:V2SF 2 "register_operand" "f")
453 (match_operand:V2SF 3 "register_operand" "f")
454 (match_operand:V2SF 4 "register_operand" "f")
455 (match_operand 5 "const_int_operand" "")]
457 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
459 "&& reload_completed"
461 (unspec:CCV2 [(match_dup 1)
466 (unspec:CCV2 [(match_dup 3)
471 operands[6] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 0);
472 operands[7] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 8);
474 [(set_attr "type" "fcmp")
475 (set_attr "insn_count" "2")
476 (set_attr "mode" "FPSW")])
478 (define_insn_and_split "mips_cabs_cond_4s"
479 [(set (match_operand:CCV4 0 "register_operand" "=z")
480 (unspec:CCV4 [(match_operand:V2SF 1 "register_operand" "f")
481 (match_operand:V2SF 2 "register_operand" "f")
482 (match_operand:V2SF 3 "register_operand" "f")
483 (match_operand:V2SF 4 "register_operand" "f")
484 (match_operand 5 "const_int_operand" "")]
486 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
488 "&& reload_completed"
490 (unspec:CCV2 [(match_dup 1)
495 (unspec:CCV2 [(match_dup 3)
500 operands[6] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 0);
501 operands[7] = simplify_gen_subreg (CCV2mode, operands[0], CCV4mode, 8);
503 [(set_attr "type" "fcmp")
504 (set_attr "insn_count" "2")
505 (set_attr "mode" "FPSW")])
508 ;----------------------------------------------------------------------------
509 ; Floating Point Comparisons for Paired Singles
510 ;----------------------------------------------------------------------------
512 (define_insn "mips_c_cond_ps"
513 [(set (match_operand:CCV2 0 "register_operand" "=z")
514 (unspec:CCV2 [(match_operand:V2SF 1 "register_operand" "f")
515 (match_operand:V2SF 2 "register_operand" "f")
516 (match_operand 3 "const_int_operand" "")]
518 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
520 [(set_attr "type" "fcmp")
521 (set_attr "mode" "FPSW")])
523 (define_insn "mips_cabs_cond_ps"
524 [(set (match_operand:CCV2 0 "register_operand" "=z")
525 (unspec:CCV2 [(match_operand:V2SF 1 "register_operand" "f")
526 (match_operand:V2SF 2 "register_operand" "f")
527 (match_operand 3 "const_int_operand" "")]
529 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
530 "cabs.%Y3.ps\t%0,%1,%2"
531 [(set_attr "type" "fcmp")
532 (set_attr "mode" "FPSW")])
534 ;; An expander for generating an scc operation.
535 (define_expand "scc_ps"
536 [(set (match_operand:CCV2 0)
537 (unspec:CCV2 [(match_operand 1)] UNSPEC_SCC))])
539 (define_insn "s<code>_ps"
540 [(set (match_operand:CCV2 0 "register_operand" "=z")
542 [(fcond (match_operand:V2SF 1 "register_operand" "f")
543 (match_operand:V2SF 2 "register_operand" "f"))]
545 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
546 "c.<fcond>.ps\t%0,%1,%2"
547 [(set_attr "type" "fcmp")
548 (set_attr "mode" "FPSW")])
550 (define_insn "s<code>_ps"
551 [(set (match_operand:CCV2 0 "register_operand" "=z")
553 [(swapped_fcond (match_operand:V2SF 1 "register_operand" "f")
554 (match_operand:V2SF 2 "register_operand" "f"))]
556 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
557 "c.<swapped_fcond>.ps\t%0,%2,%1"
558 [(set_attr "type" "fcmp")
559 (set_attr "mode" "FPSW")])
561 ;----------------------------------------------------------------------------
562 ; Floating Point Branch Instructions.
563 ;----------------------------------------------------------------------------
565 ; Branch on Any of Four Floating Point Condition Codes True
566 (define_insn "bc1any4t"
568 (if_then_else (ne (match_operand:CCV4 1 "register_operand" "z")
570 (label_ref (match_operand 0 "" ""))
572 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
573 "%*bc1any4t\t%1,%0%/"
574 [(set_attr "type" "branch")])
576 ; Branch on Any of Four Floating Point Condition Codes False
577 (define_insn "bc1any4f"
579 (if_then_else (ne (match_operand:CCV4 1 "register_operand" "z")
581 (label_ref (match_operand 0 "" ""))
583 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
584 "%*bc1any4f\t%1,%0%/"
585 [(set_attr "type" "branch")])
587 ; Branch on Any of Two Floating Point Condition Codes True
588 (define_insn "bc1any2t"
590 (if_then_else (ne (match_operand:CCV2 1 "register_operand" "z")
592 (label_ref (match_operand 0 "" ""))
594 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
595 "%*bc1any2t\t%1,%0%/"
596 [(set_attr "type" "branch")])
598 ; Branch on Any of Two Floating Point Condition Codes False
599 (define_insn "bc1any2f"
601 (if_then_else (ne (match_operand:CCV2 1 "register_operand" "z")
603 (label_ref (match_operand 0 "" ""))
605 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
606 "%*bc1any2f\t%1,%0%/"
607 [(set_attr "type" "branch")])
609 ; Used to access one register in a CCV2 pair. Operand 0 is the register
610 ; pair and operand 1 is the index of the register we want (a CONST_INT).
611 (define_expand "single_cc"
612 [(ne (unspec:CC [(match_operand 0) (match_operand 1)] UNSPEC_SINGLE_CC)
615 ; This is a normal floating-point branch pattern, but rather than check
616 ; a single CCmode register, it checks one register in a CCV2 pair.
617 ; Operand 2 is the register pair and operand 3 is the index of the
619 (define_insn "*branch_upper_lower"
622 (match_operator 1 "equality_operator"
623 [(unspec:CC [(match_operand:CCV2 2 "register_operand" "z")
624 (match_operand 3 "const_int_operand")]
627 (label_ref (match_operand 0 "" ""))
632 = gen_rtx_REG (CCmode, REGNO (operands[2]) + INTVAL (operands[3]));
633 return mips_output_conditional_branch (insn, operands,
634 MIPS_BRANCH ("b%F1", "%2,%0"),
635 MIPS_BRANCH ("b%W1", "%2,%0"));
637 [(set_attr "type" "branch")])
639 ; As above, but with the sense of the condition reversed.
640 (define_insn "*branch_upper_lower_inverted"
643 (match_operator 1 "equality_operator"
644 [(unspec:CC [(match_operand:CCV2 2 "register_operand" "z")
645 (match_operand 3 "const_int_operand")]
649 (label_ref (match_operand 0 "" ""))))]
653 = gen_rtx_REG (CCmode, REGNO (operands[2]) + INTVAL (operands[3]));
654 return mips_output_conditional_branch (insn, operands,
655 MIPS_BRANCH ("b%W1", "%2,%0"),
656 MIPS_BRANCH ("b%F1", "%2,%0"));
658 [(set_attr "type" "branch")])
660 ;----------------------------------------------------------------------------
661 ; Floating Point Reduced Precision Reciprocal Square Root Instructions.
662 ;----------------------------------------------------------------------------
664 (define_insn "mips_rsqrt1_<fmt>"
665 [(set (match_operand:ANYF 0 "register_operand" "=f")
666 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
668 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
669 "rsqrt1.<fmt>\t%0,%1"
670 [(set_attr "type" "frsqrt1")
671 (set_attr "mode" "<UNITMODE>")])
673 (define_insn "mips_rsqrt2_<fmt>"
674 [(set (match_operand:ANYF 0 "register_operand" "=f")
675 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
676 (match_operand:ANYF 2 "register_operand" "f")]
678 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
679 "rsqrt2.<fmt>\t%0,%1,%2"
680 [(set_attr "type" "frsqrt2")
681 (set_attr "mode" "<UNITMODE>")])
683 (define_insn "mips_recip1_<fmt>"
684 [(set (match_operand:ANYF 0 "register_operand" "=f")
685 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
687 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
688 "recip1.<fmt>\t%0,%1"
689 [(set_attr "type" "frdiv1")
690 (set_attr "mode" "<UNITMODE>")])
692 (define_insn "mips_recip2_<fmt>"
693 [(set (match_operand:ANYF 0 "register_operand" "=f")
694 (unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
695 (match_operand:ANYF 2 "register_operand" "f")]
697 "TARGET_HARD_FLOAT && TARGET_MIPS3D"
698 "recip2.<fmt>\t%0,%1,%2"
699 [(set_attr "type" "frdiv2")
700 (set_attr "mode" "<UNITMODE>")])
702 (define_expand "vcondv2sfv2sf"
703 [(set (match_operand:V2SF 0 "register_operand")
706 [(match_operand:V2SF 4 "register_operand")
707 (match_operand:V2SF 5 "register_operand")])
708 (match_operand:V2SF 1 "register_operand")
709 (match_operand:V2SF 2 "register_operand")))]
710 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
712 mips_expand_vcondv2sf (operands[0], operands[1], operands[2],
713 GET_CODE (operands[3]), operands[4], operands[5]);
717 (define_expand "sminv2sf3"
718 [(set (match_operand:V2SF 0 "register_operand")
719 (smin:V2SF (match_operand:V2SF 1 "register_operand")
720 (match_operand:V2SF 2 "register_operand")))]
721 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
723 mips_expand_vcondv2sf (operands[0], operands[1], operands[2],
724 LE, operands[1], operands[2]);
728 (define_expand "smaxv2sf3"
729 [(set (match_operand:V2SF 0 "register_operand")
730 (smax:V2SF (match_operand:V2SF 1 "register_operand")
731 (match_operand:V2SF 2 "register_operand")))]
732 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
734 mips_expand_vcondv2sf (operands[0], operands[1], operands[2],
735 LE, operands[2], operands[1]);
739 (define_expand "reduc_smin_scal_v2sf"
740 [(match_operand:SF 0 "register_operand")
741 (match_operand:V2SF 1 "register_operand")]
742 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
744 rtx temp = gen_reg_rtx (V2SFmode);
745 mips_expand_vec_reduc (temp, operands[1], gen_sminv2sf3);
746 rtx lane = BYTES_BIG_ENDIAN ? const1_rtx : const0_rtx;
747 emit_insn (gen_vec_extractv2sfsf (operands[0], temp, lane));
751 (define_expand "reduc_smax_scal_v2sf"
752 [(match_operand:SF 0 "register_operand")
753 (match_operand:V2SF 1 "register_operand")]
754 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT"
756 rtx temp = gen_reg_rtx (V2SFmode);
757 mips_expand_vec_reduc (temp, operands[1], gen_smaxv2sf3);
758 rtx lane = BYTES_BIG_ENDIAN ? const1_rtx : const0_rtx;
759 emit_insn (gen_vec_extractv2sfsf (operands[0], temp, lane));