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