Bug Summary

File:build/gcc/config/i386/i386-expand.c
Warning:line 8647, column 4
Value stored to 'max_size' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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