Bug Summary

File:build/gcc/config/i386/i386-expand.cc
Warning:line 22363, column 7
Value stored to 'nelt2' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-suse-linux -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name i386-expand.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/15.0.7 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/backward -internal-isystem /usr/lib64/clang/15.0.7/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2023-03-27-141847-20772-1/report-L1IOGH.plist -x c++ /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc
1/* Copyright (C) 1988-2023 Free Software Foundation, Inc.
2
3This file is part of GCC.
4
5GCC is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 3, or (at your option)
8any later version.
9
10GCC is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GCC; see the file COPYING3. If not see
17<http://www.gnu.org/licenses/>. */
18
19#define IN_TARGET_CODE1 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 "tree-vectorizer.h"
70#include "shrink-wrap.h"
71#include "builtins.h"
72#include "rtl-iter.h"
73#include "tree-iterator.h"
74#include "dbgcnt.h"
75#include "case-cfn-macros.h"
76#include "dojump.h"
77#include "fold-const-call.h"
78#include "tree-vrp.h"
79#include "tree-ssanames.h"
80#include "selftest.h"
81#include "selftest-rtl.h"
82#include "print-rtl.h"
83#include "intl.h"
84#include "ifcvt.h"
85#include "symbol-summary.h"
86#include "ipa-prop.h"
87#include "ipa-fnsummary.h"
88#include "wide-int-bitmask.h"
89#include "tree-vector-builder.h"
90#include "debug.h"
91#include "dwarf2out.h"
92#include "i386-options.h"
93#include "i386-builtins.h"
94#include "i386-expand.h"
95#include "asan.h"
96
97/* Split one or more double-mode RTL references into pairs of half-mode
98 references. The RTL can be REG, offsettable MEM, integer constant, or
99 CONST_DOUBLE. "operands" is a pointer to an array of double-mode RTLs to
100 split and "num" is its length. lo_half and hi_half are output arrays
101 that parallel "operands". */
102
103void
104split_double_mode (machine_mode mode, rtx operands[],
105 int num, rtx lo_half[], rtx hi_half[])
106{
107 machine_mode half_mode;
108 unsigned int byte;
109 rtx mem_op = NULL_RTX(rtx) 0;
110 int mem_num = 0;
111
112 switch (mode)
113 {
114 case E_TImode:
115 half_mode = DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode));
116 break;
117 case E_DImode:
118 half_mode = SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode));
119 break;
120 case E_P2HImode:
121 half_mode = HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode));
122 break;
123 case E_P2QImode:
124 half_mode = QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode));
125 break;
126 default:
127 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 127, __FUNCTION__))
;
128 }
129
130 byte = GET_MODE_SIZE (half_mode)((unsigned short) mode_to_bytes (half_mode).coeffs[0]);
131
132 while (num--)
133 {
134 rtx op = operands[num];
135
136 /* simplify_subreg refuse to split volatile memory addresses,
137 but we still have to handle it. */
138 if (MEM_P (op)(((enum rtx_code) (op)->code) == MEM))
139 {
140 if (mem_op && rtx_equal_p (op, mem_op))
141 {
142 lo_half[num] = lo_half[mem_num];
143 hi_half[num] = hi_half[mem_num];
144 }
145 else
146 {
147 mem_op = op;
148 mem_num = num;
149 lo_half[num] = adjust_address (op, half_mode, 0)adjust_address_1 (op, half_mode, 0, 1, 1, 0, 0);
150 hi_half[num] = adjust_address (op, half_mode, byte)adjust_address_1 (op, half_mode, byte, 1, 1, 0, 0);
151 }
152 }
153 else
154 {
155 lo_half[num] = simplify_gen_subreg (half_mode, op,
156 GET_MODE (op)((machine_mode) (op)->mode) == VOIDmode((void) 0, E_VOIDmode)
157 ? mode : GET_MODE (op)((machine_mode) (op)->mode), 0);
158
159 rtx tmp = simplify_gen_subreg (half_mode, op,
160 GET_MODE (op)((machine_mode) (op)->mode) == VOIDmode((void) 0, E_VOIDmode)
161 ? mode : GET_MODE (op)((machine_mode) (op)->mode), byte);
162 /* simplify_gen_subreg will return NULL RTX for the
163 high half of the paradoxical subreg. */
164 hi_half[num] = tmp ? tmp : gen_reg_rtx (half_mode);
165 }
166 }
167}
168
169/* Emit the double word assignment DST = { LO, HI }. */
170
171void
172split_double_concat (machine_mode mode, rtx dst, rtx lo, rtx hi)
173{
174 rtx dlo, dhi;
175 int deleted_move_count = 0;
176 split_double_mode (mode, &dst, 1, &dlo, &dhi);
177 /* Constraints ensure that if both lo and hi are MEMs, then
178 dst has early-clobber and thus addresses of MEMs don't use
179 dlo/dhi registers. Otherwise if at least one of li and hi are MEMs,
180 dlo/dhi are registers. */
181 if (MEM_P (lo)(((enum rtx_code) (lo)->code) == MEM)
182 && rtx_equal_p (dlo, hi)
183 && reg_overlap_mentioned_p (dhi, lo))
184 {
185 /* If dlo is same as hi and lo's address uses dhi register,
186 code below would first emit_move_insn (dhi, hi)
187 and then emit_move_insn (dlo, lo). But the former
188 would invalidate lo's address. Load into dhi first,
189 then swap. */
190 emit_move_insn (dhi, lo);
191 lo = dhi;
192 }
193 else if (MEM_P (hi)(((enum rtx_code) (hi)->code) == MEM)
194 && !MEM_P (lo)(((enum rtx_code) (lo)->code) == MEM)
195 && !rtx_equal_p (dlo, lo)
196 && reg_overlap_mentioned_p (dlo, hi))
197 {
198 /* In this case, code below would first emit_move_insn (dlo, lo)
199 and then emit_move_insn (dhi, hi). But the former would
200 invalidate hi's address. */
201 if (rtx_equal_p (dhi, lo))
202 {
203 /* We can't load into dhi first, so load into dlo
204 first and we'll swap. */
205 emit_move_insn (dlo, hi);
206 hi = dlo;
207 }
208 else
209 {
210 /* Load into dhi first. */
211 emit_move_insn (dhi, hi);
212 hi = dhi;
213 }
214 }
215 if (!rtx_equal_p (dlo, hi))
216 {
217 if (!rtx_equal_p (dlo, lo))
218 emit_move_insn (dlo, lo);
219 else
220 deleted_move_count++;
221 if (!rtx_equal_p (dhi, hi))
222 emit_move_insn (dhi, hi);
223 else
224 deleted_move_count++;
225 }
226 else if (!rtx_equal_p (lo, dhi))
227 {
228 if (!rtx_equal_p (dhi, hi))
229 emit_move_insn (dhi, hi);
230 else
231 deleted_move_count++;
232 if (!rtx_equal_p (dlo, lo))
233 emit_move_insn (dlo, lo);
234 else
235 deleted_move_count++;
236 }
237 else if (mode == TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode)))
238 emit_insn (gen_swapdi (dlo, dhi));
239 else
240 emit_insn (gen_swapsi (dlo, dhi));
241
242 if (deleted_move_count == 2)
243 emit_note (NOTE_INSN_DELETED);
244}
245
246
247/* Generate either "mov $0, reg" or "xor reg, reg", as appropriate
248 for the target. */
249
250void
251ix86_expand_clear (rtx dest)
252{
253 rtx tmp;
254
255 /* We play register width games, which are only valid after reload. */
256 gcc_assert (reload_completed)((void)(!(reload_completed) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 256, __FUNCTION__), 0 : 0))
;
257
258 /* Avoid HImode and its attendant prefix byte. */
259 if (GET_MODE_SIZE (GET_MODE (dest))((unsigned short) mode_to_bytes (((machine_mode) (dest)->mode
)).coeffs[0])
< 4)
260 dest = gen_rtx_REG (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), REGNO (dest)(rhs_regno(dest)));
261 tmp = gen_rtx_SET (dest, const0_rtx)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), (((const_int_rtx[64]))) )
;
262
263 if (!TARGET_USE_MOV0ix86_tune_features[X86_TUNE_USE_MOV0] || optimize_insn_for_size_p ())
264 {
265 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
266 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, tmp, clob))) )
;
267 }
268
269 emit_insn (tmp);
270}
271
272/* Return true if V can be broadcasted from an integer of WIDTH bits
273 which is returned in VAL_BROADCAST. Otherwise, return false. */
274
275static bool
276ix86_broadcast (HOST_WIDE_INTlong v, unsigned int width,
277 HOST_WIDE_INTlong &val_broadcast)
278{
279 wide_int val = wi::uhwi (v, HOST_BITS_PER_WIDE_INT64);
280 val_broadcast = wi::extract_uhwi (val, 0, width);
281 for (unsigned int i = width; i < HOST_BITS_PER_WIDE_INT64; i += width)
282 {
283 HOST_WIDE_INTlong each = wi::extract_uhwi (val, i, width);
284 if (val_broadcast != each)
285 return false;
286 }
287 val_broadcast = sext_hwi (val_broadcast, width);
288 return true;
289}
290
291/* Convert the CONST_WIDE_INT operand OP to broadcast in MODE. */
292
293static rtx
294ix86_convert_const_wide_int_to_broadcast (machine_mode mode, rtx op)
295{
296 /* Don't use integer vector broadcast if we can't move from GPR to SSE
297 register directly. */
298 if (!TARGET_INTER_UNIT_MOVES_TO_VECix86_tune_features[X86_TUNE_INTER_UNIT_MOVES_TO_VEC])
299 return nullptr;
300
301 /* Convert CONST_WIDE_INT to a non-standard SSE constant integer
302 broadcast only if vector broadcast is available. */
303 if (!TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
304 || !CONST_WIDE_INT_P (op)(((enum rtx_code) (op)->code) == CONST_WIDE_INT)
305 || standard_sse_constant_p (op, mode)
306 || (CONST_WIDE_INT_NUNITS (op)((int)__extension__ ({ __typeof ((op)) const _rtx = ((op)); if
(((enum rtx_code) (_rtx)->code) != CONST_WIDE_INT) rtl_check_failed_flag
("CWI_GET_NUM_ELEM", _rtx, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 306, __FUNCTION__); _rtx; })->u2.num_elem)
* HOST_BITS_PER_WIDE_INT64
307 != GET_MODE_BITSIZE (mode)((unsigned short) mode_to_bits (mode).coeffs[0])))
308 return nullptr;
309
310 HOST_WIDE_INTlong val = CONST_WIDE_INT_ELT (op, 0)((op)->u.hwiv.elem[0]);
311 HOST_WIDE_INTlong val_broadcast;
312 scalar_int_mode broadcast_mode;
313 if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
314 && ix86_broadcast (val, GET_MODE_BITSIZE (QImode)((unsigned short) mode_to_bits ((scalar_int_mode ((scalar_int_mode
::from_int) E_QImode))).coeffs[0])
,
315 val_broadcast))
316 broadcast_mode = QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode));
317 else if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
318 && ix86_broadcast (val, GET_MODE_BITSIZE (HImode)((unsigned short) mode_to_bits ((scalar_int_mode ((scalar_int_mode
::from_int) E_HImode))).coeffs[0])
,
319 val_broadcast))
320 broadcast_mode = HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode));
321 else if (ix86_broadcast (val, GET_MODE_BITSIZE (SImode)((unsigned short) mode_to_bits ((scalar_int_mode ((scalar_int_mode
::from_int) E_SImode))).coeffs[0])
,
322 val_broadcast))
323 broadcast_mode = SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode));
324 else if (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
325 && ix86_broadcast (val, GET_MODE_BITSIZE (DImode)((unsigned short) mode_to_bits ((scalar_int_mode ((scalar_int_mode
::from_int) E_DImode))).coeffs[0])
,
326 val_broadcast))
327 broadcast_mode = DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode));
328 else
329 return nullptr;
330
331 /* Check if OP can be broadcasted from VAL. */
332 for (int i = 1; i < CONST_WIDE_INT_NUNITS (op)((int)__extension__ ({ __typeof ((op)) const _rtx = ((op)); if
(((enum rtx_code) (_rtx)->code) != CONST_WIDE_INT) rtl_check_failed_flag
("CWI_GET_NUM_ELEM", _rtx, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 332, __FUNCTION__); _rtx; })->u2.num_elem)
; i++)
333 if (val != CONST_WIDE_INT_ELT (op, i)((op)->u.hwiv.elem[i]))
334 return nullptr;
335
336 unsigned int nunits = (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0])
337 / GET_MODE_SIZE (broadcast_mode)((unsigned short) mode_to_bytes (broadcast_mode).coeffs[0]));
338 machine_mode vector_mode;
339 if (!mode_for_vector (broadcast_mode, nunits).exists (&vector_mode))
340 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 340, __FUNCTION__))
;
341 rtx target = gen_reg_rtx (vector_mode);
342 bool ok = ix86_expand_vector_init_duplicate (false, vector_mode,
343 target,
344 GEN_INT (val_broadcast)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (val_broadcast)));
345 gcc_assert (ok)((void)(!(ok) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 345, __FUNCTION__), 0 : 0))
;
346 target = lowpart_subreg (mode, target, vector_mode);
347 return target;
348}
349
350void
351ix86_expand_move (machine_mode mode, rtx operands[])
352{
353 rtx op0, op1;
354 rtx tmp, addend = NULL_RTX(rtx) 0;
355 enum tls_model model;
356
357 op0 = operands[0];
358 op1 = operands[1];
359
360 /* Avoid complex sets of likely spilled hard registers before reload. */
361 if (!ix86_hardreg_mov_ok (op0, op1))
362 {
363 tmp = gen_reg_rtx (mode);
364 operands[0] = tmp;
365 ix86_expand_move (mode, operands);
366 operands[0] = op0;
367 operands[1] = tmp;
368 op1 = tmp;
369 }
370
371 switch (GET_CODE (op1)((enum rtx_code) (op1)->code))
372 {
373 case CONST:
374 tmp = XEXP (op1, 0)(((op1)->u.fld[0]).rt_rtx);
375
376 if (GET_CODE (tmp)((enum rtx_code) (tmp)->code) != PLUS
377 || GET_CODE (XEXP (tmp, 0))((enum rtx_code) ((((tmp)->u.fld[0]).rt_rtx))->code) != SYMBOL_REF)
378 break;
379
380 op1 = XEXP (tmp, 0)(((tmp)->u.fld[0]).rt_rtx);
381 addend = XEXP (tmp, 1)(((tmp)->u.fld[1]).rt_rtx);
382 /* FALLTHRU */
383
384 case SYMBOL_REF:
385 model = SYMBOL_REF_TLS_MODEL (op1)((enum tls_model) (((__extension__ ({ __typeof ((op1)) const _rtx
= ((op1)); if (((enum rtx_code) (_rtx)->code) != SYMBOL_REF
) rtl_check_failed_flag ("SYMBOL_REF_FLAGS", _rtx, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 385, __FUNCTION__); _rtx; }) ->u2.symbol_ref_flags) >>
3) & 7))
;
386
387 if (model)
388 op1 = legitimize_tls_address (op1, model, true);
389 else if (ix86_force_load_from_GOT_p (op1))
390 {
391 /* Load the external function address via GOT slot to avoid PLT. */
392 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op1),gen_rtx_fmt_Ei_stat ((UNSPEC), (((global_options.x_ix86_pmode
== PMODE_DI ? (scalar_int_mode ((scalar_int_mode::from_int) E_DImode
)) : (scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
))), ((gen_rtvec (1, op1))), (((((global_options.x_ix86_isa_flags
& (1UL << 1)) != 0) ? UNSPEC_GOTPCREL : UNSPEC_GOT
))) )
393 (TARGET_64BITgen_rtx_fmt_Ei_stat ((UNSPEC), (((global_options.x_ix86_pmode
== PMODE_DI ? (scalar_int_mode ((scalar_int_mode::from_int) E_DImode
)) : (scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
))), ((gen_rtvec (1, op1))), (((((global_options.x_ix86_isa_flags
& (1UL << 1)) != 0) ? UNSPEC_GOTPCREL : UNSPEC_GOT
))) )
394 ? UNSPEC_GOTPCRELgen_rtx_fmt_Ei_stat ((UNSPEC), (((global_options.x_ix86_pmode
== PMODE_DI ? (scalar_int_mode ((scalar_int_mode::from_int) E_DImode
)) : (scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
))), ((gen_rtvec (1, op1))), (((((global_options.x_ix86_isa_flags
& (1UL << 1)) != 0) ? UNSPEC_GOTPCREL : UNSPEC_GOT
))) )
395 : UNSPEC_GOT))gen_rtx_fmt_Ei_stat ((UNSPEC), (((global_options.x_ix86_pmode
== PMODE_DI ? (scalar_int_mode ((scalar_int_mode::from_int) E_DImode
)) : (scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
))), ((gen_rtvec (1, op1))), (((((global_options.x_ix86_isa_flags
& (1UL << 1)) != 0) ? UNSPEC_GOTPCREL : UNSPEC_GOT
))) )
;
396 op1 = gen_rtx_CONST (Pmode, op1)gen_rtx_fmt_e_stat ((CONST), (((global_options.x_ix86_pmode ==
PMODE_DI ? (scalar_int_mode ((scalar_int_mode::from_int) E_DImode
)) : (scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
))), ((op1)) )
;
397 op1 = gen_const_mem (Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
, op1);
398 set_mem_alias_set (op1, ix86_GOT_alias_set ());
399 }
400 else
401 {
402 tmp = legitimize_pe_coff_symbol (op1, addend != NULL_RTX(rtx) 0);
403 if (tmp)
404 {
405 op1 = tmp;
406 if (!addend)
407 break;
408 }
409 else
410 {
411 op1 = operands[1];
412 break;
413 }
414 }
415
416 if (addend)
417 {
418 op1 = force_operand (op1, NULL_RTX(rtx) 0);
419 op1 = expand_simple_binop (Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
, PLUS, op1, addend,
420 op0, 1, OPTAB_DIRECT);
421 }
422 else
423 op1 = force_operand (op1, op0);
424
425 if (op1 == op0)
426 return;
427
428 op1 = convert_to_mode (mode, op1, 1);
429
430 default:
431 break;
432 }
433
434 if ((flag_picglobal_options.x_flag_pic || MACHOPIC_INDIRECT0)
435 && symbolic_operand (op1, mode))
436 {
437 if (TARGET_MACHO0 && !TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
)
438 {
439#if TARGET_MACHO0
440 /* dynamic-no-pic */
441 if (MACHOPIC_INDIRECT0)
442 {
443 rtx temp = (op0 && REG_P (op0)(((enum rtx_code) (op0)->code) == REG) && mode == Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
)
444 ? op0 : gen_reg_rtx (Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
);
445 op1 = machopic_indirect_data_reference (op1, temp);
446 if (MACHOPIC_PURE0)
447 op1 = machopic_legitimize_pic_address (op1, mode,
448 temp == op1 ? 0 : temp);
449 }
450 if (op0 != op1 && GET_CODE (op0)((enum rtx_code) (op0)->code) != MEM)
451 {
452 rtx insn = gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
;
453 emit_insn (insn);
454 return;
455 }
456 if (GET_CODE (op0)((enum rtx_code) (op0)->code) == MEM)
457 op1 = force_reg (Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
, op1);
458 else
459 {
460 rtx temp = op0;
461 if (GET_CODE (temp)((enum rtx_code) (temp)->code) != REG)
462 temp = gen_reg_rtx (Pmode(global_options.x_ix86_pmode == PMODE_DI ? (scalar_int_mode (
(scalar_int_mode::from_int) E_DImode)) : (scalar_int_mode ((scalar_int_mode
::from_int) E_SImode)))
);
463 temp = legitimize_pic_address (op1, temp);
464 if (temp == op0)
465 return;
466 op1 = temp;
467 }
468 /* dynamic-no-pic */
469#endif
470 }
471 else
472 {
473 if (MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM))
474 op1 = force_reg (mode, op1);
475 else if (!(TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
&& x86_64_movabs_operand (op1, DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)))))
476 {
477 rtx reg = can_create_pseudo_p ()(!reload_in_progress && !reload_completed) ? NULL_RTX(rtx) 0 : op0;
478 op1 = legitimize_pic_address (op1, reg);
479 if (op0 == op1)
480 return;
481 op1 = convert_to_mode (mode, op1, 1);
482 }
483 }
484 }
485 else
486 {
487 if (MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM)
488 && (PUSH_ROUNDING (GET_MODE_SIZE (mode))ix86_push_rounding (((unsigned short) mode_to_bytes (mode).coeffs
[0]))
!= GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0])
489 || !push_operand (op0, mode))
490 && MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM))
491 op1 = force_reg (mode, op1);
492
493 if (push_operand (op0, mode)
494 && ! general_no_elim_operand (op1, mode))
495 op1 = copy_to_mode_reg (mode, op1);
496
497 /* Force large constants in 64bit compilation into register
498 to get them CSEed. */
499 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed)
500 && (mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))) && TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
501 && immediate_operand (op1, mode)
502 && !x86_64_zext_immediate_operand (op1, VOIDmode((void) 0, E_VOIDmode))
503 && !register_operand (op0, mode)
504 && optimizeglobal_options.x_optimize)
505 op1 = copy_to_mode_reg (mode, op1);
506
507 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed))
508 {
509 if (CONST_DOUBLE_P (op1)(((enum rtx_code) (op1)->code) == CONST_DOUBLE))
510 {
511 /* If we are loading a floating point constant to a
512 register, force the value to memory now, since we'll
513 get better code out the back end. */
514
515 op1 = validize_mem (force_const_mem (mode, op1));
516 if (!register_operand (op0, mode))
517 {
518 rtx temp = gen_reg_rtx (mode);
519 emit_insn (gen_rtx_SET (temp, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((temp)
), ((op1)) )
);
520 emit_move_insn (op0, temp);
521 return;
522 }
523 }
524 else if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) >= 16)
525 {
526 rtx tmp = ix86_convert_const_wide_int_to_broadcast
527 (GET_MODE (op0)((machine_mode) (op0)->mode), op1);
528 if (tmp != nullptr)
529 op1 = tmp;
530 }
531 }
532 }
533
534 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
535}
536
537/* OP is a memref of CONST_VECTOR, return scalar constant mem
538 if CONST_VECTOR is a vec_duplicate, else return NULL. */
539static rtx
540ix86_broadcast_from_constant (machine_mode mode, rtx op)
541{
542 int nunits = GET_MODE_NUNITS (mode)(mode_to_nunits (mode).coeffs[0]);
543 if (nunits < 2)
544 return nullptr;
545
546 /* Don't use integer vector broadcast if we can't move from GPR to SSE
547 register directly. */
548 if (!TARGET_INTER_UNIT_MOVES_TO_VECix86_tune_features[X86_TUNE_INTER_UNIT_MOVES_TO_VEC]
549 && INTEGRAL_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_INT || ((enum mode_class
) mode_class[mode]) == MODE_PARTIAL_INT || ((enum mode_class)
mode_class[mode]) == MODE_COMPLEX_INT || ((enum mode_class) mode_class
[mode]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[
mode]) == MODE_VECTOR_INT)
)
550 return nullptr;
551
552 /* Convert CONST_VECTOR to a non-standard SSE constant integer
553 broadcast only if vector broadcast is available. */
554 if (!(TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
555 || (TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
556 && (GET_MODE_INNER (mode)(mode_to_inner (mode)) == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
557 || GET_MODE_INNER (mode)(mode_to_inner (mode)) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))))
558 || FLOAT_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_DECIMAL_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_COMPLEX_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT)
)
559 || standard_sse_constant_p (op, mode))
560 return nullptr;
561
562 /* Don't broadcast from a 64-bit integer constant in 32-bit mode.
563 We can still put 64-bit integer constant in memory when
564 avx512 embed broadcast is available. */
565 if (GET_MODE_INNER (mode)(mode_to_inner (mode)) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)) && !TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
566 && (!TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
567 || (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) < 64 && !TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)))
568 return nullptr;
569
570 if (GET_MODE_INNER (mode)(mode_to_inner (mode)) == TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode)))
571 return nullptr;
572
573 rtx constant = get_pool_constant (XEXP (op, 0)(((op)->u.fld[0]).rt_rtx));
574 if (GET_CODE (constant)((enum rtx_code) (constant)->code) != CONST_VECTOR)
575 return nullptr;
576
577 /* There could be some rtx like
578 (mem/u/c:V16QI (symbol_ref/u:DI ("*.LC1")))
579 but with "*.LC1" refer to V2DI constant vector. */
580 if (GET_MODE (constant)((machine_mode) (constant)->mode) != mode)
581 {
582 constant = simplify_subreg (mode, constant, GET_MODE (constant)((machine_mode) (constant)->mode),
583 0);
584 if (constant == nullptr || GET_CODE (constant)((enum rtx_code) (constant)->code) != CONST_VECTOR)
585 return nullptr;
586 }
587
588 rtx first = XVECEXP (constant, 0, 0)(((((constant)->u.fld[0]).rt_rtvec))->elem[0]);
589
590 for (int i = 1; i < nunits; ++i)
591 {
592 rtx tmp = XVECEXP (constant, 0, i)(((((constant)->u.fld[0]).rt_rtvec))->elem[i]);
593 /* Vector duplicate value. */
594 if (!rtx_equal_p (tmp, first))
595 return nullptr;
596 }
597
598 return first;
599}
600
601void
602ix86_expand_vector_move (machine_mode mode, rtx operands[])
603{
604 rtx op0 = operands[0], op1 = operands[1];
605 /* Use GET_MODE_BITSIZE instead of GET_MODE_ALIGNMENT for IA MCU
606 psABI since the biggest alignment is 4 byte for IA MCU psABI. */
607 unsigned int align = (TARGET_IAMCU((global_options.x_target_flags & (1U << 12)) != 0)
608 ? GET_MODE_BITSIZE (mode)((unsigned short) mode_to_bits (mode).coeffs[0])
609 : GET_MODE_ALIGNMENT (mode)get_mode_alignment (mode));
610
611 if (push_operand (op0, VOIDmode((void) 0, E_VOIDmode)))
612 op0 = emit_move_resolve_push (mode, op0);
613
614 /* Force constants other than zero into memory. We do not know how
615 the instructions used to build constants modify the upper 64 bits
616 of the register, once we have that information we may be able
617 to handle some of them more efficiently. */
618 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed)
619 && (CONSTANT_P (op1)((rtx_class[(int) (((enum rtx_code) (op1)->code))]) == RTX_CONST_OBJ
)
620 || (SUBREG_P (op1)(((enum rtx_code) (op1)->code) == SUBREG)
621 && CONSTANT_P (SUBREG_REG (op1))((rtx_class[(int) (((enum rtx_code) ((((op1)->u.fld[0]).rt_rtx
))->code))]) == RTX_CONST_OBJ)
))
622 && ((register_operand (op0, mode)
623 && !standard_sse_constant_p (op1, mode))
624 /* ix86_expand_vector_move_misalign() does not like constants. */
625 || (SSE_REG_MODE_P (mode)((mode) == ((void) 0, E_V1TImode) || (mode) == (scalar_int_mode
((scalar_int_mode::from_int) E_TImode)) || (mode) == ((void)
0, E_V16QImode) || (mode) == (scalar_float_mode ((scalar_float_mode
::from_int) E_TFmode)) || (mode) == ((void) 0, E_V8HImode) ||
(mode) == ((void) 0, E_V2DFmode) || (mode) == ((void) 0, E_V2DImode
) || (mode) == ((void) 0, E_V4SFmode) || (mode) == ((void) 0,
E_V4SImode) || (mode) == ((void) 0, E_V32QImode) || (mode) ==
((void) 0, E_V16HImode) || (mode) == ((void) 0, E_V8SImode) ||
(mode) == ((void) 0, E_V4DImode) || (mode) == ((void) 0, E_V8SFmode
) || (mode) == ((void) 0, E_V4DFmode) || (mode) == ((void) 0,
E_V2TImode) || (mode) == ((void) 0, E_V8DImode) || (mode) ==
((void) 0, E_V64QImode) || (mode) == ((void) 0, E_V16SImode)
|| (mode) == ((void) 0, E_V32HImode) || (mode) == ((void) 0,
E_V8DFmode) || (mode) == ((void) 0, E_V16SFmode) || (mode) ==
((void) 0, E_V32HFmode) || (mode) == ((void) 0, E_V16HFmode)
|| (mode) == ((void) 0, E_V8HFmode) || (mode) == ((void) 0, E_V32BFmode
) || (mode) == ((void) 0, E_V16BFmode) || (mode) == ((void) 0
, E_V8BFmode))
626 && MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM)
627 && MEM_ALIGN (op0)(get_mem_attrs (op0)->align) < align)))
628 {
629 if (SUBREG_P (op1)(((enum rtx_code) (op1)->code) == SUBREG))
630 {
631 machine_mode imode = GET_MODE (SUBREG_REG (op1))((machine_mode) ((((op1)->u.fld[0]).rt_rtx))->mode);
632 rtx r = force_const_mem (imode, SUBREG_REG (op1)(((op1)->u.fld[0]).rt_rtx));
633 if (r)
634 r = validize_mem (r);
635 else
636 r = force_reg (imode, SUBREG_REG (op1)(((op1)->u.fld[0]).rt_rtx));
637 op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1)(((op1)->u.fld[1]).rt_subreg));
638 }
639 else
640 {
641 machine_mode mode = GET_MODE (op0)((machine_mode) (op0)->mode);
642 rtx tmp = ix86_convert_const_wide_int_to_broadcast
643 (mode, op1);
644 if (tmp == nullptr)
645 op1 = validize_mem (force_const_mem (mode, op1));
646 else
647 op1 = tmp;
648 }
649 }
650
651 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed)
652 && GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) >= 16
653 && VECTOR_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_VECTOR_BOOL || (
(enum mode_class) mode_class[mode]) == MODE_VECTOR_INT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FRACT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_UFRACT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_ACCUM || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_UACCUM)
654 && (MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM)
655 && SYMBOL_REF_P (XEXP (op1, 0))(((enum rtx_code) ((((op1)->u.fld[0]).rt_rtx))->code) ==
SYMBOL_REF)
656 && CONSTANT_POOL_ADDRESS_P (XEXP (op1, 0))(__extension__ ({ __typeof (((((op1)->u.fld[0]).rt_rtx))) const
_rtx = (((((op1)->u.fld[0]).rt_rtx))); if (((enum rtx_code
) (_rtx)->code) != SYMBOL_REF) rtl_check_failed_flag ("CONSTANT_POOL_ADDRESS_P"
, _rtx, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 656, __FUNCTION__); _rtx; })->unchanging)
))
657 {
658 rtx first = ix86_broadcast_from_constant (mode, op1);
659 if (first != nullptr)
660 {
661 /* Broadcast to XMM/YMM/ZMM register from an integer
662 constant or scalar mem. */
663 op1 = gen_reg_rtx (mode);
664 if (FLOAT_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_DECIMAL_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_COMPLEX_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT)
665 || (!TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
&& GET_MODE_INNER (mode)(mode_to_inner (mode)) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))))
666 first = force_const_mem (GET_MODE_INNER (mode)(mode_to_inner (mode)), first);
667 bool ok = ix86_expand_vector_init_duplicate (false, mode,
668 op1, first);
669 gcc_assert (ok)((void)(!(ok) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 669, __FUNCTION__), 0 : 0))
;
670 emit_move_insn (op0, op1);
671 return;
672 }
673 }
674
675 /* We need to check memory alignment for SSE mode since attribute
676 can make operands unaligned. */
677 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed)
678 && SSE_REG_MODE_P (mode)((mode) == ((void) 0, E_V1TImode) || (mode) == (scalar_int_mode
((scalar_int_mode::from_int) E_TImode)) || (mode) == ((void)
0, E_V16QImode) || (mode) == (scalar_float_mode ((scalar_float_mode
::from_int) E_TFmode)) || (mode) == ((void) 0, E_V8HImode) ||
(mode) == ((void) 0, E_V2DFmode) || (mode) == ((void) 0, E_V2DImode
) || (mode) == ((void) 0, E_V4SFmode) || (mode) == ((void) 0,
E_V4SImode) || (mode) == ((void) 0, E_V32QImode) || (mode) ==
((void) 0, E_V16HImode) || (mode) == ((void) 0, E_V8SImode) ||
(mode) == ((void) 0, E_V4DImode) || (mode) == ((void) 0, E_V8SFmode
) || (mode) == ((void) 0, E_V4DFmode) || (mode) == ((void) 0,
E_V2TImode) || (mode) == ((void) 0, E_V8DImode) || (mode) ==
((void) 0, E_V64QImode) || (mode) == ((void) 0, E_V16SImode)
|| (mode) == ((void) 0, E_V32HImode) || (mode) == ((void) 0,
E_V8DFmode) || (mode) == ((void) 0, E_V16SFmode) || (mode) ==
((void) 0, E_V32HFmode) || (mode) == ((void) 0, E_V16HFmode)
|| (mode) == ((void) 0, E_V8HFmode) || (mode) == ((void) 0, E_V32BFmode
) || (mode) == ((void) 0, E_V16BFmode) || (mode) == ((void) 0
, E_V8BFmode))
679 && ((MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM) && (MEM_ALIGN (op0)(get_mem_attrs (op0)->align) < align))
680 || (MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM) && (MEM_ALIGN (op1)(get_mem_attrs (op1)->align) < align))))
681 {
682 rtx tmp[2];
683
684 /* ix86_expand_vector_move_misalign() does not like both
685 arguments in memory. */
686 if (!register_operand (op0, mode)
687 && !register_operand (op1, mode))
688 {
689 rtx scratch = gen_reg_rtx (mode);
690 emit_move_insn (scratch, op1);
691 op1 = scratch;
692 }
693
694 tmp[0] = op0; tmp[1] = op1;
695 ix86_expand_vector_move_misalign (mode, tmp);
696 return;
697 }
698
699 /* Special case TImode to V1TImode conversions, via V2DI. */
700 if (mode == V1TImode((void) 0, E_V1TImode)
701 && SUBREG_P (op1)(((enum rtx_code) (op1)->code) == SUBREG)
702 && GET_MODE (SUBREG_REG (op1))((machine_mode) ((((op1)->u.fld[0]).rt_rtx))->mode) == TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode))
703 && TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
&& TARGET_SSE((global_options.x_ix86_isa_flags & (1UL << 50)) !=
0)
704 && can_create_pseudo_p ()(!reload_in_progress && !reload_completed))
705 {
706 rtx tmp = gen_reg_rtx (V2DImode((void) 0, E_V2DImode));
707 rtx lo = gen_reg_rtx (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)));
708 rtx hi = gen_reg_rtx (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)));
709 emit_move_insn (lo, gen_lowpartrtl_hooks.gen_lowpart (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)), SUBREG_REG (op1)(((op1)->u.fld[0]).rt_rtx)));
710 emit_move_insn (hi, gen_highpart (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)), SUBREG_REG (op1)(((op1)->u.fld[0]).rt_rtx)));
711 emit_insn (gen_vec_concatv2di (tmp, lo, hi));
712 emit_move_insn (op0, gen_lowpartrtl_hooks.gen_lowpart (V1TImode((void) 0, E_V1TImode), tmp));
713 return;
714 }
715
716 /* If operand0 is a hard register, make operand1 a pseudo. */
717 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed)
718 && !ix86_hardreg_mov_ok (op0, op1))
719 {
720 rtx tmp = gen_reg_rtx (GET_MODE (op0)((machine_mode) (op0)->mode));
721 emit_move_insn (tmp, op1);
722 emit_move_insn (op0, tmp);
723 return;
724 }
725
726 /* Make operand1 a register if it isn't already. */
727 if (can_create_pseudo_p ()(!reload_in_progress && !reload_completed)
728 && !register_operand (op0, mode)
729 && !register_operand (op1, mode))
730 {
731 rtx tmp = gen_reg_rtx (GET_MODE (op0)((machine_mode) (op0)->mode));
732 emit_move_insn (tmp, op1);
733 emit_move_insn (op0, tmp);
734 return;
735 }
736
737 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
738}
739
740/* Split 32-byte AVX unaligned load and store if needed. */
741
742static void
743ix86_avx256_split_vector_move_misalign (rtx op0, rtx op1)
744{
745 rtx m;
746 rtx (*extract) (rtx, rtx, rtx);
747 machine_mode mode;
748
749 if ((MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM) && !TARGET_AVX256_SPLIT_UNALIGNED_LOAD((global_options.x_target_flags & (1U << 6)) != 0))
750 || (MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM) && !TARGET_AVX256_SPLIT_UNALIGNED_STORE((global_options.x_target_flags & (1U << 7)) != 0)))
751 {
752 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
753 return;
754 }
755
756 rtx orig_op0 = NULL_RTX(rtx) 0;
757 mode = GET_MODE (op0)((machine_mode) (op0)->mode);
758 switch (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]))
759 {
760 case MODE_VECTOR_INT:
761 case MODE_INT:
762 if (mode != V32QImode((void) 0, E_V32QImode))
763 {
764 if (!MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM))
765 {
766 orig_op0 = op0;
767 op0 = gen_reg_rtx (V32QImode((void) 0, E_V32QImode));
768 }
769 else
770 op0 = gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), op0);
771 op1 = gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), op1);
772 mode = V32QImode((void) 0, E_V32QImode);
773 }
774 break;
775 case MODE_VECTOR_FLOAT:
776 break;
777 default:
778 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 778, __FUNCTION__))
;
779 }
780
781 switch (mode)
782 {
783 default:
784 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 784, __FUNCTION__))
;
785 case E_V32QImode:
786 extract = gen_avx_vextractf128v32qi;
787 mode = V16QImode((void) 0, E_V16QImode);
788 break;
789 case E_V16BFmode:
790 extract = gen_avx_vextractf128v16bf;
791 mode = V8BFmode((void) 0, E_V8BFmode);
792 break;
793 case E_V16HFmode:
794 extract = gen_avx_vextractf128v16hf;
795 mode = V8HFmode((void) 0, E_V8HFmode);
796 break;
797 case E_V8SFmode:
798 extract = gen_avx_vextractf128v8sf;
799 mode = V4SFmode((void) 0, E_V4SFmode);
800 break;
801 case E_V4DFmode:
802 extract = gen_avx_vextractf128v4df;
803 mode = V2DFmode((void) 0, E_V2DFmode);
804 break;
805 }
806
807 if (MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM))
808 {
809 rtx r = gen_reg_rtx (mode);
810 m = adjust_address (op1, mode, 0)adjust_address_1 (op1, mode, 0, 1, 1, 0, 0);
811 emit_move_insn (r, m);
812 m = adjust_address (op1, mode, 16)adjust_address_1 (op1, mode, 16, 1, 1, 0, 0);
813 r = gen_rtx_VEC_CONCAT (GET_MODE (op0), r, m)gen_rtx_fmt_ee_stat ((VEC_CONCAT), ((((machine_mode) (op0)->
mode))), ((r)), ((m)) )
;
814 emit_move_insn (op0, r);
815 }
816 else if (MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM))
817 {
818 m = adjust_address (op0, mode, 0)adjust_address_1 (op0, mode, 0, 1, 1, 0, 0);
819 emit_insn (extract (m, op1, const0_rtx(const_int_rtx[64])));
820 m = adjust_address (op0, mode, 16)adjust_address_1 (op0, mode, 16, 1, 1, 0, 0);
821 emit_insn (extract (m, copy_rtx (op1), const1_rtx(const_int_rtx[64 +1])));
822 }
823 else
824 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 824, __FUNCTION__))
;
825
826 if (orig_op0)
827 emit_move_insn (orig_op0, gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (orig_op0)((machine_mode) (orig_op0)->mode), op0));
828}
829
830/* Implement the movmisalign patterns for SSE. Non-SSE modes go
831 straight to ix86_expand_vector_move. */
832/* Code generation for scalar reg-reg moves of single and double precision data:
833 if (x86_sse_partial_reg_dependency == true | x86_sse_split_regs == true)
834 movaps reg, reg
835 else
836 movss reg, reg
837 if (x86_sse_partial_reg_dependency == true)
838 movapd reg, reg
839 else
840 movsd reg, reg
841
842 Code generation for scalar loads of double precision data:
843 if (x86_sse_split_regs == true)
844 movlpd mem, reg (gas syntax)
845 else
846 movsd mem, reg
847
848 Code generation for unaligned packed loads of single precision data
849 (x86_sse_unaligned_move_optimal overrides x86_sse_partial_reg_dependency):
850 if (x86_sse_unaligned_move_optimal)
851 movups mem, reg
852
853 if (x86_sse_partial_reg_dependency == true)
854 {
855 xorps reg, reg
856 movlps mem, reg
857 movhps mem+8, reg
858 }
859 else
860 {
861 movlps mem, reg
862 movhps mem+8, reg
863 }
864
865 Code generation for unaligned packed loads of double precision data
866 (x86_sse_unaligned_move_optimal overrides x86_sse_split_regs):
867 if (x86_sse_unaligned_move_optimal)
868 movupd mem, reg
869
870 if (x86_sse_split_regs == true)
871 {
872 movlpd mem, reg
873 movhpd mem+8, reg
874 }
875 else
876 {
877 movsd mem, reg
878 movhpd mem+8, reg
879 }
880 */
881
882void
883ix86_expand_vector_move_misalign (machine_mode mode, rtx operands[])
884{
885 rtx op0, op1, m;
886
887 op0 = operands[0];
888 op1 = operands[1];
889
890 /* Use unaligned load/store for AVX512 or when optimizing for size. */
891 if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) == 64 || optimize_insn_for_size_p ())
892 {
893 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
894 return;
895 }
896
897 if (TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
)
898 {
899 if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) == 32)
900 ix86_avx256_split_vector_move_misalign (op0, op1);
901 else
902 /* Always use 128-bit mov<mode>_internal pattern for AVX. */
903 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
904 return;
905 }
906
907 if (TARGET_SSE_UNALIGNED_LOAD_OPTIMALix86_tune_features[X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL]
908 || TARGET_SSE_PACKED_SINGLE_INSN_OPTIMALix86_tune_features[X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL])
909 {
910 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
911 return;
912 }
913
914 /* ??? If we have typed data, then it would appear that using
915 movdqu is the only way to get unaligned data loaded with
916 integer type. */
917 if (TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
&& GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_VECTOR_INT)
918 {
919 emit_insn (gen_rtx_SET (op0, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((op0))
, ((op1)) )
);
920 return;
921 }
922
923 if (MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM))
924 {
925 if (TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
&& mode == V2DFmode((void) 0, E_V2DFmode))
926 {
927 rtx zero;
928
929 /* When SSE registers are split into halves, we can avoid
930 writing to the top half twice. */
931 if (TARGET_SSE_SPLIT_REGSix86_tune_features[X86_TUNE_SSE_SPLIT_REGS])
932 {
933 emit_clobber (op0);
934 zero = op0;
935 }
936 else
937 {
938 /* ??? Not sure about the best option for the Intel chips.
939 The following would seem to satisfy; the register is
940 entirely cleared, breaking the dependency chain. We
941 then store to the upper half, with a dependency depth
942 of one. A rumor has it that Intel recommends two movsd
943 followed by an unpacklpd, but this is unconfirmed. And
944 given that the dependency depth of the unpacklpd would
945 still be one, I'm not sure why this would be better. */
946 zero = CONST0_RTX (V2DFmode)(const_tiny_rtx[0][(int) (((void) 0, E_V2DFmode))]);
947 }
948
949 m = adjust_address (op1, DFmode, 0)adjust_address_1 (op1, (scalar_float_mode ((scalar_float_mode
::from_int) E_DFmode)), 0, 1, 1, 0, 0)
;
950 emit_insn (gen_sse2_loadlpd (op0, zero, m));
951 m = adjust_address (op1, DFmode, 8)adjust_address_1 (op1, (scalar_float_mode ((scalar_float_mode
::from_int) E_DFmode)), 8, 1, 1, 0, 0)
;
952 emit_insn (gen_sse2_loadhpd (op0, op0, m));
953 }
954 else
955 {
956 rtx t;
957
958 if (mode != V4SFmode((void) 0, E_V4SFmode))
959 t = gen_reg_rtx (V4SFmode((void) 0, E_V4SFmode));
960 else
961 t = op0;
962
963 if (TARGET_SSE_PARTIAL_REG_DEPENDENCYix86_tune_features[X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY])
964 emit_move_insn (t, CONST0_RTX (V4SFmode)(const_tiny_rtx[0][(int) (((void) 0, E_V4SFmode))]));
965 else
966 emit_clobber (t);
967
968 m = adjust_address (op1, V2SFmode, 0)adjust_address_1 (op1, ((void) 0, E_V2SFmode), 0, 1, 1, 0, 0);
969 emit_insn (gen_sse_loadlps (t, t, m));
970 m = adjust_address (op1, V2SFmode, 8)adjust_address_1 (op1, ((void) 0, E_V2SFmode), 8, 1, 1, 0, 0);
971 emit_insn (gen_sse_loadhps (t, t, m));
972 if (mode != V4SFmode((void) 0, E_V4SFmode))
973 emit_move_insn (op0, gen_lowpartrtl_hooks.gen_lowpart (mode, t));
974 }
975 }
976 else if (MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM))
977 {
978 if (TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
&& mode == V2DFmode((void) 0, E_V2DFmode))
979 {
980 m = adjust_address (op0, DFmode, 0)adjust_address_1 (op0, (scalar_float_mode ((scalar_float_mode
::from_int) E_DFmode)), 0, 1, 1, 0, 0)
;
981 emit_insn (gen_sse2_storelpd (m, op1));
982 m = adjust_address (op0, DFmode, 8)adjust_address_1 (op0, (scalar_float_mode ((scalar_float_mode
::from_int) E_DFmode)), 8, 1, 1, 0, 0)
;
983 emit_insn (gen_sse2_storehpd (m, op1));
984 }
985 else
986 {
987 if (mode != V4SFmode((void) 0, E_V4SFmode))
988 op1 = gen_lowpartrtl_hooks.gen_lowpart (V4SFmode((void) 0, E_V4SFmode), op1);
989
990 m = adjust_address (op0, V2SFmode, 0)adjust_address_1 (op0, ((void) 0, E_V2SFmode), 0, 1, 1, 0, 0);
991 emit_insn (gen_sse_storelps (m, op1));
992 m = adjust_address (op0, V2SFmode, 8)adjust_address_1 (op0, ((void) 0, E_V2SFmode), 8, 1, 1, 0, 0);
993 emit_insn (gen_sse_storehps (m, copy_rtx (op1)));
994 }
995 }
996 else
997 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 997, __FUNCTION__))
;
998}
999
1000/* Move bits 64:95 to bits 32:63. */
1001
1002void
1003ix86_move_vector_high_sse_to_mmx (rtx op)
1004{
1005 rtx mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (0))))) )
1006 gen_rtvec (4, GEN_INT (0), GEN_INT (2),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (0))))) )
1007 GEN_INT (0), GEN_INT (0)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (0))))) )
;
1008 rtx dest = lowpart_subreg (V4SImode((void) 0, E_V4SImode), op, GET_MODE (op)((machine_mode) (op)->mode));
1009 op = gen_rtx_VEC_SELECT (V4SImode, dest, mask)gen_rtx_fmt_ee_stat ((VEC_SELECT), ((((void) 0, E_V4SImode)))
, ((dest)), ((mask)) )
;
1010 rtx insn = gen_rtx_SET (dest, op)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((op)) )
;
1011 emit_insn (insn);
1012}
1013
1014/* Split MMX pack with signed/unsigned saturation with SSE/SSE2. */
1015
1016void
1017ix86_split_mmx_pack (rtx operands[], enum rtx_code code)
1018{
1019 rtx op0 = operands[0];
1020 rtx op1 = operands[1];
1021 rtx op2 = operands[2];
1022
1023 machine_mode dmode = GET_MODE (op0)((machine_mode) (op0)->mode);
1024 machine_mode smode = GET_MODE (op1)((machine_mode) (op1)->mode);
1025 machine_mode inner_dmode = GET_MODE_INNER (dmode)(mode_to_inner (dmode));
1026 machine_mode inner_smode = GET_MODE_INNER (smode)(mode_to_inner (smode));
1027
1028 /* Get the corresponding SSE mode for destination. */
1029 int nunits = 16 / GET_MODE_SIZE (inner_dmode)((unsigned short) mode_to_bytes (inner_dmode).coeffs[0]);
1030 machine_mode sse_dmode = mode_for_vector (GET_MODE_INNER (dmode)(mode_to_inner (dmode)),
1031 nunits).require ();
1032 machine_mode sse_half_dmode = mode_for_vector (GET_MODE_INNER (dmode)(mode_to_inner (dmode)),
1033 nunits / 2).require ();
1034
1035 /* Get the corresponding SSE mode for source. */
1036 nunits = 16 / GET_MODE_SIZE (inner_smode)((unsigned short) mode_to_bytes (inner_smode).coeffs[0]);
1037 machine_mode sse_smode = mode_for_vector (GET_MODE_INNER (smode)(mode_to_inner (smode)),
1038 nunits).require ();
1039
1040 /* Generate SSE pack with signed/unsigned saturation. */
1041 rtx dest = lowpart_subreg (sse_dmode, op0, GET_MODE (op0)((machine_mode) (op0)->mode));
1042 op1 = lowpart_subreg (sse_smode, op1, GET_MODE (op1)((machine_mode) (op1)->mode));
1043 op2 = lowpart_subreg (sse_smode, op2, GET_MODE (op2)((machine_mode) (op2)->mode));
1044
1045 op1 = gen_rtx_fmt_e (code, sse_half_dmode, op1)gen_rtx_fmt_e_stat ((code), (sse_half_dmode), (op1) );
1046 op2 = gen_rtx_fmt_e (code, sse_half_dmode, op2)gen_rtx_fmt_e_stat ((code), (sse_half_dmode), (op2) );
1047 rtx insn = gen_rtx_SET (dest, gen_rtx_VEC_CONCAT (sse_dmode,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_ee_stat ((VEC_CONCAT), ((sse_dmode)), ((op1)
), ((op2)) ))) )
1048 op1, op2))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_ee_stat ((VEC_CONCAT), ((sse_dmode)), ((op1)
), ((op2)) ))) )
;
1049 emit_insn (insn);
1050
1051 ix86_move_vector_high_sse_to_mmx (op0);
1052}
1053
1054/* Split MMX punpcklXX/punpckhXX with SSE punpcklXX. */
1055
1056void
1057ix86_split_mmx_punpck (rtx operands[], bool high_p)
1058{
1059 rtx op0 = operands[0];
1060 rtx op1 = operands[1];
1061 rtx op2 = operands[2];
1062 machine_mode mode = GET_MODE (op0)((machine_mode) (op0)->mode);
1063 rtx mask;
1064 /* The corresponding SSE mode. */
1065 machine_mode sse_mode, double_sse_mode;
1066
1067 switch (mode)
1068 {
1069 case E_V4QImode:
1070 case E_V8QImode:
1071 sse_mode = V16QImode((void) 0, E_V16QImode);
1072 double_sse_mode = V32QImode((void) 0, E_V32QImode);
1073 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1074 gen_rtvec (16,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1075 GEN_INT (0), GEN_INT (16),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1076 GEN_INT (1), GEN_INT (17),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1077 GEN_INT (2), GEN_INT (18),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1078 GEN_INT (3), GEN_INT (19),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1079 GEN_INT (4), GEN_INT (20),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1080 GEN_INT (5), GEN_INT (21),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1081 GEN_INT (6), GEN_INT (22),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
1082 GEN_INT (7), GEN_INT (23)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (16, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0
)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (17)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (18)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (19)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (4)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (20)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (5)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (21)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (6)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (22)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (7)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (23))))) )
;
1083 break;
1084
1085 case E_V4HImode:
1086 case E_V2HImode:
1087 sse_mode = V8HImode((void) 0, E_V8HImode);
1088 double_sse_mode = V16HImode((void) 0, E_V16HImode);
1089 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (8, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (8)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (9)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode)
, (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (10)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (11))))) )
1090 gen_rtvec (8,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (8, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (8)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (9)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode)
, (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (10)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (11))))) )
1091 GEN_INT (0), GEN_INT (8),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (8, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (8)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (9)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode)
, (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (10)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (11))))) )
1092 GEN_INT (1), GEN_INT (9),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (8, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (8)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (9)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode)
, (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (10)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (11))))) )
1093 GEN_INT (2), GEN_INT (10),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (8, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (8)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (9)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode)
, (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (10)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (11))))) )
1094 GEN_INT (3), GEN_INT (11)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (8, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (8)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (9)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode)
, (2)), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (10)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (11))))) )
;
1095 break;
1096
1097 case E_V2SImode:
1098 sse_mode = V4SImode((void) 0, E_V4SImode);
1099 double_sse_mode = V8SImode((void) 0, E_V8SImode);
1100 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1101 gen_rtvec (4,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1102 GEN_INT (0), GEN_INT (4),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1103 GEN_INT (1), GEN_INT (5)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
;
1104 break;
1105
1106 case E_V2SFmode:
1107 sse_mode = V4SFmode((void) 0, E_V4SFmode);
1108 double_sse_mode = V8SFmode((void) 0, E_V8SFmode);
1109 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1110 gen_rtvec (4,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1111 GEN_INT (0), GEN_INT (4),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1112 GEN_INT (1), GEN_INT (5)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (1)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
;
1113 break;
1114
1115 default:
1116 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1116, __FUNCTION__))
;
1117 }
1118
1119 /* Generate SSE punpcklXX. */
1120 rtx dest = lowpart_subreg (sse_mode, op0, GET_MODE (op0)((machine_mode) (op0)->mode));
1121 op1 = lowpart_subreg (sse_mode, op1, GET_MODE (op1)((machine_mode) (op1)->mode));
1122 op2 = lowpart_subreg (sse_mode, op2, GET_MODE (op2)((machine_mode) (op2)->mode));
1123
1124 op1 = gen_rtx_VEC_CONCAT (double_sse_mode, op1, op2)gen_rtx_fmt_ee_stat ((VEC_CONCAT), ((double_sse_mode)), ((op1
)), ((op2)) )
;
1125 op2 = gen_rtx_VEC_SELECT (sse_mode, op1, mask)gen_rtx_fmt_ee_stat ((VEC_SELECT), ((sse_mode)), ((op1)), ((mask
)) )
;
1126 rtx insn = gen_rtx_SET (dest, op2)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((op2)) )
;
1127 emit_insn (insn);
1128
1129 /* Move high bits to low bits. */
1130 if (high_p)
1131 {
1132 if (sse_mode == V4SFmode((void) 0, E_V4SFmode))
1133 {
1134 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1135 gen_rtvec (4, GEN_INT (2), GEN_INT (3),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
1136 GEN_INT (4), GEN_INT (5)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (4)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (5))))) )
;
1137 op2 = gen_rtx_VEC_CONCAT (V8SFmode, dest, dest)gen_rtx_fmt_ee_stat ((VEC_CONCAT), ((((void) 0, E_V8SFmode)))
, ((dest)), ((dest)) )
;
1138 op1 = gen_rtx_VEC_SELECT (V4SFmode, op2, mask)gen_rtx_fmt_ee_stat ((VEC_SELECT), ((((void) 0, E_V4SFmode)))
, ((op2)), ((mask)) )
;
1139 }
1140 else
1141 {
1142 int sz = GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]);
1143
1144 if (sz == 4)
1145 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (1)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (1))))) )
1146 gen_rtvec (4, GEN_INT (1), GEN_INT (0),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (1)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (1))))) )
1147 GEN_INT (0), GEN_INT (1)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (1)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (1))))) )
;
1148 else if (sz == 8)
1149 mask = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (1))))) )
1150 gen_rtvec (4, GEN_INT (2), GEN_INT (3),gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (1))))) )
1151 GEN_INT (0), GEN_INT (1)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (4, gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2)
), gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)), gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (0)), gen_rtx_CONST_INT (((void) 0,
E_VOIDmode), (1))))) )
;
1152 else
1153 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1153, __FUNCTION__))
;
1154
1155 dest = lowpart_subreg (V4SImode((void) 0, E_V4SImode), dest, GET_MODE (dest)((machine_mode) (dest)->mode));
1156 op1 = gen_rtx_VEC_SELECT (V4SImode, dest, mask)gen_rtx_fmt_ee_stat ((VEC_SELECT), ((((void) 0, E_V4SImode)))
, ((dest)), ((mask)) )
;
1157 }
1158
1159 insn = gen_rtx_SET (dest, op1)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((op1)) )
;
1160 emit_insn (insn);
1161 }
1162}
1163
1164/* Helper function of ix86_fixup_binary_operands to canonicalize
1165 operand order. Returns true if the operands should be swapped. */
1166
1167static bool
1168ix86_swap_binary_operands_p (enum rtx_code code, machine_mode mode,
1169 rtx operands[])
1170{
1171 rtx dst = operands[0];
1172 rtx src1 = operands[1];
1173 rtx src2 = operands[2];
1174
1175 /* If the operation is not commutative, we can't do anything. */
1176 if (GET_RTX_CLASS (code)(rtx_class[(int) (code)]) != RTX_COMM_ARITH
1177 && GET_RTX_CLASS (code)(rtx_class[(int) (code)]) != RTX_COMM_COMPARE)
1178 return false;
1179
1180 /* Highest priority is that src1 should match dst. */
1181 if (rtx_equal_p (dst, src1))
1182 return false;
1183 if (rtx_equal_p (dst, src2))
1184 return true;
1185
1186 /* Next highest priority is that immediate constants come second. */
1187 if (immediate_operand (src2, mode))
1188 return false;
1189 if (immediate_operand (src1, mode))
1190 return true;
1191
1192 /* Lowest priority is that memory references should come second. */
1193 if (MEM_P (src2)(((enum rtx_code) (src2)->code) == MEM))
1194 return false;
1195 if (MEM_P (src1)(((enum rtx_code) (src1)->code) == MEM))
1196 return true;
1197
1198 return false;
1199}
1200
1201
1202/* Fix up OPERANDS to satisfy ix86_binary_operator_ok. Return the
1203 destination to use for the operation. If different from the true
1204 destination in operands[0], a copy operation will be required. */
1205
1206rtx
1207ix86_fixup_binary_operands (enum rtx_code code, machine_mode mode,
1208 rtx operands[])
1209{
1210 rtx dst = operands[0];
1211 rtx src1 = operands[1];
1212 rtx src2 = operands[2];
1213
1214 /* Canonicalize operand order. */
1215 if (ix86_swap_binary_operands_p (code, mode, operands))
1216 {
1217 /* It is invalid to swap operands of different modes. */
1218 gcc_assert (GET_MODE (src1) == GET_MODE (src2))((void)(!(((machine_mode) (src1)->mode) == ((machine_mode)
(src2)->mode)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1218, __FUNCTION__), 0 : 0))
;
1219
1220 std::swap (src1, src2);
1221 }
1222
1223 /* Both source operands cannot be in memory. */
1224 if (MEM_P (src1)(((enum rtx_code) (src1)->code) == MEM) && MEM_P (src2)(((enum rtx_code) (src2)->code) == MEM))
1225 {
1226 /* Optimization: Only read from memory once. */
1227 if (rtx_equal_p (src1, src2))
1228 {
1229 src2 = force_reg (mode, src2);
1230 src1 = src2;
1231 }
1232 else if (rtx_equal_p (dst, src1))
1233 src2 = force_reg (mode, src2);
1234 else
1235 src1 = force_reg (mode, src1);
1236 }
1237
1238 /* If the destination is memory, and we do not have matching source
1239 operands, do things in registers. */
1240 if (MEM_P (dst)(((enum rtx_code) (dst)->code) == MEM) && !rtx_equal_p (dst, src1))
1241 dst = gen_reg_rtx (mode);
1242
1243 /* Source 1 cannot be a constant. */
1244 if (CONSTANT_P (src1)((rtx_class[(int) (((enum rtx_code) (src1)->code))]) == RTX_CONST_OBJ
)
)
1245 src1 = force_reg (mode, src1);
1246
1247 /* Source 1 cannot be a non-matching memory. */
1248 if (MEM_P (src1)(((enum rtx_code) (src1)->code) == MEM) && !rtx_equal_p (dst, src1))
1249 src1 = force_reg (mode, src1);
1250
1251 /* Improve address combine. */
1252 if (code == PLUS
1253 && GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_INT
1254 && MEM_P (src2)(((enum rtx_code) (src2)->code) == MEM))
1255 src2 = force_reg (mode, src2);
1256
1257 operands[1] = src1;
1258 operands[2] = src2;
1259 return dst;
1260}
1261
1262/* Similarly, but assume that the destination has already been
1263 set up properly. */
1264
1265void
1266ix86_fixup_binary_operands_no_copy (enum rtx_code code,
1267 machine_mode mode, rtx operands[])
1268{
1269 rtx dst = ix86_fixup_binary_operands (code, mode, operands);
1270 gcc_assert (dst == operands[0])((void)(!(dst == operands[0]) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1270, __FUNCTION__), 0 : 0))
;
1271}
1272
1273/* Attempt to expand a binary operator. Make the expansion closer to the
1274 actual machine, then just general_operand, which will allow 3 separate
1275 memory references (one output, two input) in a single insn. */
1276
1277void
1278ix86_expand_binary_operator (enum rtx_code code, machine_mode mode,
1279 rtx operands[])
1280{
1281 rtx src1, src2, dst, op, clob;
1282
1283 dst = ix86_fixup_binary_operands (code, mode, operands);
1284 src1 = operands[1];
1285 src2 = operands[2];
1286
1287 /* Emit the instruction. */
1288
1289 op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, mode, src1, src2))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_ee_stat ((code), (mode), (src1), (src2) ))) )
;
1290
1291 if (reload_completed
1292 && code == PLUS
1293 && !rtx_equal_p (dst, src1))
1294 {
1295 /* This is going to be an LEA; avoid splitting it later. */
1296 emit_insn (op);
1297 }
1298 else
1299 {
1300 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
1301 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, op, clob))) )
);
1302 }
1303
1304 /* Fix up the destination if needed. */
1305 if (dst != operands[0])
1306 emit_move_insn (operands[0], dst);
1307}
1308
1309/* Expand vector logical operation CODE (AND, IOR, XOR) in MODE with
1310 the given OPERANDS. */
1311
1312void
1313ix86_expand_vector_logical_operator (enum rtx_code code, machine_mode mode,
1314 rtx operands[])
1315{
1316 rtx op1 = NULL_RTX(rtx) 0, op2 = NULL_RTX(rtx) 0;
1317 if (SUBREG_P (operands[1])(((enum rtx_code) (operands[1])->code) == SUBREG))
1318 {
1319 op1 = operands[1];
1320 op2 = operands[2];
1321 }
1322 else if (SUBREG_P (operands[2])(((enum rtx_code) (operands[2])->code) == SUBREG))
1323 {
1324 op1 = operands[2];
1325 op2 = operands[1];
1326 }
1327 /* Optimize (__m128i) d | (__m128i) e and similar code
1328 when d and e are float vectors into float vector logical
1329 insn. In C/C++ without using intrinsics there is no other way
1330 to express vector logical operation on float vectors than
1331 to cast them temporarily to integer vectors. */
1332 if (op1
1333 && !TARGET_SSE_PACKED_SINGLE_INSN_OPTIMALix86_tune_features[X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL]
1334 && (SUBREG_P (op2)(((enum rtx_code) (op2)->code) == SUBREG) || GET_CODE (op2)((enum rtx_code) (op2)->code) == CONST_VECTOR)
1335 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op1)))((enum mode_class) mode_class[((machine_mode) ((((op1)->u.
fld[0]).rt_rtx))->mode)])
== MODE_VECTOR_FLOAT
1336 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))((unsigned short) mode_to_bytes (((machine_mode) ((((op1)->
u.fld[0]).rt_rtx))->mode)).coeffs[0])
== GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0])
1337 && SUBREG_BYTE (op1)(((op1)->u.fld[1]).rt_subreg) == 0
1338 && (GET_CODE (op2)((enum rtx_code) (op2)->code) == CONST_VECTOR
1339 || (GET_MODE (SUBREG_REG (op1))((machine_mode) ((((op1)->u.fld[0]).rt_rtx))->mode) == GET_MODE (SUBREG_REG (op2))((machine_mode) ((((op2)->u.fld[0]).rt_rtx))->mode)
1340 && SUBREG_BYTE (op2)(((op2)->u.fld[1]).rt_subreg) == 0))
1341 && can_create_pseudo_p ()(!reload_in_progress && !reload_completed))
1342 {
1343 rtx dst;
1344 switch (GET_MODE (SUBREG_REG (op1))((machine_mode) ((((op1)->u.fld[0]).rt_rtx))->mode))
1345 {
1346 case E_V4SFmode:
1347 case E_V8SFmode:
1348 case E_V16SFmode:
1349 case E_V2DFmode:
1350 case E_V4DFmode:
1351 case E_V8DFmode:
1352 dst = gen_reg_rtx (GET_MODE (SUBREG_REG (op1))((machine_mode) ((((op1)->u.fld[0]).rt_rtx))->mode));
1353 if (GET_CODE (op2)((enum rtx_code) (op2)->code) == CONST_VECTOR)
1354 {
1355 op2 = gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (dst)((machine_mode) (dst)->mode), op2);
1356 op2 = force_reg (GET_MODE (dst)((machine_mode) (dst)->mode), op2);
1357 }
1358 else
1359 {
1360 op1 = operands[1];
1361 op2 = SUBREG_REG (operands[2])(((operands[2])->u.fld[0]).rt_rtx);
1362 if (!vector_operand (op2, GET_MODE (dst)((machine_mode) (dst)->mode)))
1363 op2 = force_reg (GET_MODE (dst)((machine_mode) (dst)->mode), op2);
1364 }
1365 op1 = SUBREG_REG (op1)(((op1)->u.fld[0]).rt_rtx);
1366 if (!vector_operand (op1, GET_MODE (dst)((machine_mode) (dst)->mode)))
1367 op1 = force_reg (GET_MODE (dst)((machine_mode) (dst)->mode), op1);
1368 emit_insn (gen_rtx_SET (dst,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_ee_stat ((code), (((machine_mode) (dst)->mode
)), (op1), (op2) ))) )
1369 gen_rtx_fmt_ee (code, GET_MODE (dst),gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_ee_stat ((code), (((machine_mode) (dst)->mode
)), (op1), (op2) ))) )
1370 op1, op2))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_ee_stat ((code), (((machine_mode) (dst)->mode
)), (op1), (op2) ))) )
);
1371 emit_move_insn (operands[0], gen_lowpartrtl_hooks.gen_lowpart (mode, dst));
1372 return;
1373 default:
1374 break;
1375 }
1376 }
1377 if (!vector_operand (operands[1], mode))
1378 operands[1] = force_reg (mode, operands[1]);
1379 if (!vector_operand (operands[2], mode))
1380 operands[2] = force_reg (mode, operands[2]);
1381 ix86_fixup_binary_operands_no_copy (code, mode, operands);
1382 emit_insn (gen_rtx_SET (operands[0],gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_ee_stat ((code), (mode), (operands[1]), (
operands[2]) ))) )
1383 gen_rtx_fmt_ee (code, mode, operands[1],gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_ee_stat ((code), (mode), (operands[1]), (
operands[2]) ))) )
1384 operands[2]))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_ee_stat ((code), (mode), (operands[1]), (
operands[2]) ))) )
);
1385}
1386
1387/* Return TRUE or FALSE depending on whether the binary operator meets the
1388 appropriate constraints. */
1389
1390bool
1391ix86_binary_operator_ok (enum rtx_code code, machine_mode mode,
1392 rtx operands[3])
1393{
1394 rtx dst = operands[0];
1395 rtx src1 = operands[1];
1396 rtx src2 = operands[2];
1397
1398 /* Both source operands cannot be in memory. */
1399 if ((MEM_P (src1)(((enum rtx_code) (src1)->code) == MEM) || bcst_mem_operand (src1, mode))
1400 && (MEM_P (src2)(((enum rtx_code) (src2)->code) == MEM) || bcst_mem_operand (src2, mode)))
1401 return false;
1402
1403 /* Canonicalize operand order for commutative operators. */
1404 if (ix86_swap_binary_operands_p (code, mode, operands))
1405 std::swap (src1, src2);
1406
1407 /* If the destination is memory, we must have a matching source operand. */
1408 if (MEM_P (dst)(((enum rtx_code) (dst)->code) == MEM) && !rtx_equal_p (dst, src1))
1409 return false;
1410
1411 /* Source 1 cannot be a constant. */
1412 if (CONSTANT_P (src1)((rtx_class[(int) (((enum rtx_code) (src1)->code))]) == RTX_CONST_OBJ
)
)
1413 return false;
1414
1415 /* Source 1 cannot be a non-matching memory. */
1416 if (MEM_P (src1)(((enum rtx_code) (src1)->code) == MEM) && !rtx_equal_p (dst, src1))
1417 /* Support "andhi/andsi/anddi" as a zero-extending move. */
1418 return (code == AND
1419 && (mode == HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode))
1420 || mode == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
1421 || (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
&& mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))))
1422 && satisfies_constraint_L (src2));
1423
1424 return true;
1425}
1426
1427/* Attempt to expand a unary operator. Make the expansion closer to the
1428 actual machine, then just general_operand, which will allow 2 separate
1429 memory references (one output, one input) in a single insn. */
1430
1431void
1432ix86_expand_unary_operator (enum rtx_code code, machine_mode mode,
1433 rtx operands[])
1434{
1435 bool matching_memory = false;
1436 rtx src, dst, op, clob;
1437
1438 dst = operands[0];
1439 src = operands[1];
1440
1441 /* If the destination is memory, and we do not have matching source
1442 operands, do things in registers. */
1443 if (MEM_P (dst)(((enum rtx_code) (dst)->code) == MEM))
1444 {
1445 if (rtx_equal_p (dst, src))
1446 matching_memory = true;
1447 else
1448 dst = gen_reg_rtx (mode);
1449 }
1450
1451 /* When source operand is memory, destination must match. */
1452 if (MEM_P (src)(((enum rtx_code) (src)->code) == MEM) && !matching_memory)
1453 src = force_reg (mode, src);
1454
1455 /* Emit the instruction. */
1456
1457 op = gen_rtx_SET (dst, gen_rtx_fmt_e (code, mode, src))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_e_stat ((code), (mode), (src) ))) )
;
1458
1459 if (code == NOT)
1460 emit_insn (op);
1461 else
1462 {
1463 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
1464 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, op, clob))) )
);
1465 }
1466
1467 /* Fix up the destination if needed. */
1468 if (dst != operands[0])
1469 emit_move_insn (operands[0], dst);
1470}
1471
1472/* Predict just emitted jump instruction to be taken with probability PROB. */
1473
1474static void
1475predict_jump (int prob)
1476{
1477 rtx_insn *insn = get_last_insn ();
1478 gcc_assert (JUMP_P (insn))((void)(!((((enum rtx_code) (insn)->code) == JUMP_INSN)) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1478, __FUNCTION__), 0 : 0))
;
1479 add_reg_br_prob_note (insn, profile_probability::from_reg_br_prob_base (prob));
1480}
1481
1482/* Split 32bit/64bit divmod with 8bit unsigned divmod if dividend and
1483 divisor are within the range [0-255]. */
1484
1485void
1486ix86_split_idivmod (machine_mode mode, rtx operands[],
1487 bool unsigned_p)
1488{
1489 rtx_code_label *end_label, *qimode_label;
1490 rtx div, mod;
1491 rtx_insn *insn;
1492 rtx scratch, tmp0, tmp1, tmp2;
1493 rtx (*gen_divmod4_1) (rtx, rtx, rtx, rtx);
1494
1495 operands[2] = force_reg (mode, operands[2]);
1496 operands[3] = force_reg (mode, operands[3]);
1497
1498 switch (mode)
1499 {
1500 case E_SImode:
1501 if (GET_MODE (operands[0])((machine_mode) (operands[0])->mode) == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)))
1502 {
1503 if (GET_MODE (operands[1])((machine_mode) (operands[1])->mode) == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)))
1504 gen_divmod4_1 = unsigned_p ? gen_udivmodsi4_1 : gen_divmodsi4_1;
1505 else
1506 gen_divmod4_1
1507 = unsigned_p ? gen_udivmodsi4_zext_2 : gen_divmodsi4_zext_2;
1508 }
1509 else
1510 gen_divmod4_1
1511 = unsigned_p ? gen_udivmodsi4_zext_1 : gen_divmodsi4_zext_1;
1512 break;
1513
1514 case E_DImode:
1515 gen_divmod4_1 = unsigned_p ? gen_udivmoddi4_1 : gen_divmoddi4_1;
1516 break;
1517
1518 default:
1519 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1519, __FUNCTION__))
;
1520 }
1521
1522 end_label = gen_label_rtx ();
1523 qimode_label = gen_label_rtx ();
1524
1525 scratch = gen_reg_rtx (mode);
1526
1527 /* Use 8bit unsigned divimod if dividend and divisor are within
1528 the range [0-255]. */
1529 emit_move_insn (scratch, operands[2]);
1530 scratch = expand_simple_binop (mode, IOR, scratch, operands[3],
1531 scratch, 1, OPTAB_DIRECT);
1532 emit_insn (gen_test_ccno_1 (mode, scratch, GEN_INT (-0x100)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (-0x100))));
1533 tmp0 = gen_rtx_REG (CCNOmode((void) 0, E_CCNOmode), FLAGS_REG17);
1534 tmp0 = gen_rtx_EQ (VOIDmode, tmp0, const0_rtx)gen_rtx_fmt_ee_stat ((EQ), ((((void) 0, E_VOIDmode))), ((tmp0
)), (((const_int_rtx[64]))) )
;
1535 tmp0 = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp0,gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp0)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0
, E_VOIDmode))), ((qimode_label)) ))), ((pc_rtx)) )
1536 gen_rtx_LABEL_REF (VOIDmode, qimode_label),gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp0)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0
, E_VOIDmode))), ((qimode_label)) ))), ((pc_rtx)) )
1537 pc_rtx)gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp0)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0
, E_VOIDmode))), ((qimode_label)) ))), ((pc_rtx)) )
;
1538 insn = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp0)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((pc_rtx
)), ((tmp0)) )
);
1539 predict_jump (REG_BR_PROB_BASE10000 * 50 / 100);
1540 JUMP_LABEL (insn)(((insn)->u.fld[7]).rt_rtx) = qimode_label;
1541
1542 /* Generate original signed/unsigned divimod. */
1543 emit_insn (gen_divmod4_1 (operands[0], operands[1],
1544 operands[2], operands[3]));
1545
1546 /* Branch to the end. */
1547 emit_jump_insn (gen_jump (end_label));
1548 emit_barrier ();
1549
1550 /* Generate 8bit unsigned divide. */
1551 emit_label (qimode_label);
1552 /* Don't use operands[0] for result of 8bit divide since not all
1553 registers support QImode ZERO_EXTRACT. */
1554 tmp0 = lowpart_subreg (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)), scratch, mode);
1555 tmp1 = lowpart_subreg (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)), operands[2], mode);
1556 tmp2 = lowpart_subreg (QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)), operands[3], mode);
1557 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, tmp2));
1558
1559 if (unsigned_p)
1560 {
1561 div = gen_rtx_UDIV (mode, operands[2], operands[3])gen_rtx_fmt_ee_stat ((UDIV), ((mode)), ((operands[2])), ((operands
[3])) )
;
1562 mod = gen_rtx_UMOD (mode, operands[2], operands[3])gen_rtx_fmt_ee_stat ((UMOD), ((mode)), ((operands[2])), ((operands
[3])) )
;
1563 }
1564 else
1565 {
1566 div = gen_rtx_DIV (mode, operands[2], operands[3])gen_rtx_fmt_ee_stat ((DIV), ((mode)), ((operands[2])), ((operands
[3])) )
;
1567 mod = gen_rtx_MOD (mode, operands[2], operands[3])gen_rtx_fmt_ee_stat ((MOD), ((mode)), ((operands[2])), ((operands
[3])) )
;
1568 }
1569 if (mode == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)))
1570 {
1571 if (GET_MODE (operands[0])((machine_mode) (operands[0])->mode) != SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)))
1572 div = gen_rtx_ZERO_EXTEND (DImode, div)gen_rtx_fmt_e_stat ((ZERO_EXTEND), (((scalar_int_mode ((scalar_int_mode
::from_int) E_DImode)))), ((div)) )
;
1573 if (GET_MODE (operands[1])((machine_mode) (operands[1])->mode) != SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)))
1574 mod = gen_rtx_ZERO_EXTEND (DImode, mod)gen_rtx_fmt_e_stat ((ZERO_EXTEND), (((scalar_int_mode ((scalar_int_mode
::from_int) E_DImode)))), ((mod)) )
;
1575 }
1576
1577 /* Extract remainder from AH. */
1578 scratch = gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (operands[1])((machine_mode) (operands[1])->mode), scratch);
1579 tmp1 = gen_rtx_ZERO_EXTRACT (GET_MODE (operands[1]), scratch,gen_rtx_fmt_eee_stat ((ZERO_EXTRACT), ((((machine_mode) (operands
[1])->mode))), ((scratch)), ((gen_rtx_CONST_INT (((void) 0
, E_VOIDmode), (8)))), ((gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (8)))) )
1580 GEN_INT (8), GEN_INT (8))gen_rtx_fmt_eee_stat ((ZERO_EXTRACT), ((((machine_mode) (operands
[1])->mode))), ((scratch)), ((gen_rtx_CONST_INT (((void) 0
, E_VOIDmode), (8)))), ((gen_rtx_CONST_INT (((void) 0, E_VOIDmode
), (8)))) )
;
1581 insn = emit_move_insn (operands[1], tmp1);
1582 set_unique_reg_note (insn, REG_EQUAL, mod);
1583
1584 /* Zero extend quotient from AL. */
1585 tmp1 = gen_lowpartrtl_hooks.gen_lowpart (QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)), tmp0);
1586 insn = emit_insn (gen_extend_insn
1587 (operands[0], tmp1,
1588 GET_MODE (operands[0])((machine_mode) (operands[0])->mode), QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)), 1));
1589 set_unique_reg_note (insn, REG_EQUAL, div);
1590
1591 emit_label (end_label);
1592}
1593
1594/* Emit x86 binary operand CODE in mode MODE, where the first operand
1595 matches destination. RTX includes clobber of FLAGS_REG. */
1596
1597void
1598ix86_emit_binop (enum rtx_code code, machine_mode mode,
1599 rtx dst, rtx src)
1600{
1601 rtx op, clob;
1602
1603 op = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, mode, dst, src))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_ee_stat ((code), (mode), (dst), (src) ))) )
;
1604 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
1605
1606 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, op, clob))) )
);
1607}
1608
1609/* Return true if regno1 def is nearest to the insn. */
1610
1611static bool
1612find_nearest_reg_def (rtx_insn *insn, int regno1, int regno2)
1613{
1614 rtx_insn *prev = insn;
1615 rtx_insn *start = BB_HEAD (BLOCK_FOR_INSN (insn))(BLOCK_FOR_INSN (insn))->il.x.head_;
1616
1617 if (insn == start)
1618 return false;
1619 while (prev && prev != start)
1620 {
1621 if (!INSN_P (prev)(((((enum rtx_code) (prev)->code) == INSN) || (((enum rtx_code
) (prev)->code) == JUMP_INSN) || (((enum rtx_code) (prev)->
code) == CALL_INSN)) || (((enum rtx_code) (prev)->code) ==
DEBUG_INSN))
|| !NONDEBUG_INSN_P (prev)((((enum rtx_code) (prev)->code) == INSN) || (((enum rtx_code
) (prev)->code) == JUMP_INSN) || (((enum rtx_code) (prev)->
code) == CALL_INSN))
)
1622 {
1623 prev = PREV_INSN (prev);
1624 continue;
1625 }
1626 if (insn_defines_reg (regno1, INVALID_REGNUM(~(unsigned int) 0), prev))
1627 return true;
1628 else if (insn_defines_reg (regno2, INVALID_REGNUM(~(unsigned int) 0), prev))
1629 return false;
1630 prev = PREV_INSN (prev);
1631 }
1632
1633 /* None of the regs is defined in the bb. */
1634 return false;
1635}
1636
1637/* INSN_UID of the last insn emitted by zero store peephole2s. */
1638int ix86_last_zero_store_uid;
1639
1640/* Split lea instructions into a sequence of instructions
1641 which are executed on ALU to avoid AGU stalls.
1642 It is assumed that it is allowed to clobber flags register
1643 at lea position. */
1644
1645void
1646ix86_split_lea_for_addr (rtx_insn *insn, rtx operands[], machine_mode mode)
1647{
1648 unsigned int regno0, regno1, regno2;
1649 struct ix86_address parts;
1650 rtx target, tmp;
1651 int ok, adds;
1652
1653 ok = ix86_decompose_address (operands[1], &parts);
1654 gcc_assert (ok)((void)(!(ok) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1654, __FUNCTION__), 0 : 0))
;
1655
1656 target = gen_lowpartrtl_hooks.gen_lowpart (mode, operands[0]);
1657
1658 regno0 = true_regnum (target);
1659 regno1 = INVALID_REGNUM(~(unsigned int) 0);
1660 regno2 = INVALID_REGNUM(~(unsigned int) 0);
1661
1662 if (parts.base)
1663 {
1664 parts.base = gen_lowpartrtl_hooks.gen_lowpart (mode, parts.base);
1665 regno1 = true_regnum (parts.base);
1666 }
1667
1668 if (parts.index)
1669 {
1670 parts.index = gen_lowpartrtl_hooks.gen_lowpart (mode, parts.index);
1671 regno2 = true_regnum (parts.index);
1672 }
1673
1674 if (parts.disp)
1675 parts.disp = gen_lowpartrtl_hooks.gen_lowpart (mode, parts.disp);
1676
1677 if (parts.scale > 1)
1678 {
1679 /* Case r1 = r1 + ... */
1680 if (regno1 == regno0)
1681 {
1682 /* If we have a case r1 = r1 + C * r2 then we
1683 should use multiplication which is very
1684 expensive. Assume cost model is wrong if we
1685 have such case here. */
1686 gcc_assert (regno2 != regno0)((void)(!(regno2 != regno0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1686, __FUNCTION__), 0 : 0))
;
1687
1688 for (adds = parts.scale; adds > 0; adds--)
1689 ix86_emit_binop (PLUS, mode, target, parts.index);
1690 }
1691 else
1692 {
1693 /* r1 = r2 + r3 * C case. Need to move r3 into r1. */
1694 if (regno0 != regno2)
1695 emit_insn (gen_rtx_SET (target, parts.index)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((target
)), ((parts.index)) )
);
1696
1697 /* Use shift for scaling, but emit it as MULT instead
1698 to avoid it being immediately peephole2 optimized back
1699 into lea. */
1700 ix86_emit_binop (MULT, mode, target, GEN_INT (parts.scale)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (parts.scale)));
1701
1702 if (parts.base)
1703 ix86_emit_binop (PLUS, mode, target, parts.base);
1704
1705 if (parts.disp && parts.disp != const0_rtx(const_int_rtx[64]))
1706 ix86_emit_binop (PLUS, mode, target, parts.disp);
1707 }
1708 }
1709 else if (!parts.base && !parts.index)
1710 {
1711 gcc_assert(parts.disp)((void)(!(parts.disp) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1711, __FUNCTION__), 0 : 0))
;
1712 emit_insn (gen_rtx_SET (target, parts.disp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((target
)), ((parts.disp)) )
);
1713 }
1714 else
1715 {
1716 if (!parts.base)
1717 {
1718 if (regno0 != regno2)
1719 emit_insn (gen_rtx_SET (target, parts.index)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((target
)), ((parts.index)) )
);
1720 }
1721 else if (!parts.index)
1722 {
1723 if (regno0 != regno1)
1724 emit_insn (gen_rtx_SET (target, parts.base)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((target
)), ((parts.base)) )
);
1725 }
1726 else
1727 {
1728 if (regno0 == regno1)
1729 tmp = parts.index;
1730 else if (regno0 == regno2)
1731 tmp = parts.base;
1732 else
1733 {
1734 rtx tmp1;
1735
1736 /* Find better operand for SET instruction, depending
1737 on which definition is farther from the insn. */
1738 if (find_nearest_reg_def (insn, regno1, regno2))
1739 tmp = parts.index, tmp1 = parts.base;
1740 else
1741 tmp = parts.base, tmp1 = parts.index;
1742
1743 emit_insn (gen_rtx_SET (target, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((target
)), ((tmp)) )
);
1744
1745 if (parts.disp && parts.disp != const0_rtx(const_int_rtx[64]))
1746 ix86_emit_binop (PLUS, mode, target, parts.disp);
1747
1748 ix86_emit_binop (PLUS, mode, target, tmp1);
1749 return;
1750 }
1751
1752 ix86_emit_binop (PLUS, mode, target, tmp);
1753 }
1754
1755 if (parts.disp && parts.disp != const0_rtx(const_int_rtx[64]))
1756 ix86_emit_binop (PLUS, mode, target, parts.disp);
1757 }
1758}
1759
1760/* Post-reload splitter for converting an SF or DFmode value in an
1761 SSE register into an unsigned SImode. */
1762
1763void
1764ix86_split_convert_uns_si_sse (rtx operands[])
1765{
1766 machine_mode vecmode;
1767 rtx value, large, zero_or_two31, input, two31, x;
1768
1769 large = operands[1];
1770 zero_or_two31 = operands[2];
1771 input = operands[3];
1772 two31 = operands[4];
1773 vecmode = GET_MODE (large)((machine_mode) (large)->mode);
1774 value = gen_rtx_REG (vecmode, REGNO (operands[0])(rhs_regno(operands[0])));
1775
1776 /* Load up the value into the low element. We must ensure that the other
1777 elements are valid floats -- zero is the easiest such value. */
1778 if (MEM_P (input)(((enum rtx_code) (input)->code) == MEM))
1779 {
1780 if (vecmode == V4SFmode((void) 0, E_V4SFmode))
1781 emit_insn (gen_vec_setv4sf_0 (value, CONST0_RTX (V4SFmode)(const_tiny_rtx[0][(int) (((void) 0, E_V4SFmode))]), input));
1782 else
1783 emit_insn (gen_sse2_loadlpd (value, CONST0_RTX (V2DFmode)(const_tiny_rtx[0][(int) (((void) 0, E_V2DFmode))]), input));
1784 }
1785 else
1786 {
1787 input = gen_rtx_REG (vecmode, REGNO (input)(rhs_regno(input)));
1788 emit_move_insn (value, CONST0_RTX (vecmode)(const_tiny_rtx[0][(int) (vecmode)]));
1789 if (vecmode == V4SFmode((void) 0, E_V4SFmode))
1790 emit_insn (gen_sse_movss_v4sf (value, value, input));
1791 else
1792 emit_insn (gen_sse2_movsd_v2df (value, value, input));
1793 }
1794
1795 emit_move_insn (large, two31);
1796 emit_move_insn (zero_or_two31, MEM_P (two31)(((enum rtx_code) (two31)->code) == MEM) ? large : two31);
1797
1798 x = gen_rtx_fmt_ee (LE, vecmode, large, value)gen_rtx_fmt_ee_stat ((LE), (vecmode), (large), (value) );
1799 emit_insn (gen_rtx_SET (large, x)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((large
)), ((x)) )
);
1800
1801 x = gen_rtx_AND (vecmode, zero_or_two31, large)gen_rtx_fmt_ee_stat ((AND), ((vecmode)), ((zero_or_two31)), (
(large)) )
;
1802 emit_insn (gen_rtx_SET (zero_or_two31, x)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((zero_or_two31
)), ((x)) )
);
1803
1804 x = gen_rtx_MINUS (vecmode, value, zero_or_two31)gen_rtx_fmt_ee_stat ((MINUS), ((vecmode)), ((value)), ((zero_or_two31
)) )
;
1805 emit_insn (gen_rtx_SET (value, x)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((value
)), ((x)) )
);
1806
1807 large = gen_rtx_REG (V4SImode((void) 0, E_V4SImode), REGNO (large)(rhs_regno(large)));
1808 emit_insn (gen_ashlv4si3 (large, large, GEN_INT (31)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (31))));
1809
1810 x = gen_rtx_REG (V4SImode((void) 0, E_V4SImode), REGNO (value)(rhs_regno(value)));
1811 if (vecmode == V4SFmode((void) 0, E_V4SFmode))
1812 emit_insn (gen_fix_truncv4sfv4si2 (x, value));
1813 else
1814 emit_insn (gen_sse2_cvttpd2dq (x, value));
1815 value = x;
1816
1817 emit_insn (gen_xorv4si3 (value, value, large));
1818}
1819
1820static bool ix86_expand_vector_init_one_nonzero (bool mmx_ok,
1821 machine_mode mode, rtx target,
1822 rtx var, int one_var);
1823
1824/* Convert an unsigned DImode value into a DFmode, using only SSE.
1825 Expects the 64-bit DImode to be supplied in a pair of integral
1826 registers. Requires SSE2; will use SSE3 if available. For x86_32,
1827 -mfpmath=sse, !optimize_size only. */
1828
1829void
1830ix86_expand_convert_uns_didf_sse (rtx target, rtx input)
1831{
1832 REAL_VALUE_TYPEstruct real_value bias_lo_rvt, bias_hi_rvt;
1833 rtx int_xmm, fp_xmm;
1834 rtx biases, exponents;
1835 rtx x;
1836
1837 int_xmm = gen_reg_rtx (V4SImode((void) 0, E_V4SImode));
1838 if (TARGET_INTER_UNIT_MOVES_TO_VECix86_tune_features[X86_TUNE_INTER_UNIT_MOVES_TO_VEC])
1839 emit_insn (gen_movdi_to_sse (int_xmm, input));
1840 else if (TARGET_SSE_SPLIT_REGSix86_tune_features[X86_TUNE_SSE_SPLIT_REGS])
1841 {
1842 emit_clobber (int_xmm);
1843 emit_move_insn (gen_lowpartrtl_hooks.gen_lowpart (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)), int_xmm), input);
1844 }
1845 else
1846 {
1847 x = gen_reg_rtx (V2DImode((void) 0, E_V2DImode));
1848 ix86_expand_vector_init_one_nonzero (false, V2DImode((void) 0, E_V2DImode), x, input, 0);
1849 emit_move_insn (int_xmm, gen_lowpartrtl_hooks.gen_lowpart (V4SImode((void) 0, E_V4SImode), x));
1850 }
1851
1852 x = gen_rtx_CONST_VECTOR (V4SImode((void) 0, E_V4SImode),
1853 gen_rtvec (4, GEN_INT (0x43300000UL)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x43300000UL)),
1854 GEN_INT (0x45300000UL)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45300000UL)),
1855 const0_rtx(const_int_rtx[64]), const0_rtx(const_int_rtx[64])));
1856 exponents = validize_mem (force_const_mem (V4SImode((void) 0, E_V4SImode), x));
1857
1858 /* int_xmm = {0x45300000UL, fp_xmm/hi, 0x43300000, fp_xmm/lo } */
1859 emit_insn (gen_vec_interleave_lowv4si (int_xmm, int_xmm, exponents));
1860
1861 /* Concatenating (juxtaposing) (0x43300000UL ## fp_value_low_xmm)
1862 yields a valid DF value equal to (0x1.0p52 + double(fp_value_lo_xmm)).
1863 Similarly (0x45300000UL ## fp_value_hi_xmm) yields
1864 (0x1.0p84 + double(fp_value_hi_xmm)).
1865 Note these exponents differ by 32. */
1866
1867 fp_xmm = copy_to_mode_reg (V2DFmode((void) 0, E_V2DFmode), gen_lowpartrtl_hooks.gen_lowpart (V2DFmode((void) 0, E_V2DFmode), int_xmm));
1868
1869 /* Subtract off those 0x1.0p52 and 0x1.0p84 biases, to produce values
1870 in [0,2**32-1] and [0]+[2**32,2**64-1] respectively. */
1871 real_ldexp (&bias_lo_rvt, &dconst1, 52);
1872 real_ldexp (&bias_hi_rvt, &dconst1, 84);
1873 biases = const_double_from_real_value (bias_lo_rvt, DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1874 x = const_double_from_real_value (bias_hi_rvt, DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1875 biases = gen_rtx_CONST_VECTOR (V2DFmode((void) 0, E_V2DFmode), gen_rtvec (2, biases, x));
1876 biases = validize_mem (force_const_mem (V2DFmode((void) 0, E_V2DFmode), biases));
1877 emit_insn (gen_subv2df3 (fp_xmm, fp_xmm, biases));
1878
1879 /* Add the upper and lower DFmode values together. */
1880 if (TARGET_SSE3((global_options.x_ix86_isa_flags & (1UL << 52)) !=
0)
)
1881 emit_insn (gen_sse3_haddv2df3 (fp_xmm, fp_xmm, fp_xmm));
1882 else
1883 {
1884 x = copy_to_mode_reg (V2DFmode((void) 0, E_V2DFmode), fp_xmm);
1885 emit_insn (gen_vec_interleave_highv2df (fp_xmm, fp_xmm, fp_xmm));
1886 emit_insn (gen_addv2df3 (fp_xmm, fp_xmm, x));
1887 }
1888
1889 ix86_expand_vector_extract (false, target, fp_xmm, 0);
1890}
1891
1892/* Not used, but eases macroization of patterns. */
1893void
1894ix86_expand_convert_uns_sixf_sse (rtx, rtx)
1895{
1896 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 1896, __FUNCTION__))
;
1897}
1898
1899static rtx ix86_expand_sse_fabs (rtx op0, rtx *smask);
1900
1901/* Convert an unsigned SImode value into a DFmode. Only currently used
1902 for SSE, but applicable anywhere. */
1903
1904void
1905ix86_expand_convert_uns_sidf_sse (rtx target, rtx input)
1906{
1907 REAL_VALUE_TYPEstruct real_value TWO31r;
1908 rtx x, fp;
1909
1910 x = expand_simple_binop (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), PLUS, input, GEN_INT (-2147483647 - 1)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (-2147483647 - 1)),
1911 NULL__null, 1, OPTAB_DIRECT);
1912
1913 fp = gen_reg_rtx (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1914 emit_insn (gen_floatsidf2 (fp, x));
1915
1916 real_ldexp (&TWO31r, &dconst1, 31);
1917 x = const_double_from_real_value (TWO31r, DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1918
1919 x = expand_simple_binop (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)), PLUS, fp, x, target, 0, OPTAB_DIRECT);
1920
1921 /* Remove the sign with FE_DOWNWARD, where x - x = -0.0. */
1922 if (HONOR_SIGNED_ZEROS (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode))) && flag_rounding_mathglobal_options.x_flag_rounding_math)
1923 x = ix86_expand_sse_fabs (x, NULL__null);
1924
1925 if (x != target)
1926 emit_move_insn (target, x);
1927}
1928
1929/* Convert a signed DImode value into a DFmode. Only used for SSE in
1930 32-bit mode; otherwise we have a direct convert instruction. */
1931
1932void
1933ix86_expand_convert_sign_didf_sse (rtx target, rtx input)
1934{
1935 REAL_VALUE_TYPEstruct real_value TWO32r;
1936 rtx fp_lo, fp_hi, x;
1937
1938 fp_lo = gen_reg_rtx (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1939 fp_hi = gen_reg_rtx (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1940
1941 emit_insn (gen_floatsidf2 (fp_hi, gen_highpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), input)));
1942
1943 real_ldexp (&TWO32r, &dconst1, 32);
1944 x = const_double_from_real_value (TWO32r, DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)));
1945 fp_hi = expand_simple_binop (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)), MULT, fp_hi, x, fp_hi, 0, OPTAB_DIRECT);
1946
1947 ix86_expand_convert_uns_sidf_sse (fp_lo, gen_lowpartrtl_hooks.gen_lowpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), input));
1948
1949 x = expand_simple_binop (DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)), PLUS, fp_hi, fp_lo, target,
1950 0, OPTAB_DIRECT);
1951 if (x != target)
1952 emit_move_insn (target, x);
1953}
1954
1955/* Convert an unsigned SImode value into a SFmode, using only SSE.
1956 For x86_32, -mfpmath=sse, !optimize_size only. */
1957void
1958ix86_expand_convert_uns_sisf_sse (rtx target, rtx input)
1959{
1960 REAL_VALUE_TYPEstruct real_value ONE16r;
1961 rtx fp_hi, fp_lo, int_hi, int_lo, x;
1962
1963 real_ldexp (&ONE16r, &dconst1, 16);
1964 x = const_double_from_real_value (ONE16r, SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)));
1965 int_lo = expand_simple_binop (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), AND, input, GEN_INT(0xffff)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0xffff)),
1966 NULL__null, 0, OPTAB_DIRECT);
1967 int_hi = expand_simple_binop (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), LSHIFTRT, input, GEN_INT(16)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)),
1968 NULL__null, 0, OPTAB_DIRECT);
1969 fp_hi = gen_reg_rtx (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)));
1970 fp_lo = gen_reg_rtx (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)));
1971 emit_insn (gen_floatsisf2 (fp_hi, int_hi));
1972 emit_insn (gen_floatsisf2 (fp_lo, int_lo));
1973 if (TARGET_FMA((global_options.x_ix86_isa_flags & (1UL << 29)) !=
0)
)
1974 {
1975 x = validize_mem (force_const_mem (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)), x));
1976 fp_hi = gen_rtx_FMA (SFmode, fp_hi, x, fp_lo)gen_rtx_fmt_eee_stat ((FMA), (((scalar_float_mode ((scalar_float_mode
::from_int) E_SFmode)))), ((fp_hi)), ((x)), ((fp_lo)) )
;
1977 emit_move_insn (target, fp_hi);
1978 }
1979 else
1980 {
1981 fp_hi = expand_simple_binop (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)), MULT, fp_hi, x, fp_hi,
1982 0, OPTAB_DIRECT);
1983 fp_hi = expand_simple_binop (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)), PLUS, fp_hi, fp_lo, target,
1984 0, OPTAB_DIRECT);
1985 if (!rtx_equal_p (target, fp_hi))
1986 emit_move_insn (target, fp_hi);
1987 }
1988}
1989
1990/* floatunsv{4,8}siv{4,8}sf2 expander. Expand code to convert
1991 a vector of unsigned ints VAL to vector of floats TARGET. */
1992
1993void
1994ix86_expand_vector_convert_uns_vsivsf (rtx target, rtx val)
1995{
1996 rtx tmp[8];
1997 REAL_VALUE_TYPEstruct real_value TWO16r;
1998 machine_mode intmode = GET_MODE (val)((machine_mode) (val)->mode);
1999 machine_mode fltmode = GET_MODE (target)((machine_mode) (target)->mode);
2000 rtx (*cvt) (rtx, rtx);
2001
2002 if (intmode == V4SImode((void) 0, E_V4SImode))
2003 cvt = gen_floatv4siv4sf2;
2004 else
2005 cvt = gen_floatv8siv8sf2;
2006 tmp[0] = ix86_build_const_vector (intmode, 1, GEN_INT (0xffff)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0xffff)));
2007 tmp[0] = force_reg (intmode, tmp[0]);
2008 tmp[1] = expand_simple_binop (intmode, AND, val, tmp[0], NULL_RTX(rtx) 0, 1,
2009 OPTAB_DIRECT);
2010 tmp[2] = expand_simple_binop (intmode, LSHIFTRT, val, GEN_INT (16)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16)),
2011 NULL_RTX(rtx) 0, 1, OPTAB_DIRECT);
2012 tmp[3] = gen_reg_rtx (fltmode);
2013 emit_insn (cvt (tmp[3], tmp[1]));
2014 tmp[4] = gen_reg_rtx (fltmode);
2015 emit_insn (cvt (tmp[4], tmp[2]));
2016 real_ldexp (&TWO16r, &dconst1, 16);
2017 tmp[5] = const_double_from_real_value (TWO16r, SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)));
2018 tmp[5] = force_reg (fltmode, ix86_build_const_vector (fltmode, 1, tmp[5]));
2019 if (TARGET_FMA((global_options.x_ix86_isa_flags & (1UL << 29)) !=
0)
)
2020 {
2021 tmp[6] = gen_rtx_FMA (fltmode, tmp[4], tmp[5], tmp[3])gen_rtx_fmt_eee_stat ((FMA), ((fltmode)), ((tmp[4])), ((tmp[5
])), ((tmp[3])) )
;
2022 emit_move_insn (target, tmp[6]);
2023 }
2024 else
2025 {
2026 tmp[6] = expand_simple_binop (fltmode, MULT, tmp[4], tmp[5],
2027 NULL_RTX(rtx) 0, 1, OPTAB_DIRECT);
2028 tmp[7] = expand_simple_binop (fltmode, PLUS, tmp[3], tmp[6],
2029 target, 1, OPTAB_DIRECT);
2030 if (tmp[7] != target)
2031 emit_move_insn (target, tmp[7]);
2032 }
2033}
2034
2035/* Adjust a V*SFmode/V*DFmode value VAL so that *sfix_trunc* resp. fix_trunc*
2036 pattern can be used on it instead of *ufix_trunc* resp. fixuns_trunc*.
2037 This is done by doing just signed conversion if < 0x1p31, and otherwise by
2038 subtracting 0x1p31 first and xoring in 0x80000000 from *XORP afterwards. */
2039
2040rtx
2041ix86_expand_adjust_ufix_to_sfix_si (rtx val, rtx *xorp)
2042{
2043 REAL_VALUE_TYPEstruct real_value TWO31r;
2044 rtx two31r, tmp[4];
2045 machine_mode mode = GET_MODE (val)((machine_mode) (val)->mode);
2046 machine_mode scalarmode = GET_MODE_INNER (mode)(mode_to_inner (mode));
2047 machine_mode intmode = GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) == 32 ? V8SImode((void) 0, E_V8SImode) : V4SImode((void) 0, E_V4SImode);
2048 rtx (*cmp) (rtx, rtx, rtx, rtx);
2049 int i;
2050
2051 for (i = 0; i < 3; i++)
2052 tmp[i] = gen_reg_rtx (mode);
2053 real_ldexp (&TWO31r, &dconst1, 31);
2054 two31r = const_double_from_real_value (TWO31r, scalarmode);
2055 two31r = ix86_build_const_vector (mode, 1, two31r);
2056 two31r = force_reg (mode, two31r);
2057 switch (mode)
2058 {
2059 case E_V8SFmode: cmp = gen_avx_maskcmpv8sf3; break;
2060 case E_V4SFmode: cmp = gen_sse_maskcmpv4sf3; break;
2061 case E_V4DFmode: cmp = gen_avx_maskcmpv4df3; break;
2062 case E_V2DFmode: cmp = gen_sse2_maskcmpv2df3; break;
2063 default: gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2063, __FUNCTION__))
;
2064 }
2065 tmp[3] = gen_rtx_LE (mode, two31r, val)gen_rtx_fmt_ee_stat ((LE), ((mode)), ((two31r)), ((val)) );
2066 emit_insn (cmp (tmp[0], two31r, val, tmp[3]));
2067 tmp[1] = expand_simple_binop (mode, AND, tmp[0], two31r, tmp[1],
2068 0, OPTAB_DIRECT);
2069 if (intmode == V4SImode((void) 0, E_V4SImode) || TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
)
2070 *xorp = expand_simple_binop (intmode, ASHIFT,
2071 gen_lowpartrtl_hooks.gen_lowpart (intmode, tmp[0]),
2072 GEN_INT (31)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (31)), NULL_RTX(rtx) 0, 0,
2073 OPTAB_DIRECT);
2074 else
2075 {
2076 rtx two31 = gen_int_mode (HOST_WIDE_INT_1U1UL << 31, SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2077 two31 = ix86_build_const_vector (intmode, 1, two31);
2078 *xorp = expand_simple_binop (intmode, AND,
2079 gen_lowpartrtl_hooks.gen_lowpart (intmode, tmp[0]),
2080 two31, NULL_RTX(rtx) 0, 0,
2081 OPTAB_DIRECT);
2082 }
2083 return expand_simple_binop (mode, MINUS, val, tmp[1], tmp[2],
2084 0, OPTAB_DIRECT);
2085}
2086
2087/* Generate code for floating point ABS or NEG. */
2088
2089void
2090ix86_expand_fp_absneg_operator (enum rtx_code code, machine_mode mode,
2091 rtx operands[])
2092{
2093 rtx set, dst, src;
2094 bool use_sse = false;
2095 bool vector_mode = VECTOR_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_VECTOR_BOOL || (
(enum mode_class) mode_class[mode]) == MODE_VECTOR_INT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FRACT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_UFRACT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_ACCUM || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_UACCUM)
;
2096 machine_mode vmode = mode;
2097 rtvec par;
2098
2099 if (vector_mode || mode == TFmode(scalar_float_mode ((scalar_float_mode::from_int) E_TFmode)) || mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
2100 {
2101 use_sse = true;
2102 if (mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
2103 vmode = V8HFmode((void) 0, E_V8HFmode);
2104 }
2105 else if (TARGET_SSE_MATH((global_options.x_ix86_fpmath & FPMATH_SSE) != 0))
2106 {
2107 use_sse = SSE_FLOAT_MODE_P (mode)((((global_options.x_ix86_isa_flags & (1UL << 50)) !=
0) && (mode) == (scalar_float_mode ((scalar_float_mode
::from_int) E_SFmode))) || (((global_options.x_ix86_isa_flags
& (1UL << 51)) != 0) && (mode) == (scalar_float_mode
((scalar_float_mode::from_int) E_DFmode))))
;
2108 if (mode == SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)))
2109 vmode = V4SFmode((void) 0, E_V4SFmode);
2110 else if (mode == DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)))
2111 vmode = V2DFmode((void) 0, E_V2DFmode);
2112 }
2113
2114 dst = operands[0];
2115 src = operands[1];
2116
2117 set = gen_rtx_fmt_e (code, mode, src)gen_rtx_fmt_e_stat ((code), (mode), (src) );
2118 set = gen_rtx_SET (dst, set)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((set)) )
;
2119
2120 if (use_sse)
2121 {
2122 rtx mask, use, clob;
2123
2124 /* NEG and ABS performed with SSE use bitwise mask operations.
2125 Create the appropriate mask now. */
2126 mask = ix86_build_signbit_mask (vmode, vector_mode, code == ABS);
2127 use = gen_rtx_USE (VOIDmode, mask)gen_rtx_fmt_e_stat ((USE), ((((void) 0, E_VOIDmode))), ((mask
)) )
;
2128 if (vector_mode || mode == TFmode(scalar_float_mode ((scalar_float_mode::from_int) E_TFmode)))
2129 par = gen_rtvec (2, set, use);
2130 else
2131 {
2132 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
2133 par = gen_rtvec (3, set, use, clob);
2134 }
2135 }
2136 else
2137 {
2138 rtx clob;
2139
2140 /* Changing of sign for FP values is doable using integer unit too. */
2141 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
2142 par = gen_rtvec (2, set, clob);
2143 }
2144
2145 emit_insn (gen_rtx_PARALLEL (VOIDmode, par)gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(par)) )
);
2146}
2147
2148/* Deconstruct a floating point ABS or NEG operation
2149 with integer registers into integer operations. */
2150
2151void
2152ix86_split_fp_absneg_operator (enum rtx_code code, machine_mode mode,
2153 rtx operands[])
2154{
2155 enum rtx_code absneg_op;
2156 rtx dst, set;
2157
2158 gcc_assert (operands_match_p (operands[0], operands[1]))((void)(!(operands_match_p (operands[0], operands[1])) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2158, __FUNCTION__), 0 : 0))
;
2159
2160 switch (mode)
2161 {
2162 case E_SFmode:
2163 dst = gen_lowpartrtl_hooks.gen_lowpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), operands[0]);
2164
2165 if (code == ABS)
2166 {
2167 set = gen_int_mode (0x7fffffff, SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2168 absneg_op = AND;
2169 }
2170 else
2171 {
2172 set = gen_int_mode (0x80000000, SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2173 absneg_op = XOR;
2174 }
2175 set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set)gen_rtx_fmt_ee_stat ((absneg_op), ((scalar_int_mode ((scalar_int_mode
::from_int) E_SImode))), (dst), (set) )
;
2176 break;
2177
2178 case E_DFmode:
2179 if (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
)
2180 {
2181 dst = gen_lowpartrtl_hooks.gen_lowpart (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)), operands[0]);
2182 dst = gen_rtx_ZERO_EXTRACT (DImode, dst, const1_rtx, GEN_INT (63))gen_rtx_fmt_eee_stat ((ZERO_EXTRACT), (((scalar_int_mode ((scalar_int_mode
::from_int) E_DImode)))), ((dst)), (((const_int_rtx[64 +1])))
, ((gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (63)))) )
;
2183
2184 if (code == ABS)
2185 set = const0_rtx(const_int_rtx[64]);
2186 else
2187 set = gen_rtx_NOT (DImode, dst)gen_rtx_fmt_e_stat ((NOT), (((scalar_int_mode ((scalar_int_mode
::from_int) E_DImode)))), ((dst)) )
;
2188 }
2189 else
2190 {
2191 dst = gen_highpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), operands[0]);
2192
2193 if (code == ABS)
2194 {
2195 set = gen_int_mode (0x7fffffff, SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2196 absneg_op = AND;
2197 }
2198 else
2199 {
2200 set = gen_int_mode (0x80000000, SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2201 absneg_op = XOR;
2202 }
2203 set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set)gen_rtx_fmt_ee_stat ((absneg_op), ((scalar_int_mode ((scalar_int_mode
::from_int) E_SImode))), (dst), (set) )
;
2204 }
2205 break;
2206
2207 case E_XFmode:
2208 dst = gen_rtx_REG (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)),
2209 REGNO (operands[0])(rhs_regno(operands[0])) + (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
? 1 : 2));
2210 if (code == ABS)
2211 {
2212 set = GEN_INT (0x7fff)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x7fff));
2213 absneg_op = AND;
2214 }
2215 else
2216 {
2217 set = GEN_INT (0x8000)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x8000));
2218 absneg_op = XOR;
2219 }
2220 set = gen_rtx_fmt_ee (absneg_op, SImode, dst, set)gen_rtx_fmt_ee_stat ((absneg_op), ((scalar_int_mode ((scalar_int_mode
::from_int) E_SImode))), (dst), (set) )
;
2221 break;
2222
2223 default:
2224 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2224, __FUNCTION__))
;
2225 }
2226
2227 set = gen_rtx_SET (dst, set)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((set)) )
;
2228
2229 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
2230 rtvec par = gen_rtvec (2, set, clob);
2231
2232 emit_insn (gen_rtx_PARALLEL (VOIDmode, par)gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(par)) )
);
2233}
2234
2235/* Expand a copysign operation. Special case operand 0 being a constant. */
2236
2237void
2238ix86_expand_copysign (rtx operands[])
2239{
2240 machine_mode mode, vmode;
2241 rtx dest, vdest, op0, op1, mask, op2, op3;
2242
2243 mode = GET_MODE (operands[0])((machine_mode) (operands[0])->mode);
2244
2245 if (mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
2246 vmode = V8HFmode((void) 0, E_V8HFmode);
2247 else if (mode == SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)))
2248 vmode = V4SFmode((void) 0, E_V4SFmode);
2249 else if (mode == DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)))
2250 vmode = V2DFmode((void) 0, E_V2DFmode);
2251 else if (mode == TFmode(scalar_float_mode ((scalar_float_mode::from_int) E_TFmode)))
2252 vmode = mode;
2253 else
2254 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2254, __FUNCTION__))
;
2255
2256 if (rtx_equal_p (operands[1], operands[2]))
2257 {
2258 emit_move_insn (operands[0], operands[1]);
2259 return;
2260 }
2261
2262 dest = operands[0];
2263 vdest = lowpart_subreg (vmode, dest, mode);
2264 if (vdest == NULL_RTX(rtx) 0)
2265 vdest = gen_reg_rtx (vmode);
2266 else
2267 dest = NULL_RTX(rtx) 0;
2268 op1 = lowpart_subreg (vmode, force_reg (mode, operands[2]), mode);
2269 mask = ix86_build_signbit_mask (vmode, 0, 0);
2270
2271 if (CONST_DOUBLE_P (operands[1])(((enum rtx_code) (operands[1])->code) == CONST_DOUBLE))
2272 {
2273 op0 = simplify_unary_operation (ABS, mode, operands[1], mode);
2274 /* Optimize for 0, simplify b = copy_signf (0.0f, a) to b = mask & a. */
2275 if (op0 == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)]))
2276 {
2277 emit_move_insn (vdest, gen_rtx_AND (vmode, mask, op1)gen_rtx_fmt_ee_stat ((AND), ((vmode)), ((mask)), ((op1)) ));
2278 if (dest)
2279 emit_move_insn (dest, lowpart_subreg (mode, vdest, vmode));
2280 return;
2281 }
2282
2283 if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) < 16)
2284 op0 = ix86_build_const_vector (vmode, false, op0);
2285 op0 = force_reg (vmode, op0);
2286 }
2287 else
2288 op0 = lowpart_subreg (vmode, force_reg (mode, operands[1]), mode);
2289
2290 op2 = gen_reg_rtx (vmode);
2291 op3 = gen_reg_rtx (vmode);
2292 emit_move_insn (op2, gen_rtx_AND (vmode,gen_rtx_fmt_ee_stat ((AND), ((vmode)), ((gen_rtx_fmt_e_stat (
(NOT), ((vmode)), ((mask)) ))), ((op0)) )
2293 gen_rtx_NOT (vmode, mask),gen_rtx_fmt_ee_stat ((AND), ((vmode)), ((gen_rtx_fmt_e_stat (
(NOT), ((vmode)), ((mask)) ))), ((op0)) )
2294 op0)gen_rtx_fmt_ee_stat ((AND), ((vmode)), ((gen_rtx_fmt_e_stat (
(NOT), ((vmode)), ((mask)) ))), ((op0)) )
);
2295 emit_move_insn (op3, gen_rtx_AND (vmode, mask, op1)gen_rtx_fmt_ee_stat ((AND), ((vmode)), ((mask)), ((op1)) ));
2296 emit_move_insn (vdest, gen_rtx_IOR (vmode, op2, op3)gen_rtx_fmt_ee_stat ((IOR), ((vmode)), ((op2)), ((op3)) ));
2297 if (dest)
2298 emit_move_insn (dest, lowpart_subreg (mode, vdest, vmode));
2299}
2300
2301/* Expand an xorsign operation. */
2302
2303void
2304ix86_expand_xorsign (rtx operands[])
2305{
2306 machine_mode mode, vmode;
2307 rtx dest, vdest, op0, op1, mask, x, temp;
2308
2309 dest = operands[0];
2310 op0 = operands[1];
2311 op1 = operands[2];
2312
2313 mode = GET_MODE (dest)((machine_mode) (dest)->mode);
2314
2315 if (mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
2316 vmode = V8HFmode((void) 0, E_V8HFmode);
2317 else if (mode == SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)))
2318 vmode = V4SFmode((void) 0, E_V4SFmode);
2319 else if (mode == DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)))
2320 vmode = V2DFmode((void) 0, E_V2DFmode);
2321 else
2322 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2322, __FUNCTION__))
;
2323
2324 temp = gen_reg_rtx (vmode);
2325 mask = ix86_build_signbit_mask (vmode, 0, 0);
2326
2327 op1 = lowpart_subreg (vmode, force_reg (mode, op1), mode);
2328 x = gen_rtx_AND (vmode, op1, mask)gen_rtx_fmt_ee_stat ((AND), ((vmode)), ((op1)), ((mask)) );
2329 emit_insn (gen_rtx_SET (temp, x)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((temp)
), ((x)) )
);
2330
2331 op0 = lowpart_subreg (vmode, force_reg (mode, op0), mode);
2332 x = gen_rtx_XOR (vmode, temp, op0)gen_rtx_fmt_ee_stat ((XOR), ((vmode)), ((temp)), ((op0)) );
2333
2334 vdest = lowpart_subreg (vmode, dest, mode);
2335 if (vdest == NULL_RTX(rtx) 0)
2336 vdest = gen_reg_rtx (vmode);
2337 else
2338 dest = NULL_RTX(rtx) 0;
2339 emit_insn (gen_rtx_SET (vdest, x)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((vdest
)), ((x)) )
);
2340
2341 if (dest)
2342 emit_move_insn (dest, lowpart_subreg (mode, vdest, vmode));
2343}
2344
2345static rtx ix86_expand_compare (enum rtx_code code, rtx op0, rtx op1);
2346
2347void
2348ix86_expand_branch (enum rtx_code code, rtx op0, rtx op1, rtx label)
2349{
2350 machine_mode mode = GET_MODE (op0)((machine_mode) (op0)->mode);
2351 rtx tmp;
2352
2353 /* Handle special case - vector comparsion with boolean result, transform
2354 it using ptest instruction. */
2355 if (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_VECTOR_INT
2356 || mode == OImode(scalar_int_mode ((scalar_int_mode::from_int) E_OImode)))
2357 {
2358 rtx flag = gen_rtx_REG (CCZmode((void) 0, E_CCZmode), FLAGS_REG17);
2359 machine_mode p_mode = GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) == 32 ? V4DImode((void) 0, E_V4DImode) : V2DImode((void) 0, E_V2DImode);
2360
2361 gcc_assert (code == EQ || code == NE)((void)(!(code == EQ || code == NE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2361, __FUNCTION__), 0 : 0))
;
2362
2363 if (mode == OImode(scalar_int_mode ((scalar_int_mode::from_int) E_OImode)))
2364 {
2365 op0 = lowpart_subreg (p_mode, force_reg (mode, op0), mode);
2366 op1 = lowpart_subreg (p_mode, force_reg (mode, op1), mode);
2367 mode = p_mode;
2368 }
2369 /* Generate XOR since we can't check that one operand is zero vector. */
2370 tmp = gen_reg_rtx (mode);
2371 emit_insn (gen_rtx_SET (tmp, gen_rtx_XOR (mode, op0, op1))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((tmp))
, ((gen_rtx_fmt_ee_stat ((XOR), ((mode)), ((op0)), ((op1)) ))
) )
);
2372 tmp = gen_lowpartrtl_hooks.gen_lowpart (p_mode, tmp);
2373 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, FLAGS_REG),gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((gen_rtx_REG
(((void) 0, E_CCmode), 17))), ((gen_rtx_fmt_Ei_stat ((UNSPEC
), ((((void) 0, E_CCmode))), ((gen_rtvec (2, tmp, tmp))), ((UNSPEC_PTEST
)) ))) )
2374 gen_rtx_UNSPEC (CCmode,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((gen_rtx_REG
(((void) 0, E_CCmode), 17))), ((gen_rtx_fmt_Ei_stat ((UNSPEC
), ((((void) 0, E_CCmode))), ((gen_rtvec (2, tmp, tmp))), ((UNSPEC_PTEST
)) ))) )
2375 gen_rtvec (2, tmp, tmp),gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((gen_rtx_REG
(((void) 0, E_CCmode), 17))), ((gen_rtx_fmt_Ei_stat ((UNSPEC
), ((((void) 0, E_CCmode))), ((gen_rtvec (2, tmp, tmp))), ((UNSPEC_PTEST
)) ))) )
2376 UNSPEC_PTEST))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((gen_rtx_REG
(((void) 0, E_CCmode), 17))), ((gen_rtx_fmt_Ei_stat ((UNSPEC
), ((((void) 0, E_CCmode))), ((gen_rtvec (2, tmp, tmp))), ((UNSPEC_PTEST
)) ))) )
);
2377 tmp = gen_rtx_fmt_ee (code, VOIDmode, flag, const0_rtx)gen_rtx_fmt_ee_stat ((code), (((void) 0, E_VOIDmode)), (flag)
, ((const_int_rtx[64])) )
;
2378 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0,
E_VOIDmode))), ((label)) ))), ((pc_rtx)) )
2379 gen_rtx_LABEL_REF (VOIDmode, label),gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0,
E_VOIDmode))), ((label)) ))), ((pc_rtx)) )
2380 pc_rtx)gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0,
E_VOIDmode))), ((label)) ))), ((pc_rtx)) )
;
2381 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((pc_rtx
)), ((tmp)) )
);
2382 return;
2383 }
2384
2385 switch (mode)
2386 {
2387 case E_HFmode:
2388 case E_SFmode:
2389 case E_DFmode:
2390 case E_XFmode:
2391 case E_QImode:
2392 case E_HImode:
2393 case E_SImode:
2394 simple:
2395 tmp = ix86_expand_compare (code, op0, op1);
2396 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0,
E_VOIDmode))), ((label)) ))), ((pc_rtx)) )
2397 gen_rtx_LABEL_REF (VOIDmode, label),gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0,
E_VOIDmode))), ((label)) ))), ((pc_rtx)) )
2398 pc_rtx)gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((tmp)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0,
E_VOIDmode))), ((label)) ))), ((pc_rtx)) )
;
2399 emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((pc_rtx
)), ((tmp)) )
);
2400 return;
2401
2402 case E_DImode:
2403 if (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
)
2404 goto simple;
2405 /* FALLTHRU */
2406 case E_TImode:
2407 /* DI and TI mode equality/inequality comparisons may be performed
2408 on SSE registers. Avoid splitting them, except when optimizing
2409 for size. */
2410 if ((code == EQ || code == NE)
2411 && !optimize_insn_for_size_p ())
2412 goto simple;
2413
2414 /* Expand DImode branch into multiple compare+branch. */
2415 {
2416 rtx lo[2], hi[2];
2417 rtx_code_label *label2;
2418 enum rtx_code code1, code2, code3;
2419 machine_mode submode;
2420
2421 if (CONSTANT_P (op0)((rtx_class[(int) (((enum rtx_code) (op0)->code))]) == RTX_CONST_OBJ
)
&& !CONSTANT_P (op1)((rtx_class[(int) (((enum rtx_code) (op1)->code))]) == RTX_CONST_OBJ
)
)
2422 {
2423 std::swap (op0, op1);
2424 code = swap_condition (code);
2425 }
2426
2427 split_double_mode (mode, &op0, 1, lo+0, hi+0);
2428 split_double_mode (mode, &op1, 1, lo+1, hi+1);
2429
2430 submode = mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)) ? SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)) : DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode));
2431
2432 /* If we are doing less-than or greater-or-equal-than,
2433 op1 is a constant and the low word is zero, then we can just
2434 examine the high word. Similarly for low word -1 and
2435 less-or-equal-than or greater-than. */
2436
2437 if (CONST_INT_P (hi[1])(((enum rtx_code) (hi[1])->code) == CONST_INT))
2438 switch (code)
2439 {
2440 case LT: case LTU: case GE: case GEU:
2441 if (lo[1] == const0_rtx(const_int_rtx[64]))
2442 {
2443 ix86_expand_branch (code, hi[0], hi[1], label);
2444 return;
2445 }
2446 break;
2447 case LE: case LEU: case GT: case GTU:
2448 if (lo[1] == constm1_rtx(const_int_rtx[64 -1]))
2449 {
2450 ix86_expand_branch (code, hi[0], hi[1], label);
2451 return;
2452 }
2453 break;
2454 default:
2455 break;
2456 }
2457
2458 /* Emulate comparisons that do not depend on Zero flag with
2459 double-word subtraction. Note that only Overflow, Sign
2460 and Carry flags are valid, so swap arguments and condition
2461 of comparisons that would otherwise test Zero flag. */
2462
2463 switch (code)
2464 {
2465 case LE: case LEU: case GT: case GTU:
2466 std::swap (lo[0], lo[1]);
2467 std::swap (hi[0], hi[1]);
2468 code = swap_condition (code);
2469 /* FALLTHRU */
2470
2471 case LT: case LTU: case GE: case GEU:
2472 {
2473 bool uns = (code == LTU || code == GEU);
2474 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
2475 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
2476
2477 if (!nonimmediate_operand (lo[0], submode))
2478 lo[0] = force_reg (submode, lo[0]);
2479 if (!x86_64_general_operand (lo[1], submode))
2480 lo[1] = force_reg (submode, lo[1]);
2481
2482 if (!register_operand (hi[0], submode))
2483 hi[0] = force_reg (submode, hi[0]);
2484 if ((uns && !nonimmediate_operand (hi[1], submode))
2485 || (!uns && !x86_64_general_operand (hi[1], submode)))
2486 hi[1] = force_reg (submode, hi[1]);
2487
2488 emit_insn (gen_cmp_1 (submode, lo[0], lo[1]));
2489
2490 tmp = gen_rtx_SCRATCH (submode)gen_rtx_fmt__stat ((SCRATCH), ((submode)) );
2491 emit_insn (sbb_insn (submode, tmp, hi[0], hi[1]));
2492
2493 tmp = gen_rtx_REG (uns ? CCCmode((void) 0, E_CCCmode) : CCGZmode((void) 0, E_CCGZmode), FLAGS_REG17);
2494 ix86_expand_branch (code, tmp, const0_rtx(const_int_rtx[64]), label);
2495 return;
2496 }
2497
2498 default:
2499 break;
2500 }
2501
2502 /* Otherwise, we need two or three jumps. */
2503
2504 label2 = gen_label_rtx ();
2505
2506 code1 = code;
2507 code2 = swap_condition (code);
2508 code3 = unsigned_condition (code);
2509
2510 switch (code)
2511 {
2512 case LT: case GT: case LTU: case GTU:
2513 break;
2514
2515 case LE: code1 = LT; code2 = GT; break;
2516 case GE: code1 = GT; code2 = LT; break;
2517 case LEU: code1 = LTU; code2 = GTU; break;
2518 case GEU: code1 = GTU; code2 = LTU; break;
2519
2520 case EQ: code1 = UNKNOWN; code2 = NE; break;
2521 case NE: code2 = UNKNOWN; break;
2522
2523 default:
2524 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2524, __FUNCTION__))
;
2525 }
2526
2527 /*
2528 * a < b =>
2529 * if (hi(a) < hi(b)) goto true;
2530 * if (hi(a) > hi(b)) goto false;
2531 * if (lo(a) < lo(b)) goto true;
2532 * false:
2533 */
2534
2535 if (code1 != UNKNOWN)
2536 ix86_expand_branch (code1, hi[0], hi[1], label);
2537 if (code2 != UNKNOWN)
2538 ix86_expand_branch (code2, hi[0], hi[1], label2);
2539
2540 ix86_expand_branch (code3, lo[0], lo[1], label);
2541
2542 if (code2 != UNKNOWN)
2543 emit_label (label2);
2544 return;
2545 }
2546
2547 default:
2548 gcc_assert (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)((void)(!(((enum mode_class) mode_class[((machine_mode) (op0)
->mode)]) == MODE_CC) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2548, __FUNCTION__), 0 : 0))
;
2549 goto simple;
2550 }
2551}
2552
2553/* Figure out whether to use unordered fp comparisons. */
2554
2555static bool
2556ix86_unordered_fp_compare (enum rtx_code code)
2557{
2558 if (!TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2559 return false;
2560
2561 switch (code)
2562 {
2563 case LT:
2564 case LE:
2565 case GT:
2566 case GE:
2567 case LTGT:
2568 return false;
2569
2570 case EQ:
2571 case NE:
2572
2573 case UNORDERED:
2574 case ORDERED:
2575 case UNLT:
2576 case UNLE:
2577 case UNGT:
2578 case UNGE:
2579 case UNEQ:
2580 return true;
2581
2582 default:
2583 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2583, __FUNCTION__))
;
2584 }
2585}
2586
2587/* Return a comparison we can do and that it is equivalent to
2588 swap_condition (code) apart possibly from orderedness.
2589 But, never change orderedness if TARGET_IEEE_FP, returning
2590 UNKNOWN in that case if necessary. */
2591
2592static enum rtx_code
2593ix86_fp_swap_condition (enum rtx_code code)
2594{
2595 switch (code)
2596 {
2597 case GT: /* GTU - CF=0 & ZF=0 */
2598 return TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? UNKNOWN : UNLT;
2599 case GE: /* GEU - CF=0 */
2600 return TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? UNKNOWN : UNLE;
2601 case UNLT: /* LTU - CF=1 */
2602 return TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? UNKNOWN : GT;
2603 case UNLE: /* LEU - CF=1 | ZF=1 */
2604 return TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? UNKNOWN : GE;
2605 default:
2606 return swap_condition (code);
2607 }
2608}
2609
2610/* Return cost of comparison CODE using the best strategy for performance.
2611 All following functions do use number of instructions as a cost metrics.
2612 In future this should be tweaked to compute bytes for optimize_size and
2613 take into account performance of various instructions on various CPUs. */
2614
2615static int
2616ix86_fp_comparison_cost (enum rtx_code code)
2617{
2618 int arith_cost;
2619
2620 /* The cost of code using bit-twiddling on %ah. */
2621 switch (code)
2622 {
2623 case UNLE:
2624 case UNLT:
2625 case LTGT:
2626 case GT:
2627 case GE:
2628 case UNORDERED:
2629 case ORDERED:
2630 case UNEQ:
2631 arith_cost = 4;
2632 break;
2633 case LT:
2634 case NE:
2635 case EQ:
2636 case UNGE:
2637 arith_cost = TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? 5 : 4;
2638 break;
2639 case LE:
2640 case UNGT:
2641 arith_cost = TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? 6 : 4;
2642 break;
2643 default:
2644 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2644, __FUNCTION__))
;
2645 }
2646
2647 switch (ix86_fp_comparison_strategy (code))
2648 {
2649 case IX86_FPCMP_COMI:
2650 return arith_cost > 4 ? 3 : 2;
2651 case IX86_FPCMP_SAHF:
2652 return arith_cost > 4 ? 4 : 3;
2653 default:
2654 return arith_cost;
2655 }
2656}
2657
2658/* Swap, force into registers, or otherwise massage the two operands
2659 to a fp comparison. The operands are updated in place; the new
2660 comparison code is returned. */
2661
2662static enum rtx_code
2663ix86_prepare_fp_compare_args (enum rtx_code code, rtx *pop0, rtx *pop1)
2664{
2665 bool unordered_compare = ix86_unordered_fp_compare (code);
2666 rtx op0 = *pop0, op1 = *pop1;
2667 machine_mode op_mode = GET_MODE (op0)((machine_mode) (op0)->mode);
2668 bool is_sse = SSE_FLOAT_MODE_SSEMATH_OR_HF_P (op_mode)((((((global_options.x_ix86_isa_flags & (1UL << 50)
) != 0) && (op_mode) == (scalar_float_mode ((scalar_float_mode
::from_int) E_SFmode))) || (((global_options.x_ix86_isa_flags
& (1UL << 51)) != 0) && (op_mode) == (scalar_float_mode
((scalar_float_mode::from_int) E_DFmode)))) && ((global_options
.x_ix86_fpmath & FPMATH_SSE) != 0)) || (((global_options.
x_ix86_isa_flags2 & (1UL << 7)) != 0) && (op_mode
) == (scalar_float_mode ((scalar_float_mode::from_int) E_HFmode
))))
;
2669
2670 if (op_mode == BFmode(scalar_float_mode ((scalar_float_mode::from_int) E_BFmode)))
2671 {
2672 rtx op = gen_lowpartrtl_hooks.gen_lowpart (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)), op0);
2673 if (CONST_INT_P (op)(((enum rtx_code) (op)->code) == CONST_INT))
2674 op = simplify_const_unary_operation (FLOAT_EXTEND, SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)),
2675 op0, BFmode(scalar_float_mode ((scalar_float_mode::from_int) E_BFmode)));
2676 else
2677 {
2678 rtx t1 = gen_reg_rtx (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2679 emit_insn (gen_zero_extendhisi2 (t1, op));
2680 emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16))));
2681 op = gen_lowpartrtl_hooks.gen_lowpart (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)), t1);
2682 }
2683 *pop0 = op;
2684 op = gen_lowpartrtl_hooks.gen_lowpart (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)), op1);
2685 if (CONST_INT_P (op)(((enum rtx_code) (op)->code) == CONST_INT))
2686 op = simplify_const_unary_operation (FLOAT_EXTEND, SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)),
2687 op1, BFmode(scalar_float_mode ((scalar_float_mode::from_int) E_BFmode)));
2688 else
2689 {
2690 rtx t1 = gen_reg_rtx (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)));
2691 emit_insn (gen_zero_extendhisi2 (t1, op));
2692 emit_insn (gen_ashlsi3 (t1, t1, GEN_INT (16)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (16))));
2693 op = gen_lowpartrtl_hooks.gen_lowpart (SFmode(scalar_float_mode ((scalar_float_mode::from_int) E_SFmode)), t1);
2694 }
2695 *pop1 = op;
2696 return ix86_prepare_fp_compare_args (code, pop0, pop1);
2697 }
2698
2699 /* All of the unordered compare instructions only work on registers.
2700 The same is true of the fcomi compare instructions. The XFmode
2701 compare instructions require registers except when comparing
2702 against zero or when converting operand 1 from fixed point to
2703 floating point. */
2704
2705 if (!is_sse
2706 && (unordered_compare
2707 || (op_mode == XFmode(scalar_float_mode ((scalar_float_mode::from_int) E_XFmode))
2708 && ! (standard_80387_constant_p (op0) == 1
2709 || standard_80387_constant_p (op1) == 1)
2710 && GET_CODE (op1)((enum rtx_code) (op1)->code) != FLOAT)
2711 || ix86_fp_comparison_strategy (code) == IX86_FPCMP_COMI))
2712 {
2713 op0 = force_reg (op_mode, op0);
2714 op1 = force_reg (op_mode, op1);
2715 }
2716 else
2717 {
2718 /* %%% We only allow op1 in memory; op0 must be st(0). So swap
2719 things around if they appear profitable, otherwise force op0
2720 into a register. */
2721
2722 if (standard_80387_constant_p (op0) == 0
2723 || (MEM_P (op0)(((enum rtx_code) (op0)->code) == MEM)
2724 && ! (standard_80387_constant_p (op1) == 0
2725 || MEM_P (op1)(((enum rtx_code) (op1)->code) == MEM))))
2726 {
2727 enum rtx_code new_code = ix86_fp_swap_condition (code);
2728 if (new_code != UNKNOWN)
2729 {
2730 std::swap (op0, op1);
2731 code = new_code;
2732 }
2733 }
2734
2735 if (!REG_P (op0)(((enum rtx_code) (op0)->code) == REG))
2736 op0 = force_reg (op_mode, op0);
2737
2738 if (CONSTANT_P (op1)((rtx_class[(int) (((enum rtx_code) (op1)->code))]) == RTX_CONST_OBJ
)
)
2739 {
2740 int tmp = standard_80387_constant_p (op1);
2741 if (tmp == 0)
2742 op1 = validize_mem (force_const_mem (op_mode, op1));
2743 else if (tmp == 1)
2744 {
2745 if (TARGET_CMOVE(ix86_arch_features[X86_ARCH_CMOV] || ((global_options.x_ix86_isa_flags
& (1UL << 50)) != 0) || ((global_options.x_ix86_isa_flags
& (1UL << 44)) != 0))
)
2746 op1 = force_reg (op_mode, op1);
2747 }
2748 else
2749 op1 = force_reg (op_mode, op1);
2750 }
2751 }
2752
2753 /* Try to rearrange the comparison to make it cheaper. */
2754 if (ix86_fp_comparison_cost (code)
2755 > ix86_fp_comparison_cost (swap_condition (code))
2756 && (REG_P (op1)(((enum rtx_code) (op1)->code) == REG) || can_create_pseudo_p ()(!reload_in_progress && !reload_completed)))
2757 {
2758 std::swap (op0, op1);
2759 code = swap_condition (code);
2760 if (!REG_P (op0)(((enum rtx_code) (op0)->code) == REG))
2761 op0 = force_reg (op_mode, op0);
2762 }
2763
2764 *pop0 = op0;
2765 *pop1 = op1;
2766 return code;
2767}
2768
2769/* Generate insn patterns to do a floating point compare of OPERANDS. */
2770
2771static rtx
2772ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1)
2773{
2774 bool unordered_compare = ix86_unordered_fp_compare (code);
2775 machine_mode cmp_mode;
2776 rtx tmp, scratch;
2777
2778 code = ix86_prepare_fp_compare_args (code, &op0, &op1);
2779
2780 tmp = gen_rtx_COMPARE (CCFPmode, op0, op1)gen_rtx_fmt_ee_stat ((COMPARE), ((((void) 0, E_CCFPmode))), (
(op0)), ((op1)) )
;
2781 if (unordered_compare)
2782 tmp = gen_rtx_UNSPEC (CCFPmode, gen_rtvec (1, tmp), UNSPEC_NOTRAP)gen_rtx_fmt_Ei_stat ((UNSPEC), ((((void) 0, E_CCFPmode))), ((
gen_rtvec (1, tmp))), ((UNSPEC_NOTRAP)) )
;
2783
2784 /* Do fcomi/sahf based test when profitable. */
2785 switch (ix86_fp_comparison_strategy (code))
2786 {
2787 case IX86_FPCMP_COMI:
2788 cmp_mode = CCFPmode((void) 0, E_CCFPmode);
2789 emit_insn (gen_rtx_SET (gen_rtx_REG (CCFPmode, FLAGS_REG), tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((gen_rtx_REG
(((void) 0, E_CCFPmode), 17))), ((tmp)) )
);
2790 break;
2791
2792 case IX86_FPCMP_SAHF:
2793 cmp_mode = CCFPmode((void) 0, E_CCFPmode);
2794 tmp = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW)gen_rtx_fmt_Ei_stat ((UNSPEC), (((scalar_int_mode ((scalar_int_mode
::from_int) E_HImode)))), ((gen_rtvec (1, tmp))), ((UNSPEC_FNSTSW
)) )
;
2795 scratch = gen_reg_rtx (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)));
2796 emit_insn (gen_rtx_SET (scratch, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((scratch
)), ((tmp)) )
);
2797 emit_insn (gen_x86_sahf_1 (scratch));
2798 break;
2799
2800 case IX86_FPCMP_ARITH:
2801 cmp_mode = CCNOmode((void) 0, E_CCNOmode);
2802 tmp = gen_rtx_UNSPEC (HImode, gen_rtvec (1, tmp), UNSPEC_FNSTSW)gen_rtx_fmt_Ei_stat ((UNSPEC), (((scalar_int_mode ((scalar_int_mode
::from_int) E_HImode)))), ((gen_rtvec (1, tmp))), ((UNSPEC_FNSTSW
)) )
;
2803 scratch = gen_reg_rtx (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)));
2804 emit_insn (gen_rtx_SET (scratch, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((scratch
)), ((tmp)) )
);
2805
2806 /* In the unordered case, we have to check C2 for NaN's, which
2807 doesn't happen to work out to anything nice combination-wise.
2808 So do some bit twiddling on the value we've got in AH to come
2809 up with an appropriate set of condition codes. */
2810
2811 switch (code)
2812 {
2813 case GT:
2814 case UNGT:
2815 if (code == GT || !TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2816 {
2817 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2818 code = EQ;
2819 }
2820 else
2821 {
2822 emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2823 emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx(const_int_rtx[64 -1])));
2824 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x44)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x44))));
2825 cmp_mode = CCmode((void) 0, E_CCmode);
2826 code = GEU;
2827 }
2828 break;
2829 case LT:
2830 case UNLT:
2831 if (code == LT && TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2832 {
2833 emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2834 emit_insn (gen_cmpqi_ext_3 (scratch, const1_rtx(const_int_rtx[64 +1])));
2835 cmp_mode = CCmode((void) 0, E_CCmode);
2836 code = EQ;
2837 }
2838 else
2839 {
2840 emit_insn (gen_testqi_ext_1_ccno (scratch, const1_rtx(const_int_rtx[64 +1])));
2841 code = NE;
2842 }
2843 break;
2844 case GE:
2845 case UNGE:
2846 if (code == GE || !TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2847 {
2848 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x05)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x05))));
2849 code = EQ;
2850 }
2851 else
2852 {
2853 emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2854 emit_insn (gen_xorqi_ext_1_cc (scratch, scratch, const1_rtx(const_int_rtx[64 +1])));
2855 code = NE;
2856 }
2857 break;
2858 case LE:
2859 case UNLE:
2860 if (code == LE && TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2861 {
2862 emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2863 emit_insn (gen_addqi_ext_1 (scratch, scratch, constm1_rtx(const_int_rtx[64 -1])));
2864 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x40))));
2865 cmp_mode = CCmode((void) 0, E_CCmode);
2866 code = LTU;
2867 }
2868 else
2869 {
2870 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2871 code = NE;
2872 }
2873 break;
2874 case EQ:
2875 case UNEQ:
2876 if (code == EQ && TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2877 {
2878 emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2879 emit_insn (gen_cmpqi_ext_3 (scratch, GEN_INT (0x40)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x40))));
2880 cmp_mode = CCmode((void) 0, E_CCmode);
2881 code = EQ;
2882 }
2883 else
2884 {
2885 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x40)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x40))));
2886 code = NE;
2887 }
2888 break;
2889 case NE:
2890 case LTGT:
2891 if (code == NE && TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
2892 {
2893 emit_insn (gen_andqi_ext_1 (scratch, scratch, GEN_INT (0x45)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x45))));
2894 emit_insn (gen_xorqi_ext_1_cc (scratch, scratch,
2895 GEN_INT (0x40)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x40))));
2896 code = NE;
2897 }
2898 else
2899 {
2900 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x40)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x40))));
2901 code = EQ;
2902 }
2903 break;
2904
2905 case UNORDERED:
2906 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x04)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x04))));
2907 code = NE;
2908 break;
2909 case ORDERED:
2910 emit_insn (gen_testqi_ext_1_ccno (scratch, GEN_INT (0x04)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (0x04))));
2911 code = EQ;
2912 break;
2913
2914 default:
2915 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2915, __FUNCTION__))
;
2916 }
2917 break;
2918
2919 default:
2920 gcc_unreachable()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2920, __FUNCTION__))
;
2921 }
2922
2923 /* Return the test that should be put into the flags user, i.e.
2924 the bcc, scc, or cmov instruction. */
2925 return gen_rtx_fmt_ee (code, VOIDmode,gen_rtx_fmt_ee_stat ((code), (((void) 0, E_VOIDmode)), (gen_rtx_REG
(cmp_mode, 17)), ((const_int_rtx[64])) )
2926 gen_rtx_REG (cmp_mode, FLAGS_REG),gen_rtx_fmt_ee_stat ((code), (((void) 0, E_VOIDmode)), (gen_rtx_REG
(cmp_mode, 17)), ((const_int_rtx[64])) )
2927 const0_rtx)gen_rtx_fmt_ee_stat ((code), (((void) 0, E_VOIDmode)), (gen_rtx_REG
(cmp_mode, 17)), ((const_int_rtx[64])) )
;
2928}
2929
2930/* Generate insn patterns to do an integer compare of OPERANDS. */
2931
2932static rtx
2933ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1)
2934{
2935 machine_mode cmpmode;
2936 rtx tmp, flags;
2937
2938 /* Swap operands to emit carry flag comparison. */
2939 if ((code == GTU || code == LEU)
2940 && nonimmediate_operand (op1, VOIDmode((void) 0, E_VOIDmode)))
2941 {
2942 std::swap (op0, op1);
2943 code = swap_condition (code);
2944 }
2945
2946 cmpmode = SELECT_CC_MODE (code, op0, op1)ix86_cc_mode ((code), (op0), (op1));
2947 flags = gen_rtx_REG (cmpmode, FLAGS_REG17);
2948
2949 /* This is very simple, but making the interface the same as in the
2950 FP case makes the rest of the code easier. */
2951 tmp = gen_rtx_COMPARE (cmpmode, op0, op1)gen_rtx_fmt_ee_stat ((COMPARE), ((cmpmode)), ((op0)), ((op1))
)
;
2952 emit_insn (gen_rtx_SET (flags, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((flags
)), ((tmp)) )
);
2953
2954 /* Return the test that should be put into the flags user, i.e.
2955 the bcc, scc, or cmov instruction. */
2956 return gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx)gen_rtx_fmt_ee_stat ((code), (((void) 0, E_VOIDmode)), (flags
), ((const_int_rtx[64])) )
;
2957}
2958
2959static rtx
2960ix86_expand_compare (enum rtx_code code, rtx op0, rtx op1)
2961{
2962 rtx ret;
2963
2964 if (GET_MODE_CLASS (GET_MODE (op0))((enum mode_class) mode_class[((machine_mode) (op0)->mode)
])
== MODE_CC)
2965 ret = gen_rtx_fmt_ee (code, VOIDmode, op0, op1)gen_rtx_fmt_ee_stat ((code), (((void) 0, E_VOIDmode)), (op0),
(op1) )
;
2966
2967 else if (SCALAR_FLOAT_MODE_P (GET_MODE (op0))(((enum mode_class) mode_class[((machine_mode) (op0)->mode
)]) == MODE_FLOAT || ((enum mode_class) mode_class[((machine_mode
) (op0)->mode)]) == MODE_DECIMAL_FLOAT)
)
2968 {
2969 gcc_assert (!DECIMAL_FLOAT_MODE_P (GET_MODE (op0)))((void)(!(!(((enum mode_class) mode_class[((machine_mode) (op0
)->mode)]) == MODE_DECIMAL_FLOAT)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2969, __FUNCTION__), 0 : 0))
;
2970 ret = ix86_expand_fp_compare (code, op0, op1);
2971 }
2972 else
2973 ret = ix86_expand_int_compare (code, op0, op1);
2974
2975 return ret;
2976}
2977
2978void
2979ix86_expand_setcc (rtx dest, enum rtx_code code, rtx op0, rtx op1)
2980{
2981 rtx ret;
2982
2983 gcc_assert (GET_MODE (dest) == QImode)((void)(!(((machine_mode) (dest)->mode) == (scalar_int_mode
((scalar_int_mode::from_int) E_QImode))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2983, __FUNCTION__), 0 : 0))
;
2984
2985 ret = ix86_expand_compare (code, op0, op1);
2986 PUT_MODE (ret, QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)));
2987 emit_insn (gen_rtx_SET (dest, ret)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((ret)) )
);
2988}
2989
2990/* Expand floating point op0 <=> op1, i.e.
2991 dest = op0 == op1 ? 0 : op0 < op1 ? -1 : op0 > op1 ? 1 : 2. */
2992
2993void
2994ix86_expand_fp_spaceship (rtx dest, rtx op0, rtx op1)
2995{
2996 gcc_checking_assert (ix86_fp_comparison_strategy (GT) != IX86_FPCMP_ARITH)((void)(!(ix86_fp_comparison_strategy (GT) != IX86_FPCMP_ARITH
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 2996, __FUNCTION__), 0 : 0))
;
2997 rtx gt = ix86_expand_fp_compare (GT, op0, op1);
2998 rtx l0 = gen_label_rtx ();
2999 rtx l1 = gen_label_rtx ();
3000 rtx l2 = TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0) ? gen_label_rtx () : NULL_RTX(rtx) 0;
3001 rtx lend = gen_label_rtx ();
3002 rtx tmp;
3003 rtx_insn *jmp;
3004 if (l2)
3005 {
3006 rtx un = gen_rtx_fmt_ee (UNORDERED, VOIDmode,gen_rtx_fmt_ee_stat ((UNORDERED), (((void) 0, E_VOIDmode)), (
gen_rtx_REG (((void) 0, E_CCFPmode), 17)), ((const_int_rtx[64
])) )
3007 gen_rtx_REG (CCFPmode, FLAGS_REG), const0_rtx)gen_rtx_fmt_ee_stat ((UNORDERED), (((void) 0, E_VOIDmode)), (
gen_rtx_REG (((void) 0, E_CCFPmode), 17)), ((const_int_rtx[64
])) )
;
3008 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, un,gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((un)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0, E_VOIDmode
))), ((l2)) ))), ((pc_rtx)) )
3009 gen_rtx_LABEL_REF (VOIDmode, l2), pc_rtx)gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((un)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0, E_VOIDmode
))), ((l2)) ))), ((pc_rtx)) )
;
3010 jmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((pc_rtx
)), ((tmp)) )
);
3011 add_reg_br_prob_note (jmp, profile_probability:: very_unlikely ());
3012 }
3013 rtx eq = gen_rtx_fmt_ee (UNEQ, VOIDmode,gen_rtx_fmt_ee_stat ((UNEQ), (((void) 0, E_VOIDmode)), (gen_rtx_REG
(((void) 0, E_CCFPmode), 17)), ((const_int_rtx[64])) )
3014 gen_rtx_REG (CCFPmode, FLAGS_REG), const0_rtx)gen_rtx_fmt_ee_stat ((UNEQ), (((void) 0, E_VOIDmode)), (gen_rtx_REG
(((void) 0, E_CCFPmode), 17)), ((const_int_rtx[64])) )
;
3015 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, eq,gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((eq)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0, E_VOIDmode
))), ((l0)) ))), ((pc_rtx)) )
3016 gen_rtx_LABEL_REF (VOIDmode, l0), pc_rtx)gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((eq)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0, E_VOIDmode
))), ((l0)) ))), ((pc_rtx)) )
;
3017 jmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((pc_rtx
)), ((tmp)) )
);
3018 add_reg_br_prob_note (jmp, profile_probability::unlikely ());
3019 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, gt,gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((gt)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0, E_VOIDmode
))), ((l1)) ))), ((pc_rtx)) )
3020 gen_rtx_LABEL_REF (VOIDmode, l1), pc_rtx)gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((((void) 0, E_VOIDmode
))), ((gt)), ((gen_rtx_fmt_u_stat ((LABEL_REF), ((((void) 0, E_VOIDmode
))), ((l1)) ))), ((pc_rtx)) )
;
3021 jmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((pc_rtx
)), ((tmp)) )
);
3022 add_reg_br_prob_note (jmp, profile_probability::even ());
3023 emit_move_insn (dest, constm1_rtx(const_int_rtx[64 -1]));
3024 emit_jump (lend);
3025 emit_label (l0);
3026 emit_move_insn (dest, const0_rtx(const_int_rtx[64]));
3027 emit_jump (lend);
3028 emit_label (l1);
3029 emit_move_insn (dest, const1_rtx(const_int_rtx[64 +1]));
3030 emit_jump (lend);
3031 if (l2)
3032 {
3033 emit_label (l2);
3034 emit_move_insn (dest, const2_rtx(const_int_rtx[64 +2]));
3035 }
3036 emit_label (lend);
3037}
3038
3039/* Expand comparison setting or clearing carry flag. Return true when
3040 successful and set pop for the operation. */
3041static bool
3042ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop)
3043{
3044 machine_mode mode
3045 = GET_MODE (op0)((machine_mode) (op0)->mode) != VOIDmode((void) 0, E_VOIDmode) ? GET_MODE (op0)((machine_mode) (op0)->mode) : GET_MODE (op1)((machine_mode) (op1)->mode);
3046
3047 /* Do not handle double-mode compares that go through special path. */
3048 if (mode == (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
? TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode)) : DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))))
3049 return false;
3050
3051 if (SCALAR_FLOAT_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_DECIMAL_FLOAT)
)
3052 {
3053 rtx compare_op;
3054 rtx_insn *compare_seq;
3055
3056 gcc_assert (!DECIMAL_FLOAT_MODE_P (mode))((void)(!(!(((enum mode_class) mode_class[mode]) == MODE_DECIMAL_FLOAT
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 3056, __FUNCTION__), 0 : 0))
;
3057
3058 /* Shortcut: following common codes never translate
3059 into carry flag compares. */
3060 if (code == EQ || code == NE || code == UNEQ || code == LTGT
3061 || code == ORDERED || code == UNORDERED)
3062 return false;
3063
3064 /* These comparisons require zero flag; swap operands so they won't. */
3065 if ((code == GT || code == UNLE || code == LE || code == UNGT)
3066 && !TARGET_IEEE_FP((global_options.x_target_flags & (1U << 13)) != 0))
3067 {
3068 std::swap (op0, op1);
3069 code = swap_condition (code);
3070 }
3071
3072 /* Try to expand the comparison and verify that we end up with
3073 carry flag based comparison. This fails to be true only when
3074 we decide to expand comparison using arithmetic that is not
3075 too common scenario. */
3076 start_sequence ();
3077 compare_op = ix86_expand_fp_compare (code, op0, op1);
3078 compare_seq = get_insns ();
3079 end_sequence ();
3080
3081 if (GET_MODE (XEXP (compare_op, 0))((machine_mode) ((((compare_op)->u.fld[0]).rt_rtx))->mode
)
== CCFPmode((void) 0, E_CCFPmode))
3082 code = ix86_fp_compare_code_to_integer (GET_CODE (compare_op)((enum rtx_code) (compare_op)->code));
3083 else
3084 code = GET_CODE (compare_op)((enum rtx_code) (compare_op)->code);
3085
3086 if (code != LTU && code != GEU)
3087 return false;
3088
3089 emit_insn (compare_seq);
3090 *pop = compare_op;
3091 return true;
3092 }
3093
3094 if (!INTEGRAL_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_INT || ((enum mode_class
) mode_class[mode]) == MODE_PARTIAL_INT || ((enum mode_class)
mode_class[mode]) == MODE_COMPLEX_INT || ((enum mode_class) mode_class
[mode]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[
mode]) == MODE_VECTOR_INT)
)
3095 return false;
3096
3097 switch (code)
3098 {
3099 case LTU:
3100 case GEU:
3101 break;
3102
3103 /* Convert a==0 into (unsigned)a<1. */
3104 case EQ:
3105 case NE:
3106 if (op1 != const0_rtx(const_int_rtx[64]))
3107 return false;
3108 op1 = const1_rtx(const_int_rtx[64 +1]);
3109 code = (code == EQ ? LTU : GEU);
3110 break;
3111
3112 /* Convert a>b into b<a or a>=b-1. */
3113 case GTU:
3114 case LEU:
3115 if (CONST_INT_P (op1)(((enum rtx_code) (op1)->code) == CONST_INT))
3116 {
3117 op1 = gen_int_mode (INTVAL (op1)((op1)->u.hwint[0]) + 1, GET_MODE (op0)((machine_mode) (op0)->mode));
3118 /* Bail out on overflow. We still can swap operands but that
3119 would force loading of the constant into register. */
3120 if (op1 == const0_rtx(const_int_rtx[64])
3121 || !x86_64_immediate_operand (op1, GET_MODE (op1)((machine_mode) (op1)->mode)))
3122 return false;
3123 code = (code == GTU ? GEU : LTU);
3124 }
3125 else
3126 {
3127 std::swap (op0, op1);
3128 code = (code == GTU ? LTU : GEU);
3129 }
3130 break;
3131
3132 /* Convert a>=0 into (unsigned)a<0x80000000. */
3133 case LT:
3134 case GE:
3135 if (mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)) || op1 != const0_rtx(const_int_rtx[64]))
3136 return false;
3137 op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode)((unsigned short) mode_to_bits (mode).coeffs[0]) - 1), mode);
3138 code = (code == LT ? GEU : LTU);
3139 break;
3140 case LE:
3141 case GT:
3142 if (mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)) || op1 != constm1_rtx(const_int_rtx[64 -1]))
3143 return false;
3144 op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode)((unsigned short) mode_to_bits (mode).coeffs[0]) - 1), mode);
3145 code = (code == LE ? GEU : LTU);
3146 break;
3147
3148 default:
3149 return false;
3150 }
3151 /* Swapping operands may cause constant to appear as first operand. */
3152 if (!nonimmediate_operand (op0, VOIDmode((void) 0, E_VOIDmode)))
3153 {
3154 if (!can_create_pseudo_p ()(!reload_in_progress && !reload_completed))
3155 return false;
3156 op0 = force_reg (mode, op0);
3157 }
3158 *pop = ix86_expand_compare (code, op0, op1);
3159 gcc_assert (GET_CODE (*pop) == LTU || GET_CODE (*pop) == GEU)((void)(!(((enum rtx_code) (*pop)->code) == LTU || ((enum rtx_code
) (*pop)->code) == GEU) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 3159, __FUNCTION__), 0 : 0))
;
3160 return true;
3161}
3162
3163/* Expand conditional increment or decrement using adb/sbb instructions.
3164 The default case using setcc followed by the conditional move can be
3165 done by generic code. */
3166bool
3167ix86_expand_int_addcc (rtx operands[])
3168{
3169 enum rtx_code code = GET_CODE (operands[1])((enum rtx_code) (operands[1])->code);
3170 rtx flags;
3171 rtx (*insn) (machine_mode, rtx, rtx, rtx, rtx, rtx);
3172 rtx compare_op;
3173 rtx val = const0_rtx(const_int_rtx[64]);
3174 bool fpcmp = false;
3175 machine_mode mode;
3176 rtx op0 = XEXP (operands[1], 0)(((operands[1])->u.fld[0]).rt_rtx);
3177 rtx op1 = XEXP (operands[1], 1)(((operands[1])->u.fld[1]).rt_rtx);
3178
3179 if (operands[3] != const1_rtx(const_int_rtx[64 +1])
3180 && operands[3] != constm1_rtx(const_int_rtx[64 -1]))
3181 return false;
3182 if (!ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
3183 return false;
3184 code = GET_CODE (compare_op)((enum rtx_code) (compare_op)->code);
3185
3186 flags = XEXP (compare_op, 0)(((compare_op)->u.fld[0]).rt_rtx);
3187
3188 if (GET_MODE (flags)((machine_mode) (flags)->mode) == CCFPmode((void) 0, E_CCFPmode))
3189 {
3190 fpcmp = true;
3191 code = ix86_fp_compare_code_to_integer (code);
3192 }
3193
3194 if (code != LTU)
3195 {
3196 val = constm1_rtx(const_int_rtx[64 -1]);
3197 if (fpcmp)
3198 PUT_CODE (compare_op,((compare_op)->code = (reverse_condition_maybe_unordered (
((enum rtx_code) (compare_op)->code))))
3199 reverse_condition_maybe_unordered((compare_op)->code = (reverse_condition_maybe_unordered (
((enum rtx_code) (compare_op)->code))))
3200 (GET_CODE (compare_op)))((compare_op)->code = (reverse_condition_maybe_unordered (
((enum rtx_code) (compare_op)->code))))
;
3201 else
3202 PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)))((compare_op)->code = (reverse_condition (((enum rtx_code)
(compare_op)->code))))
;
3203 }
3204
3205 mode = GET_MODE (operands[0])((machine_mode) (operands[0])->mode);
3206
3207 /* Construct either adc or sbb insn. */
3208 if ((code == LTU) == (operands[3] == constm1_rtx(const_int_rtx[64 -1])))
3209 insn = gen_sub3_carry;
3210 else
3211 insn = gen_add3_carry;
3212
3213 emit_insn (insn (mode, operands[0], operands[2], val, flags, compare_op));
3214
3215 return true;
3216}
3217
3218bool
3219ix86_expand_int_movcc (rtx operands[])
3220{
3221 enum rtx_code code = GET_CODE (operands[1])((enum rtx_code) (operands[1])->code), compare_code;
3222 rtx_insn *compare_seq;
3223 rtx compare_op;
3224 machine_mode mode = GET_MODE (operands[0])((machine_mode) (operands[0])->mode);
3225 bool sign_bit_compare_p = false;
3226 bool negate_cc_compare_p = false;
3227 rtx op0 = XEXP (operands[1], 0)(((operands[1])->u.fld[0]).rt_rtx);
3228 rtx op1 = XEXP (operands[1], 1)(((operands[1])->u.fld[1]).rt_rtx);
3229 rtx op2 = operands[2];
3230 rtx op3 = operands[3];
3231
3232 if (GET_MODE (op0)((machine_mode) (op0)->mode) == TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode))
3233 || (GET_MODE (op0)((machine_mode) (op0)->mode) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))
3234 && !TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
))
3235 return false;
3236
3237 if (GET_MODE (op0)((machine_mode) (op0)->mode) == BFmode(scalar_float_mode ((scalar_float_mode::from_int) E_BFmode))
3238 && !ix86_fp_comparison_operator (operands[1], VOIDmode((void) 0, E_VOIDmode)))
3239 return false;
3240
3241 start_sequence ();
3242 compare_op = ix86_expand_compare (code, op0, op1);
3243 compare_seq = get_insns ();
3244 end_sequence ();
3245
3246 compare_code = GET_CODE (compare_op)((enum rtx_code) (compare_op)->code);
3247
3248 if ((op1 == const0_rtx(const_int_rtx[64]) && (code == GE || code == LT))
3249 || (op1 == constm1_rtx(const_int_rtx[64 -1]) && (code == GT || code == LE)))
3250 sign_bit_compare_p = true;
3251
3252 /* op0 == op1 ? op0 : op3 is equivalent to op0 == op1 ? op1 : op3,
3253 but if op1 is a constant, the latter form allows more optimizations,
3254 either through the last 2 ops being constant handling, or the one
3255 constant and one variable cases. On the other side, for cmov the
3256 former might be better as we don't need to load the constant into
3257 another register. */
3258 if (code == EQ && CONST_INT_P (op1)(((enum rtx_code) (op1)->code) == CONST_INT) && rtx_equal_p (op0, op2))
3259 op2 = op1;
3260 /* Similarly for op0 != op1 ? op2 : op0 and op0 != op1 ? op2 : op1. */
3261 else if (code == NE && CONST_INT_P (op1)(((enum rtx_code) (op1)->code) == CONST_INT) && rtx_equal_p (op0, op3))
3262 op3 = op1;
3263
3264 /* Don't attempt mode expansion here -- if we had to expand 5 or 6
3265 HImode insns, we'd be swallowed in word prefix ops. */
3266
3267 if ((mode != HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)) || TARGET_FAST_PREFIXix86_tune_features[X86_TUNE_FAST_PREFIX])
3268 && (mode != (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
? TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode)) : DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))))
3269 && CONST_INT_P (op2)(((enum rtx_code) (op2)->code) == CONST_INT)
3270 && CONST_INT_P (op3)(((enum rtx_code) (op3)->code) == CONST_INT))
3271 {
3272 rtx out = operands[0];
3273 HOST_WIDE_INTlong ct = INTVAL (op2)((op2)->u.hwint[0]);
3274 HOST_WIDE_INTlong cf = INTVAL (op3)((op3)->u.hwint[0]);
3275 HOST_WIDE_INTlong diff;
3276
3277 if ((mode == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
3278 || (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
&& mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))))
3279 && (GET_MODE (op0)((machine_mode) (op0)->mode) == SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode))
3280 || (TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
&& GET_MODE (op0)((machine_mode) (op0)->mode) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)))))
3281 {
3282 /* Special case x != 0 ? -1 : y. */
3283 if (code == NE && op1 == const0_rtx(const_int_rtx[64]) && ct == -1)
3284 {
3285 negate_cc_compare_p = true;
3286 std::swap (ct, cf);
3287 code = EQ;
3288 }
3289 else if (code == EQ && op1 == const0_rtx(const_int_rtx[64]) && cf == -1)
3290 negate_cc_compare_p = true;
3291 }
3292
3293 diff = ct - cf;
3294 /* Sign bit compares are better done using shifts than we do by using
3295 sbb. */
3296 if (sign_bit_compare_p
3297 || negate_cc_compare_p
3298 || ix86_expand_carry_flag_compare (code, op0, op1, &compare_op))
3299 {
3300 /* Detect overlap between destination and compare sources. */
3301 rtx tmp = out;
3302
3303 if (negate_cc_compare_p)
3304 {
3305 if (GET_MODE (op0)((machine_mode) (op0)->mode) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)))
3306 emit_insn (gen_x86_negdi_ccc (gen_reg_rtx (DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))), op0));
3307 else
3308 emit_insn (gen_x86_negsi_ccc (gen_reg_rtx (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode))),
3309 gen_lowpartrtl_hooks.gen_lowpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), op0)));
3310
3311 tmp = gen_reg_rtx (mode);
3312 if (mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)))
3313 emit_insn (gen_x86_movdicc_0_m1_neg (tmp));
3314 else
3315 emit_insn (gen_x86_movsicc_0_m1_neg (gen_lowpartrtl_hooks.gen_lowpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)),
3316 tmp)));
3317 }
3318 else if (!sign_bit_compare_p)
3319 {
3320 rtx flags;
3321 bool fpcmp = false;
3322
3323 compare_code = GET_CODE (compare_op)((enum rtx_code) (compare_op)->code);
3324
3325 flags = XEXP (compare_op, 0)(((compare_op)->u.fld[0]).rt_rtx);
3326
3327 if (GET_MODE (flags)((machine_mode) (flags)->mode) == CCFPmode((void) 0, E_CCFPmode))
3328 {
3329 fpcmp = true;
3330 compare_code
3331 = ix86_fp_compare_code_to_integer (compare_code);
3332 }
3333
3334 /* To simplify rest of code, restrict to the GEU case. */
3335 if (compare_code == LTU)
3336 {
3337 std::swap (ct, cf);
3338 compare_code = reverse_condition (compare_code);
3339 code = reverse_condition (code);
3340 }
3341 else
3342 {
3343 if (fpcmp)
3344 PUT_CODE (compare_op,((compare_op)->code = (reverse_condition_maybe_unordered (
((enum rtx_code) (compare_op)->code))))
3345 reverse_condition_maybe_unordered((compare_op)->code = (reverse_condition_maybe_unordered (
((enum rtx_code) (compare_op)->code))))
3346 (GET_CODE (compare_op)))((compare_op)->code = (reverse_condition_maybe_unordered (
((enum rtx_code) (compare_op)->code))))
;
3347 else
3348 PUT_CODE (compare_op,((compare_op)->code = (reverse_condition (((enum rtx_code)
(compare_op)->code))))
3349 reverse_condition (GET_CODE (compare_op)))((compare_op)->code = (reverse_condition (((enum rtx_code)
(compare_op)->code))))
;
3350 }
3351 diff = ct - cf;
3352
3353 if (reg_overlap_mentioned_p (out, compare_op))
3354 tmp = gen_reg_rtx (mode);
3355
3356 if (mode == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode)))
3357 emit_insn (gen_x86_movdicc_0_m1 (tmp, flags, compare_op));
3358 else
3359 emit_insn (gen_x86_movsicc_0_m1 (gen_lowpartrtl_hooks.gen_lowpart (SImode(scalar_int_mode ((scalar_int_mode::from_int) E_SImode)), tmp),
3360 flags, compare_op));
3361 }
3362 else
3363 {
3364 if (code == GT || code == GE)
3365 code = reverse_condition (code);
3366 else
3367 {
3368 std::swap (ct, cf);
3369 diff = ct - cf;
3370 }
3371 tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode((void) 0, E_VOIDmode), 0, -1);
3372 }
3373
3374 if (diff == 1)
3375 {
3376 /*
3377 * cmpl op0,op1
3378 * sbbl dest,dest
3379 * [addl dest, ct]
3380 *
3381 * Size 5 - 8.
3382 */
3383 if (ct)
3384 tmp = expand_simple_binop (mode, PLUS,
3385 tmp, GEN_INT (ct)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (ct)),
3386 copy_rtx (tmp), 1, OPTAB_DIRECT);
3387 }
3388 else if (cf == -1)
3389 {
3390 /*
3391 * cmpl op0,op1
3392 * sbbl dest,dest
3393 * orl $ct, dest
3394 *
3395 * Size 8.
3396 */
3397 tmp = expand_simple_binop (mode, IOR,
3398 tmp, GEN_INT (ct)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (ct)),
3399 copy_rtx (tmp), 1, OPTAB_DIRECT);
3400 }
3401 else if (diff == -1 && ct)
3402 {
3403 /*
3404 * cmpl op0,op1
3405 * sbbl dest,dest
3406 * notl dest
3407 * [addl dest, cf]
3408 *
3409 * Size 8 - 11.
3410 */
3411 tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
3412 if (cf)
3413 tmp = expand_simple_binop (mode, PLUS,
3414 copy_rtx (tmp), GEN_INT (cf)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (cf)),
3415 copy_rtx (tmp), 1, OPTAB_DIRECT);
3416 }
3417 else
3418 {
3419 /*
3420 * cmpl op0,op1
3421 * sbbl dest,dest
3422 * [notl dest]
3423 * andl cf - ct, dest
3424 * [addl dest, ct]
3425 *
3426 * Size 8 - 11.
3427 */
3428
3429 if (cf == 0)
3430 {
3431 cf = ct;
3432 ct = 0;
3433 tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
3434 }
3435
3436 tmp = expand_simple_binop (mode, AND,
3437 copy_rtx (tmp),
3438 gen_int_mode (cf - ct, mode),
3439 copy_rtx (tmp), 1, OPTAB_DIRECT);
3440 if (ct)
3441 tmp = expand_simple_binop (mode, PLUS,
3442 copy_rtx (tmp), GEN_INT (ct)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (ct)),
3443 copy_rtx (tmp), 1, OPTAB_DIRECT);
3444 }
3445
3446 if (!rtx_equal_p (tmp, out))
3447 emit_move_insn (copy_rtx (out), copy_rtx (tmp));
3448
3449 return true;
3450 }
3451
3452 if (diff < 0)
3453 {
3454 machine_mode cmp_mode = GET_MODE (op0)((machine_mode) (op0)->mode);
3455 enum rtx_code new_code;
3456
3457 if (SCALAR_FLOAT_MODE_P (cmp_mode)(((enum mode_class) mode_class[cmp_mode]) == MODE_FLOAT || ((
enum mode_class) mode_class[cmp_mode]) == MODE_DECIMAL_FLOAT)
)
3458 {
3459 gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode))((void)(!(!(((enum mode_class) mode_class[cmp_mode]) == MODE_DECIMAL_FLOAT
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 3459, __FUNCTION__), 0 : 0))
;
3460
3461 /* We may be reversing a non-trapping
3462 comparison to a trapping comparison. */
3463 if (HONOR_NANS (cmp_mode) && flag_trapping_mathglobal_options.x_flag_trapping_math
3464 && code != EQ && code != NE
3465 && code != ORDERED && code != UNORDERED)
3466 new_code = UNKNOWN;
3467 else
3468 new_code = reverse_condition_maybe_unordered (code);
3469 }
3470 else
3471 new_code = ix86_reverse_condition (code, cmp_mode);
3472 if (new_code != UNKNOWN)
3473 {
3474 std::swap (ct, cf);
3475 diff = -diff;
3476 code = new_code;
3477 }
3478 }
3479
3480 compare_code = UNKNOWN;
3481 if (GET_MODE_CLASS (GET_MODE (op0))((enum mode_class) mode_class[((machine_mode) (op0)->mode)
])
== MODE_INT
3482 && CONST_INT_P (op1)(((enum rtx_code) (op1)->code) == CONST_INT))
3483 {
3484 if (op1 == const0_rtx(const_int_rtx[64])
3485 && (code == LT || code == GE))
3486 compare_code = code;
3487 else if (op1 == constm1_rtx(const_int_rtx[64 -1]))
3488 {
3489 if (code == LE)
3490 compare_code = LT;
3491 else if (code == GT)
3492 compare_code = GE;
3493 }
3494 }
3495
3496 /* Optimize dest = (op0 < 0) ? -1 : cf. */
3497 if (compare_code != UNKNOWN
3498 && GET_MODE (op0)((machine_mode) (op0)->mode) == GET_MODE (out)((machine_mode) (out)->mode)
3499 && (cf == -1 || ct == -1))
3500 {
3501 /* If lea code below could be used, only optimize
3502 if it results in a 2 insn sequence. */
3503
3504 if (! (diff == 1 || diff == 2 || diff == 4 || diff == 8
3505 || diff == 3 || diff == 5 || diff == 9)
3506 || (compare_code == LT && ct == -1)
3507 || (compare_code == GE && cf == -1))
3508 {
3509 /*
3510 * notl op1 (if necessary)
3511 * sarl $31, op1
3512 * orl cf, op1
3513 */
3514 if (ct != -1)
3515 {
3516 cf = ct;
3517 ct = -1;
3518 code = reverse_condition (code);
3519 }
3520
3521 out = emit_store_flag (out, code, op0, op1, VOIDmode((void) 0, E_VOIDmode), 0, -1);
3522
3523 out = expand_simple_binop (mode, IOR,
3524 out, GEN_INT (cf)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (cf)),
3525 out, 1, OPTAB_DIRECT);
3526 if (out != operands[0])
3527 emit_move_insn (operands[0], out);
3528
3529 return true;
3530 }
3531 }
3532
3533
3534 if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
3535 || diff == 3 || diff == 5 || diff == 9)
3536 && ((mode != QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)) && mode != HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode))) || !TARGET_PARTIAL_REG_STALLix86_tune_features[X86_TUNE_PARTIAL_REG_STALL])
3537 && (mode != DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))
3538 || x86_64_immediate_operand (GEN_INT (cf)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (cf)), VOIDmode((void) 0, E_VOIDmode))))
3539 {
3540 /*
3541 * xorl dest,dest
3542 * cmpl op1,op2
3543 * setcc dest
3544 * lea cf(dest*(ct-cf)),dest
3545 *
3546 * Size 14.
3547 *
3548 * This also catches the degenerate setcc-only case.
3549 */
3550
3551 rtx tmp;
3552 int nops;
3553
3554 out = emit_store_flag (out, code, op0, op1, VOIDmode((void) 0, E_VOIDmode), 0, 1);
3555
3556 nops = 0;
3557 /* On x86_64 the lea instruction operates on Pmode, so we need
3558 to get arithmetics done in proper mode to match. */
3559 if (diff == 1)
3560 tmp = copy_rtx (out);
3561 else
3562 {
3563 rtx out1;
3564 out1 = copy_rtx (out);
3565 tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1))gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((out1)), ((gen_rtx_CONST_INT
(((void) 0, E_VOIDmode), (diff & ~1)))) )
;
3566 nops++;
3567 if (diff & 1)
3568 {
3569 tmp = gen_rtx_PLUS (mode, tmp, out1)gen_rtx_fmt_ee_stat ((PLUS), ((mode)), ((tmp)), ((out1)) );
3570 nops++;
3571 }
3572 }
3573 if (cf != 0)
3574 {
3575 tmp = plus_constant (mode, tmp, cf);
3576 nops++;
3577 }
3578 if (!rtx_equal_p (tmp, out))
3579 {
3580 if (nops == 1)
3581 out = force_operand (tmp, copy_rtx (out));
3582 else
3583 emit_insn (gen_rtx_SET (copy_rtx (out), copy_rtx (tmp))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((copy_rtx
(out))), ((copy_rtx (tmp))) )
);
3584 }
3585 if (!rtx_equal_p (out, operands[0]))
3586 emit_move_insn (operands[0], copy_rtx (out));
3587
3588 return true;
3589 }
3590
3591 /*
3592 * General case: Jumpful:
3593 * xorl dest,dest cmpl op1, op2
3594 * cmpl op1, op2 movl ct, dest
3595 * setcc dest jcc 1f
3596 * decl dest movl cf, dest
3597 * andl (cf-ct),dest 1:
3598 * addl ct,dest
3599 *
3600 * Size 20. Size 14.
3601 *
3602 * This is reasonably steep, but branch mispredict costs are
3603 * high on modern cpus, so consider failing only if optimizing
3604 * for space.
3605 */
3606
3607 if ((!TARGET_CMOVE(ix86_arch_features[X86_ARCH_CMOV] || ((global_options.x_ix86_isa_flags
& (1UL << 50)) != 0) || ((global_options.x_ix86_isa_flags
& (1UL << 44)) != 0))
|| (mode == QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)) && TARGET_PARTIAL_REG_STALLix86_tune_features[X86_TUNE_PARTIAL_REG_STALL]))
3608 && BRANCH_COST (optimize_insn_for_speed_p (),(!(optimize_insn_for_speed_p ()) ? 2 : (false) ? 0 : global_options
.x_ix86_branch_cost)
3609 false)(!(optimize_insn_for_speed_p ()) ? 2 : (false) ? 0 : global_options
.x_ix86_branch_cost)
>= 2)
3610 {
3611 if (cf == 0)
3612 {
3613 machine_mode cmp_mode = GET_MODE (op0)((machine_mode) (op0)->mode);
3614 enum rtx_code new_code;
3615
3616 if (SCALAR_FLOAT_MODE_P (cmp_mode)(((enum mode_class) mode_class[cmp_mode]) == MODE_FLOAT || ((
enum mode_class) mode_class[cmp_mode]) == MODE_DECIMAL_FLOAT)
)
3617 {
3618 gcc_assert (!DECIMAL_FLOAT_MODE_P (cmp_mode))((void)(!(!(((enum mode_class) mode_class[cmp_mode]) == MODE_DECIMAL_FLOAT
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 3618, __FUNCTION__), 0 : 0))
;
3619
3620 /* We may be reversing a non-trapping
3621 comparison to a trapping comparison. */
3622 if (HONOR_NANS (cmp_mode) && flag_trapping_mathglobal_options.x_flag_trapping_math
3623 && code != EQ && code != NE
3624 && code != ORDERED && code != UNORDERED)
3625 new_code = UNKNOWN;
3626 else
3627 new_code = reverse_condition_maybe_unordered (code);
3628
3629 }
3630 else
3631 {
3632 new_code = ix86_reverse_condition (code, cmp_mode);
3633 if (compare_code != UNKNOWN && new_code != UNKNOWN)
3634 compare_code = reverse_condition (compare_code);
3635 }
3636
3637 if (new_code != UNKNOWN)
3638 {
3639 cf = ct;
3640 ct = 0;
3641 code = new_code;
3642 }
3643 }
3644
3645 if (compare_code != UNKNOWN)
3646 {
3647 /* notl op1 (if needed)
3648 sarl $31, op1
3649 andl (cf-ct), op1
3650 addl ct, op1
3651
3652 For x < 0 (resp. x <= -1) there will be no notl,
3653 so if possible swap the constants to get rid of the
3654 complement.
3655 True/false will be -1/0 while code below (store flag
3656 followed by decrement) is 0/-1, so the constants need
3657 to be exchanged once more. */
3658
3659 if (compare_code == GE || !cf)
3660 {
3661 code = reverse_condition (code);
3662 compare_code = LT;
3663 }
3664 else
3665 std::swap (ct, cf);
3666
3667 out = emit_store_flag (out, code, op0, op1, VOIDmode((void) 0, E_VOIDmode), 0, -1);
3668 }
3669 else
3670 {
3671 out = emit_store_flag (out, code, op0, op1, VOIDmode((void) 0, E_VOIDmode), 0, 1);
3672
3673 out = expand_simple_binop (mode, PLUS, copy_rtx (out),
3674 constm1_rtx(const_int_rtx[64 -1]),
3675 copy_rtx (out), 1, OPTAB_DIRECT);
3676 }
3677
3678 out = expand_simple_binop (mode, AND, copy_rtx (out),
3679 gen_int_mode (cf - ct, mode),
3680 copy_rtx (out), 1, OPTAB_DIRECT);
3681 if (ct)
3682 out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (ct)),
3683 copy_rtx (out), 1, OPTAB_DIRECT);
3684 if (!rtx_equal_p (out, operands[0]))
3685 emit_move_insn (operands[0], copy_rtx (out));
3686
3687 return true;
3688 }
3689 }
3690
3691 if (!TARGET_CMOVE(ix86_arch_features[X86_ARCH_CMOV] || ((global_options.x_ix86_isa_flags
& (1UL << 50)) != 0) || ((global_options.x_ix86_isa_flags
& (1UL << 44)) != 0))
|| (mode == QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)) && TARGET_PARTIAL_REG_STALLix86_tune_features[X86_TUNE_PARTIAL_REG_STALL]))
3692 {
3693 /* Try a few things more with specific constants and a variable. */
3694
3695 optab op;
3696 rtx var, orig_out, out, tmp;
3697
3698 if (BRANCH_COST (optimize_insn_for_speed_p (), false)(!(optimize_insn_for_speed_p ()) ? 2 : (false) ? 0 : global_options
.x_ix86_branch_cost)
<= 2)
3699 return false;
3700
3701 operands[2] = op2;
3702 operands[3] = op3;
3703
3704 /* If one of the two operands is an interesting constant, load a
3705 constant with the above and mask it in with a logical operation. */
3706
3707 if (CONST_INT_P (operands[2])(((enum rtx_code) (operands[2])->code) == CONST_INT))
3708 {
3709 var = operands[3];
3710 if (INTVAL (operands[2])((operands[2])->u.hwint[0]) == 0 && operands[3] != constm1_rtx(const_int_rtx[64 -1]))
3711 operands[3] = constm1_rtx(const_int_rtx[64 -1]), op = and_optab;
3712 else if (INTVAL (operands[2])((operands[2])->u.hwint[0]) == -1 && operands[3] != const0_rtx(const_int_rtx[64]))
3713 operands[3] = const0_rtx(const_int_rtx[64]), op = ior_optab;
3714 else
3715 return false;
3716 }
3717 else if (CONST_INT_P (operands[3])(((enum rtx_code) (operands[3])->code) == CONST_INT))
3718 {
3719 var = operands[2];
3720 if (INTVAL (operands[3])((operands[3])->u.hwint[0]) == 0 && operands[2] != constm1_rtx(const_int_rtx[64 -1]))
3721 {
3722 /* For smin (x, 0), expand as "x < 0 ? x : 0" instead of
3723 "x <= 0 ? x : 0" to enable sign_bit_compare_p. */
3724 if (code == LE && op1 == const0_rtx(const_int_rtx[64]) && rtx_equal_p (op0, var))
3725 operands[1] = simplify_gen_relational (LT, VOIDmode((void) 0, E_VOIDmode),
3726 GET_MODE (op0)((machine_mode) (op0)->mode),
3727 op0, const0_rtx(const_int_rtx[64]));
3728
3729 operands[2] = constm1_rtx(const_int_rtx[64 -1]);
3730 op = and_optab;
3731 }
3732 else if (INTVAL (operands[3])((operands[3])->u.hwint[0]) == -1 && operands[3] != const0_rtx(const_int_rtx[64]))
3733 operands[2] = const0_rtx(const_int_rtx[64]), op = ior_optab;
3734 else
3735 return false;
3736 }
3737 else
3738 return false;
3739
3740 orig_out = operands[0];
3741 tmp = gen_reg_rtx (mode);
3742 operands[0] = tmp;
3743
3744 /* Recurse to get the constant loaded. */
3745 if (!ix86_expand_int_movcc (operands))
3746 return false;
3747
3748 /* Mask in the interesting variable. */
3749 out = expand_binop (mode, op, var, tmp, orig_out, 0,
3750 OPTAB_WIDEN);
3751 if (!rtx_equal_p (out, orig_out))
3752 emit_move_insn (copy_rtx (orig_out), copy_rtx (out));
3753
3754 return true;
3755 }
3756
3757 /*
3758 * For comparison with above,
3759 *
3760 * movl cf,dest
3761 * movl ct,tmp
3762 * cmpl op1,op2
3763 * cmovcc tmp,dest
3764 *
3765 * Size 15.
3766 */
3767
3768 if (! nonimmediate_operand (operands[2], mode))
3769 operands[2] = force_reg (mode, operands[2]);
3770 if (! nonimmediate_operand (operands[3], mode))
3771 operands[3] = force_reg (mode, operands[3]);
3772
3773 if (! register_operand (operands[2], VOIDmode((void) 0, E_VOIDmode))
3774 && (mode == QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode))
3775 || ! register_operand (operands[3], VOIDmode((void) 0, E_VOIDmode))))
3776 operands[2] = force_reg (mode, operands[2]);
3777
3778 if (mode == QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode))
3779 && ! register_operand (operands[3], VOIDmode((void) 0, E_VOIDmode)))
3780 operands[3] = force_reg (mode, operands[3]);
3781
3782 emit_insn (compare_seq);
3783 emit_insn (gen_rtx_SET (operands[0],gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
3784 gen_rtx_IF_THEN_ELSE (mode,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
3785 compare_op, operands[2],gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
3786 operands[3]))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
);
3787 return true;
3788}
3789
3790/* Detect conditional moves that exactly match min/max operational
3791 semantics. Note that this is IEEE safe, as long as we don't
3792 interchange the operands.
3793
3794 Returns FALSE if this conditional move doesn't match a MIN/MAX,
3795 and TRUE if the operation is successful and instructions are emitted. */
3796
3797static bool
3798ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0,
3799 rtx cmp_op1, rtx if_true, rtx if_false)
3800{
3801 machine_mode mode;
3802 bool is_min;
3803 rtx tmp;
3804
3805 if (code == LT)
3806 ;
3807 else if (code == UNGE)
3808 std::swap (if_true, if_false);
3809 else
3810 return false;
3811
3812 if (rtx_equal_p (cmp_op0, if_true) && rtx_equal_p (cmp_op1, if_false))
3813 is_min = true;
3814 else if (rtx_equal_p (cmp_op1, if_true) && rtx_equal_p (cmp_op0, if_false))
3815 is_min = false;
3816 else
3817 return false;
3818
3819 mode = GET_MODE (dest)((machine_mode) (dest)->mode);
3820
3821 /* We want to check HONOR_NANS and HONOR_SIGNED_ZEROS here,
3822 but MODE may be a vector mode and thus not appropriate. */
3823 if (!flag_finite_math_onlyglobal_options.x_flag_finite_math_only || flag_signed_zerosglobal_options.x_flag_signed_zeros)
3824 {
3825 int u = is_min ? UNSPEC_IEEE_MIN : UNSPEC_IEEE_MAX;
3826 rtvec v;
3827
3828 if_true = force_reg (mode, if_true);
3829 v = gen_rtvec (2, if_true, if_false);
3830 tmp = gen_rtx_UNSPEC (mode, v, u)gen_rtx_fmt_Ei_stat ((UNSPEC), ((mode)), ((v)), ((u)) );
3831 }
3832 else
3833 {
3834 code = is_min ? SMIN : SMAX;
3835 if (MEM_P (if_true)(((enum rtx_code) (if_true)->code) == MEM) && MEM_P (if_false)(((enum rtx_code) (if_false)->code) == MEM))
3836 if_true = force_reg (mode, if_true);
3837 tmp = gen_rtx_fmt_ee (code, mode, if_true, if_false)gen_rtx_fmt_ee_stat ((code), (mode), (if_true), (if_false) );
3838 }
3839
3840 emit_insn (gen_rtx_SET (dest, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((tmp)) )
);
3841 return true;
3842}
3843
3844/* Return true if MODE is valid for vector compare to mask register,
3845 Same result for conditionl vector move with mask register. */
3846static bool
3847ix86_valid_mask_cmp_mode (machine_mode mode)
3848{
3849 /* XOP has its own vector conditional movement. */
3850 if (TARGET_XOP((global_options.x_ix86_isa_flags & (1UL << 59)) !=
0)
&& !TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
)
3851 return false;
3852
3853 /* HFmode only supports vcmpsh whose dest is mask register. */
3854 if (TARGET_AVX512FP16((global_options.x_ix86_isa_flags2 & (1UL << 7)) !=
0)
&& mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
3855 return true;
3856
3857 /* AVX512F is needed for mask operation. */
3858 if (!(TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
&& VECTOR_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_VECTOR_BOOL || (
(enum mode_class) mode_class[mode]) == MODE_VECTOR_INT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FRACT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_UFRACT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_ACCUM || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_UACCUM)
))
3859 return false;
3860
3861 /* AVX512BW is needed for vector QI/HImode,
3862 AVX512VL is needed for 128/256-bit vector. */
3863 machine_mode inner_mode = GET_MODE_INNER (mode)(mode_to_inner (mode));
3864 int vector_size = GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]);
3865 if ((inner_mode == QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)) || inner_mode == HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode))) && !TARGET_AVX512BW((global_options.x_ix86_isa_flags & (1UL << 11)) !=
0)
)
3866 return false;
3867
3868 return vector_size == 64 || TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
;
3869}
3870
3871/* Return true if integer mask comparison should be used. */
3872static bool
3873ix86_use_mask_cmp_p (machine_mode mode, machine_mode cmp_mode,
3874 rtx op_true, rtx op_false)
3875{
3876 int vector_size = GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]);
3877
3878 if (cmp_mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
3879 return true;
3880 else if (vector_size < 16)
3881 return false;
3882 else if (vector_size == 64)
3883 return true;
3884 else if (GET_MODE_INNER (cmp_mode)(mode_to_inner (cmp_mode)) == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
3885 return true;
3886
3887 /* When op_true is NULL, op_false must be NULL, or vice versa. */
3888 gcc_assert (!op_true == !op_false)((void)(!(!op_true == !op_false) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 3888, __FUNCTION__), 0 : 0))
;
3889
3890 /* When op_true/op_false is NULL or cmp_mode is not valid mask cmp mode,
3891 vector dest is required. */
3892 if (!op_true || !ix86_valid_mask_cmp_mode (cmp_mode))
3893 return false;
3894
3895 /* Exclude those that could be optimized in ix86_expand_sse_movcc. */
3896 if (op_false == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)])
3897 || op_true == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)])
3898 || (INTEGRAL_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_INT || ((enum mode_class
) mode_class[mode]) == MODE_PARTIAL_INT || ((enum mode_class)
mode_class[mode]) == MODE_COMPLEX_INT || ((enum mode_class) mode_class
[mode]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[
mode]) == MODE_VECTOR_INT)
3899 && (op_true == CONSTM1_RTX (mode)(const_tiny_rtx[3][(int) (mode)])
3900 || op_false == CONSTM1_RTX (mode)(const_tiny_rtx[3][(int) (mode)]))))
3901 return false;
3902
3903 return true;
3904}
3905
3906/* Expand an SSE comparison. Return the register with the result. */
3907
3908static rtx
3909ix86_expand_sse_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1,
3910 rtx op_true, rtx op_false)
3911{
3912 machine_mode mode = GET_MODE (dest)((machine_mode) (dest)->mode);
3913 machine_mode cmp_ops_mode = GET_MODE (cmp_op0)((machine_mode) (cmp_op0)->mode);
3914
3915 /* In general case result of comparison can differ from operands' type. */
3916 machine_mode cmp_mode;
3917
3918 /* In AVX512F the result of comparison is an integer mask. */
3919 bool maskcmp = false;
3920 rtx x;
3921
3922 if (ix86_use_mask_cmp_p (mode, cmp_ops_mode, op_true, op_false))
3923 {
3924 unsigned int nbits = GET_MODE_NUNITS (cmp_ops_mode)(mode_to_nunits (cmp_ops_mode).coeffs[0]);
3925 maskcmp = true;
3926 cmp_mode = nbits > 8 ? int_mode_for_size (nbits, 0).require () : E_QImode;
3927 }
3928 else
3929 cmp_mode = cmp_ops_mode;
3930
3931 cmp_op0 = force_reg (cmp_ops_mode, cmp_op0);
3932
3933 bool (*op1_predicate)(rtx, machine_mode)
3934 = VECTOR_MODE_P (cmp_ops_mode)(((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_BOOL
|| ((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_INT
|| ((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[cmp_ops_mode]) == MODE_VECTOR_UACCUM
)
? vector_operand : nonimmediate_operand;
3935
3936 if (!op1_predicate (cmp_op1, cmp_ops_mode))
3937 cmp_op1 = force_reg (cmp_ops_mode, cmp_op1);
3938
3939 if (optimizeglobal_options.x_optimize
3940 || (maskcmp && cmp_mode != mode)
3941 || (op_true && reg_overlap_mentioned_p (dest, op_true))
3942 || (op_false && reg_overlap_mentioned_p (dest, op_false)))
3943 dest = gen_reg_rtx (maskcmp ? cmp_mode : mode);
3944
3945 if (maskcmp)
3946 {
3947 bool ok = ix86_expand_mask_vec_cmp (dest, code, cmp_op0, cmp_op1);
3948 gcc_assert (ok)((void)(!(ok) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 3948, __FUNCTION__), 0 : 0))
;
3949 return dest;
3950 }
3951
3952 x = gen_rtx_fmt_ee (code, cmp_mode, cmp_op0, cmp_op1)gen_rtx_fmt_ee_stat ((code), (cmp_mode), (cmp_op0), (cmp_op1)
)
;
3953
3954 if (cmp_mode != mode)
3955 {
3956 x = force_reg (cmp_ops_mode, x);
3957 convert_move (dest, x, false);
3958 }
3959 else
3960 emit_insn (gen_rtx_SET (dest, x)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((x)) )
);
3961
3962 return dest;
3963}
3964
3965/* Emit x86 binary operand CODE in mode MODE for SSE vector
3966 instructions that can be performed using GP registers. */
3967
3968static void
3969ix86_emit_vec_binop (enum rtx_code code, machine_mode mode,
3970 rtx dst, rtx src1, rtx src2)
3971{
3972 rtx tmp;
3973
3974 tmp = gen_rtx_SET (dst, gen_rtx_fmt_ee (code, mode, src1, src2))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dst))
, ((gen_rtx_fmt_ee_stat ((code), (mode), (src1), (src2) ))) )
;
3975
3976 if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) <= GET_MODE_SIZE (SImode)((unsigned short) mode_to_bytes ((scalar_int_mode ((scalar_int_mode
::from_int) E_SImode))).coeffs[0])
3977 && GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_VECTOR_INT)
3978 {
3979 rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG))gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
gen_rtx_REG (((void) 0, E_CCmode), 17))) )
;
3980 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, tmp, clob))) )
;
3981 }
3982
3983 emit_insn (tmp);
3984}
3985
3986/* Expand DEST = CMP ? OP_TRUE : OP_FALSE into a sequence of logical
3987 operations. This is used for both scalar and vector conditional moves. */
3988
3989void
3990ix86_expand_sse_movcc (rtx dest, rtx cmp, rtx op_true, rtx op_false)
3991{
3992 machine_mode mode = GET_MODE (dest)((machine_mode) (dest)->mode);
3993 machine_mode cmpmode = GET_MODE (cmp)((machine_mode) (cmp)->mode);
3994 rtx x;
3995
3996 /* Simplify trivial VEC_COND_EXPR to avoid ICE in pr97506. */
3997 if (rtx_equal_p (op_true, op_false))
3998 {
3999 emit_move_insn (dest, op_true);
4000 return;
4001 }
4002
4003 /* If we have an integer mask and FP value then we need
4004 to cast mask to FP mode. */
4005 if (mode != cmpmode && VECTOR_MODE_P (cmpmode)(((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_BOOL ||
((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_INT ||
((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_FLOAT
|| ((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_FRACT
|| ((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_UFRACT
|| ((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_ACCUM
|| ((enum mode_class) mode_class[cmpmode]) == MODE_VECTOR_UACCUM
)
)
4006 {
4007 cmp = force_reg (cmpmode, cmp);
4008 cmp = gen_rtx_SUBREG (mode, cmp, 0);
4009 }
4010
4011 /* In AVX512F the result of comparison is an integer mask. */
4012 if (mode != cmpmode
4013 && GET_MODE_CLASS (cmpmode)((enum mode_class) mode_class[cmpmode]) == MODE_INT)
4014 {
4015 gcc_assert (ix86_valid_mask_cmp_mode (mode))((void)(!(ix86_valid_mask_cmp_mode (mode)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4015, __FUNCTION__), 0 : 0))
;
4016 /* Using scalar/vector move with mask register. */
4017 cmp = force_reg (cmpmode, cmp);
4018 /* Optimize for mask zero. */
4019 op_true = (op_true != CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)])
4020 ? force_reg (mode, op_true) : op_true);
4021 op_false = (op_false != CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)])
4022 ? force_reg (mode, op_false) : op_false);
4023 if (op_true == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)]))
4024 {
4025 if (cmpmode == E_DImode && !TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
)
4026 {
4027 x = gen_reg_rtx (cmpmode);
4028 emit_insn (gen_knotdi (x, cmp));
4029 }
4030 else
4031 x = expand_simple_unop (cmpmode, NOT, cmp, NULL__null, 1);
4032 cmp = x;
4033 /* Reverse op_true op_false. */
4034 std::swap (op_true, op_false);
4035 }
4036
4037 if (mode == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
4038 emit_insn (gen_movhf_mask (dest, op_true, op_false, cmp));
4039 else
4040 emit_insn (gen_rtx_SET (dest,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_eee_stat ((VEC_MERGE), ((mode)), ((op_true))
, ((op_false)), ((cmp)) ))) )
4041 gen_rtx_VEC_MERGE (mode,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_eee_stat ((VEC_MERGE), ((mode)), ((op_true))
, ((op_false)), ((cmp)) ))) )
4042 op_true, op_false, cmp))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_eee_stat ((VEC_MERGE), ((mode)), ((op_true))
, ((op_false)), ((cmp)) ))) )
);
4043 return;
4044 }
4045
4046 if (vector_all_ones_operand (op_true, mode)
4047 && op_false == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)]))
4048 {
4049 emit_move_insn (dest, cmp);
4050 return;
4051 }
4052 else if (op_false == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)]))
4053 {
4054 x = expand_simple_binop (mode, AND, cmp, op_true,
4055 dest, 1, OPTAB_DIRECT);
4056 if (x != dest)
4057 emit_move_insn (dest, x);
4058 return;
4059 }
4060 else if (op_true == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)]))
4061 {
4062 op_false = force_reg (mode, op_false);
4063 x = gen_rtx_NOT (mode, cmp)gen_rtx_fmt_e_stat ((NOT), ((mode)), ((cmp)) );
4064 ix86_emit_vec_binop (AND, mode, dest, x, op_false);
4065 return;
4066 }
4067 else if (vector_all_ones_operand (op_true, mode))
4068 {
4069 x = expand_simple_binop (mode, IOR, cmp, op_false,
4070 dest, 1, OPTAB_DIRECT);
4071 if (x != dest)
4072 emit_move_insn (dest, x);
4073 return;
4074 }
4075
4076 if (TARGET_XOP((global_options.x_ix86_isa_flags & (1UL << 59)) !=
0)
)
4077 {
4078 op_true = force_reg (mode, op_true);
4079
4080 if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) < 16
4081 || !nonimmediate_operand (op_false, mode))
4082 op_false = force_reg (mode, op_false);
4083
4084 emit_insn (gen_rtx_SET (dest,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((cmp)),
((op_true)), ((op_false)) ))) )
4085 gen_rtx_IF_THEN_ELSE (mode, cmp,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((cmp)),
((op_true)), ((op_false)) ))) )
4086 op_true, op_false))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((cmp)),
((op_true)), ((op_false)) ))) )
);
4087 return;
4088 }
4089
4090 rtx (*gen) (rtx, rtx, rtx, rtx) = NULL__null;
4091 machine_mode blend_mode = mode;
4092
4093 if (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) < 16
4094 || !vector_operand (op_true, mode))
4095 op_true = force_reg (mode, op_true);
4096
4097 op_false = force_reg (mode, op_false);
4098
4099 switch (mode)
4100 {
4101 case E_V2SFmode:
4102 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4103 gen = gen_mmx_blendvps;
4104 break;
4105 case E_V4SFmode:
4106 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4107 gen = gen_sse4_1_blendvps;
4108 break;
4109 case E_V2DFmode:
4110 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4111 gen = gen_sse4_1_blendvpd;
4112 break;
4113 case E_SFmode:
4114 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4115 gen = gen_sse4_1_blendvss;
4116 break;
4117 case E_DFmode:
4118 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4119 gen = gen_sse4_1_blendvsd;
4120 break;
4121 case E_V8QImode:
4122 case E_V4HImode:
4123 case E_V2SImode:
4124 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4125 {
4126 gen = gen_mmx_pblendvb_v8qi;
4127 blend_mode = V8QImode((void) 0, E_V8QImode);
4128 }
4129 break;
4130 case E_V4QImode:
4131 case E_V2HImode:
4132 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4133 {
4134 gen = gen_mmx_pblendvb_v4qi;
4135 blend_mode = V4QImode((void) 0, E_V4QImode);
4136 }
4137 break;
4138 case E_V2QImode:
4139 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4140 gen = gen_mmx_pblendvb_v2qi;
4141 break;
4142 case E_V16QImode:
4143 case E_V8HImode:
4144 case E_V8HFmode:
4145 case E_V8BFmode:
4146 case E_V4SImode:
4147 case E_V2DImode:
4148 case E_V1TImode:
4149 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4150 {
4151 gen = gen_sse4_1_pblendvb;
4152 blend_mode = V16QImode((void) 0, E_V16QImode);
4153 }
4154 break;
4155 case E_V8SFmode:
4156 if (TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
)
4157 gen = gen_avx_blendvps256;
4158 break;
4159 case E_V4DFmode:
4160 if (TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
)
4161 gen = gen_avx_blendvpd256;
4162 break;
4163 case E_V32QImode:
4164 case E_V16HImode:
4165 case E_V16HFmode:
4166 case E_V16BFmode:
4167 case E_V8SImode:
4168 case E_V4DImode:
4169 if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
)
4170 {
4171 gen = gen_avx2_pblendvb;
4172 blend_mode = V32QImode((void) 0, E_V32QImode);
4173 }
4174 break;
4175
4176 case E_V64QImode:
4177 gen = gen_avx512bw_blendmv64qi;
4178 break;
4179 case E_V32HImode:
4180 gen = gen_avx512bw_blendmv32hi;
4181 break;
4182 case E_V32HFmode:
4183 gen = gen_avx512bw_blendmv32hf;
4184 break;
4185 case E_V32BFmode:
4186 gen = gen_avx512bw_blendmv32bf;
4187 break;
4188 case E_V16SImode:
4189 gen = gen_avx512f_blendmv16si;
4190 break;
4191 case E_V8DImode:
4192 gen = gen_avx512f_blendmv8di;
4193 break;
4194 case E_V8DFmode:
4195 gen = gen_avx512f_blendmv8df;
4196 break;
4197 case E_V16SFmode:
4198 gen = gen_avx512f_blendmv16sf;
4199 break;
4200
4201 default:
4202 break;
4203 }
4204
4205 if (gen != NULL__null)
4206 {
4207 if (blend_mode == mode)
4208 x = dest;
4209 else
4210 {
4211 x = gen_reg_rtx (blend_mode);
4212 op_false = gen_lowpartrtl_hooks.gen_lowpart (blend_mode, op_false);
4213 op_true = gen_lowpartrtl_hooks.gen_lowpart (blend_mode, op_true);
4214 cmp = gen_lowpartrtl_hooks.gen_lowpart (blend_mode, cmp);
4215 }
4216
4217 emit_insn (gen (x, op_false, op_true, cmp));
4218
4219 if (x != dest)
4220 emit_move_insn (dest, gen_lowpartrtl_hooks.gen_lowpart (mode, x));
4221 }
4222 else
4223 {
4224 rtx t2, t3;
4225
4226 t2 = expand_simple_binop (mode, AND, op_true, cmp,
4227 NULL__null, 1, OPTAB_DIRECT);
4228
4229 t3 = gen_reg_rtx (mode);
4230 x = gen_rtx_NOT (mode, cmp)gen_rtx_fmt_e_stat ((NOT), ((mode)), ((cmp)) );
4231 ix86_emit_vec_binop (AND, mode, t3, x, op_false);
4232
4233 x = expand_simple_binop (mode, IOR, t3, t2,
4234 dest, 1, OPTAB_DIRECT);
4235 if (x != dest)
4236 emit_move_insn (dest, x);
4237 }
4238}
4239
4240/* Swap, force into registers, or otherwise massage the two operands
4241 to an sse comparison with a mask result. Thus we differ a bit from
4242 ix86_prepare_fp_compare_args which expects to produce a flags result.
4243
4244 The DEST operand exists to help determine whether to commute commutative
4245 operators. The POP0/POP1 operands are updated in place. The new
4246 comparison code is returned, or UNKNOWN if not implementable. */
4247
4248static enum rtx_code
4249ix86_prepare_sse_fp_compare_args (rtx dest, enum rtx_code code,
4250 rtx *pop0, rtx *pop1)
4251{
4252 switch (code)
4253 {
4254 case LTGT:
4255 case UNEQ:
4256 /* AVX supports all the needed comparisons. */
4257 if (TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
)
4258 break;
4259 /* We have no LTGT as an operator. We could implement it with
4260 NE & ORDERED, but this requires an extra temporary. It's
4261 not clear that it's worth it. */
4262 return UNKNOWN;
4263
4264 case LT:
4265 case LE:
4266 case UNGT:
4267 case UNGE:
4268 /* These are supported directly. */
4269 break;
4270
4271 case EQ:
4272 case NE:
4273 case UNORDERED:
4274 case ORDERED:
4275 /* AVX has 3 operand comparisons, no need to swap anything. */
4276 if (TARGET_AVX((global_options.x_ix86_isa_flags & (1UL << 8)) != 0
)
)
4277 break;
4278 /* For commutative operators, try to canonicalize the destination
4279 operand to be first in the comparison - this helps reload to
4280 avoid extra moves. */
4281 if (!dest || !rtx_equal_p (dest, *pop1))
4282 break;
4283 /* FALLTHRU */
4284
4285 case GE:
4286 case GT:
4287 case UNLE:
4288 case UNLT:
4289 /* These are not supported directly before AVX, and furthermore
4290 ix86_expand_sse_fp_minmax only optimizes LT/UNGE. Swap the
4291 comparison operands to transform into something that is
4292 supported. */
4293 std::swap (*pop0, *pop1);
4294 code = swap_condition (code);
4295 break;
4296
4297 default:
4298 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4298, __FUNCTION__))
;
4299 }
4300
4301 return code;
4302}
4303
4304/* Expand a floating-point conditional move. Return true if successful. */
4305
4306bool
4307ix86_expand_fp_movcc (rtx operands[])
4308{
4309 machine_mode mode = GET_MODE (operands[0])((machine_mode) (operands[0])->mode);
4310 enum rtx_code code = GET_CODE (operands[1])((enum rtx_code) (operands[1])->code);
4311 rtx tmp, compare_op;
4312 rtx op0 = XEXP (operands[1], 0)(((operands[1])->u.fld[0]).rt_rtx);
4313 rtx op1 = XEXP (operands[1], 1)(((operands[1])->u.fld[1]).rt_rtx);
4314
4315 if (GET_MODE (op0)((machine_mode) (op0)->mode) == BFmode(scalar_float_mode ((scalar_float_mode::from_int) E_BFmode))
4316 && !ix86_fp_comparison_operator (operands[1], VOIDmode((void) 0, E_VOIDmode)))
4317 return false;
4318
4319 if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode)((((((global_options.x_ix86_isa_flags & (1UL << 50)
) != 0) && (mode) == (scalar_float_mode ((scalar_float_mode
::from_int) E_SFmode))) || (((global_options.x_ix86_isa_flags
& (1UL << 51)) != 0) && (mode) == (scalar_float_mode
((scalar_float_mode::from_int) E_DFmode)))) && ((global_options
.x_ix86_fpmath & FPMATH_SSE) != 0)) || (((global_options.
x_ix86_isa_flags2 & (1UL << 7)) != 0) && (mode
) == (scalar_float_mode ((scalar_float_mode::from_int) E_HFmode
))))
)
4320 {
4321 machine_mode cmode;
4322
4323 /* Since we've no cmove for sse registers, don't force bad register
4324 allocation just to gain access to it. Deny movcc when the
4325 comparison mode doesn't match the move mode. */
4326 cmode = GET_MODE (op0)((machine_mode) (op0)->mode);
4327 if (cmode == VOIDmode((void) 0, E_VOIDmode))
4328 cmode = GET_MODE (op1)((machine_mode) (op1)->mode);
4329 if (cmode != mode)
4330 return false;
4331
4332 code = ix86_prepare_sse_fp_compare_args (operands[0], code, &op0, &op1);
4333 if (code == UNKNOWN)
4334 return false;
4335
4336 if (ix86_expand_sse_fp_minmax (operands[0], code, op0, op1,
4337 operands[2], operands[3]))
4338 return true;
4339
4340 tmp = ix86_expand_sse_cmp (operands[0], code, op0, op1,
4341 operands[2], operands[3]);
4342 ix86_expand_sse_movcc (operands[0], tmp, operands[2], operands[3]);
4343 return true;
4344 }
4345
4346 if (GET_MODE (op0)((machine_mode) (op0)->mode) == TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode))
4347 || (GET_MODE (op0)((machine_mode) (op0)->mode) == DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))
4348 && !TARGET_64BIT((global_options.x_ix86_isa_flags & (1UL << 1)) != 0
)
))
4349 return false;
4350
4351 /* The floating point conditional move instructions don't directly
4352 support conditions resulting from a signed integer comparison. */
4353
4354 compare_op = ix86_expand_compare (code, op0, op1);
4355 if (!fcmov_comparison_operator (compare_op, VOIDmode((void) 0, E_VOIDmode)))
4356 {
4357 tmp = gen_reg_rtx (QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode)));
4358 ix86_expand_setcc (tmp, code, op0, op1);
4359
4360 compare_op = ix86_expand_compare (NE, tmp, const0_rtx(const_int_rtx[64]));
4361 }
4362
4363 emit_insn (gen_rtx_SET (operands[0],gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
4364 gen_rtx_IF_THEN_ELSE (mode, compare_op,gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
4365 operands[2], operands[3]))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((operands
[0])), ((gen_rtx_fmt_eee_stat ((IF_THEN_ELSE), ((mode)), ((compare_op
)), ((operands[2])), ((operands[3])) ))) )
);
4366
4367 return true;
4368}
4369
4370/* Helper for ix86_cmp_code_to_pcmp_immediate for int modes. */
4371
4372static int
4373ix86_int_cmp_code_to_pcmp_immediate (enum rtx_code code)
4374{
4375 switch (code)
4376 {
4377 case EQ:
4378 return 0;
4379 case LT:
4380 case LTU:
4381 return 1;
4382 case LE:
4383 case LEU:
4384 return 2;
4385 case NE:
4386 return 4;
4387 case GE:
4388 case GEU:
4389 return 5;
4390 case GT:
4391 case GTU:
4392 return 6;
4393 default:
4394 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4394, __FUNCTION__))
;
4395 }
4396}
4397
4398/* Helper for ix86_cmp_code_to_pcmp_immediate for fp modes. */
4399
4400static int
4401ix86_fp_cmp_code_to_pcmp_immediate (enum rtx_code code)
4402{
4403 switch (code)
4404 {
4405 case EQ:
4406 return 0x00;
4407 case NE:
4408 return 0x04;
4409 case GT:
4410 return 0x0e;
4411 case LE:
4412 return 0x02;
4413 case GE:
4414 return 0x0d;
4415 case LT:
4416 return 0x01;
4417 case UNLE:
4418 return 0x0a;
4419 case UNLT:
4420 return 0x09;
4421 case UNGE:
4422 return 0x05;
4423 case UNGT:
4424 return 0x06;
4425 case UNEQ:
4426 return 0x18;
4427 case LTGT:
4428 return 0x0c;
4429 case ORDERED:
4430 return 0x07;
4431 case UNORDERED:
4432 return 0x03;
4433 default:
4434 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4434, __FUNCTION__))
;
4435 }
4436}
4437
4438/* Return immediate value to be used in UNSPEC_PCMP
4439 for comparison CODE in MODE. */
4440
4441static int
4442ix86_cmp_code_to_pcmp_immediate (enum rtx_code code, machine_mode mode)
4443{
4444 if (FLOAT_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_DECIMAL_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_COMPLEX_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT)
)
4445 return ix86_fp_cmp_code_to_pcmp_immediate (code);
4446 return ix86_int_cmp_code_to_pcmp_immediate (code);
4447}
4448
4449/* Expand AVX-512 vector comparison. */
4450
4451bool
4452ix86_expand_mask_vec_cmp (rtx dest, enum rtx_code code, rtx cmp_op0, rtx cmp_op1)
4453{
4454 machine_mode mask_mode = GET_MODE (dest)((machine_mode) (dest)->mode);
4455 machine_mode cmp_mode = GET_MODE (cmp_op0)((machine_mode) (cmp_op0)->mode);
4456 rtx imm = GEN_INT (ix86_cmp_code_to_pcmp_immediate (code, cmp_mode))gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (ix86_cmp_code_to_pcmp_immediate
(code, cmp_mode)))
;
4457 int unspec_code;
4458 rtx unspec;
4459
4460 switch (code)
4461 {
4462 case LEU:
4463 case GTU:
4464 case GEU:
4465 case LTU:
4466 unspec_code = UNSPEC_UNSIGNED_PCMP;
4467 break;
4468
4469 default:
4470 unspec_code = UNSPEC_PCMP;
4471 }
4472
4473 unspec = gen_rtx_UNSPEC (mask_mode, gen_rtvec (3, cmp_op0, cmp_op1, imm),gen_rtx_fmt_Ei_stat ((UNSPEC), ((mask_mode)), ((gen_rtvec (3,
cmp_op0, cmp_op1, imm))), ((unspec_code)) )
4474 unspec_code)gen_rtx_fmt_Ei_stat ((UNSPEC), ((mask_mode)), ((gen_rtvec (3,
cmp_op0, cmp_op1, imm))), ((unspec_code)) )
;
4475 emit_insn (gen_rtx_SET (dest, unspec)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((dest)
), ((unspec)) )
);
4476
4477 return true;
4478}
4479
4480/* Expand fp vector comparison. */
4481
4482bool
4483ix86_expand_fp_vec_cmp (rtx operands[])
4484{
4485 enum rtx_code code = GET_CODE (operands[1])((enum rtx_code) (operands[1])->code);
4486 rtx cmp;
4487
4488 code = ix86_prepare_sse_fp_compare_args (operands[0], code,
4489 &operands[2], &operands[3]);
4490 if (code == UNKNOWN)
4491 {
4492 rtx temp;
4493 switch (GET_CODE (operands[1])((enum rtx_code) (operands[1])->code))
4494 {
4495 case LTGT:
4496 temp = ix86_expand_sse_cmp (operands[0], ORDERED, operands[2],
4497 operands[3], NULL__null, NULL__null);
4498 cmp = ix86_expand_sse_cmp (operands[0], NE, operands[2],
4499 operands[3], NULL__null, NULL__null);
4500 code = AND;
4501 break;
4502 case UNEQ:
4503 temp = ix86_expand_sse_cmp (operands[0], UNORDERED, operands[2],
4504 operands[3], NULL__null, NULL__null);
4505 cmp = ix86_expand_sse_cmp (operands[0], EQ, operands[2],
4506 operands[3], NULL__null, NULL__null);
4507 code = IOR;
4508 break;
4509 default:
4510 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4510, __FUNCTION__))
;
4511 }
4512 cmp = expand_simple_binop (GET_MODE (cmp)((machine_mode) (cmp)->mode), code, temp, cmp, cmp, 1,
4513 OPTAB_DIRECT);
4514 }
4515 else
4516 cmp = ix86_expand_sse_cmp (operands[0], code, operands[2], operands[3],
4517 NULL__null, NULL__null);
4518
4519 if (operands[0] != cmp)
4520 emit_move_insn (operands[0], cmp);
4521
4522 return true;
4523}
4524
4525static rtx
4526ix86_expand_int_sse_cmp (rtx dest, enum rtx_code code, rtx cop0, rtx cop1,
4527 rtx op_true, rtx op_false, bool *negate)
4528{
4529 machine_mode data_mode = GET_MODE (dest)((machine_mode) (dest)->mode);
4530 machine_mode mode = GET_MODE (cop0)((machine_mode) (cop0)->mode);
4531 rtx x;
4532
4533 *negate = false;
4534
4535 /* XOP supports all of the comparisons on all 128-bit vector int types. */
4536 if (TARGET_XOP((global_options.x_ix86_isa_flags & (1UL << 59)) !=
0)
4537 && GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_VECTOR_INT
4538 && GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) <= 16)
4539 ;
4540 /* AVX512F supports all of the comparsions
4541 on all 128/256/512-bit vector int types. */
4542 else if (ix86_use_mask_cmp_p (data_mode, mode, op_true, op_false))
4543 ;
4544 else
4545 {
4546 /* Canonicalize the comparison to EQ, GT, GTU. */
4547 switch (code)
4548 {
4549 case EQ:
4550 case GT:
4551 case GTU:
4552 break;
4553
4554 case LE:
4555 case LEU:
4556 /* x <= cst can be handled as x < cst + 1 unless there is
4557 wrap around in cst + 1. */
4558 if (GET_CODE (cop1)((enum rtx_code) (cop1)->code) == CONST_VECTOR
4559 && GET_MODE_INNER (mode)(mode_to_inner (mode)) != TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode)))
4560 {
4561 unsigned int n_elts = GET_MODE_NUNITS (mode)(mode_to_nunits (mode).coeffs[0]), i;
4562 machine_mode eltmode = GET_MODE_INNER (mode)(mode_to_inner (mode));
4563 for (i = 0; i < n_elts; ++i)
4564 {
4565 rtx elt = CONST_VECTOR_ELT (cop1, i)const_vector_elt (cop1, i);
4566 if (!CONST_INT_P (elt)(((enum rtx_code) (elt)->code) == CONST_INT))
4567 break;
4568 if (code == GE)
4569 {
4570 /* For LE punt if some element is signed maximum. */
4571 if ((INTVAL (elt)((elt)->u.hwint[0]) & (GET_MODE_MASK (eltmode)mode_mask_array[eltmode] >> 1))
4572 == (GET_MODE_MASK (eltmode)mode_mask_array[eltmode] >> 1))
4573 break;
4574 }
4575 /* For LEU punt if some element is unsigned maximum. */
4576 else if (elt == constm1_rtx(const_int_rtx[64 -1]))
4577 break;
4578 }
4579 if (i == n_elts)
4580 {
4581 rtvec v = rtvec_alloc (n_elts);
4582 for (i = 0; i < n_elts; ++i)
4583 RTVEC_ELT (v, i)((v)->elem[i])
4584 = gen_int_mode (INTVAL (CONST_VECTOR_ELT (cop1, i))((const_vector_elt (cop1, i))->u.hwint[0]) + 1,
4585 eltmode);
4586 cop1 = gen_rtx_CONST_VECTOR (mode, v);
4587 std::swap (cop0, cop1);
4588 code = code == LE ? GT : GTU;
4589 break;
4590 }
4591 }
4592 /* FALLTHRU */
4593 case NE:
4594 code = reverse_condition (code);
4595 *negate = true;
4596 break;
4597
4598 case GE:
4599 case GEU:
4600 /* x >= cst can be handled as x > cst - 1 unless there is
4601 wrap around in cst - 1. */
4602 if (GET_CODE (cop1)((enum rtx_code) (cop1)->code) == CONST_VECTOR
4603 && GET_MODE_INNER (mode)(mode_to_inner (mode)) != TImode(scalar_int_mode ((scalar_int_mode::from_int) E_TImode)))
4604 {
4605 unsigned int n_elts = GET_MODE_NUNITS (mode)(mode_to_nunits (mode).coeffs[0]), i;
4606 machine_mode eltmode = GET_MODE_INNER (mode)(mode_to_inner (mode));
4607 for (i = 0; i < n_elts; ++i)
4608 {
4609 rtx elt = CONST_VECTOR_ELT (cop1, i)const_vector_elt (cop1, i);
4610 if (!CONST_INT_P (elt)(((enum rtx_code) (elt)->code) == CONST_INT))
4611 break;
4612 if (code == GE)
4613 {
4614 /* For GE punt if some element is signed minimum. */
4615 if (INTVAL (elt)((elt)->u.hwint[0]) < 0
4616 && ((INTVAL (elt)((elt)->u.hwint[0]) & (GET_MODE_MASK (eltmode)mode_mask_array[eltmode] >> 1))
4617 == 0))
4618 break;
4619 }
4620 /* For GEU punt if some element is zero. */
4621 else if (elt == const0_rtx(const_int_rtx[64]))
4622 break;
4623 }
4624 if (i == n_elts)
4625 {
4626 rtvec v = rtvec_alloc (n_elts);
4627 for (i = 0; i < n_elts; ++i)
4628 RTVEC_ELT (v, i)((v)->elem[i])
4629 = gen_int_mode (INTVAL (CONST_VECTOR_ELT (cop1, i))((const_vector_elt (cop1, i))->u.hwint[0]) - 1,
4630 eltmode);
4631 cop1 = gen_rtx_CONST_VECTOR (mode, v);
4632 code = code == GE ? GT : GTU;
4633 break;
4634 }
4635 }
4636 code = reverse_condition (code);
4637 *negate = true;
4638 /* FALLTHRU */
4639
4640 case LT:
4641 case LTU:
4642 std::swap (cop0, cop1);
4643 code = swap_condition (code);
4644 break;
4645
4646 default:
4647 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4647, __FUNCTION__))
;
4648 }
4649
4650 /* Only SSE4.1/SSE4.2 supports V2DImode. */
4651 if (mode == V2DImode((void) 0, E_V2DImode))
4652 {
4653 switch (code)
4654 {
4655 case EQ:
4656 /* SSE4.1 supports EQ. */
4657 if (!TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4658 return NULL__null;
4659 break;
4660
4661 case GT:
4662 case GTU:
4663 /* SSE4.2 supports GT/GTU. */
4664 if (!TARGET_SSE4_2((global_options.x_ix86_isa_flags & (1UL << 53)) !=
0)
)
4665 return NULL__null;
4666 break;
4667
4668 default:
4669 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4669, __FUNCTION__))
;
4670 }
4671 }
4672
4673 if (GET_CODE (cop0)((enum rtx_code) (cop0)->code) == CONST_VECTOR)
4674 cop0 = force_reg (mode, cop0);
4675 else if (GET_CODE (cop1)((enum rtx_code) (cop1)->code) == CONST_VECTOR)
4676 cop1 = force_reg (mode, cop1);
4677
4678 rtx optrue = op_true ? op_true : CONSTM1_RTX (data_mode)(const_tiny_rtx[3][(int) (data_mode)]);
4679 rtx opfalse = op_false ? op_false : CONST0_RTX (data_mode)(const_tiny_rtx[0][(int) (data_mode)]);
4680 if (*negate)
4681 std::swap (optrue, opfalse);
4682
4683 /* Transform x > y ? 0 : -1 (i.e. x <= y ? -1 : 0 or x <= y) when
4684 not using integer masks into min (x, y) == x ? -1 : 0 (i.e.
4685 min (x, y) == x). While we add one instruction (the minimum),
4686 we remove the need for two instructions in the negation, as the
4687 result is done this way.
4688 When using masks, do it for SI/DImode element types, as it is shorter
4689 than the two subtractions. */
4690 if ((code != EQ
4691 && GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) != 64
4692 && vector_all_ones_operand (opfalse, data_mode)
4693 && optrue == CONST0_RTX (data_mode)(const_tiny_rtx[0][(int) (data_mode)]))
4694 || (code == GTU
4695 && GET_MODE_SIZE (GET_MODE_INNER (mode))((unsigned short) mode_to_bytes ((mode_to_inner (mode))).coeffs
[0])
>= 4
4696 /* Don't do it if not using integer masks and we'd end up with
4697 the right values in the registers though. */
4698 && (GET_MODE_SIZE (mode)((unsigned short) mode_to_bytes (mode).coeffs[0]) == 64
4699 || !vector_all_ones_operand (optrue, data_mode)
4700 || opfalse != CONST0_RTX (data_mode)(const_tiny_rtx[0][(int) (data_mode)]))))
4701 {
4702 rtx (*gen) (rtx, rtx, rtx) = NULL__null;
4703
4704 switch (mode)
4705 {
4706 case E_V16SImode:
4707 gen = (code == GTU) ? gen_uminv16si3 : gen_sminv16si3;
4708 break;
4709 case E_V8DImode:
4710 gen = (code == GTU) ? gen_uminv8di3 : gen_sminv8di3;
4711 cop0 = force_reg (mode, cop0);
4712 cop1 = force_reg (mode, cop1);
4713 break;
4714 case E_V32QImode:
4715 if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
)
4716 gen = (code == GTU) ? gen_uminv32qi3 : gen_sminv32qi3;
4717 break;
4718 case E_V16HImode:
4719 if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
)
4720 gen = (code == GTU) ? gen_uminv16hi3 : gen_sminv16hi3;
4721 break;
4722 case E_V8SImode:
4723 if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
)
4724 gen = (code == GTU) ? gen_uminv8si3 : gen_sminv8si3;
4725 break;
4726 case E_V4DImode:
4727 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
4728 {
4729 gen = (code == GTU) ? gen_uminv4di3 : gen_sminv4di3;
4730 cop0 = force_reg (mode, cop0);
4731 cop1 = force_reg (mode, cop1);
4732 }
4733 break;
4734 case E_V16QImode:
4735 if (code == GTU && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4736 gen = gen_uminv16qi3;
4737 else if (code == GT && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4738 gen = gen_sminv16qi3;
4739 break;
4740 case E_V8QImode:
4741 if (code == GTU && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4742 gen = gen_uminv8qi3;
4743 else if (code == GT && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4744 gen = gen_sminv8qi3;
4745 break;
4746 case E_V4QImode:
4747 if (code == GTU && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4748 gen = gen_uminv4qi3;
4749 else if (code == GT && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4750 gen = gen_sminv4qi3;
4751 break;
4752 case E_V2QImode:
4753 if (code == GTU && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4754 gen = gen_uminv2qi3;
4755 else if (code == GT && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4756 gen = gen_sminv2qi3;
4757 break;
4758 case E_V8HImode:
4759 if (code == GTU && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4760 gen = gen_uminv8hi3;
4761 else if (code == GT && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4762 gen = gen_sminv8hi3;
4763 break;
4764 case E_V4HImode:
4765 if (code == GTU && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4766 gen = gen_uminv4hi3;
4767 else if (code == GT && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4768 gen = gen_sminv4hi3;
4769 break;
4770 case E_V2HImode:
4771 if (code == GTU && TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4772 gen = gen_uminv2hi3;
4773 else if (code == GT && TARGET_SSE2((global_options.x_ix86_isa_flags & (1UL << 51)) !=
0)
)
4774 gen = gen_sminv2hi3;
4775 break;
4776 case E_V4SImode:
4777 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4778 gen = (code == GTU) ? gen_uminv4si3 : gen_sminv4si3;
4779 break;
4780 case E_V2SImode:
4781 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
4782 gen = (code == GTU) ? gen_uminv2si3 : gen_sminv2si3;
4783 break;
4784 case E_V2DImode:
4785 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
4786 {
4787 gen = (code == GTU) ? gen_uminv2di3 : gen_sminv2di3;
4788 cop0 = force_reg (mode, cop0);
4789 cop1 = force_reg (mode, cop1);
4790 }
4791 break;
4792 default:
4793 break;
4794 }
4795
4796 if (gen)
4797 {
4798 rtx tem = gen_reg_rtx (mode);
4799 if (!vector_operand (cop0, mode))
4800 cop0 = force_reg (mode, cop0);
4801 if (!vector_operand (cop1, mode))
4802 cop1 = force_reg (mode, cop1);
4803 *negate = !*negate;
4804 emit_insn (gen (tem, cop0, cop1));
4805 cop1 = tem;
4806 code = EQ;
4807 }
4808 }
4809
4810 /* Unsigned parallel compare is not supported by the hardware.
4811 Play some tricks to turn this into a signed comparison
4812 against 0. */
4813 if (code == GTU)
4814 {
4815 cop0 = force_reg (mode, cop0);
4816
4817 switch (mode)
4818 {
4819 case E_V16SImode:
4820 case E_V8DImode:
4821 case E_V8SImode:
4822 case E_V4DImode:
4823 case E_V4SImode:
4824 case E_V2SImode:
4825 case E_V2DImode:
4826 {
4827 rtx t1, t2, mask;
4828
4829 /* Subtract (-(INT MAX) - 1) from both operands to make
4830 them signed. */
4831 mask = ix86_build_signbit_mask (mode, true, false);
4832 t1 = gen_reg_rtx (mode);
4833 emit_insn (gen_sub3_insn (t1, cop0, mask));
4834
4835 t2 = gen_reg_rtx (mode);
4836 emit_insn (gen_sub3_insn (t2, cop1, mask));
4837
4838 cop0 = t1;
4839 cop1 = t2;
4840 code = GT;
4841 }
4842 break;
4843
4844 case E_V64QImode:
4845 case E_V32HImode:
4846 case E_V32QImode:
4847 case E_V16HImode:
4848 case E_V16QImode:
4849 case E_V8QImode:
4850 case E_V4QImode:
4851 case E_V2QImode:
4852 case E_V8HImode:
4853 case E_V4HImode:
4854 case E_V2HImode:
4855 /* Perform a parallel unsigned saturating subtraction. */
4856 x = gen_reg_rtx (mode);
4857 emit_insn (gen_rtx_SETgen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((x)), (
(gen_rtx_fmt_ee_stat ((US_MINUS), ((mode)), ((cop0)), ((cop1)
) ))) )
4858 (x, gen_rtx_US_MINUS (mode, cop0, cop1))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((x)), (
(gen_rtx_fmt_ee_stat ((US_MINUS), ((mode)), ((cop0)), ((cop1)
) ))) )
);
4859 cop0 = x;
4860 cop1 = CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)]);
4861 code = EQ;
4862 *negate = !*negate;
4863 break;
4864
4865 default:
4866 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4866, __FUNCTION__))
;
4867 }
4868 }
4869 }
4870
4871 if (*negate)
4872 std::swap (op_true, op_false);
4873
4874 if (GET_CODE (cop1)((enum rtx_code) (cop1)->code) == CONST_VECTOR)
4875 cop1 = force_reg (mode, cop1);
4876
4877 /* Allow the comparison to be done in one mode, but the movcc to
4878 happen in another mode. */
4879 if (data_mode == mode)
4880 x = ix86_expand_sse_cmp (dest, code, cop0, cop1, op_true, op_false);
4881 else
4882 {
4883 gcc_assert (GET_MODE_SIZE (data_mode) == GET_MODE_SIZE (mode))((void)(!(((unsigned short) mode_to_bytes (data_mode).coeffs[
0]) == ((unsigned short) mode_to_bytes (mode).coeffs[0])) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4883, __FUNCTION__), 0 : 0))
;
4884 x = ix86_expand_sse_cmp (gen_reg_rtx (mode), code, cop0, cop1,
4885 op_true, op_false);
4886 if (GET_MODE (x)((machine_mode) (x)->mode) == mode)
4887 x = gen_lowpartrtl_hooks.gen_lowpart (data_mode, x);
4888 }
4889
4890 return x;
4891}
4892
4893/* Expand integer vector comparison. */
4894
4895bool
4896ix86_expand_int_vec_cmp (rtx operands[])
4897{
4898 rtx_code code = GET_CODE (operands[1])((enum rtx_code) (operands[1])->code);
4899 bool negate = false;
4900 rtx cmp = ix86_expand_int_sse_cmp (operands[0], code, operands[2],
4901 operands[3], NULL__null, NULL__null, &negate);
4902
4903 if (!cmp)
4904 return false;
4905
4906 if (negate)
4907 cmp = ix86_expand_int_sse_cmp (operands[0], EQ, cmp,
4908 CONST0_RTX (GET_MODE (cmp))(const_tiny_rtx[0][(int) (((machine_mode) (cmp)->mode))]),
4909 NULL__null, NULL__null, &negate);
4910
4911 gcc_assert (!negate)((void)(!(!negate) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4911, __FUNCTION__), 0 : 0))
;
4912
4913 if (operands[0] != cmp)
4914 emit_move_insn (operands[0], cmp);
4915
4916 return true;
4917}
4918
4919/* Expand a floating-point vector conditional move; a vcond operation
4920 rather than a movcc operation. */
4921
4922bool
4923ix86_expand_fp_vcond (rtx operands[])
4924{
4925 enum rtx_code code = GET_CODE (operands[3])((enum rtx_code) (operands[3])->code);
4926 rtx cmp;
4927
4928 code = ix86_prepare_sse_fp_compare_args (operands[0], code,
4929 &operands[4], &operands[5]);
4930 if (code == UNKNOWN)
4931 {
4932 rtx temp;
4933 switch (GET_CODE (operands[3])((enum rtx_code) (operands[3])->code))
4934 {
4935 case LTGT:
4936 temp = ix86_expand_sse_cmp (operands[0], ORDERED, operands[4],
4937 operands[5], operands[0], operands[0]);
4938 cmp = ix86_expand_sse_cmp (operands[0], NE, operands[4],
4939 operands[5], operands[1], operands[2]);
4940 code = AND;
4941 break;
4942 case UNEQ:
4943 temp = ix86_expand_sse_cmp (operands[0], UNORDERED, operands[4],
4944 operands[5], operands[0], operands[0]);
4945 cmp = ix86_expand_sse_cmp (operands[0], EQ, operands[4],
4946 operands[5], operands[1], operands[2]);
4947 code = IOR;
4948 break;
4949 default:
4950 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 4950, __FUNCTION__))
;
4951 }
4952 cmp = expand_simple_binop (GET_MODE (cmp)((machine_mode) (cmp)->mode), code, temp, cmp, cmp, 1,
4953 OPTAB_DIRECT);
4954 ix86_expand_sse_movcc (operands[0], cmp, operands[1], operands[2]);
4955 return true;
4956 }
4957
4958 if (ix86_expand_sse_fp_minmax (operands[0], code, operands[4],
4959 operands[5], operands[1], operands[2]))
4960 return true;
4961
4962 cmp = ix86_expand_sse_cmp (operands[0], code, operands[4], operands[5],
4963 operands[1], operands[2]);
4964 ix86_expand_sse_movcc (operands[0], cmp, operands[1], operands[2]);
4965 return true;
4966}
4967
4968/* Expand a signed/unsigned integral vector conditional move. */
4969
4970bool
4971ix86_expand_int_vcond (rtx operands[])
4972{
4973 machine_mode data_mode = GET_MODE (operands[0])((machine_mode) (operands[0])->mode);
4974 machine_mode mode = GET_MODE (operands[4])((machine_mode) (operands[4])->mode);
4975 enum rtx_code code = GET_CODE (operands[3])((enum rtx_code) (operands[3])->code);
4976 bool negate = false;
4977 rtx x, cop0, cop1;
4978
4979 cop0 = operands[4];
4980 cop1 = operands[5];
4981
4982 /* Try to optimize x < 0 ? -1 : 0 into (signed) x >> 31
4983 and x < 0 ? 1 : 0 into (unsigned) x >> 31. */
4984 if ((code == LT || code == GE)
4985 && data_mode == mode
4986 && cop1 == CONST0_RTX (mode)(const_tiny_rtx[0][(int) (mode)])
4987 && operands[1 + (code == LT)] == CONST0_RTX (data_mode)(const_tiny_rtx[0][(int) (data_mode)])
4988 && GET_MODE_UNIT_SIZE (data_mode)mode_to_unit_size (data_mode) > 1
4989 && GET_MODE_UNIT_SIZE (data_mode)mode_to_unit_size (data_mode) <= 8
4990 && (GET_MODE_SIZE (data_mode)((unsigned short) mode_to_bytes (data_mode).coeffs[0]) == 16
4991 || (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
&& GET_MODE_SIZE (data_mode)((unsigned short) mode_to_bytes (data_mode).coeffs[0]) == 32)))
4992 {
4993 rtx negop = operands[2 - (code == LT)];
4994 int shift = GET_MODE_UNIT_BITSIZE (data_mode)((unsigned short) (mode_to_unit_size (data_mode) * (8))) - 1;
4995 if (negop == CONST1_RTX (data_mode)(const_tiny_rtx[1][(int) (data_mode)]))
4996 {
4997 rtx res = expand_simple_binop (mode, LSHIFTRT, cop0, GEN_INT (shift)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (shift)),
4998 operands[0], 1, OPTAB_DIRECT);
4999 if (res != operands[0])
5000 emit_move_insn (operands[0], res);
5001 return true;
5002 }
5003 else if (GET_MODE_INNER (data_mode)(mode_to_inner (data_mode)) != DImode(scalar_int_mode ((scalar_int_mode::from_int) E_DImode))
5004 && vector_all_ones_operand (negop, data_mode))
5005 {
5006 rtx res = expand_simple_binop (mode, ASHIFTRT, cop0, GEN_INT (shift)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (shift)),
5007 operands[0], 0, OPTAB_DIRECT);
5008 if (res != operands[0])
5009 emit_move_insn (operands[0], res);
5010 return true;
5011 }
5012 }
5013
5014 if (!nonimmediate_operand (cop1, mode))
5015 cop1 = force_reg (mode, cop1);
5016 if (!general_operand (operands[1], data_mode))
5017 operands[1] = force_reg (data_mode, operands[1]);
5018 if (!general_operand (operands[2], data_mode))
5019 operands[2] = force_reg (data_mode, operands[2]);
5020
5021 x = ix86_expand_int_sse_cmp (operands[0], code, cop0, cop1,
5022 operands[1], operands[2], &negate);
5023
5024 if (!x)
5025 return false;
5026
5027 ix86_expand_sse_movcc (operands[0], x, operands[1+negate],
5028 operands[2-negate]);
5029 return true;
5030}
5031
5032static bool
5033ix86_expand_vec_perm_vpermt2 (rtx target, rtx mask, rtx op0, rtx op1,
5034 struct expand_vec_perm_d *d)
5035{
5036 /* ix86_expand_vec_perm_vpermt2 is called from both const and non-const
5037 expander, so args are either in d, or in op0, op1 etc. */
5038 machine_mode mode = GET_MODE (d ? d->op0 : op0)((machine_mode) (d ? d->op0 : op0)->mode);
5039 machine_mode maskmode = mode;
5040 rtx (*gen) (rtx, rtx, rtx, rtx) = NULL__null;
5041
5042 switch (mode)
5043 {
5044 case E_V16QImode:
5045 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
&& TARGET_AVX512VBMI((global_options.x_ix86_isa_flags & (1UL << 18)) !=
0)
)
5046 gen = gen_avx512vl_vpermt2varv16qi3;
5047 break;
5048 case E_V32QImode:
5049 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
&& TARGET_AVX512VBMI((global_options.x_ix86_isa_flags & (1UL << 18)) !=
0)
)
5050 gen = gen_avx512vl_vpermt2varv32qi3;
5051 break;
5052 case E_V64QImode:
5053 if (TARGET_AVX512VBMI((global_options.x_ix86_isa_flags & (1UL << 18)) !=
0)
)
5054 gen = gen_avx512bw_vpermt2varv64qi3;
5055 break;
5056 case E_V8HImode:
5057 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
&& TARGET_AVX512BW((global_options.x_ix86_isa_flags & (1UL << 11)) !=
0)
)
5058 gen = gen_avx512vl_vpermt2varv8hi3;
5059 break;
5060 case E_V16HImode:
5061 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
&& TARGET_AVX512BW((global_options.x_ix86_isa_flags & (1UL << 11)) !=
0)
)
5062 gen = gen_avx512vl_vpermt2varv16hi3;
5063 break;
5064 case E_V32HImode:
5065 if (TARGET_AVX512BW((global_options.x_ix86_isa_flags & (1UL << 11)) !=
0)
)
5066 gen = gen_avx512bw_vpermt2varv32hi3;
5067 break;
5068 case E_V4SImode:
5069 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5070 gen = gen_avx512vl_vpermt2varv4si3;
5071 break;
5072 case E_V8SImode:
5073 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5074 gen = gen_avx512vl_vpermt2varv8si3;
5075 break;
5076 case E_V16SImode:
5077 if (TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
)
5078 gen = gen_avx512f_vpermt2varv16si3;
5079 break;
5080 case E_V4SFmode:
5081 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5082 {
5083 gen = gen_avx512vl_vpermt2varv4sf3;
5084 maskmode = V4SImode((void) 0, E_V4SImode);
5085 }
5086 break;
5087 case E_V8SFmode:
5088 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5089 {
5090 gen = gen_avx512vl_vpermt2varv8sf3;
5091 maskmode = V8SImode((void) 0, E_V8SImode);
5092 }
5093 break;
5094 case E_V16SFmode:
5095 if (TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
)
5096 {
5097 gen = gen_avx512f_vpermt2varv16sf3;
5098 maskmode = V16SImode((void) 0, E_V16SImode);
5099 }
5100 break;
5101 case E_V2DImode:
5102 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5103 gen = gen_avx512vl_vpermt2varv2di3;
5104 break;
5105 case E_V4DImode:
5106 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5107 gen = gen_avx512vl_vpermt2varv4di3;
5108 break;
5109 case E_V8DImode:
5110 if (TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
)
5111 gen = gen_avx512f_vpermt2varv8di3;
5112 break;
5113 case E_V2DFmode:
5114 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5115 {
5116 gen = gen_avx512vl_vpermt2varv2df3;
5117 maskmode = V2DImode((void) 0, E_V2DImode);
5118 }
5119 break;
5120 case E_V4DFmode:
5121 if (TARGET_AVX512VL((global_options.x_ix86_isa_flags & (1UL << 20)) !=
0)
)
5122 {
5123 gen = gen_avx512vl_vpermt2varv4df3;
5124 maskmode = V4DImode((void) 0, E_V4DImode);
5125 }
5126 break;
5127 case E_V8DFmode:
5128 if (TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
)
5129 {
5130 gen = gen_avx512f_vpermt2varv8df3;
5131 maskmode = V8DImode((void) 0, E_V8DImode);
5132 }
5133 break;
5134 default:
5135 break;
5136 }
5137
5138 if (gen == NULL__null)
5139 return false;
5140
5141 /* ix86_expand_vec_perm_vpermt2 is called from both const and non-const
5142 expander, so args are either in d, or in op0, op1 etc. */
5143 if (d)
5144 {
5145 rtx vec[64];
5146 target = d->target;
5147 op0 = d->op0;
5148 op1 = d->op1;
5149 for (int i = 0; i < d->nelt; ++i)
5150 vec[i] = GEN_INT (d->perm[i])gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (d->perm[i]));
5151 mask = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (d->nelt, vec));
5152 }
5153
5154 emit_insn (gen (target, force_reg (maskmode, mask), op0, op1));
5155 return true;
5156}
5157
5158/* Expand a variable vector permutation. */
5159
5160void
5161ix86_expand_vec_perm (rtx operands[])
5162{
5163 rtx target = operands[0];
5164 rtx op0 = operands[1];
5165 rtx op1 = operands[2];
5166 rtx mask = operands[3];
5167 rtx t1, t2, t3, t4, t5, t6, t7, t8, vt, vt2, vec[32];
5168 machine_mode mode = GET_MODE (op0)((machine_mode) (op0)->mode);
5169 machine_mode maskmode = GET_MODE (mask)((machine_mode) (mask)->mode);
5170 int w, e, i;
5171 bool one_operand_shuffle = rtx_equal_p (op0, op1);
5172
5173 /* Number of elements in the vector. */
5174 w = GET_MODE_NUNITS (mode)(mode_to_nunits (mode).coeffs[0]);
5175 e = GET_MODE_UNIT_SIZE (mode)mode_to_unit_size (mode);
5176 gcc_assert (w <= 64)((void)(!(w <= 64) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 5176, __FUNCTION__), 0 : 0))
;
5177
5178 /* For HF mode vector, convert it to HI using subreg. */
5179 if (GET_MODE_INNER (mode)(mode_to_inner (mode)) == HFmode(scalar_float_mode ((scalar_float_mode::from_int) E_HFmode)))
5180 {
5181 machine_mode orig_mode = mode;
5182 mode = mode_for_vector (HImode(scalar_int_mode ((scalar_int_mode::from_int) E_HImode)), w).require ();
5183 target = lowpart_subreg (mode, target, orig_mode);
5184 op0 = lowpart_subreg (mode, op0, orig_mode);
5185 op1 = lowpart_subreg (mode, op1, orig_mode);
5186 }
5187
5188 if (TARGET_AVX512F((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0)
&& one_operand_shuffle)
5189 {
5190 rtx (*gen) (rtx, rtx, rtx) = NULL__null;
5191 switch (mode)
5192 {
5193 case E_V16SImode:
5194 gen =gen_avx512f_permvarv16si;
5195 break;
5196 case E_V16SFmode:
5197 gen = gen_avx512f_permvarv16sf;
5198 break;
5199 case E_V8DImode:
5200 gen = gen_avx512f_permvarv8di;
5201 break;
5202 case E_V8DFmode:
5203 gen = gen_avx512f_permvarv8df;
5204 break;
5205 default:
5206 break;
5207 }
5208 if (gen != NULL__null)
5209 {
5210 emit_insn (gen (target, op0, mask));
5211 return;
5212 }
5213 }
5214
5215 if (ix86_expand_vec_perm_vpermt2 (target, mask, op0, op1, NULL__null))
5216 return;
5217
5218 if (TARGET_AVX2((global_options.x_ix86_isa_flags & (1UL << 9)) != 0
)
)
5219 {
5220 if (mode == V4DImode((void) 0, E_V4DImode) || mode == V4DFmode((void) 0, E_V4DFmode) || mode == V16HImode((void) 0, E_V16HImode))
5221 {
5222 /* Unfortunately, the VPERMQ and VPERMPD instructions only support
5223 an constant shuffle operand. With a tiny bit of effort we can
5224 use VPERMD instead. A re-interpretation stall for V4DFmode is
5225 unfortunate but there's no avoiding it.
5226 Similarly for V16HImode we don't have instructions for variable
5227 shuffling, while for V32QImode we can use after preparing suitable
5228 masks vpshufb; vpshufb; vpermq; vpor. */
5229
5230 if (mode == V16HImode((void) 0, E_V16HImode))
5231 {
5232 maskmode = mode = V32QImode((void) 0, E_V32QImode);
5233 w = 32;
5234 e = 1;
5235 }
5236 else
5237 {
5238 maskmode = mode = V8SImode((void) 0, E_V8SImode);
5239 w = 8;
5240 e = 4;
5241 }
5242 t1 = gen_reg_rtx (maskmode);
5243
5244 /* Replicate the low bits of the V4DImode mask into V8SImode:
5245 mask = { A B C D }
5246 t1 = { A A B B C C D D }. */
5247 for (i = 0; i < w / 2; ++i)
5248 vec[i*2 + 1] = vec[i*2] = GEN_INT (i * 2)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (i * 2));
5249 vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
5250 vt = force_reg (maskmode, vt);
5251 mask = gen_lowpartrtl_hooks.gen_lowpart (maskmode, mask);
5252 if (maskmode == V8SImode((void) 0, E_V8SImode))
5253 emit_insn (gen_avx2_permvarv8si (t1, mask, vt));
5254 else
5255 emit_insn (gen_avx2_pshufbv32qi3 (t1, mask, vt));
5256
5257 /* Multiply the shuffle indicies by two. */
5258 t1 = expand_simple_binop (maskmode, PLUS, t1, t1, t1, 1,
5259 OPTAB_DIRECT);
5260
5261 /* Add one to the odd shuffle indicies:
5262 t1 = { A*2, A*2+1, B*2, B*2+1, ... }. */
5263 for (i = 0; i < w / 2; ++i)
5264 {
5265 vec[i * 2] = const0_rtx(const_int_rtx[64]);
5266 vec[i * 2 + 1] = const1_rtx(const_int_rtx[64 +1]);
5267 }
5268 vt = gen_rtx_CONST_VECTOR (maskmode, gen_rtvec_v (w, vec));
5269 vt = validize_mem (force_const_mem (maskmode, vt));
5270 t1 = expand_simple_binop (maskmode, PLUS, t1, vt, t1, 1,
5271 OPTAB_DIRECT);
5272
5273 /* Continue as if V8SImode (resp. V32QImode) was used initially. */
5274 operands[3] = mask = t1;
5275 target = gen_reg_rtx (mode);
5276 op0 = gen_lowpartrtl_hooks.gen_lowpart (mode, op0);
5277 op1 = gen_lowpartrtl_hooks.gen_lowpart (mode, op1);
5278 }
5279
5280 switch (mode)
5281 {
5282 case E_V8SImode:
5283 /* The VPERMD and VPERMPS instructions already properly ignore
5284 the high bits of the shuffle elements. No need for us to
5285 perform an AND ourselves. */
5286 if (one_operand_shuffle)
5287 {
5288 emit_insn (gen_avx2_permvarv8si (target, op0, mask));
5289 if (target != operands[0])
5290 emit_move_insn (operands[0],
5291 gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (operands[0])((machine_mode) (operands[0])->mode), target));
5292 }
5293 else
5294 {
5295 t1 = gen_reg_rtx (V8SImode((void) 0, E_V8SImode));
5296 t2 = gen_reg_rtx (V8SImode((void) 0, E_V8SImode));
5297 emit_insn (gen_avx2_permvarv8si (t1, op0, mask));
5298 emit_insn (gen_avx2_permvarv8si (t2, op1, mask));
5299 goto merge_two;
5300 }
5301 return;
5302
5303 case E_V8SFmode:
5304 mask = gen_lowpartrtl_hooks.gen_lowpart (V8SImode((void) 0, E_V8SImode), mask);
5305 if (one_operand_shuffle)
5306 emit_insn (gen_avx2_permvarv8sf (target, op0, mask));
5307 else
5308 {
5309 t1 = gen_reg_rtx (V8SFmode((void) 0, E_V8SFmode));
5310 t2 = gen_reg_rtx (V8SFmode((void) 0, E_V8SFmode));
5311 emit_insn (gen_avx2_permvarv8sf (t1, op0, mask));
5312 emit_insn (gen_avx2_permvarv8sf (t2, op1, mask));
5313 goto merge_two;
5314 }
5315 return;
5316
5317 case E_V4SImode:
5318 /* By combining the two 128-bit input vectors into one 256-bit
5319 input vector, we can use VPERMD and VPERMPS for the full
5320 two-operand shuffle. */
5321 t1 = gen_reg_rtx (V8SImode((void) 0, E_V8SImode));
5322 t2 = gen_reg_rtx (V8SImode((void) 0, E_V8SImode));
5323 emit_insn (gen_avx_vec_concatv8si (t1, op0, op1));
5324 emit_insn (gen_avx_vec_concatv8si (t2, mask, mask));
5325 emit_insn (gen_avx2_permvarv8si (t1, t1, t2));
5326 emit_insn (gen_avx_vextractf128v8si (target, t1, const0_rtx(const_int_rtx[64])));
5327 return;
5328
5329 case E_V4SFmode:
5330 t1 = gen_reg_rtx (V8SFmode((void) 0, E_V8SFmode));
5331 t2 = gen_reg_rtx (V8SImode((void) 0, E_V8SImode));
5332 mask = gen_lowpartrtl_hooks.gen_lowpart (V4SImode((void) 0, E_V4SImode), mask);
5333 emit_insn (gen_avx_vec_concatv8sf (t1, op0, op1));
5334 emit_insn (gen_avx_vec_concatv8si (t2, mask, mask));
5335 emit_insn (gen_avx2_permvarv8sf (t1, t1, t2));
5336 emit_insn (gen_avx_vextractf128v8sf (target, t1, const0_rtx(const_int_rtx[64])));
5337 return;
5338
5339 case E_V32QImode:
5340 t1 = gen_reg_rtx (V32QImode((void) 0, E_V32QImode));
5341 t2 = gen_reg_rtx (V32QImode((void) 0, E_V32QImode));
5342 t3 = gen_reg_rtx (V32QImode((void) 0, E_V32QImode));
5343 vt2 = GEN_INT (-128)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (-128));
5344 vt = gen_const_vec_duplicate (V32QImode((void) 0, E_V32QImode), vt2);
5345 vt = force_reg (V32QImode((void) 0, E_V32QImode), vt);
5346 for (i = 0; i < 32; i++)
5347 vec[i] = i < 16 ? vt2 : const0_rtx(const_int_rtx[64]);
5348 vt2 = gen_rtx_CONST_VECTOR (V32QImode((void) 0, E_V32QImode), gen_rtvec_v (32, vec));
5349 vt2 = force_reg (V32QImode((void) 0, E_V32QImode), vt2);
5350 /* From mask create two adjusted masks, which contain the same
5351 bits as mask in the low 7 bits of each vector element.
5352 The first mask will have the most significant bit clear
5353 if it requests element from the same 128-bit lane
5354 and MSB set if it requests element from the other 128-bit lane.
5355 The second mask will have the opposite values of the MSB,
5356 and additionally will have its 128-bit lanes swapped.
5357 E.g. { 07 12 1e 09 ... | 17 19 05 1f ... } mask vector will have
5358 t1 { 07 92 9e 09 ... | 17 19 85 1f ... } and
5359 t3 { 97 99 05 9f ... | 87 12 1e 89 ... } where each ...
5360 stands for other 12 bytes. */
5361 /* The bit whether element is from the same lane or the other
5362 lane is bit 4, so shift it up by 3 to the MSB position. */
5363 t5 = gen_reg_rtx (V4DImode((void) 0, E_V4DImode));
5364 emit_insn (gen_ashlv4di3 (t5, gen_lowpartrtl_hooks.gen_lowpart (V4DImode((void) 0, E_V4DImode), mask),
5365 GEN_INT (3)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3))));
5366 /* Clear MSB bits from the mask just in case it had them set. */
5367 emit_insn (gen_avx2_andnotv32qi3 (t2, vt, mask));
5368 /* After this t1 will have MSB set for elements from other lane. */
5369 emit_insn (gen_xorv32qi3 (t1, gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t5), vt2));
5370 /* Clear bits other than MSB. */
5371 emit_insn (gen_andv32qi3 (t1, t1, vt));
5372 /* Or in the lower bits from mask into t3. */
5373 emit_insn (gen_iorv32qi3 (t3, t1, t2));
5374 /* And invert MSB bits in t1, so MSB is set for elements from the same
5375 lane. */
5376 emit_insn (gen_xorv32qi3 (t1, t1, vt));
5377 /* Swap 128-bit lanes in t3. */
5378 t6 = gen_reg_rtx (V4DImode((void) 0, E_V4DImode));
5379 emit_insn (gen_avx2_permv4di_1 (t6, gen_lowpartrtl_hooks.gen_lowpart (V4DImode((void) 0, E_V4DImode), t3),
5380 const2_rtx(const_int_rtx[64 +2]), GEN_INT (3)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)),
5381 const0_rtx(const_int_rtx[64]), const1_rtx(const_int_rtx[64 +1])));
5382 /* And or in the lower bits from mask into t1. */
5383 emit_insn (gen_iorv32qi3 (t1, t1, t2));
5384 if (one_operand_shuffle)
5385 {
5386 /* Each of these shuffles will put 0s in places where
5387 element from the other 128-bit lane is needed, otherwise
5388 will shuffle in the requested value. */
5389 emit_insn (gen_avx2_pshufbv32qi3 (t3, op0,
5390 gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t6)));
5391 emit_insn (gen_avx2_pshufbv32qi3 (t1, op0, t1));
5392 /* For t3 the 128-bit lanes are swapped again. */
5393 t7 = gen_reg_rtx (V4DImode((void) 0, E_V4DImode));
5394 emit_insn (gen_avx2_permv4di_1 (t7, gen_lowpartrtl_hooks.gen_lowpart (V4DImode((void) 0, E_V4DImode), t3),
5395 const2_rtx(const_int_rtx[64 +2]), GEN_INT (3)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)),
5396 const0_rtx(const_int_rtx[64]), const1_rtx(const_int_rtx[64 +1])));
5397 /* And oring both together leads to the result. */
5398 emit_insn (gen_iorv32qi3 (target, t1,
5399 gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t7)));
5400 if (target != operands[0])
5401 emit_move_insn (operands[0],
5402 gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (operands[0])((machine_mode) (operands[0])->mode), target));
5403 return;
5404 }
5405
5406 t4 = gen_reg_rtx (V32QImode((void) 0, E_V32QImode));
5407 /* Similarly to the above one_operand_shuffle code,
5408 just for repeated twice for each operand. merge_two:
5409 code will merge the two results together. */
5410 emit_insn (gen_avx2_pshufbv32qi3 (t4, op0,
5411 gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t6)));
5412 emit_insn (gen_avx2_pshufbv32qi3 (t3, op1,
5413 gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t6)));
5414 emit_insn (gen_avx2_pshufbv32qi3 (t2, op0, t1));
5415 emit_insn (gen_avx2_pshufbv32qi3 (t1, op1, t1));
5416 t7 = gen_reg_rtx (V4DImode((void) 0, E_V4DImode));
5417 emit_insn (gen_avx2_permv4di_1 (t7, gen_lowpartrtl_hooks.gen_lowpart (V4DImode((void) 0, E_V4DImode), t4),
5418 const2_rtx(const_int_rtx[64 +2]), GEN_INT (3)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)),
5419 const0_rtx(const_int_rtx[64]), const1_rtx(const_int_rtx[64 +1])));
5420 t8 = gen_reg_rtx (V4DImode((void) 0, E_V4DImode));
5421 emit_insn (gen_avx2_permv4di_1 (t8, gen_lowpartrtl_hooks.gen_lowpart (V4DImode((void) 0, E_V4DImode), t3),
5422 const2_rtx(const_int_rtx[64 +2]), GEN_INT (3)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (3)),
5423 const0_rtx(const_int_rtx[64]), const1_rtx(const_int_rtx[64 +1])));
5424 emit_insn (gen_iorv32qi3 (t4, t2, gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t7)));
5425 emit_insn (gen_iorv32qi3 (t3, t1, gen_lowpartrtl_hooks.gen_lowpart (V32QImode((void) 0, E_V32QImode), t8)));
5426 t1 = t4;
5427 t2 = t3;
5428 goto merge_two;
5429
5430 default:
5431 gcc_assert (GET_MODE_SIZE (mode) <= 16)((void)(!(((unsigned short) mode_to_bytes (mode).coeffs[0]) <=
16) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 5431, __FUNCTION__), 0 : 0))
;
5432 break;
5433 }
5434 }
5435
5436 if (TARGET_XOP((global_options.x_ix86_isa_flags & (1UL << 59)) !=
0)
)
5437 {
5438 /* The XOP VPPERM insn supports three inputs. By ignoring the
5439 one_operand_shuffle special case, we avoid creating another
5440 set of constant vectors in memory. */
5441 one_operand_shuffle = false;
5442
5443 /* mask = mask & {2*w-1, ...} */
5444 vt = GEN_INT (2*w - 1)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (2*w - 1));
5445 }
5446 else
5447 {
5448 /* mask = mask & {w-1, ...} */
5449 vt = GEN_INT (w - 1)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (w - 1));
5450 }
5451
5452 vt = gen_const_vec_duplicate (maskmode, vt);
5453 mask = expand_simple_binop (maskmode, AND, mask, vt,
5454 NULL_RTX(rtx) 0, 0, OPTAB_DIRECT);
5455
5456 /* For non-QImode operations, convert the word permutation control
5457 into a byte permutation control. */
5458 if (mode != V16QImode((void) 0, E_V16QImode))
5459 {
5460 mask = expand_simple_binop (maskmode, ASHIFT, mask,
5461 GEN_INT (exact_log2 (e))gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (exact_log2 (e))),
5462 NULL_RTX(rtx) 0, 0, OPTAB_DIRECT);
5463
5464 /* Convert mask to vector of chars. */
5465 mask = force_reg (V16QImode((void) 0, E_V16QImode), gen_lowpartrtl_hooks.gen_lowpart (V16QImode((void) 0, E_V16QImode), mask));
5466
5467 /* Replicate each of the input bytes into byte positions:
5468 (v2di) --> {0,0,0,0,0,0,0,0, 8,8,8,8,8,8,8,8}
5469 (v4si) --> {0,0,0,0, 4,4,4,4, 8,8,8,8, 12,12,12,12}
5470 (v8hi) --> {0,0, 2,2, 4,4, 6,6, ...}. */
5471 for (i = 0; i < 16; ++i)
5472 vec[i] = GEN_INT (i/e * e)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (i/e * e));
5473 vt = gen_rtx_CONST_VECTOR (V16QImode((void) 0, E_V16QImode), gen_rtvec_v (16, vec));
5474 vt = validize_mem (force_const_mem (V16QImode((void) 0, E_V16QImode), vt));
5475 if (TARGET_XOP((global_options.x_ix86_isa_flags & (1UL << 59)) !=
0)
)
5476 emit_insn (gen_xop_pperm (mask, mask, mask, vt));
5477 else
5478 emit_insn (gen_ssse3_pshufbv16qi3 (mask, mask, vt));
5479
5480 /* Convert it into the byte positions by doing
5481 mask = mask + {0,1,..,16/w, 0,1,..,16/w, ...} */
5482 for (i = 0; i < 16; ++i)
5483 vec[i] = GEN_INT (i % e)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (i % e));
5484 vt = gen_rtx_CONST_VECTOR (V16QImode((void) 0, E_V16QImode), gen_rtvec_v (16, vec));
5485 vt = validize_mem (force_const_mem (V16QImode((void) 0, E_V16QImode), vt));
5486 emit_insn (gen_addv16qi3 (mask, mask, vt));
5487 }
5488
5489 /* The actual shuffle operations all operate on V16QImode. */
5490 op0 = gen_lowpartrtl_hooks.gen_lowpart (V16QImode((void) 0, E_V16QImode), op0);
5491 op1 = gen_lowpartrtl_hooks.gen_lowpart (V16QImode((void) 0, E_V16QImode), op1);
5492
5493 if (TARGET_XOP((global_options.x_ix86_isa_flags & (1UL << 59)) !=
0)
)
5494 {
5495 if (GET_MODE (target)((machine_mode) (target)->mode) != V16QImode((void) 0, E_V16QImode))
5496 target = gen_reg_rtx (V16QImode((void) 0, E_V16QImode));
5497 emit_insn (gen_xop_pperm (target, op0, op1, mask));
5498 if (target != operands[0])
5499 emit_move_insn (operands[0],
5500 gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (operands[0])((machine_mode) (operands[0])->mode), target));
5501 }
5502 else if (one_operand_shuffle)
5503 {
5504 if (GET_MODE (target)((machine_mode) (target)->mode) != V16QImode((void) 0, E_V16QImode))
5505 target = gen_reg_rtx (V16QImode((void) 0, E_V16QImode));
5506 emit_insn (gen_ssse3_pshufbv16qi3 (target, op0, mask));
5507 if (target != operands[0])
5508 emit_move_insn (operands[0],
5509 gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (operands[0])((machine_mode) (operands[0])->mode), target));
5510 }
5511 else
5512 {
5513 rtx xops[6];
5514 bool ok;
5515
5516 /* Shuffle the two input vectors independently. */
5517 t1 = gen_reg_rtx (V16QImode((void) 0, E_V16QImode));
5518 t2 = gen_reg_rtx (V16QImode((void) 0, E_V16QImode));
5519 emit_insn (gen_ssse3_pshufbv16qi3 (t1, op0, mask));
5520 emit_insn (gen_ssse3_pshufbv16qi3 (t2, op1, mask));
5521
5522 merge_two:
5523 /* Then merge them together. The key is whether any given control
5524 element contained a bit set that indicates the second word. */
5525 mask = operands[3];
5526 vt = GEN_INT (w)gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (w));
5527 if (maskmode == V2DImode((void) 0, E_V2DImode) && !TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
5528 {
5529 /* Without SSE4.1, we don't have V2DImode EQ. Perform one
5530 more shuffle to convert the V2DI input mask into a V4SI
5531 input mask. At which point the masking that expand_int_vcond
5532 will work as desired. */
5533 rtx t3 = gen_reg_rtx (V4SImode((void) 0, E_V4SImode));
5534 emit_insn (gen_sse2_pshufd_1 (t3, gen_lowpartrtl_hooks.gen_lowpart (V4SImode((void) 0, E_V4SImode), mask),
5535 const0_rtx(const_int_rtx[64]), const0_rtx(const_int_rtx[64]),
5536 const2_rtx(const_int_rtx[64 +2]), const2_rtx(const_int_rtx[64 +2])));
5537 mask = t3;
5538 maskmode = V4SImode((void) 0, E_V4SImode);
5539 e = w = 4;
5540 }
5541
5542 vt = gen_const_vec_duplicate (maskmode, vt);
5543 vt = force_reg (maskmode, vt);
5544 mask = expand_simple_binop (maskmode, AND, mask, vt,
5545 NULL_RTX(rtx) 0, 0, OPTAB_DIRECT);
5546
5547 if (GET_MODE (target)((machine_mode) (target)->mode) != mode)
5548 target = gen_reg_rtx (mode);
5549 xops[0] = target;
5550 xops[1] = gen_lowpartrtl_hooks.gen_lowpart (mode, t2);
5551 xops[2] = gen_lowpartrtl_hooks.gen_lowpart (mode, t1);
5552 xops[3] = gen_rtx_EQ (maskmode, mask, vt)gen_rtx_fmt_ee_stat ((EQ), ((maskmode)), ((mask)), ((vt)) );
5553 xops[4] = mask;
5554 xops[5] = vt;
5555 ok = ix86_expand_int_vcond (xops);
5556 gcc_assert (ok)((void)(!(ok) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/config/i386/i386-expand.cc"
, 5556, __FUNCTION__), 0 : 0))
;
5557 if (target != operands[0])
5558 emit_move_insn (operands[0],
5559 gen_lowpartrtl_hooks.gen_lowpart (GET_MODE (operands[0])((machine_mode) (operands[0])->mode), target));
5560 }
5561}
5562
5563/* Unpack OP[1] into the next wider integer vector type. UNSIGNED_P is
5564 true if we should do zero extension, else sign extension. HIGH_P is
5565 true if we want the N/2 high elements, else the low elements. */
5566
5567void
5568ix86_expand_sse_unpack (rtx dest, rtx src, bool unsigned_p, bool high_p)
5569{
5570 machine_mode imode = GET_MODE (src)((machine_mode) (src)->mode);
5571 rtx tmp;
5572
5573 if (TARGET_SSE4_1((global_options.x_ix86_isa_flags & (1UL << 38)) !=
0)
)
5574 {
5575 rtx (*unpack)(rtx, rtx);
5576 rtx (*extract)(rtx, rtx) = NULL__null;
5577 machine_mode halfmode = BLKmode((void) 0, E_BLKmode);
5578
5579 switch (imode)
5580 {
5581 case E_V64QImode:
5582 if (unsigned_p)
5583 unpack = gen_avx512bw_zero_extendv32qiv32hi2;
5584 else
5585 unpack = gen_avx512bw_sign_extendv32qiv32hi2;
5586 halfmode = V32QImode((void) 0, E_V32QImode);
5587 extract
5588 = high_p ? gen_vec_extract_hi_v64qi : gen_vec_extract_lo_v64qi;
5589 break;
5590 case E_V32QImode:
5591 if (unsigned_p)
5592 unpack = gen_avx2_zero_extendv16qiv16hi2;
5593 else
5594 unpack = gen_avx2_sign_extendv16qiv16hi2;
5595 halfmode = V16QImode((void) 0, E_V16QImode);
5596 extract
5597 = high_p ? gen_vec_extract_hi_v32qi : gen_vec_extract_lo_v32qi;
5598 break;
5599 case E_V32HImode:
5600 if (unsigned_p)
5601 unpack = gen_avx512f_zero_extendv16hiv16si2;
5602 else
5603 unpack = gen_avx512f_sign_extendv16hiv16si2;
5604 halfmode = V16HImode((void) 0, E_V16HImode);
5605 extract
5606 = high_p ? gen_vec_extract_hi_v32hi : gen_vec_extract_lo_v32hi;
5607 break;
5608 case E_V16HImode:
5609 if (unsigned_p)
5610 unpack = gen_avx2_zero_extendv8hiv8si2;
5611 else
5612 unpack = gen_avx2_sign_extendv8hiv8si2;
5613 halfmode = V8HImode((void) 0, E_V8HImode);
5614 extract
5615 = high_p ? gen_vec_extract_hi_v16hi : gen_vec_extract_lo_v16hi;
5616 break;
5617 case E_V16SImode:
5618 if (unsigned_p)
5619 unpack = gen_avx512f_zero_extendv8siv8di2;
5620 else
5621 unpack = gen_avx512f_sign_extendv8siv8di2;
5622 halfmode = V8SImode((void) 0, E_V8SImode);
5623 extract
5624 = high_p ? gen_vec_extract_hi_v16si : gen_vec_extract_lo_v16si;
5625 break;
5626 case E_V8SImode:
5627 if (unsigned_p)
5628 unpack = gen_avx2_zero_extendv4siv4di2;
5629 else
5630 unpack = gen_avx2_sign_extendv4siv4di2;
5631 halfmode = V4SImode((void) 0, E_V4SImode);
5632 extract
5633 = high_p ? gen_vec_extract_hi_v8si : gen_vec_extract_lo_v8si;
5634 break;
5635 case E_V16QImode:
5636 if (unsigned_p)
5637 unpack = gen_sse4_1_zero_extendv8qiv8hi2;
5638 else
5639 unpack = gen_sse4_1_sign_extendv8qiv8hi2;
5640 break;
5641 case E_V8HImode:
5642 if (unsigned_p)
5643 unpack = gen_sse4_1_zero_extendv4hiv4si2;
5644 else