Bug Summary

File:build/gcc/config/i386/i386-expand.c
Warning:line 17210, column 5
Division by zero

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