Branch data Line data Source code
1 : : /* Copyright (C) 1988-2024 Free Software Foundation, Inc.
2 : :
3 : : This file is part of GCC.
4 : :
5 : : GCC is free software; you can redistribute it and/or modify
6 : : it under the terms of the GNU General Public License as published by
7 : : the Free Software Foundation; either version 3, or (at your option)
8 : : any later version.
9 : :
10 : : GCC is distributed in the hope that it will be useful,
11 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : : GNU General Public License for more details.
14 : :
15 : : You should have received a copy of the GNU General Public License
16 : : along with GCC; see the file COPYING3. If not see
17 : : <http://www.gnu.org/licenses/>. */
18 : :
19 : : #define IN_TARGET_CODE 1
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "backend.h"
25 : : #include "rtl.h"
26 : : #include "tree.h"
27 : : #include "memmodel.h"
28 : : #include "gimple.h"
29 : : #include "cfghooks.h"
30 : : #include "cfgloop.h"
31 : : #include "df.h"
32 : : #include "tm_p.h"
33 : : #include "stringpool.h"
34 : : #include "expmed.h"
35 : : #include "optabs.h"
36 : : #include "regs.h"
37 : : #include "emit-rtl.h"
38 : : #include "recog.h"
39 : : #include "cgraph.h"
40 : : #include "diagnostic.h"
41 : : #include "cfgbuild.h"
42 : : #include "alias.h"
43 : : #include "fold-const.h"
44 : : #include "attribs.h"
45 : : #include "calls.h"
46 : : #include "stor-layout.h"
47 : : #include "varasm.h"
48 : : #include "output.h"
49 : : #include "insn-attr.h"
50 : : #include "flags.h"
51 : : #include "except.h"
52 : : #include "explow.h"
53 : : #include "expr.h"
54 : : #include "cfgrtl.h"
55 : : #include "common/common-target.h"
56 : : #include "langhooks.h"
57 : : #include "reload.h"
58 : : #include "gimplify.h"
59 : : #include "dwarf2.h"
60 : : #include "tm-constrs.h"
61 : : #include "cselib.h"
62 : : #include "sched-int.h"
63 : : #include "opts.h"
64 : : #include "tree-pass.h"
65 : : #include "context.h"
66 : : #include "pass_manager.h"
67 : : #include "target-globals.h"
68 : : #include "gimple-iterator.h"
69 : : #include "shrink-wrap.h"
70 : : #include "builtins.h"
71 : : #include "rtl-iter.h"
72 : : #include "tree-iterator.h"
73 : : #include "dbgcnt.h"
74 : : #include "case-cfn-macros.h"
75 : : #include "dojump.h"
76 : : #include "fold-const-call.h"
77 : : #include "tree-vrp.h"
78 : : #include "tree-ssanames.h"
79 : : #include "selftest.h"
80 : : #include "selftest-rtl.h"
81 : : #include "print-rtl.h"
82 : : #include "intl.h"
83 : : #include "ifcvt.h"
84 : : #include "symbol-summary.h"
85 : : #include "sreal.h"
86 : : #include "ipa-cp.h"
87 : : #include "ipa-prop.h"
88 : : #include "ipa-fnsummary.h"
89 : : #include "wide-int-bitmask.h"
90 : : #include "tree-vector-builder.h"
91 : : #include "debug.h"
92 : : #include "dwarf2out.h"
93 : : #include "i386-options.h"
94 : : #include "i386-builtins.h"
95 : : #include "i386-expand.h"
96 : : #include "asan.h"
97 : :
98 : : /* Split one or more double-mode RTL references into pairs of half-mode
99 : : references. The RTL can be REG, offsettable MEM, integer constant, or
100 : : CONST_DOUBLE. "operands" is a pointer to an array of double-mode RTLs to
101 : : split and "num" is its length. lo_half and hi_half are output arrays
102 : : that parallel "operands". */
103 : :
104 : : void
105 : 4059837 : split_double_mode (machine_mode mode, rtx operands[],
106 : : int num, rtx lo_half[], rtx hi_half[])
107 : : {
108 : 4059837 : machine_mode half_mode;
109 : 4059837 : unsigned int byte;
110 : 4059837 : rtx mem_op = NULL_RTX;
111 : 4059837 : int mem_num = 0;
112 : :
113 : 4059837 : switch (mode)
114 : : {
115 : : case E_TImode:
116 : : half_mode = DImode;
117 : : break;
118 : 583291 : case E_DImode:
119 : 583291 : half_mode = SImode;
120 : 583291 : break;
121 : 6 : case E_P2HImode:
122 : 6 : half_mode = HImode;
123 : 6 : break;
124 : 30 : case E_P2QImode:
125 : 30 : half_mode = QImode;
126 : 30 : break;
127 : 0 : default:
128 : 0 : gcc_unreachable ();
129 : : }
130 : :
131 : 4059837 : byte = GET_MODE_SIZE (half_mode);
132 : :
133 : 8305792 : while (num--)
134 : : {
135 : 4245955 : rtx op = operands[num];
136 : :
137 : : /* simplify_subreg refuse to split volatile memory addresses,
138 : : but we still have to handle it. */
139 : 4245955 : if (MEM_P (op))
140 : : {
141 : 1660651 : if (mem_op && rtx_equal_p (op, mem_op))
142 : : {
143 : 1872 : lo_half[num] = lo_half[mem_num];
144 : 1872 : hi_half[num] = hi_half[mem_num];
145 : : }
146 : : else
147 : : {
148 : 1658779 : mem_op = op;
149 : 1658779 : mem_num = num;
150 : 1658779 : lo_half[num] = adjust_address (op, half_mode, 0);
151 : 1658779 : hi_half[num] = adjust_address (op, half_mode, byte);
152 : : }
153 : : }
154 : : else
155 : : {
156 : 2585304 : lo_half[num] = simplify_gen_subreg (half_mode, op,
157 : 2585304 : GET_MODE (op) == VOIDmode
158 : 2585304 : ? mode : GET_MODE (op), 0);
159 : :
160 : 2585304 : rtx tmp = simplify_gen_subreg (half_mode, op,
161 : 2585304 : GET_MODE (op) == VOIDmode
162 : : ? mode : GET_MODE (op), byte);
163 : : /* simplify_gen_subreg will return NULL RTX for the
164 : : high half of the paradoxical subreg. */
165 : 2585304 : hi_half[num] = tmp ? tmp : gen_reg_rtx (half_mode);
166 : : }
167 : : }
168 : 4059837 : }
169 : :
170 : : /* Emit the double word assignment DST = { LO, HI }. */
171 : :
172 : : void
173 : 109611 : split_double_concat (machine_mode mode, rtx dst, rtx lo, rtx hi)
174 : : {
175 : 109611 : rtx dlo, dhi;
176 : 109611 : int deleted_move_count = 0;
177 : 109611 : split_double_mode (mode, &dst, 1, &dlo, &dhi);
178 : : /* Constraints ensure that if both lo and hi are MEMs, then
179 : : dst has early-clobber and thus addresses of MEMs don't use
180 : : dlo/dhi registers. Otherwise if at least one of li and hi are MEMs,
181 : : dlo/dhi are registers. */
182 : 109611 : if (MEM_P (lo)
183 : 7073 : && rtx_equal_p (dlo, hi)
184 : 110573 : && reg_overlap_mentioned_p (dhi, lo))
185 : : {
186 : : /* If dlo is same as hi and lo's address uses dhi register,
187 : : code below would first emit_move_insn (dhi, hi)
188 : : and then emit_move_insn (dlo, lo). But the former
189 : : would invalidate lo's address. Load into dhi first,
190 : : then swap. */
191 : 163 : emit_move_insn (dhi, lo);
192 : 163 : lo = dhi;
193 : : }
194 : 109448 : else if (MEM_P (hi)
195 : 12786 : && !MEM_P (lo)
196 : 8387 : && !rtx_equal_p (dlo, lo)
197 : 111861 : && reg_overlap_mentioned_p (dlo, hi))
198 : : {
199 : : /* In this case, code below would first emit_move_insn (dlo, lo)
200 : : and then emit_move_insn (dhi, hi). But the former would
201 : : invalidate hi's address. */
202 : 20 : if (rtx_equal_p (dhi, lo))
203 : : {
204 : : /* We can't load into dhi first, so load into dlo
205 : : first and we'll swap. */
206 : 6 : emit_move_insn (dlo, hi);
207 : 6 : hi = dlo;
208 : : }
209 : : else
210 : : {
211 : : /* Load into dhi first. */
212 : 14 : emit_move_insn (dhi, hi);
213 : 14 : hi = dhi;
214 : : }
215 : : }
216 : 109611 : if (!rtx_equal_p (dlo, hi))
217 : : {
218 : 95195 : if (!rtx_equal_p (dlo, lo))
219 : 41992 : emit_move_insn (dlo, lo);
220 : : else
221 : : deleted_move_count++;
222 : 95195 : if (!rtx_equal_p (dhi, hi))
223 : 87177 : emit_move_insn (dhi, hi);
224 : : else
225 : 8018 : deleted_move_count++;
226 : : }
227 : 14416 : else if (!rtx_equal_p (lo, dhi))
228 : : {
229 : 7433 : if (!rtx_equal_p (dhi, hi))
230 : 7433 : emit_move_insn (dhi, hi);
231 : : else
232 : : deleted_move_count++;
233 : 7433 : if (!rtx_equal_p (dlo, lo))
234 : 7331 : emit_move_insn (dlo, lo);
235 : : else
236 : 102 : deleted_move_count++;
237 : : }
238 : 6983 : else if (mode == TImode)
239 : 6964 : emit_insn (gen_swapdi (dlo, dhi));
240 : : else
241 : 19 : emit_insn (gen_swapsi (dlo, dhi));
242 : :
243 : 109611 : if (deleted_move_count == 2)
244 : 4574 : emit_note (NOTE_INSN_DELETED);
245 : 109611 : }
246 : :
247 : :
248 : : /* Generate either "mov $0, reg" or "xor reg, reg", as appropriate
249 : : for the target. */
250 : :
251 : : void
252 : 104339 : ix86_expand_clear (rtx dest)
253 : : {
254 : 104339 : rtx tmp;
255 : :
256 : : /* We play register width games, which are only valid after reload. */
257 : 104339 : gcc_assert (reload_completed);
258 : :
259 : : /* Avoid HImode and its attendant prefix byte. */
260 : 208678 : if (GET_MODE_SIZE (GET_MODE (dest)) < 4)
261 : 979 : dest = gen_rtx_REG (SImode, REGNO (dest));
262 : 104339 : tmp = gen_rtx_SET (dest, const0_rtx);
263 : :
264 : 104339 : if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
265 : : {
266 : 104339 : rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
267 : 104339 : tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
268 : : }
269 : :
270 : 104339 : emit_insn (tmp);
271 : 104339 : }
272 : :
273 : : /* Return true if V can be broadcasted from an integer of WIDTH bits
274 : : which is returned in VAL_BROADCAST. Otherwise, return false. */
275 : :
276 : : static bool
277 : 4624 : ix86_broadcast (HOST_WIDE_INT v, unsigned int width,
278 : : HOST_WIDE_INT &val_broadcast)
279 : : {
280 : 4624 : wide_int val = wi::uhwi (v, HOST_BITS_PER_WIDE_INT);
281 : 4624 : val_broadcast = wi::extract_uhwi (val, 0, width);
282 : 6142 : for (unsigned int i = width; i < HOST_BITS_PER_WIDE_INT; i += width)
283 : : {
284 : 4761 : HOST_WIDE_INT each = wi::extract_uhwi (val, i, width);
285 : 4761 : if (val_broadcast != each)
286 : : return false;
287 : : }
288 : 1381 : val_broadcast = sext_hwi (val_broadcast, width);
289 : 1381 : return true;
290 : 4624 : }
291 : :
292 : : /* Convert the CONST_WIDE_INT operand OP to broadcast in MODE. */
293 : :
294 : : rtx
295 : 35430 : ix86_convert_const_wide_int_to_broadcast (machine_mode mode, rtx op)
296 : : {
297 : : /* Don't use integer vector broadcast if we can't move from GPR to SSE
298 : : register directly. */
299 : 35430 : if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
300 : : return nullptr;
301 : :
302 : 35430 : unsigned int msize = GET_MODE_SIZE (mode);
303 : :
304 : : /* Only optimized for vpbroadcast[bwsd]/vbroadcastss with xmm/ymm/zmm. */
305 : 35430 : if (msize != 16 && msize != 32 && msize != 64)
306 : : return nullptr;
307 : :
308 : : /* Convert CONST_WIDE_INT to a non-standard SSE constant integer
309 : : broadcast only if vector broadcast is available. */
310 : 35430 : if (!TARGET_AVX
311 : 1535 : || !CONST_WIDE_INT_P (op)
312 : 1528 : || standard_sse_constant_p (op, mode)
313 : 36958 : || (CONST_WIDE_INT_NUNITS (op) * HOST_BITS_PER_WIDE_INT
314 : 1528 : != GET_MODE_BITSIZE (mode)))
315 : 33908 : return nullptr;
316 : :
317 : 1522 : HOST_WIDE_INT val = CONST_WIDE_INT_ELT (op, 0);
318 : 1522 : HOST_WIDE_INT val_broadcast;
319 : 1522 : scalar_int_mode broadcast_mode;
320 : : /* vpbroadcastb zmm requires TARGET_AVX512BW. */
321 : 667 : if ((msize == 64 ? TARGET_AVX512BW : TARGET_AVX2)
322 : 2614 : && ix86_broadcast (val, GET_MODE_BITSIZE (QImode),
323 : : val_broadcast))
324 : : broadcast_mode = QImode;
325 : 622 : else if ((msize == 64 ? TARGET_AVX512BW : TARGET_AVX2)
326 : 2514 : && ix86_broadcast (val, GET_MODE_BITSIZE (HImode),
327 : : val_broadcast))
328 : : broadcast_mode = HImode;
329 : : /* vbroadcasts[sd] only support memory operand w/o AVX2.
330 : : When msize == 16, pshufs is used for vec_duplicate.
331 : : when msize == 64, vpbroadcastd is used, and TARGET_AVX512F must be existed. */
332 : 380 : else if ((msize != 32 || TARGET_AVX2)
333 : 2733 : && ix86_broadcast (val, GET_MODE_BITSIZE (SImode),
334 : : val_broadcast))
335 : : broadcast_mode = SImode;
336 : 1335 : else if (TARGET_64BIT && (msize != 32 || TARGET_AVX2)
337 : 2529 : && ix86_broadcast (val, GET_MODE_BITSIZE (DImode),
338 : : val_broadcast))
339 : : broadcast_mode = DImode;
340 : : else
341 : 141 : return nullptr;
342 : :
343 : : /* Check if OP can be broadcasted from VAL. */
344 : 1703 : for (int i = 1; i < CONST_WIDE_INT_NUNITS (op); i++)
345 : 1488 : if (val != CONST_WIDE_INT_ELT (op, i))
346 : : return nullptr;
347 : :
348 : 215 : unsigned int nunits = (GET_MODE_SIZE (mode)
349 : 215 : / GET_MODE_SIZE (broadcast_mode));
350 : 215 : machine_mode vector_mode;
351 : 215 : if (!mode_for_vector (broadcast_mode, nunits).exists (&vector_mode))
352 : 0 : gcc_unreachable ();
353 : 215 : rtx target = gen_reg_rtx (vector_mode);
354 : 215 : bool ok = ix86_expand_vector_init_duplicate (false, vector_mode,
355 : : target,
356 : : GEN_INT (val_broadcast));
357 : 215 : if (!ok)
358 : : return nullptr;
359 : 215 : target = lowpart_subreg (mode, target, vector_mode);
360 : 215 : return target;
361 : : }
362 : :
363 : : void
364 : 71049298 : ix86_expand_move (machine_mode mode, rtx operands[])
365 : : {
366 : 71049298 : rtx op0, op1;
367 : 71049298 : rtx tmp, addend = NULL_RTX;
368 : 71049298 : enum tls_model model;
369 : :
370 : 71049298 : op0 = operands[0];
371 : 71049298 : op1 = operands[1];
372 : :
373 : : /* Avoid complex sets of likely spilled hard registers before reload. */
374 : 71049298 : if (!ix86_hardreg_mov_ok (op0, op1))
375 : : {
376 : 136651 : tmp = gen_reg_rtx (mode);
377 : 136651 : operands[0] = tmp;
378 : 136651 : ix86_expand_move (mode, operands);
379 : 136651 : operands[0] = op0;
380 : 136651 : operands[1] = tmp;
381 : 136651 : op1 = tmp;
382 : : }
383 : :
384 : 71049298 : switch (GET_CODE (op1))
385 : : {
386 : 345612 : case CONST:
387 : 345612 : tmp = XEXP (op1, 0);
388 : :
389 : 345612 : if (GET_CODE (tmp) != PLUS
390 : 333943 : || GET_CODE (XEXP (tmp, 0)) != SYMBOL_REF)
391 : : break;
392 : :
393 : 331334 : op1 = XEXP (tmp, 0);
394 : 331334 : addend = XEXP (tmp, 1);
395 : : /* FALLTHRU */
396 : :
397 : 4731927 : case SYMBOL_REF:
398 : 4731927 : model = SYMBOL_REF_TLS_MODEL (op1);
399 : :
400 : 4731927 : if (model)
401 : 9613 : op1 = legitimize_tls_address (op1, model, true);
402 : 4722314 : else if (ix86_force_load_from_GOT_p (op1))
403 : : {
404 : : /* Load the external function address via GOT slot to avoid PLT. */
405 : 12 : op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),
406 : : (TARGET_64BIT
407 : : ? UNSPEC_GOTPCREL
408 : : : UNSPEC_GOT));
409 : 12 : op1 = gen_rtx_CONST (Pmode, op1);
410 : 12 : op1 = gen_const_mem (Pmode, op1);
411 : 12 : set_mem_alias_set (op1, GOT_ALIAS_SET);
412 : : }
413 : : else
414 : : {
415 : : #if TARGET_PECOFF
416 : : tmp = legitimize_pe_coff_symbol (op1, addend != NULL_RTX);
417 : :
418 : : if (tmp)
419 : : {
420 : : op1 = tmp;
421 : : if (!addend)
422 : : break;
423 : : }
424 : : else
425 : : #endif
426 : 4722302 : {
427 : 4722302 : op1 = operands[1];
428 : 4722302 : break;
429 : : }
430 : : }
431 : :
432 : 9625 : if (addend)
433 : : {
434 : 2787 : op1 = force_operand (op1, NULL_RTX);
435 : 2796 : op1 = expand_simple_binop (Pmode, PLUS, op1, addend,
436 : : op0, 1, OPTAB_DIRECT);
437 : : }
438 : : else
439 : 6838 : op1 = force_operand (op1, op0);
440 : :
441 : 9625 : if (op1 == op0)
442 : : return;
443 : :
444 : 4521 : op1 = convert_to_mode (mode, op1, 1);
445 : :
446 : : default:
447 : : break;
448 : :
449 : 1599607 : case SUBREG:
450 : : /* Transform TImode paradoxical SUBREG into zero_extendditi2. */
451 : 1599607 : if (TARGET_64BIT
452 : 1351484 : && mode == TImode
453 : : && SUBREG_P (op1)
454 : 71943 : && GET_MODE (SUBREG_REG (op1)) == DImode
455 : 1642855 : && SUBREG_BYTE (op1) == 0)
456 : 43248 : op1 = gen_rtx_ZERO_EXTEND (TImode, SUBREG_REG (op1));
457 : : /* As not all values in XFmode are representable in real_value,
458 : : we might be called with unfoldable SUBREGs of constants. */
459 : 1599607 : if (mode == XFmode
460 : 2523 : && CONSTANT_P (SUBREG_REG (op1))
461 : 2 : && can_create_pseudo_p ())
462 : : {
463 : 2 : machine_mode imode = GET_MODE (SUBREG_REG (op1));
464 : 2 : rtx r = force_const_mem (imode, SUBREG_REG (op1));
465 : 2 : if (r)
466 : 2 : r = validize_mem (r);
467 : : else
468 : 0 : r = force_reg (imode, SUBREG_REG (op1));
469 : 2 : op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
470 : : }
471 : : break;
472 : : }
473 : :
474 : 71044194 : if ((flag_pic || MACHOPIC_INDIRECT)
475 : 71044194 : && symbolic_operand (op1, mode))
476 : : {
477 : : #if TARGET_MACHO
478 : : if (TARGET_MACHO && !TARGET_64BIT)
479 : : {
480 : : /* dynamic-no-pic */
481 : : if (MACHOPIC_INDIRECT)
482 : : {
483 : : tmp = (op0 && REG_P (op0) && mode == Pmode)
484 : : ? op0 : gen_reg_rtx (Pmode);
485 : : op1 = machopic_indirect_data_reference (op1, tmp);
486 : : if (MACHOPIC_PURE)
487 : : op1 = machopic_legitimize_pic_address (op1, mode,
488 : : tmp == op1 ? 0 : tmp);
489 : : }
490 : : if (op0 != op1 && GET_CODE (op0) != MEM)
491 : : {
492 : : rtx insn = gen_rtx_SET (op0, op1);
493 : : emit_insn (insn);
494 : : return;
495 : : }
496 : : }
497 : : #endif
498 : :
499 : 331528 : if (MEM_P (op0))
500 : 87324 : op1 = force_reg (mode, op1);
501 : 244204 : else if (!(TARGET_64BIT && x86_64_movabs_operand (op1, DImode)))
502 : : {
503 : 244166 : rtx reg = can_create_pseudo_p () ? NULL_RTX : op0;
504 : 244166 : op1 = legitimize_pic_address (op1, reg);
505 : 244166 : if (op0 == op1)
506 : : return;
507 : 244166 : op1 = convert_to_mode (mode, op1, 1);
508 : : }
509 : : }
510 : : else
511 : : {
512 : 70712666 : if (MEM_P (op0)
513 : 95558504 : && (PUSH_ROUNDING (GET_MODE_SIZE (mode)) != GET_MODE_SIZE (mode)
514 : 10113394 : || !push_operand (op0, mode))
515 : 82165837 : && MEM_P (op1))
516 : 2133740 : op1 = force_reg (mode, op1);
517 : :
518 : 70712666 : if (push_operand (op0, mode)
519 : 70712666 : && ! general_no_elim_operand (op1, mode))
520 : 1002 : op1 = copy_to_mode_reg (mode, op1);
521 : :
522 : : /* Force large constants in 64bit compilation into register
523 : : to get them CSEed. */
524 : 70712666 : if (can_create_pseudo_p ()
525 : 65481740 : && (mode == DImode) && TARGET_64BIT
526 : 33386271 : && immediate_operand (op1, mode)
527 : 8078697 : && !x86_64_zext_immediate_operand (op1, VOIDmode)
528 : 787319 : && !register_operand (op0, mode)
529 : 70873508 : && optimize)
530 : 111680 : op1 = copy_to_mode_reg (mode, op1);
531 : :
532 : 70712666 : if (can_create_pseudo_p ())
533 : : {
534 : 65481740 : if (CONST_DOUBLE_P (op1))
535 : : {
536 : : /* If we are loading a floating point constant to a
537 : : register, force the value to memory now, since we'll
538 : : get better code out the back end. */
539 : :
540 : 873001 : op1 = validize_mem (force_const_mem (mode, op1));
541 : 873001 : if (!register_operand (op0, mode))
542 : : {
543 : 119226 : tmp = gen_reg_rtx (mode);
544 : 119226 : emit_insn (gen_rtx_SET (tmp, op1));
545 : 119226 : emit_move_insn (op0, tmp);
546 : 119226 : return;
547 : : }
548 : : }
549 : : }
550 : : }
551 : :
552 : : /* Special case inserting 64-bit values into a TImode register. */
553 : 70924968 : if (TARGET_64BIT
554 : : /* Disable for -O0 (see PR110587) unless naked (PR110533). */
555 : 61099574 : && (optimize || ix86_function_naked (current_function_decl))
556 : 41648852 : && (mode == DImode || mode == DFmode)
557 : 27960480 : && SUBREG_P (op0)
558 : 461636 : && GET_MODE (SUBREG_REG (op0)) == TImode
559 : 461636 : && REG_P (SUBREG_REG (op0))
560 : 71308327 : && REG_P (op1))
561 : : {
562 : : /* Use *insvti_lowpart_1 to set lowpart. */
563 : 183792 : if (SUBREG_BYTE (op0) == 0)
564 : : {
565 : 51458 : wide_int mask = wi::mask (64, true, 128);
566 : 51458 : tmp = immed_wide_int_const (mask, TImode);
567 : 51458 : op0 = SUBREG_REG (op0);
568 : 51458 : tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp);
569 : 51458 : if (mode == DFmode)
570 : 343 : op1 = gen_lowpart (DImode, op1);
571 : 51458 : op1 = gen_rtx_ZERO_EXTEND (TImode, op1);
572 : 51458 : op1 = gen_rtx_IOR (TImode, tmp, op1);
573 : 51458 : }
574 : : /* Use *insvti_highpart_1 to set highpart. */
575 : 132334 : else if (SUBREG_BYTE (op0) == 8)
576 : : {
577 : 132334 : wide_int mask = wi::mask (64, false, 128);
578 : 132334 : tmp = immed_wide_int_const (mask, TImode);
579 : 132334 : op0 = SUBREG_REG (op0);
580 : 132334 : tmp = gen_rtx_AND (TImode, copy_rtx (op0), tmp);
581 : 132334 : if (mode == DFmode)
582 : 191 : op1 = gen_lowpart (DImode, op1);
583 : 132334 : op1 = gen_rtx_ZERO_EXTEND (TImode, op1);
584 : 132334 : op1 = gen_rtx_ASHIFT (TImode, op1, GEN_INT (64));
585 : 132334 : op1 = gen_rtx_IOR (TImode, tmp, op1);
586 : 132334 : }
587 : : }
588 : :
589 : 70924968 : emit_insn (gen_rtx_SET (op0, op1));
590 : : }
591 : :
592 : : /* OP is a memref of CONST_VECTOR, return scalar constant mem
593 : : if CONST_VECTOR is a vec_duplicate, else return NULL. */
594 : : rtx
595 : 2081320 : ix86_broadcast_from_constant (machine_mode mode, rtx op)
596 : : {
597 : 2081320 : int nunits = GET_MODE_NUNITS (mode);
598 : 2081320 : if (nunits < 2)
599 : : return nullptr;
600 : :
601 : : /* Don't use integer vector broadcast if we can't move from GPR to SSE
602 : : register directly. */
603 : 1939825 : if (!TARGET_INTER_UNIT_MOVES_TO_VEC
604 : 7993 : && INTEGRAL_MODE_P (mode))
605 : : return nullptr;
606 : :
607 : : /* Convert CONST_VECTOR to a non-standard SSE constant integer
608 : : broadcast only if vector broadcast is available. */
609 : 1934449 : if (standard_sse_constant_p (op, mode))
610 : : return nullptr;
611 : :
612 : 3868892 : if (GET_MODE_INNER (mode) == TImode)
613 : : return nullptr;
614 : :
615 : 1934336 : rtx constant = get_pool_constant (XEXP (op, 0));
616 : 1934336 : if (!CONST_VECTOR_P (constant))
617 : : return nullptr;
618 : :
619 : : /* There could be some rtx like
620 : : (mem/u/c:V16QI (symbol_ref/u:DI ("*.LC1")))
621 : : but with "*.LC1" refer to V2DI constant vector. */
622 : 1934336 : if (GET_MODE (constant) != mode)
623 : : {
624 : 1076 : constant = simplify_subreg (mode, constant, GET_MODE (constant),
625 : 538 : 0);
626 : 538 : if (constant == nullptr || !CONST_VECTOR_P (constant))
627 : : return nullptr;
628 : : }
629 : :
630 : 1934336 : rtx first = XVECEXP (constant, 0, 0);
631 : :
632 : 4991368 : for (int i = 1; i < nunits; ++i)
633 : : {
634 : 4577794 : rtx tmp = XVECEXP (constant, 0, i);
635 : : /* Vector duplicate value. */
636 : 4577794 : if (!rtx_equal_p (tmp, first))
637 : : return nullptr;
638 : : }
639 : :
640 : : return first;
641 : : }
642 : :
643 : : void
644 : 4061519 : ix86_expand_vector_move (machine_mode mode, rtx operands[])
645 : : {
646 : 4061519 : rtx op0 = operands[0], op1 = operands[1];
647 : : /* Use GET_MODE_BITSIZE instead of GET_MODE_ALIGNMENT for IA MCU
648 : : psABI since the biggest alignment is 4 byte for IA MCU psABI. */
649 : 4061519 : unsigned int align = (TARGET_IAMCU
650 : 4061519 : ? GET_MODE_BITSIZE (mode)
651 : 4061519 : : GET_MODE_ALIGNMENT (mode));
652 : :
653 : 4061519 : if (push_operand (op0, VOIDmode))
654 : 2875 : op0 = emit_move_resolve_push (mode, op0);
655 : :
656 : : /* Force constants other than zero into memory. We do not know how
657 : : the instructions used to build constants modify the upper 64 bits
658 : : of the register, once we have that information we may be able
659 : : to handle some of them more efficiently. */
660 : 4061519 : if (can_create_pseudo_p ()
661 : 3862632 : && (CONSTANT_P (op1)
662 : 3619056 : || (SUBREG_P (op1)
663 : 265128 : && CONSTANT_P (SUBREG_REG (op1))))
664 : 4305109 : && ((register_operand (op0, mode)
665 : 197736 : && !standard_sse_constant_p (op1, mode))
666 : : /* ix86_expand_vector_move_misalign() does not like constants. */
667 : : || (SSE_REG_MODE_P (mode)
668 : 195771 : && MEM_P (op0)
669 : 33707 : && MEM_ALIGN (op0) < align)))
670 : : {
671 : 2118 : if (SUBREG_P (op1))
672 : : {
673 : 14 : machine_mode imode = GET_MODE (SUBREG_REG (op1));
674 : 14 : rtx r = force_const_mem (imode, SUBREG_REG (op1));
675 : 14 : if (r)
676 : 14 : r = validize_mem (r);
677 : : else
678 : 0 : r = force_reg (imode, SUBREG_REG (op1));
679 : 14 : op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1));
680 : : }
681 : : else
682 : : {
683 : 2104 : machine_mode mode = GET_MODE (op0);
684 : 2104 : rtx tmp = ix86_convert_const_wide_int_to_broadcast
685 : 2104 : (mode, op1);
686 : 2104 : if (tmp == nullptr)
687 : 2083 : op1 = validize_mem (force_const_mem (mode, op1));
688 : : else
689 : : op1 = tmp;
690 : : }
691 : : }
692 : :
693 : 4061519 : if (can_create_pseudo_p ()
694 : 3862632 : && GET_MODE_SIZE (mode) >= 16
695 : 3165313 : && VECTOR_MODE_P (mode)
696 : 6998953 : && (MEM_P (op1)
697 : 624773 : && SYMBOL_REF_P (XEXP (op1, 0))
698 : 447283 : && CONSTANT_POOL_ADDRESS_P (XEXP (op1, 0))))
699 : : {
700 : 430975 : rtx first = ix86_broadcast_from_constant (mode, op1);
701 : 430975 : if (first != nullptr)
702 : : {
703 : : /* Broadcast to XMM/YMM/ZMM register from an integer
704 : : constant or scalar mem. */
705 : 108420 : rtx tmp = gen_reg_rtx (mode);
706 : 108420 : if (FLOAT_MODE_P (mode))
707 : 25216 : first = force_const_mem (GET_MODE_INNER (mode), first);
708 : 108420 : bool ok = ix86_expand_vector_init_duplicate (false, mode,
709 : : tmp, first);
710 : 108420 : if (!ok && !TARGET_64BIT && GET_MODE_INNER (mode) == DImode)
711 : : {
712 : 0 : first = force_const_mem (GET_MODE_INNER (mode), first);
713 : 0 : ok = ix86_expand_vector_init_duplicate (false, mode,
714 : : tmp, first);
715 : : }
716 : 108420 : if (ok)
717 : : {
718 : 108420 : emit_move_insn (op0, tmp);
719 : 108420 : return;
720 : : }
721 : : }
722 : : }
723 : :
724 : : /* We need to check memory alignment for SSE mode since attribute
725 : : can make operands unaligned. */
726 : 3953099 : if (can_create_pseudo_p ()
727 : : && SSE_REG_MODE_P (mode)
728 : 6977219 : && ((MEM_P (op0) && (MEM_ALIGN (op0) < align))
729 : 2874082 : || (MEM_P (op1) && (MEM_ALIGN (op1) < align))))
730 : : {
731 : 252073 : rtx tmp[2];
732 : :
733 : : /* ix86_expand_vector_move_misalign() does not like both
734 : : arguments in memory. */
735 : 252073 : if (!register_operand (op0, mode)
736 : 252073 : && !register_operand (op1, mode))
737 : : {
738 : 92060 : rtx scratch = gen_reg_rtx (mode);
739 : 92060 : emit_move_insn (scratch, op1);
740 : 92060 : op1 = scratch;
741 : : }
742 : :
743 : 252073 : tmp[0] = op0; tmp[1] = op1;
744 : 252073 : ix86_expand_vector_move_misalign (mode, tmp);
745 : 252073 : return;
746 : : }
747 : :
748 : : /* Special case TImode to 128-bit vector conversions via V2DI. */
749 : 1101550 : if (VECTOR_MODE_P (mode)
750 : 3649189 : && GET_MODE_SIZE (mode) == 16
751 : 2455586 : && SUBREG_P (op1)
752 : 201014 : && GET_MODE (SUBREG_REG (op1)) == TImode
753 : 2692 : && TARGET_64BIT && TARGET_SSE
754 : 3703107 : && ix86_pre_reload_split ())
755 : : {
756 : 2017 : rtx tmp = gen_reg_rtx (V2DImode);
757 : 2017 : rtx lo = gen_reg_rtx (DImode);
758 : 2017 : rtx hi = gen_reg_rtx (DImode);
759 : 2017 : emit_move_insn (lo, gen_lowpart (DImode, SUBREG_REG (op1)));
760 : 2017 : emit_move_insn (hi, gen_highpart (DImode, SUBREG_REG (op1)));
761 : 2017 : emit_insn (gen_vec_concatv2di (tmp, lo, hi));
762 : 2017 : emit_move_insn (op0, gen_lowpart (mode, tmp));
763 : 2017 : return;
764 : : }
765 : :
766 : : /* If operand0 is a hard register, make operand1 a pseudo. */
767 : 3699009 : if (can_create_pseudo_p ()
768 : 7199131 : && !ix86_hardreg_mov_ok (op0, op1))
769 : : {
770 : 130 : rtx tmp = gen_reg_rtx (GET_MODE (op0));
771 : 130 : emit_move_insn (tmp, op1);
772 : 130 : emit_move_insn (op0, tmp);
773 : 130 : return;
774 : : }
775 : :
776 : : /* Make operand1 a register if it isn't already. */
777 : 3698879 : if (can_create_pseudo_p ()
778 : 3499992 : && !register_operand (op0, mode)
779 : 4680533 : && !register_operand (op1, mode))
780 : : {
781 : 192839 : rtx tmp = gen_reg_rtx (GET_MODE (op0));
782 : 192839 : emit_move_insn (tmp, op1);
783 : 192839 : emit_move_insn (op0, tmp);
784 : 192839 : return;
785 : : }
786 : :
787 : 3506040 : emit_insn (gen_rtx_SET (op0, op1));
788 : : }
789 : :
790 : : /* Split 32-byte AVX unaligned load and store if needed. */
791 : :
792 : : static void
793 : 9888 : ix86_avx256_split_vector_move_misalign (rtx op0, rtx op1)
794 : : {
795 : 9888 : rtx m;
796 : 9888 : rtx (*extract) (rtx, rtx, rtx);
797 : 9888 : machine_mode mode;
798 : :
799 : 9888 : if ((MEM_P (op1) && !TARGET_AVX256_SPLIT_UNALIGNED_LOAD)
800 : 3364 : || (MEM_P (op0) && !TARGET_AVX256_SPLIT_UNALIGNED_STORE))
801 : : {
802 : 9838 : emit_insn (gen_rtx_SET (op0, op1));
803 : 9838 : return;
804 : : }
805 : :
806 : 50 : rtx orig_op0 = NULL_RTX;
807 : 50 : mode = GET_MODE (op0);
808 : 50 : switch (GET_MODE_CLASS (mode))
809 : : {
810 : 33 : case MODE_VECTOR_INT:
811 : 33 : case MODE_INT:
812 : 33 : if (mode != V32QImode)
813 : : {
814 : 7 : if (!MEM_P (op0))
815 : : {
816 : 3 : orig_op0 = op0;
817 : 3 : op0 = gen_reg_rtx (V32QImode);
818 : : }
819 : : else
820 : 4 : op0 = gen_lowpart (V32QImode, op0);
821 : 7 : op1 = gen_lowpart (V32QImode, op1);
822 : 7 : mode = V32QImode;
823 : : }
824 : : break;
825 : : case MODE_VECTOR_FLOAT:
826 : : break;
827 : 0 : default:
828 : 0 : gcc_unreachable ();
829 : : }
830 : :
831 : 50 : switch (mode)
832 : : {
833 : 0 : default:
834 : 0 : gcc_unreachable ();
835 : : case E_V32QImode:
836 : : extract = gen_avx_vextractf128v32qi;
837 : : mode = V16QImode;
838 : : break;
839 : 1 : case E_V16BFmode:
840 : 1 : extract = gen_avx_vextractf128v16bf;
841 : 1 : mode = V8BFmode;
842 : 1 : break;
843 : 0 : case E_V16HFmode:
844 : 0 : extract = gen_avx_vextractf128v16hf;
845 : 0 : mode = V8HFmode;
846 : 0 : break;
847 : 8 : case E_V8SFmode:
848 : 8 : extract = gen_avx_vextractf128v8sf;
849 : 8 : mode = V4SFmode;
850 : 8 : break;
851 : 8 : case E_V4DFmode:
852 : 8 : extract = gen_avx_vextractf128v4df;
853 : 8 : mode = V2DFmode;
854 : 8 : break;
855 : : }
856 : :
857 : 50 : if (MEM_P (op1))
858 : : {
859 : 9 : rtx r = gen_reg_rtx (mode);
860 : 9 : m = adjust_address (op1, mode, 0);
861 : 9 : emit_move_insn (r, m);
862 : 9 : m = adjust_address (op1, mode, 16);
863 : 9 : r = gen_rtx_VEC_CONCAT (GET_MODE (op0), r, m);
864 : 9 : emit_move_insn (op0, r);
865 : : }
866 : 41 : else if (MEM_P (op0))
867 : : {
868 : 41 : m = adjust_address (op0, mode, 0);
869 : 41 : emit_insn (extract (m, op1, const0_rtx));
870 : 41 : m = adjust_address (op0, mode, 16);
871 : 41 : emit_insn (extract (m, copy_rtx (op1), const1_rtx));
872 : : }
873 : : else
874 : 0 : gcc_unreachable ();
875 : :
876 : 50 : if (orig_op0)
877 : 3 : emit_move_insn (orig_op0, gen_lowpart (GET_MODE (orig_op0), op0));
878 : : }
879 : :
880 : : /* Implement the movmisalign patterns for SSE. Non-SSE modes go
881 : : straight to ix86_expand_vector_move. */
882 : : /* Code generation for scalar reg-reg moves of single and double precision data:
883 : : if (x86_sse_partial_reg_dependency == true | x86_sse_split_regs == true)
884 : : movaps reg, reg
885 : : else
886 : : movss reg, reg
887 : : if (x86_sse_partial_reg_dependency == true)
888 : : movapd reg, reg
889 : : else
890 : : movsd reg, reg
891 : :
892 : : Code generation for scalar loads of double precision data:
893 : : if (x86_sse_split_regs == true)
894 : : movlpd mem, reg (gas syntax)
895 : : else
896 : : movsd mem, reg
897 : :
898 : : Code generation for unaligned packed loads of single precision data
899 : : (x86_sse_unaligned_move_optimal overrides x86_sse_partial_reg_dependency):
900 : : if (x86_sse_unaligned_move_optimal)
901 : : movups mem, reg
902 : :
903 : : if (x86_sse_partial_reg_dependency == true)
904 : : {
905 : : xorps reg, reg
906 : : movlps mem, reg
907 : : movhps mem+8, reg
908 : : }
909 : : else
910 : : {
911 : : movlps mem, reg
912 : : movhps mem+8, reg
913 : : }
914 : :
915 : : Code generation for unaligned packed loads of double precision data
916 : : (x86_sse_unaligned_move_optimal overrides x86_sse_split_regs):
917 : : if (x86_sse_unaligned_move_optimal)
918 : : movupd mem, reg
919 : :
920 : : if (x86_sse_split_regs == true)
921 : : {
922 : : movlpd mem, reg
923 : : movhpd mem+8, reg
924 : : }
925 : : else
926 : : {
927 : : movsd mem, reg
928 : : movhpd mem+8, reg
929 : : }
930 : : */
931 : :
932 : : void
933 : 546300 : ix86_expand_vector_move_misalign (machine_mode mode, rtx operands[])
934 : : {
935 : 546300 : rtx op0, op1, m;
936 : :
937 : 546300 : op0 = operands[0];
938 : 546300 : op1 = operands[1];
939 : :
940 : : /* Use unaligned load/store for AVX512 or when optimizing for size. */
941 : 1092600 : if (GET_MODE_SIZE (mode) == 64 || optimize_insn_for_size_p ())
942 : : {
943 : 13691 : emit_insn (gen_rtx_SET (op0, op1));
944 : 13691 : return;
945 : : }
946 : :
947 : 532609 : if (TARGET_AVX)
948 : : {
949 : 49340 : if (GET_MODE_SIZE (mode) == 32)
950 : 9888 : ix86_avx256_split_vector_move_misalign (op0, op1);
951 : : else
952 : : /* Always use 128-bit mov<mode>_internal pattern for AVX. */
953 : 14782 : emit_insn (gen_rtx_SET (op0, op1));
954 : 24670 : return;
955 : : }
956 : :
957 : 507939 : if (TARGET_SSE_UNALIGNED_LOAD_OPTIMAL
958 : 99 : || TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
959 : : {
960 : 507840 : emit_insn (gen_rtx_SET (op0, op1));
961 : 507840 : return;
962 : : }
963 : :
964 : : /* ??? If we have typed data, then it would appear that using
965 : : movdqu is the only way to get unaligned data loaded with
966 : : integer type. */
967 : 99 : if (TARGET_SSE2 && GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
968 : : {
969 : 85 : emit_insn (gen_rtx_SET (op0, op1));
970 : 85 : return;
971 : : }
972 : :
973 : 14 : if (MEM_P (op1))
974 : : {
975 : 6 : if (TARGET_SSE2 && mode == V2DFmode)
976 : : {
977 : 2 : rtx zero;
978 : :
979 : : /* When SSE registers are split into halves, we can avoid
980 : : writing to the top half twice. */
981 : 2 : if (TARGET_SSE_SPLIT_REGS)
982 : : {
983 : 2 : emit_clobber (op0);
984 : 2 : zero = op0;
985 : : }
986 : : else
987 : : {
988 : : /* ??? Not sure about the best option for the Intel chips.
989 : : The following would seem to satisfy; the register is
990 : : entirely cleared, breaking the dependency chain. We
991 : : then store to the upper half, with a dependency depth
992 : : of one. A rumor has it that Intel recommends two movsd
993 : : followed by an unpacklpd, but this is unconfirmed. And
994 : : given that the dependency depth of the unpacklpd would
995 : : still be one, I'm not sure why this would be better. */
996 : 0 : zero = CONST0_RTX (V2DFmode);
997 : : }
998 : :
999 : 2 : m = adjust_address (op1, DFmode, 0);
1000 : 2 : emit_insn (gen_sse2_loadlpd (op0, zero, m));
1001 : 2 : m = adjust_address (op1, DFmode, 8);
1002 : 2 : emit_insn (gen_sse2_loadhpd (op0, op0, m));
1003 : 2 : }
1004 : : else
1005 : : {
1006 : 4 : rtx t;
1007 : :
1008 : 4 : if (mode != V4SFmode)
1009 : 0 : t = gen_reg_rtx (V4SFmode);
1010 : : else
1011 : : t = op0;
1012 : :
1013 : 4 : if (TARGET_SSE_PARTIAL_REG_DEPENDENCY)
1014 : 2 : emit_move_insn (t, CONST0_RTX (V4SFmode));
1015 : : else
1016 : 2 : emit_clobber (t);
1017 : :
1018 : 4 : m = adjust_address (op1, V2SFmode, 0);
1019 : 4 : emit_insn (gen_sse_loadlps (t, t, m));
1020 : 4 : m = adjust_address (op1, V2SFmode, 8);
1021 : 4 : emit_insn (gen_sse_loadhps (t, t, m));
1022 : 4 : if (mode != V4SFmode)
1023 : 0 : emit_move_insn (op0, gen_lowpart (mode, t));
1024 : : }
1025 : : }
1026 : 8 : else if (MEM_P (op0))
1027 : : {
1028 : 8 : if (TARGET_SSE2 && mode == V2DFmode)
1029 : : {
1030 : 2 : m = adjust_address (op0, DFmode, 0);
1031 : 2 : emit_insn (gen_sse2_storelpd (m, op1));
1032 : 2 : m = adjust_address (op0, DFmode, 8);
1033 : 2 : emit_insn (gen_sse2_storehpd (m, op1));
1034 : : }
1035 : : else
1036 : : {
1037 : 6 : if (mode != V4SFmode)
1038 : 0 : op1 = gen_lowpart (V4SFmode, op1);
1039 : :
1040 : 6 : m = adjust_address (op0, V2SFmode, 0);
1041 : 6 : emit_insn (gen_sse_storelps (m, op1));
1042 : 6 : m = adjust_address (op0, V2SFmode, 8);
1043 : 6 : emit_insn (gen_sse_storehps (m, copy_rtx (op1)));
1044 : : }
1045 : : }
1046 : : else
1047 : 0 : gcc_unreachable ();
1048 : : }
1049 : :
1050 : : /* Move bits 64:95 to bits 32:63. */
1051 : :
1052 : : void
1053 : 860 : ix86_move_vector_high_sse_to_mmx (rtx op)
1054 : : {
1055 : 860 : rtx mask = gen_rtx_PARALLEL (VOIDmode,
1056 : : gen_rtvec (4, GEN_INT (0), GEN_INT (2),
1057 : : GEN_INT (0), GEN_INT (0)));
1058 : 860 : rtx dest = lowpart_subreg (V4SImode, op, GET_MODE (op));
1059 : 860 : op = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
1060 : 860 : rtx insn = gen_rtx_SET (dest, op);
1061 : 860 : emit_insn (insn);
1062 : 860 : }
1063 : :
1064 : : /* Split MMX pack with signed/unsigned saturation with SSE/SSE2. */
1065 : :
1066 : : void
1067 : 770 : ix86_split_mmx_pack (rtx operands[], enum rtx_code code)
1068 : : {
1069 : 770 : rtx op0 = operands[0];
1070 : 770 : rtx op1 = operands[1];
1071 : 770 : rtx op2 = operands[2];
1072 : 770 : rtx src;
1073 : :
1074 : 770 : machine_mode dmode = GET_MODE (op0);
1075 : 770 : machine_mode smode = GET_MODE (op1);
1076 : 770 : machine_mode inner_dmode = GET_MODE_INNER (dmode);
1077 : 770 : machine_mode inner_smode = GET_MODE_INNER (smode);
1078 : :
1079 : : /* Get the corresponding SSE mode for destination. */
1080 : 770 : int nunits = 16 / GET_MODE_SIZE (inner_dmode);
1081 : 1540 : machine_mode sse_dmode = mode_for_vector (GET_MODE_INNER (dmode),
1082 : 770 : nunits).require ();
1083 : 770 : machine_mode sse_half_dmode = mode_for_vector (GET_MODE_INNER (dmode),
1084 : 1540 : nunits / 2).require ();
1085 : :
1086 : : /* Get the corresponding SSE mode for source. */
1087 : 770 : nunits = 16 / GET_MODE_SIZE (inner_smode);
1088 : 1540 : machine_mode sse_smode = mode_for_vector (GET_MODE_INNER (smode),
1089 : 770 : nunits).require ();
1090 : :
1091 : : /* Generate SSE pack with signed/unsigned saturation. */
1092 : 770 : rtx dest = lowpart_subreg (sse_dmode, op0, GET_MODE (op0));
1093 : 770 : op1 = lowpart_subreg (sse_smode, op1, GET_MODE (op1));
1094 : 770 : op2 = lowpart_subreg (sse_smode, op2, GET_MODE (op2));
1095 : :
1096 : : /* paskusdw/packuswb does unsigned saturation of a signed source
1097 : : which is different from generic us_truncate RTX. */
1098 : 770 : if (code == US_TRUNCATE)
1099 : 668 : src = gen_rtx_UNSPEC (sse_dmode,
1100 : : gen_rtvec (2, op1, op2),
1101 : : UNSPEC_US_TRUNCATE);
1102 : : else
1103 : : {
1104 : 102 : op1 = gen_rtx_fmt_e (code, sse_half_dmode, op1);
1105 : 102 : op2 = gen_rtx_fmt_e (code, sse_half_dmode, op2);
1106 : 102 : src = gen_rtx_VEC_CONCAT (sse_dmode, op1, op2);
1107 : : }
1108 : :
1109 : 770 : emit_move_insn (dest, src);
1110 : :
1111 : 770 : ix86_move_vector_high_sse_to_mmx (op0);
1112 : 770 : }
1113 : :
1114 : : /* Split MMX punpcklXX/punpckhXX with SSE punpcklXX. This is also used
1115 : : for a full unpack of OPERANDS[1] and OPERANDS[2] into a wider
1116 : : OPERANDS[0]. */
1117 : :
1118 : : void
1119 : 6090 : ix86_split_mmx_punpck (rtx operands[], bool high_p)
1120 : : {
1121 : 6090 : rtx op0 = operands[0];
1122 : 6090 : rtx op1 = operands[1];
1123 : 6090 : rtx op2 = operands[2];
1124 : 6090 : machine_mode mode = GET_MODE (op1);
1125 : 6090 : rtx mask;
1126 : : /* The corresponding SSE mode. */
1127 : 6090 : machine_mode sse_mode, double_sse_mode;
1128 : :
1129 : 6090 : switch (mode)
1130 : : {
1131 : 1765 : case E_V8QImode:
1132 : 1765 : case E_V4QImode:
1133 : 1765 : case E_V2QImode:
1134 : 1765 : sse_mode = V16QImode;
1135 : 1765 : double_sse_mode = V32QImode;
1136 : 1765 : mask = gen_rtx_PARALLEL (VOIDmode,
1137 : : gen_rtvec (16,
1138 : : GEN_INT (0), GEN_INT (16),
1139 : : GEN_INT (1), GEN_INT (17),
1140 : : GEN_INT (2), GEN_INT (18),
1141 : : GEN_INT (3), GEN_INT (19),
1142 : : GEN_INT (4), GEN_INT (20),
1143 : : GEN_INT (5), GEN_INT (21),
1144 : : GEN_INT (6), GEN_INT (22),
1145 : : GEN_INT (7), GEN_INT (23)));
1146 : 1765 : break;
1147 : :
1148 : 3222 : case E_V4HImode:
1149 : 3222 : case E_V2HImode:
1150 : 3222 : sse_mode = V8HImode;
1151 : 3222 : double_sse_mode = V16HImode;
1152 : 3222 : mask = gen_rtx_PARALLEL (VOIDmode,
1153 : : gen_rtvec (8,
1154 : : GEN_INT (0), GEN_INT (8),
1155 : : GEN_INT (1), GEN_INT (9),
1156 : : GEN_INT (2), GEN_INT (10),
1157 : : GEN_INT (3), GEN_INT (11)));
1158 : 3222 : break;
1159 : :
1160 : 931 : case E_V2SImode:
1161 : 931 : sse_mode = V4SImode;
1162 : 931 : double_sse_mode = V8SImode;
1163 : 931 : mask = gen_rtx_PARALLEL (VOIDmode,
1164 : : gen_rtvec (4,
1165 : : GEN_INT (0), GEN_INT (4),
1166 : : GEN_INT (1), GEN_INT (5)));
1167 : 931 : break;
1168 : :
1169 : 172 : case E_V2SFmode:
1170 : 172 : sse_mode = V4SFmode;
1171 : 172 : double_sse_mode = V8SFmode;
1172 : 172 : mask = gen_rtx_PARALLEL (VOIDmode,
1173 : : gen_rtvec (4,
1174 : : GEN_INT (0), GEN_INT (4),
1175 : : GEN_INT (1), GEN_INT (5)));
1176 : 172 : break;
1177 : :
1178 : 0 : default:
1179 : 0 : gcc_unreachable ();
1180 : : }
1181 : :
1182 : : /* Generate SSE punpcklXX. */
1183 : 6090 : rtx dest = lowpart_subreg (sse_mode, op0, GET_MODE (op0));
1184 : 6090 : op1 = lowpart_subreg (sse_mode, op1, GET_MODE (op1));
1185 : 6090 : op2 = lowpart_subreg (sse_mode, op2, GET_MODE (op2));
1186 : :
1187 : 6090 : op1 = gen_rtx_VEC_CONCAT (double_sse_mode, op1, op2);
1188 : 6090 : op2 = gen_rtx_VEC_SELECT (sse_mode, op1, mask);
1189 : 6090 : rtx insn = gen_rtx_SET (dest, op2);
1190 : 6090 : emit_insn (insn);
1191 : :
1192 : : /* Move high bits to low bits. */
1193 : 6090 : if (high_p)
1194 : : {
1195 : 2337 : if (sse_mode == V4SFmode)
1196 : : {
1197 : 80 : mask = gen_rtx_PARALLEL (VOIDmode,
1198 : : gen_rtvec (4, GEN_INT (2), GEN_INT (3),
1199 : : GEN_INT (4), GEN_INT (5)));
1200 : 80 : op2 = gen_rtx_VEC_CONCAT (V8SFmode, dest, dest);
1201 : 80 : op1 = gen_rtx_VEC_SELECT (V4SFmode, op2, mask);
1202 : : }
1203 : : else
1204 : : {
1205 : 2257 : int sz = GET_MODE_SIZE (mode);
1206 : :
1207 : 2257 : if (sz == 4)
1208 : 341 : mask = gen_rtx_PARALLEL (VOIDmode,
1209 : : gen_rtvec (4, GEN_INT (1), GEN_INT (0),
1210 : : GEN_INT (0), GEN_INT (1)));
1211 : 1916 : else if (sz == 8)
1212 : 1916 : mask = gen_rtx_PARALLEL (VOIDmode,
1213 : : gen_rtvec (4, GEN_INT (2), GEN_INT (3),
1214 : : GEN_INT (0), GEN_INT (1)));
1215 : : else
1216 : 0 : gcc_unreachable ();
1217 : :
1218 : 2257 : dest = lowpart_subreg (V4SImode, dest, GET_MODE (dest));
1219 : 2257 : op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask);
1220 : : }
1221 : :
1222 : 2337 : insn = gen_rtx_SET (dest, op1);
1223 : 2337 : emit_insn (insn);
1224 : : }
1225 : 6090 : }
1226 : :
1227 : : /* Helper function of ix86_fixup_binary_operands to canonicalize
1228 : : operand order. Returns true if the operands should be swapped. */
1229 : :
1230 : : static bool
1231 : 159256867 : ix86_swap_binary_operands_p (enum rtx_code code, machine_mode mode,
1232 : : rtx operands[])
1233 : : {
1234 : 159256867 : rtx dst = operands[0];
1235 : 159256867 : rtx src1 = operands[1];
1236 : 159256867 : rtx src2 = operands[2];
1237 : :
1238 : : /* If the operation is not commutative, we can't do anything. */
1239 : 159256867 : if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
1240 : 23408115 : && GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
1241 : : return false;
1242 : :
1243 : : /* Highest priority is that src1 should match dst. */
1244 : 135859019 : if (rtx_equal_p (dst, src1))
1245 : : return false;
1246 : 98004885 : if (rtx_equal_p (dst, src2))
1247 : : return true;
1248 : :
1249 : : /* Next highest priority is that immediate constants come second. */
1250 : 97919289 : if (immediate_operand (src2, mode))
1251 : : return false;
1252 : 22694009 : if (immediate_operand (src1, mode))
1253 : : return true;
1254 : :
1255 : : /* Lowest priority is that memory references should come second. */
1256 : 22694009 : if (MEM_P (src2))
1257 : : return false;
1258 : 21279290 : if (MEM_P (src1))
1259 : : return true;
1260 : :
1261 : : return false;
1262 : : }
1263 : :
1264 : : /* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the
1265 : : destination to use for the operation. If different from the true
1266 : : destination in operands[0], a copy operation will be required except
1267 : : under TARGET_APX_NDD. */
1268 : :
1269 : : rtx
1270 : 12474493 : ix86_fixup_binary_operands (enum rtx_code code, machine_mode mode,
1271 : : rtx operands[], bool use_ndd)
1272 : : {
1273 : 12474493 : rtx dst = operands[0];
1274 : 12474493 : rtx src1 = operands[1];
1275 : 12474493 : rtx src2 = operands[2];
1276 : :
1277 : : /* Canonicalize operand order. */
1278 : 12474493 : if (ix86_swap_binary_operands_p (code, mode, operands))
1279 : : {
1280 : : /* It is invalid to swap operands of different modes. */
1281 : 79721 : gcc_assert (GET_MODE (src1) == GET_MODE (src2));
1282 : :
1283 : : std::swap (src1, src2);
1284 : : }
1285 : :
1286 : : /* Both source operands cannot be in memory. */
1287 : 12474493 : if (MEM_P (src1) && MEM_P (src2))
1288 : : {
1289 : : /* Optimization: Only read from memory once. */
1290 : 78782 : if (rtx_equal_p (src1, src2))
1291 : : {
1292 : 9 : src2 = force_reg (mode, src2);
1293 : 9 : src1 = src2;
1294 : : }
1295 : 78773 : else if (rtx_equal_p (dst, src1))
1296 : 2825 : src2 = force_reg (mode, src2);
1297 : : else
1298 : 75948 : src1 = force_reg (mode, src1);
1299 : : }
1300 : :
1301 : : /* If the destination is memory, and we do not have matching source
1302 : : operands, do things in registers. */
1303 : 12474493 : if (MEM_P (dst) && !rtx_equal_p (dst, src1))
1304 : 466471 : dst = gen_reg_rtx (mode);
1305 : :
1306 : : /* Source 1 cannot be a constant. */
1307 : 12474493 : if (CONSTANT_P (src1))
1308 : 610 : src1 = force_reg (mode, src1);
1309 : :
1310 : : /* Source 1 cannot be a non-matching memory. */
1311 : 12474493 : if (!use_ndd && MEM_P (src1) && !rtx_equal_p (dst, src1))
1312 : 429928 : src1 = force_reg (mode, src1);
1313 : :
1314 : : /* Improve address combine. */
1315 : 12474493 : if (code == PLUS
1316 : 9215047 : && GET_MODE_CLASS (mode) == MODE_INT
1317 : 9118686 : && MEM_P (src2))
1318 : 184332 : src2 = force_reg (mode, src2);
1319 : :
1320 : 12474493 : operands[1] = src1;
1321 : 12474493 : operands[2] = src2;
1322 : 12474493 : return dst;
1323 : : }
1324 : :
1325 : : /* Similarly, but assume that the destination has already been
1326 : : set up properly. */
1327 : :
1328 : : void
1329 : 223049 : ix86_fixup_binary_operands_no_copy (enum rtx_code code,
1330 : : machine_mode mode, rtx operands[],
1331 : : bool use_ndd)
1332 : : {
1333 : 223049 : rtx dst = ix86_fixup_binary_operands (code, mode, operands, use_ndd);
1334 : 223049 : gcc_assert (dst == operands[0]);
1335 : 223049 : }
1336 : :
1337 : : /* Attempt to expand a binary operator. Make the expansion closer to the
1338 : : actual machine, then just general_operand, which will allow 3 separate
1339 : : memory references (one output, two input) in a single insn. */
1340 : :
1341 : : void
1342 : 12251315 : ix86_expand_binary_operator (enum rtx_code code, machine_mode mode,
1343 : : rtx operands[], bool use_ndd)
1344 : : {
1345 : 12251315 : rtx src1, src2, dst, op, clob;
1346 : :
1347 : 12251315 : dst = ix86_fixup_binary_operands (code, mode, operands, use_ndd);
1348 : 12251315 : src1 = operands[1];
1349 : 12251315 : src2 = operands[2];
1350 : :
1351 : : /* Emit the instruction. */
1352 : :
1353 : 12251315 : op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, mode, src1, src2));
1354 : :
1355 : 12251315 : if (reload_completed
1356 : 79540 : && code == PLUS
1357 : 818 : && !rtx_equal_p (dst, src1)
1358 : 12251315 : && !use_ndd)
1359 : : {
1360 : : /* This is going to be an LEA; avoid splitting it later. */
1361 : 0 : emit_insn (op);
1362 : : }
1363 : : else
1364 : : {
1365 : 12251315 : clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
1366 : 12251315 : emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1367 : : }
1368 : :
1369 : : /* Fix up the destination if needed. */
1370 : 12251315 : if (dst != operands[0])
1371 : 466462 : emit_move_insn (operands[0], dst);
1372 : 12251315 : }
1373 : :
1374 : : /* Expand vector logical operation CODE (AND, IOR, XOR) in MODE with
1375 : : the given OPERANDS. */
1376 : :
1377 : : void
1378 : 40419 : ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode,
1379 : : rtx operands[])
1380 : : {
1381 : 40419 : rtx op1 = NULL_RTX, op2 = NULL_RTX;
1382 : 40419 : if (SUBREG_P (operands[1]))
1383 : : {
1384 : 320 : op1 = operands[1];
1385 : 320 : op2 = operands[2];
1386 : : }
1387 : 40099 : else if (SUBREG_P (operands[2]))
1388 : : {
1389 : : op1 = operands[2];
1390 : : op2 = operands[1];
1391 : : }
1392 : : /* Optimize (__m128i) d | (__m128i) e and similar code
1393 : : when d and e are float vectors into float vector logical
1394 : : insn. In C/C++ without using intrinsics there is no other way
1395 : : to express vector logical operation on float vectors than
1396 : : to cast them temporarily to integer vectors. */
1397 : 2351 : if (op1
1398 : 2351 : && !TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL
1399 : 2351 : && (SUBREG_P (op2) || GET_CODE (op2) == CONST_VECTOR)
1400 : 306 : && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op1))) == MODE_VECTOR_FLOAT
1401 : 303 : && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1))) == GET_MODE_SIZE (mode)
1402 : 101 : && SUBREG_BYTE (op1) == 0
1403 : 101 : && (GET_CODE (op2) == CONST_VECTOR
1404 : 1 : || (GET_MODE (SUBREG_REG (op1)) == GET_MODE (SUBREG_REG (op2))
1405 : 1 : && SUBREG_BYTE (op2) == 0))
1406 : 101 : && can_create_pseudo_p ())
1407 : : {
1408 : 101 : rtx dst;
1409 : 101 : switch (GET_MODE (SUBREG_REG (op1)))
1410 : : {
1411 : 17 : case E_V4SFmode:
1412 : 17 : case E_V8SFmode:
1413 : 17 : case E_V16SFmode:
1414 : 17 : case E_V2DFmode:
1415 : 17 : case E_V4DFmode:
1416 : 17 : case E_V8DFmode:
1417 : 17 : dst = gen_reg_rtx (GET_MODE (SUBREG_REG (op1)));
1418 : 17 : if (GET_CODE (op2) == CONST_VECTOR)
1419 : : {
1420 : 16 : op2 = gen_lowpart (GET_MODE (dst), op2);
1421 : 16 : op2 = force_reg (GET_MODE (dst), op2);
1422 : : }
1423 : : else
1424 : : {
1425 : 1 : op1 = operands[1];
1426 : 1 : op2 = SUBREG_REG (operands[2]);
1427 : 1 : if (!vector_operand (op2, GET_MODE (dst)))
1428 : 0 : op2 = force_reg (GET_MODE (dst), op2);
1429 : : }
1430 : 17 : op1 = SUBREG_REG (op1);
1431 : 17 : if (!vector_operand (op1, GET_MODE (dst)))
1432 : 0 : op1 = force_reg (GET_MODE (dst), op1);
1433 : 17 : emit_insn (gen_rtx_SET (dst,
1434 : : gen_rtx_fmt_ee (code, GET_MODE (dst),
1435 : : op1, op2)));
1436 : 17 : emit_move_insn (operands[0], gen_lowpart (mode, dst));
1437 : 17 : return;
1438 : : default:
1439 : : break;
1440 : : }
1441 : : }
1442 : 40402 : if (!vector_operand (operands[1], mode))
1443 : 0 : operands[1] = force_reg (mode, operands[1]);
1444 : 40402 : if (!vector_operand (operands[2], mode))
1445 : 8953 : operands[2] = force_reg (mode, operands[2]);
1446 : 40402 : ix86_fixup_binary_operands_no_copy (code, mode, operands);
1447 : 40402 : emit_insn (gen_rtx_SET (operands[0],
1448 : : gen_rtx_fmt_ee (code, mode, operands[1],
1449 : : operands[2])));
1450 : : }
1451 : :
1452 : : /* Return TRUE or FALSE depending on whether the binary operator meets the
1453 : : appropriate constraints. */
1454 : :
1455 : : bool
1456 : 147630200 : ix86_binary_operator_ok (enum rtx_code code, machine_mode mode,
1457 : : rtx operands[3], bool use_ndd)
1458 : : {
1459 : 147630200 : rtx dst = operands[0];
1460 : 147630200 : rtx src1 = operands[1];
1461 : 147630200 : rtx src2 = operands[2];
1462 : :
1463 : : /* Both source operands cannot be in memory. */
1464 : 140848133 : if ((MEM_P (src1) || bcst_mem_operand (src1, mode))
1465 : 147630591 : && (MEM_P (src2) || bcst_mem_operand (src2, mode)))
1466 : 847826 : return false;
1467 : :
1468 : : /* Canonicalize operand order for commutative operators. */
1469 : 146782374 : if (ix86_swap_binary_operands_p (code, mode, operands))
1470 : 517933 : std::swap (src1, src2);
1471 : :
1472 : : /* If the destination is memory, we must have a matching source operand. */
1473 : 146782374 : if (MEM_P (dst) && !rtx_equal_p (dst, src1))
1474 : : return false;
1475 : :
1476 : : /* Source 1 cannot be a constant. */
1477 : 142363891 : if (CONSTANT_P (src1))
1478 : : return false;
1479 : :
1480 : : /* Source 1 cannot be a non-matching memory. */
1481 : 142361116 : if (!use_ndd && MEM_P (src1) && !rtx_equal_p (dst, src1))
1482 : : /* Support "andhi/andsi/anddi" as a zero-extending move. */
1483 : 4120612 : return (code == AND
1484 : 485703 : && (mode == HImode
1485 : 485703 : || mode == SImode
1486 : 274578 : || (TARGET_64BIT && mode == DImode))
1487 : 4413049 : && satisfies_constraint_L (src2));
1488 : :
1489 : : return true;
1490 : : }
1491 : :
1492 : : /* Attempt to expand a unary operator. Make the expansion closer to the
1493 : : actual machine, then just general_operand, which will allow 2 separate
1494 : : memory references (one output, one input) in a single insn. */
1495 : :
1496 : : void
1497 : 108002 : ix86_expand_unary_operator (enum rtx_code code, machine_mode mode,
1498 : : rtx operands[], bool use_ndd)
1499 : : {
1500 : 108002 : bool matching_memory = false;
1501 : 108002 : rtx src, dst, op, clob;
1502 : :
1503 : 108002 : dst = operands[0];
1504 : 108002 : src = operands[1];
1505 : :
1506 : : /* If the destination is memory, and we do not have matching source
1507 : : operands, do things in registers. */
1508 : 108002 : if (MEM_P (dst))
1509 : : {
1510 : 3848 : if (rtx_equal_p (dst, src))
1511 : : matching_memory = true;
1512 : : else
1513 : 3557 : dst = gen_reg_rtx (mode);
1514 : : }
1515 : :
1516 : : /* When source operand is memory, destination must match. */
1517 : 108002 : if (!use_ndd && MEM_P (src) && !matching_memory)
1518 : 3598 : src = force_reg (mode, src);
1519 : :
1520 : : /* Emit the instruction. */
1521 : :
1522 : 108002 : op = gen_rtx_SET (dst, gen_rtx_fmt_e (code, mode, src));
1523 : :
1524 : 108002 : if (code == NOT)
1525 : 60745 : emit_insn (op);
1526 : : else
1527 : : {
1528 : 47257 : clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
1529 : 47257 : emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1530 : : }
1531 : :
1532 : : /* Fix up the destination if needed. */
1533 : 108002 : if (dst != operands[0])
1534 : 3557 : emit_move_insn (operands[0], dst);
1535 : 108002 : }
1536 : :
1537 : : /* Return TRUE or FALSE depending on whether the unary operator meets the
1538 : : appropriate constraints. */
1539 : :
1540 : : bool
1541 : 1537437 : ix86_unary_operator_ok (enum rtx_code,
1542 : : machine_mode,
1543 : : rtx operands[2],
1544 : : bool use_ndd)
1545 : : {
1546 : : /* If one of operands is memory, source and destination must match. */
1547 : 1537437 : if ((MEM_P (operands[0])
1548 : 1498671 : || (!use_ndd && MEM_P (operands[1])))
1549 : 1564975 : && ! rtx_equal_p (operands[0], operands[1]))
1550 : : return false;
1551 : : return true;
1552 : : }
1553 : :
1554 : : /* Predict just emitted jump instruction to be taken with probability PROB. */
1555 : :
1556 : : static void
1557 : 34686 : predict_jump (int prob)
1558 : : {
1559 : 34686 : rtx_insn *insn = get_last_insn ();
1560 : 34686 : gcc_assert (JUMP_P (insn));
1561 : 34686 : add_reg_br_prob_note (insn, profile_probability::from_reg_br_prob_base (prob));
1562 : 34686 : }
1563 : :
1564 : : /* Split 32bit/64bit divmod with 8bit unsigned divmod if dividend and
1565 : : divisor are within the range [0-255]. */
1566 : :
1567 : : void
1568 : 27 : ix86_split_idivmod (machine_mode mode, rtx operands[],
1569 : : bool unsigned_p)
1570 : : {
1571 : 27 : rtx_code_label *end_label, *qimode_label;
1572 : 27 : rtx div, mod;
1573 : 27 : rtx_insn *insn;
1574 : 27 : rtx scratch, tmp0, tmp1, tmp2;
1575 : 27 : rtx (*gen_divmod4_1) (rtx, rtx, rtx, rtx);
1576 : :
1577 : 27 : operands[2] = force_reg (mode, operands[2]);
1578 : 27 : operands[3] = force_reg (mode, operands[3]);
1579 : :
1580 : 27 : switch (mode)
1581 : : {
1582 : 20 : case E_SImode:
1583 : 20 : if (GET_MODE (operands[0]) == SImode)
1584 : : {
1585 : 16 : if (GET_MODE (operands[1]) == SImode)
1586 : 14 : gen_divmod4_1 = unsigned_p ? gen_udivmodsi4_1 : gen_divmodsi4_1;
1587 : : else
1588 : 2 : gen_divmod4_1
1589 : 2 : = unsigned_p ? gen_udivmodsi4_zext_2 : gen_divmodsi4_zext_2;
1590 : : }
1591 : : else
1592 : 4 : gen_divmod4_1
1593 : 4 : = unsigned_p ? gen_udivmodsi4_zext_1 : gen_divmodsi4_zext_1;
1594 : : break;
1595 : :
1596 : 7 : case E_DImode:
1597 : 7 : gen_divmod4_1 = unsigned_p ? gen_udivmoddi4_1 : gen_divmoddi4_1;
1598 : : break;
1599 : :
1600 : 0 : default:
1601 : 0 : gcc_unreachable ();
1602 : : }
1603 : :
1604 : 27 : end_label = gen_label_rtx ();
1605 : 27 : qimode_label = gen_label_rtx ();
1606 : :
1607 : 27 : scratch = gen_reg_rtx (mode);
1608 : :
1609 : : /* Use 8bit unsigned divimod if dividend and divisor are within
1610 : : the range [0-255]. */
1611 : 27 : emit_move_insn (scratch, operands[2]);
1612 : 27 : scratch = expand_simple_binop (mode, IOR, scratch, operands[3],
1613 : : scratch, 1, OPTAB_DIRECT);
1614 : 27 : emit_insn (gen_test_ccno_1 (mode, scratch, GEN_INT (-0x100)));
1615 : 27 : tmp0 = gen_rtx_REG (CCNOmode, FLAGS_REG);
1616 : 27 : tmp0 = gen_rtx_EQ (VOIDmode, tmp0, const0_rtx);
1617 : 27 : tmp0 = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp0,
1618 : : gen_rtx_LABEL_REF (VOIDmode, qimode_label),
1619 : : pc_rtx);
1620 : 27 : insn = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp0));
1621 : 27 : predict_jump (REG_BR_PROB_BASE * 50 / 100);
1622 : 27 : JUMP_LABEL (insn) = qimode_label;
1623 : :
1624 : : /* Generate original signed/unsigned divimod. */
1625 : 27 : emit_insn (gen_divmod4_1 (operands[0], operands[1],
1626 : : operands[2], operands[3]));
1627 : :
1628 : : /* Branch to the end. */
1629 : 27 : emit_jump_insn (gen_jump (end_label));
1630 : 27 : emit_barrier ();
1631 : :
1632 : : /* Generate 8bit unsigned divide. */
1633 : 27 : emit_label (qimode_label);
1634 : : /* Don't use operands[0] for result of 8bit divide since not all
1635 : : registers support QImode ZERO_EXTRACT. */
1636 : 27 : tmp0 = lowpart_subreg (HImode, scratch, mode);
1637 : 27 : tmp1 = lowpart_subreg (HImode, operands[2], mode);
1638 : 27 : tmp2 = lowpart_subreg (QImode, operands[3], mode);
1639 : 27 : emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, tmp2));
1640 : :
1641 : 27 : if (unsigned_p)
1642 : : {
1643 : 12 : div = gen_rtx_UDIV (mode, operands[2], operands[3]);
1644 : 12 : mod = gen_rtx_UMOD (mode, operands[2], operands[3]);
1645 : : }
1646 : : else
1647 : : {
1648 : 15 : div = gen_rtx_DIV (mode, operands[2], operands[3]);
1649 : 15 : mod = gen_rtx_MOD (mode, operands[2], operands[3]);
1650 : : }
1651 : 27 : if (mode == SImode)
1652 : : {
1653 : 20 : if (GET_MODE (operands[0]) != SImode)
1654 : 4 : div = gen_rtx_ZERO_EXTEND (DImode, div);
1655 : 20 : if (GET_MODE (operands[1]) != SImode)
1656 : 2 : mod = gen_rtx_ZERO_EXTEND (DImode, mod);
1657 : : }
1658 : :
1659 : : /* Extract remainder from AH. */
1660 : 27 : scratch = gen_lowpart (GET_MODE (operands[1]), scratch);
1661 : 27 : tmp1 = gen_rtx_ZERO_EXTRACT (GET_MODE (operands[1]), scratch,
1662 : : GEN_INT (8), GEN_INT (8));
1663 : 27 : insn = emit_move_insn (operands[1], tmp1);
1664 : 27 : set_unique_reg_note (insn, REG_EQUAL, mod);
1665 : :
1666 : : /* Zero extend quotient from AL. */
1667 : 27 : tmp1 = gen_lowpart (QImode, tmp0);
1668 : 27 : insn = emit_insn (gen_extend_insn
1669 : 27 : (operands[0], tmp1,
1670 : 27 : GET_MODE (operands[0]), QImode, 1));
1671 : 27 : set_unique_reg_note (insn, REG_EQUAL, div);
1672 : :
1673 : 27 : emit_label (end_label);
1674 : 27 : }
1675 : :
1676 : : /* Emit x86 binary operand CODE in mode MODE, where the first operand
1677 : : matches destination. RTX includes clobber of FLAGS_REG. */
1678 : :
1679 : : void
1680 : 6519 : ix86_emit_binop (enum rtx_code code, machine_mode mode,
1681 : : rtx dst, rtx src)
1682 : : {
1683 : 6519 : rtx op, clob;
1684 : :
1685 : 6519 : op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, mode, dst, src));
1686 : 6519 : clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
1687 : :
1688 : 6519 : emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1689 : 6519 : }
1690 : :
1691 : : /* Return true if regno1 def is nearest to the insn. */
1692 : :
1693 : : static bool
1694 : 16 : find_nearest_reg_def (rtx_insn *insn, int regno1, int regno2)
1695 : : {
1696 : 16 : rtx_insn *prev = insn;
1697 : 16 : rtx_insn *start = BB_HEAD (BLOCK_FOR_INSN (insn));
1698 : :
1699 : 16 : if (insn == start)
1700 : : return false;
1701 : 42 : while (prev && prev != start)
1702 : : {
1703 : 32 : if (!INSN_P (prev) || !NONDEBUG_INSN_P (prev))
1704 : : {
1705 : 10 : prev = PREV_INSN (prev);
1706 : 10 : continue;
1707 : : }
1708 : 22 : if (insn_defines_reg (regno1, INVALID_REGNUM, prev))
1709 : : return true;
1710 : 16 : else if (insn_defines_reg (regno2, INVALID_REGNUM, prev))
1711 : : return false;
1712 : 16 : prev = PREV_INSN (prev);
1713 : : }
1714 : :
1715 : : /* None of the regs is defined in the bb. */
1716 : : return false;
1717 : : }
1718 : :
1719 : : /* INSN_UID of the last insn emitted by zero store peephole2s. */
1720 : : int ix86_last_zero_store_uid;
1721 : :
1722 : : /* Split lea instructions into a sequence of instructions
1723 : : which are executed on ALU to avoid AGU stalls.
1724 : : It is assumed that it is allowed to clobber flags register
1725 : : at lea position. */
1726 : :
1727 : : void
1728 : 4708 : ix86_split_lea_for_addr (rtx_insn *insn, rtx operands[], machine_mode mode)
1729 : : {
1730 : 4708 : unsigned int regno0, regno1, regno2;
1731 : 4708 : struct ix86_address parts;
1732 : 4708 : rtx target, tmp;
1733 : 4708 : int ok, adds;
1734 : :
1735 : 4708 : ok = ix86_decompose_address (operands[1], &parts);
1736 : 4708 : gcc_assert (ok);
1737 : :
1738 : 4708 : target = gen_lowpart (mode, operands[0]);
1739 : :
1740 : 4708 : regno0 = true_regnum (target);
1741 : 4708 : regno1 = INVALID_REGNUM;
1742 : 4708 : regno2 = INVALID_REGNUM;
1743 : :
1744 : 4708 : if (parts.base)
1745 : : {
1746 : 4700 : parts.base = gen_lowpart (mode, parts.base);
1747 : 4700 : regno1 = true_regnum (parts.base);
1748 : : }
1749 : :
1750 : 4708 : if (parts.index)
1751 : : {
1752 : 4707 : parts.index = gen_lowpart (mode, parts.index);
1753 : 4707 : regno2 = true_regnum (parts.index);
1754 : : }
1755 : :
1756 : 4708 : if (parts.disp)
1757 : 162 : parts.disp = gen_lowpart (mode, parts.disp);
1758 : :
1759 : 4708 : if (parts.scale > 1)
1760 : : {
1761 : : /* Case r1 = r1 + ... */
1762 : 12 : if (regno1 == regno0)
1763 : : {
1764 : : /* If we have a case r1 = r1 + C * r2 then we
1765 : : should use multiplication which is very
1766 : : expensive. Assume cost model is wrong if we
1767 : : have such case here. */
1768 : 0 : gcc_assert (regno2 != regno0);
1769 : :
1770 : 0 : for (adds = parts.scale; adds > 0; adds--)
1771 : 0 : ix86_emit_binop (PLUS, mode, target, parts.index);
1772 : : }
1773 : : else
1774 : : {
1775 : : /* r1 = r2 + r3 * C case. Need to move r3 into r1. */
1776 : 12 : if (regno0 != regno2)
1777 : 7 : emit_insn (gen_rtx_SET (target, parts.index));
1778 : :
1779 : : /* Use shift for scaling, but emit it as MULT instead
1780 : : to avoid it being immediately peephole2 optimized back
1781 : : into lea. */
1782 : 12 : ix86_emit_binop (MULT, mode, target, GEN_INT (parts.scale));
1783 : :
1784 : 12 : if (parts.base)
1785 : 4 : ix86_emit_binop (PLUS, mode, target, parts.base);
1786 : :
1787 : 12 : if (parts.disp && parts.disp != const0_rtx)
1788 : 3 : ix86_emit_binop (PLUS, mode, target, parts.disp);
1789 : : }
1790 : : }
1791 : 4696 : else if (!parts.base && !parts.index)
1792 : : {
1793 : 0 : gcc_assert(parts.disp);
1794 : 0 : emit_insn (gen_rtx_SET (target, parts.disp));
1795 : : }
1796 : : else
1797 : : {
1798 : 4696 : if (!parts.base)
1799 : : {
1800 : 0 : if (regno0 != regno2)
1801 : 0 : emit_insn (gen_rtx_SET (target, parts.index));
1802 : : }
1803 : 4696 : else if (!parts.index)
1804 : : {
1805 : 1 : if (regno0 != regno1)
1806 : 1 : emit_insn (gen_rtx_SET (target, parts.base));
1807 : : }
1808 : : else
1809 : : {
1810 : 4695 : if (regno0 == regno1)
1811 : : tmp = parts.index;
1812 : 2421 : else if (regno0 == regno2)
1813 : : tmp = parts.base;
1814 : : else
1815 : : {
1816 : 16 : rtx tmp1;
1817 : :
1818 : : /* Find better operand for SET instruction, depending
1819 : : on which definition is farther from the insn. */
1820 : 16 : if (find_nearest_reg_def (insn, regno1, regno2))
1821 : 6 : tmp = parts.index, tmp1 = parts.base;
1822 : : else
1823 : 10 : tmp = parts.base, tmp1 = parts.index;
1824 : :
1825 : 16 : emit_insn (gen_rtx_SET (target, tmp));
1826 : :
1827 : 16 : if (parts.disp && parts.disp != const0_rtx)
1828 : 0 : ix86_emit_binop (PLUS, mode, target, parts.disp);
1829 : :
1830 : 16 : ix86_emit_binop (PLUS, mode, target, tmp1);
1831 : 16 : return;
1832 : : }
1833 : :
1834 : 4679 : ix86_emit_binop (PLUS, mode, target, tmp);
1835 : : }
1836 : :
1837 : 4680 : if (parts.disp && parts.disp != const0_rtx)
1838 : 2 : ix86_emit_binop (PLUS, mode, target, parts.disp);
1839 : : }
1840 : : }
1841 : :
1842 : : /* Post-reload splitter for converting an SF or DFmode value in an
1843 : : SSE register into an unsigned SImode. */
1844 : :
1845 : : void
1846 : 0 : ix86_split_convert_uns_si_sse (rtx operands[])
1847 : : {
1848 : 0 : machine_mode vecmode;
1849 : 0 : rtx value, large, zero_or_two31, input, two31, x;
1850 : :
1851 : 0 : large = operands[1];
1852 : 0 : zero_or_two31 = operands[2];
1853 : 0 : input = operands[3];
1854 : 0 : two31 = operands[4];
1855 : 0 : vecmode = GET_MODE (large);
1856 : 0 : value = gen_rtx_REG (vecmode, REGNO (operands[0]));
1857 : :
1858 : : /* Load up the value into the low element. We must ensure that the other
1859 : : elements are valid floats -- zero is the easiest such value. */
1860 : 0 : if (MEM_P (input))
1861 : : {
1862 : 0 : if (vecmode == V4SFmode)
1863 : 0 : emit_insn (gen_vec_setv4sf_0 (value, CONST0_RTX (V4SFmode), input));
1864 : : else
1865 : 0 : emit_insn (gen_sse2_loadlpd (value, CONST0_RTX (V2DFmode), input));
1866 : : }
1867 : : else
1868 : : {
1869 : 0 : input = gen_rtx_REG (vecmode, REGNO (input));
1870 : 0 : emit_move_insn (value, CONST0_RTX (vecmode));
1871 : 0 : if (vecmode == V4SFmode)
1872 : 0 : emit_insn (gen_sse_movss_v4sf (value, value, input));
1873 : : else
1874 : 0 : emit_insn (gen_sse2_movsd_v2df (value, value, input));
1875 : : }
1876 : :
1877 : 0 : emit_move_insn (large, two31);
1878 : 0 : emit_move_insn (zero_or_two31, MEM_P (two31) ? large : two31);
1879 : :
1880 : 0 : x = gen_rtx_fmt_ee (LE, vecmode, large, value);
1881 : 0 : emit_insn (gen_rtx_SET (large, x));
1882 : :
1883 : 0 : x = gen_rtx_AND (vecmode, zero_or_two31, large);
1884 : 0 : emit_insn (gen_rtx_SET (zero_or_two31, x));
1885 : :
1886 : 0 : x = gen_rtx_MINUS (vecmode, value, zero_or_two31);
1887 : 0 : emit_insn (gen_rtx_SET (value, x));
1888 : :
1889 : 0 : large = gen_rtx_REG (V4SImode, REGNO (large));
1890 : 0 : emit_insn (gen_ashlv4si3 (large, large, GEN_INT (31)));
1891 : :
1892 : 0 : x = gen_rtx_REG (V4SImode, REGNO (value));
1893 : 0 : if (vecmode == V4SFmode)
1894 : 0 : emit_insn (gen_fix_truncv4sfv4si2 (x, value));
1895 : : else
1896 : 0 : emit_insn (gen_sse2_cvttpd2dq (x, value));
1897 : 0 : value = x;
1898 : :
1899 : 0 : emit_insn (gen_xorv4si3 (value, value, large));
1900 : 0 : }
1901 : :
1902 : : /* Convert an unsigned DImode value into a DFmode, using only SSE.
1903 : : Expects the 64-bit DImode to be supplied in a pair of integral
1904 : : registers. Requires SSE2; will use SSE3 if available. For x86_32,
1905 : : -mfpmath=sse, !optimize_size only. */
1906 : :
1907 : : void
1908 : 0 : ix86_expand_convert_uns_didf_sse (rtx target, rtx input)
1909 : : {
1910 : 0 : REAL_VALUE_TYPE bias_lo_rvt, bias_hi_rvt;
1911 : 0 : rtx int_xmm, fp_xmm;
1912 : 0 : rtx biases, exponents;
1913 : 0 : rtx x;
1914 : :
1915 : 0 : int_xmm = gen_reg_rtx (V4SImode);
1916 : 0 : if (TARGET_INTER_UNIT_MOVES_TO_VEC)
1917 : 0 : emit_insn (gen_movdi_to_sse (int_xmm, input));
1918 : 0 : else if (TARGET_SSE_SPLIT_REGS)
1919 : : {
1920 : 0 : emit_clobber (int_xmm);
1921 : 0 : emit_move_insn (gen_lowpart (DImode, int_xmm), input);
1922 : : }
1923 : : else
1924 : : {
1925 : 0 : x = gen_reg_rtx (V2DImode);
1926 : 0 : ix86_expand_vector_init_one_nonzero (false, V2DImode, x, input, 0);
1927 : 0 : emit_move_insn (int_xmm, gen_lowpart (V4SImode, x));
1928 : : }
1929 : :
1930 : 0 : x = gen_rtx_CONST_VECTOR (V4SImode,
1931 : : gen_rtvec (4, GEN_INT (0x43300000UL),
1932 : : GEN_INT (0x45300000UL),
1933 : : const0_rtx, const0_rtx));
1934 : 0 : exponents = validize_mem (force_const_mem (V4SImode, x));
1935 : :
1936 : : /* int_xmm = {0x45300000UL, fp_xmm/hi, 0x43300000, fp_xmm/lo } */
1937 : 0 : emit_insn (gen_vec_interleave_lowv4si (int_xmm, int_xmm, exponents));
1938 : :
1939 : : /* Concatenating (juxtaposing) (0x43300000UL ## fp_value_low_xmm)
1940 : : yields a valid DF value equal to (0x1.0p52 + double(fp_value_lo_xmm)).
1941 : : Similarly (0x45300000UL ## fp_value_hi_xmm) yields
1942 : : (0x1.0p84 + double(fp_value_hi_xmm)).
1943 : : Note these exponents differ by 32. */
1944 : :
1945 : 0 : fp_xmm = copy_to_mode_reg (V2DFmode, gen_lowpart (V2DFmode, int_xmm));
1946 : :
1947 : : /* Subtract off those 0x1.0p52 and 0x1.0p84 biases, to produce values
1948 : : in [0,2**32-1] and [0]+[2**32,2**64-1] respectively. */
1949 : 0 : real_ldexp (&bias_lo_rvt, &dconst1, 52);
1950 : 0 : real_ldexp (&bias_hi_rvt, &dconst1, 84);
1951 : 0 : biases = const_double_from_real_value (bias_lo_rvt, DFmode);
1952 : 0 : x = const_double_from_real_value (bias_hi_rvt, DFmode);
1953 : 0 : biases = gen_rtx_CONST_VECTOR (V2DFmode, gen_rtvec (2, biases, x));
1954 : 0 : biases = validize_mem (force_const_mem (V2DFmode, biases));
1955 : 0 : emit_insn (gen_subv2df3 (fp_xmm, fp_xmm, biases));
1956 : :
1957 : : /* Add the upper and lower DFmode values together. */
1958 : 0 : if (TARGET_SSE3)
1959 : 0 : emit_insn (gen_sse3_haddv2df3 (fp_xmm, fp_xmm, fp_xmm));
1960 : : else
1961 : : {
1962 : 0 : x = copy_to_mode_reg (V2DFmode, fp_xmm);
1963 : 0 : emit_insn (gen_vec_interleave_highv2df (fp_xmm, fp_xmm, fp_xmm));
1964 : 0 : emit_insn (gen_addv2df3 (fp_xmm, fp_xmm, x));
1965 : : }
1966 : :
1967 : 0 : ix86_expand_vector_extract (false, target, fp_xmm, 0);
1968 : 0 : }
1969 : :
1970 : : /* Not used, but eases macroization of patterns. */
1971 : : void
1972 : 0 : ix86_expand_convert_uns_sixf_sse (rtx, rtx)
1973 : : {
1974 : 0 : gcc_unreachable ();
1975 : : }
1976 : :
1977 : : static rtx ix86_expand_sse_fabs (rtx op0, rtx *smask);
1978 : :
1979 : : /* Convert an unsigned SImode value into a DFmode. Only currently used
1980 : : for SSE, but applicable anywhere. */
1981 : :
1982 : : void
1983 : 0 : ix86_expand_convert_uns_sidf_sse (rtx target, rtx input)
1984 : : {
1985 : 0 : REAL_VALUE_TYPE TWO31r;
1986 : 0 : rtx x, fp;
1987 : :
1988 : 0 : x = expand_simple_binop (SImode, PLUS, input, GEN_INT (-2147483647 - 1),
1989 : : NULL, 1, OPTAB_DIRECT);
1990 : :
1991 : 0 : fp = gen_reg_rtx (DFmode);
1992 : 0 : emit_insn (gen_floatsidf2 (fp, x));
1993 : :
1994 : 0 : real_ldexp (&TWO31r, &dconst1, 31);
1995 : 0 : x = const_double_from_real_value (TWO31r, DFmode);
1996 : :
1997 : 0 : x = expand_simple_binop (DFmode, PLUS, fp, x, target, 0, OPTAB_DIRECT);
1998 : :
1999 : : /* Remove the sign with FE_DOWNWARD, where x - x = -0.0. */
2000 : 0 : if (HONOR_SIGNED_ZEROS (DFmode) && flag_rounding_math)
2001 : 0 : x = ix86_expand_sse_fabs (x, NULL);
2002 : :
2003 : 0 : if (x != target)
2004 : 0 : emit_move_insn (target, x);
2005 : 0 : }
2006 : :
2007 : : /* Convert a signed DImode value into a DFmode. Only used for SSE in
2008 : : 32-bit mode; otherwise we have a direct convert instruction. */
2009 : :
2010 : : void
2011 : 0 : ix86_expand_convert_sign_didf_sse (rtx target, rtx input)
2012 : : {
2013 : 0 : REAL_VALUE_TYPE TWO32r;
2014 : 0 : rtx fp_lo, fp_hi, x;
2015 : :
2016 : 0 : fp_lo = gen_reg_rtx (DFmode);
2017 : 0 : fp_hi = gen_reg_rtx (DFmode);
2018 : :
2019 : 0 : emit_insn (gen_floatsidf2 (fp_hi, gen_highpart (SImode, input)));
2020 : :
2021 : 0 : real_ldexp (&TWO32r, &dconst1, 32);
2022 : 0 : x = const_double_from_real_value (TWO32r, DFmode);
2023 : 0 : fp_hi = expand_simple_binop (DFmode, MULT, fp_hi, x, fp_hi, 0, OPTAB_DIRECT);
2024 : :
2025 : 0 : ix86_expand_convert_uns_sidf_sse (fp_lo, gen_lowpart (SImode, input));
2026 : :
2027 : 0 : x = expand_simple_binop (DFmode, PLUS, fp_hi, fp_lo, target,
2028 : : 0, OPTAB_DIRECT);
2029 : 0 : if (x != target)
2030 : 0 : emit_move_insn (target, x);
2031 : 0 : }
2032 : :
2033 : : /* Convert an unsigned SImode value into a SFmode, using only SSE.
2034 : : For x86_32, -mfpmath=sse, !optimize_size only. */
2035 : : void
2036 : 0 : ix86_expand_convert_uns_sisf_sse (rtx target, rtx input)
2037 : : {
2038 : 0 : REAL_VALUE_TYPE ONE16r;
2039 : 0 : rtx fp_hi, fp_lo, int_hi, int_lo, x;
2040 : :
2041 : 0 : real_ldexp (&ONE16r, &dconst1, 16);
2042 : 0 : x = const_double_from_real_value (ONE16r, SFmode);
2043 : 0 : int_lo = expand_simple_binop (SImode, AND, input, GEN_INT(0xffff),
2044 : : NULL, 0, OPTAB_DIRECT);
2045 : 0 : int_hi = expand_simple_binop (SImode, LSHIFTRT, input, GEN_INT(16),
2046 : : NULL, 0, OPTAB_DIRECT);
2047 : 0 : fp_hi = gen_reg_rtx (SFmode);
2048 : 0 : fp_lo = gen_reg_rtx (SFmode);
2049 : 0 : emit_insn (gen_floatsisf2 (fp_hi, int_hi));
2050 : 0 : emit_insn (gen_floatsisf2 (fp_lo, int_lo));
2051 : 0 : if (TARGET_FMA)
2052 : : {
2053 : 0 : x = validize_mem (force_const_mem (SFmode, x));
2054 : 0 : fp_hi = gen_rtx_FMA (SFmode, fp_hi, x, fp_lo);
2055 : 0 : emit_move_insn (target, fp_hi);
2056 : : }
2057 : : else
2058 : : {
2059 : 0 : fp_hi = expand_simple_binop (SFmode, MULT, fp_hi, x, fp_hi,
2060 : : 0, OPTAB_DIRECT);
2061 : 0 : fp_hi = expand_simple_binop (SFmode, PLUS, fp_hi, fp_lo, target,
2062 : : 0, OPTAB_DIRECT);
2063 : 0 : if (!rtx_equal_p (target, fp_hi))
2064 : 0 : emit_move_insn (target, fp_hi);
2065 : : }
2066 : 0 : }
2067 : :
2068 : : /* floatunsv{4,8}siv{4,8}sf2 expander. Expand code to convert
2069 : : a vector of unsigned ints VAL to vector of floats TARGET. */
2070 : :
2071 : : void
2072 : 46 : ix86_expand_vector_convert_uns_vsivsf (rtx target, rtx val)
2073 : : {
2074 : 46 : rtx tmp[8];
2075 : 46 : REAL_VALUE_TYPE TWO16r;
2076 : 46 : machine_mode intmode = GET_MODE (val);
2077 : 46 : machine_mode fltmode = GET_MODE (target);
2078 : 46 : rtx (*cvt) (rtx, rtx);
2079 : :
2080 : 46 : if (intmode == V4SImode)
2081 : : cvt = gen_floatv4siv4sf2;
2082 : : else
2083 : 2 : cvt = gen_floatv8siv8sf2;
2084 : 46 : tmp[0] = ix86_build_const_vector (intmode, 1, GEN_INT (0xffff));
2085 : 46 : tmp[0] = force_reg (intmode, tmp[0]);
2086 : 46 : tmp[1] = expand_simple_binop (intmode, AND, val, tmp[0], NULL_RTX, 1,
2087 : : OPTAB_DIRECT);
2088 : 46 : tmp[2] = expand_simple_binop (intmode, LSHIFTRT, val, GEN_INT (16),
2089 : : NULL_RTX, 1, OPTAB_DIRECT);
2090 : 46 : tmp[3] = gen_reg_rtx (fltmode);
2091 : 46 : emit_insn (cvt (tmp[3], tmp[1]));
2092 : 46 : tmp[4] = gen_reg_rtx (fltmode);
2093 : 46 : emit_insn (cvt (tmp[4], tmp[2]));
2094 : 46 : real_ldexp (&TWO16r, &dconst1, 16);
2095 : 46 : tmp[5] = const_double_from_real_value (TWO16r, SFmode);
2096 : 46 : tmp[5] = force_reg (fltmode, ix86_build_const_vector (fltmode, 1, tmp[5]));
2097 : 46 : if (TARGET_FMA)
2098 : : {
2099 : 1 : tmp[6] = gen_rtx_FMA (fltmode, tmp[4], tmp[5], tmp[3]);
2100 : 1 : emit_move_insn (target, tmp[6]);
2101 : : }
2102 : : else
2103 : : {
2104 : 45 : tmp[6] = expand_simple_binop (fltmode, MULT, tmp[4], tmp[5],
2105 : : NULL_RTX, 1, OPTAB_DIRECT);
2106 : 45 : tmp[7] = expand_simple_binop (fltmode, PLUS, tmp[3], tmp[6],
2107 : : target, 1, OPTAB_DIRECT);
2108 : 45 : if (tmp[7] != target)
2109 : 0 : emit_move_insn (target, tmp[7]);
2110 : : }
2111 : 46 : }
2112 : :
2113 : : /* Adjust a V*SFmode/V*DFmode value VAL so that *sfix_trunc* resp. fix_trunc*
2114 : : pattern can be used on it instead of fixuns_trunc*.
2115 : : This is done by doing just signed conversion if < 0x1p31, and otherwise by
2116 : : subtracting 0x1p31 first and xoring in 0x80000000 from *XORP afterwards. */
2117 : :
2118 : : rtx
2119 : 68 : ix86_expand_adjust_ufix_to_sfix_si (rtx val, rtx *xorp)
2120 : : {
2121 : 68 : REAL_VALUE_TYPE TWO31r;
2122 : 68 : rtx two31r, tmp[4];
2123 : 68 : machine_mode mode = GET_MODE (val);
2124 : 68 : machine_mode scalarmode = GET_MODE_INNER (mode);
2125 : 136 : machine_mode intmode = GET_MODE_SIZE (mode) == 32 ? V8SImode : V4SImode;
2126 : 68 : rtx (*cmp) (rtx, rtx, rtx, rtx);
2127 : 68 : int i;
2128 : :
2129 : 272 : for (i = 0; i < 3; i++)
2130 : 204 : tmp[i] = gen_reg_rtx (mode);
2131 : 68 : real_ldexp (&TWO31r, &dconst1, 31);
2132 : 68 : two31r = const_double_from_real_value (TWO31r, scalarmode);
2133 : 68 : two31r = ix86_build_const_vector (mode, 1, two31r);
2134 : 68 : two31r = force_reg (mode, two31r);
2135 : 68 : switch (mode)
2136 : : {
2137 : : case E_V8SFmode: cmp = gen_avx_maskcmpv8sf3; break;
2138 : 8 : case E_V4SFmode: cmp = gen_sse_maskcmpv4sf3; break;
2139 : 2 : case E_V4DFmode: cmp = gen_avx_maskcmpv4df3; break;
2140 : 58 : case E_V2DFmode: cmp = gen_sse2_maskcmpv2df3; break;
2141 : 0 : default: gcc_unreachable ();
2142 : : }
2143 : 68 : tmp[3] = gen_rtx_LE (mode, two31r, val);
2144 : 68 : emit_insn (cmp (tmp[0], two31r, val, tmp[3]));
2145 : 68 : tmp[1] = expand_simple_binop (mode, AND, tmp[0], two31r, tmp[1],
2146 : : 0, OPTAB_DIRECT);
2147 : 68 : if (intmode == V4SImode || TARGET_AVX2)
2148 : 136 : *xorp = expand_simple_binop (intmode, ASHIFT,
2149 : 68 : gen_lowpart (intmode, tmp[0]),
2150 : : GEN_INT (31), NULL_RTX, 0,
2151 : : OPTAB_DIRECT);
2152 : : else
2153 : : {
2154 : 0 : rtx two31 = gen_int_mode (HOST_WIDE_INT_1U << 31, SImode);
2155 : 0 : two31 = ix86_build_const_vector (intmode, 1, two31);
2156 : 0 : *xorp = expand_simple_binop (intmode, AND,
2157 : 0 : gen_lowpart (intmode, tmp[0]),
2158 : : two31, NULL_RTX, 0,
2159 : : OPTAB_DIRECT);
2160 : : }
2161 : 68 : return expand_simple_binop (mode, MINUS, val, tmp[1], tmp[2],
2162 : 68 : 0, OPTAB_DIRECT);
2163 : : }
2164 : :
2165 : : /* Generate code for floating point ABS or NEG. */
2166 : :
2167 : : void
2168 : 32615 : ix86_expand_fp_absneg_operator (enum rtx_code code, machine_mode mode,
2169 : : rtx operands[])
2170 : : {
2171 : 32615 : rtx set, dst, src;
2172 : 32615 : bool use_sse = false;
2173 : 32615 : bool vector_mode = VECTOR_MODE_P (mode);
2174 : 32615 : machine_mode vmode = mode;
2175 : 32615 : rtvec par;
2176 : :
2177 : 32615 : switch (mode)
2178 : : {
2179 : : case E_HFmode:
2180 : : use_sse = true;
2181 : : vmode = V8HFmode;
2182 : : break;
2183 : 0 : case E_BFmode:
2184 : 0 : use_sse = true;
2185 : 0 : vmode = V8BFmode;
2186 : 0 : break;
2187 : 9119 : case E_SFmode:
2188 : 9119 : use_sse = TARGET_SSE_MATH && TARGET_SSE;
2189 : : vmode = V4SFmode;
2190 : : break;
2191 : 14874 : case E_DFmode:
2192 : 14874 : use_sse = TARGET_SSE_MATH && TARGET_SSE2;
2193 : : vmode = V2DFmode;
2194 : : break;
2195 : 8523 : default:
2196 : 8523 : use_sse = vector_mode || mode == TFmode;
2197 : 8523 : break;
2198 : : }
2199 : :
2200 : 32615 : dst = operands[0];
2201 : 32615 : src = operands[1];
2202 : :
2203 : 32615 : set = gen_rtx_fmt_e (code, mode, src);
2204 : 32615 : set = gen_rtx_SET (dst, set);
2205 : :
2206 : 32615 : if (use_sse)
2207 : : {
2208 : 27288 : rtx mask, use, clob;
2209 : :
2210 : : /* NEG and ABS performed with SSE use bitwise mask operations.
2211 : : Create the appropriate mask now. */
2212 : 27288 : mask = ix86_build_signbit_mask (vmode, vector_mode, code == ABS);
2213 : 27288 : use = gen_rtx_USE (VOIDmode, mask);
2214 : 27288 : if (vector_mode || mode == TFmode)
2215 : 4498 : par = gen_rtvec (2, set, use);
2216 : : else
2217 : : {
2218 : 22790 : clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
2219 : 22790 : par = gen_rtvec (3, set, use, clob);
2220 : : }
2221 : : }
2222 : : else
2223 : : {
2224 : 5327 : rtx clob;
2225 : :
2226 : : /* Changing of sign for FP values is doable using integer unit too. */
2227 : 5327 : clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
2228 : 5327 : par = gen_rtvec (2, set, clob);
2229 : : }
2230 : :
2231 : 32615 : emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
2232 : 32615 : }
2233 : :
2234 : : /* Deconstruct a floating point ABS or NEG operation
2235 : : with integer registers into integer operations. */
2236 : :
2237 : : void
2238 : 24 : ix86_split_fp_absneg_operator (enum rtx_code code, machine_mode mode,
2239 : : rtx operands[])
2240 : : {
2241 : 24 : enum rtx_code absneg_op;
2242 : 24 : rtx dst, set;
2243 : :
2244 : 24 : gcc_assert (operands_match_p (operands[0], operands[1]));
2245 : :
2246 : 24 : switch (mode)
2247 : : {
2248 : 0 : case E_SFmode:
2249 : 0 : dst = gen_lowpart (SImode, operands[0]);
2250 : :
2251 : 0 : if (code == ABS)
2252 : : {
2253 : 0 : set = gen_int_mode (0x7fffffff, SImode);
2254 : 0 : absneg_op = AND;
2255 : : }
2256 : : else
2257 : : {
2258 : 0 : set = gen_int_mode (0x80000000, SImode);
2259 : 0 : absneg_op = XOR;
2260 : : }
2261 : 0 : set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set);
2262 : 0 : break;
2263 : :
2264 : 1 : case E_DFmode:
2265 : 1 : if (TARGET_64BIT)
2266 : : {
2267 : 1 : dst = gen_lowpart (DImode, operands[0]);
2268 : 1 : dst = gen_rtx_ZERO_EXTRACT (DImode, dst, const1_rtx, GEN_INT (63));
2269 : :
2270 : 1 : if (code == ABS)
2271 : 0 : set = const0_rtx;
2272 : : else
2273 : 1 : set = gen_rtx_NOT (DImode, dst);
2274 : : }
2275 : : else
2276 : : {
2277 : 0 : dst = gen_highpart (SImode, operands[0]);
2278 : :
2279 : 0 : if (code == ABS)
2280 : : {
2281 : 0 : set = gen_int_mode (0x7fffffff, SImode);
2282 : 0 : absneg_op = AND;
2283 : : }
2284 : : else
2285 : : {
2286 : 0 : set = gen_int_mode (0x80000000, SImode);
2287 : 0 : absneg_op = XOR;
2288 : : }
2289 : 0 : set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set);
2290 : : }
2291 : : break;
2292 : :
2293 : 23 : case E_XFmode:
2294 : 23 : dst = gen_rtx_REG (SImode,
2295 : 23 : REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
2296 : 23 : if (code == ABS)
2297 : : {
2298 : 1 : set = GEN_INT (0x7fff);
2299 : 1 : absneg_op = AND;
2300 : : }
2301 : : else
2302 : : {
2303 : 22 : set = GEN_INT (0x8000);
2304 : 22 : absneg_op = XOR;
2305 : : }
2306 : 23 : set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set);
2307 : 23 : break;
2308 : :
2309 : 0 : default:
2310 : 0 : gcc_unreachable ();
2311 : : }
2312 : :
2313 : 24 : set = gen_rtx_SET (dst, set);
2314 : :
2315 : 24 : rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
2316 : 24 : rtvec par = gen_rtvec (2, set, clob);
2317 : :
2318 : 24 : emit_insn (gen_rtx_PARALLEL (VOIDmode, par));
2319 : 24 : }
2320 : :
2321 : : /* Expand a copysign operation. Special case operand 0 being a constant. */
2322 : :
2323 : : void
2324 : 23192 : ix86_expand_copysign (rtx operands[])
2325 : : {
2326 : 23192 : machine_mode mode, vmode;
2327 : 23192 : rtx dest, vdest, op0, op1, mask, op2, op3;
2328 : :
2329 : 23192 : mode = GET_MODE (operands[0]);
2330 : :
2331 : 23192 : switch (mode)
2332 : : {
2333 : : case E_HFmode:
2334 : : vmode = V8HFmode;
2335 : : break;
2336 : 0 : case E_BFmode:
2337 : 0 : vmode = V8BFmode;
2338 : 0 : break;
2339 : 11557 : case E_SFmode:
2340 : 11557 : vmode = V4SFmode;
2341 : 11557 : break;
2342 : 11509 : case E_DFmode:
2343 : 11509 : vmode = V2DFmode;
2344 : 11509 : break;
2345 : 114 : case E_TFmode:
2346 : 114 : vmode = mode;
2347 : 114 : break;
2348 : 0 : default:
2349 : 0 : gcc_unreachable();
2350 : : }
2351 : :
2352 : 23192 : if (rtx_equal_p (operands[1], operands[2]))
2353 : : {
2354 : 0 : emit_move_insn (operands[0], operands[1]);
2355 : 0 : return;
2356 : : }
2357 : :
2358 : 23192 : dest = operands[0];
2359 : 23192 : vdest = lowpart_subreg (vmode, dest, mode);
2360 : 23192 : if (vdest == NULL_RTX)
2361 : 0 : vdest = gen_reg_rtx (vmode);
2362 : : else
2363 : : dest = NULL_RTX;
2364 : 23192 : op1 = lowpart_subreg (vmode, force_reg (mode, operands[2]), mode);
2365 : 46369 : mask = ix86_build_signbit_mask (vmode, TARGET_AVX512F && mode != HFmode, 0);
2366 : :
2367 : 23192 : if (CONST_DOUBLE_P (operands[1]))
2368 : : {
2369 : 22741 : op0 = simplify_unary_operation (ABS, mode, operands[1], mode);
2370 : : /* Optimize for 0, simplify b = copy_signf (0.0f, a) to b = mask & a. */
2371 : 22741 : if (op0 == CONST0_RTX (mode))
2372 : : {
2373 : 109 : emit_move_insn (vdest, gen_rtx_AND (vmode, mask, op1));
2374 : 109 : if (dest)
2375 : 0 : emit_move_insn (dest, lowpart_subreg (mode, vdest, vmode));
2376 : 109 : return;
2377 : : }
2378 : :
2379 : 45264 : if (GET_MODE_SIZE (mode) < 16)
2380 : 22620 : op0 = ix86_build_const_vector (vmode, false, op0);
2381 : 22632 : op0 = force_reg (vmode, op0);
2382 : : }
2383 : : else
2384 : 451 : op0 = lowpart_subreg (vmode, force_reg (mode, operands[1]), mode);
2385 : :
2386 : 23083 : op2 = gen_reg_rtx (vmode);
2387 : 23083 : op3 = gen_reg_rtx (vmode);
2388 : 23083 : emit_move_insn (op2, gen_rtx_AND (vmode,
2389 : : gen_rtx_NOT (vmode, mask),
2390 : : op0));
2391 : 23083 : emit_move_insn (op3, gen_rtx_AND (vmode, mask, op1));
2392 : 23083 : emit_move_insn (vdest, gen_rtx_IOR (vmode, op2, op3));
2393 : 23083 : if (dest)
2394 : 0 : emit_move_insn (dest, lowpart_subreg (mode, vdest, vmode));
2395 : : }
2396 : :
2397 : : /* Expand an xorsign operation. */
2398 : :
2399 : : void
2400 : 16 : ix86_expand_xorsign (rtx operands[])
2401 : : {
2402 : 16 : machine_mode mode, vmode;
2403 : 16 : rtx dest, vdest, op0, op1, mask, x, temp;
2404 : :
2405 : 16 : dest = operands[0];
2406 : 16 : op0 = operands[1];
2407 : 16 : op1 = operands[2];
2408 : :
2409 : 16 : mode = GET_MODE (dest);
2410 : :
2411 : 16 : switch (mode)
2412 : : {
2413 : : case E_HFmode:
2414 : : vmode = V8HFmode;
2415 : : break;
2416 : : case E_BFmode:
2417 : : vmode = V8BFmode;
2418 : : break;
2419 : : case E_SFmode:
2420 : : vmode = V4SFmode;
2421 : : break;
2422 : : case E_DFmode:
2423 : : vmode = V2DFmode;
2424 : : break;
2425 : 0 : default:
2426 : 0 : gcc_unreachable ();
2427 : 16 : break;
2428 : : }
2429 : :
2430 : 16 : temp = gen_reg_rtx (vmode);
2431 : 16 : mask = ix86_build_signbit_mask (vmode, 0, 0);
2432 : :
2433 : 16 : op1 = lowpart_subreg (vmode, force_reg (mode, op1), mode);
2434 : 16 : x = gen_rtx_AND (vmode, op1, mask);
2435 : 16 : emit_insn (gen_rtx_SET (temp, x));
2436 : :
2437 : 16 : op0 = lowpart_subreg (vmode, force_reg (mode, op0), mode);
2438 : 16 : x = gen_rtx_XOR (vmode, temp, op0);
2439 : :
2440 : 16 : vdest = lowpart_subreg (vmode, dest, mode);
2441 : 16 : if (vdest == NULL_RTX)
2442 : 0 : vdest = gen_reg_rtx (vmode);
2443 : : else
2444 : : dest = NULL_RTX;
2445 : 16 : emit_insn (gen_rtx_SET (vdest, x));
2446 : :
2447 : 16 : if (dest)
2448 : 0 : emit_move_insn (dest, lowpart_subreg (mode, vdest, vmode));
2449 : 16 : }
2450 : :
2451 : : static rtx ix86_expand_compare (enum rtx_code code, rtx op0, rtx op1);
2452 : :
2453 : : void
2454 : 5934495 : ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
2455 : : {
2456 : 5934495 : machine_mode mode = GET_MODE (op0);
2457 : 5934495 : rtx tmp;
2458 : :
2459 : : /* Handle special case - vector comparsion with boolean result, transform
2460 : : it using ptest instruction or vpcmpeq + kortest. */
2461 : 5934495 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
2462 : 5929919 : || (mode == TImode && !TARGET_64BIT)
2463 : 5929919 : || mode == OImode
2464 : 11864414 : || GET_MODE_SIZE (mode) == 64)
2465 : : {
2466 : 4576 : unsigned msize = GET_MODE_SIZE (mode);
2467 : 10708 : machine_mode p_mode
2468 : 4576 : = msize == 64 ? V16SImode : msize == 32 ? V4DImode : V2DImode;
2469 : : /* kortest set CF when result is 0xFFFF (op0 == op1). */
2470 : 4576 : rtx flag = gen_rtx_REG (msize == 64 ? CCCmode : CCZmode, FLAGS_REG);
2471 : :
2472 : 4576 : gcc_assert (code == EQ || code == NE);
2473 : :
2474 : : /* Using vpcmpeq zmm zmm k + kortest for 512-bit vectors. */
2475 : 4576 : if (msize == 64)
2476 : : {
2477 : 1356 : if (mode != V16SImode)
2478 : : {
2479 : 1356 : op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
2480 : 1356 : op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
2481 : : }
2482 : :
2483 : 1356 : tmp = gen_reg_rtx (HImode);
2484 : 1356 : emit_insn (gen_avx512f_cmpv16si3 (tmp, op0, op1, GEN_INT (0)));
2485 : 1356 : emit_insn (gen_kortesthi_ccc (tmp, tmp));
2486 : : }
2487 : : /* Using ptest for 128/256-bit vectors. */
2488 : : else
2489 : : {
2490 : 3220 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
2491 : : {
2492 : 0 : op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
2493 : 0 : op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
2494 : 0 : mode = p_mode;
2495 : : }
2496 : :
2497 : : /* Generate XOR since we can't check that one operand is zero
2498 : : vector. */
2499 : 3220 : tmp = gen_reg_rtx (mode);
2500 : 3220 : rtx ops[3] = { tmp, op0, op1 };
2501 : 3220 : ix86_expand_vector_logical_operator (XOR, mode, ops);
2502 : 3220 : tmp = gen_lowpart (p_mode, tmp);
2503 : 3220 : emit_insn (gen_rtx_SET (gen_rtx_REG (CCZmode, FLAGS_REG),
2504 : : gen_rtx_UNSPEC (CCZmode,
2505 : : gen_rtvec (2, tmp, tmp),
2506 : : UNSPEC_PTEST)));
2507 : : }
2508 : 4576 : tmp = gen_rtx_fmt_ee (code, VOIDmode, flag, const0_rtx);
2509 : 4576 : tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
2510 : : gen_rtx_LABEL_REF (VOIDmode, label),
2511 : : pc_rtx);
2512 : 4576 : emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
2513 : 4576 : return;
2514 : : }
2515 : :
2516 : 5929919 : switch (mode)
2517 : : {
2518 : 5897537 : case E_HFmode:
2519 : 5897537 : case E_SFmode:
2520 : 5897537 : case E_DFmode:
2521 : 5897537 : case E_XFmode:
2522 : 5897537 : case E_QImode:
2523 : 5897537 : case E_HImode:
2524 : 5897537 : case E_SImode:
2525 : 5897537 : simple:
2526 : 5897537 : tmp = ix86_expand_compare (code, op0, op1);
2527 : 5897537 : tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
2528 : : gen_rtx_LABEL_REF (VOIDmode, label),
2529 : : pc_rtx);
2530 : 5897537 : emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
2531 : 5897537 : return;
2532 : :
2533 : 2347289 : case E_DImode:
2534 : 2347289 : if (TARGET_64BIT)
2535 : 2320222 : goto simple;
2536 : : /* FALLTHRU */
2537 : 76048 : case E_TImode:
2538 : : /* DI and TI mode equality/inequality comparisons may be performed
2539 : : on SSE registers. Avoid splitting them, except when optimizing
2540 : : for size. */
2541 : 76048 : if ((code == EQ || code == NE)
2542 : 76048 : && !optimize_insn_for_size_p ())
2543 : 43666 : goto simple;
2544 : :
2545 : : /* Expand DImode branch into multiple compare+branch. */
2546 : 32382 : {
2547 : 32382 : rtx lo[2], hi[2];
2548 : 32382 : rtx_code_label *label2;
2549 : 32382 : enum rtx_code code1, code2, code3;
2550 : 32382 : machine_mode submode;
2551 : :
2552 : 32382 : if (CONSTANT_P (op0) && !CONSTANT_P (op1))
2553 : : {
2554 : 0 : std::swap (op0, op1);
2555 : 0 : code = swap_condition (code);
2556 : : }
2557 : :
2558 : 32382 : split_double_mode (mode, &op0, 1, lo+0, hi+0);
2559 : 32382 : split_double_mode (mode, &op1, 1, lo+1, hi+1);
2560 : :
2561 : 32382 : submode = mode == DImode ? SImode : DImode;
2562 : :
2563 : : /* If we are doing less-than or greater-or-equal-than,
2564 : : op1 is a constant and the low word is zero, then we can just
2565 : : examine the high word. Similarly for low word -1 and
2566 : : less-or-equal-than or greater-than. */
2567 : :
2568 : 32382 : if (CONST_INT_P (hi[1]))
2569 : 22448 : switch (code)
2570 : : {
2571 : 11447 : case LT: case LTU: case GE: case GEU:
2572 : 11447 : if (lo[1] == const0_rtx)
2573 : : {
2574 : 11056 : ix86_expand_branch (code, hi[0], hi[1], label);
2575 : 11056 : return;
2576 : : }
2577 : : break;
2578 : 9788 : case LE: case LEU: case GT: case GTU:
2579 : 9788 : if (lo[1] == constm1_rtx)
2580 : : {
2581 : 529 : ix86_expand_branch (code, hi[0], hi[1], label);
2582 : 529 : return;
2583 : : }
2584 : : break;
2585 : : default:
2586 : : break;
2587 : : }
2588 : :
2589 : : /* Emulate comparisons that do not depend on Zero flag with
2590 : : double-word subtraction. Note that only Overflow, Sign
2591 : : and Carry flags are valid, so swap arguments and condition
2592 : : of comparisons that would otherwise test Zero flag. */
2593 : :
2594 : 20797 : switch (code)
2595 : : {
2596 : 14200 : case LE: case LEU: case GT: case GTU:
2597 : 14200 : std::swap (lo[0], lo[1]);
2598 : 14200 : std::swap (hi[0], hi[1]);
2599 : 14200 : code = swap_condition (code);
2600 : : /* FALLTHRU */
2601 : :
2602 : 18429 : case LT: case LTU: case GE: case GEU:
2603 : 18429 : {
2604 : 18429 : bool uns = (code == LTU || code == GEU);
2605 : 36858 : rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
2606 : 18429 : = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
2607 : :
2608 : 18429 : if (!nonimmediate_operand (lo[0], submode))
2609 : 9259 : lo[0] = force_reg (submode, lo[0]);
2610 : 18429 : if (!x86_64_general_operand (lo[1], submode))
2611 : 0 : lo[1] = force_reg (submode, lo[1]);
2612 : :
2613 : 18429 : if (!register_operand (hi[0], submode))
2614 : 10006 : hi[0] = force_reg (submode, hi[0]);
2615 : 14435 : if ((uns && !nonimmediate_operand (hi[1], submode))
2616 : 18429 : || (!uns && !x86_64_general_operand (hi[1], submode)))
2617 : 315 : hi[1] = force_reg (submode, hi[1]);
2618 : :
2619 : 18429 : emit_insn (gen_cmp_1 (submode, lo[0], lo[1]));
2620 : :
2621 : 18429 : tmp = gen_rtx_SCRATCH (submode);
2622 : 18429 : emit_insn (sbb_insn (submode, tmp, hi[0], hi[1]));
2623 : :
2624 : 22423 : tmp = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
2625 : 18429 : ix86_expand_branch (code, tmp, const0_rtx, label);
2626 : 18429 : return;
2627 : : }
2628 : :
2629 : 2368 : default:
2630 : 2368 : break;
2631 : : }
2632 : :
2633 : : /* Otherwise, we need two or three jumps. */
2634 : :
2635 : 2368 : label2 = gen_label_rtx ();
2636 : :
2637 : 2368 : code1 = code;
2638 : 2368 : code2 = swap_condition (code);
2639 : 2368 : code3 = unsigned_condition (code);
2640 : :
2641 : 2368 : switch (code)
2642 : : {
2643 : : case LT: case GT: case LTU: case GTU:
2644 : : break;
2645 : :
2646 : : case LE: code1 = LT; code2 = GT; break;
2647 : : case GE: code1 = GT; code2 = LT; break;
2648 : 0 : case LEU: code1 = LTU; code2 = GTU; break;
2649 : 0 : case GEU: code1 = GTU; code2 = LTU; break;
2650 : :
2651 : : case EQ: code1 = UNKNOWN; code2 = NE; break;
2652 : : case NE: code2 = UNKNOWN; break;
2653 : :
2654 : 0 : default:
2655 : 0 : gcc_unreachable ();
2656 : : }
2657 : :
2658 : : /*
2659 : : * a < b =>
2660 : : * if (hi(a) < hi(b)) goto true;
2661 : : * if (hi(a) > hi(b)) goto false;
2662 : : * if (lo(a) < lo(b)) goto true;
2663 : : * false:
2664 : : */
2665 : :
2666 : 0 : if (code1 != UNKNOWN)
2667 : 1714 : ix86_expand_branch (code1, hi[0], hi[1], label);
2668 : 2368 : if (code2 != UNKNOWN)
2669 : 654 : ix86_expand_branch (code2, hi[0], hi[1], label2);
2670 : :
2671 : 2368 : ix86_expand_branch (code3, lo[0], lo[1], label);
2672 : :
2673 : 2368 : if (code2 != UNKNOWN)
2674 : 654 : emit_label (label2);
2675 : : return;
2676 : : }
2677 : :
2678 : 18788 : default:
2679 : 18788 : gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC);
2680 : 18788 : goto simple;
2681 : : }
2682 : : }
2683 : :
2684 : : /* Figure out whether to use unordered fp comparisons. */
2685 : :
2686 : : static bool
2687 : 1097705 : ix86_unordered_fp_compare (enum rtx_code code)
2688 : : {
2689 : 1097705 : if (!TARGET_IEEE_FP)
2690 : : return false;
2691 : :
2692 : 1093515 : switch (code)
2693 : : {
2694 : : case LT:
2695 : : case LE:
2696 : : case GT:
2697 : : case GE:
2698 : : case LTGT:
2699 : : return false;
2700 : :
2701 : : case EQ:
2702 : : case NE:
2703 : :
2704 : : case UNORDERED:
2705 : : case ORDERED:
2706 : : case UNLT:
2707 : : case UNLE:
2708 : : case UNGT:
2709 : : case UNGE:
2710 : : case UNEQ:
2711 : : return true;
2712 : :
2713 : 0 : default:
2714 : 0 : gcc_unreachable ();
2715 : : }
2716 : : }
2717 : :
2718 : : /* Return a comparison we can do and that it is equivalent to
2719 : : swap_condition (code) apart possibly from orderedness.
2720 : : But, never change orderedness if TARGET_IEEE_FP, returning
2721 : : UNKNOWN in that case if necessary. */
2722 : :
2723 : : static enum rtx_code
2724 : 35945 : ix86_fp_swap_condition (enum rtx_code code)
2725 : : {
2726 : 35945 : switch (code)
2727 : : {
2728 : 1462 : case GT: /* GTU - CF=0 & ZF=0 */
2729 : 1462 : return TARGET_IEEE_FP ? UNKNOWN : UNLT;
2730 : 510 : case GE: /* GEU - CF=0 */
2731 : 510 : return TARGET_IEEE_FP ? UNKNOWN : UNLE;
2732 : 381 : case UNLT: /* LTU - CF=1 */
2733 : 381 : return TARGET_IEEE_FP ? UNKNOWN : GT;
2734 : 6662 : case UNLE: /* LEU - CF=1 | ZF=1 */
2735 : 6662 : return TARGET_IEEE_FP ? UNKNOWN : GE;
2736 : 26930 : default:
2737 : 26930 : return swap_condition (code);
2738 : : }
2739 : : }
2740 : :
2741 : : /* Return cost of comparison CODE using the best strategy for performance.
2742 : : All following functions do use number of instructions as a cost metrics.
2743 : : In future this should be tweaked to compute bytes for optimize_size and
2744 : : take into account performance of various instructions on various CPUs. */
2745 : :
2746 : : static int
2747 : 1096734 : ix86_fp_comparison_cost (enum rtx_code code)
2748 : : {
2749 : 1096734 : int arith_cost;
2750 : :
2751 : : /* The cost of code using bit-twiddling on %ah. */
2752 : 1096734 : switch (code)
2753 : : {
2754 : : case UNLE:
2755 : : case UNLT:
2756 : : case LTGT:
2757 : : case GT:
2758 : : case GE:
2759 : : case UNORDERED:
2760 : : case ORDERED:
2761 : : case UNEQ:
2762 : : arith_cost = 4;
2763 : : break;
2764 : 67290 : case LT:
2765 : 67290 : case NE:
2766 : 67290 : case EQ:
2767 : 67290 : case UNGE:
2768 : 67290 : arith_cost = TARGET_IEEE_FP ? 5 : 4;
2769 : : break;
2770 : 22717 : case LE:
2771 : 22717 : case UNGT:
2772 : 22717 : arith_cost = TARGET_IEEE_FP ? 6 : 4;
2773 : : break;
2774 : 0 : default:
2775 : 0 : gcc_unreachable ();
2776 : : }
2777 : :
2778 : 1096734 : switch (ix86_fp_comparison_strategy (code))
2779 : : {
2780 : 1096734 : case IX86_FPCMP_COMI:
2781 : 1096734 : return arith_cost > 4 ? 3 : 2;
2782 : 0 : case IX86_FPCMP_SAHF:
2783 : 0 : return arith_cost > 4 ? 4 : 3;
2784 : : default:
2785 : : return arith_cost;
2786 : : }
2787 : : }
2788 : :
2789 : : /* Swap, force into registers, or otherwise massage the two operands
2790 : : to a fp comparison. The operands are updated in place; the new
2791 : : comparison code is returned. */
2792 : :
2793 : : static enum rtx_code
2794 : 548367 : ix86_prepare_fp_compare_args (enum rtx_code code, rtx *pop0, rtx *pop1)
2795 : : {
2796 : 548369 : bool unordered_compare = ix86_unordered_fp_compare (code);
2797 : 548369 : rtx op0 = *pop0, op1 = *pop1;
2798 : 548369 : machine_mode op_mode = GET_MODE (op0);
2799 : 548369 : bool is_sse = SSE_FLOAT_MODE_SSEMATH_OR_HF_P (op_mode);
2800 : :
2801 : 546427 : if (op_mode == BFmode)
2802 : : {
2803 : 2 : rtx op = gen_lowpart (HImode, op0);
2804 : 2 : if (CONST_INT_P (op))
2805 : 0 : op = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
2806 : : op0, BFmode);
2807 : : else
2808 : : {
2809 : 2 : rtx t1 = gen_reg_rtx (SImode);
2810 : 2 : emit_insn (gen_zero_extendhisi2 (t1, op));
2811 : 2 : emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16)));
2812 : 2 : op = gen_lowpart (SFmode, t1);
2813 : : }
2814 : 2 : *pop0 = op;
2815 : 2 : op = gen_lowpart (HImode, op1);
2816 : 2 : if (CONST_INT_P (op))
2817 : 2 : op = simplify_const_unary_operation (FLOAT_EXTEND, SFmode,
2818 : : op1, BFmode);
2819 : : else
2820 : : {
2821 : 0 : rtx t1 = gen_reg_rtx (SImode);
2822 : 0 : emit_insn (gen_zero_extendhisi2 (t1, op));
2823 : 0 : emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16)));
2824 : 0 : op = gen_lowpart (SFmode, t1);
2825 : : }
2826 : 2 : *pop1 = op;
2827 : 2 : return ix86_prepare_fp_compare_args (code, pop0, pop1);
2828 : : }
2829 : :
2830 : : /* All of the unordered compare instructions only work on registers.
2831 : : The same is true of the fcomi compare instructions. The XFmode
2832 : : compare instructions require registers except when comparing
2833 : : against zero or when converting operand 1 from fixed point to
2834 : : floating point. */
2835 : :
2836 : 548367 : if (!is_sse
2837 : 548367 : && (unordered_compare
2838 : 8962 : || (op_mode == XFmode
2839 : 10485 : && ! (standard_80387_constant_p (op0) == 1
2840 : 5240 : || standard_80387_constant_p (op1) == 1)
2841 : 4886 : && GET_CODE (op1) != FLOAT)
2842 : 4076 : || ix86_fp_comparison_strategy (code) == IX86_FPCMP_COMI))
2843 : : {
2844 : 147982 : op0 = force_reg (op_mode, op0);
2845 : 147982 : op1 = force_reg (op_mode, op1);
2846 : : }
2847 : : else
2848 : : {
2849 : : /* %%% We only allow op1 in memory; op0 must be st(0). So swap
2850 : : things around if they appear profitable, otherwise force op0
2851 : : into a register. */
2852 : :
2853 : 400385 : if (standard_80387_constant_p (op0) == 0
2854 : 400385 : || (MEM_P (op0)
2855 : 52046 : && ! (standard_80387_constant_p (op1) == 0
2856 : 37247 : || MEM_P (op1))))
2857 : : {
2858 : 35945 : enum rtx_code new_code = ix86_fp_swap_condition (code);
2859 : 35945 : if (new_code != UNKNOWN)
2860 : : {
2861 : : std::swap (op0, op1);
2862 : 400385 : code = new_code;
2863 : : }
2864 : : }
2865 : :
2866 : 400385 : if (!REG_P (op0))
2867 : 50248 : op0 = force_reg (op_mode, op0);
2868 : :
2869 : 400385 : if (CONSTANT_P (op1))
2870 : : {
2871 : 189797 : int tmp = standard_80387_constant_p (op1);
2872 : 189797 : if (tmp == 0)
2873 : 71790 : op1 = validize_mem (force_const_mem (op_mode, op1));
2874 : 118007 : else if (tmp == 1)
2875 : : {
2876 : 64392 : if (TARGET_CMOVE)
2877 : 64392 : op1 = force_reg (op_mode, op1);
2878 : : }
2879 : : else
2880 : 53615 : op1 = force_reg (op_mode, op1);
2881 : : }
2882 : : }
2883 : :
2884 : : /* Try to rearrange the comparison to make it cheaper. */
2885 : 548367 : if (ix86_fp_comparison_cost (code)
2886 : 548367 : > ix86_fp_comparison_cost (swap_condition (code))
2887 : 548367 : && (REG_P (op1) || can_create_pseudo_p ()))
2888 : : {
2889 : 0 : std::swap (op0, op1);
2890 : 0 : code = swap_condition (code);
2891 : 0 : if (!REG_P (op0))
2892 : 0 : op0 = force_reg (op_mode, op0);
2893 : : }
2894 : :
2895 : 548367 : *pop0 = op0;
2896 : 548367 : *pop1 = op1;
2897 : 548367 : return code;
2898 : : }
2899 : :
2900 : : /* Generate insn patterns to do a floating point compare of OPERANDS. */
2901 : :
2902 : : static rtx
2903 : 548367 : ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1)
2904 : : {
2905 : 548367 : bool unordered_compare = ix86_unordered_fp_compare (code);
2906 : 548367 : machine_mode cmp_mode;
2907 : 548367 : rtx tmp, scratch;
2908 : :
2909 : 548367 : code = ix86_prepare_fp_compare_args (code, &op0, &op1);
2910 : :
2911 : 548367 : tmp = gen_rtx_COMPARE (CCFPmode, op0, op1);
2912 : 548367 : if (unordered_compare)
2913 : 488057 : tmp = gen_rtx_UNSPEC (CCFPmode, gen_rtvec (1, tmp), UNSPEC_NOTRAP);
2914 : :
2915 : : /* Do fcomi/sahf based test when profitable. */
2916 : 548367 : switch (ix86_fp_comparison_strategy (code))
2917 : : {
2918 : 548367 : case IX86_FPCMP_COMI:
2919 : 548367 : tmp = gen_rtx_COMPARE (CCFPmode, op0, op1);
2920 : 548367 : if (TARGET_AVX10_2_256 && (code == EQ || code == NE))
2921 : 12 : tmp = gen_rtx_UNSPEC (CCFPmode, gen_rtvec (1, tmp), UNSPEC_OPTCOMX);
2922 : 548367 : if (unordered_compare)
2923 : 488057 : tmp = gen_rtx_UNSPEC (CCFPmode, gen_rtvec (1, tmp), UNSPEC_NOTRAP);
2924 : 548367 : cmp_mode = CCFPmode;
2925 : 548367 : emit_insn (gen_rtx_SET (gen_rtx_REG (CCFPmode, FLAGS_REG), tmp));
2926 : 548367 : break;
2927 : :
2928 : 0 : case IX86_FPCMP_SAHF:
2929 : 0 : cmp_mode = CCFPmode;
2930 : 0 : tmp = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
2931 : 0 : scratch = gen_reg_rtx (HImode);
2932 : 0 : emit_insn (gen_rtx_SET (scratch, tmp));
2933 : 0 : emit_insn (gen_x86_sahf_1 (scratch));
2934 : 0 : break;
2935 : :
2936 : 0 : case IX86_FPCMP_ARITH:
2937 : 0 : cmp_mode = CCNOmode;
2938 : 0 : tmp = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW);
2939 : 0 : scratch = gen_reg_rtx (HImode);
2940 : 0 : emit_insn (gen_rtx_SET (scratch, tmp));
2941 : :
2942 : : /* In the unordered case, we have to check C2 for NaN's, which
2943 : : doesn't happen to work out to anything nice combination-wise.
2944 : : So do some bit twiddling on the value we've got in AH to come
2945 : : up with an appropriate set of condition codes. */
2946 : :
2947 : 0 : switch (code)
2948 : : {
2949 : 0 : case GT:
2950 : 0 : case UNGT:
2951 : 0 : if (code == GT || !TARGET_IEEE_FP)
2952 : : {
2953 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x45)));
2954 : 0 : code = EQ;
2955 : : }
2956 : : else
2957 : : {
2958 : 0 : emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)));
2959 : 0 : emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
2960 : 0 : emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44)));
2961 : 0 : cmp_mode = CCmode;
2962 : 0 : code = GEU;
2963 : : }
2964 : : break;
2965 : 0 : case LT:
2966 : 0 : case UNLT:
2967 : 0 : if (code == LT && TARGET_IEEE_FP)
2968 : : {
2969 : 0 : emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)));
2970 : 0 : emit_insn (gen_cmpqi_ext_3 (scratch, const1_rtx));
2971 : 0 : cmp_mode = CCmode;
2972 : 0 : code = EQ;
2973 : : }
2974 : : else
2975 : : {
2976 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, const1_rtx));
2977 : 0 : code = NE;
2978 : : }
2979 : : break;
2980 : 0 : case GE:
2981 : 0 : case UNGE:
2982 : 0 : if (code == GE || !TARGET_IEEE_FP)
2983 : : {
2984 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x05)));
2985 : 0 : code = EQ;
2986 : : }
2987 : : else
2988 : : {
2989 : 0 : emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)));
2990 : 0 : emit_insn (gen_xorqi_ext_1_cc (scratch, scratch, const1_rtx));
2991 : 0 : code = NE;
2992 : : }
2993 : : break;
2994 : 0 : case LE:
2995 : 0 : case UNLE:
2996 : 0 : if (code == LE && TARGET_IEEE_FP)
2997 : : {
2998 : 0 : emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)));
2999 : 0 : emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx));
3000 : 0 : emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
3001 : 0 : cmp_mode = CCmode;
3002 : 0 : code = LTU;
3003 : : }
3004 : : else
3005 : : {
3006 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x45)));
3007 : 0 : code = NE;
3008 : : }
3009 : : break;
3010 : 0 : case EQ:
3011 : 0 : case UNEQ:
3012 : 0 : if (code == EQ && TARGET_IEEE_FP)
3013 : : {
3014 : 0 : emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)));
3015 : 0 : emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)));
3016 : 0 : cmp_mode = CCmode;
3017 : 0 : code = EQ;
3018 : : }
3019 : : else
3020 : : {
3021 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x40)));
3022 : 0 : code = NE;
3023 : : }
3024 : : break;
3025 : 0 : case NE:
3026 : 0 : case LTGT:
3027 : 0 : if (code == NE && TARGET_IEEE_FP)
3028 : : {
3029 : 0 : emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)));
3030 : 0 : emit_insn (gen_xorqi_ext_1_cc (scratch, scratch,
3031 : : GEN_INT (0x40)));
3032 : 0 : code = NE;
3033 : : }
3034 : : else
3035 : : {
3036 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x40)));
3037 : 0 : code = EQ;
3038 : : }
3039 : : break;
3040 : :
3041 : 0 : case UNORDERED:
3042 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x04)));
3043 : 0 : code = NE;
3044 : 0 : break;
3045 : 0 : case ORDERED:
3046 : 0 : emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x04)));
3047 : 0 : code = EQ;
3048 : 0 : break;
3049 : :
3050 : 0 : default:
3051 : 0 : gcc_unreachable ();
3052 : : }
3053 : : break;
3054 : :
3055 : 0 : default:
3056 : 0 : gcc_unreachable();
3057 : : }
3058 : :
3059 : : /* Return the test that should be put into the flags user, i.e.
3060 : : the bcc, scc, or cmov instruction. */
3061 : 548367 : return gen_rtx_fmt_ee (code, VOIDmode,
3062 : : gen_rtx_REG (cmp_mode, FLAGS_REG),
3063 : : const0_rtx);
3064 : : }
3065 : :
3066 : : /* Generate insn patterns to do an integer compare of OPERANDS. */
3067 : :
3068 : : static rtx
3069 : 6198106 : ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1)
3070 : : {
3071 : 6198106 : machine_mode cmpmode;
3072 : 6198106 : rtx tmp, flags;
3073 : :
3074 : : /* Swap operands to emit carry flag comparison. */
3075 : 6198106 : if ((code == GTU || code == LEU)
3076 : 6198106 : && nonimmediate_operand (op1, VOIDmode))
3077 : : {
3078 : 114220 : std::swap (op0, op1);
3079 : 114220 : code = swap_condition (code);
3080 : : }
3081 : :
3082 : 6198106 : cmpmode = SELECT_CC_MODE (code, op0, op1);
3083 : 6198106 : flags = gen_rtx_REG (cmpmode, FLAGS_REG);
3084 : :
3085 : : /* Attempt to use PTEST, if available, when testing vector modes for
3086 : : equality/inequality against zero. */
3087 : 6198106 : if (op1 == const0_rtx
3088 : 2705173 : && SUBREG_P (op0)
3089 : 26305 : && cmpmode == CCZmode
3090 : 12836 : && SUBREG_BYTE (op0) == 0
3091 : 11078 : && REG_P (SUBREG_REG (op0))
3092 : 11078 : && VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0)))
3093 : 6 : && TARGET_SSE4_1
3094 : 0 : && GET_MODE (op0) == TImode
3095 : 6198106 : && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))) == 16)
3096 : : {
3097 : 0 : tmp = SUBREG_REG (op0);
3098 : 0 : tmp = gen_rtx_UNSPEC (CCZmode, gen_rtvec (2, tmp, tmp), UNSPEC_PTEST);
3099 : : }
3100 : : else
3101 : 6198106 : tmp = gen_rtx_COMPARE (cmpmode, op0, op1);
3102 : :
3103 : : /* This is very simple, but making the interface the same as in the
3104 : : FP case makes the rest of the code easier. */
3105 : 6198106 : emit_insn (gen_rtx_SET (flags, tmp));
3106 : :
3107 : : /* Return the test that should be put into the flags user, i.e.
3108 : : the bcc, scc, or cmov instruction. */
3109 : 6198106 : return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
3110 : : }
3111 : :
3112 : : static rtx
3113 : 6924492 : ix86_expand_compare (enum rtx_code code, rtx op0, rtx op1)
3114 : : {
3115 : 6924492 : rtx ret;
3116 : :
3117 : 6924492 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
3118 : 178643 : ret = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
3119 : :
3120 : 6745849 : else if (SCALAR_FLOAT_MODE_P (GET_MODE (op0)))
3121 : : {
3122 : 547743 : gcc_assert (!DECIMAL_FLOAT_MODE_P (GET_MODE (op0)));
3123 : 547743 : ret = ix86_expand_fp_compare (code, op0, op1);
3124 : : }
3125 : : else
3126 : 6198106 : ret = ix86_expand_int_compare (code, op0, op1);
3127 : :
3128 : 6924492 : return ret;
3129 : : }
3130 : :
3131 : : void
3132 : 474200 : ix86_expand_setcc (rtx dest, enum rtx_code code, rtx op0, rtx op1)
3133 : : {
3134 : 474200 : rtx ret;
3135 : :
3136 : 474200 : gcc_assert (GET_MODE (dest) == QImode);
3137 : :
3138 : 474200 : ret = ix86_expand_compare (code, op0, op1);
3139 : 474200 : PUT_MODE (ret, QImode);
3140 : 474200 : emit_insn (gen_rtx_SET (dest, ret));
3141 : 474200 : }
3142 : :
3143 : : /* Expand floating point op0 <=> op1, i.e.
3144 : : dest = op0 == op1 ? 0 : op0 < op1 ? -1 : op0 > op1 ? 1 : 2. */
3145 : :
3146 : : void
3147 : 298 : ix86_expand_fp_spaceship (rtx dest, rtx op0, rtx op1)
3148 : : {
3149 : 298 : gcc_checking_assert (ix86_fp_comparison_strategy (GT) != IX86_FPCMP_ARITH);
3150 : 298 : rtx gt = ix86_expand_fp_compare (GT, op0, op1);
3151 : 298 : rtx l0 = gen_label_rtx ();
3152 : 298 : rtx l1 = gen_label_rtx ();
3153 : 298 : rtx l2 = TARGET_IEEE_FP ? gen_label_rtx () : NULL_RTX;
3154 : 298 : rtx lend = gen_label_rtx ();
3155 : 298 : rtx tmp;
3156 : 298 : rtx_insn *jmp;
3157 : 298 : if (l2)
3158 : : {
3159 : 261 : rtx un = gen_rtx_fmt_ee (UNORDERED, VOIDmode,
3160 : : gen_rtx_REG (CCFPmode, FLAGS_REG), const0_rtx);
3161 : 261 : tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, un,
3162 : : gen_rtx_LABEL_REF (VOIDmode, l2), pc_rtx);
3163 : 261 : jmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
3164 : 261 : add_reg_br_prob_note (jmp, profile_probability:: very_unlikely ());
3165 : : }
3166 : 298 : rtx eq = gen_rtx_fmt_ee (UNEQ, VOIDmode,
3167 : : gen_rtx_REG (CCFPmode, FLAGS_REG), const0_rtx);
3168 : 298 : tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, eq,
3169 : : gen_rtx_LABEL_REF (VOIDmode, l0), pc_rtx);
3170 : 298 : jmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
3171 : 298 : add_reg_br_prob_note (jmp, profile_probability::unlikely ());
3172 : 298 : tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, gt,
3173 : : gen_rtx_LABEL_REF (VOIDmode, l1), pc_rtx);
3174 : 298 : jmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
3175 : 298 : add_reg_br_prob_note (jmp, profile_probability::even ());
3176 : 298 : emit_move_insn (dest, constm1_rtx);
3177 : 298 : emit_jump (lend);
3178 : 298 : emit_label (l0);
3179 : 298 : emit_move_insn (dest, const0_rtx);
3180 : 298 : emit_jump (lend);
3181 : 298 : emit_label (l1);
3182 : 298 : emit_move_insn (dest, const1_rtx);
3183 : 298 : emit_jump (lend);
3184 : 298 : if (l2)
3185 : : {
3186 : 261 : emit_label (l2);
3187 : 261 : emit_move_insn (dest, const2_rtx);
3188 : : }
3189 : 298 : emit_label (lend);
3190 : 298 : }
3191 : :
3192 : : /* Expand comparison setting or clearing carry flag. Return true when
3193 : : successful and set pop for the operation. */
3194 : : static bool
3195 : 23296 : ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop)
3196 : : {
3197 : 46592 : machine_mode mode
3198 : 23296 : = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
3199 : :
3200 : : /* Do not handle double-mode compares that go through special path. */
3201 : 23296 : if (mode == (TARGET_64BIT ? TImode : DImode))
3202 : : return false;
3203 : :
3204 : 23294 : if (SCALAR_FLOAT_MODE_P (mode))
3205 : : {
3206 : 328 : rtx compare_op;
3207 : 328 : rtx_insn *compare_seq;
3208 : :
3209 : 328 : gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
3210 : :
3211 : : /* Shortcut: following common codes never translate
3212 : : into carry flag compares. */
3213 : 328 : if (code == EQ || code == NE || code == UNEQ || code == LTGT
3214 : : || code == ORDERED || code == UNORDERED)
3215 : : return false;
3216 : :
3217 : : /* These comparisons require zero flag; swap operands so they won't. */
3218 : : if ((code == GT || code == UNLE || code == LE || code == UNGT)
3219 : 231 : && !TARGET_IEEE_FP)
3220 : : {
3221 : 2 : std::swap (op0, op1);
3222 : 2 : code = swap_condition (code);
3223 : : }
3224 : :
3225 : : /* Try to expand the comparison and verify that we end up with
3226 : : carry flag based comparison. This fails to be true only when
3227 : : we decide to expand comparison using arithmetic that is not
3228 : : too common scenario. */
3229 : 326 : start_sequence ();
3230 : 326 : compare_op = ix86_expand_fp_compare (code, op0, op1);
3231 : 326 : compare_seq = get_insns ();
3232 : 326 : end_sequence ();
3233 : :
3234 : 326 : if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode)
3235 : 326 : code = ix86_fp_compare_code_to_integer (GET_CODE (compare_op));
3236 : : else
3237 : 0 : code = GET_CODE (compare_op);
3238 : :
3239 : 326 : if (code != LTU && code != GEU)
3240 : : return false;
3241 : :
3242 : 95 : emit_insn (compare_seq);
3243 : 95 : *pop = compare_op;
3244 : 95 : return true;
3245 : : }
3246 : :
3247 : 22966 : if (!INTEGRAL_MODE_P (mode))
3248 : : return false;
3249 : :
3250 : 22858 : switch (code)
3251 : : {
3252 : : case LTU:
3253 : : case GEU:
3254 : : break;
3255 : :
3256 : : /* Convert a==0 into (unsigned)a<1. */
3257 : 19187 : case EQ:
3258 : 19187 : case NE:
3259 : 19187 : if (op1 != const0_rtx)
3260 : : return false;
3261 : 8071 : op1 = const1_rtx;
3262 : 8071 : code = (code == EQ ? LTU : GEU);
3263 : : break;
3264 : :
3265 : : /* Convert a>b into b<a or a>=b-1. */
3266 : 610 : case GTU:
3267 : 610 : case LEU:
3268 : 610 : if (CONST_INT_P (op1))
3269 : : {
3270 : 604 : op1 = gen_int_mode (INTVAL (op1) + 1, GET_MODE (op0));
3271 : : /* Bail out on overflow. We still can swap operands but that
3272 : : would force loading of the constant into register. */
3273 : 604 : if (op1 == const0_rtx
3274 : 604 : || !x86_64_immediate_operand (op1, GET_MODE (op1)))
3275 : 0 : return false;
3276 : 604 : code = (code == GTU ? GEU : LTU);
3277 : : }
3278 : : else
3279 : : {
3280 : 6 : std::swap (op0, op1);
3281 : 6 : code = (code == GTU ? LTU : GEU);
3282 : : }
3283 : : break;
3284 : :
3285 : : /* Convert a>=0 into (unsigned)a<0x80000000. */
3286 : 1755 : case LT:
3287 : 1755 : case GE:
3288 : 1755 : if (mode == DImode || op1 != const0_rtx)
3289 : : return false;
3290 : 260 : op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode);
3291 : 130 : code = (code == LT ? GEU : LTU);
3292 : : break;
3293 : 666 : case LE:
3294 : 666 : case GT:
3295 : 666 : if (mode == DImode || op1 != constm1_rtx)
3296 : : return false;
3297 : 0 : op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode);
3298 : 0 : code = (code == LE ? GEU : LTU);
3299 : : break;
3300 : :
3301 : : default:
3302 : : return false;
3303 : : }
3304 : : /* Swapping operands may cause constant to appear as first operand. */
3305 : 9451 : if (!nonimmediate_operand (op0, VOIDmode))
3306 : : {
3307 : 0 : if (!can_create_pseudo_p ())
3308 : : return false;
3309 : 0 : op0 = force_reg (mode, op0);
3310 : : }
3311 : 9451 : *pop = ix86_expand_compare (code, op0, op1);
3312 : 9451 : gcc_assert (GET_CODE (*pop) == LTU || GET_CODE (*pop) == GEU);
3313 : : return true;
3314 : : }
3315 : :
3316 : : /* Expand conditional increment or decrement using adb/sbb instructions.
3317 : : The default case using setcc followed by the conditional move can be
3318 : : done by generic code. */
3319 : : bool
3320 : 8001 : ix86_expand_int_addcc (rtx operands[])
3321 : : {
3322 : 8001 : enum rtx_code code = GET_CODE (operands[1]);
3323 : 8001 : rtx flags;
3324 : 8001 : rtx (*insn) (machine_mode, rtx, rtx, rtx, rtx, rtx);
3325 : 8001 : rtx compare_op;
3326 : 8001 : rtx val = const0_rtx;
3327 : 8001 : bool fpcmp = false;
3328 : 8001 : machine_mode mode;
3329 : 8001 : rtx op0 = XEXP (operands[1], 0);
3330 : 8001 : rtx op1 = XEXP (operands[1], 1);
3331 : :
3332 : 8001 : if (operands[3] != const1_rtx
3333 : 4537 : && operands[3] != constm1_rtx)
3334 : : return false;
3335 : 4886 : if (!ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
3336 : : return false;
3337 : 943 : code = GET_CODE (compare_op);
3338 : :
3339 : 943 : flags = XEXP (compare_op, 0);
3340 : :
3341 : 943 : if (GET_MODE (flags) == CCFPmode)
3342 : : {
3343 : 4 : fpcmp = true;
3344 : 4 : code = ix86_fp_compare_code_to_integer (code);
3345 : : }
3346 : :
3347 : 943 : if (code != LTU)
3348 : : {
3349 : 519 : val = constm1_rtx;
3350 : 519 : if (fpcmp)
3351 : 4 : PUT_CODE (compare_op,
3352 : : reverse_condition_maybe_unordered
3353 : : (GET_CODE (compare_op)));
3354 : : else
3355 : 515 : PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)));
3356 : : }
3357 : :
3358 : 943 : mode = GET_MODE (operands[0]);
3359 : :
3360 : : /* Construct either adc or sbb insn. */
3361 : 943 : if ((code == LTU) == (operands[3] == constm1_rtx))
3362 : : insn = gen_sub3_carry;
3363 : : else
3364 : 425 : insn = gen_add3_carry;
3365 : :
3366 : 943 : emit_insn (insn (mode, operands[0], operands[2], val, flags, compare_op));
3367 : :
3368 : 943 : return true;
3369 : : }
3370 : :
3371 : : bool
3372 : 529275 : ix86_expand_int_movcc (rtx operands[])
3373 : : {
3374 : 529275 : enum rtx_code code = GET_CODE (operands[1]), compare_code;
3375 : 529275 : rtx_insn *compare_seq;
3376 : 529275 : rtx compare_op;
3377 : 529275 : machine_mode mode = GET_MODE (operands[0]);
3378 : 529275 : bool sign_bit_compare_p = false;
3379 : 529275 : bool negate_cc_compare_p = false;
3380 : 529275 : rtx op0 = XEXP (operands[1], 0);
3381 : 529275 : rtx op1 = XEXP (operands[1], 1);
3382 : 529275 : rtx op2 = operands[2];
3383 : 529275 : rtx op3 = operands[3];
3384 : :
3385 : 529275 : if (GET_MODE (op0) == TImode
3386 : 513837 : || (GET_MODE (op0) == DImode
3387 : 98320 : && !TARGET_64BIT))
3388 : : return false;
3389 : :
3390 : 512571 : if (GET_MODE (op0) == BFmode
3391 : 512571 : && !ix86_fp_comparison_operator (operands[1], VOIDmode))
3392 : : return false;
3393 : :
3394 : 512570 : start_sequence ();
3395 : 512570 : compare_op = ix86_expand_compare (code, op0, op1);
3396 : 512570 : compare_seq = get_insns ();
3397 : 512570 : end_sequence ();
3398 : :
3399 : 512570 : compare_code = GET_CODE (compare_op);
3400 : :
3401 : 512570 : if ((op1 == const0_rtx && (code == GE || code == LT))
3402 : 446520 : || (op1 == constm1_rtx && (code == GT || code == LE)))
3403 : : sign_bit_compare_p = true;
3404 : :
3405 : : /* op0 == op1 ? op0 : op3 is equivalent to op0 == op1 ? op1 : op3,
3406 : : but if op1 is a constant, the latter form allows more optimizations,
3407 : : either through the last 2 ops being constant handling, or the one
3408 : : constant and one variable cases. On the other side, for cmov the
3409 : : former might be better as we don't need to load the constant into
3410 : : another register. */
3411 : 446520 : if (code == EQ && CONST_INT_P (op1) && rtx_equal_p (op0, op2))
3412 : : op2 = op1;
3413 : : /* Similarly for op0 != op1 ? op2 : op0 and op0 != op1 ? op2 : op1. */
3414 : 512092 : else if (code == NE && CONST_INT_P (op1) && rtx_equal_p (op0, op3))
3415 : : op3 = op1;
3416 : :
3417 : : /* Don't attempt mode expansion here -- if we had to expand 5 or 6
3418 : : HImode insns, we'd be swallowed in word prefix ops. */
3419 : :
3420 : 3975 : if ((mode != HImode || TARGET_FAST_PREFIX)
3421 : 512570 : && (mode != (TARGET_64BIT ? TImode : DImode))
3422 : 512570 : && CONST_INT_P (op2)
3423 : 557908 : && CONST_INT_P (op3))
3424 : : {
3425 : 19787 : rtx out = operands[0];
3426 : 19787 : HOST_WIDE_INT ct = INTVAL (op2);
3427 : 19787 : HOST_WIDE_INT cf = INTVAL (op3);
3428 : 19787 : HOST_WIDE_INT diff;
3429 : :
3430 : 19787 : if ((mode == SImode
3431 : 10416 : || (TARGET_64BIT && mode == DImode))
3432 : 12983 : && (GET_MODE (op0) == SImode
3433 : 8665 : || (TARGET_64BIT && GET_MODE (op0) == DImode)))
3434 : : {
3435 : : /* Special case x != 0 ? -1 : y. */
3436 : 9266 : if (code == NE && op1 == const0_rtx && ct == -1)
3437 : : {
3438 : : negate_cc_compare_p = true;
3439 : : std::swap (ct, cf);
3440 : : code = EQ;
3441 : : }
3442 : 9123 : else if (code == EQ && op1 == const0_rtx && cf == -1)
3443 : 19787 : negate_cc_compare_p = true;
3444 : : }
3445 : :
3446 : 19787 : diff = ct - cf;
3447 : : /* Sign bit compares are better done using shifts than we do by using
3448 : : sbb. */
3449 : 19787 : if (sign_bit_compare_p
3450 : 19787 : || negate_cc_compare_p
3451 : 19787 : || ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
3452 : : {
3453 : : /* Detect overlap between destination and compare sources. */
3454 : 9980 : rtx tmp = out;
3455 : :
3456 : 9980 : if (negate_cc_compare_p)
3457 : : {
3458 : 314 : if (GET_MODE (op0) == DImode)
3459 : 120 : emit_insn (gen_x86_negdi_ccc (gen_reg_rtx (DImode), op0));
3460 : : else
3461 : 194 : emit_insn (gen_x86_negsi_ccc (gen_reg_rtx (SImode),
3462 : 194 : gen_lowpart (SImode, op0)));
3463 : :
3464 : 314 : tmp = gen_reg_rtx (mode);
3465 : 314 : if (mode == DImode)
3466 : 126 : emit_insn (gen_x86_movdicc_0_m1_neg (tmp));
3467 : : else
3468 : 188 : emit_insn (gen_x86_movsicc_0_m1_neg (gen_lowpart (SImode,
3469 : : tmp)));
3470 : : }
3471 : 9666 : else if (!sign_bit_compare_p)
3472 : : {
3473 : 8603 : rtx flags;
3474 : 8603 : bool fpcmp = false;
3475 : :
3476 : 8603 : compare_code = GET_CODE (compare_op);
3477 : :
3478 : 8603 : flags = XEXP (compare_op, 0);
3479 : :
3480 : 8603 : if (GET_MODE (flags) == CCFPmode)
3481 : : {
3482 : 91 : fpcmp = true;
3483 : 91 : compare_code
3484 : 91 : = ix86_fp_compare_code_to_integer (compare_code);
3485 : : }
3486 : :
3487 : : /* To simplify rest of code, restrict to the GEU case. */
3488 : 8603 : if (compare_code == LTU)
3489 : : {
3490 : 4446 : std::swap (ct, cf);
3491 : 4446 : compare_code = reverse_condition (compare_code);
3492 : 4446 : code = reverse_condition (code);
3493 : : }
3494 : : else
3495 : : {
3496 : 4157 : if (fpcmp)
3497 : 91 : PUT_CODE (compare_op,
3498 : : reverse_condition_maybe_unordered
3499 : : (GET_CODE (compare_op)));
3500 : : else
3501 : 4066 : PUT_CODE (compare_op,
3502 : : reverse_condition (GET_CODE (compare_op)));
3503 : : }
3504 : 8603 : diff = ct - cf;
3505 : :
3506 : 8603 : if (reg_overlap_mentioned_p (out, compare_op))
3507 : 0 : tmp = gen_reg_rtx (mode);
3508 : :
3509 : 8603 : if (mode == DImode)
3510 : 1897 : emit_insn (gen_x86_movdicc_0_m1 (tmp, flags, compare_op));
3511 : : else
3512 : 6706 : emit_insn (gen_x86_movsicc_0_m1 (gen_lowpart (SImode, tmp),
3513 : : flags, compare_op));
3514 : : }
3515 : : else
3516 : : {
3517 : 1063 : if (code == GT || code == GE)
3518 : 154 : code = reverse_condition (code);
3519 : : else
3520 : : {
3521 : 909 : std::swap (ct, cf);
3522 : 909 : diff = ct - cf;
3523 : : }
3524 : 1063 : tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode, 0, -1);
3525 : : }
3526 : :
3527 : 9980 : if (diff == 1)
3528 : : {
3529 : : /*
3530 : : * cmpl op0,op1
3531 : : * sbbl dest,dest
3532 : : * [addl dest, ct]
3533 : : *
3534 : : * Size 5 - 8.
3535 : : */
3536 : 1358 : if (ct)
3537 : 1218 : tmp = expand_simple_binop (mode, PLUS,
3538 : : tmp, GEN_INT (ct),
3539 : : copy_rtx (tmp), 1, OPTAB_DIRECT);
3540 : : }
3541 : 8622 : else if (cf == -1)
3542 : : {
3543 : : /*
3544 : : * cmpl op0,op1
3545 : : * sbbl dest,dest
3546 : : * orl $ct, dest
3547 : : *
3548 : : * Size 8.
3549 : : */
3550 : 707 : tmp = expand_simple_binop (mode, IOR,
3551 : : tmp, GEN_INT (ct),
3552 : : copy_rtx (tmp), 1, OPTAB_DIRECT);
3553 : : }
3554 : 7915 : else if (diff == -1 && ct)
3555 : : {
3556 : : /*
3557 : : * cmpl op0,op1
3558 : : * sbbl dest,dest
3559 : : * notl dest
3560 : : * [addl dest, cf]
3561 : : *
3562 : : * Size 8 - 11.
3563 : : */
3564 : 938 : tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
3565 : 938 : if (cf)
3566 : 922 : tmp = expand_simple_binop (mode, PLUS,
3567 : : copy_rtx (tmp), GEN_INT (cf),
3568 : : copy_rtx (tmp), 1, OPTAB_DIRECT);
3569 : : }
3570 : : else
3571 : : {
3572 : : /*
3573 : : * cmpl op0,op1
3574 : : * sbbl dest,dest
3575 : : * [notl dest]
3576 : : * andl cf - ct, dest
3577 : : * [addl dest, ct]
3578 : : *
3579 : : * Size 8 - 11.
3580 : : */
3581 : :
3582 : 6977 : if (cf == 0)
3583 : : {
3584 : 799 : cf = ct;
3585 : 799 : ct = 0;
3586 : 799 : tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
3587 : : }
3588 : :
3589 : 6977 : tmp = expand_simple_binop (mode, AND,
3590 : : copy_rtx (tmp),
3591 : 6977 : gen_int_mode (cf - ct, mode),
3592 : : copy_rtx (tmp), 1, OPTAB_DIRECT);
3593 : 6977 : if (ct)
3594 : 4944 : tmp = expand_simple_binop (mode, PLUS,
3595 : : copy_rtx (tmp), GEN_INT (ct),
3596 : : copy_rtx (tmp), 1, OPTAB_DIRECT);
3597 : : }
3598 : :
3599 : 9980 : if (!rtx_equal_p (tmp, out))
3600 : 409 : emit_move_insn (copy_rtx (out), copy_rtx (tmp));
3601 : :
3602 : 9980 : return true;
3603 : : }
3604 : :
3605 : 9807 : if (diff < 0)
3606 : : {
3607 : 5274 : machine_mode cmp_mode = GET_MODE (op0);
3608 : 5274 : enum rtx_code new_code;
3609 : :
3610 : 5274 : if (SCALAR_FLOAT_MODE_P (cmp_mode))
3611 : : {
3612 : 41 : gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode));
3613 : :
3614 : : /* We may be reversing a non-trapping
3615 : : comparison to a trapping comparison. */
3616 : 78 : if (HONOR_NANS (cmp_mode) && flag_trapping_math
3617 : 29 : && code != EQ && code != NE
3618 : 70 : && code != ORDERED && code != UNORDERED)
3619 : : new_code = UNKNOWN;
3620 : : else
3621 : 12 : new_code = reverse_condition_maybe_unordered (code);
3622 : : }
3623 : : else
3624 : 5233 : new_code = ix86_reverse_condition (code, cmp_mode);
3625 : 5245 : if (new_code != UNKNOWN)
3626 : : {
3627 : 5245 : std::swap (ct, cf);
3628 : 5245 : diff = -diff;
3629 : 5245 : code = new_code;
3630 : : }
3631 : : }
3632 : :
3633 : 9807 : compare_code = UNKNOWN;
3634 : 9807 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
3635 : 9616 : && CONST_INT_P (op1))
3636 : : {
3637 : 7266 : if (op1 == const0_rtx
3638 : 90 : && (code == LT || code == GE))
3639 : : compare_code = code;
3640 : 7266 : else if (op1 == constm1_rtx)
3641 : : {
3642 : 284 : if (code == LE)
3643 : : compare_code = LT;
3644 : 284 : else if (code == GT)
3645 : : compare_code = GE;
3646 : : }
3647 : : }
3648 : :
3649 : : /* Optimize dest = (op0 < 0) ? -1 : cf. */
3650 : : if (compare_code != UNKNOWN
3651 : 0 : && GET_MODE (op0) == GET_MODE (out)
3652 : 0 : && (cf == -1 || ct == -1))
3653 : : {
3654 : : /* If lea code below could be used, only optimize
3655 : : if it results in a 2 insn sequence. */
3656 : :
3657 : 0 : if (! (diff == 1 || diff == 2 || diff == 4 || diff == 8
3658 : 0 : || diff == 3 || diff == 5 || diff == 9)
3659 : 0 : || (compare_code == LT && ct == -1)
3660 : 0 : || (compare_code == GE && cf == -1))
3661 : : {
3662 : : /*
3663 : : * notl op1 (if necessary)
3664 : : * sarl $31, op1
3665 : : * orl cf, op1
3666 : : */
3667 : 0 : if (ct != -1)
3668 : : {
3669 : 0 : cf = ct;
3670 : 0 : ct = -1;
3671 : 0 : code = reverse_condition (code);
3672 : : }
3673 : :
3674 : 0 : out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, -1);
3675 : :
3676 : 0 : out = expand_simple_binop (mode, IOR,
3677 : : out, GEN_INT (cf),
3678 : : out, 1, OPTAB_DIRECT);
3679 : 0 : if (out != operands[0])
3680 : 0 : emit_move_insn (operands[0], out);
3681 : :
3682 : 0 : return true;
3683 : : }
3684 : : }
3685 : :
3686 : :
3687 : 17217 : if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
3688 : 7410 : || diff == 3 || diff == 5 || diff == 9)
3689 : 2676 : && ((mode != QImode && mode != HImode) || !TARGET_PARTIAL_REG_STALL)
3690 : 12483 : && (mode != DImode
3691 : 463 : || x86_64_immediate_operand (GEN_INT (cf), VOIDmode)))
3692 : : {
3693 : : /*
3694 : : * xorl dest,dest
3695 : : * cmpl op1,op2
3696 : : * setcc dest
3697 : : * lea cf(dest*(ct-cf)),dest
3698 : : *
3699 : : * Size 14.
3700 : : *
3701 : : * This also catches the degenerate setcc-only case.
3702 : : */
3703 : :
3704 : 2676 : rtx tmp;
3705 : 2676 : int nops;
3706 : :
3707 : 2676 : out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, 1);
3708 : :
3709 : 2676 : nops = 0;
3710 : : /* On x86_64 the lea instruction operates on Pmode, so we need
3711 : : to get arithmetics done in proper mode to match. */
3712 : 2676 : if (diff == 1)
3713 : 1668 : tmp = copy_rtx (out);
3714 : : else
3715 : : {
3716 : 1008 : rtx out1;
3717 : 1008 : out1 = copy_rtx (out);
3718 : 1008 : tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
3719 : 1008 : nops++;
3720 : 1008 : if (diff & 1)
3721 : : {
3722 : 235 : tmp = gen_rtx_PLUS (mode, tmp, out1);
3723 : 235 : nops++;
3724 : : }
3725 : : }
3726 : 2676 : if (cf != 0)
3727 : : {
3728 : 1884 : tmp = plus_constant (mode, tmp, cf);
3729 : 1884 : nops++;
3730 : : }
3731 : 2676 : if (!rtx_equal_p (tmp, out))
3732 : : {
3733 : 2057 : if (nops == 1)
3734 : 1081 : out = force_operand (tmp, copy_rtx (out));
3735 : : else
3736 : 976 : emit_insn (gen_rtx_SET (copy_rtx (out), copy_rtx (tmp)));
3737 : : }
3738 : 2676 : if (!rtx_equal_p (out, operands[0]))
3739 : 747 : emit_move_insn (operands[0], copy_rtx (out));
3740 : :
3741 : 2676 : return true;
3742 : : }
3743 : :
3744 : : /*
3745 : : * General case: Jumpful:
3746 : : * xorl dest,dest cmpl op1, op2
3747 : : * cmpl op1, op2 movl ct, dest
3748 : : * setcc dest jcc 1f
3749 : : * decl dest movl cf, dest
3750 : : * andl (cf-ct),dest 1:
3751 : : * addl ct,dest
3752 : : *
3753 : : * Size 20. Size 14.
3754 : : *
3755 : : * This is reasonably steep, but branch mispredict costs are
3756 : : * high on modern cpus, so consider failing only if optimizing
3757 : : * for space.
3758 : : */
3759 : :
3760 : 7131 : if ((!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
3761 : 7131 : && BRANCH_COST (optimize_insn_for_speed_p (),
3762 : : false) >= 2)
3763 : : {
3764 : 0 : if (cf == 0)
3765 : : {
3766 : 0 : machine_mode cmp_mode = GET_MODE (op0);
3767 : 0 : enum rtx_code new_code;
3768 : :
3769 : 0 : if (SCALAR_FLOAT_MODE_P (cmp_mode))
3770 : : {
3771 : 0 : gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode));
3772 : :
3773 : : /* We may be reversing a non-trapping
3774 : : comparison to a trapping comparison. */
3775 : 0 : if (HONOR_NANS (cmp_mode) && flag_trapping_math
3776 : 0 : && code != EQ && code != NE
3777 : 0 : && code != ORDERED && code != UNORDERED)
3778 : : new_code = UNKNOWN;
3779 : : else
3780 : 0 : new_code = reverse_condition_maybe_unordered (code);
3781 : :
3782 : : }
3783 : : else
3784 : : {
3785 : 0 : new_code = ix86_reverse_condition (code, cmp_mode);
3786 : 0 : if (compare_code != UNKNOWN && new_code != UNKNOWN)
3787 : 0 : compare_code = reverse_condition (compare_code);
3788 : : }
3789 : :
3790 : 0 : if (new_code != UNKNOWN)
3791 : : {
3792 : 0 : cf = ct;
3793 : 0 : ct = 0;
3794 : 0 : code = new_code;
3795 : : }
3796 : : }
3797 : :
3798 : 0 : if (compare_code != UNKNOWN)
3799 : : {
3800 : : /* notl op1 (if needed)
3801 : : sarl $31, op1
3802 : : andl (cf-ct), op1
3803 : : addl ct, op1
3804 : :
3805 : : For x < 0 (resp. x <= -1) there will be no notl,
3806 : : so if possible swap the constants to get rid of the
3807 : : complement.
3808 : : True/false will be -1/0 while code below (store flag
3809 : : followed by decrement) is 0/-1, so the constants need
3810 : : to be exchanged once more. */
3811 : :
3812 : 0 : if (compare_code == GE || !cf)
3813 : : {
3814 : 0 : code = reverse_condition (code);
3815 : 0 : compare_code = LT;
3816 : : }
3817 : : else
3818 : : std::swap (ct, cf);
3819 : :
3820 : 0 : out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, -1);
3821 : : }
3822 : : else
3823 : : {
3824 : 0 : out = emit_store_flag (out, code, op0, op1, VOIDmode, 0, 1);
3825 : :
3826 : 0 : out = expand_simple_binop (mode, PLUS, copy_rtx (out),
3827 : : constm1_rtx,
3828 : : copy_rtx (out), 1, OPTAB_DIRECT);
3829 : : }
3830 : :
3831 : 0 : out = expand_simple_binop (mode, AND, copy_rtx (out),
3832 : 0 : gen_int_mode (cf - ct, mode),
3833 : : copy_rtx (out), 1, OPTAB_DIRECT);
3834 : 0 : if (ct)
3835 : 0 : out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct),
3836 : : copy_rtx (out), 1, OPTAB_DIRECT);
3837 : 0 : if (!rtx_equal_p (out, operands[0]))
3838 : 0 : emit_move_insn (operands[0], copy_rtx (out));
3839 : :
3840 : 0 : return true;
3841 : : }
3842 : : }
3843 : :
3844 : 499914 : if (!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
3845 : : {
3846 : : /* Try a few things more with specific constants and a variable. */
3847 : :
3848 : 0 : optab op;
3849 : 0 : rtx var, orig_out, out, tmp;
3850 : :
3851 : 0 : if (BRANCH_COST (optimize_insn_for_speed_p (), false) <= 2)
3852 : : return false;
3853 : :
3854 : 0 : operands[2] = op2;
3855 : 0 : operands[3] = op3;
3856 : :
3857 : : /* If one of the two operands is an interesting constant, load a
3858 : : constant with the above and mask it in with a logical operation. */
3859 : :
3860 : 0 : if (CONST_INT_P (operands[2]))
3861 : : {
3862 : 0 : var = operands[3];
3863 : 0 : if (INTVAL (operands[2]) == 0 && operands[3] != constm1_rtx)
3864 : 0 : operands[3] = constm1_rtx, op = and_optab;
3865 : 0 : else if (INTVAL (operands[2]) == -1 && operands[3] != const0_rtx)
3866 : 0 : operands[3] = const0_rtx, op = ior_optab;
3867 : : else
3868 : : return false;
3869 : : }
3870 : 0 : else if (CONST_INT_P (operands[3]))
3871 : : {
3872 : 0 : var = operands[2];
3873 : 0 : if (INTVAL (operands[3]) == 0 && operands[2] != constm1_rtx)
3874 : : {
3875 : : /* For smin (x, 0), expand as "x < 0 ? x : 0" instead of
3876 : : "x <= 0 ? x : 0" to enable sign_bit_compare_p. */
3877 : 0 : if (code == LE && op1 == const0_rtx && rtx_equal_p (op0, var))
3878 : 0 : operands[1] = simplify_gen_relational (LT, VOIDmode,
3879 : 0 : GET_MODE (op0),
3880 : : op0, const0_rtx);
3881 : :
3882 : 0 : operands[2] = constm1_rtx;
3883 : 0 : op = and_optab;
3884 : : }
3885 : 0 : else if (INTVAL (operands[3]) == -1 && operands[3] != const0_rtx)
3886 : 0 : operands[2] = const0_rtx, op = ior_optab;
3887 : : else
3888 : : return false;
3889 : : }
3890 : : else
3891 : : return false;
3892 : :
3893 : 0 : orig_out = operands[0];
3894 : 0 : tmp = gen_reg_rtx (mode);
3895 : 0 : operands[0] = tmp;
3896 : :
3897 : : /* Recurse to get the constant loaded. */
3898 : 0 : if (!ix86_expand_int_movcc (operands))
3899 : : return false;
3900 : :
3901 : : /* Mask in the interesting variable. */
3902 : 0 : out = expand_binop (mode, op, var, tmp, orig_out, 0,
3903 : : OPTAB_WIDEN);
3904 : 0 : if (!rtx_equal_p (out, orig_out))
3905 : 0 : emit_move_insn (copy_rtx (orig_out), copy_rtx (out));
3906 : :
3907 : 0 : return true;
3908 : : }
3909 : :
3910 : : /*
3911 : : * For comparison with above,
3912 : : *
3913 : : * movl cf,dest
3914 : : * movl ct,tmp
3915 : : * cmpl op1,op2
3916 : : * cmovcc tmp,dest
3917 : : *
3918 : : * Size 15.
3919 : : */
3920 : :
3921 : 499914 : if (! nonimmediate_operand (operands[2], mode))
3922 : 41246 : operands[2] = force_reg (mode, operands[2]);
3923 : 499914 : if (! nonimmediate_operand (operands[3], mode))
3924 : 208626 : operands[3] = force_reg (mode, operands[3]);
3925 : :
3926 : 499914 : if (! register_operand (operands[2], VOIDmode)
3927 : 499914 : && (mode == QImode
3928 : 1076 : || ! register_operand (operands[3], VOIDmode)))
3929 : 1545 : operands[2] = force_reg (mode, operands[2]);
3930 : :
3931 : 499914 : if (mode == QImode
3932 : 499914 : && ! register_operand (operands[3], VOIDmode))
3933 : 592 : operands[3] = force_reg (mode, operands[3]);
3934 : :
3935 : 499914 : emit_insn (compare_seq);
3936 : 499914 : emit_insn (gen_rtx_SET (operands[0],
3937 : : gen_rtx_IF_THEN_ELSE (mode,
3938 : : compare_op, operands[2],
3939 : : operands[3])));
3940 : 499914 : return true;
3941 : : }
3942 : :
3943 : : /* Detect conditional moves that exactly match min/max operational
3944 : : semantics. Note that this is IEEE safe, as long as we don't
3945 : : interchange the operands.
3946 : :
3947 : : Returns FALSE if this conditional move doesn't match a MIN/MAX,
3948 : : and TRUE if the operation is successful and instructions are emitted. */
3949 : :
3950 : : static bool
3951 : 7296 : ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0,
3952 : : rtx cmp_op1, rtx if_true, rtx if_false)
3953 : : {
3954 : 7296 : machine_mode mode;
3955 : 7296 : bool is_min;
3956 : 7296 : rtx tmp;
3957 : :
3958 : 7296 : if (code == LT)
3959 : : ;
3960 : 2506 : else if (code == UNGE)
3961 : : std::swap (if_true, if_false);
3962 : : else
3963 : : return false;
3964 : :
3965 : 6221 : if (rtx_equal_p (cmp_op0, if_true) && rtx_equal_p (cmp_op1, if_false))
3966 : : is_min = true;
3967 : 3596 : else if (rtx_equal_p (cmp_op1, if_true) && rtx_equal_p (cmp_op0, if_false))
3968 : : is_min = false;
3969 : : else
3970 : 1097 : return false;
3971 : :
3972 : 5124 : mode = GET_MODE (dest);
3973 : :
3974 : : /* We want to check HONOR_NANS and HONOR_SIGNED_ZEROS here,
3975 : : but MODE may be a vector mode and thus not appropriate. */
3976 : 5124 : if (!flag_finite_math_only || flag_signed_zeros)
3977 : : {
3978 : 5124 : int u = is_min ? UNSPEC_IEEE_MIN : UNSPEC_IEEE_MAX;
3979 : 5124 : rtvec v;
3980 : :
3981 : 5124 : if_true = force_reg (mode, if_true);
3982 : 5124 : v = gen_rtvec (2, if_true, if_false);
3983 : 5124 : tmp = gen_rtx_UNSPEC (mode, v, u);
3984 : 5124 : }
3985 : : else
3986 : : {
3987 : 0 : code = is_min ? SMIN : SMAX;
3988 : 0 : if (MEM_P (if_true) && MEM_P (if_false))
3989 : 0 : if_true = force_reg (mode, if_true);
3990 : 0 : tmp = gen_rtx_fmt_ee (code, mode, if_true, if_false);
3991 : : }
3992 : :
3993 : 5124 : emit_insn (gen_rtx_SET (dest, tmp));
3994 : 5124 : return true;
3995 : : }
3996 : :
3997 : : /* Return true if MODE is valid for vector compare to mask register,
3998 : : Same result for conditionl vector move with mask register. */
3999 : : static bool
4000 : 6912 : ix86_valid_mask_cmp_mode (machine_mode mode)
4001 : : {
4002 : : /* XOP has its own vector conditional movement. */
4003 : 6912 : if (TARGET_XOP && !TARGET_AVX512F)
4004 : : return false;
4005 : :
4006 : : /* HFmode only supports vcmpsh whose dest is mask register. */
4007 : 6906 : if (TARGET_AVX512FP16 && mode == HFmode)
4008 : : return true;
4009 : :
4010 : : /* AVX512F is needed for mask operation. */
4011 : 6902 : if (!(TARGET_AVX512F && VECTOR_MODE_P (mode)))
4012 : : return false;
4013 : :
4014 : : /* AVX512BW is needed for vector QI/HImode,
4015 : : AVX512VL is needed for 128/256-bit vector. */
4016 : 190 : machine_mode inner_mode = GET_MODE_INNER (mode);
4017 : 190 : int vector_size = GET_MODE_SIZE (mode);
4018 : 190 : if ((inner_mode == QImode || inner_mode == HImode) && !TARGET_AVX512BW)
4019 : : return false;
4020 : :
4021 : 170 : return (vector_size == 64 && TARGET_EVEX512) || TARGET_AVX512VL;
4022 : : }
4023 : :
4024 : : /* Return true if integer mask comparison should be used. */
4025 : : static bool
4026 : 36750 : ix86_use_mask_cmp_p (machine_mode mode, machine_mode cmp_mode,
4027 : : rtx op_true, rtx op_false)
4028 : : {
4029 : 36750 : int vector_size = GET_MODE_SIZE (mode);
4030 : :
4031 : 36750 : if (cmp_mode == HFmode)
4032 : : return true;
4033 : 36746 : else if (vector_size < 16)
4034 : : return false;
4035 : 30998 : else if (vector_size == 64)
4036 : : return true;
4037 : 61880 : else if (GET_MODE_INNER (cmp_mode) == HFmode)
4038 : : return true;
4039 : 61880 : else if (GET_MODE_INNER (cmp_mode) == BFmode)
4040 : : return true;
4041 : :
4042 : : /* When op_true is NULL, op_false must be NULL, or vice versa. */
4043 : 30940 : gcc_assert (!op_true == !op_false);
4044 : :
4045 : : /* When op_true/op_false is NULL or cmp_mode is not valid mask cmp mode,
4046 : : vector dest is required. */
4047 : 30940 : if (!op_true || !ix86_valid_mask_cmp_mode (cmp_mode))
4048 : 30892 : return false;
4049 : :
4050 : : /* Exclude those that could be optimized in ix86_expand_sse_movcc. */
4051 : 48 : if (op_false == CONST0_RTX (mode)
4052 : 48 : || op_true == CONST0_RTX (mode)
4053 : 48 : || (INTEGRAL_MODE_P (mode)
4054 : 40 : && (op_true == CONSTM1_RTX (mode)
4055 : 40 : || op_false == CONSTM1_RTX (mode))))
4056 : : return false;
4057 : :
4058 : : return true;
4059 : : }
4060 : :
4061 : : /* Expand an SSE comparison. Return the register with the result. */
4062 : :
4063 : : static rtx
4064 : 25587 : ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
4065 : : rtx op_true, rtx op_false)
4066 : : {
4067 : 25587 : machine_mode mode = GET_MODE (dest);
4068 : 25587 : machine_mode cmp_ops_mode = GET_MODE (cmp_op0);
4069 : :
4070 : : /* In general case result of comparison can differ from operands' type. */
4071 : 25587 : machine_mode cmp_mode;
4072 : :
4073 : : /* In AVX512F the result of comparison is an integer mask. */
4074 : 25587 : bool maskcmp = false;
4075 : 25587 : rtx x;
4076 : :
4077 : 25587 : if (ix86_use_mask_cmp_p (mode, cmp_ops_mode, op_true, op_false))
4078 : : {
4079 : 57 : unsigned int nbits = GET_MODE_NUNITS (cmp_ops_mode);
4080 : 57 : maskcmp = true;
4081 : 57 : cmp_mode = nbits > 8 ? int_mode_for_size (nbits, 0).require () : E_QImode;
4082 : : }
4083 : : else
4084 : : cmp_mode = cmp_ops_mode;
4085 : :
4086 : 25587 : cmp_op0 = force_reg (cmp_ops_mode, cmp_op0);
4087 : :
4088 : 51174 : bool (*op1_predicate)(rtx, machine_mode)
4089 : 25587 : = VECTOR_MODE_P (cmp_ops_mode) ? vector_operand : nonimmediate_operand;
4090 : :
4091 : 25587 : if (!op1_predicate (cmp_op1, cmp_ops_mode))
4092 : 0 : cmp_op1 = force_reg (cmp_ops_mode, cmp_op1);
4093 : :
4094 : 25587 : if (optimize
4095 : 503 : || (maskcmp && cmp_mode != mode)
4096 : 503 : || (op_true && reg_overlap_mentioned_p (dest, op_true))
4097 : 26090 : || (op_false && reg_overlap_mentioned_p (dest, op_false)))
4098 : 50111 : dest = gen_reg_rtx (maskcmp ? cmp_mode : mode);
4099 : :
4100 : 25587 : if (maskcmp)
4101 : : {
4102 : 57 : bool ok = ix86_expand_mask_vec_cmp (dest, code, cmp_op0, cmp_op1);
4103 : 57 : gcc_assert (ok);
4104 : : return dest;
4105 : : }
4106 : :
4107 : 25530 : x = gen_rtx_fmt_ee (code, cmp_mode, cmp_op0, cmp_op1);
4108 : :
4109 : 25530 : if (cmp_mode != mode)
4110 : : {
4111 : 6648 : x = force_reg (cmp_ops_mode, x);
4112 : 6648 : convert_move (dest, x, false);
4113 : : }
4114 : : else
4115 : 18882 : emit_insn (gen_rtx_SET (dest, x));
4116 : :
4117 : : return dest;
4118 : : }
4119 : :
4120 : : /* Emit x86 binary operand CODE in mode MODE for SSE vector
4121 : : instructions that can be performed using GP registers. */
4122 : :
4123 : : static void
4124 : 4256 : ix86_emit_vec_binop (enum rtx_code code, machine_mode mode,
4125 : : rtx dst, rtx src1, rtx src2)
4126 : : {
4127 : 4256 : rtx tmp;
4128 : :
4129 : 4256 : tmp = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, mode, src1, src2));
4130 : :
4131 : 8512 : if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode)
4132 : 4256 : && GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4133 : : {
4134 : 48 : rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
4135 : 48 : tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
4136 : : }
4137 : :
4138 : 4256 : emit_insn (tmp);
4139 : 4256 : }
4140 : :
4141 : : /* Expand DEST = CMP ? OP_TRUE : OP_FALSE into a sequence of logical
4142 : : operations. This is used for both scalar and vector conditional moves. */
4143 : :
4144 : : void
4145 : 6094 : ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
4146 : : {
4147 : 6094 : machine_mode mode = GET_MODE (dest);
4148 : 6094 : machine_mode cmpmode = GET_MODE (cmp);
4149 : 6094 : rtx x;
4150 : :
4151 : : /* Simplify trivial VEC_COND_EXPR to avoid ICE in pr97506. */
4152 : 6094 : if (rtx_equal_p (op_true, op_false))
4153 : : {
4154 : 0 : emit_move_insn (dest, op_true);
4155 : 0 : return;
4156 : : }
4157 : :
4158 : : /* If we have an integer mask and FP value then we need
4159 : : to cast mask to FP mode. */
4160 : 6094 : if (mode != cmpmode && VECTOR_MODE_P (cmpmode))
4161 : : {
4162 : 954 : cmp = force_reg (cmpmode, cmp);
4163 : 954 : cmp = gen_rtx_SUBREG (mode, cmp, 0);
4164 : : }
4165 : :
4166 : : /* In AVX512F the result of comparison is an integer mask. */
4167 : 6094 : if (mode != cmpmode
4168 : 1011 : && GET_MODE_CLASS (cmpmode) == MODE_INT)
4169 : : {
4170 : 57 : gcc_assert (ix86_valid_mask_cmp_mode (mode));
4171 : : /* Using scalar/vector move with mask register. */
4172 : 57 : cmp = force_reg (cmpmode, cmp);
4173 : : /* Optimize for mask zero. */
4174 : 114 : op_true = (op_true != CONST0_RTX (mode)
4175 : 57 : ? force_reg (mode, op_true) : op_true);
4176 : 114 : op_false = (op_false != CONST0_RTX (mode)
4177 : 57 : ? force_reg (mode, op_false) : op_false);
4178 : 57 : if (op_true == CONST0_RTX (mode))
4179 : : {
4180 : 0 : if (cmpmode == E_DImode && !TARGET_64BIT)
4181 : : {
4182 : 0 : x = gen_reg_rtx (cmpmode);
4183 : 0 : emit_insn (gen_knotdi (x, cmp));
4184 : : }
4185 : : else
4186 : 0 : x = expand_simple_unop (cmpmode, NOT, cmp, NULL, 1);
4187 : : cmp = x;
4188 : : /* Reverse op_true op_false. */
4189 : : std::swap (op_true, op_false);
4190 : : }
4191 : :
4192 : 57 : if (mode == HFmode)
4193 : 4 : emit_insn (gen_movhf_mask (dest, op_true, op_false, cmp));
4194 : : else
4195 : 53 : emit_insn (gen_rtx_SET (dest,
4196 : : gen_rtx_VEC_MERGE (mode,
4197 : : op_true, op_false, cmp)));
4198 : 57 : return;
4199 : : }
4200 : :
4201 : 6037 : if (vector_all_ones_operand (op_true, mode)
4202 : 6037 : && op_false == CONST0_RTX (mode))
4203 : : {
4204 : 0 : emit_move_insn (dest, cmp);
4205 : 0 : return;
4206 : : }
4207 : 6037 : else if (op_false == CONST0_RTX (mode))
4208 : : {
4209 : 252 : x = expand_simple_binop (mode, AND, cmp, op_true,
4210 : : dest, 1, OPTAB_DIRECT);
4211 : 252 : if (x != dest)
4212 : 0 : emit_move_insn (dest, x);
4213 : 252 : return;
4214 : : }
4215 : 5785 : else if (op_true == CONST0_RTX (mode))
4216 : : {
4217 : 0 : op_false = force_reg (mode, op_false);
4218 : 0 : x = gen_rtx_NOT (mode, cmp);
4219 : 0 : ix86_emit_vec_binop (AND, mode, dest, x, op_false);
4220 : 0 : return;
4221 : : }
4222 : 5785 : else if (vector_all_ones_operand (op_true, mode))
4223 : : {
4224 : 0 : x = expand_simple_binop (mode, IOR, cmp, op_false,
4225 : : dest, 1, OPTAB_DIRECT);
4226 : 0 : if (x != dest)
4227 : 0 : emit_move_insn (dest, x);
4228 : 0 : return;
4229 : : }
4230 : :
4231 : 5785 : if (TARGET_XOP)
4232 : : {
4233 : 66 : op_true = force_reg (mode, op_true);
4234 : :
4235 : 66 : if (GET_MODE_SIZE (mode) < 16
4236 : 66 : || !nonimmediate_operand (op_false, mode))
4237 : 49 : op_false = force_reg (mode, op_false);
4238 : :
4239 : 66 : emit_insn (gen_rtx_SET (dest,
4240 : : gen_rtx_IF_THEN_ELSE (mode, cmp,
4241 : : op_true, op_false)));
4242 : 66 : return;
4243 : : }
4244 : :
4245 : 5719 : rtx (*gen) (rtx, rtx, rtx, rtx) = NULL;
4246 : 5719 : machine_mode blend_mode = mode;
4247 : :
4248 : 5719 : if (GET_MODE_SIZE (mode) < 16
4249 : 5719 : || !vector_operand (op_true, mode))
4250 : 2526 : op_true = force_reg (mode, op_true);
4251 : :
4252 : 5719 : op_false = force_reg (mode, op_false);
4253 : :
4254 : 5719 : switch (mode)
4255 : : {
4256 : 29 : case E_V2SFmode:
4257 : 29 : if (TARGET_SSE4_1)
4258 : : gen = gen_mmx_blendvps;
4259 : : break;
4260 : 280 : case E_V4SFmode:
4261 : 280 : if (TARGET_SSE4_1)
4262 : : gen = gen_sse4_1_blendvps;
4263 : : break;
4264 : 184 : case E_V2DFmode:
4265 : 184 : if (TARGET_SSE4_1)
4266 : : gen = gen_sse4_1_blendvpd;
4267 : : break;
4268 : 1267 : case E_SFmode:
4269 : 1267 : if (TARGET_SSE4_1)
4270 : : gen = gen_sse4_1_blendvss;
4271 : : break;
4272 : 897 : case E_DFmode:
4273 : 897 : if (TARGET_SSE4_1)
4274 : : gen = gen_sse4_1_blendvsd;
4275 : : break;
4276 : 220 : case E_V8QImode:
4277 : 220 : case E_V4HImode:
4278 : 220 : case E_V4HFmode:
4279 : 220 : case E_V4BFmode:
4280 : 220 : case E_V2SImode:
4281 : 220 : if (TARGET_SSE4_1)
4282 : : {
4283 : : gen = gen_mmx_pblendvb_v8qi;
4284 : : blend_mode = V8QImode;
4285 : : }
4286 : : break;
4287 : 77 : case E_V4QImode:
4288 : 77 : case E_V2HImode:
4289 : 77 : case E_V2HFmode:
4290 : 77 : case E_V2BFmode:
4291 : 77 : if (TARGET_SSE4_1)
4292 : : {
4293 : : gen = gen_mmx_pblendvb_v4qi;
4294 : : blend_mode = V4QImode;
4295 : : }
4296 : : break;
4297 : 36 : case E_V2QImode:
4298 : 36 : if (TARGET_SSE4_1)
4299 : : gen = gen_mmx_pblendvb_v2qi;
4300 : : break;
4301 : 2349 : case E_V16QImode:
4302 : 2349 : case E_V8HImode:
4303 : 2349 : case E_V8HFmode:
4304 : 2349 : case E_V8BFmode:
4305 : 2349 : case E_V4SImode:
4306 : 2349 : case E_V2DImode:
4307 : 2349 : case E_V1TImode:
4308 : 2349 : if (TARGET_SSE4_1)
4309 : : {
4310 : : gen = gen_sse4_1_pblendvb;
4311 : : blend_mode = V16QImode;
4312 : : }
4313 : : break;
4314 : 76 : case E_V8SFmode:
4315 : 76 : if (TARGET_AVX)
4316 : : gen = gen_avx_blendvps256;
4317 : : break;
4318 : 89 : case E_V4DFmode:
4319 : 89 : if (TARGET_AVX)
4320 : : gen = gen_avx_blendvpd256;
4321 : : break;
4322 : 215 : case E_V32QImode:
4323 : 215 : case E_V16HImode:
4324 : 215 : case E_V16HFmode:
4325 : 215 : case E_V16BFmode:
4326 : 215 : case E_V8SImode:
4327 : 215 : case E_V4DImode:
4328 : 215 : if (TARGET_AVX2)
4329 : : {
4330 : : gen = gen_avx2_pblendvb;
4331 : : blend_mode = V32QImode;
4332 : : }
4333 : : break;
4334 : :
4335 : 0 : case E_V64QImode:
4336 : 0 : gen = gen_avx512bw_blendmv64qi;
4337 : 0 : break;
4338 : 0 : case E_V32HImode:
4339 : 0 : gen = gen_avx512bw_blendmv32hi;
4340 : 0 : break;
4341 : 0 : case E_V32HFmode:
4342 : 0 : gen = gen_avx512bw_blendmv32hf;
4343 : 0 : break;
4344 : 0 : case E_V32BFmode:
4345 : 0 : gen = gen_avx512bw_blendmv32bf;
4346 : 0 : break;
4347 : 0 : case E_V16SImode:
4348 : 0 : gen = gen_avx512f_blendmv16si;
4349 : 0 : break;
4350 : 0 : case E_V8DImode:
4351 : 0 : gen = gen_avx512f_blendmv8di;
4352 : 0 : break;
4353 : 0 : case E_V8DFmode:
4354 : 0 : gen = gen_avx512f_blendmv8df;
4355 : 0 : break;
4356 : : case E_V16SFmode:
4357 : : gen = gen_avx512f_blendmv16sf;
4358 : : break;
4359 : :
4360 : : default:
4361 : : break;
4362 : : }
4363 : :
4364 : 0 : if (gen != NULL)
4365 : : {
4366 : 1530 : if (blend_mode == mode)
4367 : : x = dest;
4368 : : else
4369 : : {
4370 : 780 : x = gen_reg_rtx (blend_mode);
4371 : 780 : op_false = gen_lowpart (blend_mode, op_false);
4372 : 780 : op_true = gen_lowpart (blend_mode, op_true);
4373 : 780 : cmp = gen_lowpart (blend_mode, cmp);
4374 : : }
4375 : :
4376 : 1530 : emit_insn (gen (x, op_false, op_true, cmp));
4377 : :
4378 : 1530 : if (x != dest)
4379 : 780 : emit_move_insn (dest, gen_lowpart (mode, x));
4380 : : }
4381 : : else
4382 : : {
4383 : 4189 : rtx t2, t3;
4384 : :
4385 : 4189 : t2 = expand_simple_binop (mode, AND, op_true, cmp,
4386 : : NULL, 1, OPTAB_DIRECT);
4387 : :
4388 : 4189 : t3 = gen_reg_rtx (mode);
4389 : 4189 : x = gen_rtx_NOT (mode, cmp);
4390 : 4189 : ix86_emit_vec_binop (AND, mode, t3, x, op_false);
4391 : :
4392 : 4189 : x = expand_simple_binop (mode, IOR, t3, t2,
4393 : : dest, 1, OPTAB_DIRECT);
4394 : 4189 : if (x != dest)
4395 : 0 : emit_move_insn (dest, x);
4396 : : }
4397 : : }
4398 : :
4399 : : /* Swap, force into registers, or otherwise massage the two operands
4400 : : to an sse comparison with a mask result. Thus we differ a bit from
4401 : : ix86_prepare_fp_compare_args which expects to produce a flags result.
4402 : :
4403 : : The DEST operand exists to help determine whether to commute commutative
4404 : : operators. The POP0/POP1 operands are updated in place. The new
4405 : : comparison code is returned, or UNKNOWN if not implementable. */
4406 : :
4407 : : static enum rtx_code
4408 : 13945 : ix86_prepare_sse_fp_compare_args (rtx dest, enum rtx_code code,
4409 : : rtx *pop0, rtx *pop1)
4410 : : {
4411 : 13945 : switch (code)
4412 : : {
4413 : 53 : case LTGT:
4414 : 53 : case UNEQ:
4415 : : /* AVX supports all the needed comparisons. */
4416 : 53 : if (TARGET_AVX)
4417 : : break;
4418 : : /* We have no LTGT as an operator. We could implement it with
4419 : : NE & ORDERED, but this requires an extra temporary. It's
4420 : : not clear that it's worth it. */
4421 : : return UNKNOWN;
4422 : :
4423 : : case LT:
4424 : : case LE:
4425 : : case UNGT:
4426 : : case UNGE:
4427 : : /* These are supported directly. */
4428 : : break;
4429 : :
4430 : 5125 : case EQ:
4431 : 5125 : case NE:
4432 : 5125 : case UNORDERED:
4433 : 5125 : case ORDERED:
4434 : : /* AVX has 3 operand comparisons, no need to swap anything. */
4435 : 5125 : if (TARGET_AVX)
4436 : : break;
4437 : : /* For commutative operators, try to canonicalize the destination
4438 : : operand to be first in the comparison - this helps reload to
4439 : : avoid extra moves. */
4440 : 334 : if (!dest || !rtx_equal_p (dest, *pop1))
4441 : : break;
4442 : : /* FALLTHRU */
4443 : :
4444 : 7836 : case GE:
4445 : 7836 : case GT:
4446 : 7836 : case UNLE:
4447 : 7836 : case UNLT:
4448 : : /* These are not supported directly before AVX, and furthermore
4449 : : ix86_expand_sse_fp_minmax only optimizes LT/UNGE. Swap the
4450 : : comparison operands to transform into something that is
4451 : : supported. */
4452 : 7836 : std::swap (*pop0, *pop1);
4453 : 7836 : code = swap_condition (code);
4454 : 7836 : break;
4455 : :
4456 : 0 : default:
4457 : 0 : gcc_unreachable ();
4458 : : }
4459 : :
4460 : : return code;
4461 : : }
4462 : :
4463 : : /* Expand a floating-point conditional move. Return true if successful. */
4464 : :
4465 : : bool
4466 : 76495 : ix86_expand_fp_movcc (rtx operands[])
4467 : : {
4468 : 76495 : machine_mode mode = GET_MODE (operands[0]);
4469 : 76495 : enum rtx_code code = GET_CODE (operands[1]);
4470 : 76495 : rtx tmp, compare_op;
4471 : 76495 : rtx op0 = XEXP (operands[1], 0);
4472 : 76495 : rtx op1 = XEXP (operands[1], 1);
4473 : :
4474 : 76495 : if (GET_MODE (op0) == BFmode
4475 : 76495 : && !ix86_fp_comparison_operator (operands[1], VOIDmode))
4476 : : return false;
4477 : :
4478 : 76495 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
4479 : : {
4480 : 45868 : machine_mode cmode;
4481 : :
4482 : : /* Since we've no cmove for sse registers, don't force bad register
4483 : : allocation just to gain access to it. Deny movcc when the
4484 : : comparison mode doesn't match the move mode. */
4485 : 45868 : cmode = GET_MODE (op0);
4486 : 45868 : if (cmode == VOIDmode)
4487 : 0 : cmode = GET_MODE (op1);
4488 : 45868 : if (cmode != mode)
4489 : : return false;
4490 : :
4491 : 7316 : code = ix86_prepare_sse_fp_compare_args (operands[0], code, &op0, &op1);
4492 : 7316 : if (code == UNKNOWN)
4493 : : return false;
4494 : :
4495 : 7296 : if (ix86_expand_sse_fp_minmax (operands[0], code, op0, op1,
4496 : : operands[2], operands[3]))
4497 : : return true;
4498 : :
4499 : 2172 : tmp = ix86_expand_sse_cmp (operands[0], code, op0, op1,
4500 : : operands[2], operands[3]);
4501 : 2172 : ix86_expand_sse_movcc (operands[0], tmp, operands[2], operands[3]);
4502 : 2172 : return true;
4503 : : }
4504 : :
4505 : 30627 : if (GET_MODE (op0) == TImode
4506 : 30627 : || (GET_MODE (op0) == DImode
4507 : 72 : && !TARGET_64BIT))
4508 : : return false;
4509 : :
4510 : : /* The floating point conditional move instructions don't directly
4511 : : support conditions resulting from a signed integer comparison. */
4512 : :
4513 : 30555 : compare_op = ix86_expand_compare (code, op0, op1);
4514 : 30555 : if (!fcmov_comparison_operator (compare_op, VOIDmode))
4515 : : {
4516 : 143 : tmp = gen_reg_rtx (QImode);
4517 : 143 : ix86_expand_setcc (tmp, code, op0, op1);
4518 : :
4519 : 143 : compare_op = ix86_expand_compare (NE, tmp, const0_rtx);
4520 : : }
4521 : :
4522 : 30555 : emit_insn (gen_rtx_SET (operands[0],
4523 : : gen_rtx_IF_THEN_ELSE (mode, compare_op,
4524 : : operands[2], operands[3])));
4525 : :
4526 : 30555 : return true;
4527 : : }
4528 : :
4529 : : /* Helper for ix86_cmp_code_to_pcmp_immediate for int modes. */
4530 : :
4531 : : static int
4532 : 3016 : ix86_int_cmp_code_to_pcmp_immediate (enum rtx_code code)
4533 : : {
4534 : 3016 : switch (code)
4535 : : {
4536 : : case EQ:
4537 : : return 0;
4538 : 349 : case LT:
4539 : 349 : case LTU:
4540 : 349 : return 1;
4541 : 188 : case LE:
4542 : 188 : case LEU:
4543 : 188 : return 2;
4544 : 1387 : case NE:
4545 : 1387 : return 4;
4546 : 277 : case GE:
4547 : 277 : case GEU:
4548 : 277 : return 5;
4549 : 361 : case GT:
4550 : 361 : case GTU:
4551 : 361 : return 6;
4552 : 0 : default:
4553 : 0 : gcc_unreachable ();
4554 : : }
4555 : : }
4556 : :
4557 : : /* Helper for ix86_cmp_code_to_pcmp_immediate for fp modes. */
4558 : :
4559 : : static int
4560 : 1676 : ix86_fp_cmp_code_to_pcmp_immediate (enum rtx_code code)
4561 : : {
4562 : 1676 : switch (code)
4563 : : {
4564 : : case EQ:
4565 : : return 0x00;
4566 : 408 : case NE:
4567 : 408 : return 0x04;
4568 : 500 : case GT:
4569 : 500 : return 0x0e;
4570 : 45 : case LE:
4571 : 45 : return 0x02;
4572 : 52 : case GE:
4573 : 52 : return 0x0d;
4574 : 575 : case LT:
4575 : 575 : return 0x01;
4576 : 1 : case UNLE:
4577 : 1 : return 0x0a;
4578 : 1 : case UNLT:
4579 : 1 : return 0x09;
4580 : 4 : case UNGE:
4581 : 4 : return 0x05;
4582 : 1 : case UNGT:
4583 : 1 : return 0x06;
4584 : 1 : case UNEQ:
4585 : 1 : return 0x18;
4586 : 0 : case LTGT:
4587 : 0 : return 0x0c;
4588 : 1 : case ORDERED:
4589 : 1 : return 0x07;
4590 : 1 : case UNORDERED:
4591 : 1 : return 0x03;
4592 : 0 : default:
4593 : 0 : gcc_unreachable ();
4594 : : }
4595 : : }
4596 : :
4597 : : /* Return immediate value to be used in UNSPEC_PCMP
4598 : : for comparison CODE in MODE. */
4599 : :
4600 : : static int
4601 : 4692 : ix86_cmp_code_to_pcmp_immediate (enum rtx_code code, machine_mode mode)
4602 : : {
4603 : 4692 : if (FLOAT_MODE_P (mode))
4604 : 1676 : return ix86_fp_cmp_code_to_pcmp_immediate (code);
4605 : 3016 : return ix86_int_cmp_code_to_pcmp_immediate (code);
4606 : : }
4607 : :
4608 : : /* Expand AVX-512 vector comparison. */
4609 : :
4610 : : bool
4611 : 4692 : ix86_expand_mask_vec_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1)
4612 : : {
4613 : 4692 : machine_mode mask_mode = GET_MODE (dest);
4614 : 4692 : machine_mode cmp_mode = GET_MODE (cmp_op0);
4615 : 4692 : rtx imm = GEN_INT (ix86_cmp_code_to_pcmp_immediate (code, cmp_mode));
4616 : 4692 : int unspec_code;
4617 : 4692 : rtx unspec;
4618 : :
4619 : 4692 : switch (code)
4620 : : {
4621 : : case LEU:
4622 : : case GTU:
4623 : : case GEU:
4624 : : case LTU:
4625 : : unspec_code = UNSPEC_UNSIGNED_PCMP;
4626 : : break;
4627 : :
4628 : 4384 : default:
4629 : 4384 : unspec_code = UNSPEC_PCMP;
4630 : : }
4631 : :
4632 : 4692 : unspec = gen_rtx_UNSPEC (mask_mode, gen_rtvec (3, cmp_op0, cmp_op1, imm),
4633 : : unspec_code);
4634 : 4692 : emit_insn (gen_rtx_SET (dest, unspec));
4635 : :
4636 : 4692 : return true;
4637 : : }
4638 : :
4639 : : /* Expand fp vector comparison. */
4640 : :
4641 : : bool
4642 : 6629 : ix86_expand_fp_vec_cmp (rtx operands[])
4643 : : {
4644 : 6629 : enum rtx_code code = GET_CODE (operands[1]);
4645 : 6629 : rtx cmp;
4646 : :
4647 : 6629 : code = ix86_prepare_sse_fp_compare_args (operands[0], code,
4648 : : &operands[2], &operands[3]);
4649 : 6629 : if (code == UNKNOWN)
4650 : : {
4651 : 19 : rtx temp;
4652 : 19 : switch (GET_CODE (operands[1]))
4653 : : {
4654 : 2 : case LTGT:
4655 : 2 : temp = ix86_expand_sse_cmp (operands[0], ORDERED, operands[2],
4656 : : operands[3], NULL, NULL);
4657 : 2 : cmp = ix86_expand_sse_cmp (operands[0], NE, operands[2],
4658 : : operands[3], NULL, NULL);
4659 : 2 : code = AND;
4660 : 2 : break;
4661 : 17 : case UNEQ:
4662 : 17 : temp = ix86_expand_sse_cmp (operands[0], UNORDERED, operands[2],
4663 : : operands[3], NULL, NULL);
4664 : 17 : cmp = ix86_expand_sse_cmp (operands[0], EQ, operands[2],
4665 : : operands[3], NULL, NULL);
4666 : 17 : code = IOR;
4667 : 17 : break;
4668 : 0 : default:
4669 : 0 : gcc_unreachable ();
4670 : : }
4671 : 19 : cmp = expand_simple_binop (GET_MODE (cmp), code, temp, cmp, cmp, 1,
4672 : : OPTAB_DIRECT);
4673 : : }
4674 : : else
4675 : 6610 : cmp = ix86_expand_sse_cmp (operands[0], code, operands[2], operands[3],
4676 : : NULL, NULL);
4677 : :
4678 : 6629 : if (operands[0] != cmp)
4679 : 6546 : emit_move_insn (operands[0], cmp);
4680 : :
4681 : 6629 : return true;
4682 : : }
4683 : :
4684 : : static rtx
4685 : 11321 : ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
4686 : : rtx op_true, rtx op_false, bool *negate)
4687 : : {
4688 : 11321 : machine_mode data_mode = GET_MODE (dest);
4689 : 11321 : machine_mode mode = GET_MODE (cop0);
4690 : 11321 : rtx x;
4691 : :
4692 : 11321 : *negate = false;
4693 : :
4694 : : /* XOP supports all of the comparisons on all 128-bit vector int types. */
4695 : 11321 : if (TARGET_XOP
4696 : 161 : && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
4697 : 11482 : && GET_MODE_SIZE (mode) <= 16)
4698 : : ;
4699 : : /* AVX512F supports all of the comparsions
4700 : : on all 128/256/512-bit vector int types. */
4701 : 11163 : else if (ix86_use_mask_cmp_p (data_mode, mode, op_true, op_false))
4702 : : ;
4703 : : else
4704 : : {
4705 : : /* Canonicalize the comparison to EQ, GT, GTU. */
4706 : 11110 : switch (code)
4707 : : {
4708 : : case EQ:
4709 : : case GT:
4710 : : case GTU:
4711 : : break;
4712 : :
4713 : 572 : case LE:
4714 : 572 : case LEU:
4715 : : /* x <= cst can be handled as x < cst + 1 unless there is
4716 : : wrap around in cst + 1. */
4717 : 572 : if (GET_CODE (cop1) == CONST_VECTOR
4718 : 962 : && GET_MODE_INNER (mode) != TImode)
4719 : : {
4720 : 390 : unsigned int n_elts = GET_MODE_NUNITS (mode), i;
4721 : 390 : machine_mode eltmode = GET_MODE_INNER (mode);
4722 : 2487 : for (i = 0; i < n_elts; ++i)
4723 : : {
4724 : 2098 : rtx elt = CONST_VECTOR_ELT (cop1, i);
4725 : 2098 : if (!CONST_INT_P (elt))
4726 : : break;
4727 : 2098 : if (code == LE)
4728 : : {
4729 : : /* For LE punt if some element is signed maximum. */
4730 : 1322 : if ((INTVAL (elt) & (GET_MODE_MASK (eltmode) >> 1))
4731 : : == (GET_MODE_MASK (eltmode) >> 1))
4732 : : break;
4733 : : }
4734 : : /* For LEU punt if some element is unsigned maximum. */
4735 : 776 : else if (elt == constm1_rtx)
4736 : : break;
4737 : : }
4738 : 390 : if (i == n_elts)
4739 : : {
4740 : 389 : rtvec v = rtvec_alloc (n_elts);
4741 : 2874 : for (i = 0; i < n_elts; ++i)
4742 : 2096 : RTVEC_ELT (v, i)
4743 : 2096 : = gen_int_mode (INTVAL (CONST_VECTOR_ELT (cop1, i)) + 1,
4744 : : eltmode);
4745 : 389 : cop1 = gen_rtx_CONST_VECTOR (mode, v);
4746 : 389 : std::swap (cop0, cop1);
4747 : 389 : code = code == LE ? GT : GTU;
4748 : : break;
4749 : : }
4750 : : }
4751 : : /* FALLTHRU */
4752 : 2869 : case NE:
4753 : 2869 : code = reverse_condition (code);
4754 : 2869 : *negate = true;
4755 : 2869 : break;
4756 : :
4757 : 373 : case GE:
4758 : 373 : case GEU:
4759 : : /* x >= cst can be handled as x > cst - 1 unless there is
4760 : : wrap around in cst - 1. */
4761 : 373 : if (GET_CODE (cop1) == CONST_VECTOR
4762 : 538 : && GET_MODE_INNER (mode) != TImode)
4763 : : {
4764 : 165 : unsigned int n_elts = GET_MODE_NUNITS (mode), i;
4765 : 165 : machine_mode eltmode = GET_MODE_INNER (mode);
4766 : 1067 : for (i = 0; i < n_elts; ++i)
4767 : : {
4768 : 950 : rtx elt = CONST_VECTOR_ELT (cop1, i);
4769 : 950 : if (!CONST_INT_P (elt))
4770 : : break;
4771 : 950 : if (code == GE)
4772 : : {
4773 : : /* For GE punt if some element is signed minimum. */
4774 : 902 : if (INTVAL (elt) < 0
4775 : 136 : && ((INTVAL (elt) & (GET_MODE_MASK (eltmode) >> 1))
4776 : : == 0))
4777 : : break;
4778 : : }
4779 : : /* For GEU punt if some element is zero. */
4780 : 48 : else if (elt == const0_rtx)
4781 : : break;
4782 : : }
4783 : 165 : if (i == n_elts)
4784 : : {
4785 : 117 : rtvec v = rtvec_alloc (n_elts);
4786 : 1136 : for (i = 0; i < n_elts; ++i)
4787 : 902 : RTVEC_ELT (v, i)
4788 : 902 : = gen_int_mode (INTVAL (CONST_VECTOR_ELT (cop1, i)) - 1,
4789 : : eltmode);
4790 : 117 : cop1 = gen_rtx_CONST_VECTOR (mode, v);
4791 : 117 : code = code == GE ? GT : GTU;
4792 : : break;
4793 : : }
4794 : : }
4795 : 256 : code = reverse_condition (code);
4796 : 256 : *negate = true;
4797 : : /* FALLTHRU */
4798 : :
4799 : 1180 : case LT:
4800 : 1180 : case LTU:
4801 : 1180 : std::swap (cop0, cop1);
4802 : 1180 : code = swap_condition (code);
4803 : 1180 : break;
4804 : :
4805 : 0 : default:
4806 : 0 : gcc_unreachable ();
4807 : : }
4808 : :
4809 : : /* Only SSE4.1/SSE4.2 supports V2DImode. */
4810 : 11110 : if (mode == V2DImode)
4811 : : {
4812 : 668 : switch (code)
4813 : : {
4814 : 467 : case EQ:
4815 : : /* SSE4.1 supports EQ. */
4816 : 467 : if (!TARGET_SSE4_1)
4817 : 0 : return NULL;
4818 : : break;
4819 : :
4820 : 201 : case GT:
4821 : 201 : case GTU:
4822 : : /* SSE4.2 supports GT/GTU. */
4823 : 201 : if (!TARGET_SSE4_2)
4824 : : return NULL;
4825 : : break;
4826 : :
4827 : 0 : default:
4828 : 0 : gcc_unreachable ();
4829 : : }
4830 : : }
4831 : :
4832 : 11110 : if (GET_CODE (cop0) == CONST_VECTOR)
4833 : 879 : cop0 = force_reg (mode, cop0);
4834 : 10231 : else if (GET_CODE (cop1) == CONST_VECTOR)
4835 : 5812 : cop1 = force_reg (mode, cop1);
4836 : :
4837 : 11110 : rtx optrue = op_true ? op_true : CONSTM1_RTX (data_mode);
4838 : 11110 : rtx opfalse = op_false ? op_false : CONST0_RTX (data_mode);
4839 : 11110 : if (*negate)
4840 : 3125 : std::swap (optrue, opfalse);
4841 : :
4842 : : /* Transform x > y ? 0 : -1 (i.e. x <= y ? -1 : 0 or x <= y) when
4843 : : not using integer masks into min (x, y) == x ? -1 : 0 (i.e.
4844 : : min (x, y) == x). While we add one instruction (the minimum),
4845 : : we remove the need for two instructions in the negation, as the
4846 : : result is done this way.
4847 : : When using masks, do it for SI/DImode element types, as it is shorter
4848 : : than the two subtractions. */
4849 : 11110 : if ((code != EQ
4850 : 3668 : && GET_MODE_SIZE (mode) != 64
4851 : 3668 : && vector_all_ones_operand (opfalse, data_mode)
4852 : 439 : && optrue == CONST0_RTX (data_mode))
4853 : 14339 : || (code == GTU
4854 : 1576 : && GET_MODE_SIZE (GET_MODE_INNER (mode)) >= 4
4855 : : /* Don't do it if not using integer masks and we'd end up with
4856 : : the right values in the registers though. */
4857 : 476 : && ((GET_MODE_SIZE (mode) == 64 && TARGET_EVEX512)
4858 : 476 : || !vector_all_ones_operand (optrue, data_mode)
4859 : 367 : || opfalse != CONST0_RTX (data_mode))))
4860 : : {
4861 : 548 : rtx (*gen) (rtx, rtx, rtx) = NULL;
4862 : :
4863 : 548 : switch (mode)
4864 : : {
4865 : 0 : case E_V16SImode:
4866 : 0 : gen = (code == GTU) ? gen_uminv16si3 : gen_sminv16si3;
4867 : : break;
4868 : 0 : case E_V8DImode:
4869 : 0 : gen = (code == GTU) ? gen_uminv8di3 : gen_sminv8di3;
4870 : 0 : cop0 = force_reg (mode, cop0);
4871 : 0 : cop1 = force_reg (mode, cop1);
4872 : 0 : break;
4873 : 16 : case E_V32QImode:
4874 : 16 : if (TARGET_AVX2)
4875 : 16 : gen = (code == GTU) ? gen_uminv32qi3 : gen_sminv32qi3;
4876 : : break;
4877 : 16 : case E_V16HImode:
4878 : 16 : if (TARGET_AVX2)
4879 : 16 : gen = (code == GTU) ? gen_uminv16hi3 : gen_sminv16hi3;
4880 : : break;
4881 : 20 : case E_V8SImode:
4882 : 20 : if (TARGET_AVX2)
4883 : 20 : gen = (code == GTU) ? gen_uminv8si3 : gen_sminv8si3;
4884 : : break;
4885 : 20 : case E_V4DImode:
4886 : 20 : if (TARGET_AVX512VL)
4887 : : {
4888 : 0 : gen = (code == GTU) ? gen_uminv4di3 : gen_sminv4di3;
4889 : 0 : cop0 = force_reg (mode, cop0);
4890 : 0 : cop1 = force_reg (mode, cop1);
4891 : : }
4892 : : break;
4893 : 55 : case E_V16QImode:
4894 : 55 : if (code == GTU && TARGET_SSE2)
4895 : : gen = gen_uminv16qi3;
4896 : 18 : else if (code == GT && TARGET_SSE4_1)
4897 : : gen = gen_sminv16qi3;
4898 : : break;
4899 : 40 : case E_V8QImode:
4900 : 40 : if (code == GTU && TARGET_SSE2)
4901 : : gen = gen_uminv8qi3;
4902 : 38 : else if (code == GT && TARGET_SSE4_1)
4903 : : gen = gen_sminv8qi3;
4904 : : break;
4905 : 13 : case E_V4QImode:
4906 : 13 : if (code == GTU && TARGET_SSE2)
4907 : : gen = gen_uminv4qi3;
4908 : 2 : else if (code == GT && TARGET_SSE4_1)
4909 : : gen = gen_sminv4qi3;
4910 : : break;
4911 : 8 : case E_V2QImode:
4912 : 8 : if (code == GTU && TARGET_SSE2)
4913 : : gen = gen_uminv2qi3;
4914 : 6 : else if (code == GT && TARGET_SSE4_1)
4915 : : gen = gen_sminv2qi3;
4916 : : break;
4917 : 61 : case E_V8HImode:
4918 : 61 : if (code == GTU && TARGET_SSE4_1)
4919 : : gen = gen_uminv8hi3;
4920 : 53 : else if (code == GT && TARGET_SSE2)
4921 : : gen = gen_sminv8hi3;
4922 : : break;
4923 : 4 : case E_V4HImode:
4924 : 4 : if (code == GTU && TARGET_SSE4_1)
4925 : : gen = gen_uminv4hi3;
4926 : 4 : else if (code == GT && TARGET_SSE2)
4927 : : gen = gen_sminv4hi3;
4928 : : break;
4929 : 13 : case E_V2HImode:
4930 : 13 : if (code == GTU && TARGET_SSE4_1)
4931 : : gen = gen_uminv2hi3;
4932 : 13 : else if (code == GT && TARGET_SSE2)
4933 : : gen = gen_sminv2hi3;
4934 : : break;
4935 : 185 : case E_V4SImode:
4936 : 185 : if (TARGET_SSE4_1)
4937 : 31 : gen = (code == GTU) ? gen_uminv4si3 : gen_sminv4si3;
4938 : : break;
4939 : 69 : case E_V2SImode:
4940 : 69 : if (TARGET_SSE4_1)
4941 : 0 : gen = (code == GTU) ? gen_uminv2si3 : gen_sminv2si3;
4942 : : break;
4943 : 28 : case E_V2DImode:
4944 : 28 : if (TARGET_AVX512VL)
4945 : : {
4946 : 0 : gen = (code == GTU) ? gen_uminv2di3 : gen_sminv2di3;
4947 : 0 : cop0 = force_reg (mode, cop0);
4948 : 0 : cop1 = force_reg (mode, cop1);
4949 : : }
4950 : : break;
4951 : : default:
4952 : : break;
4953 : : }
4954 : :
4955 : 0 : if (gen)
4956 : : {
4957 : 222 : rtx tem = gen_reg_rtx (mode);
4958 : 222 : if (!vector_operand (cop0, mode))
4959 : 0 : cop0 = force_reg (mode, cop0);
4960 : 222 : if (!vector_operand (cop1, mode))
4961 : 0 : cop1 = force_reg (mode, cop1);
4962 : 222 : *negate = !*negate;
4963 : 222 : emit_insn (gen (tem, cop0, cop1));
4964 : 222 : cop1 = tem;
4965 : 222 : code = EQ;
4966 : : }
4967 : : }
4968 : :
4969 : : /* Unsigned parallel compare is not supported by the hardware.
4970 : : Play some tricks to turn this into a signed comparison
4971 : : against 0. */
4972 : 11110 : if (code == GTU)
4973 : : {
4974 : 870 : cop0 = force_reg (mode, cop0);
4975 : :
4976 : 870 : switch (mode)
4977 : : {
4978 : 527 : case E_V16SImode:
4979 : 527 : case E_V8DImode:
4980 : 527 : case E_V8SImode:
4981 : 527 : case E_V4DImode:
4982 : 527 : case E_V4SImode:
4983 : 527 : case E_V2SImode:
4984 : 527 : case E_V2DImode:
4985 : 527 : {
4986 : 527 : rtx t1, t2, mask;
4987 : :
4988 : : /* Subtract (-(INT MAX) - 1) from both operands to make
4989 : : them signed. */
4990 : 527 : mask = ix86_build_signbit_mask (mode, true, false);
4991 : 527 : t1 = gen_reg_rtx (mode);
4992 : 527 : emit_insn (gen_sub3_insn (t1, cop0, mask));
4993 : :
4994 : 527 : t2 = gen_reg_rtx (mode);
4995 : 527 : emit_insn (gen_sub3_insn (t2, cop1, mask));
4996 : :
4997 : 527 : cop0 = t1;
4998 : 527 : cop1 = t2;
4999 : 527 : code = GT;
5000 : : }
5001 : 527 : break;
5002 : :
5003 : 343 : case E_V64QImode:
5004 : 343 : case E_V32HImode:
5005 : 343 : case E_V32QImode:
5006 : 343 : case E_V16HImode:
5007 : 343 : case E_V16QImode:
5008 : 343 : case E_V8QImode:
5009 : 343 : case E_V4QImode:
5010 : 343 : case E_V2QImode:
5011 : 343 : case E_V8HImode:
5012 : 343 : case E_V4HImode:
5013 : 343 : case E_V2HImode:
5014 : : /* Perform a parallel unsigned saturating subtraction. */
5015 : 343 : x = gen_reg_rtx (mode);
5016 : 343 : emit_insn (gen_rtx_SET
5017 : : (x, gen_rtx_US_MINUS (mode, cop0, cop1)));
5018 : 343 : cop0 = x;
5019 : 343 : cop1 = CONST0_RTX (mode);
5020 : 343 : code = EQ;
5021 : 343 : *negate = !*negate;
5022 : 343 : break;
5023 : :
5024 : 0 : default:
5025 : 0 : gcc_unreachable ();
5026 : : }
5027 : : }
5028 : : }
5029 : :
5030 : 11321 : if (*negate)
5031 : 3184 : std::swap (op_true, op_false);
5032 : :
5033 : 11321 : if (GET_CODE (cop1) == CONST_VECTOR)
5034 : 388 : cop1 = force_reg (mode, cop1);
5035 : :
5036 : : /* Allow the comparison to be done in one mode, but the movcc to
5037 : : happen in another mode. */
5038 : 11321 : if (data_mode == mode)
5039 : 11279 : x = ix86_expand_sse_cmp (dest, code, cop0, cop1, op_true, op_false);
5040 : : else
5041 : : {
5042 : 126 : gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode));
5043 : 42 : x = ix86_expand_sse_cmp (gen_reg_rtx (mode), code, cop0, cop1,
5044 : : op_true, op_false);
5045 : 42 : if (GET_MODE (x) == mode)
5046 : 24 : x = gen_lowpart (data_mode, x);
5047 : : }
5048 : :
5049 : : return x;
5050 : : }
5051 : :
5052 : : /* Expand integer vector comparison. */
5053 : :
5054 : : bool
5055 : 7097 : ix86_expand_int_vec_cmp (rtx operands[])
5056 : : {
5057 : 7097 : rtx_code code = GET_CODE (operands[1]);
5058 : 7097 : bool negate = false;
5059 : 7097 : rtx cmp = ix86_expand_int_sse_cmp (operands[0], code, operands[2],
5060 : : operands[3], NULL, NULL, &negate);
5061 : :
5062 : 7097 : if (!cmp)
5063 : : return false;
5064 : :
5065 : 7097 : if (negate)
5066 : 3088 : cmp = ix86_expand_int_sse_cmp (operands[0], EQ, cmp,
5067 : 3088 : CONST0_RTX (GET_MODE (cmp)),
5068 : : NULL, NULL, &negate);
5069 : :
5070 : 7097 : gcc_assert (!negate);
5071 : :
5072 : 7097 : if (operands[0] != cmp)
5073 : 6804 : emit_move_insn (operands[0], cmp);
5074 : :
5075 : : return true;
5076 : : }
5077 : :
5078 : : /* Expand a floating-point vector conditional move; a vcond operation
5079 : : rather than a movcc operation. */
5080 : :
5081 : : bool
5082 : 0 : ix86_expand_fp_vcond (rtx operands[])
5083 : : {
5084 : 0 : enum rtx_code code = GET_CODE (operands[3]);
5085 : 0 : rtx cmp;
5086 : :
5087 : 0 : code = ix86_prepare_sse_fp_compare_args (operands[0], code,
5088 : : &operands[4], &operands[5]);
5089 : 0 : if (code == UNKNOWN)
5090 : : {
5091 : 0 : rtx temp;
5092 : 0 : switch (GET_CODE (operands[3]))
5093 : : {
5094 : 0 : case LTGT:
5095 : 0 : temp = ix86_expand_sse_cmp (operands[0], ORDERED, operands[4],
5096 : : operands[5], operands[0], operands[0]);
5097 : 0 : cmp = ix86_expand_sse_cmp (operands[0], NE, operands[4],
5098 : : operands[5], operands[1], operands[2]);
5099 : 0 : code = AND;
5100 : 0 : break;
5101 : 0 : case UNEQ:
5102 : 0 : temp = ix86_expand_sse_cmp (operands[0], UNORDERED, operands[4],
5103 : : operands[5], operands[0], operands[0]);
5104 : 0 : cmp = ix86_expand_sse_cmp (operands[0], EQ, operands[4],
5105 : : operands[5], operands[1], operands[2]);
5106 : 0 : code = IOR;
5107 : 0 : break;
5108 : 0 : default:
5109 : 0 : gcc_unreachable ();
5110 : : }
5111 : 0 : cmp = expand_simple_binop (GET_MODE (cmp), code, temp, cmp, cmp, 1,
5112 : : OPTAB_DIRECT);
5113 : 0 : ix86_expand_sse_movcc (operands[0], cmp, operands[1], operands[2]);
5114 : 0 : return true;
5115 : : }
5116 : :
5117 : 0 : if (ix86_expand_sse_fp_minmax (operands[0], code, operands[4],
5118 : : operands[5], operands[1], operands[2]))
5119 : : return true;
5120 : :
5121 : 0 : cmp = ix86_expand_sse_cmp (operands[0], code, operands[4], operands[5],
5122 : : operands[1], operands[2]);
5123 : 0 : ix86_expand_sse_movcc (operands[0], cmp, operands[1], operands[2]);
5124 : 0 : return true;
5125 : : }
5126 : :
5127 : : /* Expand a signed/unsigned integral vector conditional move. */
5128 : :
5129 : : bool
5130 : 1136 : ix86_expand_int_vcond (rtx operands[])
5131 : : {
5132 : 1136 : machine_mode data_mode = GET_MODE (operands[0]);
5133 : 1136 : machine_mode mode = GET_MODE (operands[4]);
5134 : 1136 : enum rtx_code code = GET_CODE (operands[3]);
5135 : 1136 : bool negate = false;
5136 : 1136 : rtx x, cop0, cop1;
5137 : :
5138 : 1136 : cop0 = operands[4];
5139 : 1136 : cop1 = operands[5];
5140 : :
5141 : : /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
5142 : : and x < 0 ? 1 : 0 into (unsigned) x >> 31. */
5143 : 1136 : if ((code == LT || code == GE)
5144 : 0 : && data_mode == mode
5145 : 0 : && cop1 == CONST0_RTX (mode)
5146 : 0 : && operands[1 + (code == LT)] == CONST0_RTX (data_mode)
5147 : 0 : && GET_MODE_UNIT_SIZE (data_mode) > 1
5148 : 0 : && GET_MODE_UNIT_SIZE (data_mode) <= 8
5149 : 1136 : && (GET_MODE_SIZE (data_mode) == 16
5150 : 0 : || (TARGET_AVX2 && GET_MODE_SIZE (data_mode) == 32)))
5151 : : {
5152 : 0 : rtx negop = operands[2 - (code == LT)];
5153 : 0 : int shift = GET_MODE_UNIT_BITSIZE (data_mode) - 1;
5154 : 0 : if (negop == CONST1_RTX (data_mode))
5155 : : {
5156 : 0 : rtx res = expand_simple_binop (mode, LSHIFTRT, cop0, GEN_INT (shift),
5157 : : operands[0], 1, OPTAB_DIRECT);
5158 : 0 : if (res != operands[0])
5159 : 0 : emit_move_insn (operands[0], res);
5160 : 0 : return true;
5161 : : }
5162 : 0 : else if (GET_MODE_INNER (data_mode) != DImode
5163 : 0 : && vector_all_ones_operand (negop, data_mode))
5164 : : {
5165 : 0 : rtx res = expand_simple_binop (mode, ASHIFTRT, cop0, GEN_INT (shift),
5166 : : operands[0], 0, OPTAB_DIRECT);
5167 : 0 : if (res != operands[0])
5168 : 0 : emit_move_insn (operands[0], res);
5169 : 0 : return true;
5170 : : }
5171 : : }
5172 : :
5173 : 1136 : if (!nonimmediate_operand (cop1, mode))
5174 : 125 : cop1 = force_reg (mode, cop1);
5175 : 1136 : if (!general_operand (operands[1], data_mode))
5176 : 0 : operands[1] = force_reg (data_mode, operands[1]);
5177 : 1136 : if (!general_operand (operands[2], data_mode))
5178 : 0 : operands[2] = force_reg (data_mode, operands[2]);
5179 : :
5180 : 1136 : x = ix86_expand_int_sse_cmp (operands[0], code, cop0, cop1,
5181 : : operands[1], operands[2], &negate);
5182 : :
5183 : 1136 : if (!x)
5184 : : return false;
5185 : :
5186 : 1136 : ix86_expand_sse_movcc (operands[0], x, operands[1+negate],
5187 : 1136 : operands[2-negate]);
5188 : 1136 : return true;
5189 : : }
5190 : :
5191 : : static bool
5192 : 136346 : ix86_expand_vec_perm_vpermt2 (rtx target, rtx mask, rtx op0, rtx op1,
5193 : : struct expand_vec_perm_d *d)
5194 : : {
5195 : : /* ix86_expand_vec_perm_vpermt2 is called from both const and non-const
5196 : : expander, so args are either in d, or in op0, op1 etc. */
5197 : 136346 : machine_mode mode = GET_MODE (d ? d->op0 : op0);
5198 : 136346 : machine_mode maskmode = mode;
5199 : 136346 : rtx (*gen) (rtx, rtx, rtx, rtx) = NULL;
5200 : :
5201 : 136346 : switch (mode)
5202 : : {
5203 : 20905 : case E_V16QImode:
5204 : 20905 : if (TARGET_AVX512VL && TARGET_AVX512VBMI)
5205 : : gen = gen_avx512vl_vpermt2varv16qi3;
5206 : : break;
5207 : 811 : case E_V32QImode:
5208 : 811 : if (TARGET_AVX512VL && TARGET_AVX512VBMI)
5209 : : gen = gen_avx512vl_vpermt2varv32qi3;
5210 : : break;
5211 : 183 : case E_V64QImode:
5212 : 183 : if (TARGET_AVX512VBMI)
5213 : : gen = gen_avx512bw_vpermt2varv64qi3;
5214 : : break;
5215 : 15286 : case E_V8HImode:
5216 : 15286 : if (TARGET_AVX512VL && TARGET_AVX512BW)
5217 : : gen = gen_avx512vl_vpermt2varv8hi3;
5218 : : break;
5219 : 768 : case E_V16HImode:
5220 : 768 : if (TARGET_AVX512VL && TARGET_AVX512BW)
5221 : : gen = gen_avx512vl_vpermt2varv16hi3;
5222 : : break;
5223 : 373 : case E_V32HImode:
5224 : 373 : if (TARGET_AVX512BW)
5225 : : gen = gen_avx512bw_vpermt2varv32hi3;
5226 : : break;
5227 : 44364 : case E_V4SImode:
5228 : 44364 : if (TARGET_AVX512VL)
5229 : : gen = gen_avx512vl_vpermt2varv4si3;
5230 : : break;
5231 : 1195 : case E_V8SImode:
5232 : 1195 : if (TARGET_AVX512VL)
5233 : : gen = gen_avx512vl_vpermt2varv8si3;
5234 : : break;
5235 : 118 : case E_V16SImode:
5236 : 118 : if (TARGET_AVX512F)
5237 : : gen = gen_avx512f_vpermt2varv16si3;
5238 : : break;
5239 : 9133 : case E_V4SFmode:
5240 : 9133 : if (TARGET_AVX512VL)
5241 : : {
5242 : : gen = gen_avx512vl_vpermt2varv4sf3;
5243 : : maskmode = V4SImode;
5244 : : }
5245 : : break;
5246 : 11217 : case E_V8SFmode:
5247 : 11217 : if (TARGET_AVX512VL)
5248 : : {
5249 : : gen = gen_avx512vl_vpermt2varv8sf3;
5250 : : maskmode = V8SImode;
5251 : : }
5252 : : break;
5253 : 255 : case E_V16SFmode:
5254 : 255 : if (TARGET_AVX512F)
5255 : : {
5256 : : gen = gen_avx512f_vpermt2varv16sf3;
5257 : : maskmode = V16SImode;
5258 : : }
5259 : : break;
5260 : 0 : case E_V2DImode:
5261 : 0 : if (TARGET_AVX512VL)
5262 : : gen = gen_avx512vl_vpermt2varv2di3;
5263 : : break;
5264 : 396 : case E_V4DImode:
5265 : 396 : if (TARGET_AVX512VL)
5266 : : gen = gen_avx512vl_vpermt2varv4di3;
5267 : : break;
5268 : 42 : case E_V8DImode:
5269 : 42 : if (TARGET_AVX512F)
5270 : : gen = gen_avx512f_vpermt2varv8di3;
5271 : : break;
5272 : 0 : case E_V2DFmode:
5273 : 0 : if (TARGET_AVX512VL)
5274 : : {
5275 : : gen = gen_avx512vl_vpermt2varv2df3;
5276 : : maskmode = V2DImode;
5277 : : }
5278 : : break;
5279 : 3544 : case E_V4DFmode:
5280 : 3544 : if (TARGET_AVX512VL)
5281 : : {
5282 : : gen = gen_avx512vl_vpermt2varv4df3;
5283 : : maskmode = V4DImode;
5284 : : }
5285 : : break;
5286 : 254 : case E_V8DFmode:
5287 : 254 : if (TARGET_AVX512F)
5288 : : {
5289 : : gen = gen_avx512f_vpermt2varv8df3;
5290 : : maskmode = V8DImode;
5291 : : }
5292 : : break;
5293 : : default:
5294 : : break;
5295 : : }
5296 : :
5297 : : if (gen == NULL)
5298 : : return false;
5299 : :
5300 : 1051 : if (d && d->testing_p)
5301 : : return true;
5302 : :
5303 : : /* ix86_expand_vec_perm_vpermt2 is called from both const and non-const
5304 : : expander, so args are either in d, or in op0, op1 etc. */
5305 : 1040 : if (d)
5306 : : {
5307 : 1040 : rtx vec[64];
5308 : 1040 : target = d->target;
5309 : 1040 : op0 = d->op0;
5310 : 1040 : op1 = d->op1;
5311 : 17604 : for (int i = 0; i < d->nelt; ++i)
5312 : 16564 : vec[i] = GEN_INT (d->perm[i]);
5313 : 1040 : mask = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (d->nelt, vec));
5314 : : }
5315 : :
5316 : 1048 : emit_insn (gen (target, force_reg (maskmode, mask), op0, op1));
5317 : 1048 : return true;
5318 : : }
5319 : :
5320 : : /* Expand a variable vector permutation. */
5321 : :
5322 : : void
5323 : 10 : ix86_expand_vec_perm (rtx operands[])
5324 : : {
5325 : 10 : rtx target = operands[0];
5326 : 10 : rtx op0 = operands[1];
5327 : 10 : rtx op1 = operands[2];
5328 : 10 : rtx mask = operands[3];
5329 : 10 : rtx t1, t2, t3, t4, t5, t6, t7, t8, vt, vt2, vec[32];
5330 : 10 : machine_mode mode = GET_MODE (op0);
5331 : 10 : machine_mode maskmode = GET_MODE (mask);
5332 : 10 : int w, e, i;
5333 : 10 : bool one_operand_shuffle = rtx_equal_p (op0, op1);
5334 : :
5335 : : /* Number of elements in the vector. */
5336 : 10 : w = GET_MODE_NUNITS (mode);
5337 : 10 : e = GET_MODE_UNIT_SIZE (mode);
5338 : 10 : gcc_assert (w <= 64);
5339 : :
5340 : : /* For HF mode vector, convert it to HI using subreg. */
5341 : 20 : if (GET_MODE_INNER (mode) == HFmode)
5342 : : {
5343 : 6 : machine_mode orig_mode = mode;
5344 : 6 : mode = mode_for_vector (HImode, w).require ();
5345 : 6 : target = lowpart_subreg (mode, target, orig_mode);
5346 : 6 : op0 = lowpart_subreg (mode, op0, orig_mode);
5347 : 6 : op1 = lowpart_subreg (mode, op1, orig_mode);
5348 : : }
5349 : :
5350 : 10 : if (TARGET_AVX512F && one_operand_shuffle)
5351 : : {
5352 : 5 : rtx (*gen) (rtx, rtx, rtx) = NULL;
5353 : 5 : switch (mode)
5354 : : {
5355 : : case E_V16SImode:
5356 : : gen =gen_avx512f_permvarv16si;
5357 : : break;
5358 : 0 : case E_V16SFmode:
5359 : 0 : gen = gen_avx512f_permvarv16sf;
5360 : 0 : break;
5361 : 0 : case E_V8DImode:
5362 : 0 : gen = gen_avx512f_permvarv8di;
5363 : 0 : break;
5364 : 0 : case E_V8DFmode:
5365 : 0 : gen = gen_avx512f_permvarv8df;
5366 : 0 : break;
5367 : : default:
5368 : : break;
5369 : : }
5370 : 0 : if (gen != NULL)
5371 : : {
5372 : 0 : emit_insn (gen (target, op0, mask));
5373 : 8 : return;
5374 : : }
5375 : : }
5376 : :
5377 : 10 : if (ix86_expand_vec_perm_vpermt2 (target, mask, op0, op1, NULL))
5378 : : return;
5379 : :
5380 : 2 : if (TARGET_AVX2)
5381 : : {
5382 : 1 : if (mode == V4DImode || mode == V4DFmode || mode == V16HImode)
5383 : : {
5384 : : /* Unfortunately, the VPERMQ and VPERMPD instructions only support
5385 : : an constant shuffle operand. With a tiny bit of effort we can
5386 : : use VPERMD instead. A re-interpretation stall for V4DFmode is
5387 : : unfortunate but there's no avoiding it.
5388 : : Similarly for V16HImode we don't have instructions for variable
5389 : : shuffling, while for V32QImode we can use after preparing suitable
5390 : : masks vpshufb; vpshufb; vpermq; vpor. */
5391 : :
5392 : 0 : if (mode == V16HImode)
5393 : : {
5394 : 0 : maskmode = mode = V32QImode;
5395 : 0 : w = 32;
5396 : 0 : e = 1;
5397 : : }
5398 : : else
5399 : : {
5400 : 0 : maskmode = mode = V8SImode;
5401 : 0 : w = 8;
5402 : 0 : e = 4;
5403 : : }
5404 : 0 : t1 = gen_reg_rtx (maskmode);
5405 : :
5406 : : /* Replicate the low bits of the V4DImode mask into V8SImode:
5407 : : mask = { A B C D }
5408 : : t1 = { A A B B C C D D }. */
5409 : 0 : for (i = 0; i < w / 2; ++i)
5410 : 0 : vec[i*2 + 1] = vec[i*2] = GEN_INT (i * 2);
5411 : 0 : vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
5412 : 0 : vt = force_reg (maskmode, vt);
5413 : 0 : mask = gen_lowpart (maskmode, mask);
5414 : 0 : if (maskmode == V8SImode)
5415 : 0 : emit_insn (gen_avx2_permvarv8si (t1, mask, vt));
5416 : : else
5417 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t1, mask, vt));
5418 : :
5419 : : /* Multiply the shuffle indicies by two. */
5420 : 0 : t1 = expand_simple_binop (maskmode, PLUS, t1, t1, t1, 1,
5421 : : OPTAB_DIRECT);
5422 : :
5423 : : /* Add one to the odd shuffle indicies:
5424 : : t1 = { A*2, A*2+1, B*2, B*2+1, ... }. */
5425 : 0 : for (i = 0; i < w / 2; ++i)
5426 : : {
5427 : 0 : vec[i * 2] = const0_rtx;
5428 : 0 : vec[i * 2 + 1] = const1_rtx;
5429 : : }
5430 : 0 : vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
5431 : 0 : vt = validize_mem (force_const_mem (maskmode, vt));
5432 : 0 : t1 = expand_simple_binop (maskmode, PLUS, t1, vt, t1, 1,
5433 : : OPTAB_DIRECT);
5434 : :
5435 : : /* Continue as if V8SImode (resp. V32QImode) was used initially. */
5436 : 0 : operands[3] = mask = t1;
5437 : 0 : target = gen_reg_rtx (mode);
5438 : 0 : op0 = gen_lowpart (mode, op0);
5439 : 0 : op1 = gen_lowpart (mode, op1);
5440 : : }
5441 : :
5442 : 1 : switch (mode)
5443 : : {
5444 : 1 : case E_V8SImode:
5445 : : /* The VPERMD and VPERMPS instructions already properly ignore
5446 : : the high bits of the shuffle elements. No need for us to
5447 : : perform an AND ourselves. */
5448 : 1 : if (one_operand_shuffle)
5449 : : {
5450 : 0 : emit_insn (gen_avx2_permvarv8si (target, op0, mask));
5451 : 0 : if (target != operands[0])
5452 : 0 : emit_move_insn (operands[0],
5453 : 0 : gen_lowpart (GET_MODE (operands[0]), target));
5454 : : }
5455 : : else
5456 : : {
5457 : 1 : t1 = gen_reg_rtx (V8SImode);
5458 : 1 : t2 = gen_reg_rtx (V8SImode);
5459 : 1 : emit_insn (gen_avx2_permvarv8si (t1, op0, mask));
5460 : 1 : emit_insn (gen_avx2_permvarv8si (t2, op1, mask));
5461 : 1 : goto merge_two;
5462 : : }
5463 : 0 : return;
5464 : :
5465 : 0 : case E_V8SFmode:
5466 : 0 : mask = gen_lowpart (V8SImode, mask);
5467 : 0 : if (one_operand_shuffle)
5468 : 0 : emit_insn (gen_avx2_permvarv8sf (target, op0, mask));
5469 : : else
5470 : : {
5471 : 0 : t1 = gen_reg_rtx (V8SFmode);
5472 : 0 : t2 = gen_reg_rtx (V8SFmode);
5473 : 0 : emit_insn (gen_avx2_permvarv8sf (t1, op0, mask));
5474 : 0 : emit_insn (gen_avx2_permvarv8sf (t2, op1, mask));
5475 : 0 : goto merge_two;
5476 : : }
5477 : 0 : return;
5478 : :
5479 : 0 : case E_V4SImode:
5480 : : /* By combining the two 128-bit input vectors into one 256-bit
5481 : : input vector, we can use VPERMD and VPERMPS for the full
5482 : : two-operand shuffle. */
5483 : 0 : t1 = gen_reg_rtx (V8SImode);
5484 : 0 : t2 = gen_reg_rtx (V8SImode);
5485 : 0 : emit_insn (gen_avx_vec_concatv8si (t1, op0, op1));
5486 : 0 : emit_insn (gen_avx_vec_concatv8si (t2, mask, mask));
5487 : 0 : emit_insn (gen_avx2_permvarv8si (t1, t1, t2));
5488 : 0 : emit_insn (gen_avx_vextractf128v8si (target, t1, const0_rtx));
5489 : 0 : return;
5490 : :
5491 : 0 : case E_V4SFmode:
5492 : 0 : t1 = gen_reg_rtx (V8SFmode);
5493 : 0 : t2 = gen_reg_rtx (V8SImode);
5494 : 0 : mask = gen_lowpart (V4SImode, mask);
5495 : 0 : emit_insn (gen_avx_vec_concatv8sf (t1, op0, op1));
5496 : 0 : emit_insn (gen_avx_vec_concatv8si (t2, mask, mask));
5497 : 0 : emit_insn (gen_avx2_permvarv8sf (t1, t1, t2));
5498 : 0 : emit_insn (gen_avx_vextractf128v8sf (target, t1, const0_rtx));
5499 : 0 : return;
5500 : :
5501 : 0 : case E_V32QImode:
5502 : 0 : t1 = gen_reg_rtx (V32QImode);
5503 : 0 : t2 = gen_reg_rtx (V32QImode);
5504 : 0 : t3 = gen_reg_rtx (V32QImode);
5505 : 0 : vt2 = GEN_INT (-128);
5506 : 0 : vt = gen_const_vec_duplicate (V32QImode, vt2);
5507 : 0 : vt = force_reg (V32QImode, vt);
5508 : 0 : for (i = 0; i < 32; i++)
5509 : 0 : vec[i] = i < 16 ? vt2 : const0_rtx;
5510 : 0 : vt2 = gen_rtx_CONST_VECTOR (V32QImode, gen_rtvec_v (32, vec));
5511 : 0 : vt2 = force_reg (V32QImode, vt2);
5512 : : /* From mask create two adjusted masks, which contain the same
5513 : : bits as mask in the low 7 bits of each vector element.
5514 : : The first mask will have the most significant bit clear
5515 : : if it requests element from the same 128-bit lane
5516 : : and MSB set if it requests element from the other 128-bit lane.
5517 : : The second mask will have the opposite values of the MSB,
5518 : : and additionally will have its 128-bit lanes swapped.
5519 : : E.g. { 07 12 1e 09 ... | 17 19 05 1f ... } mask vector will have
5520 : : t1 { 07 92 9e 09 ... | 17 19 85 1f ... } and
5521 : : t3 { 97 99 05 9f ... | 87 12 1e 89 ... } where each ...
5522 : : stands for other 12 bytes. */
5523 : : /* The bit whether element is from the same lane or the other
5524 : : lane is bit 4, so shift it up by 3 to the MSB position. */
5525 : 0 : t5 = gen_reg_rtx (V4DImode);
5526 : 0 : emit_insn (gen_ashlv4di3 (t5, gen_lowpart (V4DImode, mask),
5527 : : GEN_INT (3)));
5528 : : /* Clear MSB bits from the mask just in case it had them set. */
5529 : 0 : emit_insn (gen_avx2_andnotv32qi3 (t2, vt, mask));
5530 : : /* After this t1 will have MSB set for elements from other lane. */
5531 : 0 : emit_insn (gen_xorv32qi3 (t1, gen_lowpart (V32QImode, t5), vt2));
5532 : : /* Clear bits other than MSB. */
5533 : 0 : emit_insn (gen_andv32qi3 (t1, t1, vt));
5534 : : /* Or in the lower bits from mask into t3. */
5535 : 0 : emit_insn (gen_iorv32qi3 (t3, t1, t2));
5536 : : /* And invert MSB bits in t1, so MSB is set for elements from the same
5537 : : lane. */
5538 : 0 : emit_insn (gen_xorv32qi3 (t1, t1, vt));
5539 : : /* Swap 128-bit lanes in t3. */
5540 : 0 : t6 = gen_reg_rtx (V4DImode);
5541 : 0 : emit_insn (gen_avx2_permv4di_1 (t6, gen_lowpart (V4DImode, t3),
5542 : : const2_rtx, GEN_INT (3),
5543 : : const0_rtx, const1_rtx));
5544 : : /* And or in the lower bits from mask into t1. */
5545 : 0 : emit_insn (gen_iorv32qi3 (t1, t1, t2));
5546 : 0 : if (one_operand_shuffle)
5547 : : {
5548 : : /* Each of these shuffles will put 0s in places where
5549 : : element from the other 128-bit lane is needed, otherwise
5550 : : will shuffle in the requested value. */
5551 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t3, op0,
5552 : 0 : gen_lowpart (V32QImode, t6)));
5553 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t1, op0, t1));
5554 : : /* For t3 the 128-bit lanes are swapped again. */
5555 : 0 : t7 = gen_reg_rtx (V4DImode);
5556 : 0 : emit_insn (gen_avx2_permv4di_1 (t7, gen_lowpart (V4DImode, t3),
5557 : : const2_rtx, GEN_INT (3),
5558 : : const0_rtx, const1_rtx));
5559 : : /* And oring both together leads to the result. */
5560 : 0 : emit_insn (gen_iorv32qi3 (target, t1,
5561 : 0 : gen_lowpart (V32QImode, t7)));
5562 : 0 : if (target != operands[0])
5563 : 0 : emit_move_insn (operands[0],
5564 : 0 : gen_lowpart (GET_MODE (operands[0]), target));
5565 : 0 : return;
5566 : : }
5567 : :
5568 : 0 : t4 = gen_reg_rtx (V32QImode);
5569 : : /* Similarly to the above one_operand_shuffle code,
5570 : : just for repeated twice for each operand. merge_two:
5571 : : code will merge the two results together. */
5572 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t4, op0,
5573 : 0 : gen_lowpart (V32QImode, t6)));
5574 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t3, op1,
5575 : 0 : gen_lowpart (V32QImode, t6)));
5576 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t2, op0, t1));
5577 : 0 : emit_insn (gen_avx2_pshufbv32qi3 (t1, op1, t1));
5578 : 0 : t7 = gen_reg_rtx (V4DImode);
5579 : 0 : emit_insn (gen_avx2_permv4di_1 (t7, gen_lowpart (V4DImode, t4),
5580 : : const2_rtx, GEN_INT (3),
5581 : : const0_rtx, const1_rtx));
5582 : 0 : t8 = gen_reg_rtx (V4DImode);
5583 : 0 : emit_insn (gen_avx2_permv4di_1 (t8, gen_lowpart (V4DImode, t3),
5584 : : const2_rtx, GEN_INT (3),
5585 : : const0_rtx, const1_rtx));
5586 : 0 : emit_insn (gen_iorv32qi3 (t4, t2, gen_lowpart (V32QImode, t7)));
5587 : 0 : emit_insn (gen_iorv32qi3 (t3, t1, gen_lowpart (V32QImode, t8)));
5588 : 0 : t1 = t4;
5589 : 0 : t2 = t3;
5590 : 0 : goto merge_two;
5591 : :
5592 : 0 : default:
5593 : 0 : gcc_assert (GET_MODE_SIZE (mode) <= 16);
5594 : : break;
5595 : : }
5596 : : }
5597 : :
5598 : 1 : if (TARGET_XOP)
5599 : : {
5600 : : /* The XOP VPPERM insn supports three inputs. By ignoring the
5601 : : one_operand_shuffle special case, we avoid creating another
5602 : : set of constant vectors in memory. */
5603 : 0 : one_operand_shuffle = false;
5604 : :
5605 : : /* mask = mask & {2*w-1, ...} */
5606 : 0 : vt = GEN_INT (2*w - 1);
5607 : : }
5608 : : else
5609 : : {
5610 : : /* mask = mask & {w-1, ...} */
5611 : 1 : vt = GEN_INT (w - 1);
5612 : : }
5613 : :
5614 : 1 : vt = gen_const_vec_duplicate (maskmode, vt);
5615 : 1 : mask = expand_simple_binop (maskmode, AND, mask, vt,
5616 : : NULL_RTX, 0, OPTAB_DIRECT);
5617 : :
5618 : : /* For non-QImode operations, convert the word permutation control
5619 : : into a byte permutation control. */
5620 : 1 : if (mode != V16QImode)
5621 : : {
5622 : 1 : mask = expand_simple_binop (maskmode, ASHIFT, mask,
5623 : 1 : GEN_INT (exact_log2 (e)),
5624 : : NULL_RTX, 0, OPTAB_DIRECT);
5625 : :
5626 : : /* Convert mask to vector of chars. */
5627 : 1 : mask = force_reg (V16QImode, gen_lowpart (V16QImode, mask));
5628 : :
5629 : : /* Replicate each of the input bytes into byte positions:
5630 : : (v2di) --> {0,0,0,0,0,0,0,0, 8,8,8,8,8,8,8,8}
5631 : : (v4si) --> {0,0,0,0, 4,4,4,4, 8,8,8,8, 12,12,12,12}
5632 : : (v8hi) --> {0,0, 2,2, 4,4, 6,6, ...}. */
5633 : 18 : for (i = 0; i < 16; ++i)
5634 : 16 : vec[i] = GEN_INT (i/e * e);
5635 : 1 : vt = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, vec));
5636 : 1 : vt = validize_mem (force_const_mem (V16QImode, vt));
5637 : 1 : if (TARGET_XOP)
5638 : 0 : emit_insn (gen_xop_pperm (mask, mask, mask, vt));
5639 : : else
5640 : 1 : emit_insn (gen_ssse3_pshufbv16qi3 (mask, mask, vt));
5641 : :
5642 : : /* Convert it into the byte positions by doing
5643 : : mask = mask + {0,1,..,16/w, 0,1,..,16/w, ...} */
5644 : 17 : for (i = 0; i < 16; ++i)
5645 : 16 : vec[i] = GEN_INT (i % e);
5646 : 1 : vt = gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, vec));
5647 : 1 : vt = validize_mem (force_const_mem (V16QImode, vt));
5648 : 1 : emit_insn (gen_addv16qi3 (mask, mask, vt));
5649 : : }
5650 : :
5651 : : /* The actual shuffle operations all operate on V16QImode. */
5652 : 1 : op0 = gen_lowpart (V16QImode, op0);
5653 : 1 : op1 = gen_lowpart (V16QImode, op1);
5654 : :
5655 : 1 : if (TARGET_XOP)
5656 : : {
5657 : 0 : if (GET_MODE (target) != V16QImode)
5658 : 0 : target = gen_reg_rtx (V16QImode);
5659 : 0 : emit_insn (gen_xop_pperm (target, op0, op1, mask));
5660 : 0 : if (target != operands[0])
5661 : 0 : emit_move_insn (operands[0],
5662 : 0 : gen_lowpart (GET_MODE (operands[0]), target));
5663 : : }
5664 : 1 : else if (one_operand_shuffle)
5665 : : {
5666 : 1 : if (GET_MODE (target) != V16QImode)
5667 : 1 : target = gen_reg_rtx (V16QImode);
5668 : 1 : emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, mask));
5669 : 1 : if (target != operands[0])
5670 : 1 : emit_move_insn (operands[0],
5671 : 1 : gen_lowpart (GET_MODE (operands[0]), target));
5672 : : }
5673 : : else
5674 : : {
5675 : 0 : rtx xops[6];
5676 : 0 : bool ok;
5677 : :
5678 : : /* Shuffle the two input vectors independently. */
5679 : 0 : t1 = gen_reg_rtx (V16QImode);
5680 : 0 : t2 = gen_reg_rtx (V16QImode);
5681 : 0 : emit_insn (gen_ssse3_pshufbv16qi3 (t1, op0, mask));
5682 : 0 : emit_insn (gen_ssse3_pshufbv16qi3 (t2, op1, mask));
5683 : :
5684 : 1 : merge_two:
5685 : : /* Then merge them together. The key is whether any given control
5686 : : element contained a bit set that indicates the second word. */
5687 : 1 : mask = operands[3];
5688 : 1 : vt = GEN_INT (w);
5689 : 1 : if (maskmode == V2DImode && !TARGET_SSE4_1)
5690 : : {
5691 : : /* Without SSE4.1, we don't have V2DImode EQ. Perform one
5692 : : more shuffle to convert the V2DI input mask into a V4SI
5693 : : input mask. At which point the masking that expand_int_vcond
5694 : : will work as desired. */
5695 : 0 : rtx t3 = gen_reg_rtx (V4SImode);
5696 : 0 : emit_insn (gen_sse2_pshufd_1 (t3, gen_lowpart (V4SImode, mask),
5697 : : const0_rtx, const0_rtx,
5698 : : const2_rtx, const2_rtx));
5699 : 0 : mask = t3;
5700 : 0 : maskmode = V4SImode;
5701 : 0 : e = w = 4;
5702 : : }
5703 : :
5704 : 1 : vt = gen_const_vec_duplicate (maskmode, vt);
5705 : 1 : vt = force_reg (maskmode, vt);
5706 : 1 : mask = expand_simple_binop (maskmode, AND, mask, vt,
5707 : : NULL_RTX, 0, OPTAB_DIRECT);
5708 : :
5709 : 1 : if (GET_MODE (target) != mode)
5710 : 0 : target = gen_reg_rtx (mode);
5711 : 1 : xops[0] = target;
5712 : 1 : xops[1] = gen_lowpart (mode, t2);
5713 : 1 : xops[2] = gen_lowpart (mode, t1);
5714 : 1 : xops[3] = gen_rtx_EQ (maskmode, mask, vt);
5715 : 1 : xops[4] = mask;
5716 : 1 : xops[5] = vt;
5717 : 1 : ok = ix86_expand_int_vcond (xops);
5718 : 1 : gcc_assert (ok);
5719 : 1 : if (target != operands[0])
5720 : 0 : emit_move_insn (operands[0],
5721 : 0 : gen_lowpart (GET_MODE (operands[0]), target));
5722 : : }
5723 : : }
5724 : :
5725 : : /* Extend SRC into next wider integer vector type. UNSIGNED_P is
5726 : : true if we should do zero extension, else sign extension. */
5727 : :
5728 : : void
5729 : 609 : ix86_expand_sse_extend (rtx dest, rtx src, bool unsigned_p)
5730 : : {
5731 : 609 : machine_mode imode = GET_MODE (src);
5732 : 609 : rtx ops[3];
5733 : :
5734 : 609 : switch (imode)
5735 : : {
5736 : 609 : case E_V8QImode:
5737 : 609 : case E_V4QImode:
5738 : 609 : case E_V2QImode:
5739 : 609 : case E_V4HImode:
5740 : 609 : case E_V2HImode:
5741 : 609 : case E_V2SImode:
5742 : 609 : break;
5743 : 0 : default:
5744 : 0 : gcc_unreachable ();
5745 : : }
5746 : :
5747 : 609 : ops[0] = dest;
5748 : :
5749 : 609 : ops[1] = force_reg (imode, src);
5750 : :
5751 : 609 : if (unsigned_p)
5752 : 125 : ops[2] = force_reg (imode, CONST0_RTX (imode));
5753 : : else
5754 : 484 : ops[2] = ix86_expand_sse_cmp (gen_reg_rtx (imode), GT, CONST0_RTX (imode),
5755 : : ops[1], pc_rtx, pc_rtx);
5756 : :
5757 : 609 : ix86_split_mmx_punpck (ops, false);
5758 : 609 : }
5759 : :
5760 : : /* Unpack SRC into the next wider integer vector type. UNSIGNED_P is
5761 : : true if we should do zero extension, else sign extension. HIGH_P is
5762 : : true if we want the N/2 high elements, else the low elements. */
5763 : :
5764 : : void
5765 : 13240 : ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
5766 : : {
5767 : 13240 : machine_mode imode = GET_MODE (src);
5768 : 13240 : rtx tmp;
5769 : :
5770 : 13240 : if (TARGET_SSE4_1)
5771 : : {
5772 : 5150 : rtx (*unpack)(rtx, rtx);
5773 : 5150 : rtx (*extract)(rtx, rtx) = NULL;
5774 : 5150 : machine_mode halfmode = BLKmode;
5775 : :
5776 : 5150 : switch (imode)
5777 : : {
5778 : 48 : case E_V64QImode:
5779 : 48 : if (unsigned_p)
5780 : : unpack = gen_avx512bw_zero_extendv32qiv32hi2;
5781 : : else
5782 : 10 : unpack = gen_avx512bw_sign_extendv32qiv32hi2;
5783 : 48 : halfmode = V32QImode;
5784 : 48 : extract
5785 : 48 : = high_p ? gen_vec_extract_hi_v64qi : gen_vec_extract_lo_v64qi;
5786 : : break;
5787 : 595 : case E_V32QImode:
5788 : 595 : if (unsigned_p)
5789 : : unpack = gen_avx2_zero_extendv16qiv16hi2;
5790 : : else
5791 : 90 : unpack = gen_avx2_sign_extendv16qiv16hi2;
5792 : 595 : halfmode = V16QImode;
5793 : 595 : extract
5794 : 595 : = high_p ? gen_vec_extract_hi_v32qi : gen_vec_extract_lo_v32qi;
5795 : : break;
5796 : 28 : case E_V32HImode:
5797 : 28 : if (unsigned_p)
5798 : : unpack = gen_avx512f_zero_extendv16hiv16si2;
5799 : : else
5800 : 16 : unpack = gen_avx512f_sign_extendv16hiv16si2;
5801 : 28 : halfmode = V16HImode;
5802 : 28 : extract
5803 : 28 : = high_p ? gen_vec_extract_hi_v32hi : gen_vec_extract_lo_v32hi;
5804 : : break;
5805 : 385 : case E_V16HImode:
5806 : 385 : if (unsigned_p)
5807 : : unpack = gen_avx2_zero_extendv8hiv8si2;
5808 : : else
5809 : 300 : unpack = gen_avx2_sign_extendv8hiv8si2;
5810 : 385 : halfmode = V8HImode;
5811 : 385 : extract
5812 : 385 : = high_p ? gen_vec_extract_hi_v16hi : gen_vec_extract_lo_v16hi;
5813 : : break;
5814 : 110 : case E_V16SImode:
5815 : 110 : if (unsigned_p)
5816 : : unpack = gen_avx512f_zero_extendv8siv8di2;
5817 : : else
5818 : 106 : unpack = gen_avx512f_sign_extendv8siv8di2;
5819 : 110 : halfmode = V8SImode;
5820 : 110 : extract
5821 : 110 : = high_p ? gen_vec_extract_hi_v16si : gen_vec_extract_lo_v16si;
5822 : : break;
5823 : 348 : case E_V8SImode:
5824 : 348 : if (unsigned_p)
5825 : : unpack = gen_avx2_zero_extendv4siv4di2;
5826 : : else
5827 : 308 : unpack = gen_avx2_sign_extendv4siv4di2;
5828 : 348 : halfmode = V4SImode;
5829 : 348 : extract
5830 : 348 : = high_p ? gen_vec_extract_hi_v8si : gen_vec_extract_lo_v8si;
5831 : : break;
5832 : 1841 : case E_V16QImode:
5833 : 1841 : if (unsigned_p)
5834 : : unpack = gen_sse4_1_zero_extendv8qiv8hi2;
5835 : : else
5836 : 232 : unpack = gen_sse4_1_sign_extendv8qiv8hi2;
5837 : : break;
5838 : 1039 : case E_V8HImode:
5839 : 1039 : if (unsigned_p)
5840 : : unpack = gen_sse4_1_zero_extendv4hiv4si2;
5841 : : else
5842 : 716 : unpack = gen_sse4_1_sign_extendv4hiv4si2;
5843 : : break;
5844 : 392 : case E_V4SImode:
5845 : 392 : if (unsigned_p)
5846 : : unpack = gen_sse4_1_zero_extendv2siv2di2;
5847 : : else
5848 : 370 : unpack = gen_sse4_1_sign_extendv2siv2di2;
5849 : : break;
5850 : 102 : case E_V8QImode:
5851 : 102 : if (unsigned_p)
5852 : : unpack = gen_sse4_1_zero_extendv4qiv4hi2;
5853 : : else
5854 : 62 : unpack = gen_sse4_1_sign_extendv4qiv4hi2;
5855 : : break;
5856 : 262 : case E_V4HImode:
5857 : 262 : if (unsigned_p)
5858 : : unpack = gen_sse4_1_zero_extendv2hiv2si2;
5859 : : else
5860 : 216 : unpack = gen_sse4_1_sign_extendv2hiv2si2;
5861 : : break;
5862 : 0 : case E_V4QImode:
5863 : 0 : if (unsigned_p)
5864 : : unpack = gen_sse4_1_zero_extendv2qiv2hi2;
5865 : : else
5866 : 0 : unpack = gen_sse4_1_sign_extendv2qiv2hi2;
5867 : : break;
5868 : 0 : default:
5869 : 0 : gcc_unreachable ();
5870 : : }
5871 : :
5872 : 10300 : if (GET_MODE_SIZE (imode) >= 32)
5873 : : {
5874 : 1514 : tmp = gen_reg_rtx (halfmode);
5875 : 1514 : emit_insn (extract (tmp, src));
5876 : : }
5877 : 3636 : else if (high_p)
5878 : : {
5879 : 2150 : switch (GET_MODE_SIZE (imode))
5880 : : {
5881 : 893 : case 16:
5882 : : /* Shift higher 8 bytes to lower 8 bytes. */
5883 : 893 : tmp = gen_reg_rtx (V1TImode);
5884 : 893 : emit_insn (gen_sse2_lshrv1ti3 (tmp, gen_lowpart (V1TImode, src),
5885 : : GEN_INT (64)));
5886 : 893 : break;
5887 : 182 : case 8:
5888 : : /* Shift higher 4 bytes to lower 4 bytes. */
5889 : 182 : tmp = gen_reg_rtx (V1DImode);
5890 : 182 : emit_insn (gen_mmx_lshrv1di3 (tmp, gen_lowpart (V1DImode, src),
5891 : : GEN_INT (32)));
5892 : 182 : break;
5893 : 0 : case 4:
5894 : : /* Shift higher 2 bytes to lower 2 bytes. */
5895 : 0 : tmp = gen_reg_rtx (V1SImode);
5896 : 0 : emit_insn (gen_mmx_lshrv1si3 (tmp, gen_lowpart (V1SImode, src),
5897 : : GEN_INT (16)));
5898 : 0 : break;
5899 : 0 : default:
5900 : 0 : gcc_unreachable ();
5901 : : }
5902 : :
5903 : 1075 : tmp = gen_lowpart (imode, tmp);
5904 : : }
5905 : : else
5906 : : tmp = src;
5907 : :
5908 : 5150 : emit_insn (unpack (dest, tmp));
5909 : : }
5910 : : else
5911 : : {
5912 : 8090 : rtx (*unpack)(rtx, rtx, rtx);
5913 : :
5914 : 8090 : switch (imode)
5915 : : {
5916 : 2398 : case E_V16QImode:
5917 : 2398 : if (high_p)
5918 : : unpack = gen_vec_interleave_highv16qi;
5919 : : else
5920 : 1202 : unpack = gen_vec_interleave_lowv16qi;
5921 : : break;
5922 : 3222 : case E_V8HImode:
5923 : 3222 : if (high_p)
5924 : : unpack = gen_vec_interleave_highv8hi;
5925 : : else
5926 : 1611 : unpack = gen_vec_interleave_lowv8hi;
5927 : : break;
5928 : 1402 : case E_V4SImode:
5929 : 1402 : if (high_p)
5930 : : unpack = gen_vec_interleave_highv4si;
5931 : : else
5932 : 701 : unpack = gen_vec_interleave_lowv4si;
5933 : : break;
5934 : 360 : case E_V8QImode:
5935 : 360 : if (high_p)
5936 : : unpack = gen_mmx_punpckhbw;
5937 : : else
5938 : 180 : unpack = gen_mmx_punpcklbw;
5939 : : break;
5940 : 698 : case E_V4HImode:
5941 : 698 : if (high_p)
5942 : : unpack = gen_mmx_punpckhwd;
5943 : : else
5944 : 349 : unpack = gen_mmx_punpcklwd;
5945 : : break;
5946 : 10 : case E_V4QImode:
5947 : 10 : if (high_p)
5948 : : unpack = gen_mmx_punpckhbw_low;
5949 : : else
5950 : 5 : unpack = gen_mmx_punpcklbw_low;
5951 : : break;
5952 : 0 : default:
5953 : 0 : gcc_unreachable ();
5954 : : }
5955 : :
5956 : 8090 : if (unsigned_p)
5957 : 4312 : tmp = force_reg (imode, CONST0_RTX (imode));
5958 : : else
5959 : 3778 : tmp = ix86_expand_sse_cmp (gen_reg_rtx (imode), GT, CONST0_RTX (imode),
5960 : : src, pc_rtx, pc_rtx);
5961 : :
5962 : 8090 : rtx tmp2 = gen_reg_rtx (imode);
5963 : 8090 : emit_insn (unpack (tmp2, src, tmp));
5964 : 8090 : emit_move_insn (dest, gen_lowpart (GET_MODE (dest), tmp2));
5965 : : }
5966 : 13240 : }
5967 : :
5968 : : /* Return true if mem is pool constant which contains a const_vector
5969 : : perm index, assign the index to PERM. */
5970 : : bool
5971 : 35 : ix86_extract_perm_from_pool_constant (int* perm, rtx mem)
5972 : : {
5973 : 35 : machine_mode mode = GET_MODE (mem);
5974 : 35 : int nelt = GET_MODE_NUNITS (mode);
5975 : :
5976 : 35 : if (!INTEGRAL_MODE_P (mode))
5977 : : return false;
5978 : :
5979 : : /* Needs to be constant pool. */
5980 : 35 : if (!(MEM_P (mem))
5981 : 35 : || !SYMBOL_REF_P (XEXP (mem, 0))
5982 : 70 : || !CONSTANT_POOL_ADDRESS_P (XEXP (mem, 0)))
5983 : : return false;
5984 : :
5985 : 35 : rtx constant = get_pool_constant (XEXP (mem, 0));
5986 : :
5987 : 35 : if (GET_CODE (constant) != CONST_VECTOR)
5988 : : return false;
5989 : :
5990 : : /* There could be some rtx like
5991 : : (mem/u/c:V16QI (symbol_ref/u:DI ("*.LC1")))
5992 : : but with "*.LC1" refer to V2DI constant vector. */
5993 : 35 : if (GET_MODE (constant) != mode)
5994 : : {
5995 : 0 : constant = simplify_subreg (mode, constant, GET_MODE (constant), 0);
5996 : :
5997 : 0 : if (constant == nullptr || GET_CODE (constant) != CONST_VECTOR)
5998 : : return false;
5999 : : }
6000 : :
6001 : 771 : for (int i = 0; i != nelt; i++)
6002 : 736 : perm[i] = UINTVAL (XVECEXP (constant, 0, i));
6003 : :
6004 : : return true;
6005 : : }
6006 : :
6007 : : /* Split operands 0 and 1 into half-mode parts. Similar to split_double_mode,
6008 : : but works for floating pointer parameters and nonoffsetable memories.
6009 : : For pushes, it returns just stack offsets; the values will be saved
6010 : : in the right order. Maximally three parts are generated. */
6011 : :
6012 : : static int
6013 : 4035122 : ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode)
6014 : : {
6015 : 4035122 : int size;
6016 : :
6017 : 4035122 : if (!TARGET_64BIT)
6018 : 1537692 : size = mode==XFmode ? 3 : GET_MODE_SIZE (mode) / 4;
6019 : : else
6020 : 6531348 : size = (GET_MODE_SIZE (mode) + 4) / 8;
6021 : :
6022 : 4035122 : gcc_assert (!REG_P (operand) || !MMX_REGNO_P (REGNO (operand)));
6023 : 4035122 : gcc_assert (size >= 2 && size <= 4);
6024 : :
6025 : : /* Optimize constant pool reference to immediates. This is used by fp
6026 : : moves, that force all constants to memory to allow combining. */
6027 : 4035122 : if (MEM_P (operand) && MEM_READONLY_P (operand))
6028 : 34316 : operand = avoid_constant_pool_reference (operand);
6029 : :
6030 : 4035122 : if (MEM_P (operand) && !offsettable_memref_p (operand))
6031 : : {
6032 : : /* The only non-offsetable memories we handle are pushes. */
6033 : 185776 : int ok = push_operand (operand, VOIDmode);
6034 : :
6035 : 185776 : gcc_assert (ok);
6036 : :
6037 : 185776 : operand = copy_rtx (operand);
6038 : 185776 : PUT_MODE (operand, word_mode);
6039 : 185776 : parts[0] = parts[1] = parts[2] = parts[3] = operand;
6040 : 185776 : return size;
6041 : : }
6042 : :
6043 : 3849346 : if (GET_CODE (operand) == CONST_VECTOR)
6044 : : {
6045 : 40930 : scalar_int_mode imode = int_mode_for_mode (mode).require ();
6046 : : /* Caution: if we looked through a constant pool memory above,
6047 : : the operand may actually have a different mode now. That's
6048 : : ok, since we want to pun this all the way back to an integer. */
6049 : 40930 : operand = simplify_subreg (imode, operand, GET_MODE (operand), 0);
6050 : 40930 : gcc_assert (operand != NULL);
6051 : 40930 : mode = imode;
6052 : : }
6053 : :
6054 : 3849346 : if (!TARGET_64BIT)
6055 : : {
6056 : 608922 : if (mode == DImode)
6057 : 480607 : split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
6058 : : else
6059 : : {
6060 : 128315 : int i;
6061 : :
6062 : 128315 : if (REG_P (operand))
6063 : : {
6064 : 66286 : gcc_assert (reload_completed);
6065 : 198858 : for (i = 0; i < size; i++)
6066 : 132572 : parts[i] = gen_rtx_REG (SImode, REGNO (operand) + i);
6067 : : }
6068 : 62029 : else if (offsettable_memref_p (operand))
6069 : : {
6070 : 60664 : operand = adjust_address (operand, SImode, 0);
6071 : 60664 : parts[0] = operand;
6072 : 121805 : for (i = 1; i < size; i++)
6073 : 61141 : parts[i] = adjust_address (operand, SImode, 4 * i);
6074 : : }
6075 : 1365 : else if (CONST_DOUBLE_P (operand))
6076 : : {
6077 : 1365 : const REAL_VALUE_TYPE *r;
6078 : 1365 : long l[4];
6079 : :
6080 : 1365 : r = CONST_DOUBLE_REAL_VALUE (operand);
6081 : 1365 : switch (mode)
6082 : : {
6083 : 0 : case E_TFmode:
6084 : 0 : real_to_target (l, r, mode);
6085 : 0 : parts[3] = gen_int_mode (l[3], SImode);
6086 : 0 : parts[2] = gen_int_mode (l[2], SImode);
6087 : 0 : break;
6088 : 192 : case E_XFmode:
6089 : : /* We can't use REAL_VALUE_TO_TARGET_LONG_DOUBLE since
6090 : : long double may not be 80-bit. */
6091 : 192 : real_to_target (l, r, mode);
6092 : 192 : parts[2] = gen_int_mode (l[2], SImode);
6093 : 192 : break;
6094 : 1173 : case E_DFmode:
6095 : 1173 : REAL_VALUE_TO_TARGET_DOUBLE (*r, l);
6096 : 1173 : break;
6097 : 0 : default:
6098 : 0 : gcc_unreachable ();
6099 : : }
6100 : 1365 : parts[1] = gen_int_mode (l[1], SImode);
6101 : 1365 : parts[0] = gen_int_mode (l[0], SImode);
6102 : : }
6103 : : else
6104 : 0 : gcc_unreachable ();
6105 : : }
6106 : : }
6107 : : else
6108 : : {
6109 : 3240424 : if (mode == TImode)
6110 : 3223936 : split_double_mode (mode, &operand, 1, &parts[0], &parts[1]);
6111 : 3240424 : if (mode == XFmode || mode == TFmode)
6112 : : {
6113 : 16488 : machine_mode upper_mode = mode==XFmode ? SImode : DImode;
6114 : 16488 : if (REG_P (operand))
6115 : : {
6116 : 1513 : gcc_assert (reload_completed);
6117 : 1513 : parts[0] = gen_rtx_REG (DImode, REGNO (operand) + 0);
6118 : 1513 : parts[1] = gen_rtx_REG (upper_mode, REGNO (operand) + 1);
6119 : : }
6120 : 14975 : else if (offsettable_memref_p (operand))
6121 : : {
6122 : 11400 : operand = adjust_address (operand, DImode, 0);
6123 : 11400 : parts[0] = operand;
6124 : 11400 : parts[1] = adjust_address (operand, upper_mode, 8);
6125 : : }
6126 : 3575 : else if (CONST_DOUBLE_P (operand))
6127 : : {
6128 : 3575 : long l[4];
6129 : :
6130 : 3575 : real_to_target (l, CONST_DOUBLE_REAL_VALUE (operand), mode);
6131 : :
6132 : : /* real_to_target puts 32-bit pieces in each long. */
6133 : 7150 : parts[0] = gen_int_mode ((l[0] & HOST_WIDE_INT_C (0xffffffff))
6134 : 3575 : | ((l[1] & HOST_WIDE_INT_C (0xffffffff))
6135 : 3575 : << 32), DImode);
6136 : :
6137 : 3575 : if (upper_mode == SImode)
6138 : 2960 : parts[1] = gen_int_mode (l[2], SImode);
6139 : : else
6140 : 615 : parts[1]
6141 : 615 : = gen_int_mode ((l[2] & HOST_WIDE_INT_C (0xffffffff))
6142 : 615 : | ((l[3] & HOST_WIDE_INT_C (0xffffffff))
6143 : 615 : << 32), DImode);
6144 : : }
6145 : : else
6146 : 0 : gcc_unreachable ();
6147 : : }
6148 : : }
6149 : :
6150 : : return size;
6151 : : }
6152 : :
6153 : : /* Emit insns to perform a move or push of DI, DF, XF, and TF values.
6154 : : Return false when normal moves are needed; true when all required
6155 : : insns have been emitted. Operands 2-4 contain the input values
6156 : : int the correct order; operands 5-7 contain the output values. */
6157 : :
6158 : : void
6159 : 2030572 : ix86_split_long_move (rtx operands[])
6160 : : {
6161 : 2030572 : rtx part[2][4];
6162 : 2030572 : int nparts, i, j;
6163 : 2030572 : int push = 0;
6164 : 2030572 : int collisions = 0;
6165 : 2030572 : machine_mode mode = GET_MODE (operands[0]);
6166 : 2030572 : bool collisionparts[4];
6167 : :
6168 : : /* The DFmode expanders may ask us to move double.
6169 : : For 64bit target this is single move. By hiding the fact
6170 : : here we simplify i386.md splitters. */
6171 : 3676420 : if (TARGET_64BIT && GET_MODE_SIZE (GET_MODE (operands[0])) == 8)
6172 : : {
6173 : : /* Optimize constant pool reference to immediates. This is used by
6174 : : fp moves, that force all constants to memory to allow combining. */
6175 : :
6176 : 13011 : if (MEM_P (operands[1])
6177 : 12746 : && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6178 : 13829 : && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
6179 : 318 : operands[1] = get_pool_constant (XEXP (operands[1], 0));
6180 : 13011 : if (push_operand (operands[0], VOIDmode))
6181 : : {
6182 : 13011 : operands[0] = copy_rtx (operands[0]);
6183 : 13011 : PUT_MODE (operands[0], word_mode);
6184 : : }
6185 : : else
6186 : 0 : operands[0] = gen_lowpart (DImode, operands[0]);
6187 : 13011 : operands[1] = gen_lowpart (DImode, operands[1]);
6188 : 13011 : emit_move_insn (operands[0], operands[1]);
6189 : 13011 : return;
6190 : : }
6191 : :
6192 : : /* The only non-offsettable memory we handle is push. */
6193 : 2017561 : if (push_operand (operands[0], VOIDmode))
6194 : : push = 1;
6195 : : else
6196 : 1831785 : gcc_assert (!MEM_P (operands[0])
6197 : : || offsettable_memref_p (operands[0]));
6198 : :
6199 : 2017561 : nparts = ix86_split_to_parts (operands[1], part[1], GET_MODE (operands[0]));
6200 : 2017561 : ix86_split_to_parts (operands[0], part[0], GET_MODE (operands[0]));
6201 : :
6202 : : /* When emitting push, take care for source operands on the stack. */
6203 : 185776 : if (push && MEM_P (operands[1])
6204 : 2110718 : && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
6205 : : {
6206 : 53456 : rtx src_base = XEXP (part[1][nparts - 1], 0);
6207 : :
6208 : : /* Compensate for the stack decrement by 4. */
6209 : 53456 : if (!TARGET_64BIT && nparts == 3
6210 : 49194 : && mode == XFmode && TARGET_128BIT_LONG_DOUBLE)
6211 : 0 : src_base = plus_constant (Pmode, src_base, 4);
6212 : :
6213 : : /* src_base refers to the stack pointer and is
6214 : : automatically decreased by emitted push. */
6215 : 160656 : for (i = 0; i < nparts; i++)
6216 : 107200 : part[1][i] = change_address (part[1][i],
6217 : 107200 : GET_MODE (part[1][i]), src_base);
6218 : : }
6219 : :
6220 : : /* We need to do copy in the right order in case an address register
6221 : : of the source overlaps the destination. */
6222 : 2017561 : if (REG_P (part[0][0]) && MEM_P (part[1][0]))
6223 : : {
6224 : : rtx tmp;
6225 : :
6226 : 2309196 : for (i = 0; i < nparts; i++)
6227 : : {
6228 : 1539464 : collisionparts[i]
6229 : 1539464 : = reg_overlap_mentioned_p (part[0][i], XEXP (part[1][0], 0));
6230 : 1539464 : if (collisionparts[i])
6231 : 16142 : collisions++;
6232 : : }
6233 : :
6234 : : /* Collision in the middle part can be handled by reordering. */
6235 : 769732 : if (collisions == 1 && nparts == 3 && collisionparts [1])
6236 : : {
6237 : 0 : std::swap (part[0][1], part[0][2]);
6238 : 0 : std::swap (part[1][1], part[1][2]);
6239 : : }
6240 : 769732 : else if (collisions == 1
6241 : 769732 : && nparts == 4
6242 : 0 : && (collisionparts [1] || collisionparts [2]))
6243 : : {
6244 : 0 : if (collisionparts [1])
6245 : : {
6246 : 0 : std::swap (part[0][1], part[0][2]);
6247 : 0 : std::swap (part[1][1], part[1][2]);
6248 : : }
6249 : : else
6250 : : {
6251 : 0 : std::swap (part[0][2], part[0][3]);
6252 : 0 : std::swap (part[1][2], part[1][3]);
6253 : : }
6254 : : }
6255 : :
6256 : : /* If there are more collisions, we can't handle it by reordering.
6257 : : Do an lea to the last part and use only one colliding move. */
6258 : 769732 : else if (collisions > 1)
6259 : : {
6260 : 69 : rtx base, addr;
6261 : :
6262 : 69 : collisions = 1;
6263 : :
6264 : 69 : base = part[0][nparts - 1];
6265 : :
6266 : : /* Handle the case when the last part isn't valid for lea.
6267 : : Happens in 64-bit mode storing the 12-byte XFmode. */
6268 : 69 : if (GET_MODE (base) != Pmode)
6269 : 0 : base = gen_rtx_REG (Pmode, REGNO (base));
6270 : :
6271 : 69 : addr = XEXP (part[1][0], 0);
6272 : 69 : if (TARGET_TLS_DIRECT_SEG_REFS)
6273 : : {
6274 : 69 : struct ix86_address parts;
6275 : 69 : int ok = ix86_decompose_address (addr, &parts);
6276 : 69 : gcc_assert (ok);
6277 : : /* It is not valid to use %gs: or %fs: in lea. */
6278 : 69 : gcc_assert (parts.seg == ADDR_SPACE_GENERIC);
6279 : : }
6280 : 69 : emit_insn (gen_rtx_SET (base, addr));
6281 : 69 : part[1][0] = replace_equiv_address (part[1][0], base);
6282 : 138 : for (i = 1; i < nparts; i++)
6283 : : {
6284 : 99 : tmp = plus_constant (Pmode, base, UNITS_PER_WORD * i);
6285 : 69 : part[1][i] = replace_equiv_address (part[1][i], tmp);
6286 : : }
6287 : : }
6288 : : }
6289 : :
6290 : 2017561 : if (push)
6291 : : {
6292 : 185776 : if (!TARGET_64BIT)
6293 : : {
6294 : 160526 : if (nparts == 3)
6295 : : {
6296 : 535 : if (TARGET_128BIT_LONG_DOUBLE && mode == XFmode)
6297 : 0 : emit_insn (gen_add2_insn (stack_pointer_rtx, GEN_INT (-4)));
6298 : 535 : emit_move_insn (part[0][2], part[1][2]);
6299 : : }
6300 : 159991 : else if (nparts == 4)
6301 : : {
6302 : 0 : emit_move_insn (part[0][3], part[1][3]);
6303 : 0 : emit_move_insn (part[0][2], part[1][2]);
6304 : : }
6305 : : }
6306 : : else
6307 : : {
6308 : : /* In 64bit mode we don't have 32bit push available. In case this is
6309 : : register, it is OK - we will just use larger counterpart. We also
6310 : : retype memory - these comes from attempt to avoid REX prefix on
6311 : : moving of second half of TFmode value. */
6312 : 25250 : if (GET_MODE (part[1][1]) == SImode)
6313 : : {
6314 : 9775 : switch (GET_CODE (part[1][1]))
6315 : : {
6316 : 9337 : case MEM:
6317 : 9337 : part[1][1] = adjust_address (part[1][1], DImode, 0);
6318 : 9337 : break;
6319 : :
6320 : 438 : case REG:
6321 : 438 : part[1][1] = gen_rtx_REG (DImode, REGNO (part[1][1]));
6322 : 438 : break;
6323 : :
6324 : 0 : default:
6325 : 0 : gcc_unreachable ();
6326 : : }
6327 : :
6328 : 9775 : if (GET_MODE (part[1][0]) == SImode)
6329 : 0 : part[1][0] = part[1][1];
6330 : : }
6331 : : }
6332 : 185776 : emit_move_insn (part[0][1], part[1][1]);
6333 : 185776 : emit_move_insn (part[0][0], part[1][0]);
6334 : 185776 : return;
6335 : : }
6336 : :
6337 : : /* Choose correct order to not overwrite the source before it is copied. */
6338 : 1831785 : if ((REG_P (part[0][0])
6339 : 1009425 : && REG_P (part[1][1])
6340 : 81357 : && (REGNO (part[0][0]) == REGNO (part[1][1])
6341 : 66125 : || (nparts == 3
6342 : 0 : && REGNO (part[0][0]) == REGNO (part[1][2]))
6343 : 66125 : || (nparts == 4
6344 : 0 : && REGNO (part[0][0]) == REGNO (part[1][3]))))
6345 : 2825978 : || (collisions > 0
6346 : 16073 : && reg_overlap_mentioned_p (part[0][0], XEXP (part[1][0], 0))))
6347 : : {
6348 : 92961 : for (i = 0, j = nparts - 1; i < nparts; i++, j--)
6349 : : {
6350 : 61974 : operands[2 + i] = part[0][j];
6351 : 61974 : operands[6 + i] = part[1][j];
6352 : : }
6353 : : }
6354 : : else
6355 : : {
6356 : 5402461 : for (i = 0; i < nparts; i++)
6357 : : {
6358 : 3601663 : operands[2 + i] = part[0][i];
6359 : 3601663 : operands[6 + i] = part[1][i];
6360 : : }
6361 : : }
6362 : :
6363 : : /* Attempt to locally unCSE nonzero constants. */
6364 : 3663637 : for (j = 0; j < nparts - 1; j++)
6365 : 1831852 : if (CONST_INT_P (operands[6 + j])
6366 : 216440 : && operands[6 + j] != const0_rtx
6367 : 57277 : && REG_P (operands[2 + j]))
6368 : 104726 : for (i = j; i < nparts - 1; i++)
6369 : 52363 : if (CONST_INT_P (operands[7 + i])
6370 : 52363 : && INTVAL (operands[7 + i]) == INTVAL (operands[6 + j]))
6371 : 21895 : operands[7 + i] = operands[2 + j];
6372 : :
6373 : 5495422 : for (i = 0; i < nparts; i++)
6374 : 3663637 : emit_move_insn (operands[2 + i], operands[6 + i]);
6375 : :
6376 : : return;
6377 : : }
6378 : :
6379 : : /* Helper function of ix86_split_ashl used to generate an SImode/DImode
6380 : : left shift by a constant, either using a single shift or
6381 : : a sequence of add instructions. */
6382 : :
6383 : : static void
6384 : 4026 : ix86_expand_ashl_const (rtx operand, int count, machine_mode mode)
6385 : : {
6386 : 4026 : if (count == 1
6387 : 4026 : || (count * ix86_cost->add <= ix86_cost->shift_const
6388 : 0 : && !optimize_insn_for_size_p ()))
6389 : : {
6390 : 4 : while (count-- > 0)
6391 : 2 : emit_insn (gen_add2_insn (operand, operand));
6392 : : }
6393 : : else
6394 : : {
6395 : 4024 : rtx (*insn)(rtx, rtx, rtx);
6396 : :
6397 : 4024 : insn = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
6398 : 4024 : emit_insn (insn (operand, operand, GEN_INT (count)));
6399 : : }
6400 : 4026 : }
6401 : :
6402 : : void
6403 : 9758 : ix86_split_ashl (rtx *operands, rtx scratch, machine_mode mode)
6404 : : {
6405 : 9758 : rtx (*gen_ashl3)(rtx, rtx, rtx);
6406 : 9758 : rtx (*gen_shld)(rtx, rtx, rtx);
6407 : 9758 : int half_width = GET_MODE_BITSIZE (mode) >> 1;
6408 : 9758 : machine_mode half_mode;
6409 : :
6410 : 9758 : rtx low[2], high[2];
6411 : 9758 : int count;
6412 : :
6413 : 9758 : if (CONST_INT_P (operands[2]))
6414 : : {
6415 : 8175 : split_double_mode (mode, operands, 2, low, high);
6416 : 8175 : count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1);
6417 : :
6418 : 8175 : if (count >= half_width)
6419 : : {
6420 : 2432 : emit_move_insn (high[0], low[1]);
6421 : 2432 : ix86_expand_clear (low[0]);
6422 : :
6423 : 2432 : if (count > half_width)
6424 : 91 : ix86_expand_ashl_const (high[0], count - half_width, mode);
6425 : : }
6426 : 5743 : else if (count == 1)
6427 : : {
6428 : 1808 : if (!rtx_equal_p (operands[0], operands[1]))
6429 : 0 : emit_move_insn (operands[0], operands[1]);
6430 : 1808 : rtx x3 = gen_rtx_REG (CCCmode, FLAGS_REG);
6431 : 1808 : rtx x4 = gen_rtx_LTU (mode, x3, const0_rtx);
6432 : 1808 : half_mode = mode == DImode ? SImode : DImode;
6433 : 1808 : emit_insn (gen_add3_cc_overflow_1 (half_mode, low[0],
6434 : : low[0], low[0]));
6435 : 1808 : emit_insn (gen_add3_carry (half_mode, high[0], high[0], high[0],
6436 : : x3, x4));
6437 : : }
6438 : : else
6439 : : {
6440 : 3935 : gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
6441 : :
6442 : 3935 : if (!rtx_equal_p (operands[0], operands[1]))
6443 : 0 : emit_move_insn (operands[0], operands[1]);
6444 : :
6445 : 3935 : emit_insn (gen_shld (high[0], low[0], GEN_INT (count)));
6446 : 3935 : ix86_expand_ashl_const (low[0], count, mode);
6447 : : }
6448 : 8424 : return;
6449 : : }
6450 : :
6451 : 1583 : split_double_mode (mode, operands, 1, low, high);
6452 : 1583 : half_mode = mode == DImode ? SImode : DImode;
6453 : :
6454 : 1583 : gen_ashl3 = mode == DImode ? gen_ashlsi3 : gen_ashldi3;
6455 : :
6456 : 1583 : if (operands[1] == const1_rtx)
6457 : : {
6458 : : /* Assuming we've chosen a QImode capable registers, then 1 << N
6459 : : can be done with two 32/64-bit shifts, no branches, no cmoves. */
6460 : 249 : if (ANY_QI_REG_P (low[0]) && ANY_QI_REG_P (high[0]))
6461 : : {
6462 : 152 : rtx s, d, flags = gen_rtx_REG (CCZmode, FLAGS_REG);
6463 : :
6464 : 152 : ix86_expand_clear (low[0]);
6465 : 152 : ix86_expand_clear (high[0]);
6466 : 152 : emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (half_width)));
6467 : :
6468 : 152 : d = gen_lowpart (QImode, low[0]);
6469 : 152 : d = gen_rtx_STRICT_LOW_PART (VOIDmode, d);
6470 : 152 : s = gen_rtx_EQ (QImode, flags, const0_rtx);
6471 : 152 : emit_insn (gen_rtx_SET (d, s));
6472 : :
6473 : 152 : d = gen_lowpart (QImode, high[0]);
6474 : 152 : d = gen_rtx_STRICT_LOW_PART (VOIDmode, d);
6475 : 152 : s = gen_rtx_NE (QImode, flags, const0_rtx);
6476 : 152 : emit_insn (gen_rtx_SET (d, s));
6477 : : }
6478 : :
6479 : : /* Otherwise, we can get the same results by manually performing
6480 : : a bit extract operation on bit 5/6, and then performing the two
6481 : : shifts. The two methods of getting 0/1 into low/high are exactly
6482 : : the same size. Avoiding the shift in the bit extract case helps
6483 : : pentium4 a bit; no one else seems to care much either way. */
6484 : : else
6485 : : {
6486 : 97 : rtx (*gen_lshr3)(rtx, rtx, rtx);
6487 : 97 : rtx (*gen_and3)(rtx, rtx, rtx);
6488 : 97 : rtx (*gen_xor3)(rtx, rtx, rtx);
6489 : 97 : HOST_WIDE_INT bits;
6490 : 97 : rtx x;
6491 : :
6492 : 97 : if (mode == DImode)
6493 : : {
6494 : : gen_lshr3 = gen_lshrsi3;
6495 : : gen_and3 = gen_andsi3;
6496 : : gen_xor3 = gen_xorsi3;
6497 : : bits = 5;
6498 : : }
6499 : : else
6500 : : {
6501 : 0 : gen_lshr3 = gen_lshrdi3;
6502 : 0 : gen_and3 = gen_anddi3;
6503 : 0 : gen_xor3 = gen_xordi3;
6504 : 0 : bits = 6;
6505 : : }
6506 : :
6507 : 97 : if (TARGET_PARTIAL_REG_STALL && !optimize_insn_for_size_p ())
6508 : 0 : x = gen_rtx_ZERO_EXTEND (half_mode, operands[2]);
6509 : : else
6510 : 97 : x = gen_lowpart (half_mode, operands[2]);
6511 : 97 : emit_insn (gen_rtx_SET (high[0], x));
6512 : :
6513 : 97 : emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (bits)));
6514 : 97 : emit_insn (gen_and3 (high[0], high[0], const1_rtx));
6515 : 97 : emit_move_insn (low[0], high[0]);
6516 : 97 : emit_insn (gen_xor3 (low[0], low[0], const1_rtx));
6517 : : }
6518 : :
6519 : 249 : emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
6520 : 249 : emit_insn (gen_ashl3 (high[0], high[0], operands[2]));
6521 : 249 : return;
6522 : : }
6523 : :
6524 : 1334 : if (operands[1] == constm1_rtx)
6525 : : {
6526 : : /* For -1 << N, we can avoid the shld instruction, because we
6527 : : know that we're shifting 0...31/63 ones into a -1. */
6528 : 116 : emit_move_insn (low[0], constm1_rtx);
6529 : 116 : if (optimize_insn_for_size_p ())
6530 : 6 : emit_move_insn (high[0], low[0]);
6531 : : else
6532 : 110 : emit_move_insn (high[0], constm1_rtx);
6533 : : }
6534 : : else
6535 : : {
6536 : 1218 : gen_shld = mode == DImode ? gen_x86_shld : gen_x86_64_shld;
6537 : :
6538 : 1218 : if (!rtx_equal_p (operands[0], operands[1]))
6539 : 0 : emit_move_insn (operands[0], operands[1]);
6540 : :
6541 : 1218 : split_double_mode (mode, operands, 1, low, high);
6542 : 1218 : emit_insn (gen_shld (high[0], low[0], operands[2]));
6543 : : }
6544 : :
6545 : 1334 : emit_insn (gen_ashl3 (low[0], low[0], operands[2]));
6546 : :
6547 : 1334 : if (TARGET_CMOVE && scratch)
6548 : : {
6549 : 948 : ix86_expand_clear (scratch);
6550 : 948 : emit_insn (gen_x86_shift_adj_1
6551 : : (half_mode, high[0], low[0], operands[2], scratch));
6552 : : }
6553 : : else
6554 : 386 : emit_insn (gen_x86_shift_adj_2 (half_mode, high[0], low[0], operands[2]));
6555 : : }
6556 : :
6557 : : void
6558 : 6366 : ix86_split_ashr (rtx *operands, rtx scratch, machine_mode mode)
6559 : : {
6560 : 12732 : rtx (*gen_ashr3)(rtx, rtx, rtx)
6561 : 6366 : = mode == DImode ? gen_ashrsi3 : gen_ashrdi3;
6562 : 6366 : rtx (*gen_shrd)(rtx, rtx, rtx);
6563 : 6366 : int half_width = GET_MODE_BITSIZE (mode) >> 1;
6564 : :
6565 : 6366 : rtx low[2], high[2];
6566 : 6366 : int count;
6567 : :
6568 : 6366 : if (CONST_INT_P (operands[2]))
6569 : : {
6570 : 6195 : split_double_mode (mode, operands, 2, low, high);
6571 : 6195 : count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1);
6572 : :
6573 : 12390 : if (count == GET_MODE_BITSIZE (mode) - 1)
6574 : : {
6575 : 56 : emit_move_insn (high[0], high[1]);
6576 : 56 : emit_insn (gen_ashr3 (high[0], high[0],
6577 : 56 : GEN_INT (half_width - 1)));
6578 : 56 : emit_move_insn (low[0], high[0]);
6579 : :
6580 : : }
6581 : 6139 : else if (count >= half_width)
6582 : : {
6583 : 1984 : emit_move_insn (low[0], high[1]);
6584 : 1984 : emit_move_insn (high[0], low[0]);
6585 : 1984 : emit_insn (gen_ashr3 (high[0], high[0],
6586 : 1984 : GEN_INT (half_width - 1)));
6587 : :
6588 : 1984 : if (count > half_width)
6589 : 28 : emit_insn (gen_ashr3 (low[0], low[0],
6590 : 28 : GEN_INT (count - half_width)));
6591 : : }
6592 : 4155 : else if (count == 1
6593 : 774 : && (TARGET_USE_RCR || optimize_size > 1))
6594 : : {
6595 : 1 : if (!rtx_equal_p (operands[0], operands[1]))
6596 : 0 : emit_move_insn (operands[0], operands[1]);
6597 : 1 : if (mode == DImode)
6598 : : {
6599 : 0 : emit_insn (gen_ashrsi3_carry (high[0], high[0]));
6600 : 0 : emit_insn (gen_rcrsi2 (low[0], low[0]));
6601 : : }
6602 : : else
6603 : : {
6604 : 1 : emit_insn (gen_ashrdi3_carry (high[0], high[0]));
6605 : 1 : emit_insn (gen_rcrdi2 (low[0], low[0]));
6606 : : }
6607 : : }
6608 : : else
6609 : : {
6610 : 4154 : gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
6611 : :
6612 : 4154 : if (!rtx_equal_p (operands[0], operands[1]))
6613 : 0 : emit_move_insn (operands[0], operands[1]);
6614 : :
6615 : 4154 : emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
6616 : 4154 : emit_insn (gen_ashr3 (high[0], high[0], GEN_INT (count)));
6617 : : }
6618 : : }
6619 : : else
6620 : : {
6621 : 171 : machine_mode half_mode;
6622 : :
6623 : 171 : gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
6624 : :
6625 : 171 : if (!rtx_equal_p (operands[0], operands[1]))
6626 : 0 : emit_move_insn (operands[0], operands[1]);
6627 : :
6628 : 171 : split_double_mode (mode, operands, 1, low, high);
6629 : 171 : half_mode = mode == DImode ? SImode : DImode;
6630 : :
6631 : 171 : emit_insn (gen_shrd (low[0], high[0], operands[2]));
6632 : 171 : emit_insn (gen_ashr3 (high[0], high[0], operands[2]));
6633 : :
6634 : 171 : if (TARGET_CMOVE && scratch)
6635 : : {
6636 : 131 : emit_move_insn (scratch, high[0]);
6637 : 131 : emit_insn (gen_ashr3 (scratch, scratch,
6638 : 131 : GEN_INT (half_width - 1)));
6639 : 131 : emit_insn (gen_x86_shift_adj_1
6640 : : (half_mode, low[0], high[0], operands[2], scratch));
6641 : : }
6642 : : else
6643 : 40 : emit_insn (gen_x86_shift_adj_3
6644 : : (half_mode, low[0], high[0], operands[2]));
6645 : : }
6646 : 6366 : }
6647 : :
6648 : : void
6649 : 13468 : ix86_split_lshr (rtx *operands, rtx scratch, machine_mode mode)
6650 : : {
6651 : 26936 : rtx (*gen_lshr3)(rtx, rtx, rtx)
6652 : 13468 : = mode == DImode ? gen_lshrsi3 : gen_lshrdi3;
6653 : 13468 : rtx (*gen_shrd)(rtx, rtx, rtx);
6654 : 13468 : int half_width = GET_MODE_BITSIZE (mode) >> 1;
6655 : :
6656 : 13468 : rtx low[2], high[2];
6657 : 13468 : int count;
6658 : :
6659 : 13468 : if (CONST_INT_P (operands[2]))
6660 : : {
6661 : 12092 : split_double_mode (mode, operands, 2, low, high);
6662 : 12092 : count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (mode) - 1);
6663 : :
6664 : 12092 : if (count >= half_width)
6665 : : {
6666 : 8235 : emit_move_insn (low[0], high[1]);
6667 : 8235 : ix86_expand_clear (high[0]);
6668 : :
6669 : 8235 : if (count > half_width)
6670 : 553 : emit_insn (gen_lshr3 (low[0], low[0],
6671 : 553 : GEN_INT (count - half_width)));
6672 : : }
6673 : 3857 : else if (count == 1
6674 : 677 : && (TARGET_USE_RCR || optimize_size > 1))
6675 : : {
6676 : 1 : if (!rtx_equal_p (operands[0], operands[1]))
6677 : 0 : emit_move_insn (operands[0], operands[1]);
6678 : 1 : if (mode == DImode)
6679 : : {
6680 : 0 : emit_insn (gen_lshrsi3_carry (high[0], high[0]));
6681 : 0 : emit_insn (gen_rcrsi2 (low[0], low[0]));
6682 : : }
6683 : : else
6684 : : {
6685 : 1 : emit_insn (gen_lshrdi3_carry (high[0], high[0]));
6686 : 1 : emit_insn (gen_rcrdi2 (low[0], low[0]));
6687 : : }
6688 : : }
6689 : : else
6690 : : {
6691 : 3856 : gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
6692 : :
6693 : 3856 : if (!rtx_equal_p (operands[0], operands[1]))
6694 : 0 : emit_move_insn (operands[0], operands[1]);
6695 : :
6696 : 3856 : emit_insn (gen_shrd (low[0], high[0], GEN_INT (count)));
6697 : 3856 : emit_insn (gen_lshr3 (high[0], high[0], GEN_INT (count)));
6698 : : }
6699 : : }
6700 : : else
6701 : : {
6702 : 1376 : machine_mode half_mode;
6703 : :
6704 : 1376 : gen_shrd = mode == DImode ? gen_x86_shrd : gen_x86_64_shrd;
6705 : :
6706 : 1376 : if (!rtx_equal_p (operands[0], operands[1]))
6707 : 0 : emit_move_insn (operands[0], operands[1]);
6708 : :
6709 : 1376 : split_double_mode (mode, operands, 1, low, high);
6710 : 1376 : half_mode = mode == DImode ? SImode : DImode;
6711 : :
6712 : 1376 : emit_insn (gen_shrd (low[0], high[0], operands[2]));
6713 : 1376 : emit_insn (gen_lshr3 (high[0], high[0], operands[2]));
6714 : :
6715 : 1376 : if (TARGET_CMOVE && scratch)
6716 : : {
6717 : 1101 : ix86_expand_clear (scratch);
6718 : 1101 : emit_insn (gen_x86_shift_adj_1
6719 : : (half_mode, low[0], high[0], operands[2], scratch));
6720 : : }
6721 : : else
6722 : 275 : emit_insn (gen_x86_shift_adj_2
6723 : : (half_mode, low[0], high[0], operands[2]));
6724 : : }
6725 : 13468 : }
6726 : :
6727 : : /* Helper function to split TImode ashl under NDD. */
6728 : : void
6729 : 1 : ix86_split_ashl_ndd (rtx *operands, rtx scratch)
6730 : : {
6731 : 1 : gcc_assert (TARGET_APX_NDD);
6732 : 1 : int half_width = GET_MODE_BITSIZE (TImode) >> 1;
6733 : :
6734 : 1 : rtx low[2], high[2];
6735 : 1 : int count;
6736 : :
6737 : 1 : split_double_mode (TImode, operands, 2, low, high);
6738 : 1 : if (CONST_INT_P (operands[2]))
6739 : : {
6740 : 0 : count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (TImode) - 1);
6741 : :
6742 : 0 : if (count >= half_width)
6743 : : {
6744 : 0 : count = count - half_width;
6745 : 0 : if (count == 0)
6746 : : {
6747 : 0 : if (!rtx_equal_p (high[0], low[1]))
6748 : 0 : emit_move_insn (high[0], low[1]);
6749 : : }
6750 : 0 : else if (count == 1)
6751 : 0 : emit_insn (gen_adddi3 (high[0], low[1], low[1]));
6752 : : else
6753 : 0 : emit_insn (gen_ashldi3 (high[0], low[1], GEN_INT (count)));
6754 : :
6755 : 0 : ix86_expand_clear (low[0]);
6756 : : }
6757 : 0 : else if (count == 1)
6758 : : {
6759 : 0 : rtx x3 = gen_rtx_REG (CCCmode, FLAGS_REG);
6760 : 0 : rtx x4 = gen_rtx_LTU (TImode, x3, const0_rtx);
6761 : 0 : emit_insn (gen_add3_cc_overflow_1 (DImode, low[0],
6762 : : low[1], low[1]));
6763 : 0 : emit_insn (gen_add3_carry (DImode, high[0], high[1], high[1],
6764 : : x3, x4));
6765 : : }
6766 : : else
6767 : : {
6768 : 0 : emit_insn (gen_x86_64_shld_ndd (high[0], high[1], low[1],
6769 : : GEN_INT (count)));
6770 : 0 : emit_insn (gen_ashldi3 (low[0], low[1], GEN_INT (count)));
6771 : : }
6772 : : }
6773 : : else
6774 : : {
6775 : 1 : emit_insn (gen_x86_64_shld_ndd (high[0], high[1], low[1],
6776 : : operands[2]));
6777 : 1 : emit_insn (gen_ashldi3 (low[0], low[1], operands[2]));
6778 : 1 : if (TARGET_CMOVE && scratch)
6779 : : {
6780 : 1 : ix86_expand_clear (scratch);
6781 : 1 : emit_insn (gen_x86_shift_adj_1
6782 : : (DImode, high[0], low[0], operands[2], scratch));
6783 : : }
6784 : : else
6785 : 0 : emit_insn (gen_x86_shift_adj_2 (DImode, high[0], low[0], operands[2]));
6786 : : }
6787 : 1 : }
6788 : :
6789 : : /* Helper function to split TImode l/ashr under NDD. */
6790 : : void
6791 : 2 : ix86_split_rshift_ndd (enum rtx_code code, rtx *operands, rtx scratch)
6792 : : {
6793 : 2 : gcc_assert (TARGET_APX_NDD);
6794 : 2 : int half_width = GET_MODE_BITSIZE (TImode) >> 1;
6795 : 2 : bool ashr_p = code == ASHIFTRT;
6796 : 2 : rtx (*gen_shr)(rtx, rtx, rtx) = ashr_p ? gen_ashrdi3
6797 : : : gen_lshrdi3;
6798 : :
6799 : 2 : rtx low[2], high[2];
6800 : 2 : int count;
6801 : :
6802 : 2 : split_double_mode (TImode, operands, 2, low, high);
6803 : 2 : if (CONST_INT_P (operands[2]))
6804 : : {
6805 : 0 : count = INTVAL (operands[2]) & (GET_MODE_BITSIZE (TImode) - 1);
6806 : :
6807 : 0 : if (ashr_p && (count == GET_MODE_BITSIZE (TImode) - 1))
6808 : : {
6809 : 0 : emit_insn (gen_shr (high[0], high[1],
6810 : : GEN_INT (half_width - 1)));
6811 : 0 : emit_move_insn (low[0], high[0]);
6812 : : }
6813 : 0 : else if (count >= half_width)
6814 : : {
6815 : 0 : if (ashr_p)
6816 : 0 : emit_insn (gen_shr (high[0], high[1],
6817 : : GEN_INT (half_width - 1)));
6818 : : else
6819 : 0 : ix86_expand_clear (high[0]);
6820 : :
6821 : 0 : if (count > half_width)
6822 : 0 : emit_insn (gen_shr (low[0], high[1],
6823 : 0 : GEN_INT (count - half_width)));
6824 : : else
6825 : 0 : emit_move_insn (low[0], high[1]);
6826 : : }
6827 : : else
6828 : : {
6829 : 0 : emit_insn (gen_x86_64_shrd_ndd (low[0], low[1], high[1],
6830 : : GEN_INT (count)));
6831 : 0 : emit_insn (gen_shr (high[0], high[1], GEN_INT (count)));
6832 : : }
6833 : : }
6834 : : else
6835 : : {
6836 : 2 : emit_insn (gen_x86_64_shrd_ndd (low[0], low[1], high[1],
6837 : : operands[2]));
6838 : 2 : emit_insn (gen_shr (high[0], high[1], operands[2]));
6839 : :
6840 : 2 : if (TARGET_CMOVE && scratch)
6841 : : {
6842 : 2 : if (ashr_p)
6843 : : {
6844 : 1 : emit_move_insn (scratch, high[0]);
6845 : 1 : emit_insn (gen_shr (scratch, scratch,
6846 : : GEN_INT (half_width - 1)));
6847 : : }
6848 : : else
6849 : 1 : ix86_expand_clear (scratch);
6850 : :
6851 : 2 : emit_insn (gen_x86_shift_adj_1
6852 : : (DImode, low[0], high[0], operands[2], scratch));
6853 : : }
6854 : 0 : else if (ashr_p)
6855 : 0 : emit_insn (gen_x86_shift_adj_3
6856 : : (DImode, low[0], high[0], operands[2]));
6857 : : else
6858 : 0 : emit_insn (gen_x86_shift_adj_2
6859 : : (DImode, low[0], high[0], operands[2]));
6860 : : }
6861 : 2 : }
6862 : :
6863 : : /* Expand move of V1TI mode register X to a new TI mode register. */
6864 : : static rtx
6865 : 17 : ix86_expand_v1ti_to_ti (rtx x)
6866 : : {
6867 : 17 : rtx result = gen_reg_rtx (TImode);
6868 : 17 : if (TARGET_SSE2)
6869 : : {
6870 : 17 : rtx temp = force_reg (V2DImode, gen_lowpart (V2DImode, x));
6871 : 17 : rtx lo = gen_lowpart (DImode, result);
6872 : 17 : emit_insn (gen_vec_extractv2didi (lo, temp, const0_rtx));
6873 : 17 : rtx hi = gen_highpart (DImode, result);
6874 : 17 : emit_insn (gen_vec_extractv2didi (hi, temp, const1_rtx));
6875 : : }
6876 : : else
6877 : 0 : emit_move_insn (result, gen_lowpart (TImode, x));
6878 : 17 : return result;
6879 : : }
6880 : :
6881 : : /* Expand move of TI mode register X to a new V1TI mode register. */
6882 : : static rtx
6883 : 17 : ix86_expand_ti_to_v1ti (rtx x)
6884 : : {
6885 : 17 : if (TARGET_SSE2)
6886 : : {
6887 : 17 : rtx lo = gen_lowpart (DImode, x);
6888 : 17 : rtx hi = gen_highpart (DImode, x);
6889 : 17 : rtx tmp = gen_reg_rtx (V2DImode);
6890 : 17 : emit_insn (gen_vec_concatv2di (tmp, lo, hi));
6891 : 17 : return force_reg (V1TImode, gen_lowpart (V1TImode, tmp));
6892 : : }
6893 : :
6894 : 0 : return force_reg (V1TImode, gen_lowpart (V1TImode, x));
6895 : : }
6896 : :
6897 : : /* Expand V1TI mode shift (of rtx_code CODE) by constant. */
6898 : : void
6899 : 42 : ix86_expand_v1ti_shift (enum rtx_code code, rtx operands[])
6900 : : {
6901 : 42 : rtx op1 = force_reg (V1TImode, operands[1]);
6902 : :
6903 : 42 : if (!CONST_INT_P (operands[2]))
6904 : : {
6905 : 6 : rtx tmp1 = ix86_expand_v1ti_to_ti (op1);
6906 : 6 : rtx tmp2 = gen_reg_rtx (TImode);
6907 : 12 : rtx (*shift) (rtx, rtx, rtx)
6908 : 6 : = (code == ASHIFT) ? gen_ashlti3 : gen_lshrti3;
6909 : 6 : emit_insn (shift (tmp2, tmp1, operands[2]));
6910 : 6 : rtx tmp3 = ix86_expand_ti_to_v1ti (tmp2);
6911 : 6 : emit_move_insn (operands[0], tmp3);
6912 : 6 : return;
6913 : : }
6914 : :
6915 : 36 : HOST_WIDE_INT bits = INTVAL (operands[2]) & 127;
6916 : :
6917 : 36 : if (bits == 0)
6918 : : {
6919 : 0 : emit_move_insn (operands[0], op1);
6920 : 0 : return;
6921 : : }
6922 : :
6923 : 36 : if ((bits & 7) == 0)
6924 : : {
6925 : 0 : rtx tmp = gen_reg_rtx (V1TImode);
6926 : 0 : if (code == ASHIFT)
6927 : 0 : emit_insn (gen_sse2_ashlv1ti3 (tmp, op1, GEN_INT (bits)));
6928 : : else
6929 : 0 : emit_insn (gen_sse2_lshrv1ti3 (tmp, op1, GEN_INT (bits)));
6930 : 0 : emit_move_insn (operands[0], tmp);
6931 : 0 : return;
6932 : : }
6933 : :
6934 : 36 : rtx tmp1 = gen_reg_rtx (V1TImode);
6935 : 36 : if (code == ASHIFT)
6936 : 18 : emit_insn (gen_sse2_ashlv1ti3 (tmp1, op1, GEN_INT (64)));
6937 : : else
6938 : 18 : emit_insn (gen_sse2_lshrv1ti3 (tmp1, op1, GEN_INT (64)));
6939 : :
6940 : : /* tmp2 is operands[1] shifted by 64, in V2DImode. */
6941 : 36 : rtx tmp2 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp1));
6942 : :
6943 : : /* tmp3 will be the V2DImode result. */
6944 : 36 : rtx tmp3 = gen_reg_rtx (V2DImode);
6945 : :
6946 : 36 : if (bits > 64)
6947 : : {
6948 : 18 : if (code == ASHIFT)
6949 : 9 : emit_insn (gen_ashlv2di3 (tmp3, tmp2, GEN_INT (bits - 64)));
6950 : : else
6951 : 9 : emit_insn (gen_lshrv2di3 (tmp3, tmp2, GEN_INT (bits - 64)));
6952 : : }
6953 : : else
6954 : : {
6955 : : /* tmp4 is operands[1], in V2DImode. */
6956 : 18 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, op1));
6957 : :
6958 : 18 : rtx tmp5 = gen_reg_rtx (V2DImode);
6959 : 18 : if (code == ASHIFT)
6960 : 9 : emit_insn (gen_ashlv2di3 (tmp5, tmp4, GEN_INT (bits)));
6961 : : else
6962 : 9 : emit_insn (gen_lshrv2di3 (tmp5, tmp4, GEN_INT (bits)));
6963 : :
6964 : 18 : rtx tmp6 = gen_reg_rtx (V2DImode);
6965 : 18 : if (code == ASHIFT)
6966 : 9 : emit_insn (gen_lshrv2di3 (tmp6, tmp2, GEN_INT (64 - bits)));
6967 : : else
6968 : 9 : emit_insn (gen_ashlv2di3 (tmp6, tmp2, GEN_INT (64 - bits)));
6969 : :
6970 : 18 : emit_insn (gen_iorv2di3 (tmp3, tmp5, tmp6));
6971 : : }
6972 : :
6973 : : /* Convert the result back to V1TImode and store in operands[0]. */
6974 : 36 : rtx tmp7 = force_reg (V1TImode, gen_lowpart (V1TImode, tmp3));
6975 : 36 : emit_move_insn (operands[0], tmp7);
6976 : : }
6977 : :
6978 : : /* Expand V1TI mode rotate (of rtx_code CODE) by constant. */
6979 : : void
6980 : 39 : ix86_expand_v1ti_rotate (enum rtx_code code, rtx operands[])
6981 : : {
6982 : 39 : rtx op1 = force_reg (V1TImode, operands[1]);
6983 : :
6984 : 39 : if (!CONST_INT_P (operands[2]))
6985 : : {
6986 : 8 : rtx tmp1 = ix86_expand_v1ti_to_ti (op1);
6987 : 8 : rtx tmp2 = gen_reg_rtx (TImode);
6988 : 16 : rtx (*rotate) (rtx, rtx, rtx)
6989 : 8 : = (code == ROTATE) ? gen_rotlti3 : gen_rotrti3;
6990 : 8 : emit_insn (rotate (tmp2, tmp1, operands[2]));
6991 : 8 : rtx tmp3 = ix86_expand_ti_to_v1ti (tmp2);
6992 : 8 : emit_move_insn (operands[0], tmp3);
6993 : 8 : return;
6994 : : }
6995 : :
6996 : 31 : HOST_WIDE_INT bits = INTVAL (operands[2]) & 127;
6997 : :
6998 : 31 : if (bits == 0)
6999 : : {
7000 : 0 : emit_move_insn (operands[0], op1);
7001 : 0 : return;
7002 : : }
7003 : :
7004 : 31 : if (code == ROTATERT)
7005 : 16 : bits = 128 - bits;
7006 : :
7007 : 31 : if ((bits & 31) == 0)
7008 : : {
7009 : 5 : rtx tmp2 = gen_reg_rtx (V4SImode);
7010 : 5 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7011 : 5 : if (bits == 32)
7012 : 1 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0x93)));
7013 : 4 : else if (bits == 64)
7014 : 2 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0x4e)));
7015 : : else
7016 : 2 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0x39)));
7017 : 5 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp2));
7018 : 5 : return;
7019 : : }
7020 : :
7021 : 26 : if ((bits & 7) == 0)
7022 : : {
7023 : 6 : rtx tmp1 = gen_reg_rtx (V1TImode);
7024 : 6 : rtx tmp2 = gen_reg_rtx (V1TImode);
7025 : 6 : rtx tmp3 = gen_reg_rtx (V1TImode);
7026 : :
7027 : 6 : emit_insn (gen_sse2_ashlv1ti3 (tmp1, op1, GEN_INT (bits)));
7028 : 6 : emit_insn (gen_sse2_lshrv1ti3 (tmp2, op1, GEN_INT (128 - bits)));
7029 : 6 : emit_insn (gen_iorv1ti3 (tmp3, tmp1, tmp2));
7030 : 6 : emit_move_insn (operands[0], tmp3);
7031 : 6 : return;
7032 : : }
7033 : :
7034 : 20 : rtx op1_v4si = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7035 : :
7036 : 20 : rtx lobits;
7037 : 20 : rtx hibits;
7038 : :
7039 : 20 : switch (bits >> 5)
7040 : : {
7041 : 7 : case 0:
7042 : 7 : lobits = op1_v4si;
7043 : 7 : hibits = gen_reg_rtx (V4SImode);
7044 : 7 : emit_insn (gen_sse2_pshufd (hibits, op1_v4si, GEN_INT (0x93)));
7045 : 7 : break;
7046 : :
7047 : 2 : case 1:
7048 : 2 : lobits = gen_reg_rtx (V4SImode);
7049 : 2 : hibits = gen_reg_rtx (V4SImode);
7050 : 2 : emit_insn (gen_sse2_pshufd (lobits, op1_v4si, GEN_INT (0x93)));
7051 : 2 : emit_insn (gen_sse2_pshufd (hibits, op1_v4si, GEN_INT (0x4e)));
7052 : 2 : break;
7053 : :
7054 : 2 : case 2:
7055 : 2 : lobits = gen_reg_rtx (V4SImode);
7056 : 2 : hibits = gen_reg_rtx (V4SImode);
7057 : 2 : emit_insn (gen_sse2_pshufd (lobits, op1_v4si, GEN_INT (0x4e)));
7058 : 2 : emit_insn (gen_sse2_pshufd (hibits, op1_v4si, GEN_INT (0x39)));
7059 : 2 : break;
7060 : :
7061 : 9 : default:
7062 : 9 : lobits = gen_reg_rtx (V4SImode);
7063 : 9 : emit_insn (gen_sse2_pshufd (lobits, op1_v4si, GEN_INT (0x39)));
7064 : 9 : hibits = op1_v4si;
7065 : 9 : break;
7066 : : }
7067 : :
7068 : 20 : rtx tmp1 = gen_reg_rtx (V4SImode);
7069 : 20 : rtx tmp2 = gen_reg_rtx (V4SImode);
7070 : 20 : rtx tmp3 = gen_reg_rtx (V4SImode);
7071 : :
7072 : 20 : emit_insn (gen_ashlv4si3 (tmp1, lobits, GEN_INT (bits & 31)));
7073 : 20 : emit_insn (gen_lshrv4si3 (tmp2, hibits, GEN_INT (32 - (bits & 31))));
7074 : 20 : emit_insn (gen_iorv4si3 (tmp3, tmp1, tmp2));
7075 : :
7076 : 20 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp3));
7077 : : }
7078 : :
7079 : : /* Expand V1TI mode ashiftrt by constant. */
7080 : : void
7081 : 109 : ix86_expand_v1ti_ashiftrt (rtx operands[])
7082 : : {
7083 : 109 : rtx op1 = force_reg (V1TImode, operands[1]);
7084 : :
7085 : 109 : if (!CONST_INT_P (operands[2]))
7086 : : {
7087 : 3 : rtx tmp1 = ix86_expand_v1ti_to_ti (op1);
7088 : 3 : rtx tmp2 = gen_reg_rtx (TImode);
7089 : 3 : emit_insn (gen_ashrti3 (tmp2, tmp1, operands[2]));
7090 : 3 : rtx tmp3 = ix86_expand_ti_to_v1ti (tmp2);
7091 : 3 : emit_move_insn (operands[0], tmp3);
7092 : 3 : return;
7093 : : }
7094 : :
7095 : 106 : HOST_WIDE_INT bits = INTVAL (operands[2]) & 127;
7096 : :
7097 : 106 : if (bits == 0)
7098 : : {
7099 : 0 : emit_move_insn (operands[0], op1);
7100 : 0 : return;
7101 : : }
7102 : :
7103 : 106 : if (bits == 127)
7104 : : {
7105 : : /* Two operations. */
7106 : 3 : rtx tmp1 = force_reg(V4SImode, gen_lowpart (V4SImode, op1));
7107 : 3 : rtx tmp2 = gen_reg_rtx (V4SImode);
7108 : 3 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0xff)));
7109 : :
7110 : 3 : rtx tmp3 = gen_reg_rtx (V4SImode);
7111 : 3 : emit_insn (gen_ashrv4si3 (tmp3, tmp2, GEN_INT (31)));
7112 : :
7113 : 3 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp3));
7114 : 3 : return;
7115 : : }
7116 : :
7117 : 103 : if (bits == 64)
7118 : : {
7119 : : /* Three operations. */
7120 : 3 : rtx tmp1 = force_reg(V4SImode, gen_lowpart (V4SImode, op1));
7121 : 3 : rtx tmp2 = gen_reg_rtx (V4SImode);
7122 : 3 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0xff)));
7123 : :
7124 : 3 : rtx tmp3 = gen_reg_rtx (V4SImode);
7125 : 3 : emit_insn (gen_ashrv4si3 (tmp3, tmp2, GEN_INT (31)));
7126 : :
7127 : 3 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp1));
7128 : 3 : rtx tmp5 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp3));
7129 : 3 : rtx tmp6 = gen_reg_rtx (V2DImode);
7130 : 3 : emit_insn (gen_vec_interleave_highv2di (tmp6, tmp4, tmp5));
7131 : :
7132 : 3 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp6));
7133 : 3 : return;
7134 : : }
7135 : :
7136 : 100 : if (bits == 96)
7137 : : {
7138 : : /* Three operations. */
7139 : 3 : rtx tmp1 = force_reg(V4SImode, gen_lowpart (V4SImode, op1));
7140 : 3 : rtx tmp2 = gen_reg_rtx (V4SImode);
7141 : 3 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (31)));
7142 : :
7143 : 3 : rtx tmp3 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp1));
7144 : 3 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp2));
7145 : 3 : rtx tmp5 = gen_reg_rtx (V2DImode);
7146 : 3 : emit_insn (gen_vec_interleave_highv2di (tmp5, tmp3, tmp4));
7147 : :
7148 : 3 : rtx tmp6 = force_reg(V4SImode, gen_lowpart (V4SImode, tmp5));
7149 : 3 : rtx tmp7 = gen_reg_rtx (V4SImode);
7150 : 3 : emit_insn (gen_sse2_pshufd (tmp7, tmp6, GEN_INT (0xfd)));
7151 : :
7152 : 3 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp7));
7153 : 3 : return;
7154 : : }
7155 : :
7156 : 97 : if (bits >= 111)
7157 : : {
7158 : : /* Three operations. */
7159 : 21 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7160 : 21 : rtx tmp2 = gen_reg_rtx (V4SImode);
7161 : 21 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (bits - 96)));
7162 : :
7163 : 21 : rtx tmp3 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp2));
7164 : 21 : rtx tmp4 = gen_reg_rtx (V8HImode);
7165 : 21 : emit_insn (gen_sse2_pshufhw (tmp4, tmp3, GEN_INT (0xfe)));
7166 : :
7167 : 21 : rtx tmp5 = force_reg (V4SImode, gen_lowpart (V4SImode, tmp4));
7168 : 21 : rtx tmp6 = gen_reg_rtx (V4SImode);
7169 : 21 : emit_insn (gen_sse2_pshufd (tmp6, tmp5, GEN_INT (0xfe)));
7170 : :
7171 : 21 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp6));
7172 : 21 : return;
7173 : : }
7174 : :
7175 : 76 : if (TARGET_AVX2 || TARGET_SSE4_1)
7176 : : {
7177 : : /* Three operations. */
7178 : 50 : if (bits == 32)
7179 : : {
7180 : 2 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7181 : 2 : rtx tmp2 = gen_reg_rtx (V4SImode);
7182 : 2 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (31)));
7183 : :
7184 : 2 : rtx tmp3 = gen_reg_rtx (V1TImode);
7185 : 2 : emit_insn (gen_sse2_lshrv1ti3 (tmp3, op1, GEN_INT (32)));
7186 : :
7187 : 2 : if (TARGET_AVX2)
7188 : : {
7189 : 1 : rtx tmp4 = force_reg (V4SImode, gen_lowpart (V4SImode, tmp3));
7190 : 1 : rtx tmp5 = gen_reg_rtx (V4SImode);
7191 : 1 : emit_insn (gen_avx2_pblenddv4si (tmp5, tmp2, tmp4,
7192 : : GEN_INT (7)));
7193 : :
7194 : 1 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp5));
7195 : : }
7196 : : else
7197 : : {
7198 : 1 : rtx tmp4 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp2));
7199 : 1 : rtx tmp5 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp3));
7200 : 1 : rtx tmp6 = gen_reg_rtx (V8HImode);
7201 : 1 : emit_insn (gen_sse4_1_pblendw (tmp6, tmp4, tmp5,
7202 : : GEN_INT (0x3f)));
7203 : :
7204 : 1 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp6));
7205 : : }
7206 : 2 : return;
7207 : : }
7208 : :
7209 : : /* Three operations. */
7210 : 48 : if (bits == 8 || bits == 16 || bits == 24)
7211 : : {
7212 : 6 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7213 : 6 : rtx tmp2 = gen_reg_rtx (V4SImode);
7214 : 6 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (bits)));
7215 : :
7216 : 6 : rtx tmp3 = gen_reg_rtx (V1TImode);
7217 : 6 : emit_insn (gen_sse2_lshrv1ti3 (tmp3, op1, GEN_INT (bits)));
7218 : :
7219 : 6 : if (TARGET_AVX2)
7220 : : {
7221 : 3 : rtx tmp4 = force_reg (V4SImode, gen_lowpart (V4SImode, tmp3));
7222 : 3 : rtx tmp5 = gen_reg_rtx (V4SImode);
7223 : 3 : emit_insn (gen_avx2_pblenddv4si (tmp5, tmp2, tmp4,
7224 : : GEN_INT (7)));
7225 : :
7226 : 3 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp5));
7227 : : }
7228 : : else
7229 : : {
7230 : 3 : rtx tmp4 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp2));
7231 : 3 : rtx tmp5 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp3));
7232 : 3 : rtx tmp6 = gen_reg_rtx (V8HImode);
7233 : 3 : emit_insn (gen_sse4_1_pblendw (tmp6, tmp4, tmp5,
7234 : : GEN_INT (0x3f)));
7235 : :
7236 : 3 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp6));
7237 : : }
7238 : 6 : return;
7239 : : }
7240 : : }
7241 : :
7242 : 68 : if (bits > 96)
7243 : : {
7244 : : /* Four operations. */
7245 : 3 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7246 : 3 : rtx tmp2 = gen_reg_rtx (V4SImode);
7247 : 3 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (bits - 96)));
7248 : :
7249 : 3 : rtx tmp3 = gen_reg_rtx (V4SImode);
7250 : 3 : emit_insn (gen_ashrv4si3 (tmp3, tmp1, GEN_INT (31)));
7251 : :
7252 : 3 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp2));
7253 : 3 : rtx tmp5 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp3));
7254 : 3 : rtx tmp6 = gen_reg_rtx (V2DImode);
7255 : 3 : emit_insn (gen_vec_interleave_highv2di (tmp6, tmp4, tmp5));
7256 : :
7257 : 3 : rtx tmp7 = force_reg (V4SImode, gen_lowpart (V4SImode, tmp6));
7258 : 3 : rtx tmp8 = gen_reg_rtx (V4SImode);
7259 : 3 : emit_insn (gen_sse2_pshufd (tmp8, tmp7, GEN_INT (0xfd)));
7260 : :
7261 : 3 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp8));
7262 : 3 : return;
7263 : : }
7264 : :
7265 : 65 : if (TARGET_SSE4_1 && (bits == 48 || bits == 80))
7266 : : {
7267 : : /* Four operations. */
7268 : 4 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7269 : 4 : rtx tmp2 = gen_reg_rtx (V4SImode);
7270 : 4 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0xff)));
7271 : :
7272 : 4 : rtx tmp3 = gen_reg_rtx (V4SImode);
7273 : 4 : emit_insn (gen_ashrv4si3 (tmp3, tmp2, GEN_INT (31)));
7274 : :
7275 : 4 : rtx tmp4 = gen_reg_rtx (V1TImode);
7276 : 4 : emit_insn (gen_sse2_lshrv1ti3 (tmp4, op1, GEN_INT (bits)));
7277 : :
7278 : 4 : rtx tmp5 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp3));
7279 : 4 : rtx tmp6 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp4));
7280 : 4 : rtx tmp7 = gen_reg_rtx (V8HImode);
7281 : 6 : emit_insn (gen_sse4_1_pblendw (tmp7, tmp5, tmp6,
7282 : : GEN_INT (bits == 48 ? 0x1f : 0x07)));
7283 : :
7284 : 4 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp7));
7285 : 4 : return;
7286 : : }
7287 : :
7288 : 61 : if ((bits & 7) == 0)
7289 : : {
7290 : : /* Five operations. */
7291 : 9 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7292 : 9 : rtx tmp2 = gen_reg_rtx (V4SImode);
7293 : 9 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0xff)));
7294 : :
7295 : 9 : rtx tmp3 = gen_reg_rtx (V4SImode);
7296 : 9 : emit_insn (gen_ashrv4si3 (tmp3, tmp2, GEN_INT (31)));
7297 : :
7298 : 9 : rtx tmp4 = gen_reg_rtx (V1TImode);
7299 : 9 : emit_insn (gen_sse2_lshrv1ti3 (tmp4, op1, GEN_INT (bits)));
7300 : :
7301 : 9 : rtx tmp5 = force_reg (V1TImode, gen_lowpart (V1TImode, tmp3));
7302 : 9 : rtx tmp6 = gen_reg_rtx (V1TImode);
7303 : 9 : emit_insn (gen_sse2_ashlv1ti3 (tmp6, tmp5, GEN_INT (128 - bits)));
7304 : :
7305 : 9 : rtx tmp7 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp4));
7306 : 9 : rtx tmp8 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp6));
7307 : 9 : rtx tmp9 = gen_reg_rtx (V2DImode);
7308 : 9 : emit_insn (gen_iorv2di3 (tmp9, tmp7, tmp8));
7309 : :
7310 : 9 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp9));
7311 : 9 : return;
7312 : : }
7313 : :
7314 : 52 : if (TARGET_AVX2 && bits < 32)
7315 : : {
7316 : : /* Six operations. */
7317 : 9 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7318 : 9 : rtx tmp2 = gen_reg_rtx (V4SImode);
7319 : 9 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (bits)));
7320 : :
7321 : 9 : rtx tmp3 = gen_reg_rtx (V1TImode);
7322 : 9 : emit_insn (gen_sse2_lshrv1ti3 (tmp3, op1, GEN_INT (64)));
7323 : :
7324 : 9 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, op1));
7325 : 9 : rtx tmp5 = gen_reg_rtx (V2DImode);
7326 : 9 : emit_insn (gen_lshrv2di3 (tmp5, tmp4, GEN_INT (bits)));
7327 : :
7328 : 9 : rtx tmp6 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp3));
7329 : 9 : rtx tmp7 = gen_reg_rtx (V2DImode);
7330 : 9 : emit_insn (gen_ashlv2di3 (tmp7, tmp6, GEN_INT (64 - bits)));
7331 : :
7332 : 9 : rtx tmp8 = gen_reg_rtx (V2DImode);
7333 : 9 : emit_insn (gen_iorv2di3 (tmp8, tmp5, tmp7));
7334 : :
7335 : 9 : rtx tmp9 = force_reg (V4SImode, gen_lowpart (V4SImode, tmp8));
7336 : 9 : rtx tmp10 = gen_reg_rtx (V4SImode);
7337 : 9 : emit_insn (gen_avx2_pblenddv4si (tmp10, tmp2, tmp9, GEN_INT (7)));
7338 : :
7339 : 9 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp10));
7340 : 9 : return;
7341 : : }
7342 : :
7343 : 43 : if (TARGET_SSE4_1 && bits < 15)
7344 : : {
7345 : : /* Six operations. */
7346 : 4 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7347 : 4 : rtx tmp2 = gen_reg_rtx (V4SImode);
7348 : 4 : emit_insn (gen_ashrv4si3 (tmp2, tmp1, GEN_INT (bits)));
7349 : :
7350 : 4 : rtx tmp3 = gen_reg_rtx (V1TImode);
7351 : 4 : emit_insn (gen_sse2_lshrv1ti3 (tmp3, op1, GEN_INT (64)));
7352 : :
7353 : 4 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, op1));
7354 : 4 : rtx tmp5 = gen_reg_rtx (V2DImode);
7355 : 4 : emit_insn (gen_lshrv2di3 (tmp5, tmp4, GEN_INT (bits)));
7356 : :
7357 : 4 : rtx tmp6 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp3));
7358 : 4 : rtx tmp7 = gen_reg_rtx (V2DImode);
7359 : 4 : emit_insn (gen_ashlv2di3 (tmp7, tmp6, GEN_INT (64 - bits)));
7360 : :
7361 : 4 : rtx tmp8 = gen_reg_rtx (V2DImode);
7362 : 4 : emit_insn (gen_iorv2di3 (tmp8, tmp5, tmp7));
7363 : :
7364 : 4 : rtx tmp9 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp2));
7365 : 4 : rtx tmp10 = force_reg (V8HImode, gen_lowpart (V8HImode, tmp8));
7366 : 4 : rtx tmp11 = gen_reg_rtx (V8HImode);
7367 : 4 : emit_insn (gen_sse4_1_pblendw (tmp11, tmp9, tmp10, GEN_INT (0x3f)));
7368 : :
7369 : 4 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp11));
7370 : 4 : return;
7371 : : }
7372 : :
7373 : 18 : if (bits == 1)
7374 : : {
7375 : : /* Eight operations. */
7376 : 1 : rtx tmp1 = gen_reg_rtx (V1TImode);
7377 : 1 : emit_insn (gen_sse2_lshrv1ti3 (tmp1, op1, GEN_INT (64)));
7378 : :
7379 : 1 : rtx tmp2 = force_reg (V2DImode, gen_lowpart (V2DImode, op1));
7380 : 1 : rtx tmp3 = gen_reg_rtx (V2DImode);
7381 : 1 : emit_insn (gen_lshrv2di3 (tmp3, tmp2, GEN_INT (1)));
7382 : :
7383 : 1 : rtx tmp4 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp1));
7384 : 1 : rtx tmp5 = gen_reg_rtx (V2DImode);
7385 : 1 : emit_insn (gen_ashlv2di3 (tmp5, tmp4, GEN_INT (63)));
7386 : :
7387 : 1 : rtx tmp6 = gen_reg_rtx (V2DImode);
7388 : 1 : emit_insn (gen_iorv2di3 (tmp6, tmp3, tmp5));
7389 : :
7390 : 1 : rtx tmp7 = gen_reg_rtx (V2DImode);
7391 : 1 : emit_insn (gen_lshrv2di3 (tmp7, tmp2, GEN_INT (63)));
7392 : :
7393 : 1 : rtx tmp8 = force_reg (V4SImode, gen_lowpart (V4SImode, tmp7));
7394 : 1 : rtx tmp9 = gen_reg_rtx (V4SImode);
7395 : 1 : emit_insn (gen_sse2_pshufd (tmp9, tmp8, GEN_INT (0xbf)));
7396 : :
7397 : 1 : rtx tmp10 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp9));
7398 : 1 : rtx tmp11 = gen_reg_rtx (V2DImode);
7399 : 1 : emit_insn (gen_ashlv2di3 (tmp11, tmp10, GEN_INT (31)));
7400 : :
7401 : 1 : rtx tmp12 = gen_reg_rtx (V2DImode);
7402 : 1 : emit_insn (gen_iorv2di3 (tmp12, tmp6, tmp11));
7403 : :
7404 : 1 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp12));
7405 : 1 : return;
7406 : : }
7407 : :
7408 : 38 : if (bits > 64)
7409 : : {
7410 : : /* Eight operations. */
7411 : 12 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7412 : 12 : rtx tmp2 = gen_reg_rtx (V4SImode);
7413 : 12 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0xff)));
7414 : :
7415 : 12 : rtx tmp3 = gen_reg_rtx (V4SImode);
7416 : 12 : emit_insn (gen_ashrv4si3 (tmp3, tmp2, GEN_INT (31)));
7417 : :
7418 : 12 : rtx tmp4 = gen_reg_rtx (V1TImode);
7419 : 12 : emit_insn (gen_sse2_lshrv1ti3 (tmp4, op1, GEN_INT (64)));
7420 : :
7421 : 12 : rtx tmp5 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp4));
7422 : 12 : rtx tmp6 = gen_reg_rtx (V2DImode);
7423 : 12 : emit_insn (gen_lshrv2di3 (tmp6, tmp5, GEN_INT (bits - 64)));
7424 : :
7425 : 12 : rtx tmp7 = force_reg (V1TImode, gen_lowpart (V1TImode, tmp3));
7426 : 12 : rtx tmp8 = gen_reg_rtx (V1TImode);
7427 : 12 : emit_insn (gen_sse2_ashlv1ti3 (tmp8, tmp7, GEN_INT (64)));
7428 : :
7429 : 12 : rtx tmp9 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp3));
7430 : 12 : rtx tmp10 = gen_reg_rtx (V2DImode);
7431 : 12 : emit_insn (gen_ashlv2di3 (tmp10, tmp9, GEN_INT (128 - bits)));
7432 : :
7433 : 12 : rtx tmp11 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp8));
7434 : 12 : rtx tmp12 = gen_reg_rtx (V2DImode);
7435 : 12 : emit_insn (gen_iorv2di3 (tmp12, tmp10, tmp11));
7436 : :
7437 : 12 : rtx tmp13 = gen_reg_rtx (V2DImode);
7438 : 12 : emit_insn (gen_iorv2di3 (tmp13, tmp6, tmp12));
7439 : :
7440 : 12 : emit_move_insn (operands[0], gen_lowpart (V1TImode, tmp13));
7441 : : }
7442 : : else
7443 : : {
7444 : : /* Nine operations. */
7445 : 26 : rtx tmp1 = force_reg (V4SImode, gen_lowpart (V4SImode, op1));
7446 : 26 : rtx tmp2 = gen_reg_rtx (V4SImode);
7447 : 26 : emit_insn (gen_sse2_pshufd (tmp2, tmp1, GEN_INT (0xff)));
7448 : :
7449 : 26 : rtx tmp3 = gen_reg_rtx (V4SImode);
7450 : 26 : emit_insn (gen_ashrv4si3 (tmp3, tmp2, GEN_INT (31)));
7451 : :
7452 : 26 : rtx tmp4 = gen_reg_rtx (V1TImode);
7453 : 26 : emit_insn (gen_sse2_lshrv1ti3 (tmp4, op1, GEN_INT (64)));
7454 : :
7455 : 26 : rtx tmp5 = force_reg (V2DImode, gen_lowpart (V2DImode, op1));
7456 : 26 : rtx tmp6 = gen_reg_rtx (V2DImode);
7457 : 26 : emit_insn (gen_lshrv2di3 (tmp6, tmp5, GEN_INT (bits)));
7458 : :
7459 : 26 : rtx tmp7 = force_reg (V2DImode, gen_lowpart (V2DImode, tmp4));
|