Branch data Line data Source code
1 : : /* Subroutines used for code generation on IA-32.
2 : : Copyright (C) 1988-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU General Public License as published by
8 : : the Free Software Foundation; either version 3, or (at your option)
9 : : any later version.
10 : :
11 : : GCC is distributed in the hope that it will be useful,
12 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : : GNU General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #define INCLUDE_STRING
21 : : #define IN_TARGET_CODE 1
22 : :
23 : : #include "config.h"
24 : : #include "system.h"
25 : : #include "coretypes.h"
26 : : #include "backend.h"
27 : : #include "rtl.h"
28 : : #include "tree.h"
29 : : #include "memmodel.h"
30 : : #include "gimple.h"
31 : : #include "cfghooks.h"
32 : : #include "cfgloop.h"
33 : : #include "df.h"
34 : : #include "tm_p.h"
35 : : #include "stringpool.h"
36 : : #include "expmed.h"
37 : : #include "optabs.h"
38 : : #include "regs.h"
39 : : #include "emit-rtl.h"
40 : : #include "recog.h"
41 : : #include "cgraph.h"
42 : : #include "diagnostic.h"
43 : : #include "cfgbuild.h"
44 : : #include "alias.h"
45 : : #include "fold-const.h"
46 : : #include "attribs.h"
47 : : #include "calls.h"
48 : : #include "stor-layout.h"
49 : : #include "varasm.h"
50 : : #include "output.h"
51 : : #include "insn-attr.h"
52 : : #include "flags.h"
53 : : #include "except.h"
54 : : #include "explow.h"
55 : : #include "expr.h"
56 : : #include "cfgrtl.h"
57 : : #include "common/common-target.h"
58 : : #include "langhooks.h"
59 : : #include "reload.h"
60 : : #include "gimplify.h"
61 : : #include "dwarf2.h"
62 : : #include "tm-constrs.h"
63 : : #include "cselib.h"
64 : : #include "sched-int.h"
65 : : #include "opts.h"
66 : : #include "tree-pass.h"
67 : : #include "context.h"
68 : : #include "pass_manager.h"
69 : : #include "target-globals.h"
70 : : #include "gimple-iterator.h"
71 : : #include "gimple-fold.h"
72 : : #include "tree-vectorizer.h"
73 : : #include "shrink-wrap.h"
74 : : #include "builtins.h"
75 : : #include "rtl-iter.h"
76 : : #include "tree-iterator.h"
77 : : #include "dbgcnt.h"
78 : : #include "case-cfn-macros.h"
79 : : #include "dojump.h"
80 : : #include "fold-const-call.h"
81 : : #include "tree-vrp.h"
82 : : #include "tree-ssanames.h"
83 : : #include "selftest.h"
84 : : #include "selftest-rtl.h"
85 : : #include "print-rtl.h"
86 : : #include "intl.h"
87 : : #include "ifcvt.h"
88 : : #include "symbol-summary.h"
89 : : #include "sreal.h"
90 : : #include "ipa-cp.h"
91 : : #include "ipa-prop.h"
92 : : #include "ipa-fnsummary.h"
93 : : #include "wide-int-bitmask.h"
94 : : #include "tree-vector-builder.h"
95 : : #include "debug.h"
96 : : #include "dwarf2out.h"
97 : : #include "i386-options.h"
98 : : #include "i386-builtins.h"
99 : : #include "i386-expand.h"
100 : : #include "i386-features.h"
101 : : #include "function-abi.h"
102 : : #include "rtl-error.h"
103 : : #include "gimple-pretty-print.h"
104 : :
105 : : /* This file should be included last. */
106 : : #include "target-def.h"
107 : :
108 : : static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
109 : : static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
110 : :
111 : :
112 : : #ifndef CHECK_STACK_LIMIT
113 : : #define CHECK_STACK_LIMIT (-1)
114 : : #endif
115 : :
116 : : /* Return index of given mode in mult and division cost tables. */
117 : : #define MODE_INDEX(mode) \
118 : : ((mode) == QImode ? 0 \
119 : : : (mode) == HImode ? 1 \
120 : : : (mode) == SImode ? 2 \
121 : : : (mode) == DImode ? 3 \
122 : : : 4)
123 : :
124 : :
125 : : /* Set by -mtune. */
126 : : const struct processor_costs *ix86_tune_cost = NULL;
127 : :
128 : : /* Set by -mtune or -Os. */
129 : : const struct processor_costs *ix86_cost = NULL;
130 : :
131 : : /* In case the average insn count for single function invocation is
132 : : lower than this constant, emit fast (but longer) prologue and
133 : : epilogue code. */
134 : : #define FAST_PROLOGUE_INSN_COUNT 20
135 : :
136 : : /* Names for 8 (low), 8 (high), and 16-bit registers, respectively. */
137 : : static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
138 : : static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
139 : : static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
140 : :
141 : : /* Array of the smallest class containing reg number REGNO, indexed by
142 : : REGNO. Used by REGNO_REG_CLASS in i386.h. */
143 : :
144 : : enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
145 : : {
146 : : /* ax, dx, cx, bx */
147 : : AREG, DREG, CREG, BREG,
148 : : /* si, di, bp, sp */
149 : : SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
150 : : /* FP registers */
151 : : FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
152 : : FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
153 : : /* arg pointer, flags, fpsr, frame */
154 : : NON_Q_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
155 : : /* SSE registers */
156 : : SSE_FIRST_REG, SSE_REGS, SSE_REGS, SSE_REGS,
157 : : SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
158 : : /* MMX registers */
159 : : MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
160 : : MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
161 : : /* REX registers */
162 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
163 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
164 : : /* SSE REX registers */
165 : : SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
166 : : SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
167 : : /* AVX-512 SSE registers */
168 : : ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
169 : : ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
170 : : ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
171 : : ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
172 : : /* Mask registers. */
173 : : ALL_MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
174 : : MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
175 : : /* REX2 registers */
176 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
177 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
178 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
179 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
180 : : };
181 : :
182 : : /* The "default" register map used in 32bit mode. */
183 : :
184 : : unsigned int const debugger_register_map[FIRST_PSEUDO_REGISTER] =
185 : : {
186 : : /* general regs */
187 : : 0, 2, 1, 3, 6, 7, 4, 5,
188 : : /* fp regs */
189 : : 12, 13, 14, 15, 16, 17, 18, 19,
190 : : /* arg, flags, fpsr, frame */
191 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
192 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
193 : : /* SSE */
194 : : 21, 22, 23, 24, 25, 26, 27, 28,
195 : : /* MMX */
196 : : 29, 30, 31, 32, 33, 34, 35, 36,
197 : : /* extended integer registers */
198 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
199 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
200 : : /* extended sse registers */
201 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
202 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
203 : : /* AVX-512 registers 16-23 */
204 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
205 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
206 : : /* AVX-512 registers 24-31 */
207 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
208 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
209 : : /* Mask registers */
210 : : 93, 94, 95, 96, 97, 98, 99, 100
211 : : };
212 : :
213 : : /* The "default" register map used in 64bit mode. */
214 : :
215 : : unsigned int const debugger64_register_map[FIRST_PSEUDO_REGISTER] =
216 : : {
217 : : /* general regs */
218 : : 0, 1, 2, 3, 4, 5, 6, 7,
219 : : /* fp regs */
220 : : 33, 34, 35, 36, 37, 38, 39, 40,
221 : : /* arg, flags, fpsr, frame */
222 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
223 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
224 : : /* SSE */
225 : : 17, 18, 19, 20, 21, 22, 23, 24,
226 : : /* MMX */
227 : : 41, 42, 43, 44, 45, 46, 47, 48,
228 : : /* extended integer registers */
229 : : 8, 9, 10, 11, 12, 13, 14, 15,
230 : : /* extended SSE registers */
231 : : 25, 26, 27, 28, 29, 30, 31, 32,
232 : : /* AVX-512 registers 16-23 */
233 : : 67, 68, 69, 70, 71, 72, 73, 74,
234 : : /* AVX-512 registers 24-31 */
235 : : 75, 76, 77, 78, 79, 80, 81, 82,
236 : : /* Mask registers */
237 : : 118, 119, 120, 121, 122, 123, 124, 125,
238 : : /* rex2 extend interger registers */
239 : : 130, 131, 132, 133, 134, 135, 136, 137,
240 : : 138, 139, 140, 141, 142, 143, 144, 145
241 : : };
242 : :
243 : : /* Define the register numbers to be used in Dwarf debugging information.
244 : : The SVR4 reference port C compiler uses the following register numbers
245 : : in its Dwarf output code:
246 : : 0 for %eax (gcc regno = 0)
247 : : 1 for %ecx (gcc regno = 2)
248 : : 2 for %edx (gcc regno = 1)
249 : : 3 for %ebx (gcc regno = 3)
250 : : 4 for %esp (gcc regno = 7)
251 : : 5 for %ebp (gcc regno = 6)
252 : : 6 for %esi (gcc regno = 4)
253 : : 7 for %edi (gcc regno = 5)
254 : : The following three DWARF register numbers are never generated by
255 : : the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
256 : : believed these numbers have these meanings.
257 : : 8 for %eip (no gcc equivalent)
258 : : 9 for %eflags (gcc regno = 17)
259 : : 10 for %trapno (no gcc equivalent)
260 : : It is not at all clear how we should number the FP stack registers
261 : : for the x86 architecture. If the version of SDB on x86/svr4 were
262 : : a bit less brain dead with respect to floating-point then we would
263 : : have a precedent to follow with respect to DWARF register numbers
264 : : for x86 FP registers, but the SDB on x86/svr4 was so completely
265 : : broken with respect to FP registers that it is hardly worth thinking
266 : : of it as something to strive for compatibility with.
267 : : The version of x86/svr4 SDB I had does (partially)
268 : : seem to believe that DWARF register number 11 is associated with
269 : : the x86 register %st(0), but that's about all. Higher DWARF
270 : : register numbers don't seem to be associated with anything in
271 : : particular, and even for DWARF regno 11, SDB only seemed to under-
272 : : stand that it should say that a variable lives in %st(0) (when
273 : : asked via an `=' command) if we said it was in DWARF regno 11,
274 : : but SDB still printed garbage when asked for the value of the
275 : : variable in question (via a `/' command).
276 : : (Also note that the labels SDB printed for various FP stack regs
277 : : when doing an `x' command were all wrong.)
278 : : Note that these problems generally don't affect the native SVR4
279 : : C compiler because it doesn't allow the use of -O with -g and
280 : : because when it is *not* optimizing, it allocates a memory
281 : : location for each floating-point variable, and the memory
282 : : location is what gets described in the DWARF AT_location
283 : : attribute for the variable in question.
284 : : Regardless of the severe mental illness of the x86/svr4 SDB, we
285 : : do something sensible here and we use the following DWARF
286 : : register numbers. Note that these are all stack-top-relative
287 : : numbers.
288 : : 11 for %st(0) (gcc regno = 8)
289 : : 12 for %st(1) (gcc regno = 9)
290 : : 13 for %st(2) (gcc regno = 10)
291 : : 14 for %st(3) (gcc regno = 11)
292 : : 15 for %st(4) (gcc regno = 12)
293 : : 16 for %st(5) (gcc regno = 13)
294 : : 17 for %st(6) (gcc regno = 14)
295 : : 18 for %st(7) (gcc regno = 15)
296 : : */
297 : : unsigned int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER] =
298 : : {
299 : : /* general regs */
300 : : 0, 2, 1, 3, 6, 7, 5, 4,
301 : : /* fp regs */
302 : : 11, 12, 13, 14, 15, 16, 17, 18,
303 : : /* arg, flags, fpsr, frame */
304 : : IGNORED_DWARF_REGNUM, 9,
305 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
306 : : /* SSE registers */
307 : : 21, 22, 23, 24, 25, 26, 27, 28,
308 : : /* MMX registers */
309 : : 29, 30, 31, 32, 33, 34, 35, 36,
310 : : /* extended integer registers */
311 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
312 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
313 : : /* extended sse registers */
314 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
315 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
316 : : /* AVX-512 registers 16-23 */
317 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
318 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
319 : : /* AVX-512 registers 24-31 */
320 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
321 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
322 : : /* Mask registers */
323 : : 93, 94, 95, 96, 97, 98, 99, 100
324 : : };
325 : :
326 : : /* Define parameter passing and return registers. */
327 : :
328 : : static int const x86_64_int_parameter_registers[6] =
329 : : {
330 : : DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG
331 : : };
332 : :
333 : : static int const x86_64_ms_abi_int_parameter_registers[4] =
334 : : {
335 : : CX_REG, DX_REG, R8_REG, R9_REG
336 : : };
337 : :
338 : : /* Similar as Clang's preserve_none function parameter passing.
339 : : NB: Use DI_REG and SI_REG, see ix86_function_value_regno_p. */
340 : :
341 : : static int const x86_64_preserve_none_int_parameter_registers[6] =
342 : : {
343 : : R12_REG, R13_REG, R14_REG, R15_REG, DI_REG, SI_REG
344 : : };
345 : :
346 : : static int const x86_64_int_return_registers[4] =
347 : : {
348 : : AX_REG, DX_REG, DI_REG, SI_REG
349 : : };
350 : :
351 : : /* Define the structure for the machine field in struct function. */
352 : :
353 : : struct GTY(()) stack_local_entry {
354 : : unsigned short mode;
355 : : unsigned short n;
356 : : rtx rtl;
357 : : struct stack_local_entry *next;
358 : : };
359 : :
360 : : /* Which cpu are we scheduling for. */
361 : : enum attr_cpu ix86_schedule;
362 : :
363 : : /* Which cpu are we optimizing for. */
364 : : enum processor_type ix86_tune;
365 : :
366 : : /* Which instruction set architecture to use. */
367 : : enum processor_type ix86_arch;
368 : :
369 : : /* True if processor has SSE prefetch instruction. */
370 : : unsigned char ix86_prefetch_sse;
371 : :
372 : : /* Preferred alignment for stack boundary in bits. */
373 : : unsigned int ix86_preferred_stack_boundary;
374 : :
375 : : /* Alignment for incoming stack boundary in bits specified at
376 : : command line. */
377 : : unsigned int ix86_user_incoming_stack_boundary;
378 : :
379 : : /* Default alignment for incoming stack boundary in bits. */
380 : : unsigned int ix86_default_incoming_stack_boundary;
381 : :
382 : : /* Alignment for incoming stack boundary in bits. */
383 : : unsigned int ix86_incoming_stack_boundary;
384 : :
385 : : /* True if there is no direct access to extern symbols. */
386 : : bool ix86_has_no_direct_extern_access;
387 : :
388 : : /* Calling abi specific va_list type nodes. */
389 : : tree sysv_va_list_type_node;
390 : : tree ms_va_list_type_node;
391 : :
392 : : /* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
393 : : char internal_label_prefix[16];
394 : : int internal_label_prefix_len;
395 : :
396 : : /* Fence to use after loop using movnt. */
397 : : tree x86_mfence;
398 : :
399 : : /* Register class used for passing given 64bit part of the argument.
400 : : These represent classes as documented by the PS ABI, with the exception
401 : : of SSESF, SSEDF classes, that are basically SSE class, just gcc will
402 : : use SF or DFmode move instead of DImode to avoid reformatting penalties.
403 : :
404 : : Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
405 : : whenever possible (upper half does contain padding). */
406 : : enum x86_64_reg_class
407 : : {
408 : : X86_64_NO_CLASS,
409 : : X86_64_INTEGER_CLASS,
410 : : X86_64_INTEGERSI_CLASS,
411 : : X86_64_SSE_CLASS,
412 : : X86_64_SSEHF_CLASS,
413 : : X86_64_SSESF_CLASS,
414 : : X86_64_SSEDF_CLASS,
415 : : X86_64_SSEUP_CLASS,
416 : : X86_64_X87_CLASS,
417 : : X86_64_X87UP_CLASS,
418 : : X86_64_COMPLEX_X87_CLASS,
419 : : X86_64_MEMORY_CLASS
420 : : };
421 : :
422 : : #define MAX_CLASSES 8
423 : :
424 : : /* Table of constants used by fldpi, fldln2, etc.... */
425 : : static REAL_VALUE_TYPE ext_80387_constants_table [5];
426 : : static bool ext_80387_constants_init;
427 : :
428 : :
429 : : static rtx ix86_function_value (const_tree, const_tree, bool);
430 : : static bool ix86_function_value_regno_p (const unsigned int);
431 : : static unsigned int ix86_function_arg_boundary (machine_mode,
432 : : const_tree);
433 : : static rtx ix86_static_chain (const_tree, bool);
434 : : static int ix86_function_regparm (const_tree, const_tree);
435 : : static void ix86_compute_frame_layout (void);
436 : : static tree ix86_canonical_va_list_type (tree);
437 : : static unsigned int split_stack_prologue_scratch_regno (void);
438 : : static bool i386_asm_output_addr_const_extra (FILE *, rtx);
439 : :
440 : : static bool ix86_can_inline_p (tree, tree);
441 : : static unsigned int ix86_minimum_incoming_stack_boundary (bool);
442 : :
443 : : typedef enum ix86_flags_cc
444 : : {
445 : : X86_CCO = 0, X86_CCNO, X86_CCB, X86_CCNB,
446 : : X86_CCE, X86_CCNE, X86_CCBE, X86_CCNBE,
447 : : X86_CCS, X86_CCNS, X86_CCP, X86_CCNP,
448 : : X86_CCL, X86_CCNL, X86_CCLE, X86_CCNLE
449 : : } ix86_cc;
450 : :
451 : : static const char *ix86_ccmp_dfv_mapping[] =
452 : : {
453 : : "{dfv=of}", "{dfv=}", "{dfv=cf}", "{dfv=}",
454 : : "{dfv=zf}", "{dfv=}", "{dfv=cf, zf}", "{dfv=}",
455 : : "{dfv=sf}", "{dfv=}", "{dfv=cf}", "{dfv=}",
456 : : "{dfv=sf}", "{dfv=sf, of}", "{dfv=sf, of, zf}", "{dfv=sf, of}"
457 : : };
458 : :
459 : :
460 : : /* Whether -mtune= or -march= were specified */
461 : : int ix86_tune_defaulted;
462 : : int ix86_arch_specified;
463 : :
464 : : /* Return true if a red-zone is in use. We can't use red-zone when
465 : : there are local indirect jumps, like "indirect_jump" or "tablejump",
466 : : which jumps to another place in the function, since "call" in the
467 : : indirect thunk pushes the return address onto stack, destroying
468 : : red-zone.
469 : :
470 : : NB: Don't use red-zone for functions with no_caller_saved_registers
471 : : and 32 GPRs or 16 XMM registers since 128-byte red-zone is too small
472 : : for 31 GPRs or 15 GPRs + 16 XMM registers.
473 : :
474 : : TODO: If we can reserve the first 2 WORDs, for PUSH and, another
475 : : for CALL, in red-zone, we can allow local indirect jumps with
476 : : indirect thunk. */
477 : :
478 : : bool
479 : 9704290 : ix86_using_red_zone (void)
480 : : {
481 : 9704290 : return (TARGET_RED_ZONE
482 : 8768046 : && !TARGET_64BIT_MS_ABI
483 : 8465598 : && ((!TARGET_APX_EGPR && !TARGET_SSE)
484 : 8442693 : || (cfun->machine->call_saved_registers
485 : 8442693 : != TYPE_NO_CALLER_SAVED_REGISTERS))
486 : 18169835 : && (!cfun->machine->has_local_indirect_jump
487 : 72391 : || cfun->machine->indirect_branch_type == indirect_branch_keep));
488 : : }
489 : :
490 : : /* Return true, if profiling code should be emitted before
491 : : prologue. Otherwise it returns false.
492 : : Note: For x86 with "hotfix" it is sorried. */
493 : : static bool
494 : 4400499 : ix86_profile_before_prologue (void)
495 : : {
496 : 4400499 : return flag_fentry != 0;
497 : : }
498 : :
499 : : /* Update register usage after having seen the compiler flags. */
500 : :
501 : : static void
502 : 829140 : ix86_conditional_register_usage (void)
503 : : {
504 : 829140 : int i, c_mask;
505 : :
506 : : /* If there are no caller-saved registers, preserve all registers.
507 : : except fixed_regs and registers used for function return value
508 : : since aggregate_value_p checks call_used_regs[regno] on return
509 : : value. */
510 : 829140 : if (cfun
511 : 63470 : && (cfun->machine->call_saved_registers
512 : 63470 : == TYPE_NO_CALLER_SAVED_REGISTERS))
513 : 397017 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
514 : 392748 : if (!fixed_regs[i] && !ix86_function_value_regno_p (i))
515 : 353533 : call_used_regs[i] = 0;
516 : :
517 : : /* For 32-bit targets, disable the REX registers. */
518 : 829140 : if (! TARGET_64BIT)
519 : : {
520 : 133281 : for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
521 : 118472 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
522 : 133281 : for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
523 : 118472 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
524 : 251753 : for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
525 : 236944 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
526 : : }
527 : :
528 : : /* See the definition of CALL_USED_REGISTERS in i386.h. */
529 : 829140 : c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT_MS_ABI);
530 : :
531 : 829140 : CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
532 : :
533 : 77110020 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
534 : : {
535 : : /* Set/reset conditionally defined registers from
536 : : CALL_USED_REGISTERS initializer. */
537 : 76280880 : if (call_used_regs[i] > 1)
538 : 13206419 : call_used_regs[i] = !!(call_used_regs[i] & c_mask);
539 : :
540 : : /* Calculate registers of CLOBBERED_REGS register set
541 : : as call used registers from GENERAL_REGS register set. */
542 : 76280880 : if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
543 : 76280880 : && call_used_regs[i])
544 : 23118447 : SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
545 : : }
546 : :
547 : : /* If MMX is disabled, disable the registers. */
548 : 829140 : if (! TARGET_MMX)
549 : 387102 : accessible_reg_set &= ~reg_class_contents[MMX_REGS];
550 : :
551 : : /* If SSE is disabled, disable the registers. */
552 : 829140 : if (! TARGET_SSE)
553 : 381916 : accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS];
554 : :
555 : : /* If the FPU is disabled, disable the registers. */
556 : 829140 : if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
557 : 382312 : accessible_reg_set &= ~reg_class_contents[FLOAT_REGS];
558 : :
559 : : /* If AVX512F is disabled, disable the registers. */
560 : 829140 : if (! TARGET_AVX512F)
561 : : {
562 : 9947703 : for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
563 : 9362544 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
564 : :
565 : 1170318 : accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS];
566 : : }
567 : :
568 : : /* If APX is disabled, disable the registers. */
569 : 829140 : if (! (TARGET_APX_EGPR && TARGET_64BIT))
570 : : {
571 : 14085435 : for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)
572 : 13256880 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
573 : : }
574 : 829140 : }
575 : :
576 : : /* Canonicalize a comparison from one we don't have to one we do have. */
577 : :
578 : : static void
579 : 22539527 : ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
580 : : bool op0_preserve_value)
581 : : {
582 : : /* The order of operands in x87 ficom compare is forced by combine in
583 : : simplify_comparison () function. Float operator is treated as RTX_OBJ
584 : : with a precedence over other operators and is always put in the first
585 : : place. Swap condition and operands to match ficom instruction. */
586 : 22539527 : if (!op0_preserve_value
587 : 21732187 : && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1))
588 : : {
589 : 6 : enum rtx_code scode = swap_condition ((enum rtx_code) *code);
590 : :
591 : : /* We are called only for compares that are split to SAHF instruction.
592 : : Ensure that we have setcc/jcc insn for the swapped condition. */
593 : 6 : if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN)
594 : : {
595 : 6 : std::swap (*op0, *op1);
596 : 6 : *code = (int) scode;
597 : 6 : return;
598 : : }
599 : : }
600 : :
601 : : /* Swap operands of GTU comparison to canonicalize
602 : : addcarry/subborrow comparison. */
603 : 21732181 : if (!op0_preserve_value
604 : 21732181 : && *code == GTU
605 : 776841 : && GET_CODE (*op0) == PLUS
606 : 325468 : && ix86_carry_flag_operator (XEXP (*op0, 0), VOIDmode)
607 : 48691 : && GET_CODE (XEXP (*op0, 1)) == ZERO_EXTEND
608 : 44490 : && GET_CODE (*op1) == ZERO_EXTEND)
609 : : {
610 : 41455 : std::swap (*op0, *op1);
611 : 41455 : *code = (int) swap_condition ((enum rtx_code) *code);
612 : 41455 : return;
613 : : }
614 : : }
615 : :
616 : : /* Hook to determine if one function can safely inline another. */
617 : :
618 : : static bool
619 : 9625683 : ix86_can_inline_p (tree caller, tree callee)
620 : : {
621 : 9625683 : tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
622 : 9625683 : tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
623 : :
624 : : /* Changes of those flags can be tolerated for always inlines. Lets hope
625 : : user knows what he is doing. */
626 : 9625683 : unsigned HOST_WIDE_INT always_inline_safe_mask
627 : : = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
628 : : | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
629 : : | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
630 : : | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
631 : : | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
632 : : | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
633 : : | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
634 : :
635 : :
636 : 9625683 : if (!callee_tree)
637 : 8989703 : callee_tree = target_option_default_node;
638 : 9625683 : if (!caller_tree)
639 : 8989785 : caller_tree = target_option_default_node;
640 : 9625683 : if (callee_tree == caller_tree)
641 : : return true;
642 : :
643 : 5191 : struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
644 : 5191 : struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
645 : 5191 : bool ret = false;
646 : 5191 : bool always_inline
647 : 5191 : = (DECL_DISREGARD_INLINE_LIMITS (callee)
648 : 9771 : && lookup_attribute ("always_inline",
649 : 4580 : DECL_ATTRIBUTES (callee)));
650 : :
651 : : /* If callee only uses GPRs, ignore MASK_80387. */
652 : 5191 : if (TARGET_GENERAL_REGS_ONLY_P (callee_opts->x_ix86_target_flags))
653 : 1023 : always_inline_safe_mask |= MASK_80387;
654 : :
655 : 5191 : cgraph_node *callee_node = cgraph_node::get (callee);
656 : : /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
657 : : function can inline a SSE2 function but a SSE2 function can't inline
658 : : a SSE4 function. */
659 : 5191 : if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
660 : : != callee_opts->x_ix86_isa_flags)
661 : 4961 : || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
662 : : != callee_opts->x_ix86_isa_flags2))
663 : : ret = false;
664 : :
665 : : /* See if we have the same non-isa options. */
666 : 4940 : else if ((!always_inline
667 : 376 : && caller_opts->x_target_flags != callee_opts->x_target_flags)
668 : 4896 : || (caller_opts->x_target_flags & ~always_inline_safe_mask)
669 : 4896 : != (callee_opts->x_target_flags & ~always_inline_safe_mask))
670 : : ret = false;
671 : :
672 : 4896 : else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
673 : : /* If the calle doesn't use FP expressions differences in
674 : : ix86_fpmath can be ignored. We are called from FEs
675 : : for multi-versioning call optimization, so beware of
676 : : ipa_fn_summaries not available. */
677 : 1240 : && (! ipa_fn_summaries
678 : 1240 : || ipa_fn_summaries->get (callee_node) == NULL
679 : 1240 : || ipa_fn_summaries->get (callee_node)->fp_expressions))
680 : : ret = false;
681 : :
682 : : /* At this point we cannot identify whether arch or tune setting
683 : : comes from target attribute or not. So the most conservative way
684 : : is to allow the callee that uses default arch and tune string to
685 : : be inlined. */
686 : 4622 : else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
687 : 1423 : && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
688 : : ret = true;
689 : :
690 : : /* See if arch, tune, etc. are the same. As previous ISA flags already
691 : : checks if callee's ISA is subset of caller's, do not block
692 : : always_inline attribute for callee even it has different arch. */
693 : 3207 : else if (!always_inline && caller_opts->arch != callee_opts->arch)
694 : : ret = false;
695 : :
696 : 3 : else if (!always_inline && caller_opts->tune != callee_opts->tune)
697 : : ret = false;
698 : :
699 : 3207 : else if (!always_inline
700 : 3 : && caller_opts->branch_cost != callee_opts->branch_cost)
701 : : ret = false;
702 : :
703 : : else
704 : 9625114 : ret = true;
705 : :
706 : : return ret;
707 : : }
708 : :
709 : : /* Return true if this goes in large data/bss. */
710 : :
711 : : static bool
712 : 80663991 : ix86_in_large_data_p (tree exp)
713 : : {
714 : 80663991 : if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC
715 : 80663753 : && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC)
716 : : return false;
717 : :
718 : 1090 : if (exp == NULL_TREE)
719 : : return false;
720 : :
721 : : /* Functions are never large data. */
722 : 1090 : if (TREE_CODE (exp) == FUNCTION_DECL)
723 : : return false;
724 : :
725 : : /* Automatic variables are never large data. */
726 : 260 : if (VAR_P (exp) && !is_global_var (exp))
727 : : return false;
728 : :
729 : 260 : if (VAR_P (exp) && DECL_SECTION_NAME (exp))
730 : : {
731 : 51 : const char *section = DECL_SECTION_NAME (exp);
732 : 51 : if (strcmp (section, ".ldata") == 0
733 : 51 : || strcmp (section, ".lbss") == 0)
734 : : return true;
735 : : return false;
736 : : }
737 : : else
738 : : {
739 : 209 : HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
740 : :
741 : : /* If this is an incomplete type with size 0, then we can't put it
742 : : in data because it might be too big when completed. Also,
743 : : int_size_in_bytes returns -1 if size can vary or is larger than
744 : : an integer in which case also it is safer to assume that it goes in
745 : : large data. */
746 : 209 : if (size <= 0 || size > ix86_section_threshold)
747 : : return true;
748 : : }
749 : :
750 : : return false;
751 : : }
752 : :
753 : : /* i386-specific section flag to mark large sections. */
754 : : #define SECTION_LARGE SECTION_MACH_DEP
755 : :
756 : : /* Switch to the appropriate section for output of DECL.
757 : : DECL is either a `VAR_DECL' node or a constant of some sort.
758 : : RELOC indicates whether forming the initial value of DECL requires
759 : : link-time relocations. */
760 : :
761 : : ATTRIBUTE_UNUSED static section *
762 : 1640621 : x86_64_elf_select_section (tree decl, int reloc,
763 : : unsigned HOST_WIDE_INT align)
764 : : {
765 : 1640621 : if (ix86_in_large_data_p (decl))
766 : : {
767 : 6 : const char *sname = NULL;
768 : 6 : unsigned int flags = SECTION_WRITE | SECTION_LARGE;
769 : 6 : switch (categorize_decl_for_section (decl, reloc))
770 : : {
771 : 1 : case SECCAT_DATA:
772 : 1 : sname = ".ldata";
773 : 1 : break;
774 : 0 : case SECCAT_DATA_REL:
775 : 0 : sname = ".ldata.rel";
776 : 0 : break;
777 : 0 : case SECCAT_DATA_REL_LOCAL:
778 : 0 : sname = ".ldata.rel.local";
779 : 0 : break;
780 : 0 : case SECCAT_DATA_REL_RO:
781 : 0 : sname = ".ldata.rel.ro";
782 : 0 : break;
783 : 0 : case SECCAT_DATA_REL_RO_LOCAL:
784 : 0 : sname = ".ldata.rel.ro.local";
785 : 0 : break;
786 : 0 : case SECCAT_BSS:
787 : 0 : sname = ".lbss";
788 : 0 : flags |= SECTION_BSS;
789 : 0 : break;
790 : : case SECCAT_RODATA:
791 : : case SECCAT_RODATA_MERGE_STR:
792 : : case SECCAT_RODATA_MERGE_STR_INIT:
793 : : case SECCAT_RODATA_MERGE_CONST:
794 : : sname = ".lrodata";
795 : : flags &= ~SECTION_WRITE;
796 : : break;
797 : 0 : case SECCAT_SRODATA:
798 : 0 : case SECCAT_SDATA:
799 : 0 : case SECCAT_SBSS:
800 : 0 : gcc_unreachable ();
801 : : case SECCAT_TEXT:
802 : : case SECCAT_TDATA:
803 : : case SECCAT_TBSS:
804 : : /* We don't split these for medium model. Place them into
805 : : default sections and hope for best. */
806 : : break;
807 : : }
808 : 1 : if (sname)
809 : : {
810 : : /* We might get called with string constants, but get_named_section
811 : : doesn't like them as they are not DECLs. Also, we need to set
812 : : flags in that case. */
813 : 6 : if (!DECL_P (decl))
814 : 3 : return get_section (sname, flags, NULL);
815 : 3 : return get_named_section (decl, sname, reloc);
816 : : }
817 : : }
818 : 1640615 : return default_elf_select_section (decl, reloc, align);
819 : : }
820 : :
821 : : /* Select a set of attributes for section NAME based on the properties
822 : : of DECL and whether or not RELOC indicates that DECL's initializer
823 : : might contain runtime relocations. */
824 : :
825 : : static unsigned int ATTRIBUTE_UNUSED
826 : 67431893 : x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
827 : : {
828 : 67431893 : unsigned int flags = default_section_type_flags (decl, name, reloc);
829 : :
830 : 67431893 : if (ix86_in_large_data_p (decl))
831 : 7 : flags |= SECTION_LARGE;
832 : :
833 : 67431893 : if (decl == NULL_TREE
834 : 367 : && (strcmp (name, ".ldata.rel.ro") == 0
835 : 367 : || strcmp (name, ".ldata.rel.ro.local") == 0))
836 : 0 : flags |= SECTION_RELRO;
837 : :
838 : 67431893 : if (strcmp (name, ".lbss") == 0
839 : 67431889 : || startswith (name, ".lbss.")
840 : 134863779 : || startswith (name, ".gnu.linkonce.lb."))
841 : 7 : flags |= SECTION_BSS;
842 : :
843 : 67431893 : return flags;
844 : : }
845 : :
846 : : /* Build up a unique section name, expressed as a
847 : : STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
848 : : RELOC indicates whether the initial value of EXP requires
849 : : link-time relocations. */
850 : :
851 : : static void ATTRIBUTE_UNUSED
852 : 1799131 : x86_64_elf_unique_section (tree decl, int reloc)
853 : : {
854 : 1799131 : if (ix86_in_large_data_p (decl))
855 : : {
856 : 3 : const char *prefix = NULL;
857 : : /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */
858 : 3 : bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
859 : :
860 : 3 : switch (categorize_decl_for_section (decl, reloc))
861 : : {
862 : 0 : case SECCAT_DATA:
863 : 0 : case SECCAT_DATA_REL:
864 : 0 : case SECCAT_DATA_REL_LOCAL:
865 : 0 : case SECCAT_DATA_REL_RO:
866 : 0 : case SECCAT_DATA_REL_RO_LOCAL:
867 : 0 : prefix = one_only ? ".ld" : ".ldata";
868 : : break;
869 : 3 : case SECCAT_BSS:
870 : 3 : prefix = one_only ? ".lb" : ".lbss";
871 : : break;
872 : : case SECCAT_RODATA:
873 : : case SECCAT_RODATA_MERGE_STR:
874 : : case SECCAT_RODATA_MERGE_STR_INIT:
875 : : case SECCAT_RODATA_MERGE_CONST:
876 : : prefix = one_only ? ".lr" : ".lrodata";
877 : : break;
878 : 0 : case SECCAT_SRODATA:
879 : 0 : case SECCAT_SDATA:
880 : 0 : case SECCAT_SBSS:
881 : 0 : gcc_unreachable ();
882 : : case SECCAT_TEXT:
883 : : case SECCAT_TDATA:
884 : : case SECCAT_TBSS:
885 : : /* We don't split these for medium model. Place them into
886 : : default sections and hope for best. */
887 : : break;
888 : : }
889 : 3 : if (prefix)
890 : : {
891 : 3 : const char *name, *linkonce;
892 : 3 : char *string;
893 : :
894 : 3 : name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
895 : 3 : name = targetm.strip_name_encoding (name);
896 : :
897 : : /* If we're using one_only, then there needs to be a .gnu.linkonce
898 : : prefix to the section name. */
899 : 3 : linkonce = one_only ? ".gnu.linkonce" : "";
900 : :
901 : 3 : string = ACONCAT ((linkonce, prefix, ".", name, NULL));
902 : :
903 : 3 : set_decl_section_name (decl, string);
904 : 3 : return;
905 : : }
906 : : }
907 : 1799128 : default_unique_section (decl, reloc);
908 : : }
909 : :
910 : : /* Return true if TYPE has no_callee_saved_registers or preserve_none
911 : : attribute. */
912 : :
913 : : bool
914 : 7457722 : ix86_type_no_callee_saved_registers_p (const_tree type)
915 : : {
916 : 14915444 : return (lookup_attribute ("no_callee_saved_registers",
917 : 7457722 : TYPE_ATTRIBUTES (type)) != NULL
918 : 14915315 : || lookup_attribute ("preserve_none",
919 : 7457593 : TYPE_ATTRIBUTES (type)) != NULL);
920 : : }
921 : :
922 : : #ifdef COMMON_ASM_OP
923 : :
924 : : #ifndef LARGECOMM_SECTION_ASM_OP
925 : : #define LARGECOMM_SECTION_ASM_OP "\t.largecomm\t"
926 : : #endif
927 : :
928 : : /* This says how to output assembler code to declare an
929 : : uninitialized external linkage data object.
930 : :
931 : : For medium model x86-64 we need to use LARGECOMM_SECTION_ASM_OP opcode for
932 : : large objects. */
933 : : void
934 : 168198 : x86_elf_aligned_decl_common (FILE *file, tree decl,
935 : : const char *name, unsigned HOST_WIDE_INT size,
936 : : unsigned align)
937 : : {
938 : 168198 : if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
939 : 168192 : || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
940 : 6 : && size > (unsigned int)ix86_section_threshold)
941 : : {
942 : 1 : switch_to_section (get_named_section (decl, ".lbss", 0));
943 : 1 : fputs (LARGECOMM_SECTION_ASM_OP, file);
944 : : }
945 : : else
946 : 168197 : fputs (COMMON_ASM_OP, file);
947 : 168198 : assemble_name (file, name);
948 : 168198 : fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
949 : : size, align / BITS_PER_UNIT);
950 : 168198 : }
951 : : #endif
952 : :
953 : : /* Utility function for targets to use in implementing
954 : : ASM_OUTPUT_ALIGNED_BSS. */
955 : :
956 : : void
957 : 764162 : x86_output_aligned_bss (FILE *file, tree decl, const char *name,
958 : : unsigned HOST_WIDE_INT size, unsigned align)
959 : : {
960 : 764162 : if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
961 : 764152 : || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
962 : 37 : && size > (unsigned int)ix86_section_threshold)
963 : 3 : switch_to_section (get_named_section (decl, ".lbss", 0));
964 : : else
965 : 764159 : switch_to_section (bss_section);
966 : 915013 : ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
967 : : #ifdef ASM_DECLARE_OBJECT_NAME
968 : 764162 : last_assemble_variable_decl = decl;
969 : 764162 : ASM_DECLARE_OBJECT_NAME (file, name, decl);
970 : : #else
971 : : /* Standard thing is just output label for the object. */
972 : : ASM_OUTPUT_LABEL (file, name);
973 : : #endif /* ASM_DECLARE_OBJECT_NAME */
974 : 764162 : ASM_OUTPUT_SKIP (file, size ? size : 1);
975 : 764162 : }
976 : :
977 : : /* Decide whether we must probe the stack before any space allocation
978 : : on this target. It's essentially TARGET_STACK_PROBE except when
979 : : -fstack-check causes the stack to be already probed differently. */
980 : :
981 : : bool
982 : 859134 : ix86_target_stack_probe (void)
983 : : {
984 : : /* Do not probe the stack twice if static stack checking is enabled. */
985 : 859134 : if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
986 : : return false;
987 : :
988 : 859134 : return TARGET_STACK_PROBE;
989 : : }
990 : :
991 : : /* Decide whether we can make a sibling call to a function. DECL is the
992 : : declaration of the function being targeted by the call and EXP is the
993 : : CALL_EXPR representing the call. */
994 : :
995 : : static bool
996 : 134937 : ix86_function_ok_for_sibcall (tree decl, tree exp)
997 : : {
998 : 134937 : tree type, decl_or_type;
999 : 134937 : rtx a, b;
1000 : 134937 : bool bind_global = decl && !targetm.binds_local_p (decl);
1001 : :
1002 : 134937 : if (ix86_function_naked (current_function_decl))
1003 : : return false;
1004 : :
1005 : : /* Sibling call isn't OK if there are no caller-saved registers
1006 : : since all registers must be preserved before return. */
1007 : 134935 : if (cfun->machine->call_saved_registers
1008 : 134935 : == TYPE_NO_CALLER_SAVED_REGISTERS)
1009 : : return false;
1010 : :
1011 : : /* If we are generating position-independent code, we cannot sibcall
1012 : : optimize direct calls to global functions, as the PLT requires
1013 : : %ebx be live. (Darwin does not have a PLT.) */
1014 : 134906 : if (!TARGET_MACHO
1015 : 134906 : && !TARGET_64BIT
1016 : 10990 : && flag_pic
1017 : 8130 : && flag_plt
1018 : 8130 : && bind_global)
1019 : : return false;
1020 : :
1021 : : /* If we need to align the outgoing stack, then sibcalling would
1022 : : unalign the stack, which may break the called function. */
1023 : 130388 : if (ix86_minimum_incoming_stack_boundary (true)
1024 : 130388 : < PREFERRED_STACK_BOUNDARY)
1025 : : return false;
1026 : :
1027 : 129807 : if (decl)
1028 : : {
1029 : 119745 : decl_or_type = decl;
1030 : 119745 : type = TREE_TYPE (decl);
1031 : : }
1032 : : else
1033 : : {
1034 : : /* We're looking at the CALL_EXPR, we need the type of the function. */
1035 : 10062 : type = CALL_EXPR_FN (exp); /* pointer expression */
1036 : 10062 : type = TREE_TYPE (type); /* pointer type */
1037 : 10062 : type = TREE_TYPE (type); /* function type */
1038 : 10062 : decl_or_type = type;
1039 : : }
1040 : :
1041 : : /* Sibling call isn't OK if callee has no callee-saved registers
1042 : : and the calling function has callee-saved registers. */
1043 : 129807 : if ((cfun->machine->call_saved_registers
1044 : 129807 : != TYPE_NO_CALLEE_SAVED_REGISTERS)
1045 : 129786 : && cfun->machine->call_saved_registers != TYPE_PRESERVE_NONE
1046 : 259584 : && ix86_type_no_callee_saved_registers_p (type))
1047 : : return false;
1048 : :
1049 : : /* If outgoing reg parm stack space changes, we cannot do sibcall. */
1050 : 129791 : if ((OUTGOING_REG_PARM_STACK_SPACE (type)
1051 : 129791 : != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
1052 : 258835 : || (REG_PARM_STACK_SPACE (decl_or_type)
1053 : 129044 : != REG_PARM_STACK_SPACE (current_function_decl)))
1054 : : {
1055 : 747 : maybe_complain_about_tail_call (exp,
1056 : : "inconsistent size of stack space"
1057 : : " allocated for arguments which are"
1058 : : " passed in registers");
1059 : 747 : return false;
1060 : : }
1061 : :
1062 : : /* Check that the return value locations are the same. Like
1063 : : if we are returning floats on the 80387 register stack, we cannot
1064 : : make a sibcall from a function that doesn't return a float to a
1065 : : function that does or, conversely, from a function that does return
1066 : : a float to a function that doesn't; the necessary stack adjustment
1067 : : would not be executed. This is also the place we notice
1068 : : differences in the return value ABI. Note that it is ok for one
1069 : : of the functions to have void return type as long as the return
1070 : : value of the other is passed in a register. */
1071 : 129044 : a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
1072 : 129044 : b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
1073 : 129044 : cfun->decl, false);
1074 : 129044 : if (STACK_REG_P (a) || STACK_REG_P (b))
1075 : : {
1076 : 693 : if (!rtx_equal_p (a, b))
1077 : : return false;
1078 : : }
1079 : 128351 : else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
1080 : : ;
1081 : 25592 : else if (!rtx_equal_p (a, b))
1082 : : return false;
1083 : :
1084 : 128653 : if (TARGET_64BIT)
1085 : : {
1086 : : /* The SYSV ABI has more call-clobbered registers;
1087 : : disallow sibcalls from MS to SYSV. */
1088 : 122181 : if (cfun->machine->call_abi == MS_ABI
1089 : 122181 : && ix86_function_type_abi (type) == SYSV_ABI)
1090 : : return false;
1091 : : }
1092 : : else
1093 : : {
1094 : : /* If this call is indirect, we'll need to be able to use a
1095 : : call-clobbered register for the address of the target function.
1096 : : Make sure that all such registers are not used for passing
1097 : : parameters. Note that DLLIMPORT functions and call to global
1098 : : function via GOT slot are indirect. */
1099 : 6472 : if (!decl
1100 : 4678 : || (bind_global && flag_pic && !flag_plt)
1101 : : || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl))
1102 : 4678 : || flag_force_indirect_call)
1103 : : {
1104 : : /* Check if regparm >= 3 since arg_reg_available is set to
1105 : : false if regparm == 0. If regparm is 1 or 2, there is
1106 : : always a call-clobbered register available.
1107 : :
1108 : : ??? The symbol indirect call doesn't need a call-clobbered
1109 : : register. But we don't know if this is a symbol indirect
1110 : : call or not here. */
1111 : 1794 : if (ix86_function_regparm (type, decl) >= 3
1112 : 1794 : && !cfun->machine->arg_reg_available)
1113 : : return false;
1114 : : }
1115 : : }
1116 : :
1117 : 128653 : if (decl && ix86_use_pseudo_pic_reg ())
1118 : : {
1119 : : /* When PIC register is used, it must be restored after ifunc
1120 : : function returns. */
1121 : 2019 : cgraph_node *node = cgraph_node::get (decl);
1122 : 2019 : if (node && node->ifunc_resolver)
1123 : : return false;
1124 : : }
1125 : :
1126 : : /* Disable sibcall if callee has indirect_return attribute and
1127 : : caller doesn't since callee will return to the caller's caller
1128 : : via an indirect jump. */
1129 : 128653 : if (((flag_cf_protection & (CF_RETURN | CF_BRANCH))
1130 : : == (CF_RETURN | CF_BRANCH))
1131 : 53161 : && lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (type))
1132 : 128657 : && !lookup_attribute ("indirect_return",
1133 : 4 : TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
1134 : : return false;
1135 : :
1136 : : /* Otherwise okay. That also includes certain types of indirect calls. */
1137 : : return true;
1138 : : }
1139 : :
1140 : : /* This function determines from TYPE the calling-convention. */
1141 : :
1142 : : unsigned int
1143 : 6117040 : ix86_get_callcvt (const_tree type)
1144 : : {
1145 : 6117040 : unsigned int ret = 0;
1146 : 6117040 : bool is_stdarg;
1147 : 6117040 : tree attrs;
1148 : :
1149 : 6117040 : if (TARGET_64BIT)
1150 : : return IX86_CALLCVT_CDECL;
1151 : :
1152 : 3241982 : attrs = TYPE_ATTRIBUTES (type);
1153 : 3241982 : if (attrs != NULL_TREE)
1154 : : {
1155 : 63464 : if (lookup_attribute ("cdecl", attrs))
1156 : : ret |= IX86_CALLCVT_CDECL;
1157 : 63464 : else if (lookup_attribute ("stdcall", attrs))
1158 : : ret |= IX86_CALLCVT_STDCALL;
1159 : 63464 : else if (lookup_attribute ("fastcall", attrs))
1160 : : ret |= IX86_CALLCVT_FASTCALL;
1161 : 63455 : else if (lookup_attribute ("thiscall", attrs))
1162 : : ret |= IX86_CALLCVT_THISCALL;
1163 : :
1164 : : /* Regparam isn't allowed for thiscall and fastcall. */
1165 : : if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
1166 : : {
1167 : 63455 : if (lookup_attribute ("regparm", attrs))
1168 : 15683 : ret |= IX86_CALLCVT_REGPARM;
1169 : 63455 : if (lookup_attribute ("sseregparm", attrs))
1170 : 0 : ret |= IX86_CALLCVT_SSEREGPARM;
1171 : : }
1172 : :
1173 : 63464 : if (IX86_BASE_CALLCVT(ret) != 0)
1174 : 9 : return ret;
1175 : : }
1176 : :
1177 : 3241973 : is_stdarg = stdarg_p (type);
1178 : 3241973 : if (TARGET_RTD && !is_stdarg)
1179 : 0 : return IX86_CALLCVT_STDCALL | ret;
1180 : :
1181 : 3241973 : if (ret != 0
1182 : 3241973 : || is_stdarg
1183 : 3217466 : || TREE_CODE (type) != METHOD_TYPE
1184 : 3371842 : || ix86_function_type_abi (type) != MS_ABI)
1185 : 3241973 : return IX86_CALLCVT_CDECL | ret;
1186 : :
1187 : : return IX86_CALLCVT_THISCALL;
1188 : : }
1189 : :
1190 : : /* Return 0 if the attributes for two types are incompatible, 1 if they
1191 : : are compatible, and 2 if they are nearly compatible (which causes a
1192 : : warning to be generated). */
1193 : :
1194 : : static int
1195 : 1455179 : ix86_comp_type_attributes (const_tree type1, const_tree type2)
1196 : : {
1197 : 1455179 : unsigned int ccvt1, ccvt2;
1198 : :
1199 : 1455179 : if (TREE_CODE (type1) != FUNCTION_TYPE
1200 : 1455179 : && TREE_CODE (type1) != METHOD_TYPE)
1201 : : return 1;
1202 : :
1203 : 1448517 : ccvt1 = ix86_get_callcvt (type1);
1204 : 1448517 : ccvt2 = ix86_get_callcvt (type2);
1205 : 1448517 : if (ccvt1 != ccvt2)
1206 : : return 0;
1207 : 2875178 : if (ix86_function_regparm (type1, NULL)
1208 : 1437589 : != ix86_function_regparm (type2, NULL))
1209 : : return 0;
1210 : :
1211 : 1399852 : if (ix86_type_no_callee_saved_registers_p (type1)
1212 : 699926 : != ix86_type_no_callee_saved_registers_p (type2))
1213 : : return 0;
1214 : :
1215 : : /* preserve_none attribute uses a different calling convention is
1216 : : only for 64-bit. */
1217 : 699804 : if (TARGET_64BIT
1218 : 1399548 : && (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type1))
1219 : 699744 : != lookup_attribute ("preserve_none",
1220 : 699744 : TYPE_ATTRIBUTES (type2))))
1221 : : return 0;
1222 : :
1223 : : return 1;
1224 : : }
1225 : :
1226 : : /* Return the regparm value for a function with the indicated TYPE and DECL.
1227 : : DECL may be NULL when calling function indirectly
1228 : : or considering a libcall. */
1229 : :
1230 : : static int
1231 : 4136177 : ix86_function_regparm (const_tree type, const_tree decl)
1232 : : {
1233 : 4136177 : tree attr;
1234 : 4136177 : int regparm;
1235 : 4136177 : unsigned int ccvt;
1236 : :
1237 : 4136177 : if (TARGET_64BIT)
1238 : 2875058 : return (ix86_function_type_abi (type) == SYSV_ABI
1239 : 2875058 : ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
1240 : 1261119 : ccvt = ix86_get_callcvt (type);
1241 : 1261119 : regparm = ix86_regparm;
1242 : :
1243 : 1261119 : if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
1244 : : {
1245 : 2017 : attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
1246 : 2017 : if (attr)
1247 : : {
1248 : 2017 : regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
1249 : 2017 : return regparm;
1250 : : }
1251 : : }
1252 : 1259102 : else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
1253 : : return 2;
1254 : 1259102 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
1255 : : return 1;
1256 : :
1257 : : /* Use register calling convention for local functions when possible. */
1258 : 1259102 : if (decl
1259 : 1195836 : && TREE_CODE (decl) == FUNCTION_DECL)
1260 : : {
1261 : 1185741 : cgraph_node *target = cgraph_node::get (decl);
1262 : 1185741 : if (target)
1263 : 1178256 : target = target->function_symbol ();
1264 : :
1265 : : /* Caller and callee must agree on the calling convention, so
1266 : : checking here just optimize means that with
1267 : : __attribute__((optimize (...))) caller could use regparm convention
1268 : : and callee not, or vice versa. Instead look at whether the callee
1269 : : is optimized or not. */
1270 : 1178256 : if (target && opt_for_fn (target->decl, optimize)
1271 : 2355661 : && !(profile_flag && !flag_fentry))
1272 : : {
1273 : 1177405 : if (target->local && target->can_change_signature)
1274 : : {
1275 : 137864 : int local_regparm, globals = 0, regno;
1276 : :
1277 : : /* Make sure no regparm register is taken by a
1278 : : fixed register variable. */
1279 : 137864 : for (local_regparm = 0; local_regparm < REGPARM_MAX;
1280 : : local_regparm++)
1281 : 103398 : if (fixed_regs[local_regparm])
1282 : : break;
1283 : :
1284 : : /* We don't want to use regparm(3) for nested functions as
1285 : : these use a static chain pointer in the third argument. */
1286 : 34466 : if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
1287 : : local_regparm = 2;
1288 : :
1289 : : /* Save a register for the split stack. */
1290 : 34466 : if (flag_split_stack)
1291 : : {
1292 : 20895 : if (local_regparm == 3)
1293 : : local_regparm = 2;
1294 : 707 : else if (local_regparm == 2
1295 : 707 : && DECL_STATIC_CHAIN (target->decl))
1296 : : local_regparm = 1;
1297 : : }
1298 : :
1299 : : /* Each fixed register usage increases register pressure,
1300 : : so less registers should be used for argument passing.
1301 : : This functionality can be overriden by an explicit
1302 : : regparm value. */
1303 : 241262 : for (regno = AX_REG; regno <= DI_REG; regno++)
1304 : 206796 : if (fixed_regs[regno])
1305 : 0 : globals++;
1306 : :
1307 : 34466 : local_regparm
1308 : 34466 : = globals < local_regparm ? local_regparm - globals : 0;
1309 : :
1310 : 34466 : if (local_regparm > regparm)
1311 : 4136177 : regparm = local_regparm;
1312 : : }
1313 : : }
1314 : : }
1315 : :
1316 : : return regparm;
1317 : : }
1318 : :
1319 : : /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
1320 : : DFmode (2) arguments in SSE registers for a function with the
1321 : : indicated TYPE and DECL. DECL may be NULL when calling function
1322 : : indirectly or considering a libcall. Return -1 if any FP parameter
1323 : : should be rejected by error. This is used in siutation we imply SSE
1324 : : calling convetion but the function is called from another function with
1325 : : SSE disabled. Otherwise return 0. */
1326 : :
1327 : : static int
1328 : 1065651 : ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
1329 : : {
1330 : 1065651 : gcc_assert (!TARGET_64BIT);
1331 : :
1332 : : /* Use SSE registers to pass SFmode and DFmode arguments if requested
1333 : : by the sseregparm attribute. */
1334 : 1065651 : if (TARGET_SSEREGPARM
1335 : 1065651 : || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
1336 : : {
1337 : 0 : if (!TARGET_SSE)
1338 : : {
1339 : 0 : if (warn)
1340 : : {
1341 : 0 : if (decl)
1342 : 0 : error ("calling %qD with attribute sseregparm without "
1343 : : "SSE/SSE2 enabled", decl);
1344 : : else
1345 : 0 : error ("calling %qT with attribute sseregparm without "
1346 : : "SSE/SSE2 enabled", type);
1347 : : }
1348 : 0 : return 0;
1349 : : }
1350 : :
1351 : : return 2;
1352 : : }
1353 : :
1354 : 1065651 : if (!decl)
1355 : : return 0;
1356 : :
1357 : 969645 : cgraph_node *target = cgraph_node::get (decl);
1358 : 969645 : if (target)
1359 : 962167 : target = target->function_symbol ();
1360 : :
1361 : : /* For local functions, pass up to SSE_REGPARM_MAX SFmode
1362 : : (and DFmode for SSE2) arguments in SSE registers. */
1363 : 962167 : if (target
1364 : : /* TARGET_SSE_MATH */
1365 : 962167 : && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
1366 : 1296 : && opt_for_fn (target->decl, optimize)
1367 : 963463 : && !(profile_flag && !flag_fentry))
1368 : : {
1369 : 1296 : if (target->local && target->can_change_signature)
1370 : : {
1371 : : /* Refuse to produce wrong code when local function with SSE enabled
1372 : : is called from SSE disabled function.
1373 : : FIXME: We need a way to detect these cases cross-ltrans partition
1374 : : and avoid using SSE calling conventions on local functions called
1375 : : from function with SSE disabled. For now at least delay the
1376 : : warning until we know we are going to produce wrong code.
1377 : : See PR66047 */
1378 : 0 : if (!TARGET_SSE && warn)
1379 : : return -1;
1380 : 0 : return TARGET_SSE2_P (target_opts_for_fn (target->decl)
1381 : 0 : ->x_ix86_isa_flags) ? 2 : 1;
1382 : : }
1383 : : }
1384 : :
1385 : : return 0;
1386 : : }
1387 : :
1388 : : /* Return true if EAX is live at the start of the function. Used by
1389 : : ix86_expand_prologue to determine if we need special help before
1390 : : calling allocate_stack_worker. */
1391 : :
1392 : : static bool
1393 : 7090 : ix86_eax_live_at_start_p (void)
1394 : : {
1395 : : /* Cheat. Don't bother working forward from ix86_function_regparm
1396 : : to the function type to whether an actual argument is located in
1397 : : eax. Instead just look at cfg info, which is still close enough
1398 : : to correct at this point. This gives false positives for broken
1399 : : functions that might use uninitialized data that happens to be
1400 : : allocated in eax, but who cares? */
1401 : 7090 : return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 0);
1402 : : }
1403 : :
1404 : : static bool
1405 : 159260 : ix86_keep_aggregate_return_pointer (tree fntype)
1406 : : {
1407 : 159260 : tree attr;
1408 : :
1409 : 159260 : if (!TARGET_64BIT)
1410 : : {
1411 : 159260 : attr = lookup_attribute ("callee_pop_aggregate_return",
1412 : 159260 : TYPE_ATTRIBUTES (fntype));
1413 : 159260 : if (attr)
1414 : 0 : return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
1415 : :
1416 : : /* For 32-bit MS-ABI the default is to keep aggregate
1417 : : return pointer. */
1418 : 159260 : if (ix86_function_type_abi (fntype) == MS_ABI)
1419 : : return true;
1420 : : }
1421 : : return KEEP_AGGREGATE_RETURN_POINTER != 0;
1422 : : }
1423 : :
1424 : : /* Value is the number of bytes of arguments automatically
1425 : : popped when returning from a subroutine call.
1426 : : FUNDECL is the declaration node of the function (as a tree),
1427 : : FUNTYPE is the data type of the function (as a tree),
1428 : : or for a library call it is an identifier node for the subroutine name.
1429 : : SIZE is the number of bytes of arguments passed on the stack.
1430 : :
1431 : : On the 80386, the RTD insn may be used to pop them if the number
1432 : : of args is fixed, but if the number is variable then the caller
1433 : : must pop them all. RTD can't be used for library calls now
1434 : : because the library is compiled with the Unix compiler.
1435 : : Use of RTD is a selectable option, since it is incompatible with
1436 : : standard Unix calling sequences. If the option is not selected,
1437 : : the caller must always pop the args.
1438 : :
1439 : : The attribute stdcall is equivalent to RTD on a per module basis. */
1440 : :
1441 : : static poly_int64
1442 : 7502741 : ix86_return_pops_args (tree fundecl, tree funtype, poly_int64 size)
1443 : : {
1444 : 7502741 : unsigned int ccvt;
1445 : :
1446 : : /* None of the 64-bit ABIs pop arguments. */
1447 : 7502741 : if (TARGET_64BIT)
1448 : 6636607 : return 0;
1449 : :
1450 : 866134 : ccvt = ix86_get_callcvt (funtype);
1451 : :
1452 : 866134 : if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
1453 : : | IX86_CALLCVT_THISCALL)) != 0
1454 : 866134 : && ! stdarg_p (funtype))
1455 : 3 : return size;
1456 : :
1457 : : /* Lose any fake structure return argument if it is passed on the stack. */
1458 : 866131 : if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
1459 : 866131 : && !ix86_keep_aggregate_return_pointer (funtype))
1460 : : {
1461 : 159260 : int nregs = ix86_function_regparm (funtype, fundecl);
1462 : 159260 : if (nregs == 0)
1463 : 456720 : return GET_MODE_SIZE (Pmode);
1464 : : }
1465 : :
1466 : 713891 : return 0;
1467 : : }
1468 : :
1469 : : /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook. */
1470 : :
1471 : : static bool
1472 : 9785363 : ix86_legitimate_combined_insn (rtx_insn *insn)
1473 : : {
1474 : 9785363 : int i;
1475 : :
1476 : : /* Check operand constraints in case hard registers were propagated
1477 : : into insn pattern. This check prevents combine pass from
1478 : : generating insn patterns with invalid hard register operands.
1479 : : These invalid insns can eventually confuse reload to error out
1480 : : with a spill failure. See also PRs 46829 and 46843. */
1481 : :
1482 : 9785363 : gcc_assert (INSN_CODE (insn) >= 0);
1483 : :
1484 : 9785363 : extract_insn (insn);
1485 : 9785363 : preprocess_constraints (insn);
1486 : :
1487 : 9785363 : int n_operands = recog_data.n_operands;
1488 : 9785363 : int n_alternatives = recog_data.n_alternatives;
1489 : 33523571 : for (i = 0; i < n_operands; i++)
1490 : : {
1491 : 23741699 : rtx op = recog_data.operand[i];
1492 : 23741699 : machine_mode mode = GET_MODE (op);
1493 : 23741699 : const operand_alternative *op_alt;
1494 : 23741699 : int offset = 0;
1495 : 23741699 : bool win;
1496 : 23741699 : int j;
1497 : :
1498 : : /* A unary operator may be accepted by the predicate, but it
1499 : : is irrelevant for matching constraints. */
1500 : 23741699 : if (UNARY_P (op))
1501 : 52899 : op = XEXP (op, 0);
1502 : :
1503 : 23741699 : if (SUBREG_P (op))
1504 : : {
1505 : 818478 : if (REG_P (SUBREG_REG (op))
1506 : 818478 : && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
1507 : 57 : offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
1508 : 57 : GET_MODE (SUBREG_REG (op)),
1509 : 57 : SUBREG_BYTE (op),
1510 : 57 : GET_MODE (op));
1511 : 818478 : op = SUBREG_REG (op);
1512 : : }
1513 : :
1514 : 23741699 : if (!(REG_P (op) && HARD_REGISTER_P (op)))
1515 : 23434418 : continue;
1516 : :
1517 : 307281 : op_alt = recog_op_alt;
1518 : :
1519 : : /* Operand has no constraints, anything is OK. */
1520 : 307281 : win = !n_alternatives;
1521 : :
1522 : 307281 : alternative_mask preferred = get_preferred_alternatives (insn);
1523 : 823784 : for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
1524 : : {
1525 : 512769 : if (!TEST_BIT (preferred, j))
1526 : 133400 : continue;
1527 : 379369 : if (op_alt[i].anything_ok
1528 : 189791 : || (op_alt[i].matches != -1
1529 : 34054 : && operands_match_p
1530 : 34054 : (recog_data.operand[i],
1531 : 34054 : recog_data.operand[op_alt[i].matches]))
1532 : 564924 : || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
1533 : : {
1534 : : win = true;
1535 : : break;
1536 : : }
1537 : : }
1538 : :
1539 : 307281 : if (!win)
1540 : : return false;
1541 : : }
1542 : :
1543 : : return true;
1544 : : }
1545 : :
1546 : : /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
1547 : :
1548 : : static unsigned HOST_WIDE_INT
1549 : 4578 : ix86_asan_shadow_offset (void)
1550 : : {
1551 : 4578 : return SUBTARGET_SHADOW_OFFSET;
1552 : : }
1553 : :
1554 : : /* Argument support functions. */
1555 : :
1556 : : /* Return true when register may be used to pass function parameters. */
1557 : : bool
1558 : 1451287484 : ix86_function_arg_regno_p (int regno)
1559 : : {
1560 : 1451287484 : int i;
1561 : 1451287484 : enum calling_abi call_abi;
1562 : 1451287484 : const int *parm_regs;
1563 : :
1564 : 1447859285 : if (TARGET_SSE && SSE_REGNO_P (regno)
1565 : 2399205930 : && regno < FIRST_SSE_REG + SSE_REGPARM_MAX)
1566 : : return true;
1567 : :
1568 : 1334239862 : if (!TARGET_64BIT)
1569 : 128383377 : return (regno < REGPARM_MAX
1570 : 128383377 : || (TARGET_MMX && MMX_REGNO_P (regno)
1571 : 11538720 : && regno < FIRST_MMX_REG + MMX_REGPARM_MAX));
1572 : :
1573 : : /* TODO: The function should depend on current function ABI but
1574 : : builtins.cc would need updating then. Therefore we use the
1575 : : default ABI. */
1576 : 1205856485 : call_abi = ix86_cfun_abi ();
1577 : :
1578 : : /* RAX is used as hidden argument to va_arg functions. */
1579 : 1205856485 : if (call_abi == SYSV_ABI && regno == AX_REG)
1580 : : return true;
1581 : :
1582 : 1191931803 : if (cfun
1583 : 1191931471 : && cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE)
1584 : : parm_regs = x86_64_preserve_none_int_parameter_registers;
1585 : 1191914373 : else if (call_abi == MS_ABI)
1586 : : parm_regs = x86_64_ms_abi_int_parameter_registers;
1587 : : else
1588 : 1155928765 : parm_regs = x86_64_int_parameter_registers;
1589 : :
1590 : 15949524912 : for (i = 0; i < (call_abi == MS_ABI
1591 : 7974762456 : ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
1592 : 6868070276 : if (regno == parm_regs[i])
1593 : : return true;
1594 : : return false;
1595 : : }
1596 : :
1597 : : /* Return if we do not know how to pass ARG solely in registers. */
1598 : :
1599 : : static bool
1600 : 373930830 : ix86_must_pass_in_stack (const function_arg_info &arg)
1601 : : {
1602 : 373930830 : if (must_pass_in_stack_var_size_or_pad (arg))
1603 : : return true;
1604 : :
1605 : : /* For 32-bit, we want TImode aggregates to go on the stack. But watch out!
1606 : : The layout_type routine is crafty and tries to trick us into passing
1607 : : currently unsupported vector types on the stack by using TImode. */
1608 : 1754979 : return (!TARGET_64BIT && arg.mode == TImode
1609 : 373930793 : && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
1610 : : }
1611 : :
1612 : : /* It returns the size, in bytes, of the area reserved for arguments passed
1613 : : in registers for the function represented by fndecl dependent to the used
1614 : : abi format. */
1615 : : int
1616 : 10610247 : ix86_reg_parm_stack_space (const_tree fndecl)
1617 : : {
1618 : 10610247 : enum calling_abi call_abi = SYSV_ABI;
1619 : 10610247 : if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
1620 : 10291822 : call_abi = ix86_function_abi (fndecl);
1621 : : else
1622 : 318425 : call_abi = ix86_function_type_abi (fndecl);
1623 : 10610247 : if (TARGET_64BIT && call_abi == MS_ABI)
1624 : 119228 : return 32;
1625 : : return 0;
1626 : : }
1627 : :
1628 : : /* We add this as a workaround in order to use libc_has_function
1629 : : hook in i386.md. */
1630 : : bool
1631 : 0 : ix86_libc_has_function (enum function_class fn_class)
1632 : : {
1633 : 0 : return targetm.libc_has_function (fn_class, NULL_TREE);
1634 : : }
1635 : :
1636 : : /* Returns value SYSV_ABI, MS_ABI dependent on fntype,
1637 : : specifying the call abi used. */
1638 : : enum calling_abi
1639 : 406445054 : ix86_function_type_abi (const_tree fntype)
1640 : : {
1641 : 406445054 : enum calling_abi abi = ix86_abi;
1642 : :
1643 : 406445054 : if (fntype == NULL_TREE || TYPE_ATTRIBUTES (fntype) == NULL_TREE)
1644 : : return abi;
1645 : :
1646 : 17232422 : if (abi == SYSV_ABI
1647 : 17232422 : && lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
1648 : : {
1649 : 2584363 : static int warned;
1650 : 2584363 : if (TARGET_X32 && !warned)
1651 : : {
1652 : 1 : error ("X32 does not support %<ms_abi%> attribute");
1653 : 1 : warned = 1;
1654 : : }
1655 : :
1656 : : abi = MS_ABI;
1657 : : }
1658 : 14648059 : else if (abi == MS_ABI
1659 : 14648059 : && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
1660 : : abi = SYSV_ABI;
1661 : :
1662 : : return abi;
1663 : : }
1664 : :
1665 : : enum calling_abi
1666 : 198502035 : ix86_function_abi (const_tree fndecl)
1667 : : {
1668 : 198502035 : return fndecl ? ix86_function_type_abi (TREE_TYPE (fndecl)) : ix86_abi;
1669 : : }
1670 : :
1671 : : /* Returns value SYSV_ABI, MS_ABI dependent on cfun,
1672 : : specifying the call abi used. */
1673 : : enum calling_abi
1674 : 2041516753 : ix86_cfun_abi (void)
1675 : : {
1676 : 2041516753 : return cfun ? cfun->machine->call_abi : ix86_abi;
1677 : : }
1678 : :
1679 : : bool
1680 : 4991453 : ix86_function_ms_hook_prologue (const_tree fn)
1681 : : {
1682 : 4991453 : if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
1683 : : {
1684 : 15 : if (decl_function_context (fn) != NULL_TREE)
1685 : 0 : error_at (DECL_SOURCE_LOCATION (fn),
1686 : : "%<ms_hook_prologue%> attribute is not compatible "
1687 : : "with nested function");
1688 : : else
1689 : : return true;
1690 : : }
1691 : : return false;
1692 : : }
1693 : :
1694 : : bool
1695 : 109475813 : ix86_function_naked (const_tree fn)
1696 : : {
1697 : 109475813 : if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
1698 : : return true;
1699 : :
1700 : : return false;
1701 : : }
1702 : :
1703 : : /* Write the extra assembler code needed to declare a function properly. */
1704 : :
1705 : : void
1706 : 1516672 : ix86_asm_output_function_label (FILE *out_file, const char *fname,
1707 : : tree decl)
1708 : : {
1709 : 1516672 : bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
1710 : :
1711 : 1516672 : if (cfun)
1712 : 1513089 : cfun->machine->function_label_emitted = true;
1713 : :
1714 : 1516672 : if (is_ms_hook)
1715 : : {
1716 : 2 : int i, filler_count = (TARGET_64BIT ? 32 : 16);
1717 : 2 : unsigned int filler_cc = 0xcccccccc;
1718 : :
1719 : 18 : for (i = 0; i < filler_count; i += 4)
1720 : 16 : fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
1721 : : }
1722 : :
1723 : : #ifdef SUBTARGET_ASM_UNWIND_INIT
1724 : : SUBTARGET_ASM_UNWIND_INIT (out_file);
1725 : : #endif
1726 : :
1727 : 1516672 : assemble_function_label_raw (out_file, fname);
1728 : :
1729 : : /* Output magic byte marker, if hot-patch attribute is set. */
1730 : 1516672 : if (is_ms_hook)
1731 : : {
1732 : 2 : if (TARGET_64BIT)
1733 : : {
1734 : : /* leaq [%rsp + 0], %rsp */
1735 : 2 : fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
1736 : : out_file);
1737 : : }
1738 : : else
1739 : : {
1740 : : /* movl.s %edi, %edi
1741 : : push %ebp
1742 : : movl.s %esp, %ebp */
1743 : 0 : fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
1744 : : }
1745 : : }
1746 : 1516672 : }
1747 : :
1748 : : /* Output a user-defined label. In AT&T syntax, registers are prefixed
1749 : : with %, so labels require no punctuation. In Intel syntax, registers
1750 : : are unprefixed, so labels may clash with registers or other operators,
1751 : : and require quoting. */
1752 : : void
1753 : 34611254 : ix86_asm_output_labelref (FILE *file, const char *prefix, const char *label)
1754 : : {
1755 : 34611254 : if (ASSEMBLER_DIALECT == ASM_ATT)
1756 : 34610364 : fprintf (file, "%s%s", prefix, label);
1757 : : else
1758 : 890 : fprintf (file, "\"%s%s\"", prefix, label);
1759 : 34611254 : }
1760 : :
1761 : : /* Implementation of call abi switching target hook. Specific to FNDECL
1762 : : the specific call register sets are set. See also
1763 : : ix86_conditional_register_usage for more details. */
1764 : : void
1765 : 178165654 : ix86_call_abi_override (const_tree fndecl)
1766 : : {
1767 : 178165654 : cfun->machine->call_abi = ix86_function_abi (fndecl);
1768 : 178165654 : }
1769 : :
1770 : : /* Return 1 if pseudo register should be created and used to hold
1771 : : GOT address for PIC code. */
1772 : : bool
1773 : 166691574 : ix86_use_pseudo_pic_reg (void)
1774 : : {
1775 : 166691574 : if ((TARGET_64BIT
1776 : 155743988 : && (ix86_cmodel == CM_SMALL_PIC
1777 : : || TARGET_PECOFF))
1778 : 161160658 : || !flag_pic)
1779 : 161992180 : return false;
1780 : : return true;
1781 : : }
1782 : :
1783 : : /* Initialize large model PIC register. */
1784 : :
1785 : : static void
1786 : 51 : ix86_init_large_pic_reg (unsigned int tmp_regno)
1787 : : {
1788 : 51 : rtx_code_label *label;
1789 : 51 : rtx tmp_reg;
1790 : :
1791 : 51 : gcc_assert (Pmode == DImode);
1792 : 51 : label = gen_label_rtx ();
1793 : 51 : emit_label (label);
1794 : 51 : LABEL_PRESERVE_P (label) = 1;
1795 : 51 : tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
1796 : 51 : gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
1797 : 51 : emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
1798 : : label));
1799 : 51 : emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
1800 : 51 : emit_insn (gen_add2_insn (pic_offset_table_rtx, tmp_reg));
1801 : 51 : const char *name = LABEL_NAME (label);
1802 : 51 : PUT_CODE (label, NOTE);
1803 : 51 : NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
1804 : 51 : NOTE_DELETED_LABEL_NAME (label) = name;
1805 : 51 : }
1806 : :
1807 : : /* Create and initialize PIC register if required. */
1808 : : static void
1809 : 1449060 : ix86_init_pic_reg (void)
1810 : : {
1811 : 1449060 : edge entry_edge;
1812 : 1449060 : rtx_insn *seq;
1813 : :
1814 : 1449060 : if (!ix86_use_pseudo_pic_reg ())
1815 : : return;
1816 : :
1817 : 39807 : start_sequence ();
1818 : :
1819 : 39807 : if (TARGET_64BIT)
1820 : : {
1821 : 64 : if (ix86_cmodel == CM_LARGE_PIC)
1822 : 48 : ix86_init_large_pic_reg (R11_REG);
1823 : : else
1824 : 16 : emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
1825 : : }
1826 : : else
1827 : : {
1828 : : /* If there is future mcount call in the function it is more profitable
1829 : : to emit SET_GOT into ABI defined REAL_PIC_OFFSET_TABLE_REGNUM. */
1830 : 39743 : rtx reg = crtl->profile
1831 : 39743 : ? gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM)
1832 : 39743 : : pic_offset_table_rtx;
1833 : 39743 : rtx_insn *insn = emit_insn (gen_set_got (reg));
1834 : 39743 : RTX_FRAME_RELATED_P (insn) = 1;
1835 : 39743 : if (crtl->profile)
1836 : 0 : emit_move_insn (pic_offset_table_rtx, reg);
1837 : 39743 : add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
1838 : : }
1839 : :
1840 : 39807 : seq = end_sequence ();
1841 : :
1842 : 39807 : entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1843 : 39807 : insert_insn_on_edge (seq, entry_edge);
1844 : 39807 : commit_one_edge_insertion (entry_edge);
1845 : : }
1846 : :
1847 : : /* Initialize a variable CUM of type CUMULATIVE_ARGS
1848 : : for a call to a function whose data type is FNTYPE.
1849 : : For a library call, FNTYPE is 0. */
1850 : :
1851 : : void
1852 : 10346114 : init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
1853 : : tree fntype, /* tree ptr for function decl */
1854 : : rtx libname, /* SYMBOL_REF of library name or 0 */
1855 : : tree fndecl,
1856 : : int caller)
1857 : : {
1858 : 10346114 : struct cgraph_node *local_info_node = NULL;
1859 : 10346114 : struct cgraph_node *target = NULL;
1860 : :
1861 : : /* Set silent_p to false to raise an error for invalid calls when
1862 : : expanding function body. */
1863 : 10346114 : cfun->machine->silent_p = false;
1864 : :
1865 : 10346114 : memset (cum, 0, sizeof (*cum));
1866 : :
1867 : 10346114 : tree preserve_none_type;
1868 : 10346114 : if (fndecl)
1869 : : {
1870 : 9997947 : target = cgraph_node::get (fndecl);
1871 : 9997947 : if (target)
1872 : : {
1873 : 9858734 : target = target->function_symbol ();
1874 : 9858734 : local_info_node = cgraph_node::local_info_node (target->decl);
1875 : 9858734 : cum->call_abi = ix86_function_abi (target->decl);
1876 : 9858734 : preserve_none_type = TREE_TYPE (target->decl);
1877 : : }
1878 : : else
1879 : : {
1880 : 139213 : cum->call_abi = ix86_function_abi (fndecl);
1881 : 139213 : preserve_none_type = TREE_TYPE (fndecl);
1882 : : }
1883 : : }
1884 : : else
1885 : : {
1886 : 348167 : cum->call_abi = ix86_function_type_abi (fntype);
1887 : 348167 : preserve_none_type = fntype;
1888 : : }
1889 : 10346114 : cum->preserve_none_abi
1890 : 10346114 : = (preserve_none_type
1891 : 20572555 : && (lookup_attribute ("preserve_none",
1892 : 10226441 : TYPE_ATTRIBUTES (preserve_none_type))
1893 : : != nullptr));
1894 : :
1895 : 10346114 : cum->caller = caller;
1896 : :
1897 : : /* Set up the number of registers to use for passing arguments. */
1898 : 10346114 : cum->nregs = ix86_regparm;
1899 : 10346114 : if (TARGET_64BIT)
1900 : : {
1901 : 9319989 : cum->nregs = (cum->call_abi == SYSV_ABI
1902 : 9319989 : ? X86_64_REGPARM_MAX
1903 : : : X86_64_MS_REGPARM_MAX);
1904 : : }
1905 : 10346114 : if (TARGET_SSE)
1906 : : {
1907 : 10337057 : cum->sse_nregs = SSE_REGPARM_MAX;
1908 : 10337057 : if (TARGET_64BIT)
1909 : : {
1910 : 9311052 : cum->sse_nregs = (cum->call_abi == SYSV_ABI
1911 : 9311052 : ? X86_64_SSE_REGPARM_MAX
1912 : : : X86_64_MS_SSE_REGPARM_MAX);
1913 : : }
1914 : : }
1915 : 10346114 : if (TARGET_MMX)
1916 : 11159559 : cum->mmx_nregs = MMX_REGPARM_MAX;
1917 : 10346114 : cum->warn_avx512f = true;
1918 : 10346114 : cum->warn_avx = true;
1919 : 10346114 : cum->warn_sse = true;
1920 : 10346114 : cum->warn_mmx = true;
1921 : :
1922 : : /* Because type might mismatch in between caller and callee, we need to
1923 : : use actual type of function for local calls.
1924 : : FIXME: cgraph_analyze can be told to actually record if function uses
1925 : : va_start so for local functions maybe_vaarg can be made aggressive
1926 : : helping K&R code.
1927 : : FIXME: once typesytem is fixed, we won't need this code anymore. */
1928 : 10346114 : if (local_info_node && local_info_node->local
1929 : 403598 : && local_info_node->can_change_signature)
1930 : 380769 : fntype = TREE_TYPE (target->decl);
1931 : 10346114 : cum->stdarg = stdarg_p (fntype);
1932 : 20692228 : cum->maybe_vaarg = (fntype
1933 : 10811744 : ? (!prototype_p (fntype) || stdarg_p (fntype))
1934 : 119673 : : !libname);
1935 : :
1936 : 10346114 : cum->decl = fndecl;
1937 : :
1938 : 10346114 : cum->warn_empty = !warn_abi || cum->stdarg;
1939 : 10346114 : if (!cum->warn_empty && fntype)
1940 : : {
1941 : 2779817 : function_args_iterator iter;
1942 : 2779817 : tree argtype;
1943 : 2779817 : bool seen_empty_type = false;
1944 : 7786762 : FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
1945 : : {
1946 : 7786699 : if (argtype == error_mark_node || VOID_TYPE_P (argtype))
1947 : : break;
1948 : 5024971 : if (TYPE_EMPTY_P (argtype))
1949 : : seen_empty_type = true;
1950 : 4950596 : else if (seen_empty_type)
1951 : : {
1952 : 18026 : cum->warn_empty = true;
1953 : 18026 : break;
1954 : : }
1955 : : }
1956 : : }
1957 : :
1958 : 10346114 : if (!TARGET_64BIT)
1959 : : {
1960 : : /* If there are variable arguments, then we won't pass anything
1961 : : in registers in 32-bit mode. */
1962 : 1026125 : if (stdarg_p (fntype))
1963 : : {
1964 : 8873 : cum->nregs = 0;
1965 : : /* Since in 32-bit, variable arguments are always passed on
1966 : : stack, there is scratch register available for indirect
1967 : : sibcall. */
1968 : 8873 : cfun->machine->arg_reg_available = true;
1969 : 8873 : cum->sse_nregs = 0;
1970 : 8873 : cum->mmx_nregs = 0;
1971 : 8873 : cum->warn_avx512f = false;
1972 : 8873 : cum->warn_avx = false;
1973 : 8873 : cum->warn_sse = false;
1974 : 8873 : cum->warn_mmx = false;
1975 : 8873 : return;
1976 : : }
1977 : :
1978 : : /* Use ecx and edx registers if function has fastcall attribute,
1979 : : else look for regparm information. */
1980 : 1017252 : if (fntype)
1981 : : {
1982 : 1004008 : unsigned int ccvt = ix86_get_callcvt (fntype);
1983 : 1004008 : if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
1984 : : {
1985 : 0 : cum->nregs = 1;
1986 : 0 : cum->fastcall = 1; /* Same first register as in fastcall. */
1987 : : }
1988 : 1004008 : else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
1989 : : {
1990 : 4 : cum->nregs = 2;
1991 : 4 : cum->fastcall = 1;
1992 : : }
1993 : : else
1994 : 1004004 : cum->nregs = ix86_function_regparm (fntype, fndecl);
1995 : : }
1996 : :
1997 : : /* Set up the number of SSE registers used for passing SFmode
1998 : : and DFmode arguments. Warn for mismatching ABI. */
1999 : 1017252 : cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
2000 : : }
2001 : :
2002 : 10337241 : cfun->machine->arg_reg_available = (cum->nregs > 0);
2003 : : }
2004 : :
2005 : : /* Return the "natural" mode for TYPE. In most cases, this is just TYPE_MODE.
2006 : : But in the case of vector types, it is some vector mode.
2007 : :
2008 : : When we have only some of our vector isa extensions enabled, then there
2009 : : are some modes for which vector_mode_supported_p is false. For these
2010 : : modes, the generic vector support in gcc will choose some non-vector mode
2011 : : in order to implement the type. By computing the natural mode, we'll
2012 : : select the proper ABI location for the operand and not depend on whatever
2013 : : the middle-end decides to do with these vector types.
2014 : :
2015 : : The midde-end can't deal with the vector types > 16 bytes. In this
2016 : : case, we return the original mode and warn ABI change if CUM isn't
2017 : : NULL.
2018 : :
2019 : : If INT_RETURN is true, warn ABI change if the vector mode isn't
2020 : : available for function return value. */
2021 : :
2022 : : static machine_mode
2023 : 214776792 : type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
2024 : : bool in_return)
2025 : : {
2026 : 214776792 : machine_mode mode = TYPE_MODE (type);
2027 : :
2028 : 214776792 : if (VECTOR_TYPE_P (type) && !VECTOR_MODE_P (mode))
2029 : : {
2030 : 438609 : HOST_WIDE_INT size = int_size_in_bytes (type);
2031 : 438609 : if ((size == 8 || size == 16 || size == 32 || size == 64)
2032 : : /* ??? Generic code allows us to create width 1 vectors. Ignore. */
2033 : 438609 : && TYPE_VECTOR_SUBPARTS (type) > 1)
2034 : : {
2035 : 403853 : machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
2036 : :
2037 : : /* There are no XFmode vector modes ... */
2038 : 403853 : if (innermode == XFmode)
2039 : : return mode;
2040 : :
2041 : : /* ... and no decimal float vector modes. */
2042 : 403308 : if (DECIMAL_FLOAT_MODE_P (innermode))
2043 : : return mode;
2044 : :
2045 : 403019 : if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (type)))
2046 : : mode = MIN_MODE_VECTOR_FLOAT;
2047 : : else
2048 : 338920 : mode = MIN_MODE_VECTOR_INT;
2049 : :
2050 : : /* Get the mode which has this inner mode and number of units. */
2051 : 8536214 : FOR_EACH_MODE_FROM (mode, mode)
2052 : 17743410 : if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
2053 : 9610215 : && GET_MODE_INNER (mode) == innermode)
2054 : : {
2055 : 403019 : if (size == 64 && !TARGET_AVX512F && !TARGET_IAMCU)
2056 : : {
2057 : 280547 : static bool warnedavx512f;
2058 : 280547 : static bool warnedavx512f_ret;
2059 : :
2060 : 280547 : if (cum && cum->warn_avx512f && !warnedavx512f)
2061 : : {
2062 : 1194 : if (warning (OPT_Wpsabi, "AVX512F vector argument "
2063 : : "without AVX512F enabled changes the ABI"))
2064 : 2 : warnedavx512f = true;
2065 : : }
2066 : 279353 : else if (in_return && !warnedavx512f_ret)
2067 : : {
2068 : 276647 : if (warning (OPT_Wpsabi, "AVX512F vector return "
2069 : : "without AVX512F enabled changes the ABI"))
2070 : 2 : warnedavx512f_ret = true;
2071 : : }
2072 : :
2073 : 280547 : return TYPE_MODE (type);
2074 : : }
2075 : 122472 : else if (size == 32 && !TARGET_AVX && !TARGET_IAMCU)
2076 : : {
2077 : 121923 : static bool warnedavx;
2078 : 121923 : static bool warnedavx_ret;
2079 : :
2080 : 121923 : if (cum && cum->warn_avx && !warnedavx)
2081 : : {
2082 : 601 : if (warning (OPT_Wpsabi, "AVX vector argument "
2083 : : "without AVX enabled changes the ABI"))
2084 : 5 : warnedavx = true;
2085 : : }
2086 : 121322 : else if (in_return && !warnedavx_ret)
2087 : : {
2088 : 119351 : if (warning (OPT_Wpsabi, "AVX vector return "
2089 : : "without AVX enabled changes the ABI"))
2090 : 7 : warnedavx_ret = true;
2091 : : }
2092 : :
2093 : 121923 : return TYPE_MODE (type);
2094 : : }
2095 : 549 : else if (((size == 8 && TARGET_64BIT) || size == 16)
2096 : 546 : && !TARGET_SSE
2097 : 140 : && !TARGET_IAMCU)
2098 : : {
2099 : 140 : static bool warnedsse;
2100 : 140 : static bool warnedsse_ret;
2101 : :
2102 : 140 : if (cum && cum->warn_sse && !warnedsse)
2103 : : {
2104 : 19 : if (warning (OPT_Wpsabi, "SSE vector argument "
2105 : : "without SSE enabled changes the ABI"))
2106 : 6 : warnedsse = true;
2107 : : }
2108 : 121 : else if (!TARGET_64BIT && in_return && !warnedsse_ret)
2109 : : {
2110 : 0 : if (warning (OPT_Wpsabi, "SSE vector return "
2111 : : "without SSE enabled changes the ABI"))
2112 : 0 : warnedsse_ret = true;
2113 : : }
2114 : : }
2115 : 409 : else if ((size == 8 && !TARGET_64BIT)
2116 : 0 : && (!cfun
2117 : 0 : || cfun->machine->func_type == TYPE_NORMAL)
2118 : 0 : && !TARGET_MMX
2119 : 0 : && !TARGET_IAMCU)
2120 : : {
2121 : 0 : static bool warnedmmx;
2122 : 0 : static bool warnedmmx_ret;
2123 : :
2124 : 0 : if (cum && cum->warn_mmx && !warnedmmx)
2125 : : {
2126 : 0 : if (warning (OPT_Wpsabi, "MMX vector argument "
2127 : : "without MMX enabled changes the ABI"))
2128 : 0 : warnedmmx = true;
2129 : : }
2130 : 0 : else if (in_return && !warnedmmx_ret)
2131 : : {
2132 : 0 : if (warning (OPT_Wpsabi, "MMX vector return "
2133 : : "without MMX enabled changes the ABI"))
2134 : 0 : warnedmmx_ret = true;
2135 : : }
2136 : : }
2137 : 549 : return mode;
2138 : : }
2139 : :
2140 : 0 : gcc_unreachable ();
2141 : : }
2142 : : }
2143 : :
2144 : : return mode;
2145 : : }
2146 : :
2147 : : /* We want to pass a value in REGNO whose "natural" mode is MODE. However,
2148 : : this may not agree with the mode that the type system has chosen for the
2149 : : register, which is ORIG_MODE. If ORIG_MODE is not BLKmode, then we can
2150 : : go ahead and use it. Otherwise we have to build a PARALLEL instead. */
2151 : :
2152 : : static rtx
2153 : 35679438 : gen_reg_or_parallel (machine_mode mode, machine_mode orig_mode,
2154 : : unsigned int regno)
2155 : : {
2156 : 35679438 : rtx tmp;
2157 : :
2158 : 35679438 : if (orig_mode != BLKmode)
2159 : 35679410 : tmp = gen_rtx_REG (orig_mode, regno);
2160 : : else
2161 : : {
2162 : 28 : tmp = gen_rtx_REG (mode, regno);
2163 : 28 : tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
2164 : 28 : tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
2165 : : }
2166 : :
2167 : 35679438 : return tmp;
2168 : : }
2169 : :
2170 : : /* x86-64 register passing implementation. See x86-64 ABI for details. Goal
2171 : : of this code is to classify each 8bytes of incoming argument by the register
2172 : : class and assign registers accordingly. */
2173 : :
2174 : : /* Return the union class of CLASS1 and CLASS2.
2175 : : See the x86-64 PS ABI for details. */
2176 : :
2177 : : static enum x86_64_reg_class
2178 : 42989760 : merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
2179 : : {
2180 : : /* Rule #1: If both classes are equal, this is the resulting class. */
2181 : 42399981 : if (class1 == class2)
2182 : : return class1;
2183 : :
2184 : : /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
2185 : : the other class. */
2186 : 37571817 : if (class1 == X86_64_NO_CLASS)
2187 : : return class2;
2188 : 37847062 : if (class2 == X86_64_NO_CLASS)
2189 : : return class1;
2190 : :
2191 : : /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
2192 : 1710803 : if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
2193 : : return X86_64_MEMORY_CLASS;
2194 : :
2195 : : /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
2196 : 1454013 : if ((class1 == X86_64_INTEGERSI_CLASS
2197 : 193525 : && (class2 == X86_64_SSESF_CLASS || class2 == X86_64_SSEHF_CLASS))
2198 : 1452807 : || (class2 == X86_64_INTEGERSI_CLASS
2199 : 668969 : && (class1 == X86_64_SSESF_CLASS || class1 == X86_64_SSEHF_CLASS)))
2200 : : return X86_64_INTEGERSI_CLASS;
2201 : 1448991 : if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
2202 : 573555 : || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
2203 : : return X86_64_INTEGER_CLASS;
2204 : :
2205 : : /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
2206 : : MEMORY is used. */
2207 : 111687 : if (class1 == X86_64_X87_CLASS
2208 : : || class1 == X86_64_X87UP_CLASS
2209 : 111687 : || class1 == X86_64_COMPLEX_X87_CLASS
2210 : : || class2 == X86_64_X87_CLASS
2211 : 110782 : || class2 == X86_64_X87UP_CLASS
2212 : 59030 : || class2 == X86_64_COMPLEX_X87_CLASS)
2213 : 52657 : return X86_64_MEMORY_CLASS;
2214 : :
2215 : : /* Rule #6: Otherwise class SSE is used. */
2216 : : return X86_64_SSE_CLASS;
2217 : : }
2218 : :
2219 : : /* Classify the argument of type TYPE and mode MODE.
2220 : : CLASSES will be filled by the register class used to pass each word
2221 : : of the operand. The number of words is returned. In case the parameter
2222 : : should be passed in memory, 0 is returned. As a special case for zero
2223 : : sized containers, classes[0] will be NO_CLASS and 1 is returned.
2224 : :
2225 : : BIT_OFFSET is used internally for handling records and specifies offset
2226 : : of the offset in bits modulo 512 to avoid overflow cases.
2227 : :
2228 : : See the x86-64 PS ABI for details.
2229 : : */
2230 : :
2231 : : static int
2232 : 359685734 : classify_argument (machine_mode mode, const_tree type,
2233 : : enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset,
2234 : : int &zero_width_bitfields)
2235 : : {
2236 : 359685734 : HOST_WIDE_INT bytes
2237 : 714258135 : = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
2238 : 359685734 : int words = CEIL (bytes + (bit_offset % 64) / 8, UNITS_PER_WORD);
2239 : :
2240 : : /* Variable sized entities are always passed/returned in memory. */
2241 : 359685734 : if (bytes < 0)
2242 : : return 0;
2243 : :
2244 : 359684577 : if (mode != VOIDmode)
2245 : : {
2246 : : /* The value of "named" doesn't matter. */
2247 : 358709313 : function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
2248 : 358709313 : if (targetm.calls.must_pass_in_stack (arg))
2249 : 37 : return 0;
2250 : : }
2251 : :
2252 : 359684540 : if (type && (AGGREGATE_TYPE_P (type)
2253 : 333513134 : || (TREE_CODE (type) == BITINT_TYPE && words > 1)))
2254 : : {
2255 : 27224724 : int i;
2256 : 27224724 : tree field;
2257 : 27224724 : enum x86_64_reg_class subclasses[MAX_CLASSES];
2258 : :
2259 : : /* On x86-64 we pass structures larger than 64 bytes on the stack. */
2260 : 27224724 : if (bytes > 64)
2261 : : return 0;
2262 : :
2263 : 70798625 : for (i = 0; i < words; i++)
2264 : 44370326 : classes[i] = X86_64_NO_CLASS;
2265 : :
2266 : : /* Zero sized arrays or structures are NO_CLASS. We return 0 to
2267 : : signalize memory class, so handle it as special case. */
2268 : 26428299 : if (!words)
2269 : : {
2270 : 74348 : classes[0] = X86_64_NO_CLASS;
2271 : 74348 : return 1;
2272 : : }
2273 : :
2274 : : /* Classify each field of record and merge classes. */
2275 : 26353951 : switch (TREE_CODE (type))
2276 : : {
2277 : 24351445 : case RECORD_TYPE:
2278 : : /* And now merge the fields of structure. */
2279 : 633190803 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2280 : : {
2281 : 609144405 : if (TREE_CODE (field) == FIELD_DECL)
2282 : : {
2283 : 37497758 : int num;
2284 : :
2285 : 37497758 : if (TREE_TYPE (field) == error_mark_node)
2286 : 4 : continue;
2287 : :
2288 : : /* Bitfields are always classified as integer. Handle them
2289 : : early, since later code would consider them to be
2290 : : misaligned integers. */
2291 : 37497754 : if (DECL_BIT_FIELD (field))
2292 : : {
2293 : 599040 : if (integer_zerop (DECL_SIZE (field)))
2294 : : {
2295 : 12902 : if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
2296 : 8048 : continue;
2297 : 4854 : if (zero_width_bitfields != 2)
2298 : : {
2299 : 4320 : zero_width_bitfields = 1;
2300 : 4320 : continue;
2301 : : }
2302 : : }
2303 : 586672 : for (i = (int_bit_position (field)
2304 : 586672 : + (bit_offset % 64)) / 8 / 8;
2305 : 1176451 : i < ((int_bit_position (field) + (bit_offset % 64))
2306 : 1176451 : + tree_to_shwi (DECL_SIZE (field))
2307 : 1176451 : + 63) / 8 / 8; i++)
2308 : 589779 : classes[i]
2309 : 1179558 : = merge_classes (X86_64_INTEGER_CLASS, classes[i]);
2310 : : }
2311 : : else
2312 : : {
2313 : 36898714 : int pos;
2314 : :
2315 : 36898714 : type = TREE_TYPE (field);
2316 : :
2317 : : /* Flexible array member is ignored. */
2318 : 36898714 : if (TYPE_MODE (type) == BLKmode
2319 : 433968 : && TREE_CODE (type) == ARRAY_TYPE
2320 : 166978 : && TYPE_SIZE (type) == NULL_TREE
2321 : 2004 : && TYPE_DOMAIN (type) != NULL_TREE
2322 : 36899959 : && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
2323 : : == NULL_TREE))
2324 : : {
2325 : 1245 : static bool warned;
2326 : :
2327 : 1245 : if (!warned && warn_psabi)
2328 : : {
2329 : 2 : warned = true;
2330 : 2 : inform (input_location,
2331 : : "the ABI of passing struct with"
2332 : : " a flexible array member has"
2333 : : " changed in GCC 4.4");
2334 : : }
2335 : 1245 : continue;
2336 : 1245 : }
2337 : 36897469 : num = classify_argument (TYPE_MODE (type), type,
2338 : : subclasses,
2339 : 36897469 : (int_bit_position (field)
2340 : 36897469 : + bit_offset) % 512,
2341 : : zero_width_bitfields);
2342 : 36897469 : if (!num)
2343 : : return 0;
2344 : 36592422 : pos = (int_bit_position (field)
2345 : 36592422 : + (bit_offset % 64)) / 8 / 8;
2346 : 76473774 : for (i = 0; i < num && (i + pos) < words; i++)
2347 : 39881352 : classes[i + pos]
2348 : 39881352 : = merge_classes (subclasses[i], classes[i + pos]);
2349 : : }
2350 : : }
2351 : : }
2352 : : break;
2353 : :
2354 : 429931 : case ARRAY_TYPE:
2355 : : /* Arrays are handled as small records. */
2356 : 429931 : {
2357 : 429931 : int num;
2358 : 429931 : num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
2359 : 429931 : TREE_TYPE (type), subclasses, bit_offset,
2360 : : zero_width_bitfields);
2361 : 429931 : if (!num)
2362 : : return 0;
2363 : :
2364 : : /* The partial classes are now full classes. */
2365 : 409529 : if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
2366 : 13565 : subclasses[0] = X86_64_SSE_CLASS;
2367 : 409529 : if (subclasses[0] == X86_64_SSEHF_CLASS && bytes != 2)
2368 : 4734 : subclasses[0] = X86_64_SSE_CLASS;
2369 : 409529 : if (subclasses[0] == X86_64_INTEGERSI_CLASS
2370 : 230776 : && !((bit_offset % 64) == 0 && bytes == 4))
2371 : 123767 : subclasses[0] = X86_64_INTEGER_CLASS;
2372 : :
2373 : 1257007 : for (i = 0; i < words; i++)
2374 : 847478 : classes[i] = subclasses[i % num];
2375 : :
2376 : : break;
2377 : : }
2378 : 290923 : case UNION_TYPE:
2379 : 290923 : case QUAL_UNION_TYPE:
2380 : : /* Unions are similar to RECORD_TYPE but offset is always 0.
2381 : : */
2382 : 3544000 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2383 : : {
2384 : 3286718 : if (TREE_CODE (field) == FIELD_DECL)
2385 : : {
2386 : 1674537 : int num;
2387 : :
2388 : 1674537 : if (TREE_TYPE (field) == error_mark_node)
2389 : 10 : continue;
2390 : :
2391 : 1674527 : num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
2392 : 1674527 : TREE_TYPE (field), subclasses,
2393 : : bit_offset, zero_width_bitfields);
2394 : 1674527 : if (!num)
2395 : : return 0;
2396 : 4159515 : for (i = 0; i < num && i < words; i++)
2397 : 2518629 : classes[i] = merge_classes (subclasses[i], classes[i]);
2398 : : }
2399 : : }
2400 : : break;
2401 : :
2402 : 1281652 : case BITINT_TYPE:
2403 : : /* _BitInt(N) for N > 64 is passed as structure containing
2404 : : (N + 63) / 64 64-bit elements. */
2405 : 1281652 : if (words > 2)
2406 : : return 0;
2407 : 74983 : classes[0] = classes[1] = X86_64_INTEGER_CLASS;
2408 : 74983 : return 2;
2409 : :
2410 : 0 : default:
2411 : 0 : gcc_unreachable ();
2412 : : }
2413 : :
2414 : 24713209 : if (words > 2)
2415 : : {
2416 : : /* When size > 16 bytes, if the first one isn't
2417 : : X86_64_SSE_CLASS or any other ones aren't
2418 : : X86_64_SSEUP_CLASS, everything should be passed in
2419 : : memory. */
2420 : 1181060 : if (classes[0] != X86_64_SSE_CLASS)
2421 : : return 0;
2422 : :
2423 : 192795 : for (i = 1; i < words; i++)
2424 : 174606 : if (classes[i] != X86_64_SSEUP_CLASS)
2425 : : return 0;
2426 : : }
2427 : :
2428 : : /* Final merger cleanup. */
2429 : 57850195 : for (i = 0; i < words; i++)
2430 : : {
2431 : : /* If one class is MEMORY, everything should be passed in
2432 : : memory. */
2433 : 34354171 : if (classes[i] == X86_64_MEMORY_CLASS)
2434 : : return 0;
2435 : :
2436 : : /* The X86_64_SSEUP_CLASS should be always preceded by
2437 : : X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
2438 : 34302227 : if (classes[i] == X86_64_SSEUP_CLASS
2439 : 148540 : && classes[i - 1] != X86_64_SSE_CLASS
2440 : 76550 : && classes[i - 1] != X86_64_SSEUP_CLASS)
2441 : : {
2442 : : /* The first one should never be X86_64_SSEUP_CLASS. */
2443 : 1916 : gcc_assert (i != 0);
2444 : 1916 : classes[i] = X86_64_SSE_CLASS;
2445 : : }
2446 : :
2447 : : /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
2448 : : everything should be passed in memory. */
2449 : 34302227 : if (classes[i] == X86_64_X87UP_CLASS
2450 : 192646 : && (classes[i - 1] != X86_64_X87_CLASS))
2451 : : {
2452 : 2370 : static bool warned;
2453 : :
2454 : : /* The first one should never be X86_64_X87UP_CLASS. */
2455 : 2370 : gcc_assert (i != 0);
2456 : 2370 : if (!warned && warn_psabi)
2457 : : {
2458 : 1 : warned = true;
2459 : 1 : inform (input_location,
2460 : : "the ABI of passing union with %<long double%>"
2461 : : " has changed in GCC 4.4");
2462 : : }
2463 : 2370 : return 0;
2464 : : }
2465 : : }
2466 : : return words;
2467 : : }
2468 : :
2469 : : /* Compute alignment needed. We align all types to natural boundaries with
2470 : : exception of XFmode that is aligned to 64bits. */
2471 : 332459816 : if (mode != VOIDmode && mode != BLKmode)
2472 : : {
2473 : 331049100 : int mode_alignment = GET_MODE_BITSIZE (mode);
2474 : :
2475 : 331049100 : if (mode == XFmode)
2476 : : mode_alignment = 128;
2477 : 323857842 : else if (mode == XCmode)
2478 : 564873 : mode_alignment = 256;
2479 : 331049100 : if (COMPLEX_MODE_P (mode))
2480 : 2513003 : mode_alignment /= 2;
2481 : : /* Misaligned fields are always returned in memory. */
2482 : 331049100 : if (bit_offset % mode_alignment)
2483 : : return 0;
2484 : : }
2485 : :
2486 : : /* for V1xx modes, just use the base mode */
2487 : 332452183 : if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
2488 : 423027138 : && GET_MODE_UNIT_SIZE (mode) == bytes)
2489 : 5360 : mode = GET_MODE_INNER (mode);
2490 : :
2491 : : /* Classification of atomic types. */
2492 : 332452183 : switch (mode)
2493 : : {
2494 : 208531 : case E_SDmode:
2495 : 208531 : case E_DDmode:
2496 : 208531 : classes[0] = X86_64_SSE_CLASS;
2497 : 208531 : return 1;
2498 : 99178 : case E_TDmode:
2499 : 99178 : classes[0] = X86_64_SSE_CLASS;
2500 : 99178 : classes[1] = X86_64_SSEUP_CLASS;
2501 : 99178 : return 2;
2502 : 211843530 : case E_DImode:
2503 : 211843530 : case E_SImode:
2504 : 211843530 : case E_HImode:
2505 : 211843530 : case E_QImode:
2506 : 211843530 : case E_CSImode:
2507 : 211843530 : case E_CHImode:
2508 : 211843530 : case E_CQImode:
2509 : 211843530 : {
2510 : 211843530 : int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
2511 : :
2512 : : /* Analyze last 128 bits only. */
2513 : 211843530 : size = (size - 1) & 0x7f;
2514 : :
2515 : 211843530 : if (size < 32)
2516 : : {
2517 : 91031928 : classes[0] = X86_64_INTEGERSI_CLASS;
2518 : 91031928 : return 1;
2519 : : }
2520 : 120811602 : else if (size < 64)
2521 : : {
2522 : 110735739 : classes[0] = X86_64_INTEGER_CLASS;
2523 : 110735739 : return 1;
2524 : : }
2525 : 10075863 : else if (size < 64+32)
2526 : : {
2527 : 4288689 : classes[0] = X86_64_INTEGER_CLASS;
2528 : 4288689 : classes[1] = X86_64_INTEGERSI_CLASS;
2529 : 4288689 : return 2;
2530 : : }
2531 : 5787174 : else if (size < 64+64)
2532 : : {
2533 : 5787174 : classes[0] = classes[1] = X86_64_INTEGER_CLASS;
2534 : 5787174 : return 2;
2535 : : }
2536 : : else
2537 : : gcc_unreachable ();
2538 : : }
2539 : 1922094 : case E_CDImode:
2540 : 1922094 : case E_TImode:
2541 : 1922094 : classes[0] = classes[1] = X86_64_INTEGER_CLASS;
2542 : 1922094 : return 2;
2543 : 0 : case E_COImode:
2544 : 0 : case E_OImode:
2545 : : /* OImode shouldn't be used directly. */
2546 : 0 : gcc_unreachable ();
2547 : : case E_CTImode:
2548 : : return 0;
2549 : 1126186 : case E_HFmode:
2550 : 1126186 : case E_BFmode:
2551 : 1126186 : if (!(bit_offset % 64))
2552 : 1123926 : classes[0] = X86_64_SSEHF_CLASS;
2553 : : else
2554 : 2260 : classes[0] = X86_64_SSE_CLASS;
2555 : : return 1;
2556 : 10068591 : case E_SFmode:
2557 : 10068591 : if (!(bit_offset % 64))
2558 : 10015705 : classes[0] = X86_64_SSESF_CLASS;
2559 : : else
2560 : 52886 : classes[0] = X86_64_SSE_CLASS;
2561 : : return 1;
2562 : 4342650 : case E_DFmode:
2563 : 4342650 : classes[0] = X86_64_SSEDF_CLASS;
2564 : 4342650 : return 1;
2565 : 7190542 : case E_XFmode:
2566 : 7190542 : classes[0] = X86_64_X87_CLASS;
2567 : 7190542 : classes[1] = X86_64_X87UP_CLASS;
2568 : 7190542 : return 2;
2569 : 1344960 : case E_TFmode:
2570 : 1344960 : classes[0] = X86_64_SSE_CLASS;
2571 : 1344960 : classes[1] = X86_64_SSEUP_CLASS;
2572 : 1344960 : return 2;
2573 : 148624 : case E_HCmode:
2574 : 148624 : case E_BCmode:
2575 : 148624 : classes[0] = X86_64_SSE_CLASS;
2576 : 148624 : if (!(bit_offset % 64))
2577 : : return 1;
2578 : : else
2579 : : {
2580 : 98 : classes[1] = X86_64_SSEHF_CLASS;
2581 : 98 : return 2;
2582 : : }
2583 : 742026 : case E_SCmode:
2584 : 742026 : classes[0] = X86_64_SSE_CLASS;
2585 : 742026 : if (!(bit_offset % 64))
2586 : : return 1;
2587 : : else
2588 : : {
2589 : 1041 : static bool warned;
2590 : :
2591 : 1041 : if (!warned && warn_psabi)
2592 : : {
2593 : 1 : warned = true;
2594 : 1 : inform (input_location,
2595 : : "the ABI of passing structure with %<complex float%>"
2596 : : " member has changed in GCC 4.4");
2597 : : }
2598 : 1041 : classes[1] = X86_64_SSESF_CLASS;
2599 : 1041 : return 2;
2600 : : }
2601 : 753191 : case E_DCmode:
2602 : 753191 : classes[0] = X86_64_SSEDF_CLASS;
2603 : 753191 : classes[1] = X86_64_SSEDF_CLASS;
2604 : 753191 : return 2;
2605 : 564873 : case E_XCmode:
2606 : 564873 : classes[0] = X86_64_COMPLEX_X87_CLASS;
2607 : 564873 : return 1;
2608 : : case E_TCmode:
2609 : : /* This modes is larger than 16 bytes. */
2610 : : return 0;
2611 : 24542224 : case E_V8SFmode:
2612 : 24542224 : case E_V8SImode:
2613 : 24542224 : case E_V32QImode:
2614 : 24542224 : case E_V16HFmode:
2615 : 24542224 : case E_V16BFmode:
2616 : 24542224 : case E_V16HImode:
2617 : 24542224 : case E_V4DFmode:
2618 : 24542224 : case E_V4DImode:
2619 : 24542224 : classes[0] = X86_64_SSE_CLASS;
2620 : 24542224 : classes[1] = X86_64_SSEUP_CLASS;
2621 : 24542224 : classes[2] = X86_64_SSEUP_CLASS;
2622 : 24542224 : classes[3] = X86_64_SSEUP_CLASS;
2623 : 24542224 : return 4;
2624 : 26641464 : case E_V8DFmode:
2625 : 26641464 : case E_V16SFmode:
2626 : 26641464 : case E_V32HFmode:
2627 : 26641464 : case E_V32BFmode:
2628 : 26641464 : case E_V8DImode:
2629 : 26641464 : case E_V16SImode:
2630 : 26641464 : case E_V32HImode:
2631 : 26641464 : case E_V64QImode:
2632 : 26641464 : classes[0] = X86_64_SSE_CLASS;
2633 : 26641464 : classes[1] = X86_64_SSEUP_CLASS;
2634 : 26641464 : classes[2] = X86_64_SSEUP_CLASS;
2635 : 26641464 : classes[3] = X86_64_SSEUP_CLASS;
2636 : 26641464 : classes[4] = X86_64_SSEUP_CLASS;
2637 : 26641464 : classes[5] = X86_64_SSEUP_CLASS;
2638 : 26641464 : classes[6] = X86_64_SSEUP_CLASS;
2639 : 26641464 : classes[7] = X86_64_SSEUP_CLASS;
2640 : 26641464 : return 8;
2641 : 36189449 : case E_V4SFmode:
2642 : 36189449 : case E_V4SImode:
2643 : 36189449 : case E_V16QImode:
2644 : 36189449 : case E_V8HImode:
2645 : 36189449 : case E_V8HFmode:
2646 : 36189449 : case E_V8BFmode:
2647 : 36189449 : case E_V2DFmode:
2648 : 36189449 : case E_V2DImode:
2649 : 36189449 : classes[0] = X86_64_SSE_CLASS;
2650 : 36189449 : classes[1] = X86_64_SSEUP_CLASS;
2651 : 36189449 : return 2;
2652 : 3179007 : case E_V1TImode:
2653 : 3179007 : case E_V1DImode:
2654 : 3179007 : case E_V2SFmode:
2655 : 3179007 : case E_V2SImode:
2656 : 3179007 : case E_V4HImode:
2657 : 3179007 : case E_V4HFmode:
2658 : 3179007 : case E_V4BFmode:
2659 : 3179007 : case E_V2HFmode:
2660 : 3179007 : case E_V2BFmode:
2661 : 3179007 : case E_V8QImode:
2662 : 3179007 : classes[0] = X86_64_SSE_CLASS;
2663 : 3179007 : return 1;
2664 : : case E_BLKmode:
2665 : : case E_VOIDmode:
2666 : : return 0;
2667 : 37170 : default:
2668 : 37170 : gcc_assert (VECTOR_MODE_P (mode));
2669 : :
2670 : 37170 : if (bytes > 16)
2671 : : return 0;
2672 : :
2673 : 45432 : gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
2674 : :
2675 : 45432 : if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
2676 : 22276 : classes[0] = X86_64_INTEGERSI_CLASS;
2677 : : else
2678 : 440 : classes[0] = X86_64_INTEGER_CLASS;
2679 : 22716 : classes[1] = X86_64_INTEGER_CLASS;
2680 : 22716 : return 1 + (bytes > 8);
2681 : : }
2682 : : }
2683 : :
2684 : : /* Wrapper around classify_argument with the extra zero_width_bitfields
2685 : : argument, to diagnose GCC 12.1 ABI differences for C. */
2686 : :
2687 : : static int
2688 : 320683273 : classify_argument (machine_mode mode, const_tree type,
2689 : : enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
2690 : : {
2691 : 320683273 : int zero_width_bitfields = 0;
2692 : 320683273 : static bool warned = false;
2693 : 320683273 : int n = classify_argument (mode, type, classes, bit_offset,
2694 : : zero_width_bitfields);
2695 : 320683273 : if (!zero_width_bitfields || warned || !warn_psabi)
2696 : : return n;
2697 : 534 : enum x86_64_reg_class alt_classes[MAX_CLASSES];
2698 : 534 : zero_width_bitfields = 2;
2699 : 534 : if (classify_argument (mode, type, alt_classes, bit_offset,
2700 : : zero_width_bitfields) != n)
2701 : 0 : zero_width_bitfields = 3;
2702 : : else
2703 : 1286 : for (int i = 0; i < n; i++)
2704 : 760 : if (classes[i] != alt_classes[i])
2705 : : {
2706 : 8 : zero_width_bitfields = 3;
2707 : 8 : break;
2708 : : }
2709 : 534 : if (zero_width_bitfields == 3)
2710 : : {
2711 : 8 : warned = true;
2712 : 8 : const char *url
2713 : : = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields";
2714 : :
2715 : 8 : inform (input_location,
2716 : : "the ABI of passing C structures with zero-width bit-fields"
2717 : : " has changed in GCC %{12.1%}", url);
2718 : : }
2719 : : return n;
2720 : : }
2721 : :
2722 : : /* Examine the argument and return set number of register required in each
2723 : : class. Return true iff parameter should be passed in memory. */
2724 : :
2725 : : static bool
2726 : 215730366 : examine_argument (machine_mode mode, const_tree type, int in_return,
2727 : : int *int_nregs, int *sse_nregs)
2728 : : {
2729 : 215730366 : enum x86_64_reg_class regclass[MAX_CLASSES];
2730 : 215730366 : int n = classify_argument (mode, type, regclass, 0);
2731 : :
2732 : 215730366 : *int_nregs = 0;
2733 : 215730366 : *sse_nregs = 0;
2734 : :
2735 : 215730366 : if (!n)
2736 : : return true;
2737 : 632915609 : for (n--; n >= 0; n--)
2738 : 421581241 : switch (regclass[n])
2739 : : {
2740 : 140507634 : case X86_64_INTEGER_CLASS:
2741 : 140507634 : case X86_64_INTEGERSI_CLASS:
2742 : 140507634 : (*int_nregs)++;
2743 : 140507634 : break;
2744 : 72989139 : case X86_64_SSE_CLASS:
2745 : 72989139 : case X86_64_SSEHF_CLASS:
2746 : 72989139 : case X86_64_SSESF_CLASS:
2747 : 72989139 : case X86_64_SSEDF_CLASS:
2748 : 72989139 : (*sse_nregs)++;
2749 : 72989139 : break;
2750 : : case X86_64_NO_CLASS:
2751 : : case X86_64_SSEUP_CLASS:
2752 : : break;
2753 : 9730305 : case X86_64_X87_CLASS:
2754 : 9730305 : case X86_64_X87UP_CLASS:
2755 : 9730305 : case X86_64_COMPLEX_X87_CLASS:
2756 : 9730305 : if (!in_return)
2757 : : return true;
2758 : : break;
2759 : 0 : case X86_64_MEMORY_CLASS:
2760 : 0 : gcc_unreachable ();
2761 : : }
2762 : :
2763 : : return false;
2764 : : }
2765 : :
2766 : : /* Construct container for the argument used by GCC interface. See
2767 : : FUNCTION_ARG for the detailed description. */
2768 : :
2769 : : static rtx
2770 : 104952907 : construct_container (machine_mode mode, machine_mode orig_mode,
2771 : : const_tree type, int in_return, int nintregs, int nsseregs,
2772 : : const int *intreg, int sse_regno)
2773 : : {
2774 : : /* The following variables hold the static issued_error state. */
2775 : 104952907 : static bool issued_sse_arg_error;
2776 : 104952907 : static bool issued_sse_ret_error;
2777 : 104952907 : static bool issued_x87_ret_error;
2778 : :
2779 : 104952907 : machine_mode tmpmode;
2780 : 104952907 : int bytes
2781 : 209317825 : = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
2782 : 104952907 : enum x86_64_reg_class regclass[MAX_CLASSES];
2783 : 104952907 : int n;
2784 : 104952907 : int i;
2785 : 104952907 : int nexps = 0;
2786 : 104952907 : int needed_sseregs, needed_intregs;
2787 : 104952907 : rtx exp[MAX_CLASSES];
2788 : 104952907 : rtx ret;
2789 : :
2790 : 104952907 : n = classify_argument (mode, type, regclass, 0);
2791 : 104952907 : if (!n)
2792 : : return NULL;
2793 : 104500101 : if (examine_argument (mode, type, in_return, &needed_intregs,
2794 : : &needed_sseregs))
2795 : : return NULL;
2796 : 104451823 : if (needed_intregs > nintregs || needed_sseregs > nsseregs)
2797 : : return NULL;
2798 : :
2799 : : /* We allowed the user to turn off SSE for kernel mode. Don't crash if
2800 : : some less clueful developer tries to use floating-point anyway. */
2801 : 103357653 : if (needed_sseregs
2802 : 36043712 : && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2)))
2803 : : {
2804 : : /* Return early if we shouldn't raise an error for invalid
2805 : : calls. */
2806 : 71 : if (cfun != NULL && cfun->machine->silent_p)
2807 : : return NULL;
2808 : 39 : if (in_return)
2809 : : {
2810 : 34 : if (!issued_sse_ret_error)
2811 : : {
2812 : 16 : if (VALID_SSE2_TYPE_MODE (mode))
2813 : 5 : error ("SSE register return with SSE2 disabled");
2814 : : else
2815 : 11 : error ("SSE register return with SSE disabled");
2816 : 16 : issued_sse_ret_error = true;
2817 : : }
2818 : : }
2819 : 5 : else if (!issued_sse_arg_error)
2820 : : {
2821 : 5 : if (VALID_SSE2_TYPE_MODE (mode))
2822 : 0 : error ("SSE register argument with SSE2 disabled");
2823 : : else
2824 : 5 : error ("SSE register argument with SSE disabled");
2825 : 5 : issued_sse_arg_error = true;
2826 : : }
2827 : 39 : return NULL;
2828 : : }
2829 : :
2830 : : /* Likewise, error if the ABI requires us to return values in the
2831 : : x87 registers and the user specified -mno-80387. */
2832 : 103357582 : if (!TARGET_FLOAT_RETURNS_IN_80387 && in_return)
2833 : 1387642 : for (i = 0; i < n; i++)
2834 : 733325 : if (regclass[i] == X86_64_X87_CLASS
2835 : : || regclass[i] == X86_64_X87UP_CLASS
2836 : 733325 : || regclass[i] == X86_64_COMPLEX_X87_CLASS)
2837 : : {
2838 : : /* Return early if we shouldn't raise an error for invalid
2839 : : calls. */
2840 : 14 : if (cfun != NULL && cfun->machine->silent_p)
2841 : : return NULL;
2842 : 11 : if (!issued_x87_ret_error)
2843 : : {
2844 : 6 : error ("x87 register return with x87 disabled");
2845 : 6 : issued_x87_ret_error = true;
2846 : : }
2847 : 11 : return NULL;
2848 : : }
2849 : :
2850 : : /* First construct simple cases. Avoid SCmode, since we want to use
2851 : : single register to pass this type. */
2852 : 103357568 : if (n == 1 && mode != SCmode && mode != HCmode)
2853 : 67574420 : switch (regclass[0])
2854 : : {
2855 : 61384015 : case X86_64_INTEGER_CLASS:
2856 : 61384015 : case X86_64_INTEGERSI_CLASS:
2857 : 61384015 : return gen_rtx_REG (mode, intreg[0]);
2858 : 5987248 : case X86_64_SSE_CLASS:
2859 : 5987248 : case X86_64_SSEHF_CLASS:
2860 : 5987248 : case X86_64_SSESF_CLASS:
2861 : 5987248 : case X86_64_SSEDF_CLASS:
2862 : 5987248 : if (mode != BLKmode)
2863 : 11973688 : return gen_reg_or_parallel (mode, orig_mode,
2864 : 11973688 : GET_SSE_REGNO (sse_regno));
2865 : : break;
2866 : 174744 : case X86_64_X87_CLASS:
2867 : 174744 : case X86_64_COMPLEX_X87_CLASS:
2868 : 174744 : return gen_rtx_REG (mode, FIRST_STACK_REG);
2869 : : case X86_64_NO_CLASS:
2870 : : /* Zero sized array, struct or class. */
2871 : : return NULL;
2872 : 0 : default:
2873 : 0 : gcc_unreachable ();
2874 : : }
2875 : 35783552 : if (n == 2
2876 : 18502106 : && regclass[0] == X86_64_SSE_CLASS
2877 : 12509769 : && regclass[1] == X86_64_SSEUP_CLASS
2878 : 12505035 : && mode != BLKmode)
2879 : 25010070 : return gen_reg_or_parallel (mode, orig_mode,
2880 : 25010070 : GET_SSE_REGNO (sse_regno));
2881 : 23278517 : if (n == 4
2882 : 8164718 : && regclass[0] == X86_64_SSE_CLASS
2883 : 8164718 : && regclass[1] == X86_64_SSEUP_CLASS
2884 : 8164718 : && regclass[2] == X86_64_SSEUP_CLASS
2885 : 8164718 : && regclass[3] == X86_64_SSEUP_CLASS
2886 : 8164718 : && mode != BLKmode)
2887 : 16326058 : return gen_reg_or_parallel (mode, orig_mode,
2888 : 16326058 : GET_SSE_REGNO (sse_regno));
2889 : 15115488 : if (n == 8
2890 : 8850359 : && regclass[0] == X86_64_SSE_CLASS
2891 : 8850359 : && regclass[1] == X86_64_SSEUP_CLASS
2892 : 8850359 : && regclass[2] == X86_64_SSEUP_CLASS
2893 : 8850359 : && regclass[3] == X86_64_SSEUP_CLASS
2894 : 8850359 : && regclass[4] == X86_64_SSEUP_CLASS
2895 : 8850359 : && regclass[5] == X86_64_SSEUP_CLASS
2896 : 8850359 : && regclass[6] == X86_64_SSEUP_CLASS
2897 : 8850359 : && regclass[7] == X86_64_SSEUP_CLASS
2898 : 8850359 : && mode != BLKmode)
2899 : 17696446 : return gen_reg_or_parallel (mode, orig_mode,
2900 : 17696446 : GET_SSE_REGNO (sse_regno));
2901 : 6267265 : if (n == 2
2902 : 5997071 : && regclass[0] == X86_64_X87_CLASS
2903 : 2325612 : && regclass[1] == X86_64_X87UP_CLASS)
2904 : 2325612 : return gen_rtx_REG (XFmode, FIRST_STACK_REG);
2905 : :
2906 : 3941653 : if (n == 2
2907 : 3671459 : && regclass[0] == X86_64_INTEGER_CLASS
2908 : 3280376 : && regclass[1] == X86_64_INTEGER_CLASS
2909 : 3272142 : && (mode == CDImode || mode == TImode || mode == BLKmode)
2910 : 3272142 : && intreg[0] + 1 == intreg[1])
2911 : : {
2912 : 2946599 : if (mode == BLKmode)
2913 : : {
2914 : : /* Use TImode for BLKmode values in 2 integer registers. */
2915 : 502836 : exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
2916 : 251418 : gen_rtx_REG (TImode, intreg[0]),
2917 : : GEN_INT (0));
2918 : 251418 : ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
2919 : 251418 : XVECEXP (ret, 0, 0) = exp[0];
2920 : 251418 : return ret;
2921 : : }
2922 : : else
2923 : 2695181 : return gen_rtx_REG (mode, intreg[0]);
2924 : : }
2925 : :
2926 : : /* Otherwise figure out the entries of the PARALLEL. */
2927 : 2714968 : for (i = 0; i < n; i++)
2928 : : {
2929 : 1719914 : int pos;
2930 : :
2931 : 1719914 : switch (regclass[i])
2932 : : {
2933 : : case X86_64_NO_CLASS:
2934 : : break;
2935 : 912567 : case X86_64_INTEGER_CLASS:
2936 : 912567 : case X86_64_INTEGERSI_CLASS:
2937 : : /* Merge TImodes on aligned occasions here too. */
2938 : 912567 : if (i * 8 + 8 > bytes)
2939 : : {
2940 : 3221 : unsigned int tmpbits = (bytes - i * 8) * BITS_PER_UNIT;
2941 : 3221 : if (!int_mode_for_size (tmpbits, 0).exists (&tmpmode))
2942 : : /* We've requested 24 bytes we
2943 : : don't have mode for. Use DImode. */
2944 : 358 : tmpmode = DImode;
2945 : : }
2946 : 909346 : else if (regclass[i] == X86_64_INTEGERSI_CLASS)
2947 : : tmpmode = SImode;
2948 : : else
2949 : 784118 : tmpmode = DImode;
2950 : 1825134 : exp [nexps++]
2951 : 912567 : = gen_rtx_EXPR_LIST (VOIDmode,
2952 : 912567 : gen_rtx_REG (tmpmode, *intreg),
2953 : 912567 : GEN_INT (i*8));
2954 : 912567 : intreg++;
2955 : 912567 : break;
2956 : 592 : case X86_64_SSEHF_CLASS:
2957 : 592 : tmpmode = (mode == BFmode ? BFmode : HFmode);
2958 : 1184 : exp [nexps++]
2959 : 1184 : = gen_rtx_EXPR_LIST (VOIDmode,
2960 : : gen_rtx_REG (tmpmode,
2961 : 592 : GET_SSE_REGNO (sse_regno)),
2962 : 592 : GEN_INT (i*8));
2963 : 592 : sse_regno++;
2964 : 592 : break;
2965 : 2937 : case X86_64_SSESF_CLASS:
2966 : 5874 : exp [nexps++]
2967 : 5874 : = gen_rtx_EXPR_LIST (VOIDmode,
2968 : : gen_rtx_REG (SFmode,
2969 : 2937 : GET_SSE_REGNO (sse_regno)),
2970 : 2937 : GEN_INT (i*8));
2971 : 2937 : sse_regno++;
2972 : 2937 : break;
2973 : 516448 : case X86_64_SSEDF_CLASS:
2974 : 1032896 : exp [nexps++]
2975 : 1032896 : = gen_rtx_EXPR_LIST (VOIDmode,
2976 : : gen_rtx_REG (DFmode,
2977 : 516448 : GET_SSE_REGNO (sse_regno)),
2978 : 516448 : GEN_INT (i*8));
2979 : 516448 : sse_regno++;
2980 : 516448 : break;
2981 : 279290 : case X86_64_SSE_CLASS:
2982 : 279290 : pos = i;
2983 : 279290 : switch (n)
2984 : : {
2985 : : case 1:
2986 : : tmpmode = DImode;
2987 : : break;
2988 : 9310 : case 2:
2989 : 9310 : if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
2990 : : {
2991 : 0 : tmpmode = TImode;
2992 : 0 : i++;
2993 : : }
2994 : : else
2995 : : tmpmode = DImode;
2996 : : break;
2997 : 1689 : case 4:
2998 : 1689 : gcc_assert (i == 0
2999 : : && regclass[1] == X86_64_SSEUP_CLASS
3000 : : && regclass[2] == X86_64_SSEUP_CLASS
3001 : : && regclass[3] == X86_64_SSEUP_CLASS);
3002 : : tmpmode = OImode;
3003 : : i += 3;
3004 : : break;
3005 : 2136 : case 8:
3006 : 2136 : gcc_assert (i == 0
3007 : : && regclass[1] == X86_64_SSEUP_CLASS
3008 : : && regclass[2] == X86_64_SSEUP_CLASS
3009 : : && regclass[3] == X86_64_SSEUP_CLASS
3010 : : && regclass[4] == X86_64_SSEUP_CLASS
3011 : : && regclass[5] == X86_64_SSEUP_CLASS
3012 : : && regclass[6] == X86_64_SSEUP_CLASS
3013 : : && regclass[7] == X86_64_SSEUP_CLASS);
3014 : : tmpmode = XImode;
3015 : : i += 7;
3016 : : break;
3017 : 0 : default:
3018 : 0 : gcc_unreachable ();
3019 : : }
3020 : 558580 : exp [nexps++]
3021 : 558580 : = gen_rtx_EXPR_LIST (VOIDmode,
3022 : : gen_rtx_REG (tmpmode,
3023 : 279290 : GET_SSE_REGNO (sse_regno)),
3024 : 279290 : GEN_INT (pos*8));
3025 : 279290 : sse_regno++;
3026 : 279290 : break;
3027 : 0 : default:
3028 : 0 : gcc_unreachable ();
3029 : : }
3030 : : }
3031 : :
3032 : : /* Empty aligned struct, union or class. */
3033 : 995054 : if (nexps == 0)
3034 : : return NULL;
3035 : :
3036 : 994799 : ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
3037 : 2706633 : for (i = 0; i < nexps; i++)
3038 : 1711834 : XVECEXP (ret, 0, i) = exp [i];
3039 : : return ret;
3040 : : }
3041 : :
3042 : : /* Update the data in CUM to advance over an argument of mode MODE
3043 : : and data type TYPE. (TYPE is null for libcalls where that information
3044 : : may not be available.)
3045 : :
3046 : : Return a number of integer regsiters advanced over. */
3047 : :
3048 : : static int
3049 : 2105289 : function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
3050 : : const_tree type, HOST_WIDE_INT bytes,
3051 : : HOST_WIDE_INT words)
3052 : : {
3053 : 2105289 : int res = 0;
3054 : 2105289 : bool error_p = false;
3055 : :
3056 : 2105289 : if (TARGET_IAMCU)
3057 : : {
3058 : : /* Intel MCU psABI passes scalars and aggregates no larger than 8
3059 : : bytes in registers. */
3060 : 0 : if (!VECTOR_MODE_P (mode) && bytes <= 8)
3061 : 0 : goto pass_in_reg;
3062 : : return res;
3063 : : }
3064 : :
3065 : 2105289 : switch (mode)
3066 : : {
3067 : : default:
3068 : : break;
3069 : :
3070 : 93672 : case E_BLKmode:
3071 : 93672 : if (bytes < 0)
3072 : : break;
3073 : : /* FALLTHRU */
3074 : :
3075 : 2068631 : case E_DImode:
3076 : 2068631 : case E_SImode:
3077 : 2068631 : case E_HImode:
3078 : 2068631 : case E_QImode:
3079 : 93672 : pass_in_reg:
3080 : 2068631 : cum->words += words;
3081 : 2068631 : cum->nregs -= words;
3082 : 2068631 : cum->regno += words;
3083 : 2068631 : if (cum->nregs >= 0)
3084 : 45916 : res = words;
3085 : 2068631 : if (cum->nregs <= 0)
3086 : : {
3087 : 2035631 : cum->nregs = 0;
3088 : 2035631 : cfun->machine->arg_reg_available = false;
3089 : 2035631 : cum->regno = 0;
3090 : : }
3091 : : break;
3092 : :
3093 : 0 : case E_OImode:
3094 : : /* OImode shouldn't be used directly. */
3095 : 0 : gcc_unreachable ();
3096 : :
3097 : 4685 : case E_DFmode:
3098 : 4685 : if (cum->float_in_sse == -1)
3099 : 0 : error_p = true;
3100 : 4685 : if (cum->float_in_sse < 2)
3101 : : break;
3102 : : /* FALLTHRU */
3103 : 1359 : case E_SFmode:
3104 : 1359 : if (cum->float_in_sse == -1)
3105 : 0 : error_p = true;
3106 : 1359 : if (cum->float_in_sse < 1)
3107 : : break;
3108 : : /* FALLTHRU */
3109 : :
3110 : 52 : case E_V16HFmode:
3111 : 52 : case E_V16BFmode:
3112 : 52 : case E_V8SFmode:
3113 : 52 : case E_V8SImode:
3114 : 52 : case E_V64QImode:
3115 : 52 : case E_V32HImode:
3116 : 52 : case E_V16SImode:
3117 : 52 : case E_V8DImode:
3118 : 52 : case E_V32HFmode:
3119 : 52 : case E_V32BFmode:
3120 : 52 : case E_V16SFmode:
3121 : 52 : case E_V8DFmode:
3122 : 52 : case E_V32QImode:
3123 : 52 : case E_V16HImode:
3124 : 52 : case E_V4DFmode:
3125 : 52 : case E_V4DImode:
3126 : 52 : case E_TImode:
3127 : 52 : case E_V16QImode:
3128 : 52 : case E_V8HImode:
3129 : 52 : case E_V4SImode:
3130 : 52 : case E_V2DImode:
3131 : 52 : case E_V8HFmode:
3132 : 52 : case E_V8BFmode:
3133 : 52 : case E_V4SFmode:
3134 : 52 : case E_V2DFmode:
3135 : 52 : if (!type || !AGGREGATE_TYPE_P (type))
3136 : : {
3137 : 52 : cum->sse_words += words;
3138 : 52 : cum->sse_nregs -= 1;
3139 : 52 : cum->sse_regno += 1;
3140 : 52 : if (cum->sse_nregs <= 0)
3141 : : {
3142 : 4 : cum->sse_nregs = 0;
3143 : 4 : cum->sse_regno = 0;
3144 : : }
3145 : : }
3146 : : break;
3147 : :
3148 : 12 : case E_V8QImode:
3149 : 12 : case E_V4HImode:
3150 : 12 : case E_V4HFmode:
3151 : 12 : case E_V4BFmode:
3152 : 12 : case E_V2SImode:
3153 : 12 : case E_V2SFmode:
3154 : 12 : case E_V1TImode:
3155 : 12 : case E_V1DImode:
3156 : 12 : if (!type || !AGGREGATE_TYPE_P (type))
3157 : : {
3158 : 12 : cum->mmx_words += words;
3159 : 12 : cum->mmx_nregs -= 1;
3160 : 12 : cum->mmx_regno += 1;
3161 : 12 : if (cum->mmx_nregs <= 0)
3162 : : {
3163 : 0 : cum->mmx_nregs = 0;
3164 : 0 : cum->mmx_regno = 0;
3165 : : }
3166 : : }
3167 : : break;
3168 : : }
3169 : 2041727 : if (error_p)
3170 : : {
3171 : 0 : cum->float_in_sse = 0;
3172 : 0 : error ("calling %qD with SSE calling convention without "
3173 : : "SSE/SSE2 enabled", cum->decl);
3174 : 0 : sorry ("this is a GCC bug that can be worked around by adding "
3175 : : "attribute used to function called");
3176 : : }
3177 : :
3178 : : return res;
3179 : : }
3180 : :
3181 : : static int
3182 : 19077605 : function_arg_advance_64 (CUMULATIVE_ARGS *cum, machine_mode mode,
3183 : : const_tree type, HOST_WIDE_INT words, bool named)
3184 : : {
3185 : 19077605 : int int_nregs, sse_nregs;
3186 : :
3187 : : /* Unnamed 512 and 256bit vector mode parameters are passed on stack. */
3188 : 19077605 : if (!named && (VALID_AVX512F_REG_MODE (mode)
3189 : : || VALID_AVX256_REG_MODE (mode)))
3190 : : return 0;
3191 : :
3192 : 19077241 : if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
3193 : 19077241 : && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
3194 : : {
3195 : 16816535 : cum->nregs -= int_nregs;
3196 : 16816535 : cum->sse_nregs -= sse_nregs;
3197 : 16816535 : cum->regno += int_nregs;
3198 : 16816535 : cum->sse_regno += sse_nregs;
3199 : 16816535 : return int_nregs;
3200 : : }
3201 : : else
3202 : : {
3203 : 2260706 : int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
3204 : 2260706 : cum->words = ROUND_UP (cum->words, align);
3205 : 2260706 : cum->words += words;
3206 : 2260706 : return 0;
3207 : : }
3208 : : }
3209 : :
3210 : : static int
3211 : 446969 : function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
3212 : : HOST_WIDE_INT words)
3213 : : {
3214 : : /* Otherwise, this should be passed indirect. */
3215 : 446969 : gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
3216 : :
3217 : 446969 : cum->words += words;
3218 : 446969 : if (cum->nregs > 0)
3219 : : {
3220 : 289335 : cum->nregs -= 1;
3221 : 289335 : cum->regno += 1;
3222 : 289335 : return 1;
3223 : : }
3224 : : return 0;
3225 : : }
3226 : :
3227 : : /* Update the data in CUM to advance over argument ARG. */
3228 : :
3229 : : static void
3230 : 21630218 : ix86_function_arg_advance (cumulative_args_t cum_v,
3231 : : const function_arg_info &arg)
3232 : : {
3233 : 21630218 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3234 : 21630218 : machine_mode mode = arg.mode;
3235 : 21630218 : HOST_WIDE_INT bytes, words;
3236 : 21630218 : int nregs;
3237 : :
3238 : : /* The argument of interrupt handler is a special case and is
3239 : : handled in ix86_function_arg. */
3240 : 21630218 : if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
3241 : : return;
3242 : :
3243 : 21629863 : bytes = arg.promoted_size_in_bytes ();
3244 : 21629863 : words = CEIL (bytes, UNITS_PER_WORD);
3245 : :
3246 : 21629863 : if (arg.type)
3247 : 21312995 : mode = type_natural_mode (arg.type, NULL, false);
3248 : :
3249 : 21629863 : if (TARGET_64BIT)
3250 : : {
3251 : 19524574 : enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
3252 : :
3253 : 19524574 : if (call_abi == MS_ABI)
3254 : 446969 : nregs = function_arg_advance_ms_64 (cum, bytes, words);
3255 : : else
3256 : 19077605 : nregs = function_arg_advance_64 (cum, mode, arg.type, words,
3257 : 19077605 : arg.named);
3258 : : }
3259 : : else
3260 : 2105289 : nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
3261 : :
3262 : 21629863 : if (!nregs)
3263 : : {
3264 : : /* Track if there are outgoing arguments on stack. */
3265 : 5663461 : if (cum->caller)
3266 : 2698322 : cfun->machine->outgoing_args_on_stack = true;
3267 : : }
3268 : : }
3269 : :
3270 : : /* Define where to put the arguments to a function.
3271 : : Value is zero to push the argument on the stack,
3272 : : or a hard register in which to store the argument.
3273 : :
3274 : : MODE is the argument's machine mode.
3275 : : TYPE is the data type of the argument (as a tree).
3276 : : This is null for libcalls where that information may
3277 : : not be available.
3278 : : CUM is a variable of type CUMULATIVE_ARGS which gives info about
3279 : : the preceding args and about the function being called.
3280 : : NAMED is nonzero if this argument is a named parameter
3281 : : (otherwise it is an extra parameter matching an ellipsis). */
3282 : :
3283 : : static rtx
3284 : 2532506 : function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
3285 : : machine_mode orig_mode, const_tree type,
3286 : : HOST_WIDE_INT bytes, HOST_WIDE_INT words)
3287 : : {
3288 : 2532506 : bool error_p = false;
3289 : :
3290 : : /* Avoid the AL settings for the Unix64 ABI. */
3291 : 2532506 : if (mode == VOIDmode)
3292 : 735869 : return constm1_rtx;
3293 : :
3294 : 1796637 : if (TARGET_IAMCU)
3295 : : {
3296 : : /* Intel MCU psABI passes scalars and aggregates no larger than 8
3297 : : bytes in registers. */
3298 : 0 : if (!VECTOR_MODE_P (mode) && bytes <= 8)
3299 : 0 : goto pass_in_reg;
3300 : : return NULL_RTX;
3301 : : }
3302 : :
3303 : 1796637 : switch (mode)
3304 : : {
3305 : : default:
3306 : : break;
3307 : :
3308 : 77698 : case E_BLKmode:
3309 : 77698 : if (bytes < 0)
3310 : : break;
3311 : : /* FALLTHRU */
3312 : 1763230 : case E_DImode:
3313 : 1763230 : case E_SImode:
3314 : 1763230 : case E_HImode:
3315 : 1763230 : case E_QImode:
3316 : 77698 : pass_in_reg:
3317 : 1763230 : if (words <= cum->nregs)
3318 : : {
3319 : 44084 : int regno = cum->regno;
3320 : :
3321 : : /* Fastcall allocates the first two DWORD (SImode) or
3322 : : smaller arguments to ECX and EDX if it isn't an
3323 : : aggregate type . */
3324 : 44084 : if (cum->fastcall)
3325 : : {
3326 : 6 : if (mode == BLKmode
3327 : 6 : || mode == DImode
3328 : 6 : || (type && AGGREGATE_TYPE_P (type)))
3329 : : break;
3330 : :
3331 : : /* ECX not EAX is the first allocated register. */
3332 : 6 : if (regno == AX_REG)
3333 : 44084 : regno = CX_REG;
3334 : : }
3335 : 44084 : return gen_rtx_REG (mode, regno);
3336 : : }
3337 : : break;
3338 : :
3339 : 3304 : case E_DFmode:
3340 : 3304 : if (cum->float_in_sse == -1)
3341 : 0 : error_p = true;
3342 : 3304 : if (cum->float_in_sse < 2)
3343 : : break;
3344 : : /* FALLTHRU */
3345 : 968 : case E_SFmode:
3346 : 968 : if (cum->float_in_sse == -1)
3347 : 0 : error_p = true;
3348 : 968 : if (cum->float_in_sse < 1)
3349 : : break;
3350 : : /* FALLTHRU */
3351 : 12 : case E_TImode:
3352 : : /* In 32bit, we pass TImode in xmm registers. */
3353 : 12 : case E_V16QImode:
3354 : 12 : case E_V8HImode:
3355 : 12 : case E_V4SImode:
3356 : 12 : case E_V2DImode:
3357 : 12 : case E_V8HFmode:
3358 : 12 : case E_V8BFmode:
3359 : 12 : case E_V4SFmode:
3360 : 12 : case E_V2DFmode:
3361 : 12 : if (!type || !AGGREGATE_TYPE_P (type))
3362 : : {
3363 : 12 : if (cum->sse_nregs)
3364 : 12 : return gen_reg_or_parallel (mode, orig_mode,
3365 : 12 : cum->sse_regno + FIRST_SSE_REG);
3366 : : }
3367 : : break;
3368 : :
3369 : 0 : case E_OImode:
3370 : 0 : case E_XImode:
3371 : : /* OImode and XImode shouldn't be used directly. */
3372 : 0 : gcc_unreachable ();
3373 : :
3374 : 9 : case E_V64QImode:
3375 : 9 : case E_V32HImode:
3376 : 9 : case E_V16SImode:
3377 : 9 : case E_V8DImode:
3378 : 9 : case E_V32HFmode:
3379 : 9 : case E_V32BFmode:
3380 : 9 : case E_V16SFmode:
3381 : 9 : case E_V8DFmode:
3382 : 9 : case E_V16HFmode:
3383 : 9 : case E_V16BFmode:
3384 : 9 : case E_V8SFmode:
3385 : 9 : case E_V8SImode:
3386 : 9 : case E_V32QImode:
3387 : 9 : case E_V16HImode:
3388 : 9 : case E_V4DFmode:
3389 : 9 : case E_V4DImode:
3390 : 9 : if (!type || !AGGREGATE_TYPE_P (type))
3391 : : {
3392 : 9 : if (cum->sse_nregs)
3393 : 9 : return gen_reg_or_parallel (mode, orig_mode,
3394 : 9 : cum->sse_regno + FIRST_SSE_REG);
3395 : : }
3396 : : break;
3397 : :
3398 : 6 : case E_V8QImode:
3399 : 6 : case E_V4HImode:
3400 : 6 : case E_V4HFmode:
3401 : 6 : case E_V4BFmode:
3402 : 6 : case E_V2SImode:
3403 : 6 : case E_V2SFmode:
3404 : 6 : case E_V1TImode:
3405 : 6 : case E_V1DImode:
3406 : 6 : if (!type || !AGGREGATE_TYPE_P (type))
3407 : : {
3408 : 6 : if (cum->mmx_nregs)
3409 : 6 : return gen_reg_or_parallel (mode, orig_mode,
3410 : 6 : cum->mmx_regno + FIRST_MMX_REG);
3411 : : }
3412 : : break;
3413 : : }
3414 : 4272 : if (error_p)
3415 : : {
3416 : 0 : cum->float_in_sse = 0;
3417 : 0 : error ("calling %qD with SSE calling convention without "
3418 : : "SSE/SSE2 enabled", cum->decl);
3419 : 0 : sorry ("this is a GCC bug that can be worked around by adding "
3420 : : "attribute used to function called");
3421 : : }
3422 : :
3423 : : return NULL_RTX;
3424 : : }
3425 : :
3426 : : static rtx
3427 : 18731657 : function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
3428 : : machine_mode orig_mode, const_tree type, bool named)
3429 : : {
3430 : : /* Handle a hidden AL argument containing number of registers
3431 : : for varargs x86-64 functions. */
3432 : 18731657 : if (mode == VOIDmode)
3433 : 5155478 : return GEN_INT (cum->maybe_vaarg
3434 : : ? (cum->sse_nregs < 0
3435 : : ? X86_64_SSE_REGPARM_MAX
3436 : : : cum->sse_regno)
3437 : : : -1);
3438 : :
3439 : 13576179 : switch (mode)
3440 : : {
3441 : : default:
3442 : : break;
3443 : :
3444 : 89999 : case E_V16HFmode:
3445 : 89999 : case E_V16BFmode:
3446 : 89999 : case E_V8SFmode:
3447 : 89999 : case E_V8SImode:
3448 : 89999 : case E_V32QImode:
3449 : 89999 : case E_V16HImode:
3450 : 89999 : case E_V4DFmode:
3451 : 89999 : case E_V4DImode:
3452 : 89999 : case E_V32HFmode:
3453 : 89999 : case E_V32BFmode:
3454 : 89999 : case E_V16SFmode:
3455 : 89999 : case E_V16SImode:
3456 : 89999 : case E_V64QImode:
3457 : 89999 : case E_V32HImode:
3458 : 89999 : case E_V8DFmode:
3459 : 89999 : case E_V8DImode:
3460 : : /* Unnamed 256 and 512bit vector mode parameters are passed on stack. */
3461 : 89999 : if (!named)
3462 : : return NULL;
3463 : : break;
3464 : : }
3465 : :
3466 : 13575815 : const int *parm_regs;
3467 : 13575815 : if (cum->preserve_none_abi)
3468 : : parm_regs = x86_64_preserve_none_int_parameter_registers;
3469 : : else
3470 : 13575700 : parm_regs = x86_64_int_parameter_registers;
3471 : :
3472 : 13575815 : return construct_container (mode, orig_mode, type, 0, cum->nregs,
3473 : 13575815 : cum->sse_nregs,
3474 : 13575815 : &parm_regs[cum->regno],
3475 : 13575815 : cum->sse_regno);
3476 : : }
3477 : :
3478 : : static rtx
3479 : 296328 : function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
3480 : : machine_mode orig_mode, bool named, const_tree type,
3481 : : HOST_WIDE_INT bytes)
3482 : : {
3483 : 296328 : unsigned int regno;
3484 : :
3485 : : /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
3486 : : We use value of -2 to specify that current function call is MSABI. */
3487 : 296328 : if (mode == VOIDmode)
3488 : 36293 : return GEN_INT (-2);
3489 : :
3490 : : /* If we've run out of registers, it goes on the stack. */
3491 : 260035 : if (cum->nregs == 0)
3492 : : return NULL_RTX;
3493 : :
3494 : 176280 : regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
3495 : :
3496 : : /* Only floating point modes are passed in anything but integer regs. */
3497 : 176280 : if (TARGET_SSE && (mode == SFmode || mode == DFmode))
3498 : : {
3499 : 38254 : if (named)
3500 : : {
3501 : 38254 : if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
3502 : 37260 : regno = cum->regno + FIRST_SSE_REG;
3503 : : }
3504 : : else
3505 : : {
3506 : 0 : rtx t1, t2;
3507 : :
3508 : : /* Unnamed floating parameters are passed in both the
3509 : : SSE and integer registers. */
3510 : 0 : t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
3511 : 0 : t2 = gen_rtx_REG (mode, regno);
3512 : 0 : t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
3513 : 0 : t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
3514 : 0 : return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
3515 : : }
3516 : : }
3517 : : /* Handle aggregated types passed in register. */
3518 : 176280 : if (orig_mode == BLKmode)
3519 : : {
3520 : 0 : if (bytes > 0 && bytes <= 8)
3521 : 0 : mode = (bytes > 4 ? DImode : SImode);
3522 : 0 : if (mode == BLKmode)
3523 : 0 : mode = DImode;
3524 : : }
3525 : :
3526 : 176280 : return gen_reg_or_parallel (mode, orig_mode, regno);
3527 : : }
3528 : :
3529 : : /* Return where to put the arguments to a function.
3530 : : Return zero to push the argument on the stack, or a hard register in which to store the argument.
3531 : :
3532 : : ARG describes the argument while CUM gives information about the
3533 : : preceding args and about the function being called. */
3534 : :
3535 : : static rtx
3536 : 21560672 : ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
3537 : : {
3538 : 21560672 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3539 : 21560672 : machine_mode mode = arg.mode;
3540 : 21560672 : HOST_WIDE_INT bytes, words;
3541 : 21560672 : rtx reg;
3542 : :
3543 : 21560672 : if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
3544 : : {
3545 : 181 : gcc_assert (arg.type != NULL_TREE);
3546 : 181 : if (POINTER_TYPE_P (arg.type))
3547 : : {
3548 : : /* This is the pointer argument. */
3549 : 118 : gcc_assert (TYPE_MODE (arg.type) == ptr_mode);
3550 : : /* It is at -WORD(AP) in the current frame in interrupt and
3551 : : exception handlers. */
3552 : 118 : reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
3553 : : }
3554 : : else
3555 : : {
3556 : 63 : gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
3557 : : && TREE_CODE (arg.type) == INTEGER_TYPE
3558 : : && TYPE_MODE (arg.type) == word_mode);
3559 : : /* The error code is the word-mode integer argument at
3560 : : -2 * WORD(AP) in the current frame of the exception
3561 : : handler. */
3562 : 63 : reg = gen_rtx_MEM (word_mode,
3563 : 63 : plus_constant (Pmode,
3564 : : arg_pointer_rtx,
3565 : 63 : -2 * UNITS_PER_WORD));
3566 : : }
3567 : 181 : return reg;
3568 : : }
3569 : :
3570 : 21560491 : bytes = arg.promoted_size_in_bytes ();
3571 : 21560491 : words = CEIL (bytes, UNITS_PER_WORD);
3572 : :
3573 : : /* To simplify the code below, represent vector types with a vector mode
3574 : : even if MMX/SSE are not active. */
3575 : 21560491 : if (arg.type && VECTOR_TYPE_P (arg.type))
3576 : 170048 : mode = type_natural_mode (arg.type, cum, false);
3577 : :
3578 : 21560491 : if (TARGET_64BIT)
3579 : : {
3580 : 19027985 : enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
3581 : :
3582 : 19027985 : if (call_abi == MS_ABI)
3583 : 296328 : reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
3584 : 296328 : arg.type, bytes);
3585 : : else
3586 : 18731657 : reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
3587 : : }
3588 : : else
3589 : 2532506 : reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
3590 : :
3591 : : /* Track if there are outgoing arguments on stack. */
3592 : 21560491 : if (reg == NULL_RTX && cum->caller)
3593 : 2176681 : cfun->machine->outgoing_args_on_stack = true;
3594 : :
3595 : : return reg;
3596 : : }
3597 : :
3598 : : /* A C expression that indicates when an argument must be passed by
3599 : : reference. If nonzero for an argument, a copy of that argument is
3600 : : made in memory and a pointer to the argument is passed instead of
3601 : : the argument itself. The pointer is passed in whatever way is
3602 : : appropriate for passing a pointer to that type. */
3603 : :
3604 : : static bool
3605 : 21549830 : ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
3606 : : {
3607 : 21549830 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3608 : :
3609 : 21549830 : if (TARGET_64BIT)
3610 : : {
3611 : 19454802 : enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
3612 : :
3613 : : /* See Windows x64 Software Convention. */
3614 : 19454802 : if (call_abi == MS_ABI)
3615 : : {
3616 : 441370 : HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
3617 : :
3618 : 441370 : if (tree type = arg.type)
3619 : : {
3620 : : /* Arrays are passed by reference. */
3621 : 441370 : if (TREE_CODE (type) == ARRAY_TYPE)
3622 : : return true;
3623 : :
3624 : 441370 : if (RECORD_OR_UNION_TYPE_P (type))
3625 : : {
3626 : : /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
3627 : : are passed by reference. */
3628 : 15022 : msize = int_size_in_bytes (type);
3629 : : }
3630 : : }
3631 : :
3632 : : /* __m128 is passed by reference. */
3633 : 872811 : return msize != 1 && msize != 2 && msize != 4 && msize != 8;
3634 : : }
3635 : 19013432 : else if (arg.type && int_size_in_bytes (arg.type) == -1)
3636 : : return true;
3637 : : }
3638 : :
3639 : : return false;
3640 : : }
3641 : :
3642 : : /* Return true when TYPE should be 128bit aligned for 32bit argument
3643 : : passing ABI. XXX: This function is obsolete and is only used for
3644 : : checking psABI compatibility with previous versions of GCC. */
3645 : :
3646 : : static bool
3647 : 1957068 : ix86_compat_aligned_value_p (const_tree type)
3648 : : {
3649 : 1957068 : machine_mode mode = TYPE_MODE (type);
3650 : 1957068 : if (((TARGET_SSE && SSE_REG_MODE_P (mode))
3651 : 1957026 : || mode == TDmode
3652 : 1957026 : || mode == TFmode
3653 : : || mode == TCmode)
3654 : 1957280 : && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
3655 : : return true;
3656 : 1956856 : if (TYPE_ALIGN (type) < 128)
3657 : : return false;
3658 : :
3659 : 0 : if (AGGREGATE_TYPE_P (type))
3660 : : {
3661 : : /* Walk the aggregates recursively. */
3662 : 0 : switch (TREE_CODE (type))
3663 : : {
3664 : 0 : case RECORD_TYPE:
3665 : 0 : case UNION_TYPE:
3666 : 0 : case QUAL_UNION_TYPE:
3667 : 0 : {
3668 : 0 : tree field;
3669 : :
3670 : : /* Walk all the structure fields. */
3671 : 0 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
3672 : : {
3673 : 0 : if (TREE_CODE (field) == FIELD_DECL
3674 : 0 : && ix86_compat_aligned_value_p (TREE_TYPE (field)))
3675 : : return true;
3676 : : }
3677 : : break;
3678 : : }
3679 : :
3680 : 0 : case ARRAY_TYPE:
3681 : : /* Just for use if some languages passes arrays by value. */
3682 : 0 : if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
3683 : : return true;
3684 : : break;
3685 : :
3686 : : default:
3687 : : gcc_unreachable ();
3688 : : }
3689 : : }
3690 : : return false;
3691 : : }
3692 : :
3693 : : /* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
3694 : : XXX: This function is obsolete and is only used for checking psABI
3695 : : compatibility with previous versions of GCC. */
3696 : :
3697 : : static unsigned int
3698 : 5481868 : ix86_compat_function_arg_boundary (machine_mode mode,
3699 : : const_tree type, unsigned int align)
3700 : : {
3701 : : /* In 32bit, only _Decimal128 and __float128 are aligned to their
3702 : : natural boundaries. */
3703 : 5481868 : if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
3704 : : {
3705 : : /* i386 ABI defines all arguments to be 4 byte aligned. We have to
3706 : : make an exception for SSE modes since these require 128bit
3707 : : alignment.
3708 : :
3709 : : The handling here differs from field_alignment. ICC aligns MMX
3710 : : arguments to 4 byte boundaries, while structure fields are aligned
3711 : : to 8 byte boundaries. */
3712 : 1969010 : if (!type)
3713 : : {
3714 : 11942 : if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
3715 : 1968798 : align = PARM_BOUNDARY;
3716 : : }
3717 : : else
3718 : : {
3719 : 1957068 : if (!ix86_compat_aligned_value_p (type))
3720 : 1968798 : align = PARM_BOUNDARY;
3721 : : }
3722 : : }
3723 : 10570008 : if (align > BIGGEST_ALIGNMENT)
3724 : 76 : align = BIGGEST_ALIGNMENT;
3725 : 5481868 : return align;
3726 : : }
3727 : :
3728 : : /* Return true when TYPE should be 128bit aligned for 32bit argument
3729 : : passing ABI. */
3730 : :
3731 : : static bool
3732 : 1959710 : ix86_contains_aligned_value_p (const_tree type)
3733 : : {
3734 : 1959710 : machine_mode mode = TYPE_MODE (type);
3735 : :
3736 : 1959710 : if (mode == XFmode || mode == XCmode)
3737 : : return false;
3738 : :
3739 : 1957616 : if (TYPE_ALIGN (type) < 128)
3740 : : return false;
3741 : :
3742 : 2854 : if (AGGREGATE_TYPE_P (type))
3743 : : {
3744 : : /* Walk the aggregates recursively. */
3745 : 0 : switch (TREE_CODE (type))
3746 : : {
3747 : 0 : case RECORD_TYPE:
3748 : 0 : case UNION_TYPE:
3749 : 0 : case QUAL_UNION_TYPE:
3750 : 0 : {
3751 : 0 : tree field;
3752 : :
3753 : : /* Walk all the structure fields. */
3754 : 0 : for (field = TYPE_FIELDS (type);
3755 : 0 : field;
3756 : 0 : field = DECL_CHAIN (field))
3757 : : {
3758 : 0 : if (TREE_CODE (field) == FIELD_DECL
3759 : 0 : && ix86_contains_aligned_value_p (TREE_TYPE (field)))
3760 : : return true;
3761 : : }
3762 : : break;
3763 : : }
3764 : :
3765 : 0 : case ARRAY_TYPE:
3766 : : /* Just for use if some languages passes arrays by value. */
3767 : 0 : if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
3768 : : return true;
3769 : : break;
3770 : :
3771 : : default:
3772 : : gcc_unreachable ();
3773 : : }
3774 : : }
3775 : : else
3776 : 2854 : return TYPE_ALIGN (type) >= 128;
3777 : :
3778 : : return false;
3779 : : }
3780 : :
3781 : : /* Gives the alignment boundary, in bits, of an argument with the
3782 : : specified mode and type. */
3783 : :
3784 : : static unsigned int
3785 : 10833713 : ix86_function_arg_boundary (machine_mode mode, const_tree type)
3786 : : {
3787 : 10833713 : unsigned int align;
3788 : 10833713 : if (type)
3789 : : {
3790 : : /* Since the main variant type is used for call, we convert it to
3791 : : the main variant type. */
3792 : 10794016 : type = TYPE_MAIN_VARIANT (type);
3793 : 10794016 : align = TYPE_ALIGN (type);
3794 : 10794016 : if (TYPE_EMPTY_P (type))
3795 : 24052 : return PARM_BOUNDARY;
3796 : : }
3797 : : else
3798 : 39697 : align = GET_MODE_ALIGNMENT (mode);
3799 : 12816230 : if (align < PARM_BOUNDARY)
3800 : 4071183 : align = PARM_BOUNDARY;
3801 : : else
3802 : : {
3803 : 6738478 : static bool warned;
3804 : 6738478 : unsigned int saved_align = align;
3805 : :
3806 : 6738478 : if (!TARGET_64BIT)
3807 : : {
3808 : : /* i386 ABI defines XFmode arguments to be 4 byte aligned. */
3809 : 1995464 : if (!type)
3810 : : {
3811 : 35754 : if (mode == XFmode || mode == XCmode)
3812 : : align = PARM_BOUNDARY;
3813 : : }
3814 : 1959710 : else if (!ix86_contains_aligned_value_p (type))
3815 : : align = PARM_BOUNDARY;
3816 : :
3817 : 38608 : if (align < 128)
3818 : 1968798 : align = PARM_BOUNDARY;
3819 : : }
3820 : :
3821 : 6738478 : if (warn_psabi
3822 : 5484510 : && !warned
3823 : 12220346 : && align != ix86_compat_function_arg_boundary (mode, type,
3824 : : saved_align))
3825 : : {
3826 : 76 : warned = true;
3827 : 76 : inform (input_location,
3828 : : "the ABI for passing parameters with %d-byte"
3829 : : " alignment has changed in GCC 4.6",
3830 : : align / BITS_PER_UNIT);
3831 : : }
3832 : : }
3833 : :
3834 : : return align;
3835 : : }
3836 : :
3837 : : /* Return true if N is a possible register number of function value. */
3838 : :
3839 : : static bool
3840 : 4603184 : ix86_function_value_regno_p (const unsigned int regno)
3841 : : {
3842 : 4603184 : switch (regno)
3843 : : {
3844 : : case AX_REG:
3845 : : return true;
3846 : 108078 : case DX_REG:
3847 : 108078 : return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI);
3848 : 106184 : case DI_REG:
3849 : 106184 : case SI_REG:
3850 : 106184 : return TARGET_64BIT && ix86_cfun_abi () != MS_ABI;
3851 : :
3852 : : /* Complex values are returned in %st(0)/%st(1) pair. */
3853 : 21583 : case ST0_REG:
3854 : 21583 : case ST1_REG:
3855 : : /* TODO: The function should depend on current function ABI but
3856 : : builtins.cc would need updating then. Therefore we use the
3857 : : default ABI. */
3858 : 21583 : if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
3859 : : return false;
3860 : 21583 : return TARGET_FLOAT_RETURNS_IN_80387;
3861 : :
3862 : : /* Complex values are returned in %xmm0/%xmm1 pair. */
3863 : 1292303 : case XMM0_REG:
3864 : 1292303 : case XMM1_REG:
3865 : 1292303 : return TARGET_SSE;
3866 : :
3867 : 11250 : case MM0_REG:
3868 : 11250 : if (TARGET_MACHO || TARGET_64BIT)
3869 : : return false;
3870 : 5082 : return TARGET_MMX;
3871 : : }
3872 : :
3873 : : return false;
3874 : : }
3875 : :
3876 : : /* Check whether the register REGNO should be zeroed on X86.
3877 : : When ALL_SSE_ZEROED is true, all SSE registers have been zeroed
3878 : : together, no need to zero it again.
3879 : : When NEED_ZERO_MMX is true, MMX registers should be cleared. */
3880 : :
3881 : : static bool
3882 : 1296 : zero_call_used_regno_p (const unsigned int regno,
3883 : : bool all_sse_zeroed,
3884 : : bool need_zero_mmx)
3885 : : {
3886 : 763 : return GENERAL_REGNO_P (regno)
3887 : 763 : || (!all_sse_zeroed && SSE_REGNO_P (regno))
3888 : 383 : || MASK_REGNO_P (regno)
3889 : 1671 : || (need_zero_mmx && MMX_REGNO_P (regno));
3890 : : }
3891 : :
3892 : : /* Return the machine_mode that is used to zero register REGNO. */
3893 : :
3894 : : static machine_mode
3895 : 921 : zero_call_used_regno_mode (const unsigned int regno)
3896 : : {
3897 : : /* NB: We only need to zero the lower 32 bits for integer registers
3898 : : and the lower 128 bits for vector registers since destination are
3899 : : zero-extended to the full register width. */
3900 : 921 : if (GENERAL_REGNO_P (regno))
3901 : : return SImode;
3902 : : else if (SSE_REGNO_P (regno))
3903 : 380 : return V4SFmode;
3904 : : else if (MASK_REGNO_P (regno))
3905 : : return HImode;
3906 : : else if (MMX_REGNO_P (regno))
3907 : 0 : return V2SImode;
3908 : : else
3909 : 0 : gcc_unreachable ();
3910 : : }
3911 : :
3912 : : /* Generate a rtx to zero all vector registers together if possible,
3913 : : otherwise, return NULL. */
3914 : :
3915 : : static rtx
3916 : 130 : zero_all_vector_registers (HARD_REG_SET need_zeroed_hardregs)
3917 : : {
3918 : 130 : if (!TARGET_AVX)
3919 : : return NULL;
3920 : :
3921 : 279 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
3922 : 276 : if ((LEGACY_SSE_REGNO_P (regno)
3923 : 252 : || (TARGET_64BIT
3924 : 252 : && (REX_SSE_REGNO_P (regno)
3925 : 228 : || (TARGET_AVX512F && EXT_REX_SSE_REGNO_P (regno)))))
3926 : 316 : && !TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
3927 : : return NULL;
3928 : :
3929 : 3 : return gen_avx_vzeroall ();
3930 : : }
3931 : :
3932 : : /* Generate insns to zero all st registers together.
3933 : : Return true when zeroing instructions are generated.
3934 : : Assume the number of st registers that are zeroed is num_of_st,
3935 : : we will emit the following sequence to zero them together:
3936 : : fldz; \
3937 : : fldz; \
3938 : : ...
3939 : : fldz; \
3940 : : fstp %%st(0); \
3941 : : fstp %%st(0); \
3942 : : ...
3943 : : fstp %%st(0);
3944 : : i.e., num_of_st fldz followed by num_of_st fstp to clear the stack
3945 : : mark stack slots empty.
3946 : :
3947 : : How to compute the num_of_st:
3948 : : There is no direct mapping from stack registers to hard register
3949 : : numbers. If one stack register needs to be cleared, we don't know
3950 : : where in the stack the value remains. So, if any stack register
3951 : : needs to be cleared, the whole stack should be cleared. However,
3952 : : x87 stack registers that hold the return value should be excluded.
3953 : : x87 returns in the top (two for complex values) register, so
3954 : : num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
3955 : : return the value of num_of_st. */
3956 : :
3957 : :
3958 : : static int
3959 : 130 : zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
3960 : : {
3961 : :
3962 : : /* If the FPU is disabled, no need to zero all st registers. */
3963 : 130 : if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
3964 : : return 0;
3965 : :
3966 : 10320 : unsigned int num_of_st = 0;
3967 : 10320 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
3968 : 10211 : if ((STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
3969 : 10211 : && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
3970 : : {
3971 : : num_of_st++;
3972 : : break;
3973 : : }
3974 : :
3975 : 129 : if (num_of_st == 0)
3976 : : return 0;
3977 : :
3978 : 20 : bool return_with_x87 = false;
3979 : 40 : return_with_x87 = (crtl->return_rtx
3980 : 20 : && (STACK_REG_P (crtl->return_rtx)));
3981 : :
3982 : 20 : bool complex_return = false;
3983 : 40 : complex_return = (crtl->return_rtx
3984 : 20 : && COMPLEX_MODE_P (GET_MODE (crtl->return_rtx)));
3985 : :
3986 : 20 : if (return_with_x87)
3987 : 2 : if (complex_return)
3988 : : num_of_st = 6;
3989 : : else
3990 : 1 : num_of_st = 7;
3991 : : else
3992 : : num_of_st = 8;
3993 : :
3994 : 20 : rtx st_reg = gen_rtx_REG (XFmode, FIRST_STACK_REG);
3995 : 177 : for (unsigned int i = 0; i < num_of_st; i++)
3996 : 157 : emit_insn (gen_rtx_SET (st_reg, CONST0_RTX (XFmode)));
3997 : :
3998 : 177 : for (unsigned int i = 0; i < num_of_st; i++)
3999 : : {
4000 : 157 : rtx insn;
4001 : 157 : insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
4002 : 157 : add_reg_note (insn, REG_DEAD, st_reg);
4003 : : }
4004 : 20 : return num_of_st;
4005 : : }
4006 : :
4007 : :
4008 : : /* When the routine exit in MMX mode, if any ST register needs
4009 : : to be zeroed, we should clear all MMX registers except the
4010 : : RET_MMX_REGNO that holds the return value. */
4011 : : static bool
4012 : 0 : zero_all_mm_registers (HARD_REG_SET need_zeroed_hardregs,
4013 : : unsigned int ret_mmx_regno)
4014 : : {
4015 : 0 : bool need_zero_all_mm = false;
4016 : 0 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4017 : 0 : if (STACK_REGNO_P (regno)
4018 : 0 : && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
4019 : : {
4020 : : need_zero_all_mm = true;
4021 : : break;
4022 : : }
4023 : :
4024 : 0 : if (!need_zero_all_mm)
4025 : : return false;
4026 : :
4027 : : machine_mode mode = V2SImode;
4028 : 0 : for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
4029 : 0 : if (regno != ret_mmx_regno)
4030 : : {
4031 : 0 : rtx reg = gen_rtx_REG (mode, regno);
4032 : 0 : emit_insn (gen_rtx_SET (reg, CONST0_RTX (mode)));
4033 : : }
4034 : : return true;
4035 : : }
4036 : :
4037 : : /* TARGET_ZERO_CALL_USED_REGS. */
4038 : : /* Generate a sequence of instructions that zero registers specified by
4039 : : NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
4040 : : zeroed. */
4041 : : static HARD_REG_SET
4042 : 130 : ix86_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
4043 : : {
4044 : 130 : HARD_REG_SET zeroed_hardregs;
4045 : 130 : bool all_sse_zeroed = false;
4046 : 130 : int all_st_zeroed_num = 0;
4047 : 130 : bool all_mm_zeroed = false;
4048 : :
4049 : 130 : CLEAR_HARD_REG_SET (zeroed_hardregs);
4050 : :
4051 : : /* first, let's see whether we can zero all vector registers together. */
4052 : 130 : rtx zero_all_vec_insn = zero_all_vector_registers (need_zeroed_hardregs);
4053 : 130 : if (zero_all_vec_insn)
4054 : : {
4055 : 3 : emit_insn (zero_all_vec_insn);
4056 : 3 : all_sse_zeroed = true;
4057 : : }
4058 : :
4059 : : /* mm/st registers are shared registers set, we should follow the following
4060 : : rules to clear them:
4061 : : MMX exit mode x87 exit mode
4062 : : -------------|----------------------|---------------
4063 : : uses x87 reg | clear all MMX | clear all x87
4064 : : uses MMX reg | clear individual MMX | clear all x87
4065 : : x87 + MMX | clear all MMX | clear all x87
4066 : :
4067 : : first, we should decide which mode (MMX mode or x87 mode) the function
4068 : : exit with. */
4069 : :
4070 : 130 : bool exit_with_mmx_mode = (crtl->return_rtx
4071 : 130 : && (MMX_REG_P (crtl->return_rtx)));
4072 : :
4073 : 130 : if (!exit_with_mmx_mode)
4074 : : /* x87 exit mode, we should zero all st registers together. */
4075 : : {
4076 : 130 : all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
4077 : :
4078 : 130 : if (all_st_zeroed_num > 0)
4079 : 180 : for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
4080 : : /* x87 stack registers that hold the return value should be excluded.
4081 : : x87 returns in the top (two for complex values) register. */
4082 : 160 : if (all_st_zeroed_num == 8
4083 : 160 : || !((all_st_zeroed_num >= 6 && regno == REGNO (crtl->return_rtx))
4084 : : || (all_st_zeroed_num == 6
4085 : 7 : && (regno == (REGNO (crtl->return_rtx) + 1)))))
4086 : 157 : SET_HARD_REG_BIT (zeroed_hardregs, regno);
4087 : : }
4088 : : else
4089 : : /* MMX exit mode, check whether we can zero all mm registers. */
4090 : : {
4091 : 0 : unsigned int exit_mmx_regno = REGNO (crtl->return_rtx);
4092 : 0 : all_mm_zeroed = zero_all_mm_registers (need_zeroed_hardregs,
4093 : : exit_mmx_regno);
4094 : 0 : if (all_mm_zeroed)
4095 : 0 : for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
4096 : 0 : if (regno != exit_mmx_regno)
4097 : 0 : SET_HARD_REG_BIT (zeroed_hardregs, regno);
4098 : : }
4099 : :
4100 : : /* Now, generate instructions to zero all the other registers. */
4101 : :
4102 : 12090 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4103 : : {
4104 : 11960 : if (!TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
4105 : 10664 : continue;
4106 : 1671 : if (!zero_call_used_regno_p (regno, all_sse_zeroed,
4107 : 1296 : exit_with_mmx_mode && !all_mm_zeroed))
4108 : 375 : continue;
4109 : :
4110 : 921 : SET_HARD_REG_BIT (zeroed_hardregs, regno);
4111 : :
4112 : 921 : machine_mode mode = zero_call_used_regno_mode (regno);
4113 : :
4114 : 921 : rtx reg = gen_rtx_REG (mode, regno);
4115 : 921 : rtx tmp = gen_rtx_SET (reg, CONST0_RTX (mode));
4116 : :
4117 : 921 : switch (mode)
4118 : : {
4119 : 533 : case E_SImode:
4120 : 533 : if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
4121 : : {
4122 : 533 : rtx clob = gen_rtx_CLOBBER (VOIDmode,
4123 : : gen_rtx_REG (CCmode,
4124 : : FLAGS_REG));
4125 : 533 : tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4126 : : tmp,
4127 : : clob));
4128 : : }
4129 : : /* FALLTHRU. */
4130 : :
4131 : 921 : case E_V4SFmode:
4132 : 921 : case E_HImode:
4133 : 921 : case E_V2SImode:
4134 : 921 : emit_insn (tmp);
4135 : 921 : break;
4136 : :
4137 : 0 : default:
4138 : 0 : gcc_unreachable ();
4139 : : }
4140 : : }
4141 : 130 : return zeroed_hardregs;
4142 : : }
4143 : :
4144 : : /* Define how to find the value returned by a function.
4145 : : VALTYPE is the data type of the value (as a tree).
4146 : : If the precise function being called is known, FUNC is its FUNCTION_DECL;
4147 : : otherwise, FUNC is 0. */
4148 : :
4149 : : static rtx
4150 : 3873015 : function_value_32 (machine_mode orig_mode, machine_mode mode,
4151 : : const_tree fntype, const_tree fn)
4152 : : {
4153 : 3873015 : unsigned int regno;
4154 : :
4155 : : /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
4156 : : we normally prevent this case when mmx is not available. However
4157 : : some ABIs may require the result to be returned like DImode. */
4158 : 4140492 : if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
4159 : : regno = FIRST_MMX_REG;
4160 : :
4161 : : /* 16-byte vector modes in %xmm0. See ix86_return_in_memory for where
4162 : : we prevent this case when sse is not available. However some ABIs
4163 : : may require the result to be returned like integer TImode. */
4164 : 3863775 : else if (mode == TImode
4165 : 4122012 : || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
4166 : : regno = FIRST_SSE_REG;
4167 : :
4168 : : /* 32-byte vector modes in %ymm0. */
4169 : 3904378 : else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
4170 : : regno = FIRST_SSE_REG;
4171 : :
4172 : : /* 64-byte vector modes in %zmm0. */
4173 : 3760620 : else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 64)
4174 : : regno = FIRST_SSE_REG;
4175 : :
4176 : : /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387). */
4177 : 3605538 : else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
4178 : : regno = FIRST_FLOAT_REG;
4179 : : else
4180 : : /* Most things go in %eax. */
4181 : 3543391 : regno = AX_REG;
4182 : :
4183 : : /* Return __bf16/ _Float16/_Complex _Foat16 by sse register. */
4184 : 3873015 : if (mode == HFmode || mode == BFmode)
4185 : : {
4186 : 1665 : if (!TARGET_SSE2)
4187 : : {
4188 : 0 : error ("SSE register return with SSE2 disabled");
4189 : 0 : regno = AX_REG;
4190 : : }
4191 : : else
4192 : : regno = FIRST_SSE_REG;
4193 : : }
4194 : :
4195 : 3873015 : if (mode == HCmode)
4196 : : {
4197 : 80 : if (!TARGET_SSE2)
4198 : 0 : error ("SSE register return with SSE2 disabled");
4199 : :
4200 : 80 : rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1));
4201 : 160 : XVECEXP (ret, 0, 0)
4202 : 160 : = gen_rtx_EXPR_LIST (VOIDmode,
4203 : : gen_rtx_REG (SImode,
4204 : 80 : TARGET_SSE2 ? FIRST_SSE_REG : AX_REG),
4205 : : GEN_INT (0));
4206 : 80 : return ret;
4207 : : }
4208 : :
4209 : : /* Override FP return register with %xmm0 for local functions when
4210 : : SSE math is enabled or for functions with sseregparm attribute. */
4211 : 3872935 : if ((fn || fntype) && (mode == SFmode || mode == DFmode))
4212 : : {
4213 : 48399 : int sse_level = ix86_function_sseregparm (fntype, fn, false);
4214 : 48399 : if (sse_level == -1)
4215 : : {
4216 : 0 : error ("calling %qD with SSE calling convention without "
4217 : : "SSE/SSE2 enabled", fn);
4218 : 0 : sorry ("this is a GCC bug that can be worked around by adding "
4219 : : "attribute used to function called");
4220 : : }
4221 : 48399 : else if ((sse_level >= 1 && mode == SFmode)
4222 : 48399 : || (sse_level == 2 && mode == DFmode))
4223 : : regno = FIRST_SSE_REG;
4224 : : }
4225 : :
4226 : : /* OImode shouldn't be used directly. */
4227 : 3872935 : gcc_assert (mode != OImode);
4228 : :
4229 : 3872935 : return gen_rtx_REG (orig_mode, regno);
4230 : : }
4231 : :
4232 : : static rtx
4233 : 91430279 : function_value_64 (machine_mode orig_mode, machine_mode mode,
4234 : : const_tree valtype)
4235 : : {
4236 : 91430279 : rtx ret;
4237 : :
4238 : : /* Handle libcalls, which don't provide a type node. */
4239 : 91430279 : if (valtype == NULL)
4240 : : {
4241 : 104807 : unsigned int regno;
4242 : :
4243 : 104807 : switch (mode)
4244 : : {
4245 : : case E_BFmode:
4246 : : case E_HFmode:
4247 : : case E_HCmode:
4248 : : case E_SFmode:
4249 : : case E_SCmode:
4250 : : case E_DFmode:
4251 : : case E_DCmode:
4252 : : case E_TFmode:
4253 : : case E_SDmode:
4254 : : case E_DDmode:
4255 : : case E_TDmode:
4256 : : regno = FIRST_SSE_REG;
4257 : : break;
4258 : 1035 : case E_XFmode:
4259 : 1035 : case E_XCmode:
4260 : 1035 : regno = FIRST_FLOAT_REG;
4261 : 1035 : break;
4262 : : case E_TCmode:
4263 : : return NULL;
4264 : 56860 : default:
4265 : 56860 : regno = AX_REG;
4266 : : }
4267 : :
4268 : 104807 : return gen_rtx_REG (mode, regno);
4269 : : }
4270 : 91325472 : else if (POINTER_TYPE_P (valtype))
4271 : : {
4272 : : /* Pointers are always returned in word_mode. */
4273 : 14418473 : mode = word_mode;
4274 : : }
4275 : :
4276 : 91325472 : ret = construct_container (mode, orig_mode, valtype, 1,
4277 : : X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
4278 : : x86_64_int_return_registers, 0);
4279 : :
4280 : : /* For zero sized structures, construct_container returns NULL, but we
4281 : : need to keep rest of compiler happy by returning meaningful value. */
4282 : 91325472 : if (!ret)
4283 : 196546 : ret = gen_rtx_REG (orig_mode, AX_REG);
4284 : :
4285 : : return ret;
4286 : : }
4287 : :
4288 : : static rtx
4289 : 0 : function_value_ms_32 (machine_mode orig_mode, machine_mode mode,
4290 : : const_tree fntype, const_tree fn, const_tree valtype)
4291 : : {
4292 : 0 : unsigned int regno;
4293 : :
4294 : : /* Floating point return values in %st(0)
4295 : : (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes). */
4296 : 0 : if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387
4297 : 0 : && (GET_MODE_SIZE (mode) > 8
4298 : 0 : || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype)))
4299 : : {
4300 : 0 : regno = FIRST_FLOAT_REG;
4301 : 0 : return gen_rtx_REG (orig_mode, regno);
4302 : : }
4303 : : else
4304 : 0 : return function_value_32(orig_mode, mode, fntype,fn);
4305 : : }
4306 : :
4307 : : static rtx
4308 : 762440 : function_value_ms_64 (machine_mode orig_mode, machine_mode mode,
4309 : : const_tree valtype)
4310 : : {
4311 : 762440 : unsigned int regno = AX_REG;
4312 : :
4313 : 762440 : if (TARGET_SSE)
4314 : : {
4315 : 1523426 : switch (GET_MODE_SIZE (mode))
4316 : : {
4317 : 13985 : case 16:
4318 : 13985 : if (valtype != NULL_TREE
4319 : 13985 : && !VECTOR_INTEGER_TYPE_P (valtype)
4320 : 7146 : && !VECTOR_INTEGER_TYPE_P (valtype)
4321 : 7146 : && !INTEGRAL_TYPE_P (valtype)
4322 : 21131 : && !VECTOR_FLOAT_TYPE_P (valtype))
4323 : : break;
4324 : 13985 : if ((SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
4325 : : && !COMPLEX_MODE_P (mode))
4326 : 197510 : regno = FIRST_SSE_REG;
4327 : : break;
4328 : 728054 : case 8:
4329 : 728054 : case 4:
4330 : 728054 : if (valtype != NULL_TREE && AGGREGATE_TYPE_P (valtype))
4331 : : break;
4332 : 713302 : if (mode == SFmode || mode == DFmode)
4333 : 197510 : regno = FIRST_SSE_REG;
4334 : : break;
4335 : : default:
4336 : : break;
4337 : : }
4338 : : }
4339 : 762440 : return gen_rtx_REG (orig_mode, regno);
4340 : : }
4341 : :
4342 : : static rtx
4343 : 96065734 : ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
4344 : : machine_mode orig_mode, machine_mode mode)
4345 : : {
4346 : 96065734 : const_tree fn, fntype;
4347 : :
4348 : 96065734 : fn = NULL_TREE;
4349 : 96065734 : if (fntype_or_decl && DECL_P (fntype_or_decl))
4350 : 3525863 : fn = fntype_or_decl;
4351 : 3525863 : fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
4352 : :
4353 : 96065734 : if (ix86_function_type_abi (fntype) == MS_ABI)
4354 : : {
4355 : 762440 : if (TARGET_64BIT)
4356 : 762440 : return function_value_ms_64 (orig_mode, mode, valtype);
4357 : : else
4358 : 0 : return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype);
4359 : : }
4360 : 95303294 : else if (TARGET_64BIT)
4361 : 91430279 : return function_value_64 (orig_mode, mode, valtype);
4362 : : else
4363 : 3873015 : return function_value_32 (orig_mode, mode, fntype, fn);
4364 : : }
4365 : :
4366 : : static rtx
4367 : 95957743 : ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
4368 : : {
4369 : 95957743 : machine_mode mode, orig_mode;
4370 : :
4371 : 95957743 : orig_mode = TYPE_MODE (valtype);
4372 : 95957743 : mode = type_natural_mode (valtype, NULL, true);
4373 : 95957743 : return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
4374 : : }
4375 : :
4376 : : /* Pointer function arguments and return values are promoted to
4377 : : word_mode for normal functions. */
4378 : :
4379 : : static machine_mode
4380 : 31857682 : ix86_promote_function_mode (const_tree type, machine_mode mode,
4381 : : int *punsignedp, const_tree fntype,
4382 : : int for_return)
4383 : : {
4384 : 31857682 : if (cfun->machine->func_type == TYPE_NORMAL
4385 : 31856689 : && type != NULL_TREE
4386 : 31823122 : && POINTER_TYPE_P (type))
4387 : : {
4388 : 16021990 : *punsignedp = POINTERS_EXTEND_UNSIGNED;
4389 : 16021990 : return word_mode;
4390 : : }
4391 : 15835692 : return default_promote_function_mode (type, mode, punsignedp, fntype,
4392 : 15835692 : for_return);
4393 : : }
4394 : :
4395 : : /* Return true if a structure, union or array with MODE containing FIELD
4396 : : should be accessed using BLKmode. */
4397 : :
4398 : : static bool
4399 : 123953249 : ix86_member_type_forces_blk (const_tree field, machine_mode mode)
4400 : : {
4401 : : /* Union with XFmode must be in BLKmode. */
4402 : 123953249 : return (mode == XFmode
4403 : 124090191 : && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
4404 : 123712 : || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
4405 : : }
4406 : :
4407 : : rtx
4408 : 107991 : ix86_libcall_value (machine_mode mode)
4409 : : {
4410 : 107991 : return ix86_function_value_1 (NULL, NULL, mode, mode);
4411 : : }
4412 : :
4413 : : /* Return true iff type is returned in memory. */
4414 : :
4415 : : static bool
4416 : 97284358 : ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
4417 : : {
4418 : 97284358 : const machine_mode mode = type_natural_mode (type, NULL, true);
4419 : 97284358 : HOST_WIDE_INT size;
4420 : :
4421 : 97284358 : if (TARGET_64BIT)
4422 : : {
4423 : 92826582 : if (ix86_function_type_abi (fntype) == MS_ABI)
4424 : : {
4425 : 702115 : size = int_size_in_bytes (type);
4426 : :
4427 : : /* __m128 is returned in xmm0. */
4428 : 702115 : if ((!type || VECTOR_INTEGER_TYPE_P (type)
4429 : 682622 : || INTEGRAL_TYPE_P (type)
4430 : 216890 : || VECTOR_FLOAT_TYPE_P (type))
4431 : 501053 : && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
4432 : : && !COMPLEX_MODE_P (mode)
4433 : 1203168 : && (GET_MODE_SIZE (mode) == 16 || size == 16))
4434 : : return false;
4435 : :
4436 : : /* Otherwise, the size must be exactly in [1248]. */
4437 : 1339972 : return size != 1 && size != 2 && size != 4 && size != 8;
4438 : : }
4439 : : else
4440 : : {
4441 : 92124467 : int needed_intregs, needed_sseregs;
4442 : :
4443 : 92124467 : return examine_argument (mode, type, 1,
4444 : : &needed_intregs, &needed_sseregs);
4445 : : }
4446 : : }
4447 : : else
4448 : : {
4449 : 4457776 : size = int_size_in_bytes (type);
4450 : :
4451 : : /* Intel MCU psABI returns scalars and aggregates no larger than 8
4452 : : bytes in registers. */
4453 : 4457776 : if (TARGET_IAMCU)
4454 : 0 : return VECTOR_MODE_P (mode) || size < 0 || size > 8;
4455 : :
4456 : 4457776 : if (mode == BLKmode)
4457 : : return true;
4458 : :
4459 : 4457776 : if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
4460 : : return false;
4461 : :
4462 : 4457776 : if (VECTOR_MODE_P (mode) || mode == TImode)
4463 : : {
4464 : : /* User-created vectors small enough to fit in EAX. */
4465 : 267449 : if (size < 8)
4466 : : return false;
4467 : :
4468 : : /* Unless ABI prescibes otherwise,
4469 : : MMX/3dNow values are returned in MM0 if available. */
4470 : :
4471 : 267449 : if (size == 8)
4472 : 9232 : return TARGET_VECT8_RETURNS || !TARGET_MMX;
4473 : :
4474 : : /* SSE values are returned in XMM0 if available. */
4475 : 258217 : if (size == 16)
4476 : 108807 : return !TARGET_SSE;
4477 : :
4478 : : /* AVX values are returned in YMM0 if available. */
4479 : 149410 : if (size == 32)
4480 : 71870 : return !TARGET_AVX;
4481 : :
4482 : : /* AVX512F values are returned in ZMM0 if available. */
4483 : 77540 : if (size == 64)
4484 : 77540 : return !TARGET_AVX512F;
4485 : : }
4486 : :
4487 : 4190327 : if (mode == XFmode)
4488 : : return false;
4489 : :
4490 : 4179161 : if (size > 12)
4491 : : return true;
4492 : :
4493 : : /* OImode shouldn't be used directly. */
4494 : 3224989 : gcc_assert (mode != OImode);
4495 : :
4496 : : return false;
4497 : : }
4498 : : }
4499 : :
4500 : : /* Implement TARGET_PUSH_ARGUMENT. */
4501 : :
4502 : : static bool
4503 : 9219585 : ix86_push_argument (unsigned int npush)
4504 : : {
4505 : : /* If SSE2 is available, use vector move to put large argument onto
4506 : : stack. NB: In 32-bit mode, use 8-byte vector move. */
4507 : 11621407 : return ((!TARGET_SSE2 || npush < (TARGET_64BIT ? 16 : 8))
4508 : 8955363 : && TARGET_PUSH_ARGS
4509 : 18174850 : && !ACCUMULATE_OUTGOING_ARGS);
4510 : : }
4511 : :
4512 : :
4513 : : /* Create the va_list data type. */
4514 : :
4515 : : static tree
4516 : 277293 : ix86_build_builtin_va_list_64 (void)
4517 : : {
4518 : 277293 : tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4519 : :
4520 : 277293 : record = lang_hooks.types.make_type (RECORD_TYPE);
4521 : 277293 : type_decl = build_decl (BUILTINS_LOCATION,
4522 : : TYPE_DECL, get_identifier ("__va_list_tag"), record);
4523 : :
4524 : 277293 : f_gpr = build_decl (BUILTINS_LOCATION,
4525 : : FIELD_DECL, get_identifier ("gp_offset"),
4526 : : unsigned_type_node);
4527 : 277293 : f_fpr = build_decl (BUILTINS_LOCATION,
4528 : : FIELD_DECL, get_identifier ("fp_offset"),
4529 : : unsigned_type_node);
4530 : 277293 : f_ovf = build_decl (BUILTINS_LOCATION,
4531 : : FIELD_DECL, get_identifier ("overflow_arg_area"),
4532 : : ptr_type_node);
4533 : 277293 : f_sav = build_decl (BUILTINS_LOCATION,
4534 : : FIELD_DECL, get_identifier ("reg_save_area"),
4535 : : ptr_type_node);
4536 : :
4537 : 277293 : va_list_gpr_counter_field = f_gpr;
4538 : 277293 : va_list_fpr_counter_field = f_fpr;
4539 : :
4540 : 277293 : DECL_FIELD_CONTEXT (f_gpr) = record;
4541 : 277293 : DECL_FIELD_CONTEXT (f_fpr) = record;
4542 : 277293 : DECL_FIELD_CONTEXT (f_ovf) = record;
4543 : 277293 : DECL_FIELD_CONTEXT (f_sav) = record;
4544 : :
4545 : 277293 : TYPE_STUB_DECL (record) = type_decl;
4546 : 277293 : TYPE_NAME (record) = type_decl;
4547 : 277293 : TYPE_FIELDS (record) = f_gpr;
4548 : 277293 : DECL_CHAIN (f_gpr) = f_fpr;
4549 : 277293 : DECL_CHAIN (f_fpr) = f_ovf;
4550 : 277293 : DECL_CHAIN (f_ovf) = f_sav;
4551 : :
4552 : 277293 : layout_type (record);
4553 : :
4554 : 277293 : TYPE_ATTRIBUTES (record) = tree_cons (get_identifier ("sysv_abi va_list"),
4555 : 277293 : NULL_TREE, TYPE_ATTRIBUTES (record));
4556 : :
4557 : : /* The correct type is an array type of one element. */
4558 : 277293 : return build_array_type (record, build_index_type (size_zero_node));
4559 : : }
4560 : :
4561 : : /* Setup the builtin va_list data type and for 64-bit the additional
4562 : : calling convention specific va_list data types. */
4563 : :
4564 : : static tree
4565 : 284378 : ix86_build_builtin_va_list (void)
4566 : : {
4567 : 284378 : if (TARGET_64BIT)
4568 : : {
4569 : : /* Initialize ABI specific va_list builtin types.
4570 : :
4571 : : In lto1, we can encounter two va_list types:
4572 : : - one as a result of the type-merge across TUs, and
4573 : : - the one constructed here.
4574 : : These two types will not have the same TYPE_MAIN_VARIANT, and therefore
4575 : : a type identity check in canonical_va_list_type based on
4576 : : TYPE_MAIN_VARIANT (which we used to have) will not work.
4577 : : Instead, we tag each va_list_type_node with its unique attribute, and
4578 : : look for the attribute in the type identity check in
4579 : : canonical_va_list_type.
4580 : :
4581 : : Tagging sysv_va_list_type_node directly with the attribute is
4582 : : problematic since it's a array of one record, which will degrade into a
4583 : : pointer to record when used as parameter (see build_va_arg comments for
4584 : : an example), dropping the attribute in the process. So we tag the
4585 : : record instead. */
4586 : :
4587 : : /* For SYSV_ABI we use an array of one record. */
4588 : 277293 : sysv_va_list_type_node = ix86_build_builtin_va_list_64 ();
4589 : :
4590 : : /* For MS_ABI we use plain pointer to argument area. */
4591 : 277293 : tree char_ptr_type = build_pointer_type (char_type_node);
4592 : 277293 : tree attr = tree_cons (get_identifier ("ms_abi va_list"), NULL_TREE,
4593 : 277293 : TYPE_ATTRIBUTES (char_ptr_type));
4594 : 277293 : ms_va_list_type_node = build_type_attribute_variant (char_ptr_type, attr);
4595 : :
4596 : 277293 : return ((ix86_abi == MS_ABI)
4597 : 277293 : ? ms_va_list_type_node
4598 : 277293 : : sysv_va_list_type_node);
4599 : : }
4600 : : else
4601 : : {
4602 : : /* For i386 we use plain pointer to argument area. */
4603 : 7085 : return build_pointer_type (char_type_node);
4604 : : }
4605 : : }
4606 : :
4607 : : /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
4608 : :
4609 : : static void
4610 : 15546 : setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
4611 : : {
4612 : 15546 : rtx save_area, mem;
4613 : 15546 : alias_set_type set;
4614 : 15546 : int i, max;
4615 : :
4616 : : /* GPR size of varargs save area. */
4617 : 15546 : if (cfun->va_list_gpr_size)
4618 : 15109 : ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
4619 : : else
4620 : 437 : ix86_varargs_gpr_size = 0;
4621 : :
4622 : : /* FPR size of varargs save area. We don't need it if we don't pass
4623 : : anything in SSE registers. */
4624 : 15546 : if (TARGET_SSE && cfun->va_list_fpr_size)
4625 : 14508 : ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
4626 : : else
4627 : 1038 : ix86_varargs_fpr_size = 0;
4628 : :
4629 : 15546 : if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
4630 : : return;
4631 : :
4632 : 15278 : save_area = frame_pointer_rtx;
4633 : 15278 : set = get_varargs_alias_set ();
4634 : :
4635 : 15278 : max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
4636 : 15278 : if (max > X86_64_REGPARM_MAX)
4637 : : max = X86_64_REGPARM_MAX;
4638 : :
4639 : 15278 : const int *parm_regs;
4640 : 15278 : if (cum->preserve_none_abi)
4641 : : parm_regs = x86_64_preserve_none_int_parameter_registers;
4642 : : else
4643 : 15277 : parm_regs = x86_64_int_parameter_registers;
4644 : :
4645 : 84751 : for (i = cum->regno; i < max; i++)
4646 : : {
4647 : 69473 : mem = gen_rtx_MEM (word_mode,
4648 : 69473 : plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
4649 : 69473 : MEM_NOTRAP_P (mem) = 1;
4650 : 69473 : set_mem_alias_set (mem, set);
4651 : 69473 : emit_move_insn (mem,
4652 : 69473 : gen_rtx_REG (word_mode, parm_regs[i]));
4653 : : }
4654 : :
4655 : 15278 : if (ix86_varargs_fpr_size)
4656 : : {
4657 : 14508 : machine_mode smode;
4658 : 14508 : rtx_code_label *label;
4659 : 14508 : rtx test;
4660 : :
4661 : : /* Now emit code to save SSE registers. The AX parameter contains number
4662 : : of SSE parameter registers used to call this function, though all we
4663 : : actually check here is the zero/non-zero status. */
4664 : :
4665 : 14508 : label = gen_label_rtx ();
4666 : 14508 : test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
4667 : 14508 : emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
4668 : : label));
4669 : :
4670 : : /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
4671 : : we used movdqa (i.e. TImode) instead? Perhaps even better would
4672 : : be if we could determine the real mode of the data, via a hook
4673 : : into pass_stdarg. Ignore all that for now. */
4674 : 14508 : smode = V4SFmode;
4675 : 14508 : if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
4676 : 4019 : crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
4677 : :
4678 : 14508 : max = cum->sse_regno + cfun->va_list_fpr_size / 16;
4679 : 14508 : if (max > X86_64_SSE_REGPARM_MAX)
4680 : : max = X86_64_SSE_REGPARM_MAX;
4681 : :
4682 : 128969 : for (i = cum->sse_regno; i < max; ++i)
4683 : : {
4684 : 114461 : mem = plus_constant (Pmode, save_area,
4685 : 114461 : i * 16 + ix86_varargs_gpr_size);
4686 : 114461 : mem = gen_rtx_MEM (smode, mem);
4687 : 114461 : MEM_NOTRAP_P (mem) = 1;
4688 : 114461 : set_mem_alias_set (mem, set);
4689 : 114461 : set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
4690 : :
4691 : 114461 : emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
4692 : : }
4693 : :
4694 : 14508 : emit_label (label);
4695 : : }
4696 : : }
4697 : :
4698 : : static void
4699 : 5652 : setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
4700 : : {
4701 : 5652 : alias_set_type set = get_varargs_alias_set ();
4702 : 5652 : int i;
4703 : :
4704 : : /* Reset to zero, as there might be a sysv vaarg used
4705 : : before. */
4706 : 5652 : ix86_varargs_gpr_size = 0;
4707 : 5652 : ix86_varargs_fpr_size = 0;
4708 : :
4709 : 14154 : for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
4710 : : {
4711 : 8502 : rtx reg, mem;
4712 : :
4713 : 8502 : mem = gen_rtx_MEM (Pmode,
4714 : 8502 : plus_constant (Pmode, virtual_incoming_args_rtx,
4715 : 8502 : i * UNITS_PER_WORD));
4716 : 8502 : MEM_NOTRAP_P (mem) = 1;
4717 : 8502 : set_mem_alias_set (mem, set);
4718 : :
4719 : 8502 : reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
4720 : 8502 : emit_move_insn (mem, reg);
4721 : : }
4722 : 5652 : }
4723 : :
4724 : : static void
4725 : 21344 : ix86_setup_incoming_varargs (cumulative_args_t cum_v,
4726 : : const function_arg_info &arg,
4727 : : int *, int no_rtl)
4728 : : {
4729 : 21344 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4730 : 21344 : CUMULATIVE_ARGS next_cum;
4731 : 21344 : tree fntype;
4732 : :
4733 : : /* This argument doesn't appear to be used anymore. Which is good,
4734 : : because the old code here didn't suppress rtl generation. */
4735 : 21344 : gcc_assert (!no_rtl);
4736 : :
4737 : 21344 : if (!TARGET_64BIT)
4738 : 146 : return;
4739 : :
4740 : 21198 : fntype = TREE_TYPE (current_function_decl);
4741 : :
4742 : : /* For varargs, we do not want to skip the dummy va_dcl argument.
4743 : : For stdargs, we do want to skip the last named argument. */
4744 : 21198 : next_cum = *cum;
4745 : 21198 : if ((!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
4746 : 77 : || arg.type != NULL_TREE)
4747 : 21210 : && stdarg_p (fntype))
4748 : 21133 : ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
4749 : :
4750 : 21198 : if (cum->call_abi == MS_ABI)
4751 : 5652 : setup_incoming_varargs_ms_64 (&next_cum);
4752 : : else
4753 : 15546 : setup_incoming_varargs_64 (&next_cum);
4754 : : }
4755 : :
4756 : : /* Checks if TYPE is of kind va_list char *. */
4757 : :
4758 : : static bool
4759 : 72768 : is_va_list_char_pointer (tree type)
4760 : : {
4761 : 72768 : tree canonic;
4762 : :
4763 : : /* For 32-bit it is always true. */
4764 : 72768 : if (!TARGET_64BIT)
4765 : : return true;
4766 : 72606 : canonic = ix86_canonical_va_list_type (type);
4767 : 72606 : return (canonic == ms_va_list_type_node
4768 : 72606 : || (ix86_abi == MS_ABI && canonic == va_list_type_node));
4769 : : }
4770 : :
4771 : : /* Implement va_start. */
4772 : :
4773 : : static void
4774 : 20860 : ix86_va_start (tree valist, rtx nextarg)
4775 : : {
4776 : 20860 : HOST_WIDE_INT words, n_gpr, n_fpr;
4777 : 20860 : tree f_gpr, f_fpr, f_ovf, f_sav;
4778 : 20860 : tree gpr, fpr, ovf, sav, t;
4779 : 20860 : tree type;
4780 : 20860 : rtx ovf_rtx;
4781 : :
4782 : 20860 : if (flag_split_stack
4783 : 12 : && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
4784 : : {
4785 : 12 : unsigned int scratch_regno;
4786 : :
4787 : : /* When we are splitting the stack, we can't refer to the stack
4788 : : arguments using internal_arg_pointer, because they may be on
4789 : : the old stack. The split stack prologue will arrange to
4790 : : leave a pointer to the old stack arguments in a scratch
4791 : : register, which we here copy to a pseudo-register. The split
4792 : : stack prologue can't set the pseudo-register directly because
4793 : : it (the prologue) runs before any registers have been saved. */
4794 : :
4795 : 12 : scratch_regno = split_stack_prologue_scratch_regno ();
4796 : 12 : if (scratch_regno != INVALID_REGNUM)
4797 : : {
4798 : 12 : rtx reg;
4799 : 12 : rtx_insn *seq;
4800 : :
4801 : 16 : reg = gen_reg_rtx (Pmode);
4802 : 12 : cfun->machine->split_stack_varargs_pointer = reg;
4803 : :
4804 : 12 : start_sequence ();
4805 : 16 : emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
4806 : 12 : seq = end_sequence ();
4807 : :
4808 : 12 : push_topmost_sequence ();
4809 : 12 : emit_insn_after (seq, entry_of_function ());
4810 : 12 : pop_topmost_sequence ();
4811 : : }
4812 : : }
4813 : :
4814 : : /* Only 64bit target needs something special. */
4815 : 20860 : if (is_va_list_char_pointer (TREE_TYPE (valist)))
4816 : : {
4817 : 5656 : if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
4818 : 5652 : std_expand_builtin_va_start (valist, nextarg);
4819 : : else
4820 : : {
4821 : 4 : rtx va_r, next;
4822 : :
4823 : 4 : va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4824 : 8 : next = expand_binop (ptr_mode, add_optab,
4825 : 4 : cfun->machine->split_stack_varargs_pointer,
4826 : : crtl->args.arg_offset_rtx,
4827 : : NULL_RTX, 0, OPTAB_LIB_WIDEN);
4828 : 4 : convert_move (va_r, next, 0);
4829 : : }
4830 : 5656 : return;
4831 : : }
4832 : :
4833 : 15204 : f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
4834 : 15204 : f_fpr = DECL_CHAIN (f_gpr);
4835 : 15204 : f_ovf = DECL_CHAIN (f_fpr);
4836 : 15204 : f_sav = DECL_CHAIN (f_ovf);
4837 : :
4838 : 15204 : valist = build_simple_mem_ref (valist);
4839 : 15204 : TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
4840 : : /* The following should be folded into the MEM_REF offset. */
4841 : 15204 : gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
4842 : : f_gpr, NULL_TREE);
4843 : 15204 : fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
4844 : : f_fpr, NULL_TREE);
4845 : 15204 : ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
4846 : : f_ovf, NULL_TREE);
4847 : 15204 : sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
4848 : : f_sav, NULL_TREE);
4849 : :
4850 : : /* Count number of gp and fp argument registers used. */
4851 : 15204 : words = crtl->args.info.words;
4852 : 15204 : n_gpr = crtl->args.info.regno;
4853 : 15204 : n_fpr = crtl->args.info.sse_regno;
4854 : :
4855 : 15204 : if (cfun->va_list_gpr_size)
4856 : : {
4857 : 14981 : type = TREE_TYPE (gpr);
4858 : 14981 : t = build2 (MODIFY_EXPR, type,
4859 : 14981 : gpr, build_int_cst (type, n_gpr * 8));
4860 : 14981 : TREE_SIDE_EFFECTS (t) = 1;
4861 : 14981 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4862 : : }
4863 : :
4864 : 15204 : if (TARGET_SSE && cfun->va_list_fpr_size)
4865 : : {
4866 : 14368 : type = TREE_TYPE (fpr);
4867 : 14368 : t = build2 (MODIFY_EXPR, type, fpr,
4868 : 14368 : build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
4869 : 14368 : TREE_SIDE_EFFECTS (t) = 1;
4870 : 14368 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4871 : : }
4872 : :
4873 : : /* Find the overflow area. */
4874 : 15204 : type = TREE_TYPE (ovf);
4875 : 15204 : if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
4876 : 15196 : ovf_rtx = crtl->args.internal_arg_pointer;
4877 : : else
4878 : : ovf_rtx = cfun->machine->split_stack_varargs_pointer;
4879 : 15204 : t = make_tree (type, ovf_rtx);
4880 : 15204 : if (words != 0)
4881 : 486 : t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
4882 : :
4883 : 15204 : t = build2 (MODIFY_EXPR, type, ovf, t);
4884 : 15204 : TREE_SIDE_EFFECTS (t) = 1;
4885 : 15204 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4886 : :
4887 : 15204 : if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
4888 : : {
4889 : : /* Find the register save area.
4890 : : Prologue of the function save it right above stack frame. */
4891 : 15150 : type = TREE_TYPE (sav);
4892 : 15150 : t = make_tree (type, frame_pointer_rtx);
4893 : 15150 : if (!ix86_varargs_gpr_size)
4894 : 169 : t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
4895 : :
4896 : 15150 : t = build2 (MODIFY_EXPR, type, sav, t);
4897 : 15150 : TREE_SIDE_EFFECTS (t) = 1;
4898 : 15150 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4899 : : }
4900 : : }
4901 : :
4902 : : /* Implement va_arg. */
4903 : :
4904 : : static tree
4905 : 51908 : ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
4906 : : gimple_seq *post_p)
4907 : : {
4908 : 51908 : static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
4909 : 51908 : tree f_gpr, f_fpr, f_ovf, f_sav;
4910 : 51908 : tree gpr, fpr, ovf, sav, t;
4911 : 51908 : int size, rsize;
4912 : 51908 : tree lab_false, lab_over = NULL_TREE;
4913 : 51908 : tree addr, t2;
4914 : 51908 : rtx container;
4915 : 51908 : int indirect_p = 0;
4916 : 51908 : tree ptrtype;
4917 : 51908 : machine_mode nat_mode;
4918 : 51908 : unsigned int arg_boundary;
4919 : 51908 : unsigned int type_align;
4920 : :
4921 : : /* Only 64bit target needs something special. */
4922 : 51908 : if (is_va_list_char_pointer (TREE_TYPE (valist)))
4923 : 260 : return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
4924 : :
4925 : 51648 : f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
4926 : 51648 : f_fpr = DECL_CHAIN (f_gpr);
4927 : 51648 : f_ovf = DECL_CHAIN (f_fpr);
4928 : 51648 : f_sav = DECL_CHAIN (f_ovf);
4929 : :
4930 : 51648 : gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
4931 : : valist, f_gpr, NULL_TREE);
4932 : :
4933 : 51648 : fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
4934 : 51648 : ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
4935 : 51648 : sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4936 : :
4937 : 51648 : indirect_p = pass_va_arg_by_reference (type);
4938 : 51648 : if (indirect_p)
4939 : 103 : type = build_pointer_type (type);
4940 : 51648 : size = arg_int_size_in_bytes (type);
4941 : 51648 : rsize = CEIL (size, UNITS_PER_WORD);
4942 : :
4943 : 51648 : nat_mode = type_natural_mode (type, NULL, false);
4944 : 51648 : switch (nat_mode)
4945 : : {
4946 : 28 : case E_V16HFmode:
4947 : 28 : case E_V16BFmode:
4948 : 28 : case E_V8SFmode:
4949 : 28 : case E_V8SImode:
4950 : 28 : case E_V32QImode:
4951 : 28 : case E_V16HImode:
4952 : 28 : case E_V4DFmode:
4953 : 28 : case E_V4DImode:
4954 : 28 : case E_V32HFmode:
4955 : 28 : case E_V32BFmode:
4956 : 28 : case E_V16SFmode:
4957 : 28 : case E_V16SImode:
4958 : 28 : case E_V64QImode:
4959 : 28 : case E_V32HImode:
4960 : 28 : case E_V8DFmode:
4961 : 28 : case E_V8DImode:
4962 : : /* Unnamed 256 and 512bit vector mode parameters are passed on stack. */
4963 : 28 : if (!TARGET_64BIT_MS_ABI)
4964 : : {
4965 : : container = NULL;
4966 : : break;
4967 : : }
4968 : : /* FALLTHRU */
4969 : :
4970 : 51620 : default:
4971 : 51620 : container = construct_container (nat_mode, TYPE_MODE (type),
4972 : : type, 0, X86_64_REGPARM_MAX,
4973 : : X86_64_SSE_REGPARM_MAX, intreg,
4974 : : 0);
4975 : 51620 : break;
4976 : : }
4977 : :
4978 : : /* Pull the value out of the saved registers. */
4979 : :
4980 : 51648 : addr = create_tmp_var (ptr_type_node, "addr");
4981 : 51648 : type_align = TYPE_ALIGN (type);
4982 : :
4983 : 51648 : if (container)
4984 : : {
4985 : 28557 : int needed_intregs, needed_sseregs;
4986 : 28557 : bool need_temp;
4987 : 28557 : tree int_addr, sse_addr;
4988 : :
4989 : 28557 : lab_false = create_artificial_label (UNKNOWN_LOCATION);
4990 : 28557 : lab_over = create_artificial_label (UNKNOWN_LOCATION);
4991 : :
4992 : 28557 : examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
4993 : :
4994 : 28557 : bool container_in_reg = false;
4995 : 28557 : if (REG_P (container))
4996 : : container_in_reg = true;
4997 : 1641 : else if (GET_CODE (container) == PARALLEL
4998 : 1641 : && GET_MODE (container) == BLKmode
4999 : 580 : && XVECLEN (container, 0) == 1)
5000 : : {
5001 : : /* Check if it is a PARALLEL BLKmode container of an EXPR_LIST
5002 : : expression in a TImode register. In this case, temp isn't
5003 : : needed. Otherwise, the TImode variable will be put in the
5004 : : GPR save area which guarantees only 8-byte alignment. */
5005 : 509 : rtx x = XVECEXP (container, 0, 0);
5006 : 509 : if (GET_CODE (x) == EXPR_LIST
5007 : 509 : && REG_P (XEXP (x, 0))
5008 : 509 : && XEXP (x, 1) == const0_rtx)
5009 : : container_in_reg = true;
5010 : : }
5011 : :
5012 : 680 : need_temp = (!container_in_reg
5013 : 1150 : && ((needed_intregs && TYPE_ALIGN (type) > 64)
5014 : 680 : || TYPE_ALIGN (type) > 128));
5015 : :
5016 : : /* In case we are passing structure, verify that it is consecutive block
5017 : : on the register save area. If not we need to do moves. */
5018 : 680 : if (!need_temp && !container_in_reg)
5019 : : {
5020 : : /* Verify that all registers are strictly consecutive */
5021 : 966 : if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
5022 : : {
5023 : : int i;
5024 : :
5025 : 815 : for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
5026 : : {
5027 : 529 : rtx slot = XVECEXP (container, 0, i);
5028 : 529 : if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
5029 : 529 : || INTVAL (XEXP (slot, 1)) != i * 16)
5030 : : need_temp = true;
5031 : : }
5032 : : }
5033 : : else
5034 : : {
5035 : : int i;
5036 : :
5037 : 1120 : for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
5038 : : {
5039 : 726 : rtx slot = XVECEXP (container, 0, i);
5040 : 726 : if (REGNO (XEXP (slot, 0)) != (unsigned int) i
5041 : 726 : || INTVAL (XEXP (slot, 1)) != i * 8)
5042 : : need_temp = true;
5043 : : }
5044 : : }
5045 : : }
5046 : 28557 : if (!need_temp)
5047 : : {
5048 : : int_addr = addr;
5049 : : sse_addr = addr;
5050 : : }
5051 : : else
5052 : : {
5053 : 877 : int_addr = create_tmp_var (ptr_type_node, "int_addr");
5054 : 877 : sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
5055 : : }
5056 : :
5057 : : /* First ensure that we fit completely in registers. */
5058 : 28557 : if (needed_intregs)
5059 : : {
5060 : 17893 : t = build_int_cst (TREE_TYPE (gpr),
5061 : 17893 : (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
5062 : 17893 : t = build2 (GE_EXPR, boolean_type_node, gpr, t);
5063 : 17893 : t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
5064 : 17893 : t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
5065 : 17893 : gimplify_and_add (t, pre_p);
5066 : : }
5067 : 28557 : if (needed_sseregs)
5068 : : {
5069 : 11056 : t = build_int_cst (TREE_TYPE (fpr),
5070 : : (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
5071 : 11056 : + X86_64_REGPARM_MAX * 8);
5072 : 11056 : t = build2 (GE_EXPR, boolean_type_node, fpr, t);
5073 : 11056 : t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
5074 : 11056 : t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
5075 : 11056 : gimplify_and_add (t, pre_p);
5076 : : }
5077 : :
5078 : : /* Compute index to start of area used for integer regs. */
5079 : 28557 : if (needed_intregs)
5080 : : {
5081 : : /* int_addr = gpr + sav; */
5082 : 17893 : t = fold_build_pointer_plus (sav, gpr);
5083 : 17893 : gimplify_assign (int_addr, t, pre_p);
5084 : : }
5085 : 28557 : if (needed_sseregs)
5086 : : {
5087 : : /* sse_addr = fpr + sav; */
5088 : 11056 : t = fold_build_pointer_plus (sav, fpr);
5089 : 11056 : gimplify_assign (sse_addr, t, pre_p);
5090 : : }
5091 : 28557 : if (need_temp)
5092 : : {
5093 : 877 : int i, prev_size = 0;
5094 : 877 : tree temp = create_tmp_var (type, "va_arg_tmp");
5095 : 877 : TREE_ADDRESSABLE (temp) = 1;
5096 : :
5097 : : /* addr = &temp; */
5098 : 877 : t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
5099 : 877 : gimplify_assign (addr, t, pre_p);
5100 : :
5101 : 2241 : for (i = 0; i < XVECLEN (container, 0); i++)
5102 : : {
5103 : 1364 : rtx slot = XVECEXP (container, 0, i);
5104 : 1364 : rtx reg = XEXP (slot, 0);
5105 : 1364 : machine_mode mode = GET_MODE (reg);
5106 : 1364 : tree piece_type;
5107 : 1364 : tree addr_type;
5108 : 1364 : tree daddr_type;
5109 : 1364 : tree src_addr, src;
5110 : 1364 : int src_offset;
5111 : 1364 : tree dest_addr, dest;
5112 : 1364 : int cur_size = GET_MODE_SIZE (mode);
5113 : :
5114 : 1364 : gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
5115 : 1364 : prev_size = INTVAL (XEXP (slot, 1));
5116 : 1364 : if (prev_size + cur_size > size)
5117 : : {
5118 : 30 : cur_size = size - prev_size;
5119 : 30 : unsigned int nbits = cur_size * BITS_PER_UNIT;
5120 : 30 : if (!int_mode_for_size (nbits, 1).exists (&mode))
5121 : 10 : mode = QImode;
5122 : : }
5123 : 1364 : piece_type = lang_hooks.types.type_for_mode (mode, 1);
5124 : 1364 : if (mode == GET_MODE (reg))
5125 : 1334 : addr_type = build_pointer_type (piece_type);
5126 : : else
5127 : 30 : addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
5128 : : true);
5129 : 1364 : daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
5130 : : true);
5131 : :
5132 : 1364 : if (SSE_REGNO_P (REGNO (reg)))
5133 : : {
5134 : 534 : src_addr = sse_addr;
5135 : 534 : src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
5136 : : }
5137 : : else
5138 : : {
5139 : 830 : src_addr = int_addr;
5140 : 830 : src_offset = REGNO (reg) * 8;
5141 : : }
5142 : 1364 : src_addr = fold_convert (addr_type, src_addr);
5143 : 1364 : src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
5144 : :
5145 : 1364 : dest_addr = fold_convert (daddr_type, addr);
5146 : 1364 : dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
5147 : 2728 : if (cur_size == GET_MODE_SIZE (mode))
5148 : : {
5149 : 1354 : src = build_va_arg_indirect_ref (src_addr);
5150 : 1354 : dest = build_va_arg_indirect_ref (dest_addr);
5151 : :
5152 : 1354 : gimplify_assign (dest, src, pre_p);
5153 : : }
5154 : : else
5155 : : {
5156 : 10 : tree copy
5157 : 20 : = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
5158 : : 3, dest_addr, src_addr,
5159 : 10 : size_int (cur_size));
5160 : 10 : gimplify_and_add (copy, pre_p);
5161 : : }
5162 : 1364 : prev_size += cur_size;
5163 : : }
5164 : : }
5165 : :
5166 : 28557 : if (needed_intregs)
5167 : : {
5168 : 17893 : t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
5169 : 17893 : build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
5170 : 17893 : gimplify_assign (gpr, t, pre_p);
5171 : : /* The GPR save area guarantees only 8-byte alignment. */
5172 : 17893 : if (!need_temp)
5173 : 17089 : type_align = MIN (type_align, 64);
5174 : : }
5175 : :
5176 : 28557 : if (needed_sseregs)
5177 : : {
5178 : 11056 : t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
5179 : 11056 : build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
5180 : 11056 : gimplify_assign (unshare_expr (fpr), t, pre_p);
5181 : : }
5182 : :
5183 : 28557 : gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
5184 : :
5185 : 28557 : gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
5186 : : }
5187 : :
5188 : : /* ... otherwise out of the overflow area. */
5189 : :
5190 : : /* When we align parameter on stack for caller, if the parameter
5191 : : alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
5192 : : aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
5193 : : here with caller. */
5194 : 51648 : arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
5195 : 51648 : if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
5196 : : arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
5197 : :
5198 : : /* Care for on-stack alignment if needed. */
5199 : 51648 : if (arg_boundary <= 64 || size == 0)
5200 : 34611 : t = ovf;
5201 : : else
5202 : : {
5203 : 17037 : HOST_WIDE_INT align = arg_boundary / 8;
5204 : 17037 : t = fold_build_pointer_plus_hwi (ovf, align - 1);
5205 : 17037 : t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
5206 : 17037 : build_int_cst (TREE_TYPE (t), -align));
5207 : : }
5208 : :
5209 : 51648 : gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
5210 : 51648 : gimplify_assign (addr, t, pre_p);
5211 : :
5212 : 51648 : t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
5213 : 51648 : gimplify_assign (unshare_expr (ovf), t, pre_p);
5214 : :
5215 : 51648 : if (container)
5216 : 28557 : gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
5217 : :
5218 : 51648 : type = build_aligned_type (type, type_align);
5219 : 51648 : ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
5220 : 51648 : addr = fold_convert (ptrtype, addr);
5221 : :
5222 : 51648 : if (indirect_p)
5223 : 103 : addr = build_va_arg_indirect_ref (addr);
5224 : 51648 : return build_va_arg_indirect_ref (addr);
5225 : : }
5226 : :
5227 : : /* Return true if OPNUM's MEM should be matched
5228 : : in movabs* patterns. */
5229 : :
5230 : : bool
5231 : 17944 : ix86_check_movabs (rtx insn, int opnum)
5232 : : {
5233 : 17944 : rtx set, mem;
5234 : :
5235 : 17944 : set = PATTERN (insn);
5236 : 17944 : if (GET_CODE (set) == PARALLEL)
5237 : 0 : set = XVECEXP (set, 0, 0);
5238 : 17944 : gcc_assert (GET_CODE (set) == SET);
5239 : 17944 : mem = XEXP (set, opnum);
5240 : 17944 : while (SUBREG_P (mem))
5241 : 0 : mem = SUBREG_REG (mem);
5242 : 17944 : gcc_assert (MEM_P (mem));
5243 : 17944 : return volatile_ok || !MEM_VOLATILE_P (mem);
5244 : : }
5245 : :
5246 : : /* Return true if XVECEXP idx of INSN satisfies MOVS arguments. */
5247 : : bool
5248 : 175407 : ix86_check_movs (rtx insn, int idx)
5249 : : {
5250 : 175407 : rtx pat = PATTERN (insn);
5251 : 175407 : gcc_assert (GET_CODE (pat) == PARALLEL);
5252 : :
5253 : 175407 : rtx set = XVECEXP (pat, 0, idx);
5254 : 175407 : gcc_assert (GET_CODE (set) == SET);
5255 : :
5256 : 175407 : rtx dst = SET_DEST (set);
5257 : 175407 : gcc_assert (MEM_P (dst));
5258 : :
5259 : 175407 : rtx src = SET_SRC (set);
5260 : 175407 : gcc_assert (MEM_P (src));
5261 : :
5262 : 175407 : return (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (dst))
5263 : 350814 : && (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (src))
5264 : 0 : || Pmode == word_mode));
5265 : : }
5266 : :
5267 : : /* Return false if INSN contains a MEM with a non-default address space. */
5268 : : bool
5269 : 66730 : ix86_check_no_addr_space (rtx insn)
5270 : : {
5271 : 66730 : subrtx_var_iterator::array_type array;
5272 : 1468476 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), ALL)
5273 : : {
5274 : 1401746 : rtx x = *iter;
5275 : 1535206 : if (MEM_P (x) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)))
5276 : 0 : return false;
5277 : : }
5278 : 66730 : return true;
5279 : 66730 : }
5280 : :
5281 : : /* Initialize the table of extra 80387 mathematical constants. */
5282 : :
5283 : : static void
5284 : 2429 : init_ext_80387_constants (void)
5285 : : {
5286 : 2429 : static const char * cst[5] =
5287 : : {
5288 : : "0.3010299956639811952256464283594894482", /* 0: fldlg2 */
5289 : : "0.6931471805599453094286904741849753009", /* 1: fldln2 */
5290 : : "1.4426950408889634073876517827983434472", /* 2: fldl2e */
5291 : : "3.3219280948873623478083405569094566090", /* 3: fldl2t */
5292 : : "3.1415926535897932385128089594061862044", /* 4: fldpi */
5293 : : };
5294 : 2429 : int i;
5295 : :
5296 : 14574 : for (i = 0; i < 5; i++)
5297 : : {
5298 : 12145 : real_from_string (&ext_80387_constants_table[i], cst[i]);
5299 : : /* Ensure each constant is rounded to XFmode precision. */
5300 : 12145 : real_convert (&ext_80387_constants_table[i],
5301 : 24290 : XFmode, &ext_80387_constants_table[i]);
5302 : : }
5303 : :
5304 : 2429 : ext_80387_constants_init = 1;
5305 : 2429 : }
5306 : :
5307 : : /* Return non-zero if the constant is something that
5308 : : can be loaded with a special instruction. */
5309 : :
5310 : : int
5311 : 5103927 : standard_80387_constant_p (rtx x)
5312 : : {
5313 : 5103927 : machine_mode mode = GET_MODE (x);
5314 : :
5315 : 5103927 : const REAL_VALUE_TYPE *r;
5316 : :
5317 : 5103927 : if (!(CONST_DOUBLE_P (x) && X87_FLOAT_MODE_P (mode)))
5318 : : return -1;
5319 : :
5320 : 4636198 : if (x == CONST0_RTX (mode))
5321 : : return 1;
5322 : 2110869 : if (x == CONST1_RTX (mode))
5323 : : return 2;
5324 : :
5325 : 1227293 : r = CONST_DOUBLE_REAL_VALUE (x);
5326 : :
5327 : : /* For XFmode constants, try to find a special 80387 instruction when
5328 : : optimizing for size or on those CPUs that benefit from them. */
5329 : 1227293 : if (mode == XFmode
5330 : 805078 : && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
5331 : 2032371 : && !flag_rounding_math)
5332 : : {
5333 : 797391 : int i;
5334 : :
5335 : 797391 : if (! ext_80387_constants_init)
5336 : 2422 : init_ext_80387_constants ();
5337 : :
5338 : 4773732 : for (i = 0; i < 5; i++)
5339 : 3985274 : if (real_identical (r, &ext_80387_constants_table[i]))
5340 : 8933 : return i + 3;
5341 : : }
5342 : :
5343 : : /* Load of the constant -0.0 or -1.0 will be split as
5344 : : fldz;fchs or fld1;fchs sequence. */
5345 : 1218360 : if (real_isnegzero (r))
5346 : : return 8;
5347 : 1202387 : if (real_identical (r, &dconstm1))
5348 : 300961 : return 9;
5349 : :
5350 : : return 0;
5351 : : }
5352 : :
5353 : : /* Return the opcode of the special instruction to be used to load
5354 : : the constant X. */
5355 : :
5356 : : const char *
5357 : 54947 : standard_80387_constant_opcode (rtx x)
5358 : : {
5359 : 54947 : switch (standard_80387_constant_p (x))
5360 : : {
5361 : : case 1:
5362 : : return "fldz";
5363 : 33962 : case 2:
5364 : 33962 : return "fld1";
5365 : 1 : case 3:
5366 : 1 : return "fldlg2";
5367 : 10 : case 4:
5368 : 10 : return "fldln2";
5369 : 12 : case 5:
5370 : 12 : return "fldl2e";
5371 : 2 : case 6:
5372 : 2 : return "fldl2t";
5373 : 192 : case 7:
5374 : 192 : return "fldpi";
5375 : 0 : case 8:
5376 : 0 : case 9:
5377 : 0 : return "#";
5378 : 0 : default:
5379 : 0 : gcc_unreachable ();
5380 : : }
5381 : : }
5382 : :
5383 : : /* Return the CONST_DOUBLE representing the 80387 constant that is
5384 : : loaded by the specified special instruction. The argument IDX
5385 : : matches the return value from standard_80387_constant_p. */
5386 : :
5387 : : rtx
5388 : 24 : standard_80387_constant_rtx (int idx)
5389 : : {
5390 : 24 : int i;
5391 : :
5392 : 24 : if (! ext_80387_constants_init)
5393 : 7 : init_ext_80387_constants ();
5394 : :
5395 : 24 : switch (idx)
5396 : : {
5397 : 24 : case 3:
5398 : 24 : case 4:
5399 : 24 : case 5:
5400 : 24 : case 6:
5401 : 24 : case 7:
5402 : 24 : i = idx - 3;
5403 : 24 : break;
5404 : :
5405 : 0 : default:
5406 : 0 : gcc_unreachable ();
5407 : : }
5408 : :
5409 : 24 : return const_double_from_real_value (ext_80387_constants_table[i],
5410 : 24 : XFmode);
5411 : : }
5412 : :
5413 : : /* Return 1 if X is all bits 0, 2 if X is all bits 1
5414 : : and 3 if X is all bits 1 with zero extend
5415 : : in supported SSE/AVX vector mode. */
5416 : :
5417 : : int
5418 : 51003800 : standard_sse_constant_p (rtx x, machine_mode pred_mode)
5419 : : {
5420 : 51003800 : machine_mode mode;
5421 : :
5422 : 51003800 : if (!TARGET_SSE)
5423 : : return 0;
5424 : :
5425 : 50838568 : mode = GET_MODE (x);
5426 : :
5427 : 50838568 : if (x == const0_rtx || const0_operand (x, mode))
5428 : 12172058 : return 1;
5429 : :
5430 : 38666510 : if (x == constm1_rtx
5431 : 38515461 : || vector_all_ones_operand (x, mode)
5432 : 76709916 : || ((GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
5433 : 31970872 : || GET_MODE_CLASS (pred_mode) == MODE_VECTOR_FLOAT)
5434 : 6072534 : && float_vector_all_ones_operand (x, mode)))
5435 : : {
5436 : : /* VOIDmode integer constant, get mode from the predicate. */
5437 : 625023 : if (mode == VOIDmode)
5438 : 151049 : mode = pred_mode;
5439 : :
5440 : 1250046 : switch (GET_MODE_SIZE (mode))
5441 : : {
5442 : 29261 : case 64:
5443 : 29261 : if (TARGET_AVX512F)
5444 : : return 2;
5445 : : break;
5446 : 38877 : case 32:
5447 : 38877 : if (TARGET_AVX2)
5448 : : return 2;
5449 : : break;
5450 : 545992 : case 16:
5451 : 545992 : if (TARGET_SSE2)
5452 : : return 2;
5453 : : break;
5454 : 0 : case 0:
5455 : : /* VOIDmode */
5456 : 0 : gcc_unreachable ();
5457 : : default:
5458 : : break;
5459 : : }
5460 : : }
5461 : :
5462 : 38053085 : if (vector_all_ones_zero_extend_half_operand (x, mode)
5463 : 38053085 : || vector_all_ones_zero_extend_quarter_operand (x, mode))
5464 : 686 : return 3;
5465 : :
5466 : : return 0;
5467 : : }
5468 : :
5469 : : /* Return the opcode of the special instruction to be used to load
5470 : : the constant operands[1] into operands[0]. */
5471 : :
5472 : : const char *
5473 : 453435 : standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
5474 : : {
5475 : 453435 : machine_mode mode;
5476 : 453435 : rtx x = operands[1];
5477 : :
5478 : 453435 : gcc_assert (TARGET_SSE);
5479 : :
5480 : 453435 : mode = GET_MODE (x);
5481 : :
5482 : 453435 : if (x == const0_rtx || const0_operand (x, mode))
5483 : : {
5484 : 442981 : switch (get_attr_mode (insn))
5485 : : {
5486 : 426054 : case MODE_TI:
5487 : 426054 : if (!EXT_REX_SSE_REG_P (operands[0]))
5488 : : return "%vpxor\t%0, %d0";
5489 : : /* FALLTHRU */
5490 : 5708 : case MODE_XI:
5491 : 5708 : case MODE_OI:
5492 : 5708 : if (EXT_REX_SSE_REG_P (operands[0]))
5493 : : {
5494 : 70 : if (TARGET_AVX512VL)
5495 : : return "vpxord\t%x0, %x0, %x0";
5496 : : else
5497 : 30 : return "vpxord\t%g0, %g0, %g0";
5498 : : }
5499 : : return "vpxor\t%x0, %x0, %x0";
5500 : :
5501 : 2067 : case MODE_V2DF:
5502 : 2067 : if (!EXT_REX_SSE_REG_P (operands[0]))
5503 : : return "%vxorpd\t%0, %d0";
5504 : : /* FALLTHRU */
5505 : 851 : case MODE_V8DF:
5506 : 851 : case MODE_V4DF:
5507 : 851 : if (EXT_REX_SSE_REG_P (operands[0]))
5508 : : {
5509 : 4 : if (TARGET_AVX512DQ)
5510 : : {
5511 : 0 : if (TARGET_AVX512VL)
5512 : : return "vxorpd\t%x0, %x0, %x0";
5513 : : else
5514 : 0 : return "vxorpd\t%g0, %g0, %g0";
5515 : : }
5516 : : else
5517 : : {
5518 : 4 : if (TARGET_AVX512VL)
5519 : : return "vpxorq\t%x0, %x0, %x0";
5520 : : else
5521 : 4 : return "vpxorq\t%g0, %g0, %g0";
5522 : : }
5523 : : }
5524 : : return "vxorpd\t%x0, %x0, %x0";
5525 : :
5526 : 6434 : case MODE_V4SF:
5527 : 6434 : if (!EXT_REX_SSE_REG_P (operands[0]))
5528 : : return "%vxorps\t%0, %d0";
5529 : : /* FALLTHRU */
5530 : 1894 : case MODE_V16SF:
5531 : 1894 : case MODE_V8SF:
5532 : 1894 : if (EXT_REX_SSE_REG_P (operands[0]))
5533 : : {
5534 : 30 : if (TARGET_AVX512DQ)
5535 : : {
5536 : 21 : if (TARGET_AVX512VL)
5537 : : return "vxorps\t%x0, %x0, %x0";
5538 : : else
5539 : 0 : return "vxorps\t%g0, %g0, %g0";
5540 : : }
5541 : : else
5542 : : {
5543 : 9 : if (TARGET_AVX512VL)
5544 : : return "vpxord\t%x0, %x0, %x0";
5545 : : else
5546 : 6 : return "vpxord\t%g0, %g0, %g0";
5547 : : }
5548 : : }
5549 : : return "vxorps\t%x0, %x0, %x0";
5550 : :
5551 : 0 : default:
5552 : 0 : gcc_unreachable ();
5553 : : }
5554 : : }
5555 : 10454 : else if (x == constm1_rtx
5556 : 10443 : || vector_all_ones_operand (x, mode)
5557 : 10521 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
5558 : 45 : && float_vector_all_ones_operand (x, mode)))
5559 : : {
5560 : 10432 : enum attr_mode insn_mode = get_attr_mode (insn);
5561 : :
5562 : 10432 : switch (insn_mode)
5563 : : {
5564 : 2 : case MODE_XI:
5565 : 2 : case MODE_V8DF:
5566 : 2 : case MODE_V16SF:
5567 : 2 : gcc_assert (TARGET_AVX512F);
5568 : : return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
5569 : :
5570 : 954 : case MODE_OI:
5571 : 954 : case MODE_V4DF:
5572 : 954 : case MODE_V8SF:
5573 : 954 : gcc_assert (TARGET_AVX2);
5574 : : /* FALLTHRU */
5575 : 10430 : case MODE_TI:
5576 : 10430 : case MODE_V2DF:
5577 : 10430 : case MODE_V4SF:
5578 : 10430 : gcc_assert (TARGET_SSE2);
5579 : 10430 : if (EXT_REX_SSE_REG_P (operands[0]))
5580 : : {
5581 : 2 : if (TARGET_AVX512VL)
5582 : : return "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}";
5583 : : else
5584 : 0 : return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
5585 : : }
5586 : 10428 : return (TARGET_AVX
5587 : 10428 : ? "vpcmpeqd\t%0, %0, %0"
5588 : 10428 : : "pcmpeqd\t%0, %0");
5589 : :
5590 : 0 : default:
5591 : 0 : gcc_unreachable ();
5592 : : }
5593 : : }
5594 : 22 : else if (vector_all_ones_zero_extend_half_operand (x, mode))
5595 : : {
5596 : 40 : if (GET_MODE_SIZE (mode) == 64)
5597 : : {
5598 : 5 : gcc_assert (TARGET_AVX512F);
5599 : : return "vpcmpeqd\t%t0, %t0, %t0";
5600 : : }
5601 : 30 : else if (GET_MODE_SIZE (mode) == 32)
5602 : : {
5603 : 15 : gcc_assert (TARGET_AVX);
5604 : : return "vpcmpeqd\t%x0, %x0, %x0";
5605 : : }
5606 : 0 : gcc_unreachable ();
5607 : : }
5608 : 2 : else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
5609 : : {
5610 : 2 : gcc_assert (TARGET_AVX512F);
5611 : : return "vpcmpeqd\t%x0, %x0, %x0";
5612 : : }
5613 : :
5614 : 0 : gcc_unreachable ();
5615 : : }
5616 : :
5617 : : /* Returns true if INSN can be transformed from a memory load
5618 : : to a supported FP constant load. */
5619 : :
5620 : : bool
5621 : 2215007 : ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
5622 : : {
5623 : 2215007 : rtx src = find_constant_src (insn);
5624 : :
5625 : 2215007 : gcc_assert (REG_P (dst));
5626 : :
5627 : 2215007 : if (src == NULL
5628 : 622669 : || (SSE_REGNO_P (REGNO (dst))
5629 : 489713 : && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
5630 : 166185 : || (!TARGET_AVX512VL
5631 : 166124 : && EXT_REX_SSE_REGNO_P (REGNO (dst))
5632 : 0 : && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
5633 : 2381192 : || (STACK_REGNO_P (REGNO (dst))
5634 : 132956 : && standard_80387_constant_p (src) < 1))
5635 : 2139212 : return false;
5636 : :
5637 : : return true;
5638 : : }
5639 : :
5640 : : /* Predicate for pre-reload splitters with associated instructions,
5641 : : which can match any time before the split1 pass (usually combine),
5642 : : then are unconditionally split in that pass and should not be
5643 : : matched again afterwards. */
5644 : :
5645 : : bool
5646 : 16872252 : ix86_pre_reload_split (void)
5647 : : {
5648 : 16872252 : return (can_create_pseudo_p ()
5649 : 25449129 : && !(cfun->curr_properties & PROP_rtl_split_insns));
5650 : : }
5651 : :
5652 : : /* Return the opcode of the TYPE_SSEMOV instruction. To move from
5653 : : or to xmm16-xmm31/ymm16-ymm31 registers, we either require
5654 : : TARGET_AVX512VL or it is a register to register move which can
5655 : : be done with zmm register move. */
5656 : :
5657 : : static const char *
5658 : 4088416 : ix86_get_ssemov (rtx *operands, unsigned size,
5659 : : enum attr_mode insn_mode, machine_mode mode)
5660 : : {
5661 : 4088416 : char buf[128];
5662 : 4088416 : bool misaligned_p = (misaligned_operand (operands[0], mode)
5663 : 4088416 : || misaligned_operand (operands[1], mode));
5664 : 4088416 : bool evex_reg_p = (size == 64
5665 : 4005722 : || EXT_REX_SSE_REG_P (operands[0])
5666 : 8093488 : || EXT_REX_SSE_REG_P (operands[1]));
5667 : :
5668 : 4088416 : bool egpr_p = (TARGET_APX_EGPR
5669 : 4088416 : && (x86_extended_rex2reg_mentioned_p (operands[0])
5670 : 179 : || x86_extended_rex2reg_mentioned_p (operands[1])));
5671 : 192 : bool egpr_vl = egpr_p && TARGET_AVX512VL;
5672 : :
5673 : 4088416 : machine_mode scalar_mode;
5674 : :
5675 : 4088416 : const char *opcode = NULL;
5676 : 4088416 : enum
5677 : : {
5678 : : opcode_int,
5679 : : opcode_float,
5680 : : opcode_double
5681 : 4088416 : } type = opcode_int;
5682 : :
5683 : 4088416 : switch (insn_mode)
5684 : : {
5685 : : case MODE_V16SF:
5686 : : case MODE_V8SF:
5687 : : case MODE_V4SF:
5688 : : scalar_mode = E_SFmode;
5689 : : type = opcode_float;
5690 : : break;
5691 : 207794 : case MODE_V8DF:
5692 : 207794 : case MODE_V4DF:
5693 : 207794 : case MODE_V2DF:
5694 : 207794 : scalar_mode = E_DFmode;
5695 : 207794 : type = opcode_double;
5696 : 207794 : break;
5697 : 1463253 : case MODE_XI:
5698 : 1463253 : case MODE_OI:
5699 : 1463253 : case MODE_TI:
5700 : 1463253 : scalar_mode = GET_MODE_INNER (mode);
5701 : : break;
5702 : 0 : default:
5703 : 0 : gcc_unreachable ();
5704 : : }
5705 : :
5706 : : /* NB: To move xmm16-xmm31/ymm16-ymm31 registers without AVX512VL,
5707 : : we can only use zmm register move without memory operand. */
5708 : 4088416 : if (evex_reg_p
5709 : 84220 : && !TARGET_AVX512VL
5710 : 4137240 : && GET_MODE_SIZE (mode) < 64)
5711 : : {
5712 : : /* NB: Even though ix86_hard_regno_mode_ok doesn't allow
5713 : : xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when
5714 : : AVX512VL is disabled, LRA can still generate reg to
5715 : : reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit
5716 : : modes. */
5717 : 0 : if (memory_operand (operands[0], mode)
5718 : 0 : || memory_operand (operands[1], mode))
5719 : 0 : gcc_unreachable ();
5720 : 0 : size = 64;
5721 : 0 : switch (type)
5722 : : {
5723 : 0 : case opcode_int:
5724 : 0 : if (scalar_mode == E_HFmode || scalar_mode == E_BFmode)
5725 : 0 : opcode = (misaligned_p
5726 : 0 : ? (TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64")
5727 : : : "vmovdqa64");
5728 : : else
5729 : 0 : opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
5730 : : break;
5731 : 0 : case opcode_float:
5732 : 0 : opcode = misaligned_p ? "vmovups" : "vmovaps";
5733 : : break;
5734 : 0 : case opcode_double:
5735 : 0 : opcode = misaligned_p ? "vmovupd" : "vmovapd";
5736 : : break;
5737 : : }
5738 : : }
5739 : 4088416 : else if (SCALAR_FLOAT_MODE_P (scalar_mode))
5740 : : {
5741 : 2804060 : switch (scalar_mode)
5742 : : {
5743 : 36029 : case E_HFmode:
5744 : 36029 : case E_BFmode:
5745 : 36029 : if (evex_reg_p || egpr_vl)
5746 : 11225 : opcode = (misaligned_p
5747 : 164 : ? (TARGET_AVX512BW
5748 : : ? "vmovdqu16"
5749 : : : "vmovdqu64")
5750 : : : "vmovdqa64");
5751 : 24804 : else if (egpr_p)
5752 : 756452 : opcode = (misaligned_p
5753 : 0 : ? (TARGET_AVX512BW
5754 : 0 : ? "vmovdqu16"
5755 : : : "%vmovups")
5756 : : : "%vmovaps");
5757 : : else
5758 : 389338 : opcode = (misaligned_p
5759 : 24804 : ? (TARGET_AVX512BW && evex_reg_p
5760 : : ? "vmovdqu16"
5761 : : : "%vmovdqu")
5762 : : : "%vmovdqa");
5763 : : break;
5764 : 2417369 : case E_SFmode:
5765 : 2417369 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5766 : : break;
5767 : 207794 : case E_DFmode:
5768 : 207794 : opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
5769 : : break;
5770 : 142868 : case E_TFmode:
5771 : 142868 : if (evex_reg_p || egpr_vl)
5772 : 14 : opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
5773 : 142854 : else if (egpr_p)
5774 : 0 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5775 : : else
5776 : 142854 : opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
5777 : : break;
5778 : 0 : default:
5779 : 0 : gcc_unreachable ();
5780 : : }
5781 : : }
5782 : 1284356 : else if (SCALAR_INT_MODE_P (scalar_mode))
5783 : : {
5784 : 1284356 : switch (scalar_mode)
5785 : : {
5786 : 81816 : case E_QImode:
5787 : 81816 : if (evex_reg_p || egpr_vl)
5788 : 4096732 : opcode = (misaligned_p
5789 : 8316 : ? (TARGET_AVX512BW
5790 : 4756 : ? "vmovdqu8"
5791 : : : "vmovdqu64")
5792 : : : "vmovdqa64");
5793 : 73500 : else if (egpr_p)
5794 : 30 : opcode = (misaligned_p
5795 : 0 : ? (TARGET_AVX512BW
5796 : : ? "vmovdqu8"
5797 : : : "%vmovups")
5798 : : : "%vmovaps");
5799 : : else
5800 : 73470 : opcode = (misaligned_p
5801 : : ? (TARGET_AVX512BW && evex_reg_p
5802 : : ? "vmovdqu8"
5803 : : : "%vmovdqu")
5804 : : : "%vmovdqa");
5805 : : break;
5806 : 40355 : case E_HImode:
5807 : 40355 : if (evex_reg_p || egpr_vl)
5808 : 3354 : opcode = (misaligned_p
5809 : 175 : ? (TARGET_AVX512BW
5810 : : ? "vmovdqu16"
5811 : : : "vmovdqu64")
5812 : : : "vmovdqa64");
5813 : 37001 : else if (egpr_p)
5814 : 756452 : opcode = (misaligned_p
5815 : 27 : ? (TARGET_AVX512BW
5816 : 0 : ? "vmovdqu16"
5817 : : : "%vmovups")
5818 : : : "%vmovaps");
5819 : : else
5820 : 364534 : opcode = (misaligned_p
5821 : 36974 : ? (TARGET_AVX512BW && evex_reg_p
5822 : : ? "vmovdqu16"
5823 : : : "%vmovdqu")
5824 : : : "%vmovdqa");
5825 : : break;
5826 : 175135 : case E_SImode:
5827 : 175135 : if (evex_reg_p || egpr_vl)
5828 : 7845 : opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
5829 : 167290 : else if (egpr_p)
5830 : 14 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5831 : : else
5832 : 167276 : opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
5833 : : break;
5834 : 976007 : case E_DImode:
5835 : 976007 : case E_TImode:
5836 : 976007 : case E_OImode:
5837 : 976007 : if (evex_reg_p || egpr_vl)
5838 : 18292 : opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
5839 : 957715 : else if (egpr_p)
5840 : 26 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5841 : : else
5842 : 957689 : opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
5843 : : break;
5844 : 11043 : case E_XImode:
5845 : 46341 : opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
5846 : : break;
5847 : 0 : default:
5848 : 0 : gcc_unreachable ();
5849 : : }
5850 : : }
5851 : : else
5852 : 0 : gcc_unreachable ();
5853 : :
5854 : 4088416 : switch (size)
5855 : : {
5856 : 82694 : case 64:
5857 : 82694 : snprintf (buf, sizeof (buf), "%s\t{%%g1, %%g0|%%g0, %%g1}",
5858 : : opcode);
5859 : 82694 : break;
5860 : 88930 : case 32:
5861 : 88930 : snprintf (buf, sizeof (buf), "%s\t{%%t1, %%t0|%%t0, %%t1}",
5862 : : opcode);
5863 : 88930 : break;
5864 : 3916792 : case 16:
5865 : 3916792 : snprintf (buf, sizeof (buf), "%s\t{%%x1, %%x0|%%x0, %%x1}",
5866 : : opcode);
5867 : 3916792 : break;
5868 : 0 : default:
5869 : 0 : gcc_unreachable ();
5870 : : }
5871 : 4088416 : output_asm_insn (buf, operands);
5872 : 4088416 : return "";
5873 : : }
5874 : :
5875 : : /* Return the template of the TYPE_SSEMOV instruction to move
5876 : : operands[1] into operands[0]. */
5877 : :
5878 : : const char *
5879 : 6487317 : ix86_output_ssemov (rtx_insn *insn, rtx *operands)
5880 : : {
5881 : 6487317 : machine_mode mode = GET_MODE (operands[0]);
5882 : 6487317 : if (get_attr_type (insn) != TYPE_SSEMOV
5883 : 6487317 : || mode != GET_MODE (operands[1]))
5884 : 0 : gcc_unreachable ();
5885 : :
5886 : 6487317 : enum attr_mode insn_mode = get_attr_mode (insn);
5887 : :
5888 : 6487317 : switch (insn_mode)
5889 : : {
5890 : 82694 : case MODE_XI:
5891 : 82694 : case MODE_V8DF:
5892 : 82694 : case MODE_V16SF:
5893 : 82694 : return ix86_get_ssemov (operands, 64, insn_mode, mode);
5894 : :
5895 : 88930 : case MODE_OI:
5896 : 88930 : case MODE_V4DF:
5897 : 88930 : case MODE_V8SF:
5898 : 88930 : return ix86_get_ssemov (operands, 32, insn_mode, mode);
5899 : :
5900 : 3916792 : case MODE_TI:
5901 : 3916792 : case MODE_V2DF:
5902 : 3916792 : case MODE_V4SF:
5903 : 3916792 : return ix86_get_ssemov (operands, 16, insn_mode, mode);
5904 : :
5905 : 659571 : case MODE_DI:
5906 : : /* Handle broken assemblers that require movd instead of movq. */
5907 : 659571 : if (GENERAL_REG_P (operands[0]))
5908 : : {
5909 : : if (HAVE_AS_IX86_INTERUNIT_MOVQ)
5910 : : return "%vmovq\t{%1, %q0|%q0, %1}";
5911 : : else
5912 : : return "%vmovd\t{%1, %q0|%q0, %1}";
5913 : : }
5914 : 585680 : else if (GENERAL_REG_P (operands[1]))
5915 : : {
5916 : : if (HAVE_AS_IX86_INTERUNIT_MOVQ)
5917 : : return "%vmovq\t{%q1, %0|%0, %q1}";
5918 : : else
5919 : : return "%vmovd\t{%q1, %0|%0, %q1}";
5920 : : }
5921 : : else
5922 : 424299 : return "%vmovq\t{%1, %0|%0, %1}";
5923 : :
5924 : 198495 : case MODE_SI:
5925 : 198495 : if (GENERAL_REG_P (operands[0]))
5926 : : return "%vmovd\t{%1, %k0|%k0, %1}";
5927 : 143249 : else if (GENERAL_REG_P (operands[1]))
5928 : : return "%vmovd\t{%k1, %0|%0, %k1}";
5929 : : else
5930 : 61549 : return "%vmovd\t{%1, %0|%0, %1}";
5931 : :
5932 : 53393 : case MODE_HI:
5933 : 53393 : if (GENERAL_REG_P (operands[0]))
5934 : : return "vmovw\t{%1, %k0|%k0, %1}";
5935 : 53359 : else if (GENERAL_REG_P (operands[1]))
5936 : : return "vmovw\t{%k1, %0|%0, %k1}";
5937 : : else
5938 : 53272 : return "vmovw\t{%1, %0|%0, %1}";
5939 : :
5940 : 786722 : case MODE_DF:
5941 : 786722 : if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
5942 : : return "vmovsd\t{%d1, %0|%0, %d1}";
5943 : : else
5944 : 785694 : return "%vmovsd\t{%1, %0|%0, %1}";
5945 : :
5946 : 696959 : case MODE_SF:
5947 : 696959 : if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
5948 : : return "vmovss\t{%d1, %0|%0, %d1}";
5949 : : else
5950 : 696173 : return "%vmovss\t{%1, %0|%0, %1}";
5951 : :
5952 : 96 : case MODE_HF:
5953 : 96 : case MODE_BF:
5954 : 96 : if (REG_P (operands[0]) && REG_P (operands[1]))
5955 : : return "vmovsh\t{%d1, %0|%0, %d1}";
5956 : : else
5957 : 0 : return "vmovsh\t{%1, %0|%0, %1}";
5958 : :
5959 : 36 : case MODE_V1DF:
5960 : 36 : gcc_assert (!TARGET_AVX);
5961 : : return "movlpd\t{%1, %0|%0, %1}";
5962 : :
5963 : 3629 : case MODE_V2SF:
5964 : 3629 : if (TARGET_AVX && REG_P (operands[0]))
5965 : : return "vmovlps\t{%1, %d0|%d0, %1}";
5966 : : else
5967 : 3549 : return "%vmovlps\t{%1, %0|%0, %1}";
5968 : :
5969 : 0 : default:
5970 : 0 : gcc_unreachable ();
5971 : : }
5972 : : }
5973 : :
5974 : : /* Returns true if OP contains a symbol reference */
5975 : :
5976 : : bool
5977 : 560402514 : symbolic_reference_mentioned_p (rtx op)
5978 : : {
5979 : 560402514 : const char *fmt;
5980 : 560402514 : int i;
5981 : :
5982 : 560402514 : if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5983 : : return true;
5984 : :
5985 : 423750734 : fmt = GET_RTX_FORMAT (GET_CODE (op));
5986 : 719541538 : for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5987 : : {
5988 : 573931339 : if (fmt[i] == 'E')
5989 : : {
5990 : 1973079 : int j;
5991 : :
5992 : 3936707 : for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5993 : 3251823 : if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5994 : : return true;
5995 : : }
5996 : :
5997 : 571958260 : else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5998 : : return true;
5999 : : }
6000 : :
6001 : : return false;
6002 : : }
6003 : :
6004 : : /* Return true if it is appropriate to emit `ret' instructions in the
6005 : : body of a function. Do this only if the epilogue is simple, needing a
6006 : : couple of insns. Prior to reloading, we can't tell how many registers
6007 : : must be saved, so return false then. Return false if there is no frame
6008 : : marker to de-allocate. */
6009 : :
6010 : : bool
6011 : 0 : ix86_can_use_return_insn_p (void)
6012 : : {
6013 : 0 : if (ix86_function_ms_hook_prologue (current_function_decl))
6014 : : return false;
6015 : :
6016 : 0 : if (ix86_function_naked (current_function_decl))
6017 : : return false;
6018 : :
6019 : : /* Don't use `ret' instruction in interrupt handler. */
6020 : 0 : if (! reload_completed
6021 : 0 : || frame_pointer_needed
6022 : 0 : || cfun->machine->func_type != TYPE_NORMAL)
6023 : : return 0;
6024 : :
6025 : : /* Don't allow more than 32k pop, since that's all we can do
6026 : : with one instruction. */
6027 : 0 : if (crtl->args.pops_args && crtl->args.size >= 32768)
6028 : : return 0;
6029 : :
6030 : 0 : struct ix86_frame &frame = cfun->machine->frame;
6031 : 0 : return (frame.stack_pointer_offset == UNITS_PER_WORD
6032 : 0 : && (frame.nregs + frame.nsseregs) == 0);
6033 : : }
6034 : :
6035 : : /* Return stack frame size. get_frame_size () returns used stack slots
6036 : : during compilation, which may be optimized out later. If stack frame
6037 : : is needed, stack_frame_required should be true. */
6038 : :
6039 : : static HOST_WIDE_INT
6040 : 8080650 : ix86_get_frame_size (void)
6041 : : {
6042 : 8080650 : if (cfun->machine->stack_frame_required)
6043 : 8013865 : return get_frame_size ();
6044 : : else
6045 : : return 0;
6046 : : }
6047 : :
6048 : : /* Value should be nonzero if functions must have frame pointers.
6049 : : Zero means the frame pointer need not be set up (and parms may
6050 : : be accessed via the stack pointer) in functions that seem suitable. */
6051 : :
6052 : : static bool
6053 : 1208547 : ix86_frame_pointer_required (void)
6054 : : {
6055 : : /* If we accessed previous frames, then the generated code expects
6056 : : to be able to access the saved ebp value in our frame. */
6057 : 1208547 : if (cfun->machine->accesses_prev_frame)
6058 : : return true;
6059 : :
6060 : : /* Several x86 os'es need a frame pointer for other reasons,
6061 : : usually pertaining to setjmp. */
6062 : 1208514 : if (SUBTARGET_FRAME_POINTER_REQUIRED)
6063 : : return true;
6064 : :
6065 : : /* For older 32-bit runtimes setjmp requires valid frame-pointer. */
6066 : 1208514 : if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
6067 : : return true;
6068 : :
6069 : : /* Win64 SEH, very large frames need a frame-pointer as maximum stack
6070 : : allocation is 4GB. */
6071 : 1208514 : if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
6072 : : return true;
6073 : :
6074 : : /* SSE saves require frame-pointer when stack is misaligned. */
6075 : 1208514 : if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
6076 : : return true;
6077 : :
6078 : : /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
6079 : : turns off the frame pointer by default. Turn it back on now if
6080 : : we've not got a leaf function. */
6081 : 1208513 : if (TARGET_OMIT_LEAF_FRAME_POINTER
6082 : 1208513 : && (!crtl->is_leaf
6083 : 0 : || ix86_current_function_calls_tls_descriptor))
6084 : 0 : return true;
6085 : :
6086 : : /* Several versions of mcount for the x86 assumes that there is a
6087 : : frame, so we cannot allow profiling without a frame pointer. */
6088 : 1208513 : if (crtl->profile && !flag_fentry)
6089 : : return true;
6090 : :
6091 : : return false;
6092 : : }
6093 : :
6094 : : /* Record that the current function accesses previous call frames. */
6095 : :
6096 : : void
6097 : 966 : ix86_setup_frame_addresses (void)
6098 : : {
6099 : 966 : cfun->machine->accesses_prev_frame = 1;
6100 : 966 : }
6101 : :
6102 : : #if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
6103 : : # define USE_HIDDEN_LINKONCE 1
6104 : : #else
6105 : : # define USE_HIDDEN_LINKONCE 0
6106 : : #endif
6107 : :
6108 : : /* Label count for call and return thunks. It is used to make unique
6109 : : labels in call and return thunks. */
6110 : : static int indirectlabelno;
6111 : :
6112 : : /* True if call thunk function is needed. */
6113 : : static bool indirect_thunk_needed = false;
6114 : :
6115 : : /* Bit masks of integer registers, which contain branch target, used
6116 : : by call thunk functions. */
6117 : : static HARD_REG_SET indirect_thunks_used;
6118 : :
6119 : : /* True if return thunk function is needed. */
6120 : : static bool indirect_return_needed = false;
6121 : :
6122 : : /* True if return thunk function via CX is needed. */
6123 : : static bool indirect_return_via_cx;
6124 : :
6125 : : #ifndef INDIRECT_LABEL
6126 : : # define INDIRECT_LABEL "LIND"
6127 : : #endif
6128 : :
6129 : : /* Indicate what prefix is needed for an indirect branch. */
6130 : : enum indirect_thunk_prefix
6131 : : {
6132 : : indirect_thunk_prefix_none,
6133 : : indirect_thunk_prefix_nt
6134 : : };
6135 : :
6136 : : /* Return the prefix needed for an indirect branch INSN. */
6137 : :
6138 : : enum indirect_thunk_prefix
6139 : 67 : indirect_thunk_need_prefix (rtx_insn *insn)
6140 : : {
6141 : 67 : enum indirect_thunk_prefix need_prefix;
6142 : 67 : if ((cfun->machine->indirect_branch_type
6143 : 67 : == indirect_branch_thunk_extern)
6144 : 67 : && ix86_notrack_prefixed_insn_p (insn))
6145 : : {
6146 : : /* NOTRACK prefix is only used with external thunk so that it
6147 : : can be properly updated to support CET at run-time. */
6148 : : need_prefix = indirect_thunk_prefix_nt;
6149 : : }
6150 : : else
6151 : : need_prefix = indirect_thunk_prefix_none;
6152 : 67 : return need_prefix;
6153 : : }
6154 : :
6155 : : /* Fills in the label name that should be used for the indirect thunk. */
6156 : :
6157 : : static void
6158 : 73 : indirect_thunk_name (char name[32], unsigned int regno,
6159 : : enum indirect_thunk_prefix need_prefix,
6160 : : bool ret_p)
6161 : : {
6162 : 73 : if (regno != INVALID_REGNUM && regno != CX_REG && ret_p)
6163 : 0 : gcc_unreachable ();
6164 : :
6165 : 73 : if (USE_HIDDEN_LINKONCE)
6166 : : {
6167 : 73 : const char *prefix;
6168 : :
6169 : 73 : if (need_prefix == indirect_thunk_prefix_nt
6170 : 73 : && regno != INVALID_REGNUM)
6171 : : {
6172 : : /* NOTRACK prefix is only used with external thunk via
6173 : : register so that NOTRACK prefix can be added to indirect
6174 : : branch via register to support CET at run-time. */
6175 : : prefix = "_nt";
6176 : : }
6177 : : else
6178 : 71 : prefix = "";
6179 : :
6180 : 73 : const char *ret = ret_p ? "return" : "indirect";
6181 : :
6182 : 73 : if (regno != INVALID_REGNUM)
6183 : : {
6184 : 55 : const char *reg_prefix;
6185 : 55 : if (LEGACY_INT_REGNO_P (regno))
6186 : 53 : reg_prefix = TARGET_64BIT ? "r" : "e";
6187 : : else
6188 : : reg_prefix = "";
6189 : 55 : sprintf (name, "__x86_%s_thunk%s_%s%s",
6190 : : ret, prefix, reg_prefix, reg_names[regno]);
6191 : : }
6192 : : else
6193 : 18 : sprintf (name, "__x86_%s_thunk%s", ret, prefix);
6194 : : }
6195 : : else
6196 : : {
6197 : : if (regno != INVALID_REGNUM)
6198 : : ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
6199 : : else
6200 : : {
6201 : : if (ret_p)
6202 : : ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
6203 : : else
6204 : 73 : ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
6205 : : }
6206 : : }
6207 : 73 : }
6208 : :
6209 : : /* Output a call and return thunk for indirect branch. If REGNO != -1,
6210 : : the function address is in REGNO and the call and return thunk looks like:
6211 : :
6212 : : call L2
6213 : : L1:
6214 : : pause
6215 : : lfence
6216 : : jmp L1
6217 : : L2:
6218 : : mov %REG, (%sp)
6219 : : ret
6220 : :
6221 : : Otherwise, the function address is on the top of stack and the
6222 : : call and return thunk looks like:
6223 : :
6224 : : call L2
6225 : : L1:
6226 : : pause
6227 : : lfence
6228 : : jmp L1
6229 : : L2:
6230 : : lea WORD_SIZE(%sp), %sp
6231 : : ret
6232 : : */
6233 : :
6234 : : static void
6235 : 38 : output_indirect_thunk (unsigned int regno)
6236 : : {
6237 : 38 : char indirectlabel1[32];
6238 : 38 : char indirectlabel2[32];
6239 : :
6240 : 38 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
6241 : : indirectlabelno++);
6242 : 38 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
6243 : : indirectlabelno++);
6244 : :
6245 : : /* Call */
6246 : 38 : fputs ("\tcall\t", asm_out_file);
6247 : 38 : assemble_name_raw (asm_out_file, indirectlabel2);
6248 : 38 : fputc ('\n', asm_out_file);
6249 : :
6250 : 38 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
6251 : :
6252 : : /* AMD and Intel CPUs prefer each a different instruction as loop filler.
6253 : : Usage of both pause + lfence is compromise solution. */
6254 : 38 : fprintf (asm_out_file, "\tpause\n\tlfence\n");
6255 : :
6256 : : /* Jump. */
6257 : 38 : fputs ("\tjmp\t", asm_out_file);
6258 : 38 : assemble_name_raw (asm_out_file, indirectlabel1);
6259 : 38 : fputc ('\n', asm_out_file);
6260 : :
6261 : 38 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
6262 : :
6263 : : /* The above call insn pushed a word to stack. Adjust CFI info. */
6264 : 38 : if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
6265 : : {
6266 : 38 : if (! dwarf2out_do_cfi_asm ())
6267 : : {
6268 : 0 : dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
6269 : 0 : xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
6270 : 0 : xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
6271 : 0 : vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
6272 : : }
6273 : 38 : dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
6274 : 38 : xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
6275 : 38 : xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
6276 : 38 : vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
6277 : 38 : dwarf2out_emit_cfi (xcfi);
6278 : : }
6279 : :
6280 : 38 : if (regno != INVALID_REGNUM)
6281 : : {
6282 : : /* MOV. */
6283 : 27 : rtx xops[2];
6284 : 27 : xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
6285 : 27 : xops[1] = gen_rtx_REG (word_mode, regno);
6286 : 27 : output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
6287 : : }
6288 : : else
6289 : : {
6290 : : /* LEA. */
6291 : 11 : rtx xops[2];
6292 : 11 : xops[0] = stack_pointer_rtx;
6293 : 11 : xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
6294 : 11 : output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
6295 : : }
6296 : :
6297 : 38 : fputs ("\tret\n", asm_out_file);
6298 : 38 : if ((ix86_harden_sls & harden_sls_return))
6299 : 1 : fputs ("\tint3\n", asm_out_file);
6300 : 38 : }
6301 : :
6302 : : /* Output a funtion with a call and return thunk for indirect branch.
6303 : : If REGNO != INVALID_REGNUM, the function address is in REGNO.
6304 : : Otherwise, the function address is on the top of stack. Thunk is
6305 : : used for function return if RET_P is true. */
6306 : :
6307 : : static void
6308 : 22 : output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
6309 : : unsigned int regno, bool ret_p)
6310 : : {
6311 : 22 : char name[32];
6312 : 22 : tree decl;
6313 : :
6314 : : /* Create __x86_indirect_thunk. */
6315 : 22 : indirect_thunk_name (name, regno, need_prefix, ret_p);
6316 : 22 : decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
6317 : : get_identifier (name),
6318 : : build_function_type_list (void_type_node, NULL_TREE));
6319 : 22 : DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
6320 : : NULL_TREE, void_type_node);
6321 : 22 : TREE_PUBLIC (decl) = 1;
6322 : 22 : TREE_STATIC (decl) = 1;
6323 : 22 : DECL_IGNORED_P (decl) = 1;
6324 : :
6325 : : #if TARGET_MACHO
6326 : : if (TARGET_MACHO)
6327 : : {
6328 : : switch_to_section (darwin_sections[picbase_thunk_section]);
6329 : : fputs ("\t.weak_definition\t", asm_out_file);
6330 : : assemble_name (asm_out_file, name);
6331 : : fputs ("\n\t.private_extern\t", asm_out_file);
6332 : : assemble_name (asm_out_file, name);
6333 : : putc ('\n', asm_out_file);
6334 : : ASM_OUTPUT_LABEL (asm_out_file, name);
6335 : : DECL_WEAK (decl) = 1;
6336 : : }
6337 : : else
6338 : : #endif
6339 : 22 : if (USE_HIDDEN_LINKONCE)
6340 : : {
6341 : 22 : cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
6342 : :
6343 : 22 : targetm.asm_out.unique_section (decl, 0);
6344 : 22 : switch_to_section (get_named_section (decl, NULL, 0));
6345 : :
6346 : 22 : targetm.asm_out.globalize_label (asm_out_file, name);
6347 : 22 : fputs ("\t.hidden\t", asm_out_file);
6348 : 22 : assemble_name (asm_out_file, name);
6349 : 22 : putc ('\n', asm_out_file);
6350 : 22 : ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
6351 : : }
6352 : : else
6353 : : {
6354 : : switch_to_section (text_section);
6355 : 22 : ASM_OUTPUT_LABEL (asm_out_file, name);
6356 : : }
6357 : :
6358 : 22 : DECL_INITIAL (decl) = make_node (BLOCK);
6359 : 22 : current_function_decl = decl;
6360 : 22 : allocate_struct_function (decl, false);
6361 : 22 : init_function_start (decl);
6362 : : /* We're about to hide the function body from callees of final_* by
6363 : : emitting it directly; tell them we're a thunk, if they care. */
6364 : 22 : cfun->is_thunk = true;
6365 : 22 : first_function_block_is_cold = false;
6366 : : /* Make sure unwind info is emitted for the thunk if needed. */
6367 : 22 : final_start_function (emit_barrier (), asm_out_file, 1);
6368 : :
6369 : 22 : output_indirect_thunk (regno);
6370 : :
6371 : 22 : final_end_function ();
6372 : 22 : init_insn_lengths ();
6373 : 22 : free_after_compilation (cfun);
6374 : 22 : set_cfun (NULL);
6375 : 22 : current_function_decl = NULL;
6376 : 22 : }
6377 : :
6378 : : static int pic_labels_used;
6379 : :
6380 : : /* Fills in the label name that should be used for a pc thunk for
6381 : : the given register. */
6382 : :
6383 : : static void
6384 : 36755 : get_pc_thunk_name (char name[32], unsigned int regno)
6385 : : {
6386 : 36755 : gcc_assert (!TARGET_64BIT);
6387 : :
6388 : 36755 : if (USE_HIDDEN_LINKONCE)
6389 : 36755 : sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
6390 : : else
6391 : 36755 : ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
6392 : 36755 : }
6393 : :
6394 : :
6395 : : /* This function generates code for -fpic that loads %ebx with
6396 : : the return address of the caller and then returns. */
6397 : :
6398 : : static void
6399 : 228065 : ix86_code_end (void)
6400 : : {
6401 : 228065 : rtx xops[2];
6402 : 228065 : unsigned int regno;
6403 : :
6404 : 228065 : if (indirect_return_needed)
6405 : 6 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6406 : : INVALID_REGNUM, true);
6407 : 228065 : if (indirect_return_via_cx)
6408 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6409 : : CX_REG, true);
6410 : 228065 : if (indirect_thunk_needed)
6411 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6412 : : INVALID_REGNUM, false);
6413 : :
6414 : 2052585 : for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
6415 : : {
6416 : 1824520 : if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
6417 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6418 : : regno, false);
6419 : : }
6420 : :
6421 : 3877105 : for (regno = FIRST_REX2_INT_REG; regno <= LAST_REX2_INT_REG; regno++)
6422 : : {
6423 : 3649040 : if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
6424 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6425 : : regno, false);
6426 : : }
6427 : :
6428 : 2052585 : for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
6429 : : {
6430 : 1824520 : char name[32];
6431 : 1824520 : tree decl;
6432 : :
6433 : 1824520 : if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
6434 : 16 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6435 : : regno, false);
6436 : :
6437 : 1824520 : if (!(pic_labels_used & (1 << regno)))
6438 : 1820959 : continue;
6439 : :
6440 : 3561 : get_pc_thunk_name (name, regno);
6441 : :
6442 : 3561 : decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
6443 : : get_identifier (name),
6444 : : build_function_type_list (void_type_node, NULL_TREE));
6445 : 3561 : DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
6446 : : NULL_TREE, void_type_node);
6447 : 3561 : TREE_PUBLIC (decl) = 1;
6448 : 3561 : TREE_STATIC (decl) = 1;
6449 : 3561 : DECL_IGNORED_P (decl) = 1;
6450 : :
6451 : : #if TARGET_MACHO
6452 : : if (TARGET_MACHO)
6453 : : {
6454 : : switch_to_section (darwin_sections[picbase_thunk_section]);
6455 : : fputs ("\t.weak_definition\t", asm_out_file);
6456 : : assemble_name (asm_out_file, name);
6457 : : fputs ("\n\t.private_extern\t", asm_out_file);
6458 : : assemble_name (asm_out_file, name);
6459 : : putc ('\n', asm_out_file);
6460 : : ASM_OUTPUT_LABEL (asm_out_file, name);
6461 : : DECL_WEAK (decl) = 1;
6462 : : }
6463 : : else
6464 : : #endif
6465 : 3561 : if (USE_HIDDEN_LINKONCE)
6466 : : {
6467 : 3561 : cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
6468 : :
6469 : 3561 : targetm.asm_out.unique_section (decl, 0);
6470 : 3561 : switch_to_section (get_named_section (decl, NULL, 0));
6471 : :
6472 : 3561 : targetm.asm_out.globalize_label (asm_out_file, name);
6473 : 3561 : fputs ("\t.hidden\t", asm_out_file);
6474 : 3561 : assemble_name (asm_out_file, name);
6475 : 3561 : putc ('\n', asm_out_file);
6476 : 3561 : ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
6477 : : }
6478 : : else
6479 : : {
6480 : : switch_to_section (text_section);
6481 : 3561 : ASM_OUTPUT_LABEL (asm_out_file, name);
6482 : : }
6483 : :
6484 : 3561 : DECL_INITIAL (decl) = make_node (BLOCK);
6485 : 3561 : current_function_decl = decl;
6486 : 3561 : allocate_struct_function (decl, false);
6487 : 3561 : init_function_start (decl);
6488 : : /* We're about to hide the function body from callees of final_* by
6489 : : emitting it directly; tell them we're a thunk, if they care. */
6490 : 3561 : cfun->is_thunk = true;
6491 : 3561 : first_function_block_is_cold = false;
6492 : : /* Make sure unwind info is emitted for the thunk if needed. */
6493 : 3561 : final_start_function (emit_barrier (), asm_out_file, 1);
6494 : :
6495 : : /* Pad stack IP move with 4 instructions (two NOPs count
6496 : : as one instruction). */
6497 : 3561 : if (TARGET_PAD_SHORT_FUNCTION)
6498 : : {
6499 : : int i = 8;
6500 : :
6501 : 0 : while (i--)
6502 : 0 : fputs ("\tnop\n", asm_out_file);
6503 : : }
6504 : :
6505 : 7122 : xops[0] = gen_rtx_REG (Pmode, regno);
6506 : 7122 : xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
6507 : 3561 : output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
6508 : 3561 : fputs ("\tret\n", asm_out_file);
6509 : 3561 : final_end_function ();
6510 : 3561 : init_insn_lengths ();
6511 : 3561 : free_after_compilation (cfun);
6512 : 3561 : set_cfun (NULL);
6513 : 3561 : current_function_decl = NULL;
6514 : : }
6515 : :
6516 : 228065 : if (flag_split_stack)
6517 : 4711 : file_end_indicate_split_stack ();
6518 : 228065 : }
6519 : :
6520 : : /* Emit code for the SET_GOT patterns. */
6521 : :
6522 : : const char *
6523 : 33194 : output_set_got (rtx dest, rtx label)
6524 : : {
6525 : 33194 : rtx xops[3];
6526 : :
6527 : 33194 : xops[0] = dest;
6528 : :
6529 : 33194 : if (TARGET_VXWORKS_GOTTPIC && TARGET_VXWORKS_RTP && flag_pic)
6530 : : {
6531 : : /* Load (*VXWORKS_GOTT_BASE) into the PIC register. */
6532 : : xops[2] = gen_rtx_MEM (Pmode,
6533 : : gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
6534 : : output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
6535 : :
6536 : : /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
6537 : : Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
6538 : : an unadorned address. */
6539 : : xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
6540 : : SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
6541 : : output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
6542 : : return "";
6543 : : }
6544 : :
6545 : 66388 : xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
6546 : :
6547 : 33194 : if (flag_pic)
6548 : : {
6549 : 33194 : char name[32];
6550 : 33194 : get_pc_thunk_name (name, REGNO (dest));
6551 : 33194 : pic_labels_used |= 1 << REGNO (dest);
6552 : :
6553 : 66388 : xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
6554 : 33194 : xops[2] = gen_rtx_MEM (QImode, xops[2]);
6555 : 33194 : output_asm_insn ("%!call\t%X2", xops);
6556 : :
6557 : : #if TARGET_MACHO
6558 : : /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
6559 : : This is what will be referenced by the Mach-O PIC subsystem. */
6560 : : if (machopic_should_output_picbase_label () || !label)
6561 : : ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
6562 : :
6563 : : /* When we are restoring the pic base at the site of a nonlocal label,
6564 : : and we decided to emit the pic base above, we will still output a
6565 : : local label used for calculating the correction offset (even though
6566 : : the offset will be 0 in that case). */
6567 : : if (label)
6568 : : targetm.asm_out.internal_label (asm_out_file, "L",
6569 : : CODE_LABEL_NUMBER (label));
6570 : : #endif
6571 : : }
6572 : : else
6573 : : {
6574 : 0 : if (TARGET_MACHO)
6575 : : /* We don't need a pic base, we're not producing pic. */
6576 : : gcc_unreachable ();
6577 : :
6578 : 0 : xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
6579 : 0 : output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
6580 : 0 : targetm.asm_out.internal_label (asm_out_file, "L",
6581 : 0 : CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
6582 : : }
6583 : :
6584 : 33194 : if (!TARGET_MACHO)
6585 : 33194 : output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
6586 : :
6587 : 33194 : return "";
6588 : : }
6589 : :
6590 : : /* Generate an "push" pattern for input ARG. */
6591 : :
6592 : : rtx
6593 : 1872294 : gen_push (rtx arg, bool ppx_p)
6594 : : {
6595 : 1872294 : struct machine_function *m = cfun->machine;
6596 : :
6597 : 1872294 : if (m->fs.cfa_reg == stack_pointer_rtx)
6598 : 1604737 : m->fs.cfa_offset += UNITS_PER_WORD;
6599 : 1872294 : m->fs.sp_offset += UNITS_PER_WORD;
6600 : :
6601 : 1872294 : if (REG_P (arg) && GET_MODE (arg) != word_mode)
6602 : 38 : arg = gen_rtx_REG (word_mode, REGNO (arg));
6603 : :
6604 : 1872294 : rtx stack = gen_rtx_MEM (word_mode,
6605 : 1872294 : gen_rtx_PRE_DEC (Pmode,
6606 : : stack_pointer_rtx));
6607 : 3744501 : return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
6608 : : }
6609 : :
6610 : : rtx
6611 : 23 : gen_pushfl (void)
6612 : : {
6613 : 23 : struct machine_function *m = cfun->machine;
6614 : 23 : rtx flags, mem;
6615 : :
6616 : 23 : if (m->fs.cfa_reg == stack_pointer_rtx)
6617 : 0 : m->fs.cfa_offset += UNITS_PER_WORD;
6618 : 23 : m->fs.sp_offset += UNITS_PER_WORD;
6619 : :
6620 : 23 : flags = gen_rtx_REG (CCmode, FLAGS_REG);
6621 : :
6622 : 23 : mem = gen_rtx_MEM (word_mode,
6623 : 23 : gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6624 : :
6625 : 23 : return gen_pushfl2 (word_mode, mem, flags);
6626 : : }
6627 : :
6628 : : /* Generate an "pop" pattern for input ARG. */
6629 : :
6630 : : rtx
6631 : 1458787 : gen_pop (rtx arg, bool ppx_p)
6632 : : {
6633 : 1458787 : if (REG_P (arg) && GET_MODE (arg) != word_mode)
6634 : 34 : arg = gen_rtx_REG (word_mode, REGNO (arg));
6635 : :
6636 : 1458787 : rtx stack = gen_rtx_MEM (word_mode,
6637 : 1458787 : gen_rtx_POST_INC (Pmode,
6638 : : stack_pointer_rtx));
6639 : :
6640 : 2917487 : return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
6641 : : }
6642 : :
6643 : : rtx
6644 : 21 : gen_popfl (void)
6645 : : {
6646 : 21 : rtx flags, mem;
6647 : :
6648 : 21 : flags = gen_rtx_REG (CCmode, FLAGS_REG);
6649 : :
6650 : 21 : mem = gen_rtx_MEM (word_mode,
6651 : 21 : gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6652 : :
6653 : 21 : return gen_popfl1 (word_mode, flags, mem);
6654 : : }
6655 : :
6656 : : /* Generate a "push2" pattern for input ARG. */
6657 : : rtx
6658 : 17 : gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
6659 : : {
6660 : 17 : struct machine_function *m = cfun->machine;
6661 : 17 : const int offset = UNITS_PER_WORD * 2;
6662 : :
6663 : 17 : if (m->fs.cfa_reg == stack_pointer_rtx)
6664 : 14 : m->fs.cfa_offset += offset;
6665 : 17 : m->fs.sp_offset += offset;
6666 : :
6667 : 17 : if (REG_P (reg1) && GET_MODE (reg1) != word_mode)
6668 : 0 : reg1 = gen_rtx_REG (word_mode, REGNO (reg1));
6669 : :
6670 : 17 : if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
6671 : 0 : reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
6672 : :
6673 : 17 : return ppx_p ? gen_push2p_di (mem, reg1, reg2)
6674 : 4 : : gen_push2_di (mem, reg1, reg2);
6675 : : }
6676 : :
6677 : : /* Return >= 0 if there is an unused call-clobbered register available
6678 : : for the entire function. */
6679 : :
6680 : : static unsigned int
6681 : 0 : ix86_select_alt_pic_regnum (void)
6682 : : {
6683 : 0 : if (ix86_use_pseudo_pic_reg ())
6684 : : return INVALID_REGNUM;
6685 : :
6686 : 0 : if (crtl->is_leaf
6687 : 0 : && !crtl->profile
6688 : 0 : && !ix86_current_function_calls_tls_descriptor)
6689 : : {
6690 : 0 : int i, drap;
6691 : : /* Can't use the same register for both PIC and DRAP. */
6692 : 0 : if (crtl->drap_reg)
6693 : 0 : drap = REGNO (crtl->drap_reg);
6694 : : else
6695 : : drap = -1;
6696 : 0 : for (i = 2; i >= 0; --i)
6697 : 0 : if (i != drap && !df_regs_ever_live_p (i))
6698 : : return i;
6699 : : }
6700 : :
6701 : : return INVALID_REGNUM;
6702 : : }
6703 : :
6704 : : /* Return true if REGNO is used by the epilogue. */
6705 : :
6706 : : bool
6707 : 1631478510 : ix86_epilogue_uses (int regno)
6708 : : {
6709 : : /* If there are no caller-saved registers, we preserve all registers,
6710 : : except for MMX and x87 registers which aren't supported when saving
6711 : : and restoring registers. Don't explicitly save SP register since
6712 : : it is always preserved. */
6713 : 1631478510 : return (epilogue_completed
6714 : 258296746 : && (cfun->machine->call_saved_registers
6715 : 258296746 : == TYPE_NO_CALLER_SAVED_REGISTERS)
6716 : 26588 : && !fixed_regs[regno]
6717 : 4927 : && !STACK_REGNO_P (regno)
6718 : 1631483341 : && !MMX_REGNO_P (regno));
6719 : : }
6720 : :
6721 : : /* Return nonzero if register REGNO can be used as a scratch register
6722 : : in peephole2. */
6723 : :
6724 : : static bool
6725 : 1230613 : ix86_hard_regno_scratch_ok (unsigned int regno)
6726 : : {
6727 : : /* If there are no caller-saved registers, we can't use any register
6728 : : as a scratch register after epilogue and use REGNO as scratch
6729 : : register only if it has been used before to avoid saving and
6730 : : restoring it. */
6731 : 1230613 : return ((cfun->machine->call_saved_registers
6732 : 1230613 : != TYPE_NO_CALLER_SAVED_REGISTERS)
6733 : 1230613 : || (!epilogue_completed
6734 : 0 : && df_regs_ever_live_p (regno)));
6735 : : }
6736 : :
6737 : : /* Return TRUE if we need to save REGNO. */
6738 : :
6739 : : bool
6740 : 347608328 : ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
6741 : : {
6742 : 347608328 : rtx reg;
6743 : :
6744 : 347608328 : switch (cfun->machine->call_saved_registers)
6745 : : {
6746 : : case TYPE_DEFAULT_CALL_SAVED_REGISTERS:
6747 : : break;
6748 : :
6749 : 55712 : case TYPE_NO_CALLER_SAVED_REGISTERS:
6750 : : /* If there are no caller-saved registers, we preserve all
6751 : : registers, except for MMX and x87 registers which aren't
6752 : : supported when saving and restoring registers. Don't
6753 : : explicitly save SP register since it is always preserved.
6754 : :
6755 : : Don't preserve registers used for function return value. */
6756 : 55712 : reg = crtl->return_rtx;
6757 : 55712 : if (reg)
6758 : : {
6759 : 768 : unsigned int i = REGNO (reg);
6760 : 768 : unsigned int nregs = REG_NREGS (reg);
6761 : 1522 : while (nregs-- > 0)
6762 : 768 : if ((i + nregs) == regno)
6763 : : return false;
6764 : : }
6765 : :
6766 : 55698 : return (df_regs_ever_live_p (regno)
6767 : 6502 : && !fixed_regs[regno]
6768 : 5560 : && !STACK_REGNO_P (regno)
6769 : 5560 : && !MMX_REGNO_P (regno)
6770 : 61258 : && (regno != HARD_FRAME_POINTER_REGNUM
6771 : 249 : || !frame_pointer_needed));
6772 : :
6773 : 17312 : case TYPE_NO_CALLEE_SAVED_REGISTERS:
6774 : 17312 : case TYPE_PRESERVE_NONE:
6775 : 17312 : if (regno != HARD_FRAME_POINTER_REGNUM)
6776 : : return false;
6777 : : break;
6778 : : }
6779 : :
6780 : 381254053 : if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
6781 : 10567909 : && pic_offset_table_rtx)
6782 : : {
6783 : 378437 : if (ix86_use_pseudo_pic_reg ())
6784 : : {
6785 : : /* REAL_PIC_OFFSET_TABLE_REGNUM used by call to
6786 : : _mcount in prologue. */
6787 : 378437 : if (!TARGET_64BIT && flag_pic && crtl->profile)
6788 : : return true;
6789 : : }
6790 : 0 : else if (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
6791 : 0 : || crtl->profile
6792 : 0 : || crtl->calls_eh_return
6793 : 0 : || crtl->uses_const_pool
6794 : 0 : || cfun->has_nonlocal_label)
6795 : 0 : return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
6796 : : }
6797 : :
6798 : 347535845 : if (crtl->calls_eh_return && maybe_eh_return)
6799 : : {
6800 : : unsigned i;
6801 : 13603 : for (i = 0; ; i++)
6802 : : {
6803 : 20739 : unsigned test = EH_RETURN_DATA_REGNO (i);
6804 : 14049 : if (test == INVALID_REGNUM)
6805 : : break;
6806 : 14049 : if (test == regno)
6807 : : return true;
6808 : 13603 : }
6809 : : }
6810 : :
6811 : 347535399 : if (ignore_outlined && cfun->machine->call_ms2sysv)
6812 : : {
6813 : 2650688 : unsigned count = cfun->machine->call_ms2sysv_extra_regs
6814 : : + xlogue_layout::MIN_REGS;
6815 : 2650688 : if (xlogue_layout::is_stub_managed_reg (regno, count))
6816 : : return false;
6817 : : }
6818 : :
6819 : 347035530 : if (crtl->drap_reg
6820 : 2142746 : && regno == REGNO (crtl->drap_reg)
6821 : 347089600 : && !cfun->machine->no_drap_save_restore)
6822 : : return true;
6823 : :
6824 : 346981460 : return (df_regs_ever_live_p (regno)
6825 : 366315949 : && !call_used_or_fixed_reg_p (regno)
6826 : 365689081 : && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
6827 : : }
6828 : :
6829 : : /* Return number of saved general prupose registers. */
6830 : :
6831 : : static int
6832 : 8006550 : ix86_nsaved_regs (void)
6833 : : {
6834 : 8006550 : int nregs = 0;
6835 : 8006550 : int regno;
6836 : :
6837 : 744609150 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
6838 : 736602600 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
6839 : 8240748 : nregs ++;
6840 : 8006550 : return nregs;
6841 : : }
6842 : :
6843 : : /* Return number of saved SSE registers. */
6844 : :
6845 : : static int
6846 : 8040178 : ix86_nsaved_sseregs (void)
6847 : : {
6848 : 8040178 : int nregs = 0;
6849 : 8040178 : int regno;
6850 : :
6851 : 7242275 : if (!TARGET_64BIT_MS_ABI
6852 : 8040178 : && (cfun->machine->call_saved_registers
6853 : 7814797 : != TYPE_NO_CALLER_SAVED_REGISTERS))
6854 : : return 0;
6855 : 21027579 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
6856 : 20801476 : if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
6857 : 1896315 : nregs ++;
6858 : : return nregs;
6859 : : }
6860 : :
6861 : : /* Given FROM and TO register numbers, say whether this elimination is
6862 : : allowed. If stack alignment is needed, we can only replace argument
6863 : : pointer with hard frame pointer, or replace frame pointer with stack
6864 : : pointer. Otherwise, frame pointer elimination is automatically
6865 : : handled and all other eliminations are valid. */
6866 : :
6867 : : static bool
6868 : 47396369 : ix86_can_eliminate (const int from, const int to)
6869 : : {
6870 : 47396369 : if (stack_realign_fp)
6871 : 1658524 : return ((from == ARG_POINTER_REGNUM
6872 : 1658524 : && to == HARD_FRAME_POINTER_REGNUM)
6873 : 1658524 : || (from == FRAME_POINTER_REGNUM
6874 : 1658524 : && to == STACK_POINTER_REGNUM));
6875 : : else
6876 : 85157732 : return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
6877 : : }
6878 : :
6879 : : /* Return the offset between two registers, one to be eliminated, and the other
6880 : : its replacement, at the start of a routine. */
6881 : :
6882 : : HOST_WIDE_INT
6883 : 138494472 : ix86_initial_elimination_offset (int from, int to)
6884 : : {
6885 : 138494472 : struct ix86_frame &frame = cfun->machine->frame;
6886 : :
6887 : 138494472 : if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
6888 : 10314766 : return frame.hard_frame_pointer_offset;
6889 : 128179706 : else if (from == FRAME_POINTER_REGNUM
6890 : 128179706 : && to == HARD_FRAME_POINTER_REGNUM)
6891 : 7972626 : return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
6892 : : else
6893 : : {
6894 : 120207080 : gcc_assert (to == STACK_POINTER_REGNUM);
6895 : :
6896 : 120207080 : if (from == ARG_POINTER_REGNUM)
6897 : 112234454 : return frame.stack_pointer_offset;
6898 : :
6899 : 7972626 : gcc_assert (from == FRAME_POINTER_REGNUM);
6900 : 7972626 : return frame.stack_pointer_offset - frame.frame_pointer_offset;
6901 : : }
6902 : : }
6903 : :
6904 : : /* Emits a warning for unsupported msabi to sysv pro/epilogues. */
6905 : : void
6906 : 0 : warn_once_call_ms2sysv_xlogues (const char *feature)
6907 : : {
6908 : 0 : static bool warned_once = false;
6909 : 0 : if (!warned_once)
6910 : : {
6911 : 0 : warning (0, "%<-mcall-ms2sysv-xlogues%> is not compatible with %s",
6912 : : feature);
6913 : 0 : warned_once = true;
6914 : : }
6915 : 0 : }
6916 : :
6917 : : /* Return the probing interval for -fstack-clash-protection. */
6918 : :
6919 : : static HOST_WIDE_INT
6920 : 489 : get_probe_interval (void)
6921 : : {
6922 : 335 : if (flag_stack_clash_protection)
6923 : 405 : return (HOST_WIDE_INT_1U
6924 : 405 : << param_stack_clash_protection_probe_interval);
6925 : : else
6926 : : return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP);
6927 : : }
6928 : :
6929 : : /* When using -fsplit-stack, the allocation routines set a field in
6930 : : the TCB to the bottom of the stack plus this much space, measured
6931 : : in bytes. */
6932 : :
6933 : : #define SPLIT_STACK_AVAILABLE 256
6934 : :
6935 : : /* Return true if push2/pop2 can be generated. */
6936 : :
6937 : : static bool
6938 : 8007188 : ix86_can_use_push2pop2 (void)
6939 : : {
6940 : : /* Use push2/pop2 only if the incoming stack is 16-byte aligned. */
6941 : 8007188 : unsigned int incoming_stack_boundary
6942 : 8007188 : = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
6943 : 8007188 : ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
6944 : 8007188 : return incoming_stack_boundary % 128 == 0;
6945 : : }
6946 : :
6947 : : /* Helper function to determine whether push2/pop2 can be used in prologue or
6948 : : epilogue for register save/restore. */
6949 : : static bool
6950 : 8006550 : ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
6951 : : {
6952 : 8006550 : if (!ix86_can_use_push2pop2 ())
6953 : : return false;
6954 : 7970668 : int aligned = cfun->machine->fs.sp_offset % 16 == 0;
6955 : 7970668 : return TARGET_APX_PUSH2POP2
6956 : 2774 : && !cfun->machine->frame.save_regs_using_mov
6957 : 2762 : && cfun->machine->func_type == TYPE_NORMAL
6958 : 7973422 : && (nregs + aligned) >= 3;
6959 : : }
6960 : :
6961 : : /* Check if push/pop should be used to save/restore registers. */
6962 : : static bool
6963 : 8715871 : save_regs_using_push_pop (HOST_WIDE_INT to_allocate)
6964 : : {
6965 : 3081817 : return ((!to_allocate && cfun->machine->frame.nregs <= 1)
6966 : 5882291 : || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
6967 : : /* If static stack checking is enabled and done with probes,
6968 : : the registers need to be saved before allocating the frame. */
6969 : 5881594 : || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
6970 : : /* If stack clash probing needs a loop, then it needs a
6971 : : scratch register. But the returned register is only guaranteed
6972 : : to be safe to use after register saves are complete. So if
6973 : : stack clash protections are enabled and the allocated frame is
6974 : : larger than the probe interval, then use pushes to save
6975 : : callee saved registers. */
6976 : 14597385 : || (flag_stack_clash_protection
6977 : 335 : && !ix86_target_stack_probe ()
6978 : 335 : && to_allocate > get_probe_interval ()));
6979 : : }
6980 : :
6981 : : /* Fill structure ix86_frame about frame of currently computed function. */
6982 : :
6983 : : static void
6984 : 8006550 : ix86_compute_frame_layout (void)
6985 : : {
6986 : 8006550 : struct ix86_frame *frame = &cfun->machine->frame;
6987 : 8006550 : struct machine_function *m = cfun->machine;
6988 : 8006550 : unsigned HOST_WIDE_INT stack_alignment_needed;
6989 : 8006550 : HOST_WIDE_INT offset;
6990 : 8006550 : unsigned HOST_WIDE_INT preferred_alignment;
6991 : 8006550 : HOST_WIDE_INT size = ix86_get_frame_size ();
6992 : 8006550 : HOST_WIDE_INT to_allocate;
6993 : :
6994 : : /* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
6995 : : * ms_abi functions that call a sysv function. We now need to prune away
6996 : : * cases where it should be disabled. */
6997 : 8006550 : if (TARGET_64BIT && m->call_ms2sysv)
6998 : : {
6999 : 35225 : gcc_assert (TARGET_64BIT_MS_ABI);
7000 : 35225 : gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
7001 : 35225 : gcc_assert (!TARGET_SEH);
7002 : 35225 : gcc_assert (TARGET_SSE);
7003 : 35225 : gcc_assert (!ix86_using_red_zone ());
7004 : :
7005 : 35225 : if (crtl->calls_eh_return)
7006 : : {
7007 : 0 : gcc_assert (!reload_completed);
7008 : 0 : m->call_ms2sysv = false;
7009 : 0 : warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
7010 : : }
7011 : :
7012 : 35225 : else if (ix86_static_chain_on_stack)
7013 : : {
7014 : 0 : gcc_assert (!reload_completed);
7015 : 0 : m->call_ms2sysv = false;
7016 : 0 : warn_once_call_ms2sysv_xlogues ("static call chains");
7017 : : }
7018 : :
7019 : : /* Finally, compute which registers the stub will manage. */
7020 : : else
7021 : : {
7022 : 35225 : unsigned count = xlogue_layout::count_stub_managed_regs ();
7023 : 35225 : m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
7024 : 35225 : m->call_ms2sysv_pad_in = 0;
7025 : : }
7026 : : }
7027 : :
7028 : 8006550 : frame->nregs = ix86_nsaved_regs ();
7029 : 8006550 : frame->nsseregs = ix86_nsaved_sseregs ();
7030 : :
7031 : : /* 64-bit MS ABI seem to require stack alignment to be always 16,
7032 : : except for function prologues, leaf functions and when the defult
7033 : : incoming stack boundary is overriden at command line or via
7034 : : force_align_arg_pointer attribute.
7035 : :
7036 : : Darwin's ABI specifies 128b alignment for both 32 and 64 bit variants
7037 : : at call sites, including profile function calls.
7038 : :
7039 : : For APX push2/pop2, the stack also requires 128b alignment. */
7040 : 8006550 : if ((ix86_pro_and_epilogue_can_use_push2pop2 (frame->nregs)
7041 : 62 : && crtl->preferred_stack_boundary < 128)
7042 : 8006611 : || (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
7043 : 225379 : && crtl->preferred_stack_boundary < 128)
7044 : 0 : && (!crtl->is_leaf || cfun->calls_alloca != 0
7045 : 0 : || ix86_current_function_calls_tls_descriptor
7046 : 0 : || (TARGET_MACHO && crtl->profile)
7047 : 0 : || ix86_incoming_stack_boundary < 128)))
7048 : : {
7049 : 1 : crtl->preferred_stack_boundary = 128;
7050 : 1 : if (crtl->stack_alignment_needed < 128)
7051 : 1 : crtl->stack_alignment_needed = 128;
7052 : : }
7053 : :
7054 : 8006550 : stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
7055 : 8006550 : preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
7056 : :
7057 : 8006550 : gcc_assert (!size || stack_alignment_needed);
7058 : 8804424 : gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
7059 : 8006550 : gcc_assert (preferred_alignment <= stack_alignment_needed);
7060 : :
7061 : : /* The only ABI saving SSE regs should be 64-bit ms_abi or with
7062 : : no_caller_saved_registers attribue. */
7063 : 8006550 : gcc_assert (TARGET_64BIT
7064 : : || (cfun->machine->call_saved_registers
7065 : : == TYPE_NO_CALLER_SAVED_REGISTERS)
7066 : : || !frame->nsseregs);
7067 : 8006550 : if (TARGET_64BIT && m->call_ms2sysv)
7068 : : {
7069 : 35225 : gcc_assert (stack_alignment_needed >= 16);
7070 : 35225 : gcc_assert ((cfun->machine->call_saved_registers
7071 : : == TYPE_NO_CALLER_SAVED_REGISTERS)
7072 : : || !frame->nsseregs);
7073 : : }
7074 : :
7075 : : /* For SEH we have to limit the amount of code movement into the prologue.
7076 : : At present we do this via a BLOCKAGE, at which point there's very little
7077 : : scheduling that can be done, which means that there's very little point
7078 : : in doing anything except PUSHs. */
7079 : 8006550 : if (TARGET_SEH)
7080 : : m->use_fast_prologue_epilogue = false;
7081 : 8006550 : else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
7082 : : {
7083 : 7683847 : int count = frame->nregs;
7084 : 7683847 : struct cgraph_node *node = cgraph_node::get (current_function_decl);
7085 : :
7086 : : /* The fast prologue uses move instead of push to save registers. This
7087 : : is significantly longer, but also executes faster as modern hardware
7088 : : can execute the moves in parallel, but can't do that for push/pop.
7089 : :
7090 : : Be careful about choosing what prologue to emit: When function takes
7091 : : many instructions to execute we may use slow version as well as in
7092 : : case function is known to be outside hot spot (this is known with
7093 : : feedback only). Weight the size of function by number of registers
7094 : : to save as it is cheap to use one or two push instructions but very
7095 : : slow to use many of them.
7096 : :
7097 : : Calling this hook multiple times with the same frame requirements
7098 : : must produce the same layout, since the RA might otherwise be
7099 : : unable to reach a fixed point or might fail its final sanity checks.
7100 : : This means that once we've assumed that a function does or doesn't
7101 : : have a particular size, we have to stick to that assumption
7102 : : regardless of how the function has changed since. */
7103 : 7683847 : if (count)
7104 : 2599305 : count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
7105 : 7683847 : if (node->frequency < NODE_FREQUENCY_NORMAL
7106 : 7015194 : || (flag_branch_probabilities
7107 : 971 : && node->frequency < NODE_FREQUENCY_HOT))
7108 : 668963 : m->use_fast_prologue_epilogue = false;
7109 : : else
7110 : : {
7111 : 7014884 : if (count != frame->expensive_count)
7112 : : {
7113 : 286541 : frame->expensive_count = count;
7114 : 286541 : frame->expensive_p = expensive_function_p (count);
7115 : : }
7116 : 7014884 : m->use_fast_prologue_epilogue = !frame->expensive_p;
7117 : : }
7118 : : }
7119 : :
7120 : 8006550 : frame->save_regs_using_mov
7121 : 8006550 : = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
7122 : :
7123 : : /* Skip return address and error code in exception handler. */
7124 : 8006550 : offset = INCOMING_FRAME_SP_OFFSET;
7125 : :
7126 : : /* Skip pushed static chain. */
7127 : 8006550 : if (ix86_static_chain_on_stack)
7128 : 0 : offset += UNITS_PER_WORD;
7129 : :
7130 : : /* Skip saved base pointer. */
7131 : 8006550 : if (frame_pointer_needed)
7132 : 2694622 : offset += UNITS_PER_WORD;
7133 : 8006550 : frame->hfp_save_offset = offset;
7134 : :
7135 : : /* The traditional frame pointer location is at the top of the frame. */
7136 : 8006550 : frame->hard_frame_pointer_offset = offset;
7137 : :
7138 : : /* Register save area */
7139 : 8006550 : offset += frame->nregs * UNITS_PER_WORD;
7140 : 8006550 : frame->reg_save_offset = offset;
7141 : :
7142 : : /* Calculate the size of the va-arg area (not including padding, if any). */
7143 : 8006550 : frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
7144 : :
7145 : : /* Also adjust stack_realign_offset for the largest alignment of
7146 : : stack slot actually used. */
7147 : 8006550 : if (stack_realign_fp
7148 : 7708316 : || (cfun->machine->max_used_stack_alignment != 0
7149 : 120 : && (offset % cfun->machine->max_used_stack_alignment) != 0))
7150 : : {
7151 : : /* We may need a 16-byte aligned stack for the remainder of the
7152 : : register save area, but the stack frame for the local function
7153 : : may require a greater alignment if using AVX/2/512. In order
7154 : : to avoid wasting space, we first calculate the space needed for
7155 : : the rest of the register saves, add that to the stack pointer,
7156 : : and then realign the stack to the boundary of the start of the
7157 : : frame for the local function. */
7158 : 298300 : HOST_WIDE_INT space_needed = 0;
7159 : 298300 : HOST_WIDE_INT sse_reg_space_needed = 0;
7160 : :
7161 : 298300 : if (TARGET_64BIT)
7162 : : {
7163 : 296510 : if (m->call_ms2sysv)
7164 : : {
7165 : 6415 : m->call_ms2sysv_pad_in = 0;
7166 : 6415 : space_needed = xlogue_layout::get_instance ().get_stack_space_used ();
7167 : : }
7168 : :
7169 : 290095 : else if (frame->nsseregs)
7170 : : /* The only ABI that has saved SSE registers (Win64) also has a
7171 : : 16-byte aligned default stack. However, many programs violate
7172 : : the ABI, and Wine64 forces stack realignment to compensate. */
7173 : 6447 : space_needed = frame->nsseregs * 16;
7174 : :
7175 : 296510 : sse_reg_space_needed = space_needed = ROUND_UP (space_needed, 16);
7176 : :
7177 : : /* 64-bit frame->va_arg_size should always be a multiple of 16, but
7178 : : rounding to be pedantic. */
7179 : 296510 : space_needed = ROUND_UP (space_needed + frame->va_arg_size, 16);
7180 : : }
7181 : : else
7182 : 1790 : space_needed = frame->va_arg_size;
7183 : :
7184 : : /* Record the allocation size required prior to the realignment AND. */
7185 : 298300 : frame->stack_realign_allocate = space_needed;
7186 : :
7187 : : /* The re-aligned stack starts at frame->stack_realign_offset. Values
7188 : : before this point are not directly comparable with values below
7189 : : this point. Use sp_valid_at to determine if the stack pointer is
7190 : : valid for a given offset, fp_valid_at for the frame pointer, or
7191 : : choose_baseaddr to have a base register chosen for you.
7192 : :
7193 : : Note that the result of (frame->stack_realign_offset
7194 : : & (stack_alignment_needed - 1)) may not equal zero. */
7195 : 298300 : offset = ROUND_UP (offset + space_needed, stack_alignment_needed);
7196 : 298300 : frame->stack_realign_offset = offset - space_needed;
7197 : 298300 : frame->sse_reg_save_offset = frame->stack_realign_offset
7198 : 298300 : + sse_reg_space_needed;
7199 : 298300 : }
7200 : : else
7201 : : {
7202 : 7708250 : frame->stack_realign_offset = offset;
7203 : :
7204 : 7708250 : if (TARGET_64BIT && m->call_ms2sysv)
7205 : : {
7206 : 28810 : m->call_ms2sysv_pad_in = !!(offset & UNITS_PER_WORD);
7207 : 28810 : offset += xlogue_layout::get_instance ().get_stack_space_used ();
7208 : : }
7209 : :
7210 : : /* Align and set SSE register save area. */
7211 : 7679440 : else if (frame->nsseregs)
7212 : : {
7213 : : /* If the incoming stack boundary is at least 16 bytes, or DRAP is
7214 : : required and the DRAP re-alignment boundary is at least 16 bytes,
7215 : : then we want the SSE register save area properly aligned. */
7216 : 183177 : if (ix86_incoming_stack_boundary >= 128
7217 : 6400 : || (stack_realign_drap && stack_alignment_needed >= 16))
7218 : 183177 : offset = ROUND_UP (offset, 16);
7219 : 183177 : offset += frame->nsseregs * 16;
7220 : : }
7221 : 7708250 : frame->sse_reg_save_offset = offset;
7222 : 7708250 : offset += frame->va_arg_size;
7223 : : }
7224 : :
7225 : : /* Align start of frame for local function. When a function call
7226 : : is removed, it may become a leaf function. But if argument may
7227 : : be passed on stack, we need to align the stack when there is no
7228 : : tail call. */
7229 : 8006550 : if (m->call_ms2sysv
7230 : 7971325 : || frame->va_arg_size != 0
7231 : 7892930 : || size != 0
7232 : 4250278 : || !crtl->is_leaf
7233 : 1967695 : || (!crtl->tail_call_emit
7234 : 1659890 : && cfun->machine->outgoing_args_on_stack)
7235 : 1967645 : || cfun->calls_alloca
7236 : 9972613 : || ix86_current_function_calls_tls_descriptor)
7237 : 6040890 : offset = ROUND_UP (offset, stack_alignment_needed);
7238 : :
7239 : : /* Frame pointer points here. */
7240 : 8006550 : frame->frame_pointer_offset = offset;
7241 : :
7242 : 8006550 : offset += size;
7243 : :
7244 : : /* Add outgoing arguments area. Can be skipped if we eliminated
7245 : : all the function calls as dead code.
7246 : : Skipping is however impossible when function calls alloca. Alloca
7247 : : expander assumes that last crtl->outgoing_args_size
7248 : : of stack frame are unused. */
7249 : 8006550 : if (ACCUMULATE_OUTGOING_ARGS
7250 : 8623757 : && (!crtl->is_leaf || cfun->calls_alloca
7251 : 391063 : || ix86_current_function_calls_tls_descriptor))
7252 : : {
7253 : 226144 : offset += crtl->outgoing_args_size;
7254 : 226144 : frame->outgoing_arguments_size = crtl->outgoing_args_size;
7255 : : }
7256 : : else
7257 : 7780406 : frame->outgoing_arguments_size = 0;
7258 : :
7259 : : /* Align stack boundary. Only needed if we're calling another function
7260 : : or using alloca. */
7261 : 2670007 : if (!crtl->is_leaf || cfun->calls_alloca
7262 : 10673158 : || ix86_current_function_calls_tls_descriptor)
7263 : 5341733 : offset = ROUND_UP (offset, preferred_alignment);
7264 : :
7265 : : /* We've reached end of stack frame. */
7266 : 8006550 : frame->stack_pointer_offset = offset;
7267 : :
7268 : : /* Size prologue needs to allocate. */
7269 : 8006550 : to_allocate = offset - frame->sse_reg_save_offset;
7270 : :
7271 : 8006550 : if (save_regs_using_push_pop (to_allocate))
7272 : 2474151 : frame->save_regs_using_mov = false;
7273 : :
7274 : 8006550 : if (ix86_using_red_zone ()
7275 : 6983111 : && crtl->sp_is_unchanging
7276 : 6349349 : && crtl->is_leaf
7277 : 2569775 : && !cfun->machine->asm_redzone_clobber_seen
7278 : 2569762 : && !ix86_pc_thunk_call_expanded
7279 : 10576312 : && !ix86_current_function_calls_tls_descriptor)
7280 : : {
7281 : 2569762 : frame->red_zone_size = to_allocate;
7282 : 2569762 : if (frame->save_regs_using_mov)
7283 : 139705 : frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
7284 : 2569762 : if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
7285 : 110236 : frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
7286 : : }
7287 : : else
7288 : 5436788 : frame->red_zone_size = 0;
7289 : 8006550 : frame->stack_pointer_offset -= frame->red_zone_size;
7290 : :
7291 : : /* The SEH frame pointer location is near the bottom of the frame.
7292 : : This is enforced by the fact that the difference between the
7293 : : stack pointer and the frame pointer is limited to 240 bytes in
7294 : : the unwind data structure. */
7295 : 8006550 : if (TARGET_SEH)
7296 : : {
7297 : : /* Force the frame pointer to point at or below the lowest register save
7298 : : area, see the SEH code in config/i386/winnt.cc for the rationale. */
7299 : : frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
7300 : :
7301 : : /* If we can leave the frame pointer where it is, do so; however return
7302 : : the establisher frame for __builtin_frame_address (0) or else if the
7303 : : frame overflows the SEH maximum frame size.
7304 : :
7305 : : Note that the value returned by __builtin_frame_address (0) is quite
7306 : : constrained, because setjmp is piggybacked on the SEH machinery with
7307 : : recent versions of MinGW:
7308 : :
7309 : : # elif defined(__SEH__)
7310 : : # if defined(__aarch64__) || defined(_ARM64_)
7311 : : # define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
7312 : : # elif (__MINGW_GCC_VERSION < 40702)
7313 : : # define setjmp(BUF) _setjmp((BUF), mingw_getsp())
7314 : : # else
7315 : : # define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
7316 : : # endif
7317 : :
7318 : : and the second argument passed to _setjmp, if not null, is forwarded
7319 : : to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
7320 : : built an ExceptionRecord on the fly describing the setjmp buffer). */
7321 : : const HOST_WIDE_INT diff
7322 : : = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
7323 : : if (diff <= 255 && !crtl->accesses_prior_frames)
7324 : : {
7325 : : /* The resulting diff will be a multiple of 16 lower than 255,
7326 : : i.e. at most 240 as required by the unwind data structure. */
7327 : : frame->hard_frame_pointer_offset += (diff & 15);
7328 : : }
7329 : : else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
7330 : : {
7331 : : /* Ideally we'd determine what portion of the local stack frame
7332 : : (within the constraint of the lowest 240) is most heavily used.
7333 : : But without that complication, simply bias the frame pointer
7334 : : by 128 bytes so as to maximize the amount of the local stack
7335 : : frame that is addressable with 8-bit offsets. */
7336 : : frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
7337 : : }
7338 : : else
7339 : : frame->hard_frame_pointer_offset = frame->hfp_save_offset;
7340 : : }
7341 : 8006550 : }
7342 : :
7343 : : /* This is semi-inlined memory_address_length, but simplified
7344 : : since we know that we're always dealing with reg+offset, and
7345 : : to avoid having to create and discard all that rtl. */
7346 : :
7347 : : static inline int
7348 : 1001188 : choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
7349 : : {
7350 : 1001188 : int len = 4;
7351 : :
7352 : 0 : if (offset == 0)
7353 : : {
7354 : : /* EBP and R13 cannot be encoded without an offset. */
7355 : 0 : len = (regno == BP_REG || regno == R13_REG);
7356 : : }
7357 : 992907 : else if (IN_RANGE (offset, -128, 127))
7358 : 610483 : len = 1;
7359 : :
7360 : : /* ESP and R12 must be encoded with a SIB byte. */
7361 : 0 : if (regno == SP_REG || regno == R12_REG)
7362 : 0 : len++;
7363 : :
7364 : 1001188 : return len;
7365 : : }
7366 : :
7367 : : /* Determine if the stack pointer is valid for accessing the CFA_OFFSET in
7368 : : the frame save area. The register is saved at CFA - CFA_OFFSET. */
7369 : :
7370 : : static bool
7371 : 3469848 : sp_valid_at (HOST_WIDE_INT cfa_offset)
7372 : : {
7373 : 3469848 : const struct machine_frame_state &fs = cfun->machine->fs;
7374 : 3469848 : if (fs.sp_realigned && cfa_offset <= fs.sp_realigned_offset)
7375 : : {
7376 : : /* Validate that the cfa_offset isn't in a "no-man's land". */
7377 : 45976 : gcc_assert (cfa_offset <= fs.sp_realigned_fp_last);
7378 : : return false;
7379 : : }
7380 : 3423872 : return fs.sp_valid;
7381 : : }
7382 : :
7383 : : /* Determine if the frame pointer is valid for accessing the CFA_OFFSET in
7384 : : the frame save area. The register is saved at CFA - CFA_OFFSET. */
7385 : :
7386 : : static inline bool
7387 : 1386185 : fp_valid_at (HOST_WIDE_INT cfa_offset)
7388 : : {
7389 : 1386185 : const struct machine_frame_state &fs = cfun->machine->fs;
7390 : 1386185 : if (fs.sp_realigned && cfa_offset > fs.sp_realigned_fp_last)
7391 : : {
7392 : : /* Validate that the cfa_offset isn't in a "no-man's land". */
7393 : 28328 : gcc_assert (cfa_offset >= fs.sp_realigned_offset);
7394 : : return false;
7395 : : }
7396 : 1357857 : return fs.fp_valid;
7397 : : }
7398 : :
7399 : : /* Choose a base register based upon alignment requested, speed and/or
7400 : : size. */
7401 : :
7402 : : static void
7403 : 1386185 : choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
7404 : : HOST_WIDE_INT &base_offset,
7405 : : unsigned int align_reqested, unsigned int *align)
7406 : : {
7407 : 1386185 : const struct machine_function *m = cfun->machine;
7408 : 1386185 : unsigned int hfp_align;
7409 : 1386185 : unsigned int drap_align;
7410 : 1386185 : unsigned int sp_align;
7411 : 1386185 : bool hfp_ok = fp_valid_at (cfa_offset);
7412 : 1386185 : bool drap_ok = m->fs.drap_valid;
7413 : 1386185 : bool sp_ok = sp_valid_at (cfa_offset);
7414 : :
7415 : 1386185 : hfp_align = drap_align = sp_align = INCOMING_STACK_BOUNDARY;
7416 : :
7417 : : /* Filter out any registers that don't meet the requested alignment
7418 : : criteria. */
7419 : 1386185 : if (align_reqested)
7420 : : {
7421 : 973038 : if (m->fs.realigned)
7422 : 28160 : hfp_align = drap_align = sp_align = crtl->stack_alignment_needed;
7423 : : /* SEH unwind code does do not currently support REG_CFA_EXPRESSION
7424 : : notes (which we would need to use a realigned stack pointer),
7425 : : so disable on SEH targets. */
7426 : 944878 : else if (m->fs.sp_realigned)
7427 : 28328 : sp_align = crtl->stack_alignment_needed;
7428 : :
7429 : 973038 : hfp_ok = hfp_ok && hfp_align >= align_reqested;
7430 : 973038 : drap_ok = drap_ok && drap_align >= align_reqested;
7431 : 973038 : sp_ok = sp_ok && sp_align >= align_reqested;
7432 : : }
7433 : :
7434 : 1386185 : if (m->use_fast_prologue_epilogue)
7435 : : {
7436 : : /* Choose the base register most likely to allow the most scheduling
7437 : : opportunities. Generally FP is valid throughout the function,
7438 : : while DRAP must be reloaded within the epilogue. But choose either
7439 : : over the SP due to increased encoding size. */
7440 : :
7441 : 679180 : if (hfp_ok)
7442 : : {
7443 : 116547 : base_reg = hard_frame_pointer_rtx;
7444 : 116547 : base_offset = m->fs.fp_offset - cfa_offset;
7445 : : }
7446 : 562633 : else if (drap_ok)
7447 : : {
7448 : 0 : base_reg = crtl->drap_reg;
7449 : 0 : base_offset = 0 - cfa_offset;
7450 : : }
7451 : 562633 : else if (sp_ok)
7452 : : {
7453 : 562633 : base_reg = stack_pointer_rtx;
7454 : 562633 : base_offset = m->fs.sp_offset - cfa_offset;
7455 : : }
7456 : : }
7457 : : else
7458 : : {
7459 : 707005 : HOST_WIDE_INT toffset;
7460 : 707005 : int len = 16, tlen;
7461 : :
7462 : : /* Choose the base register with the smallest address encoding.
7463 : : With a tie, choose FP > DRAP > SP. */
7464 : 707005 : if (sp_ok)
7465 : : {
7466 : 689789 : base_reg = stack_pointer_rtx;
7467 : 689789 : base_offset = m->fs.sp_offset - cfa_offset;
7468 : 1371297 : len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
7469 : : }
7470 : 707005 : if (drap_ok)
7471 : : {
7472 : 0 : toffset = 0 - cfa_offset;
7473 : 0 : tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
7474 : 0 : if (tlen <= len)
7475 : : {
7476 : 0 : base_reg = crtl->drap_reg;
7477 : 0 : base_offset = toffset;
7478 : 0 : len = tlen;
7479 : : }
7480 : : }
7481 : 707005 : if (hfp_ok)
7482 : : {
7483 : 311399 : toffset = m->fs.fp_offset - cfa_offset;
7484 : 311399 : tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
7485 : 311399 : if (tlen <= len)
7486 : : {
7487 : 220755 : base_reg = hard_frame_pointer_rtx;
7488 : 220755 : base_offset = toffset;
7489 : : }
7490 : : }
7491 : : }
7492 : :
7493 : : /* Set the align return value. */
7494 : 1386185 : if (align)
7495 : : {
7496 : 973038 : if (base_reg == stack_pointer_rtx)
7497 : 691937 : *align = sp_align;
7498 : 281101 : else if (base_reg == crtl->drap_reg)
7499 : 0 : *align = drap_align;
7500 : 281101 : else if (base_reg == hard_frame_pointer_rtx)
7501 : 281101 : *align = hfp_align;
7502 : : }
7503 : 1386185 : }
7504 : :
7505 : : /* Return an RTX that points to CFA_OFFSET within the stack frame and
7506 : : the alignment of address. If ALIGN is non-null, it should point to
7507 : : an alignment value (in bits) that is preferred or zero and will
7508 : : recieve the alignment of the base register that was selected,
7509 : : irrespective of rather or not CFA_OFFSET is a multiple of that
7510 : : alignment value. If it is possible for the base register offset to be
7511 : : non-immediate then SCRATCH_REGNO should specify a scratch register to
7512 : : use.
7513 : :
7514 : : The valid base registers are taken from CFUN->MACHINE->FS. */
7515 : :
7516 : : static rtx
7517 : 1386185 : choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align,
7518 : : unsigned int scratch_regno = INVALID_REGNUM)
7519 : : {
7520 : 1386185 : rtx base_reg = NULL;
7521 : 1386185 : HOST_WIDE_INT base_offset = 0;
7522 : :
7523 : : /* If a specific alignment is requested, try to get a base register
7524 : : with that alignment first. */
7525 : 1386185 : if (align && *align)
7526 : 973038 : choose_basereg (cfa_offset, base_reg, base_offset, *align, align);
7527 : :
7528 : 1386185 : if (!base_reg)
7529 : 413147 : choose_basereg (cfa_offset, base_reg, base_offset, 0, align);
7530 : :
7531 : 1386185 : gcc_assert (base_reg != NULL);
7532 : :
7533 : 1386185 : rtx base_offset_rtx = GEN_INT (base_offset);
7534 : :
7535 : 1435694 : if (!x86_64_immediate_operand (base_offset_rtx, Pmode))
7536 : : {
7537 : 1 : gcc_assert (scratch_regno != INVALID_REGNUM);
7538 : :
7539 : 1 : rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
7540 : 1 : emit_move_insn (scratch_reg, base_offset_rtx);
7541 : :
7542 : 1 : return gen_rtx_PLUS (Pmode, base_reg, scratch_reg);
7543 : : }
7544 : :
7545 : 1435693 : return plus_constant (Pmode, base_reg, base_offset);
7546 : : }
7547 : :
7548 : : /* Emit code to save registers in the prologue. */
7549 : :
7550 : : static void
7551 : 425333 : ix86_emit_save_regs (void)
7552 : : {
7553 : 425333 : int regno;
7554 : 425333 : rtx_insn *insn;
7555 : 425333 : bool use_ppx = TARGET_APX_PPX && !crtl->calls_eh_return;
7556 : :
7557 : 425333 : if (!TARGET_APX_PUSH2POP2
7558 : 88 : || !ix86_can_use_push2pop2 ()
7559 : 425419 : || cfun->machine->func_type != TYPE_NORMAL)
7560 : : {
7561 : 39548064 : for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
7562 : 39122816 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7563 : : {
7564 : 1202109 : insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
7565 : : use_ppx));
7566 : 1202109 : RTX_FRAME_RELATED_P (insn) = 1;
7567 : : }
7568 : : }
7569 : : else
7570 : : {
7571 : 85 : int regno_list[2];
7572 : 85 : regno_list[0] = regno_list[1] = -1;
7573 : 85 : int loaded_regnum = 0;
7574 : 85 : bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
7575 : :
7576 : 7905 : for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
7577 : 7820 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7578 : : {
7579 : 122 : if (aligned)
7580 : : {
7581 : 40 : regno_list[loaded_regnum++] = regno;
7582 : 40 : if (loaded_regnum == 2)
7583 : : {
7584 : 17 : gcc_assert (regno_list[0] != -1
7585 : : && regno_list[1] != -1
7586 : : && regno_list[0] != regno_list[1]);
7587 : 17 : const int offset = UNITS_PER_WORD * 2;
7588 : 17 : rtx mem = gen_rtx_MEM (TImode,
7589 : 17 : gen_rtx_PRE_DEC (Pmode,
7590 : : stack_pointer_rtx));
7591 : 17 : insn = emit_insn (gen_push2 (mem,
7592 : : gen_rtx_REG (word_mode,
7593 : : regno_list[0]),
7594 : : gen_rtx_REG (word_mode,
7595 : : regno_list[1]),
7596 : : use_ppx));
7597 : 17 : RTX_FRAME_RELATED_P (insn) = 1;
7598 : 17 : rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
7599 : :
7600 : 51 : for (int i = 0; i < 2; i++)
7601 : : {
7602 : 68 : rtx dwarf_reg = gen_rtx_REG (word_mode,
7603 : 34 : regno_list[i]);
7604 : 34 : rtx sp_offset = plus_constant (Pmode,
7605 : : stack_pointer_rtx,
7606 : 34 : + UNITS_PER_WORD
7607 : 34 : * (1 - i));
7608 : 34 : rtx tmp = gen_rtx_SET (gen_frame_mem (DImode,
7609 : : sp_offset),
7610 : : dwarf_reg);
7611 : 34 : RTX_FRAME_RELATED_P (tmp) = 1;
7612 : 34 : XVECEXP (dwarf, 0, i + 1) = tmp;
7613 : : }
7614 : 17 : rtx sp_tmp = gen_rtx_SET (stack_pointer_rtx,
7615 : : plus_constant (Pmode,
7616 : : stack_pointer_rtx,
7617 : : -offset));
7618 : 17 : RTX_FRAME_RELATED_P (sp_tmp) = 1;
7619 : 17 : XVECEXP (dwarf, 0, 0) = sp_tmp;
7620 : 17 : add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
7621 : :
7622 : 17 : loaded_regnum = 0;
7623 : 17 : regno_list[0] = regno_list[1] = -1;
7624 : : }
7625 : : }
7626 : : else
7627 : : {
7628 : 82 : insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
7629 : : use_ppx));
7630 : 82 : RTX_FRAME_RELATED_P (insn) = 1;
7631 : 82 : aligned = true;
7632 : : }
7633 : : }
7634 : 85 : if (loaded_regnum == 1)
7635 : : {
7636 : 6 : insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
7637 : 6 : regno_list[0]),
7638 : : use_ppx));
7639 : 6 : RTX_FRAME_RELATED_P (insn) = 1;
7640 : : }
7641 : : }
7642 : 425333 : }
7643 : :
7644 : : /* Emit a single register save at CFA - CFA_OFFSET. */
7645 : :
7646 : : static void
7647 : 619087 : ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
7648 : : HOST_WIDE_INT cfa_offset)
7649 : : {
7650 : 619087 : struct machine_function *m = cfun->machine;
7651 : 619087 : rtx reg = gen_rtx_REG (mode, regno);
7652 : 619087 : rtx mem, addr, base, insn;
7653 : 619087 : unsigned int align = GET_MODE_ALIGNMENT (mode);
7654 : :
7655 : 619087 : addr = choose_baseaddr (cfa_offset, &align);
7656 : 619087 : mem = gen_frame_mem (mode, addr);
7657 : :
7658 : : /* The location aligment depends upon the base register. */
7659 : 619087 : align = MIN (GET_MODE_ALIGNMENT (mode), align);
7660 : 619087 : gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
7661 : 619087 : set_mem_align (mem, align);
7662 : :
7663 : 619087 : insn = emit_insn (gen_rtx_SET (mem, reg));
7664 : 619087 : RTX_FRAME_RELATED_P (insn) = 1;
7665 : :
7666 : 619087 : base = addr;
7667 : 619087 : if (GET_CODE (base) == PLUS)
7668 : 607146 : base = XEXP (base, 0);
7669 : 619087 : gcc_checking_assert (REG_P (base));
7670 : :
7671 : : /* When saving registers into a re-aligned local stack frame, avoid
7672 : : any tricky guessing by dwarf2out. */
7673 : 619087 : if (m->fs.realigned)
7674 : : {
7675 : 12800 : gcc_checking_assert (stack_realign_drap);
7676 : :
7677 : 12800 : if (regno == REGNO (crtl->drap_reg))
7678 : : {
7679 : : /* A bit of a hack. We force the DRAP register to be saved in
7680 : : the re-aligned stack frame, which provides us with a copy
7681 : : of the CFA that will last past the prologue. Install it. */
7682 : 0 : gcc_checking_assert (cfun->machine->fs.fp_valid);
7683 : 0 : addr = plus_constant (Pmode, hard_frame_pointer_rtx,
7684 : 0 : cfun->machine->fs.fp_offset - cfa_offset);
7685 : 0 : mem = gen_rtx_MEM (mode, addr);
7686 : 0 : add_reg_note (insn, REG_CFA_DEF_CFA, mem);
7687 : : }
7688 : : else
7689 : : {
7690 : : /* The frame pointer is a stable reference within the
7691 : : aligned frame. Use it. */
7692 : 12800 : gcc_checking_assert (cfun->machine->fs.fp_valid);
7693 : 12800 : addr = plus_constant (Pmode, hard_frame_pointer_rtx,
7694 : 12800 : cfun->machine->fs.fp_offset - cfa_offset);
7695 : 12800 : mem = gen_rtx_MEM (mode, addr);
7696 : 12800 : add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
7697 : : }
7698 : : }
7699 : :
7700 : 606287 : else if (base == stack_pointer_rtx && m->fs.sp_realigned
7701 : 12881 : && cfa_offset >= m->fs.sp_realigned_offset)
7702 : : {
7703 : 12881 : gcc_checking_assert (stack_realign_fp);
7704 : 12881 : add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
7705 : : }
7706 : :
7707 : : /* The memory may not be relative to the current CFA register,
7708 : : which means that we may need to generate a new pattern for
7709 : : use by the unwind info. */
7710 : 593406 : else if (base != m->fs.cfa_reg)
7711 : : {
7712 : 45084 : addr = plus_constant (Pmode, m->fs.cfa_reg,
7713 : 45084 : m->fs.cfa_offset - cfa_offset);
7714 : 45084 : mem = gen_rtx_MEM (mode, addr);
7715 : 45084 : add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
7716 : : }
7717 : 619087 : }
7718 : :
7719 : : /* Emit code to save registers using MOV insns.
7720 : : First register is stored at CFA - CFA_OFFSET. */
7721 : : static void
7722 : 46215 : ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
7723 : : {
7724 : 46215 : unsigned int regno;
7725 : :
7726 : 4297995 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
7727 : 4251780 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7728 : : {
7729 : : /* Skip registers, already processed by shrink wrap separate. */
7730 : 195699 : if (!cfun->machine->reg_is_wrapped_separately[regno])
7731 : 87075 : ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
7732 : 209489 : cfa_offset -= UNITS_PER_WORD;
7733 : : }
7734 : 46215 : }
7735 : :
7736 : : /* Emit code to save SSE registers using MOV insns.
7737 : : First register is stored at CFA - CFA_OFFSET. */
7738 : : static void
7739 : 33351 : ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
7740 : : {
7741 : 33351 : unsigned int regno;
7742 : :
7743 : 3101643 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
7744 : 3068292 : if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7745 : : {
7746 : 333525 : ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
7747 : 333525 : cfa_offset -= GET_MODE_SIZE (V4SFmode);
7748 : : }
7749 : 33351 : }
7750 : :
7751 : : static GTY(()) rtx queued_cfa_restores;
7752 : :
7753 : : /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
7754 : : manipulation insn. The value is on the stack at CFA - CFA_OFFSET.
7755 : : Don't add the note if the previously saved value will be left untouched
7756 : : within stack red-zone till return, as unwinders can find the same value
7757 : : in the register and on the stack. */
7758 : :
7759 : : static void
7760 : 2277686 : ix86_add_cfa_restore_note (rtx_insn *insn, rtx reg, HOST_WIDE_INT cfa_offset)
7761 : : {
7762 : 2277686 : if (!crtl->shrink_wrapped
7763 : 2258926 : && cfa_offset <= cfun->machine->fs.red_zone_offset)
7764 : : return;
7765 : :
7766 : 771163 : if (insn)
7767 : : {
7768 : 361124 : add_reg_note (insn, REG_CFA_RESTORE, reg);
7769 : 361124 : RTX_FRAME_RELATED_P (insn) = 1;
7770 : : }
7771 : : else
7772 : 410039 : queued_cfa_restores
7773 : 410039 : = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
7774 : : }
7775 : :
7776 : : /* Add queued REG_CFA_RESTORE notes if any to INSN. */
7777 : :
7778 : : static void
7779 : 2504497 : ix86_add_queued_cfa_restore_notes (rtx insn)
7780 : : {
7781 : 2504497 : rtx last;
7782 : 2504497 : if (!queued_cfa_restores)
7783 : : return;
7784 : 410039 : for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
7785 : : ;
7786 : 52876 : XEXP (last, 1) = REG_NOTES (insn);
7787 : 52876 : REG_NOTES (insn) = queued_cfa_restores;
7788 : 52876 : queued_cfa_restores = NULL_RTX;
7789 : 52876 : RTX_FRAME_RELATED_P (insn) = 1;
7790 : : }
7791 : :
7792 : : /* Expand prologue or epilogue stack adjustment.
7793 : : The pattern exist to put a dependency on all ebp-based memory accesses.
7794 : : STYLE should be negative if instructions should be marked as frame related,
7795 : : zero if %r11 register is live and cannot be freely used and positive
7796 : : otherwise. */
7797 : :
7798 : : static rtx
7799 : 1572626 : pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
7800 : : int style, bool set_cfa)
7801 : : {
7802 : 1572626 : struct machine_function *m = cfun->machine;
7803 : 1572626 : rtx addend = offset;
7804 : 1572626 : rtx insn;
7805 : 1572626 : bool add_frame_related_expr = false;
7806 : :
7807 : 1788952 : if (!x86_64_immediate_operand (offset, Pmode))
7808 : : {
7809 : : /* r11 is used by indirect sibcall return as well, set before the
7810 : : epilogue and used after the epilogue. */
7811 : 204 : if (style)
7812 : 179 : addend = gen_rtx_REG (Pmode, R11_REG);
7813 : : else
7814 : : {
7815 : 25 : gcc_assert (src != hard_frame_pointer_rtx
7816 : : && dest != hard_frame_pointer_rtx);
7817 : : addend = hard_frame_pointer_rtx;
7818 : : }
7819 : 204 : emit_insn (gen_rtx_SET (addend, offset));
7820 : 204 : if (style < 0)
7821 : 92 : add_frame_related_expr = true;
7822 : : }
7823 : :
7824 : : /* Shrink wrap separate may insert prologue between TEST and JMP. In order
7825 : : not to affect EFlags, emit add without reg clobbering. */
7826 : 1572626 : if (crtl->shrink_wrapped_separate)
7827 : 99183 : insn = emit_insn (gen_pro_epilogue_adjust_stack_add_nocc
7828 : 99183 : (Pmode, dest, src, addend));
7829 : : else
7830 : 1473443 : insn = emit_insn (gen_pro_epilogue_adjust_stack_add
7831 : 1473443 : (Pmode, dest, src, addend));
7832 : :
7833 : 1572626 : if (style >= 0)
7834 : 694959 : ix86_add_queued_cfa_restore_notes (insn);
7835 : :
7836 : 1572626 : if (set_cfa)
7837 : : {
7838 : 1218499 : rtx r;
7839 : :
7840 : 1218499 : gcc_assert (m->fs.cfa_reg == src);
7841 : 1218499 : m->fs.cfa_offset += INTVAL (offset);
7842 : 1218499 : m->fs.cfa_reg = dest;
7843 : :
7844 : 1412550 : r = gen_rtx_PLUS (Pmode, src, offset);
7845 : 1218499 : r = gen_rtx_SET (dest, r);
7846 : 1218499 : add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
7847 : 1218499 : RTX_FRAME_RELATED_P (insn) = 1;
7848 : : }
7849 : 354127 : else if (style < 0)
7850 : : {
7851 : 288869 : RTX_FRAME_RELATED_P (insn) = 1;
7852 : 288869 : if (add_frame_related_expr)
7853 : : {
7854 : 23 : rtx r = gen_rtx_PLUS (Pmode, src, offset);
7855 : 23 : r = gen_rtx_SET (dest, r);
7856 : 23 : add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
7857 : : }
7858 : : }
7859 : :
7860 : 1572626 : if (dest == stack_pointer_rtx)
7861 : : {
7862 : 1572626 : HOST_WIDE_INT ooffset = m->fs.sp_offset;
7863 : 1572626 : bool valid = m->fs.sp_valid;
7864 : 1572626 : bool realigned = m->fs.sp_realigned;
7865 : :
7866 : 1572626 : if (src == hard_frame_pointer_rtx)
7867 : : {
7868 : 29130 : valid = m->fs.fp_valid;
7869 : 29130 : realigned = false;
7870 : 29130 : ooffset = m->fs.fp_offset;
7871 : : }
7872 : 1543496 : else if (src == crtl->drap_reg)
7873 : : {
7874 : 0 : valid = m->fs.drap_valid;
7875 : 0 : realigned = false;
7876 : 0 : ooffset = 0;
7877 : : }
7878 : : else
7879 : : {
7880 : : /* Else there are two possibilities: SP itself, which we set
7881 : : up as the default above. Or EH_RETURN_STACKADJ_RTX, which is
7882 : : taken care of this by hand along the eh_return path. */
7883 : 1543496 : gcc_checking_assert (src == stack_pointer_rtx
7884 : : || offset == const0_rtx);
7885 : : }
7886 : :
7887 : 1572626 : m->fs.sp_offset = ooffset - INTVAL (offset);
7888 : 1572626 : m->fs.sp_valid = valid;
7889 : 1572626 : m->fs.sp_realigned = realigned;
7890 : : }
7891 : 1572626 : return insn;
7892 : : }
7893 : :
7894 : : /* Find an available register to be used as dynamic realign argument
7895 : : pointer regsiter. Such a register will be written in prologue and
7896 : : used in begin of body, so it must not be
7897 : : 1. parameter passing register.
7898 : : 2. GOT pointer.
7899 : : We reuse static-chain register if it is available. Otherwise, we
7900 : : use DI for i386 and R13 for x86-64. We chose R13 since it has
7901 : : shorter encoding.
7902 : :
7903 : : Return: the regno of chosen register. */
7904 : :
7905 : : static unsigned int
7906 : 7128 : find_drap_reg (void)
7907 : : {
7908 : 7128 : tree decl = cfun->decl;
7909 : :
7910 : : /* Always use callee-saved register if there are no caller-saved
7911 : : registers. */
7912 : 7128 : if (TARGET_64BIT)
7913 : : {
7914 : : /* Use R13 for nested function or function need static chain.
7915 : : Since function with tail call may use any caller-saved
7916 : : registers in epilogue, DRAP must not use caller-saved
7917 : : register in such case. */
7918 : 6847 : if (DECL_STATIC_CHAIN (decl)
7919 : 6805 : || (cfun->machine->call_saved_registers
7920 : 6805 : == TYPE_NO_CALLER_SAVED_REGISTERS)
7921 : 13652 : || crtl->tail_call_emit)
7922 : 187 : return R13_REG;
7923 : :
7924 : : return R10_REG;
7925 : : }
7926 : : else
7927 : : {
7928 : : /* Use DI for nested function or function need static chain.
7929 : : Since function with tail call may use any caller-saved
7930 : : registers in epilogue, DRAP must not use caller-saved
7931 : : register in such case. */
7932 : 281 : if (DECL_STATIC_CHAIN (decl)
7933 : 281 : || (cfun->machine->call_saved_registers
7934 : 281 : == TYPE_NO_CALLER_SAVED_REGISTERS)
7935 : 281 : || crtl->tail_call_emit
7936 : 542 : || crtl->calls_eh_return)
7937 : : return DI_REG;
7938 : :
7939 : : /* Reuse static chain register if it isn't used for parameter
7940 : : passing. */
7941 : 261 : if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
7942 : : {
7943 : 261 : unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
7944 : 261 : if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
7945 : : return CX_REG;
7946 : : }
7947 : 0 : return DI_REG;
7948 : : }
7949 : : }
7950 : :
7951 : : /* Return minimum incoming stack alignment. */
7952 : :
7953 : : static unsigned int
7954 : 1580223 : ix86_minimum_incoming_stack_boundary (bool sibcall)
7955 : : {
7956 : 1580223 : unsigned int incoming_stack_boundary;
7957 : :
7958 : : /* Stack of interrupt handler is aligned to 128 bits in 64bit mode. */
7959 : 1580223 : if (cfun->machine->func_type != TYPE_NORMAL)
7960 : 118 : incoming_stack_boundary = TARGET_64BIT ? 128 : MIN_STACK_BOUNDARY;
7961 : : /* Prefer the one specified at command line. */
7962 : 1580105 : else if (ix86_user_incoming_stack_boundary)
7963 : : incoming_stack_boundary = ix86_user_incoming_stack_boundary;
7964 : : /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
7965 : : if -mstackrealign is used, it isn't used for sibcall check and
7966 : : estimated stack alignment is 128bit. */
7967 : 1580083 : else if (!sibcall
7968 : 1449700 : && ix86_force_align_arg_pointer
7969 : 4572 : && crtl->stack_alignment_estimated == 128)
7970 : 596 : incoming_stack_boundary = MIN_STACK_BOUNDARY;
7971 : : else
7972 : 1579487 : incoming_stack_boundary = ix86_default_incoming_stack_boundary;
7973 : :
7974 : : /* Incoming stack alignment can be changed on individual functions
7975 : : via force_align_arg_pointer attribute. We use the smallest
7976 : : incoming stack boundary. */
7977 : 1580223 : if (incoming_stack_boundary > MIN_STACK_BOUNDARY
7978 : 3159840 : && lookup_attribute ("force_align_arg_pointer",
7979 : 1579617 : TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
7980 : 5708 : incoming_stack_boundary = MIN_STACK_BOUNDARY;
7981 : :
7982 : : /* The incoming stack frame has to be aligned at least at
7983 : : parm_stack_boundary. */
7984 : 1580223 : if (incoming_stack_boundary < crtl->parm_stack_boundary)
7985 : : incoming_stack_boundary = crtl->parm_stack_boundary;
7986 : :
7987 : : /* Stack at entrance of main is aligned by runtime. We use the
7988 : : smallest incoming stack boundary. */
7989 : 1580223 : if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
7990 : 139354 : && DECL_NAME (current_function_decl)
7991 : 139354 : && MAIN_NAME_P (DECL_NAME (current_function_decl))
7992 : 1582693 : && DECL_FILE_SCOPE_P (current_function_decl))
7993 : 2470 : incoming_stack_boundary = MAIN_STACK_BOUNDARY;
7994 : :
7995 : 1580223 : return incoming_stack_boundary;
7996 : : }
7997 : :
7998 : : /* Update incoming stack boundary and estimated stack alignment. */
7999 : :
8000 : : static void
8001 : 1449835 : ix86_update_stack_boundary (void)
8002 : : {
8003 : 1449835 : ix86_incoming_stack_boundary
8004 : 1449835 : = ix86_minimum_incoming_stack_boundary (false);
8005 : :
8006 : : /* x86_64 vararg needs 16byte stack alignment for register save area. */
8007 : 1449835 : if (TARGET_64BIT
8008 : 1324287 : && cfun->stdarg
8009 : 21199 : && crtl->stack_alignment_estimated < 128)
8010 : 10150 : crtl->stack_alignment_estimated = 128;
8011 : :
8012 : : /* __tls_get_addr needs to be called with 16-byte aligned stack. */
8013 : 1449835 : if (ix86_tls_descriptor_calls_expanded_in_cfun
8014 : 1281 : && crtl->preferred_stack_boundary < 128)
8015 : 933 : crtl->preferred_stack_boundary = 128;
8016 : :
8017 : : /* For 32-bit MS ABI, both the incoming and preferred stack boundaries
8018 : : are 32 bits, but if force_align_arg_pointer is specified, it should
8019 : : prefer 128 bits for a backward-compatibility reason, which is also
8020 : : what the doc suggests. */
8021 : 1449835 : if (lookup_attribute ("force_align_arg_pointer",
8022 : 1449835 : TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))
8023 : 1449835 : && crtl->preferred_stack_boundary < 128)
8024 : 4 : crtl->preferred_stack_boundary = 128;
8025 : 1449835 : }
8026 : :
8027 : : /* Handle the TARGET_GET_DRAP_RTX hook. Return NULL if no DRAP is
8028 : : needed or an rtx for DRAP otherwise. */
8029 : :
8030 : : static rtx
8031 : 1559500 : ix86_get_drap_rtx (void)
8032 : : {
8033 : : /* We must use DRAP if there are outgoing arguments on stack or
8034 : : the stack pointer register is clobbered by asm statment and
8035 : : ACCUMULATE_OUTGOING_ARGS is false. */
8036 : 1559500 : if (ix86_force_drap
8037 : 1559500 : || ((cfun->machine->outgoing_args_on_stack
8038 : 1230626 : || crtl->sp_is_clobbered_by_asm)
8039 : 326929 : && !ACCUMULATE_OUTGOING_ARGS))
8040 : 306735 : crtl->need_drap = true;
8041 : :
8042 : 1559500 : if (stack_realign_drap)
8043 : : {
8044 : : /* Assign DRAP to vDRAP and returns vDRAP */
8045 : 7128 : unsigned int regno = find_drap_reg ();
8046 : 7128 : rtx drap_vreg;
8047 : 7128 : rtx arg_ptr;
8048 : 7128 : rtx_insn *seq, *insn;
8049 : :
8050 : 7409 : arg_ptr = gen_rtx_REG (Pmode, regno);
8051 : 7128 : crtl->drap_reg = arg_ptr;
8052 : :
8053 : 7128 : start_sequence ();
8054 : 7128 : drap_vreg = copy_to_reg (arg_ptr);
8055 : 7128 : seq = end_sequence ();
8056 : :
8057 : 7128 : insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
8058 : 7128 : if (!optimize)
8059 : : {
8060 : 1882 : add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
8061 : 1882 : RTX_FRAME_RELATED_P (insn) = 1;
8062 : : }
8063 : 7128 : return drap_vreg;
8064 : : }
8065 : : else
8066 : : return NULL;
8067 : : }
8068 : :
8069 : : /* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
8070 : :
8071 : : static rtx
8072 : 1449835 : ix86_internal_arg_pointer (void)
8073 : : {
8074 : 1449835 : return virtual_incoming_args_rtx;
8075 : : }
8076 : :
8077 : : struct scratch_reg {
8078 : : rtx reg;
8079 : : bool saved;
8080 : : };
8081 : :
8082 : : /* Return a short-lived scratch register for use on function entry.
8083 : : In 32-bit mode, it is valid only after the registers are saved
8084 : : in the prologue. This register must be released by means of
8085 : : release_scratch_register_on_entry once it is dead. */
8086 : :
8087 : : static void
8088 : 25 : get_scratch_register_on_entry (struct scratch_reg *sr)
8089 : : {
8090 : 25 : int regno;
8091 : :
8092 : 25 : sr->saved = false;
8093 : :
8094 : 25 : if (TARGET_64BIT)
8095 : : {
8096 : : /* We always use R11 in 64-bit mode. */
8097 : : regno = R11_REG;
8098 : : }
8099 : : else
8100 : : {
8101 : 0 : tree decl = current_function_decl, fntype = TREE_TYPE (decl);
8102 : 0 : bool fastcall_p
8103 : 0 : = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
8104 : 0 : bool thiscall_p
8105 : 0 : = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
8106 : 0 : bool static_chain_p = DECL_STATIC_CHAIN (decl);
8107 : 0 : int regparm = ix86_function_regparm (fntype, decl);
8108 : 0 : int drap_regno
8109 : 0 : = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
8110 : :
8111 : : /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
8112 : : for the static chain register. */
8113 : 0 : if ((regparm < 1 || (fastcall_p && !static_chain_p))
8114 : 0 : && drap_regno != AX_REG)
8115 : : regno = AX_REG;
8116 : : /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
8117 : : for the static chain register. */
8118 : 0 : else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
8119 : : regno = AX_REG;
8120 : 0 : else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
8121 : : regno = DX_REG;
8122 : : /* ecx is the static chain register. */
8123 : 0 : else if (regparm < 3 && !fastcall_p && !thiscall_p
8124 : 0 : && !static_chain_p
8125 : 0 : && drap_regno != CX_REG)
8126 : : regno = CX_REG;
8127 : 0 : else if (ix86_save_reg (BX_REG, true, false))
8128 : : regno = BX_REG;
8129 : : /* esi is the static chain register. */
8130 : 0 : else if (!(regparm == 3 && static_chain_p)
8131 : 0 : && ix86_save_reg (SI_REG, true, false))
8132 : : regno = SI_REG;
8133 : 0 : else if (ix86_save_reg (DI_REG, true, false))
8134 : : regno = DI_REG;
8135 : : else
8136 : : {
8137 : 0 : regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
8138 : 0 : sr->saved = true;
8139 : : }
8140 : : }
8141 : :
8142 : 25 : sr->reg = gen_rtx_REG (Pmode, regno);
8143 : 25 : if (sr->saved)
8144 : : {
8145 : 0 : rtx_insn *insn = emit_insn (gen_push (sr->reg));
8146 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
8147 : : }
8148 : 25 : }
8149 : :
8150 : : /* Release a scratch register obtained from the preceding function.
8151 : :
8152 : : If RELEASE_VIA_POP is true, we just pop the register off the stack
8153 : : to release it. This is what non-Linux systems use with -fstack-check.
8154 : :
8155 : : Otherwise we use OFFSET to locate the saved register and the
8156 : : allocated stack space becomes part of the local frame and is
8157 : : deallocated by the epilogue. */
8158 : :
8159 : : static void
8160 : 25 : release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
8161 : : bool release_via_pop)
8162 : : {
8163 : 25 : if (sr->saved)
8164 : : {
8165 : 0 : if (release_via_pop)
8166 : : {
8167 : 0 : struct machine_function *m = cfun->machine;
8168 : 0 : rtx x, insn = emit_insn (gen_pop (sr->reg));
8169 : :
8170 : : /* The RX FRAME_RELATED_P mechanism doesn't know about pop. */
8171 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
8172 : 0 : x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
8173 : 0 : x = gen_rtx_SET (stack_pointer_rtx, x);
8174 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
8175 : 0 : m->fs.sp_offset -= UNITS_PER_WORD;
8176 : : }
8177 : : else
8178 : : {
8179 : 0 : rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
8180 : 0 : x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
8181 : 0 : emit_insn (x);
8182 : : }
8183 : : }
8184 : 25 : }
8185 : :
8186 : : /* Emit code to adjust the stack pointer by SIZE bytes while probing it.
8187 : :
8188 : : If INT_REGISTERS_SAVED is true, then integer registers have already been
8189 : : pushed on the stack.
8190 : :
8191 : : If PROTECTION AREA is true, then probe PROBE_INTERVAL plus a small dope
8192 : : beyond SIZE bytes.
8193 : :
8194 : : This assumes no knowledge of the current probing state, i.e. it is never
8195 : : allowed to allocate more than PROBE_INTERVAL bytes of stack space without
8196 : : a suitable probe. */
8197 : :
8198 : : static void
8199 : 126 : ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
8200 : : const bool int_registers_saved,
8201 : : const bool protection_area)
8202 : : {
8203 : 126 : struct machine_function *m = cfun->machine;
8204 : :
8205 : : /* If this function does not statically allocate stack space, then
8206 : : no probes are needed. */
8207 : 126 : if (!size)
8208 : : {
8209 : : /* However, the allocation of space via pushes for register
8210 : : saves could be viewed as allocating space, but without the
8211 : : need to probe. */
8212 : 43 : if (m->frame.nregs || m->frame.nsseregs || frame_pointer_needed)
8213 : 23 : dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
8214 : : else
8215 : 20 : dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
8216 : 43 : return;
8217 : : }
8218 : :
8219 : : /* If we are a noreturn function, then we have to consider the
8220 : : possibility that we're called via a jump rather than a call.
8221 : :
8222 : : Thus we don't have the implicit probe generated by saving the
8223 : : return address into the stack at the call. Thus, the stack
8224 : : pointer could be anywhere in the guard page. The safe thing
8225 : : to do is emit a probe now.
8226 : :
8227 : : The probe can be avoided if we have already emitted any callee
8228 : : register saves into the stack or have a frame pointer (which will
8229 : : have been saved as well). Those saves will function as implicit
8230 : : probes.
8231 : :
8232 : : ?!? This should be revamped to work like aarch64 and s390 where
8233 : : we track the offset from the most recent probe. Normally that
8234 : : offset would be zero. For a noreturn function we would reset
8235 : : it to PROBE_INTERVAL - (STACK_BOUNDARY / BITS_PER_UNIT). Then
8236 : : we just probe when we cross PROBE_INTERVAL. */
8237 : 83 : if (TREE_THIS_VOLATILE (cfun->decl)
8238 : 15 : && !(m->frame.nregs || m->frame.nsseregs || frame_pointer_needed))
8239 : : {
8240 : : /* We can safely use any register here since we're just going to push
8241 : : its value and immediately pop it back. But we do try and avoid
8242 : : argument passing registers so as not to introduce dependencies in
8243 : : the pipeline. For 32 bit we use %esi and for 64 bit we use %rax. */
8244 : 15 : rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
8245 : 15 : rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
8246 : 15 : rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
8247 : 15 : m->fs.sp_offset -= UNITS_PER_WORD;
8248 : 15 : if (m->fs.cfa_reg == stack_pointer_rtx)
8249 : : {
8250 : 15 : m->fs.cfa_offset -= UNITS_PER_WORD;
8251 : 15 : rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
8252 : 15 : x = gen_rtx_SET (stack_pointer_rtx, x);
8253 : 15 : add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
8254 : 15 : RTX_FRAME_RELATED_P (insn_push) = 1;
8255 : 15 : x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
8256 : 15 : x = gen_rtx_SET (stack_pointer_rtx, x);
8257 : 15 : add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
8258 : 15 : RTX_FRAME_RELATED_P (insn_pop) = 1;
8259 : : }
8260 : 15 : emit_insn (gen_blockage ());
8261 : : }
8262 : :
8263 : 83 : const HOST_WIDE_INT probe_interval = get_probe_interval ();
8264 : 83 : const int dope = 4 * UNITS_PER_WORD;
8265 : :
8266 : : /* If there is protection area, take it into account in the size. */
8267 : 83 : if (protection_area)
8268 : 25 : size += probe_interval + dope;
8269 : :
8270 : : /* If we allocate less than the size of the guard statically,
8271 : : then no probing is necessary, but we do need to allocate
8272 : : the stack. */
8273 : 58 : else if (size < (1 << param_stack_clash_protection_guard_size))
8274 : : {
8275 : 37 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8276 : : GEN_INT (-size), -1,
8277 : 37 : m->fs.cfa_reg == stack_pointer_rtx);
8278 : 37 : dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
8279 : 37 : return;
8280 : : }
8281 : :
8282 : : /* We're allocating a large enough stack frame that we need to
8283 : : emit probes. Either emit them inline or in a loop depending
8284 : : on the size. */
8285 : 46 : if (size <= 4 * probe_interval)
8286 : : {
8287 : : HOST_WIDE_INT i;
8288 : 49 : for (i = probe_interval; i <= size; i += probe_interval)
8289 : : {
8290 : : /* Allocate PROBE_INTERVAL bytes. */
8291 : 28 : rtx insn
8292 : 28 : = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8293 : : GEN_INT (-probe_interval), -1,
8294 : 28 : m->fs.cfa_reg == stack_pointer_rtx);
8295 : 28 : add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
8296 : :
8297 : : /* And probe at *sp. */
8298 : 28 : emit_stack_probe (stack_pointer_rtx);
8299 : 28 : emit_insn (gen_blockage ());
8300 : : }
8301 : :
8302 : : /* We need to allocate space for the residual, but we do not need
8303 : : to probe the residual... */
8304 : 21 : HOST_WIDE_INT residual = (i - probe_interval - size);
8305 : 21 : if (residual)
8306 : : {
8307 : 21 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8308 : : GEN_INT (residual), -1,
8309 : 21 : m->fs.cfa_reg == stack_pointer_rtx);
8310 : :
8311 : : /* ...except if there is a protection area to maintain. */
8312 : 21 : if (protection_area)
8313 : 12 : emit_stack_probe (stack_pointer_rtx);
8314 : : }
8315 : :
8316 : 21 : dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
8317 : : }
8318 : : else
8319 : : {
8320 : : /* We expect the GP registers to be saved when probes are used
8321 : : as the probing sequences might need a scratch register and
8322 : : the routine to allocate one assumes the integer registers
8323 : : have already been saved. */
8324 : 25 : gcc_assert (int_registers_saved);
8325 : :
8326 : 25 : struct scratch_reg sr;
8327 : 25 : get_scratch_register_on_entry (&sr);
8328 : :
8329 : : /* If we needed to save a register, then account for any space
8330 : : that was pushed (we are not going to pop the register when
8331 : : we do the restore). */
8332 : 25 : if (sr.saved)
8333 : 0 : size -= UNITS_PER_WORD;
8334 : :
8335 : : /* Step 1: round SIZE down to a multiple of the interval. */
8336 : 25 : HOST_WIDE_INT rounded_size = size & -probe_interval;
8337 : :
8338 : : /* Step 2: compute final value of the loop counter. Use lea if
8339 : : possible. */
8340 : 25 : rtx addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
8341 : 25 : rtx insn;
8342 : 25 : if (address_no_seg_operand (addr, Pmode))
8343 : 13 : insn = emit_insn (gen_rtx_SET (sr.reg, addr));
8344 : : else
8345 : : {
8346 : 12 : emit_move_insn (sr.reg, GEN_INT (-rounded_size));
8347 : 12 : insn = emit_insn (gen_rtx_SET (sr.reg,
8348 : : gen_rtx_PLUS (Pmode, sr.reg,
8349 : : stack_pointer_rtx)));
8350 : : }
8351 : 25 : if (m->fs.cfa_reg == stack_pointer_rtx)
8352 : : {
8353 : 22 : add_reg_note (insn, REG_CFA_DEF_CFA,
8354 : 22 : plus_constant (Pmode, sr.reg,
8355 : 22 : m->fs.cfa_offset + rounded_size));
8356 : 22 : RTX_FRAME_RELATED_P (insn) = 1;
8357 : : }
8358 : :
8359 : : /* Step 3: the loop. */
8360 : 25 : rtx size_rtx = GEN_INT (rounded_size);
8361 : 25 : insn = emit_insn (gen_adjust_stack_and_probe (Pmode, sr.reg, sr.reg,
8362 : : size_rtx));
8363 : 25 : if (m->fs.cfa_reg == stack_pointer_rtx)
8364 : : {
8365 : 22 : m->fs.cfa_offset += rounded_size;
8366 : 22 : add_reg_note (insn, REG_CFA_DEF_CFA,
8367 : 22 : plus_constant (Pmode, stack_pointer_rtx,
8368 : 22 : m->fs.cfa_offset));
8369 : 22 : RTX_FRAME_RELATED_P (insn) = 1;
8370 : : }
8371 : 25 : m->fs.sp_offset += rounded_size;
8372 : 25 : emit_insn (gen_blockage ());
8373 : :
8374 : : /* Step 4: adjust SP if we cannot assert at compile-time that SIZE
8375 : : is equal to ROUNDED_SIZE. */
8376 : :
8377 : 25 : if (size != rounded_size)
8378 : : {
8379 : 25 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8380 : : GEN_INT (rounded_size - size), -1,
8381 : 25 : m->fs.cfa_reg == stack_pointer_rtx);
8382 : :
8383 : 25 : if (protection_area)
8384 : 13 : emit_stack_probe (stack_pointer_rtx);
8385 : : }
8386 : :
8387 : 25 : dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
8388 : :
8389 : : /* This does not deallocate the space reserved for the scratch
8390 : : register. That will be deallocated in the epilogue. */
8391 : 25 : release_scratch_register_on_entry (&sr, size, false);
8392 : : }
8393 : :
8394 : : /* Adjust back to account for the protection area. */
8395 : 46 : if (protection_area)
8396 : 25 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8397 : 25 : GEN_INT (probe_interval + dope), -1,
8398 : 25 : m->fs.cfa_reg == stack_pointer_rtx);
8399 : :
8400 : : /* Make sure nothing is scheduled before we are done. */
8401 : 46 : emit_insn (gen_blockage ());
8402 : : }
8403 : :
8404 : : /* Adjust the stack pointer up to REG while probing it. */
8405 : :
8406 : : const char *
8407 : 25 : output_adjust_stack_and_probe (rtx reg)
8408 : : {
8409 : 25 : static int labelno = 0;
8410 : 25 : char loop_lab[32];
8411 : 25 : rtx xops[2];
8412 : :
8413 : 25 : ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
8414 : :
8415 : : /* Loop. */
8416 : 25 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
8417 : :
8418 : : /* SP = SP + PROBE_INTERVAL. */
8419 : 25 : xops[0] = stack_pointer_rtx;
8420 : 37 : xops[1] = GEN_INT (get_probe_interval ());
8421 : 25 : output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
8422 : :
8423 : : /* Probe at SP. */
8424 : 25 : xops[1] = const0_rtx;
8425 : 25 : output_asm_insn ("or%z0\t{%1, (%0)|DWORD PTR [%0], %1}", xops);
8426 : :
8427 : : /* Test if SP == LAST_ADDR. */
8428 : 25 : xops[0] = stack_pointer_rtx;
8429 : 25 : xops[1] = reg;
8430 : 25 : output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
8431 : :
8432 : : /* Branch. */
8433 : 25 : fputs ("\tjne\t", asm_out_file);
8434 : 25 : assemble_name_raw (asm_out_file, loop_lab);
8435 : 25 : fputc ('\n', asm_out_file);
8436 : :
8437 : 25 : return "";
8438 : : }
8439 : :
8440 : : /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
8441 : : inclusive. These are offsets from the current stack pointer.
8442 : :
8443 : : INT_REGISTERS_SAVED is true if integer registers have already been
8444 : : pushed on the stack. */
8445 : :
8446 : : static void
8447 : 0 : ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
8448 : : const bool int_registers_saved)
8449 : : {
8450 : 0 : const HOST_WIDE_INT probe_interval = get_probe_interval ();
8451 : :
8452 : : /* See if we have a constant small number of probes to generate. If so,
8453 : : that's the easy case. The run-time loop is made up of 6 insns in the
8454 : : generic case while the compile-time loop is made up of n insns for n #
8455 : : of intervals. */
8456 : 0 : if (size <= 6 * probe_interval)
8457 : : {
8458 : : HOST_WIDE_INT i;
8459 : :
8460 : : /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
8461 : : it exceeds SIZE. If only one probe is needed, this will not
8462 : : generate any code. Then probe at FIRST + SIZE. */
8463 : 0 : for (i = probe_interval; i < size; i += probe_interval)
8464 : 0 : emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
8465 : 0 : -(first + i)));
8466 : :
8467 : 0 : emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
8468 : 0 : -(first + size)));
8469 : : }
8470 : :
8471 : : /* Otherwise, do the same as above, but in a loop. Note that we must be
8472 : : extra careful with variables wrapping around because we might be at
8473 : : the very top (or the very bottom) of the address space and we have
8474 : : to be able to handle this case properly; in particular, we use an
8475 : : equality test for the loop condition. */
8476 : : else
8477 : : {
8478 : : /* We expect the GP registers to be saved when probes are used
8479 : : as the probing sequences might need a scratch register and
8480 : : the routine to allocate one assumes the integer registers
8481 : : have already been saved. */
8482 : 0 : gcc_assert (int_registers_saved);
8483 : :
8484 : 0 : HOST_WIDE_INT rounded_size, last;
8485 : 0 : struct scratch_reg sr;
8486 : :
8487 : 0 : get_scratch_register_on_entry (&sr);
8488 : :
8489 : :
8490 : : /* Step 1: round SIZE to the previous multiple of the interval. */
8491 : :
8492 : 0 : rounded_size = ROUND_DOWN (size, probe_interval);
8493 : :
8494 : :
8495 : : /* Step 2: compute initial and final value of the loop counter. */
8496 : :
8497 : : /* TEST_OFFSET = FIRST. */
8498 : 0 : emit_move_insn (sr.reg, GEN_INT (-first));
8499 : :
8500 : : /* LAST_OFFSET = FIRST + ROUNDED_SIZE. */
8501 : 0 : last = first + rounded_size;
8502 : :
8503 : :
8504 : : /* Step 3: the loop
8505 : :
8506 : : do
8507 : : {
8508 : : TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
8509 : : probe at TEST_ADDR
8510 : : }
8511 : : while (TEST_ADDR != LAST_ADDR)
8512 : :
8513 : : probes at FIRST + N * PROBE_INTERVAL for values of N from 1
8514 : : until it is equal to ROUNDED_SIZE. */
8515 : :
8516 : 0 : emit_insn
8517 : 0 : (gen_probe_stack_range (Pmode, sr.reg, sr.reg, GEN_INT (-last)));
8518 : :
8519 : :
8520 : : /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
8521 : : that SIZE is equal to ROUNDED_SIZE. */
8522 : :
8523 : 0 : if (size != rounded_size)
8524 : 0 : emit_stack_probe (plus_constant (Pmode,
8525 : 0 : gen_rtx_PLUS (Pmode,
8526 : : stack_pointer_rtx,
8527 : : sr.reg),
8528 : 0 : rounded_size - size));
8529 : :
8530 : 0 : release_scratch_register_on_entry (&sr, size, true);
8531 : : }
8532 : :
8533 : : /* Make sure nothing is scheduled before we are done. */
8534 : 0 : emit_insn (gen_blockage ());
8535 : 0 : }
8536 : :
8537 : : /* Probe a range of stack addresses from REG to END, inclusive. These are
8538 : : offsets from the current stack pointer. */
8539 : :
8540 : : const char *
8541 : 0 : output_probe_stack_range (rtx reg, rtx end)
8542 : : {
8543 : 0 : static int labelno = 0;
8544 : 0 : char loop_lab[32];
8545 : 0 : rtx xops[3];
8546 : :
8547 : 0 : ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
8548 : :
8549 : : /* Loop. */
8550 : 0 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
8551 : :
8552 : : /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
8553 : 0 : xops[0] = reg;
8554 : 0 : xops[1] = GEN_INT (get_probe_interval ());
8555 : 0 : output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
8556 : :
8557 : : /* Probe at TEST_ADDR. */
8558 : 0 : xops[0] = stack_pointer_rtx;
8559 : 0 : xops[1] = reg;
8560 : 0 : xops[2] = const0_rtx;
8561 : 0 : output_asm_insn ("or%z0\t{%2, (%0,%1)|DWORD PTR [%0+%1], %2}", xops);
8562 : :
8563 : : /* Test if TEST_ADDR == LAST_ADDR. */
8564 : 0 : xops[0] = reg;
8565 : 0 : xops[1] = end;
8566 : 0 : output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
8567 : :
8568 : : /* Branch. */
8569 : 0 : fputs ("\tjne\t", asm_out_file);
8570 : 0 : assemble_name_raw (asm_out_file, loop_lab);
8571 : 0 : fputc ('\n', asm_out_file);
8572 : :
8573 : 0 : return "";
8574 : : }
8575 : :
8576 : : /* Data passed to ix86_update_stack_alignment. */
8577 : : struct stack_access_data
8578 : : {
8579 : : /* The stack access register. */
8580 : : const_rtx reg;
8581 : : /* Pointer to stack alignment. */
8582 : : unsigned int *stack_alignment;
8583 : : };
8584 : :
8585 : : /* Update the maximum stack slot alignment from memory alignment in PAT. */
8586 : :
8587 : : static void
8588 : 53452396 : ix86_update_stack_alignment (rtx, const_rtx pat, void *data)
8589 : : {
8590 : : /* This insn may reference stack slot. Update the maximum stack slot
8591 : : alignment if the memory is referenced by the stack access register. */
8592 : 53452396 : stack_access_data *p = (stack_access_data *) data;
8593 : :
8594 : 53452396 : subrtx_iterator::array_type array;
8595 : 206814814 : FOR_EACH_SUBRTX (iter, array, pat, ALL)
8596 : : {
8597 : 175488577 : auto op = *iter;
8598 : 175488577 : if (MEM_P (op))
8599 : : {
8600 : 27653360 : if (reg_mentioned_p (p->reg, XEXP (op, 0)))
8601 : : {
8602 : 22126159 : unsigned int alignment = MEM_ALIGN (op);
8603 : :
8604 : 22126159 : if (alignment > *p->stack_alignment)
8605 : 57821 : *p->stack_alignment = alignment;
8606 : : break;
8607 : : }
8608 : : else
8609 : 5527201 : iter.skip_subrtxes ();
8610 : : }
8611 : : }
8612 : 53452396 : }
8613 : :
8614 : : /* Helper function for ix86_find_all_reg_uses. */
8615 : :
8616 : : static void
8617 : 44894518 : ix86_find_all_reg_uses_1 (HARD_REG_SET ®set,
8618 : : rtx set, unsigned int regno,
8619 : : auto_bitmap &worklist)
8620 : : {
8621 : 44894518 : rtx dest = SET_DEST (set);
8622 : :
8623 : 44894518 : if (!REG_P (dest))
8624 : 40631424 : return;
8625 : :
8626 : : /* Reject non-Pmode modes. */
8627 : 34060957 : if (GET_MODE (dest) != Pmode)
8628 : : return;
8629 : :
8630 : 17947678 : unsigned int dst_regno = REGNO (dest);
8631 : :
8632 : 17947678 : if (TEST_HARD_REG_BIT (regset, dst_regno))
8633 : : return;
8634 : :
8635 : 4263094 : const_rtx src = SET_SRC (set);
8636 : :
8637 : 4263094 : subrtx_iterator::array_type array;
8638 : 8476458 : FOR_EACH_SUBRTX (iter, array, src, ALL)
8639 : : {
8640 : 5512431 : auto op = *iter;
8641 : :
8642 : 5512431 : if (MEM_P (op))
8643 : 2951134 : iter.skip_subrtxes ();
8644 : :
8645 : 5512431 : if (REG_P (op) && REGNO (op) == regno)
8646 : : {
8647 : : /* Add this register to register set. */
8648 : 1467221 : add_to_hard_reg_set (®set, Pmode, dst_regno);
8649 : 1299067 : bitmap_set_bit (worklist, dst_regno);
8650 : 1299067 : break;
8651 : : }
8652 : : }
8653 : 4263094 : }
8654 : :
8655 : : /* Find all registers defined with register REGNO. */
8656 : :
8657 : : static void
8658 : 2302838 : ix86_find_all_reg_uses (HARD_REG_SET ®set,
8659 : : unsigned int regno, auto_bitmap &worklist)
8660 : : {
8661 : 2302838 : for (df_ref ref = DF_REG_USE_CHAIN (regno);
8662 : 80143070 : ref != NULL;
8663 : 77840232 : ref = DF_REF_NEXT_REG (ref))
8664 : : {
8665 : 77840232 : if (DF_REF_IS_ARTIFICIAL (ref))
8666 : 16507527 : continue;
8667 : :
8668 : 61332705 : rtx_insn *insn = DF_REF_INSN (ref);
8669 : :
8670 : 61332705 : if (!NONJUMP_INSN_P (insn))
8671 : 17024359 : continue;
8672 : :
8673 : 44308346 : unsigned int ref_regno = DF_REF_REGNO (ref);
8674 : :
8675 : 44308346 : rtx set = single_set (insn);
8676 : 44308346 : if (set)
8677 : : {
8678 : 43561162 : ix86_find_all_reg_uses_1 (regset, set,
8679 : : ref_regno, worklist);
8680 : 43561162 : continue;
8681 : : }
8682 : :
8683 : 747184 : rtx pat = PATTERN (insn);
8684 : 747184 : if (GET_CODE (pat) != PARALLEL)
8685 : 126987 : continue;
8686 : :
8687 : 2315880 : for (int i = 0; i < XVECLEN (pat, 0); i++)
8688 : : {
8689 : 1695683 : rtx exp = XVECEXP (pat, 0, i);
8690 : :
8691 : 1695683 : if (GET_CODE (exp) == SET)
8692 : 1333356 : ix86_find_all_reg_uses_1 (regset, exp,
8693 : : ref_regno, worklist);
8694 : : }
8695 : : }
8696 : 2302838 : }
8697 : :
8698 : : /* Set stack_frame_required to false if stack frame isn't required.
8699 : : Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
8700 : : slot used if stack frame is required and CHECK_STACK_SLOT is true. */
8701 : :
8702 : : static void
8703 : 1448987 : ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
8704 : : bool check_stack_slot)
8705 : : {
8706 : 1448987 : HARD_REG_SET set_up_by_prologue, prologue_used;
8707 : 1448987 : basic_block bb;
8708 : :
8709 : 5795948 : CLEAR_HARD_REG_SET (prologue_used);
8710 : 1448987 : CLEAR_HARD_REG_SET (set_up_by_prologue);
8711 : 1574652 : add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
8712 : 1448987 : add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
8713 : 1448987 : add_to_hard_reg_set (&set_up_by_prologue, Pmode,
8714 : : HARD_FRAME_POINTER_REGNUM);
8715 : :
8716 : 1448987 : bool require_stack_frame = false;
8717 : :
8718 : 15719342 : FOR_EACH_BB_FN (bb, cfun)
8719 : : {
8720 : 14270355 : rtx_insn *insn;
8721 : 87902820 : FOR_BB_INSNS (bb, insn)
8722 : 81495436 : if (NONDEBUG_INSN_P (insn)
8723 : 81495436 : && requires_stack_frame_p (insn, prologue_used,
8724 : : set_up_by_prologue))
8725 : : {
8726 : : require_stack_frame = true;
8727 : : break;
8728 : : }
8729 : : }
8730 : :
8731 : 1448987 : cfun->machine->stack_frame_required = require_stack_frame;
8732 : :
8733 : : /* Stop if we don't need to check stack slot. */
8734 : 1448987 : if (!check_stack_slot)
8735 : 763243 : return;
8736 : :
8737 : : /* The preferred stack alignment is the minimum stack alignment. */
8738 : 685744 : if (stack_alignment > crtl->preferred_stack_boundary)
8739 : 142396 : stack_alignment = crtl->preferred_stack_boundary;
8740 : :
8741 : : HARD_REG_SET stack_slot_access;
8742 : 685744 : CLEAR_HARD_REG_SET (stack_slot_access);
8743 : :
8744 : : /* Stack slot can be accessed by stack pointer, frame pointer or
8745 : : registers defined by stack pointer or frame pointer. */
8746 : 685744 : auto_bitmap worklist;
8747 : :
8748 : 745724 : add_to_hard_reg_set (&stack_slot_access, Pmode, STACK_POINTER_REGNUM);
8749 : 685744 : bitmap_set_bit (worklist, STACK_POINTER_REGNUM);
8750 : :
8751 : 685744 : if (frame_pointer_needed)
8752 : : {
8753 : 327058 : add_to_hard_reg_set (&stack_slot_access, Pmode,
8754 : : HARD_FRAME_POINTER_REGNUM);
8755 : 318027 : bitmap_set_bit (worklist, HARD_FRAME_POINTER_REGNUM);
8756 : : }
8757 : :
8758 : 2302838 : unsigned int regno;
8759 : :
8760 : 2302838 : do
8761 : : {
8762 : 2302838 : regno = bitmap_clear_first_set_bit (worklist);
8763 : 2302838 : ix86_find_all_reg_uses (stack_slot_access, regno, worklist);
8764 : : }
8765 : 2302838 : while (!bitmap_empty_p (worklist));
8766 : :
8767 : 685744 : hard_reg_set_iterator hrsi;
8768 : 685744 : stack_access_data data;
8769 : :
8770 : 685744 : data.stack_alignment = &stack_alignment;
8771 : :
8772 : 2988582 : EXECUTE_IF_SET_IN_HARD_REG_SET (stack_slot_access, 0, regno, hrsi)
8773 : 2302838 : for (df_ref ref = DF_REG_USE_CHAIN (regno);
8774 : 80143070 : ref != NULL;
8775 : 77840232 : ref = DF_REF_NEXT_REG (ref))
8776 : : {
8777 : 77840232 : if (DF_REF_IS_ARTIFICIAL (ref))
8778 : 16507527 : continue;
8779 : :
8780 : 61332705 : rtx_insn *insn = DF_REF_INSN (ref);
8781 : :
8782 : 61332705 : if (!NONJUMP_INSN_P (insn))
8783 : 17024359 : continue;
8784 : :
8785 : 44308346 : data.reg = DF_REF_REG (ref);
8786 : 44308346 : note_stores (insn, ix86_update_stack_alignment, &data);
8787 : : }
8788 : 685744 : }
8789 : :
8790 : : /* Finalize stack_realign_needed and frame_pointer_needed flags, which
8791 : : will guide prologue/epilogue to be generated in correct form. */
8792 : :
8793 : : static void
8794 : 3371244 : ix86_finalize_stack_frame_flags (void)
8795 : : {
8796 : : /* Check if stack realign is really needed after reload, and
8797 : : stores result in cfun */
8798 : 3371244 : unsigned int incoming_stack_boundary
8799 : 3371244 : = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
8800 : 3371244 : ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
8801 : 3371244 : unsigned int stack_alignment
8802 : 1141719 : = (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
8803 : 4512963 : ? crtl->max_used_stack_slot_alignment
8804 : 3371244 : : crtl->stack_alignment_needed);
8805 : 3371244 : unsigned int stack_realign
8806 : 3371244 : = (incoming_stack_boundary < stack_alignment);
8807 : 3371244 : bool recompute_frame_layout_p = false;
8808 : :
8809 : 3371244 : if (crtl->stack_realign_finalized)
8810 : : {
8811 : : /* After stack_realign_needed is finalized, we can't no longer
8812 : : change it. */
8813 : 1922257 : gcc_assert (crtl->stack_realign_needed == stack_realign);
8814 : 1922257 : return;
8815 : : }
8816 : :
8817 : : /* It is always safe to compute max_used_stack_alignment. We
8818 : : compute it only if 128-bit aligned load/store may be generated
8819 : : on misaligned stack slot which will lead to segfault. */
8820 : 2897974 : bool check_stack_slot
8821 : 1448987 : = (stack_realign || crtl->max_used_stack_slot_alignment >= 128);
8822 : 1448987 : ix86_find_max_used_stack_alignment (stack_alignment,
8823 : : check_stack_slot);
8824 : :
8825 : : /* If the only reason for frame_pointer_needed is that we conservatively
8826 : : assumed stack realignment might be needed or -fno-omit-frame-pointer
8827 : : is used, but in the end nothing that needed the stack alignment had
8828 : : been spilled nor stack access, clear frame_pointer_needed and say we
8829 : : don't need stack realignment.
8830 : :
8831 : : When vector register is used for piecewise move and store, we don't
8832 : : increase stack_alignment_needed as there is no register spill for
8833 : : piecewise move and store. Since stack_realign_needed is set to true
8834 : : by checking stack_alignment_estimated which is updated by pseudo
8835 : : vector register usage, we also need to check stack_realign_needed to
8836 : : eliminate frame pointer. */
8837 : 1448987 : if ((stack_realign
8838 : 1384438 : || (!flag_omit_frame_pointer && optimize)
8839 : 1374197 : || crtl->stack_realign_needed)
8840 : 75384 : && frame_pointer_needed
8841 : 75384 : && crtl->is_leaf
8842 : 51064 : && crtl->sp_is_unchanging
8843 : 51012 : && !ix86_current_function_calls_tls_descriptor
8844 : 51012 : && !crtl->accesses_prior_frames
8845 : 51012 : && !cfun->calls_alloca
8846 : 51012 : && !crtl->calls_eh_return
8847 : : /* See ira_setup_eliminable_regset for the rationale. */
8848 : 51012 : && !(STACK_CHECK_MOVING_SP
8849 : 51012 : && flag_stack_check
8850 : 0 : && flag_exceptions
8851 : 0 : && cfun->can_throw_non_call_exceptions)
8852 : 51012 : && !ix86_frame_pointer_required ()
8853 : 51011 : && ix86_get_frame_size () == 0
8854 : 33628 : && ix86_nsaved_sseregs () == 0
8855 : 1482615 : && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
8856 : : {
8857 : 33628 : if (cfun->machine->stack_frame_required)
8858 : : {
8859 : : /* Stack frame is required. If stack alignment needed is less
8860 : : than incoming stack boundary, don't realign stack. */
8861 : 237 : stack_realign = incoming_stack_boundary < stack_alignment;
8862 : 237 : if (!stack_realign)
8863 : : {
8864 : 237 : crtl->max_used_stack_slot_alignment
8865 : 237 : = incoming_stack_boundary;
8866 : 237 : crtl->stack_alignment_needed
8867 : 237 : = incoming_stack_boundary;
8868 : : /* Also update preferred_stack_boundary for leaf
8869 : : functions. */
8870 : 237 : crtl->preferred_stack_boundary
8871 : 237 : = incoming_stack_boundary;
8872 : : }
8873 : : }
8874 : : else
8875 : : {
8876 : : /* If drap has been set, but it actually isn't live at the
8877 : : start of the function, there is no reason to set it up. */
8878 : 33391 : if (crtl->drap_reg)
8879 : : {
8880 : 32 : basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
8881 : 64 : if (! REGNO_REG_SET_P (DF_LR_IN (bb),
8882 : : REGNO (crtl->drap_reg)))
8883 : : {
8884 : 32 : crtl->drap_reg = NULL_RTX;
8885 : 32 : crtl->need_drap = false;
8886 : : }
8887 : : }
8888 : : else
8889 : 33359 : cfun->machine->no_drap_save_restore = true;
8890 : :
8891 : 33391 : frame_pointer_needed = false;
8892 : 33391 : stack_realign = false;
8893 : 33391 : crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
8894 : 33391 : crtl->stack_alignment_needed = incoming_stack_boundary;
8895 : 33391 : crtl->stack_alignment_estimated = incoming_stack_boundary;
8896 : 33391 : if (crtl->preferred_stack_boundary > incoming_stack_boundary)
8897 : 1 : crtl->preferred_stack_boundary = incoming_stack_boundary;
8898 : 33391 : df_finish_pass (true);
8899 : 33391 : df_scan_alloc (NULL);
8900 : 33391 : df_scan_blocks ();
8901 : 33391 : df_compute_regs_ever_live (true);
8902 : 33391 : df_analyze ();
8903 : :
8904 : 33391 : if (flag_var_tracking)
8905 : : {
8906 : : /* Since frame pointer is no longer available, replace it with
8907 : : stack pointer - UNITS_PER_WORD in debug insns. */
8908 : 130 : df_ref ref, next;
8909 : 130 : for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM);
8910 : 130 : ref; ref = next)
8911 : : {
8912 : 0 : next = DF_REF_NEXT_REG (ref);
8913 : 0 : if (!DF_REF_INSN_INFO (ref))
8914 : 0 : continue;
8915 : :
8916 : : /* Make sure the next ref is for a different instruction,
8917 : : so that we're not affected by the rescan. */
8918 : 0 : rtx_insn *insn = DF_REF_INSN (ref);
8919 : 0 : while (next && DF_REF_INSN (next) == insn)
8920 : 0 : next = DF_REF_NEXT_REG (next);
8921 : :
8922 : 0 : if (DEBUG_INSN_P (insn))
8923 : : {
8924 : : bool changed = false;
8925 : 0 : for (; ref != next; ref = DF_REF_NEXT_REG (ref))
8926 : : {
8927 : 0 : rtx *loc = DF_REF_LOC (ref);
8928 : 0 : if (*loc == hard_frame_pointer_rtx)
8929 : : {
8930 : 0 : *loc = plus_constant (Pmode,
8931 : : stack_pointer_rtx,
8932 : 0 : -UNITS_PER_WORD);
8933 : 0 : changed = true;
8934 : : }
8935 : : }
8936 : 0 : if (changed)
8937 : 0 : df_insn_rescan (insn);
8938 : : }
8939 : : }
8940 : : }
8941 : :
8942 : : recompute_frame_layout_p = true;
8943 : : }
8944 : : }
8945 : 1415359 : else if (crtl->max_used_stack_slot_alignment >= 128
8946 : 651053 : && cfun->machine->stack_frame_required)
8947 : : {
8948 : : /* We don't need to realign stack. max_used_stack_alignment is
8949 : : used to decide how stack frame should be aligned. This is
8950 : : independent of any psABIs nor 32-bit vs 64-bit. */
8951 : 607374 : cfun->machine->max_used_stack_alignment
8952 : 607374 : = stack_alignment / BITS_PER_UNIT;
8953 : : }
8954 : :
8955 : 1448987 : if (crtl->stack_realign_needed != stack_realign)
8956 : 33846 : recompute_frame_layout_p = true;
8957 : 1448987 : crtl->stack_realign_needed = stack_realign;
8958 : 1448987 : crtl->stack_realign_finalized = true;
8959 : 1448987 : if (recompute_frame_layout_p)
8960 : 33924 : ix86_compute_frame_layout ();
8961 : : }
8962 : :
8963 : : /* Delete SET_GOT right after entry block if it is allocated to reg. */
8964 : :
8965 : : static void
8966 : 0 : ix86_elim_entry_set_got (rtx reg)
8967 : : {
8968 : 0 : basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
8969 : 0 : rtx_insn *c_insn = BB_HEAD (bb);
8970 : 0 : if (!NONDEBUG_INSN_P (c_insn))
8971 : 0 : c_insn = next_nonnote_nondebug_insn (c_insn);
8972 : 0 : if (c_insn && NONJUMP_INSN_P (c_insn))
8973 : : {
8974 : 0 : rtx pat = PATTERN (c_insn);
8975 : 0 : if (GET_CODE (pat) == PARALLEL)
8976 : : {
8977 : 0 : rtx set = XVECEXP (pat, 0, 0);
8978 : 0 : if (GET_CODE (set) == SET
8979 : 0 : && GET_CODE (SET_SRC (set)) == UNSPEC
8980 : 0 : && XINT (SET_SRC (set), 1) == UNSPEC_SET_GOT
8981 : 0 : && REGNO (SET_DEST (set)) == REGNO (reg))
8982 : 0 : delete_insn (c_insn);
8983 : : }
8984 : : }
8985 : 0 : }
8986 : :
8987 : : static rtx
8988 : 193166 : gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store)
8989 : : {
8990 : 193166 : rtx addr, mem;
8991 : :
8992 : 193166 : if (offset)
8993 : 184480 : addr = plus_constant (Pmode, frame_reg, offset);
8994 : 193166 : mem = gen_frame_mem (GET_MODE (reg), offset ? addr : frame_reg);
8995 : 193166 : return gen_rtx_SET (store ? mem : reg, store ? reg : mem);
8996 : : }
8997 : :
8998 : : static inline rtx
8999 : 100333 : gen_frame_load (rtx reg, rtx frame_reg, int offset)
9000 : : {
9001 : 100333 : return gen_frame_set (reg, frame_reg, offset, false);
9002 : : }
9003 : :
9004 : : static inline rtx
9005 : 92833 : gen_frame_store (rtx reg, rtx frame_reg, int offset)
9006 : : {
9007 : 92833 : return gen_frame_set (reg, frame_reg, offset, true);
9008 : : }
9009 : :
9010 : : static void
9011 : 7045 : ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
9012 : : {
9013 : 7045 : struct machine_function *m = cfun->machine;
9014 : 7045 : const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
9015 : 7045 : + m->call_ms2sysv_extra_regs;
9016 : 7045 : rtvec v = rtvec_alloc (ncregs + 1);
9017 : 7045 : unsigned int align, i, vi = 0;
9018 : 7045 : rtx_insn *insn;
9019 : 7045 : rtx sym, addr;
9020 : 7045 : rtx rax = gen_rtx_REG (word_mode, AX_REG);
9021 : 7045 : const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
9022 : :
9023 : : /* AL should only be live with sysv_abi. */
9024 : 7045 : gcc_assert (!ix86_eax_live_at_start_p ());
9025 : 7045 : gcc_assert (m->fs.sp_offset >= frame.sse_reg_save_offset);
9026 : :
9027 : : /* Setup RAX as the stub's base pointer. We use stack_realign_offset rather
9028 : : we've actually realigned the stack or not. */
9029 : 7045 : align = GET_MODE_ALIGNMENT (V4SFmode);
9030 : 7045 : addr = choose_baseaddr (frame.stack_realign_offset
9031 : 7045 : + xlogue.get_stub_ptr_offset (), &align, AX_REG);
9032 : 7045 : gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
9033 : :
9034 : 7045 : emit_insn (gen_rtx_SET (rax, addr));
9035 : :
9036 : : /* Get the stub symbol. */
9037 : 8327 : sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP
9038 : : : XLOGUE_STUB_SAVE);
9039 : 7045 : RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
9040 : :
9041 : 99878 : for (i = 0; i < ncregs; ++i)
9042 : : {
9043 : 92833 : const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
9044 : 92833 : rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode),
9045 : 92833 : r.regno);
9046 : 92833 : RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);
9047 : : }
9048 : :
9049 : 7045 : gcc_assert (vi == (unsigned)GET_NUM_ELEM (v));
9050 : :
9051 : 7045 : insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
9052 : 7045 : RTX_FRAME_RELATED_P (insn) = true;
9053 : 7045 : }
9054 : :
9055 : : /* Generate and return an insn body to AND X with Y. */
9056 : :
9057 : : static rtx_insn *
9058 : 31297 : gen_and2_insn (rtx x, rtx y)
9059 : : {
9060 : 31297 : enum insn_code icode = optab_handler (and_optab, GET_MODE (x));
9061 : :
9062 : 31297 : gcc_assert (insn_operand_matches (icode, 0, x));
9063 : 31297 : gcc_assert (insn_operand_matches (icode, 1, x));
9064 : 31297 : gcc_assert (insn_operand_matches (icode, 2, y));
9065 : :
9066 : 31297 : return GEN_FCN (icode) (x, x, y);
9067 : : }
9068 : :
9069 : : /* Expand the prologue into a bunch of separate insns. */
9070 : :
9071 : : void
9072 : 1495215 : ix86_expand_prologue (void)
9073 : : {
9074 : 1495215 : struct machine_function *m = cfun->machine;
9075 : 1495215 : rtx insn, t;
9076 : 1495215 : HOST_WIDE_INT allocate;
9077 : 1495215 : bool int_registers_saved;
9078 : 1495215 : bool sse_registers_saved;
9079 : 1495215 : bool save_stub_call_needed;
9080 : 1495215 : rtx static_chain = NULL_RTX;
9081 : :
9082 : 1495215 : ix86_last_zero_store_uid = 0;
9083 : 1495215 : if (ix86_function_naked (current_function_decl))
9084 : : {
9085 : 74 : if (flag_stack_usage_info)
9086 : 0 : current_function_static_stack_size = 0;
9087 : 74 : return;
9088 : : }
9089 : :
9090 : 1495141 : ix86_finalize_stack_frame_flags ();
9091 : :
9092 : : /* DRAP should not coexist with stack_realign_fp */
9093 : 1495141 : gcc_assert (!(crtl->drap_reg && stack_realign_fp));
9094 : :
9095 : 1495141 : memset (&m->fs, 0, sizeof (m->fs));
9096 : :
9097 : : /* Initialize CFA state for before the prologue. */
9098 : 1495141 : m->fs.cfa_reg = stack_pointer_rtx;
9099 : 1495141 : m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
9100 : :
9101 : : /* Track SP offset to the CFA. We continue tracking this after we've
9102 : : swapped the CFA register away from SP. In the case of re-alignment
9103 : : this is fudged; we're interested to offsets within the local frame. */
9104 : 1495141 : m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
9105 : 1495141 : m->fs.sp_valid = true;
9106 : 1495141 : m->fs.sp_realigned = false;
9107 : :
9108 : 1495141 : const struct ix86_frame &frame = cfun->machine->frame;
9109 : :
9110 : 1495141 : if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
9111 : : {
9112 : : /* We should have already generated an error for any use of
9113 : : ms_hook on a nested function. */
9114 : 0 : gcc_checking_assert (!ix86_static_chain_on_stack);
9115 : :
9116 : : /* Check if profiling is active and we shall use profiling before
9117 : : prologue variant. If so sorry. */
9118 : 0 : if (crtl->profile && flag_fentry != 0)
9119 : 0 : sorry ("%<ms_hook_prologue%> attribute is not compatible "
9120 : : "with %<-mfentry%> for 32-bit");
9121 : :
9122 : : /* In ix86_asm_output_function_label we emitted:
9123 : : 8b ff movl.s %edi,%edi
9124 : : 55 push %ebp
9125 : : 8b ec movl.s %esp,%ebp
9126 : :
9127 : : This matches the hookable function prologue in Win32 API
9128 : : functions in Microsoft Windows XP Service Pack 2 and newer.
9129 : : Wine uses this to enable Windows apps to hook the Win32 API
9130 : : functions provided by Wine.
9131 : :
9132 : : What that means is that we've already set up the frame pointer. */
9133 : :
9134 : 0 : if (frame_pointer_needed
9135 : 0 : && !(crtl->drap_reg && crtl->stack_realign_needed))
9136 : : {
9137 : 0 : rtx push, mov;
9138 : :
9139 : : /* We've decided to use the frame pointer already set up.
9140 : : Describe this to the unwinder by pretending that both
9141 : : push and mov insns happen right here.
9142 : :
9143 : : Putting the unwind info here at the end of the ms_hook
9144 : : is done so that we can make absolutely certain we get
9145 : : the required byte sequence at the start of the function,
9146 : : rather than relying on an assembler that can produce
9147 : : the exact encoding required.
9148 : :
9149 : : However it does mean (in the unpatched case) that we have
9150 : : a 1 insn window where the asynchronous unwind info is
9151 : : incorrect. However, if we placed the unwind info at
9152 : : its correct location we would have incorrect unwind info
9153 : : in the patched case. Which is probably all moot since
9154 : : I don't expect Wine generates dwarf2 unwind info for the
9155 : : system libraries that use this feature. */
9156 : :
9157 : 0 : insn = emit_insn (gen_blockage ());
9158 : :
9159 : 0 : push = gen_push (hard_frame_pointer_rtx);
9160 : 0 : mov = gen_rtx_SET (hard_frame_pointer_rtx,
9161 : : stack_pointer_rtx);
9162 : 0 : RTX_FRAME_RELATED_P (push) = 1;
9163 : 0 : RTX_FRAME_RELATED_P (mov) = 1;
9164 : :
9165 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9166 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9167 : : gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
9168 : :
9169 : : /* Note that gen_push incremented m->fs.cfa_offset, even
9170 : : though we didn't emit the push insn here. */
9171 : 0 : m->fs.cfa_reg = hard_frame_pointer_rtx;
9172 : 0 : m->fs.fp_offset = m->fs.cfa_offset;
9173 : 0 : m->fs.fp_valid = true;
9174 : 0 : }
9175 : : else
9176 : : {
9177 : : /* The frame pointer is not needed so pop %ebp again.
9178 : : This leaves us with a pristine state. */
9179 : 0 : emit_insn (gen_pop (hard_frame_pointer_rtx));
9180 : : }
9181 : : }
9182 : :
9183 : : /* The first insn of a function that accepts its static chain on the
9184 : : stack is to push the register that would be filled in by a direct
9185 : : call. This insn will be skipped by the trampoline. */
9186 : 1495141 : else if (ix86_static_chain_on_stack)
9187 : : {
9188 : 0 : static_chain = ix86_static_chain (cfun->decl, false);
9189 : 0 : insn = emit_insn (gen_push (static_chain));
9190 : 0 : emit_insn (gen_blockage ());
9191 : :
9192 : : /* We don't want to interpret this push insn as a register save,
9193 : : only as a stack adjustment. The real copy of the register as
9194 : : a save will be done later, if needed. */
9195 : 0 : t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
9196 : 0 : t = gen_rtx_SET (stack_pointer_rtx, t);
9197 : 0 : add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
9198 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9199 : : }
9200 : :
9201 : : /* Emit prologue code to adjust stack alignment and setup DRAP, in case
9202 : : of DRAP is needed and stack realignment is really needed after reload */
9203 : 1495141 : if (stack_realign_drap)
9204 : : {
9205 : 6916 : int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
9206 : :
9207 : : /* Can't use DRAP in interrupt function. */
9208 : 6916 : if (cfun->machine->func_type != TYPE_NORMAL)
9209 : 0 : sorry ("Dynamic Realign Argument Pointer (DRAP) not supported "
9210 : : "in interrupt service routine. This may be worked "
9211 : : "around by avoiding functions with aggregate return.");
9212 : :
9213 : : /* Only need to push parameter pointer reg if it is caller saved. */
9214 : 6916 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
9215 : : {
9216 : : /* Push arg pointer reg */
9217 : 136 : insn = emit_insn (gen_push (crtl->drap_reg));
9218 : 136 : RTX_FRAME_RELATED_P (insn) = 1;
9219 : : }
9220 : :
9221 : : /* Grab the argument pointer. */
9222 : 7197 : t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
9223 : 6916 : insn = emit_insn (gen_rtx_SET (crtl->drap_reg, t));
9224 : 6916 : RTX_FRAME_RELATED_P (insn) = 1;
9225 : 6916 : m->fs.cfa_reg = crtl->drap_reg;
9226 : 6916 : m->fs.cfa_offset = 0;
9227 : :
9228 : : /* Align the stack. */
9229 : 6916 : insn = emit_insn (gen_and2_insn (stack_pointer_rtx,
9230 : 6916 : GEN_INT (-align_bytes)));
9231 : 6916 : RTX_FRAME_RELATED_P (insn) = 1;
9232 : :
9233 : : /* Replicate the return address on the stack so that return
9234 : : address can be reached via (argp - 1) slot. This is needed
9235 : : to implement macro RETURN_ADDR_RTX and intrinsic function
9236 : : expand_builtin_return_addr etc. */
9237 : 7478 : t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
9238 : 6916 : t = gen_frame_mem (word_mode, t);
9239 : 6916 : insn = emit_insn (gen_push (t));
9240 : 6916 : RTX_FRAME_RELATED_P (insn) = 1;
9241 : :
9242 : : /* For the purposes of frame and register save area addressing,
9243 : : we've started over with a new frame. */
9244 : 6916 : m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
9245 : 6916 : m->fs.realigned = true;
9246 : :
9247 : 6916 : if (static_chain)
9248 : : {
9249 : : /* Replicate static chain on the stack so that static chain
9250 : : can be reached via (argp - 2) slot. This is needed for
9251 : : nested function with stack realignment. */
9252 : 0 : insn = emit_insn (gen_push (static_chain));
9253 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9254 : : }
9255 : : }
9256 : :
9257 : 1495141 : int_registers_saved = (frame.nregs == 0);
9258 : 1495141 : sse_registers_saved = (frame.nsseregs == 0);
9259 : 1495141 : save_stub_call_needed = (m->call_ms2sysv);
9260 : 1495141 : gcc_assert (sse_registers_saved || !save_stub_call_needed);
9261 : :
9262 : 1495141 : if (frame_pointer_needed && !m->fs.fp_valid)
9263 : : {
9264 : : /* Note: AT&T enter does NOT have reversed args. Enter is probably
9265 : : slower on all targets. Also sdb didn't like it. */
9266 : 467193 : insn = emit_insn (gen_push (hard_frame_pointer_rtx));
9267 : 467193 : RTX_FRAME_RELATED_P (insn) = 1;
9268 : :
9269 : 467193 : if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
9270 : : {
9271 : 467193 : insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
9272 : 467193 : RTX_FRAME_RELATED_P (insn) = 1;
9273 : :
9274 : 467193 : if (m->fs.cfa_reg == stack_pointer_rtx)
9275 : 460277 : m->fs.cfa_reg = hard_frame_pointer_rtx;
9276 : 467193 : m->fs.fp_offset = m->fs.sp_offset;
9277 : 467193 : m->fs.fp_valid = true;
9278 : : }
9279 : : }
9280 : :
9281 : 1495141 : if (!int_registers_saved)
9282 : : {
9283 : : /* If saving registers via PUSH, do so now. */
9284 : 471548 : if (!frame.save_regs_using_mov)
9285 : : {
9286 : 425333 : ix86_emit_save_regs ();
9287 : 425333 : m->fs.apx_ppx_used = TARGET_APX_PPX && !crtl->calls_eh_return;
9288 : 425333 : int_registers_saved = true;
9289 : 425333 : gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
9290 : : }
9291 : :
9292 : : /* When using red zone we may start register saving before allocating
9293 : : the stack frame saving one cycle of the prologue. However, avoid
9294 : : doing this if we have to probe the stack; at least on x86_64 the
9295 : : stack probe can turn into a call that clobbers a red zone location. */
9296 : 46215 : else if (ix86_using_red_zone ()
9297 : 46215 : && (! TARGET_STACK_PROBE
9298 : 0 : || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
9299 : : {
9300 : 42032 : HOST_WIDE_INT allocate_offset;
9301 : 42032 : if (crtl->shrink_wrapped_separate)
9302 : : {
9303 : 41976 : allocate_offset = m->fs.sp_offset - frame.stack_pointer_offset;
9304 : :
9305 : : /* Adjust the total offset at the beginning of the function. */
9306 : 41976 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9307 : : GEN_INT (allocate_offset), -1,
9308 : 41976 : m->fs.cfa_reg == stack_pointer_rtx);
9309 : 41976 : m->fs.sp_offset = cfun->machine->frame.stack_pointer_offset;
9310 : : }
9311 : :
9312 : 42032 : ix86_emit_save_regs_using_mov (frame.reg_save_offset);
9313 : 42032 : int_registers_saved = true;
9314 : : }
9315 : : }
9316 : :
9317 : 1495141 : if (frame.red_zone_size != 0)
9318 : 137434 : cfun->machine->red_zone_used = true;
9319 : :
9320 : 1495141 : if (stack_realign_fp)
9321 : : {
9322 : 24381 : int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
9323 : 24731 : gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
9324 : :
9325 : : /* Record last valid frame pointer offset. */
9326 : 24381 : m->fs.sp_realigned_fp_last = frame.reg_save_offset;
9327 : :
9328 : : /* The computation of the size of the re-aligned stack frame means
9329 : : that we must allocate the size of the register save area before
9330 : : performing the actual alignment. Otherwise we cannot guarantee
9331 : : that there's enough storage above the realignment point. */
9332 : 24381 : allocate = frame.reg_save_offset - m->fs.sp_offset
9333 : 24381 : + frame.stack_realign_allocate;
9334 : 24381 : if (allocate)
9335 : 2691 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9336 : : GEN_INT (-allocate), -1, false);
9337 : :
9338 : : /* Align the stack. */
9339 : 24381 : emit_insn (gen_and2_insn (stack_pointer_rtx, GEN_INT (-align_bytes)));
9340 : 24381 : m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes);
9341 : 24381 : m->fs.sp_realigned_offset = m->fs.sp_offset
9342 : 24381 : - frame.stack_realign_allocate;
9343 : : /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset.
9344 : : Beyond this point, stack access should be done via choose_baseaddr or
9345 : : by using sp_valid_at and fp_valid_at to determine the correct base
9346 : : register. Henceforth, any CFA offset should be thought of as logical
9347 : : and not physical. */
9348 : 24381 : gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last);
9349 : 24381 : gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset);
9350 : 24381 : m->fs.sp_realigned = true;
9351 : :
9352 : : /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which
9353 : : is needed to describe where a register is saved using a realigned
9354 : : stack pointer, so we need to invalidate the stack pointer for that
9355 : : target. */
9356 : 24381 : if (TARGET_SEH)
9357 : : m->fs.sp_valid = false;
9358 : :
9359 : : /* If SP offset is non-immediate after allocation of the stack frame,
9360 : : then emit SSE saves or stub call prior to allocating the rest of the
9361 : : stack frame. This is less efficient for the out-of-line stub because
9362 : : we can't combine allocations across the call barrier, but it's better
9363 : : than using a scratch register. */
9364 : 24381 : else if (!x86_64_immediate_operand (GEN_INT (frame.stack_pointer_offset
9365 : : - m->fs.sp_realigned_offset),
9366 : 24381 : Pmode))
9367 : : {
9368 : 3 : if (!sse_registers_saved)
9369 : : {
9370 : 1 : ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
9371 : 1 : sse_registers_saved = true;
9372 : : }
9373 : 2 : else if (save_stub_call_needed)
9374 : : {
9375 : 1 : ix86_emit_outlined_ms2sysv_save (frame);
9376 : 1 : save_stub_call_needed = false;
9377 : : }
9378 : : }
9379 : : }
9380 : :
9381 : 1495141 : allocate = frame.stack_pointer_offset - m->fs.sp_offset;
9382 : :
9383 : 1495141 : if (flag_stack_usage_info)
9384 : : {
9385 : : /* We start to count from ARG_POINTER. */
9386 : 355 : HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
9387 : :
9388 : : /* If it was realigned, take into account the fake frame. */
9389 : 355 : if (stack_realign_drap)
9390 : : {
9391 : 1 : if (ix86_static_chain_on_stack)
9392 : 0 : stack_size += UNITS_PER_WORD;
9393 : :
9394 : 1 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
9395 : 0 : stack_size += UNITS_PER_WORD;
9396 : :
9397 : : /* This over-estimates by 1 minimal-stack-alignment-unit but
9398 : : mitigates that by counting in the new return address slot. */
9399 : 1 : current_function_dynamic_stack_size
9400 : 1 : += crtl->stack_alignment_needed / BITS_PER_UNIT;
9401 : : }
9402 : :
9403 : 355 : current_function_static_stack_size = stack_size;
9404 : : }
9405 : :
9406 : : /* On SEH target with very large frame size, allocate an area to save
9407 : : SSE registers (as the very large allocation won't be described). */
9408 : 1495141 : if (TARGET_SEH
9409 : : && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
9410 : : && !sse_registers_saved)
9411 : : {
9412 : : HOST_WIDE_INT sse_size
9413 : : = frame.sse_reg_save_offset - frame.reg_save_offset;
9414 : :
9415 : : gcc_assert (int_registers_saved);
9416 : :
9417 : : /* No need to do stack checking as the area will be immediately
9418 : : written. */
9419 : : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9420 : : GEN_INT (-sse_size), -1,
9421 : : m->fs.cfa_reg == stack_pointer_rtx);
9422 : : allocate -= sse_size;
9423 : : ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
9424 : : sse_registers_saved = true;
9425 : : }
9426 : :
9427 : : /* If stack clash protection is requested, then probe the stack, unless it
9428 : : is already probed on the target. */
9429 : 1495141 : if (allocate >= 0
9430 : 1495137 : && flag_stack_clash_protection
9431 : 1495238 : && !ix86_target_stack_probe ())
9432 : : {
9433 : 97 : ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
9434 : 97 : allocate = 0;
9435 : : }
9436 : :
9437 : : /* The stack has already been decremented by the instruction calling us
9438 : : so probe if the size is non-negative to preserve the protection area. */
9439 : 1495044 : else if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
9440 : : {
9441 : 46 : const HOST_WIDE_INT probe_interval = get_probe_interval ();
9442 : :
9443 : 46 : if (STACK_CHECK_MOVING_SP)
9444 : : {
9445 : 46 : if (crtl->is_leaf
9446 : 18 : && !cfun->calls_alloca
9447 : 18 : && allocate <= probe_interval)
9448 : : ;
9449 : :
9450 : : else
9451 : : {
9452 : 29 : ix86_adjust_stack_and_probe (allocate, int_registers_saved, true);
9453 : 29 : allocate = 0;
9454 : : }
9455 : : }
9456 : :
9457 : : else
9458 : : {
9459 : : HOST_WIDE_INT size = allocate;
9460 : :
9461 : : if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
9462 : : size = 0x80000000 - get_stack_check_protect () - 1;
9463 : :
9464 : : if (TARGET_STACK_PROBE)
9465 : : {
9466 : : if (crtl->is_leaf && !cfun->calls_alloca)
9467 : : {
9468 : : if (size > probe_interval)
9469 : : ix86_emit_probe_stack_range (0, size, int_registers_saved);
9470 : : }
9471 : : else
9472 : : ix86_emit_probe_stack_range (0,
9473 : : size + get_stack_check_protect (),
9474 : : int_registers_saved);
9475 : : }
9476 : : else
9477 : : {
9478 : : if (crtl->is_leaf && !cfun->calls_alloca)
9479 : : {
9480 : : if (size > probe_interval
9481 : : && size > get_stack_check_protect ())
9482 : : ix86_emit_probe_stack_range (get_stack_check_protect (),
9483 : : (size
9484 : : - get_stack_check_protect ()),
9485 : : int_registers_saved);
9486 : : }
9487 : : else
9488 : : ix86_emit_probe_stack_range (get_stack_check_protect (), size,
9489 : : int_registers_saved);
9490 : : }
9491 : : }
9492 : : }
9493 : :
9494 : 1495137 : if (allocate == 0)
9495 : : ;
9496 : 832909 : else if (!ix86_target_stack_probe ()
9497 : 832909 : || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
9498 : : {
9499 : 832864 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9500 : : GEN_INT (-allocate), -1,
9501 : 832864 : m->fs.cfa_reg == stack_pointer_rtx);
9502 : : }
9503 : : else
9504 : : {
9505 : 45 : rtx eax = gen_rtx_REG (Pmode, AX_REG);
9506 : 45 : rtx r10 = NULL;
9507 : 45 : const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
9508 : 45 : bool eax_live = ix86_eax_live_at_start_p ();
9509 : 45 : bool r10_live = false;
9510 : :
9511 : 45 : if (TARGET_64BIT)
9512 : 45 : r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
9513 : :
9514 : 45 : if (eax_live)
9515 : : {
9516 : 0 : insn = emit_insn (gen_push (eax));
9517 : 0 : allocate -= UNITS_PER_WORD;
9518 : : /* Note that SEH directives need to continue tracking the stack
9519 : : pointer even after the frame pointer has been set up. */
9520 : 0 : if (sp_is_cfa_reg || TARGET_SEH)
9521 : : {
9522 : 0 : if (sp_is_cfa_reg)
9523 : 0 : m->fs.cfa_offset += UNITS_PER_WORD;
9524 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9525 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9526 : 0 : gen_rtx_SET (stack_pointer_rtx,
9527 : : plus_constant (Pmode,
9528 : : stack_pointer_rtx,
9529 : : -UNITS_PER_WORD)));
9530 : : }
9531 : : }
9532 : :
9533 : 45 : if (r10_live)
9534 : : {
9535 : 0 : r10 = gen_rtx_REG (Pmode, R10_REG);
9536 : 0 : insn = emit_insn (gen_push (r10));
9537 : 0 : allocate -= UNITS_PER_WORD;
9538 : 0 : if (sp_is_cfa_reg || TARGET_SEH)
9539 : : {
9540 : 0 : if (sp_is_cfa_reg)
9541 : 0 : m->fs.cfa_offset += UNITS_PER_WORD;
9542 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9543 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9544 : 0 : gen_rtx_SET (stack_pointer_rtx,
9545 : : plus_constant (Pmode,
9546 : : stack_pointer_rtx,
9547 : : -UNITS_PER_WORD)));
9548 : : }
9549 : : }
9550 : :
9551 : 45 : emit_move_insn (eax, GEN_INT (allocate));
9552 : 45 : emit_insn (gen_allocate_stack_worker_probe (Pmode, eax, eax));
9553 : :
9554 : : /* Use the fact that AX still contains ALLOCATE. */
9555 : 45 : insn = emit_insn (gen_pro_epilogue_adjust_stack_sub
9556 : 45 : (Pmode, stack_pointer_rtx, stack_pointer_rtx, eax));
9557 : :
9558 : 45 : if (sp_is_cfa_reg || TARGET_SEH)
9559 : : {
9560 : 37 : if (sp_is_cfa_reg)
9561 : 37 : m->fs.cfa_offset += allocate;
9562 : 37 : RTX_FRAME_RELATED_P (insn) = 1;
9563 : 37 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9564 : 37 : gen_rtx_SET (stack_pointer_rtx,
9565 : : plus_constant (Pmode, stack_pointer_rtx,
9566 : : -allocate)));
9567 : : }
9568 : 45 : m->fs.sp_offset += allocate;
9569 : :
9570 : : /* Use stack_pointer_rtx for relative addressing so that code works for
9571 : : realigned stack. But this means that we need a blockage to prevent
9572 : : stores based on the frame pointer from being scheduled before. */
9573 : 45 : if (r10_live && eax_live)
9574 : : {
9575 : 0 : t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
9576 : 0 : emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
9577 : : gen_frame_mem (word_mode, t));
9578 : 0 : t = plus_constant (Pmode, t, UNITS_PER_WORD);
9579 : 0 : emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
9580 : : gen_frame_mem (word_mode, t));
9581 : 0 : emit_insn (gen_memory_blockage ());
9582 : : }
9583 : 45 : else if (eax_live || r10_live)
9584 : : {
9585 : 0 : t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
9586 : 0 : emit_move_insn (gen_rtx_REG (word_mode,
9587 : : (eax_live ? AX_REG : R10_REG)),
9588 : : gen_frame_mem (word_mode, t));
9589 : 0 : emit_insn (gen_memory_blockage ());
9590 : : }
9591 : : }
9592 : 1495141 : gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
9593 : :
9594 : : /* If we havn't already set up the frame pointer, do so now. */
9595 : 1495141 : if (frame_pointer_needed && !m->fs.fp_valid)
9596 : : {
9597 : 0 : insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
9598 : 0 : GEN_INT (frame.stack_pointer_offset
9599 : : - frame.hard_frame_pointer_offset));
9600 : 0 : insn = emit_insn (insn);
9601 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9602 : 0 : add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
9603 : :
9604 : 0 : if (m->fs.cfa_reg == stack_pointer_rtx)
9605 : 0 : m->fs.cfa_reg = hard_frame_pointer_rtx;
9606 : 0 : m->fs.fp_offset = frame.hard_frame_pointer_offset;
9607 : 0 : m->fs.fp_valid = true;
9608 : : }
9609 : :
9610 : 1495141 : if (!int_registers_saved)
9611 : 4183 : ix86_emit_save_regs_using_mov (frame.reg_save_offset);
9612 : 1495141 : if (!sse_registers_saved)
9613 : 33350 : ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
9614 : 1461791 : else if (save_stub_call_needed)
9615 : 7044 : ix86_emit_outlined_ms2sysv_save (frame);
9616 : :
9617 : : /* For the mcount profiling on 32 bit PIC mode we need to emit SET_GOT
9618 : : in PROLOGUE. */
9619 : 1495141 : if (!TARGET_64BIT && pic_offset_table_rtx && crtl->profile && !flag_fentry)
9620 : : {
9621 : 0 : rtx pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
9622 : 0 : insn = emit_insn (gen_set_got (pic));
9623 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9624 : 0 : add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
9625 : 0 : emit_insn (gen_prologue_use (pic));
9626 : : /* Deleting already emmitted SET_GOT if exist and allocated to
9627 : : REAL_PIC_OFFSET_TABLE_REGNUM. */
9628 : 0 : ix86_elim_entry_set_got (pic);
9629 : : }
9630 : :
9631 : 1495141 : if (crtl->drap_reg && !crtl->stack_realign_needed)
9632 : : {
9633 : : /* vDRAP is setup but after reload it turns out stack realign
9634 : : isn't necessary, here we will emit prologue to setup DRAP
9635 : : without stack realign adjustment */
9636 : 177 : t = choose_baseaddr (0, NULL);
9637 : 177 : emit_insn (gen_rtx_SET (crtl->drap_reg, t));
9638 : : }
9639 : :
9640 : : /* Prevent instructions from being scheduled into register save push
9641 : : sequence when access to the redzone area is done through frame pointer.
9642 : : The offset between the frame pointer and the stack pointer is calculated
9643 : : relative to the value of the stack pointer at the end of the function
9644 : : prologue, and moving instructions that access redzone area via frame
9645 : : pointer inside push sequence violates this assumption. */
9646 : 1495141 : if (frame_pointer_needed && frame.red_zone_size)
9647 : 124544 : emit_insn (gen_memory_blockage ());
9648 : :
9649 : : /* SEH requires that the prologue end within 256 bytes of the start of
9650 : : the function. Prevent instruction schedules that would extend that.
9651 : : Further, prevent alloca modifications to the stack pointer from being
9652 : : combined with prologue modifications. */
9653 : : if (TARGET_SEH)
9654 : : emit_insn (gen_prologue_use (stack_pointer_rtx));
9655 : : }
9656 : :
9657 : : /* Emit code to restore REG using a POP or POPP insn. */
9658 : :
9659 : : static void
9660 : 1458732 : ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
9661 : : {
9662 : 1458732 : struct machine_function *m = cfun->machine;
9663 : 1458732 : rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
9664 : :
9665 : 1458732 : ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
9666 : 1458732 : m->fs.sp_offset -= UNITS_PER_WORD;
9667 : :
9668 : 1458732 : if (m->fs.cfa_reg == crtl->drap_reg
9669 : 1458732 : && REGNO (reg) == REGNO (crtl->drap_reg))
9670 : : {
9671 : : /* Previously we'd represented the CFA as an expression
9672 : : like *(%ebp - 8). We've just popped that value from
9673 : : the stack, which means we need to reset the CFA to
9674 : : the drap register. This will remain until we restore
9675 : : the stack pointer. */
9676 : 4021 : add_reg_note (insn, REG_CFA_DEF_CFA, reg);
9677 : 4021 : RTX_FRAME_RELATED_P (insn) = 1;
9678 : :
9679 : : /* This means that the DRAP register is valid for addressing too. */
9680 : 4021 : m->fs.drap_valid = true;
9681 : 4021 : return;
9682 : : }
9683 : :
9684 : 1454711 : if (m->fs.cfa_reg == stack_pointer_rtx)
9685 : : {
9686 : 1386462 : rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
9687 : 1021129 : x = gen_rtx_SET (stack_pointer_rtx, x);
9688 : 1021129 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
9689 : 1021129 : RTX_FRAME_RELATED_P (insn) = 1;
9690 : :
9691 : 1203788 : m->fs.cfa_offset -= UNITS_PER_WORD;
9692 : : }
9693 : :
9694 : : /* When the frame pointer is the CFA, and we pop it, we are
9695 : : swapping back to the stack pointer as the CFA. This happens
9696 : : for stack frames that don't allocate other data, so we assume
9697 : : the stack pointer is now pointing at the return address, i.e.
9698 : : the function entry state, which makes the offset be 1 word. */
9699 : 1454711 : if (reg == hard_frame_pointer_rtx)
9700 : : {
9701 : 229725 : m->fs.fp_valid = false;
9702 : 229725 : if (m->fs.cfa_reg == hard_frame_pointer_rtx)
9703 : : {
9704 : 225691 : m->fs.cfa_reg = stack_pointer_rtx;
9705 : 225691 : m->fs.cfa_offset -= UNITS_PER_WORD;
9706 : :
9707 : 225691 : add_reg_note (insn, REG_CFA_DEF_CFA,
9708 : 225691 : plus_constant (Pmode, stack_pointer_rtx,
9709 : 225691 : m->fs.cfa_offset));
9710 : 225691 : RTX_FRAME_RELATED_P (insn) = 1;
9711 : : }
9712 : : }
9713 : : }
9714 : :
9715 : : /* Emit code to restore REG using a POP2 insn. */
9716 : : static void
9717 : 17 : ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
9718 : : {
9719 : 17 : struct machine_function *m = cfun->machine;
9720 : 17 : const int offset = UNITS_PER_WORD * 2;
9721 : 17 : rtx_insn *insn;
9722 : :
9723 : 17 : rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
9724 : : stack_pointer_rtx));
9725 : :
9726 : 17 : if (ppx_p)
9727 : 13 : insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
9728 : : else
9729 : 4 : insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
9730 : :
9731 : 17 : RTX_FRAME_RELATED_P (insn) = 1;
9732 : :
9733 : 17 : rtx dwarf = NULL_RTX;
9734 : 17 : dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf);
9735 : 17 : dwarf = alloc_reg_note (REG_CFA_RESTORE, reg2, dwarf);
9736 : 17 : REG_NOTES (insn) = dwarf;
9737 : 17 : m->fs.sp_offset -= offset;
9738 : :
9739 : 17 : if (m->fs.cfa_reg == crtl->drap_reg
9740 : 17 : && (REGNO (reg1) == REGNO (crtl->drap_reg)
9741 : 3 : || REGNO (reg2) == REGNO (crtl->drap_reg)))
9742 : : {
9743 : : /* Previously we'd represented the CFA as an expression
9744 : : like *(%ebp - 8). We've just popped that value from
9745 : : the stack, which means we need to reset the CFA to
9746 : : the drap register. This will remain until we restore
9747 : : the stack pointer. */
9748 : 1 : add_reg_note (insn, REG_CFA_DEF_CFA,
9749 : 1 : REGNO (reg1) == REGNO (crtl->drap_reg) ? reg1 : reg2);
9750 : 1 : RTX_FRAME_RELATED_P (insn) = 1;
9751 : :
9752 : : /* This means that the DRAP register is valid for addressing too. */
9753 : 1 : m->fs.drap_valid = true;
9754 : 1 : return;
9755 : : }
9756 : :
9757 : 16 : if (m->fs.cfa_reg == stack_pointer_rtx)
9758 : : {
9759 : 14 : rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
9760 : 14 : x = gen_rtx_SET (stack_pointer_rtx, x);
9761 : 14 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
9762 : 14 : RTX_FRAME_RELATED_P (insn) = 1;
9763 : :
9764 : 14 : m->fs.cfa_offset -= offset;
9765 : : }
9766 : :
9767 : : /* When the frame pointer is the CFA, and we pop it, we are
9768 : : swapping back to the stack pointer as the CFA. This happens
9769 : : for stack frames that don't allocate other data, so we assume
9770 : : the stack pointer is now pointing at the return address, i.e.
9771 : : the function entry state, which makes the offset be 1 word. */
9772 : 16 : if (reg1 == hard_frame_pointer_rtx || reg2 == hard_frame_pointer_rtx)
9773 : : {
9774 : 0 : m->fs.fp_valid = false;
9775 : 0 : if (m->fs.cfa_reg == hard_frame_pointer_rtx)
9776 : : {
9777 : 0 : m->fs.cfa_reg = stack_pointer_rtx;
9778 : 0 : m->fs.cfa_offset -= offset;
9779 : :
9780 : 0 : add_reg_note (insn, REG_CFA_DEF_CFA,
9781 : 0 : plus_constant (Pmode, stack_pointer_rtx,
9782 : 0 : m->fs.cfa_offset));
9783 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9784 : : }
9785 : : }
9786 : : }
9787 : :
9788 : : /* Emit code to restore saved registers using POP insns. */
9789 : :
9790 : : static void
9791 : 1323677 : ix86_emit_restore_regs_using_pop (bool ppx_p)
9792 : : {
9793 : 1323677 : unsigned int regno;
9794 : :
9795 : 123101961 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9796 : 121778284 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
9797 : 1228689 : ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
9798 : 1323677 : }
9799 : :
9800 : : /* Emit code to restore saved registers using POP2 insns. */
9801 : :
9802 : : static void
9803 : 547 : ix86_emit_restore_regs_using_pop2 (void)
9804 : : {
9805 : 547 : int regno;
9806 : 547 : int regno_list[2];
9807 : 547 : regno_list[0] = regno_list[1] = -1;
9808 : 547 : int loaded_regnum = 0;
9809 : 547 : bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
9810 : :
9811 : 50871 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9812 : 50324 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
9813 : : {
9814 : 122 : if (aligned)
9815 : : {
9816 : 116 : regno_list[loaded_regnum++] = regno;
9817 : 116 : if (loaded_regnum == 2)
9818 : : {
9819 : 17 : gcc_assert (regno_list[0] != -1
9820 : : && regno_list[1] != -1
9821 : : && regno_list[0] != regno_list[1]);
9822 : :
9823 : 17 : ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
9824 : : regno_list[0]),
9825 : : gen_rtx_REG (word_mode,
9826 : : regno_list[1]),
9827 : 17 : TARGET_APX_PPX);
9828 : 17 : loaded_regnum = 0;
9829 : 17 : regno_list[0] = regno_list[1] = -1;
9830 : : }
9831 : : }
9832 : : else
9833 : : {
9834 : 12 : ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
9835 : 6 : TARGET_APX_PPX);
9836 : 6 : aligned = true;
9837 : : }
9838 : : }
9839 : :
9840 : 547 : if (loaded_regnum == 1)
9841 : 82 : ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
9842 : 82 : TARGET_APX_PPX);
9843 : 547 : }
9844 : :
9845 : : /* Emit code and notes for the LEAVE instruction. If insn is non-null,
9846 : : omits the emit and only attaches the notes. */
9847 : :
9848 : : static void
9849 : 238728 : ix86_emit_leave (rtx_insn *insn)
9850 : : {
9851 : 238728 : struct machine_function *m = cfun->machine;
9852 : :
9853 : 238728 : if (!insn)
9854 : 237757 : insn = emit_insn (gen_leave (word_mode));
9855 : :
9856 : 238728 : ix86_add_queued_cfa_restore_notes (insn);
9857 : :
9858 : 238728 : gcc_assert (m->fs.fp_valid);
9859 : 238728 : m->fs.sp_valid = true;
9860 : 238728 : m->fs.sp_realigned = false;
9861 : 238728 : m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
9862 : 238728 : m->fs.fp_valid = false;
9863 : :
9864 : 238728 : if (m->fs.cfa_reg == hard_frame_pointer_rtx)
9865 : : {
9866 : 235740 : m->fs.cfa_reg = stack_pointer_rtx;
9867 : 235740 : m->fs.cfa_offset = m->fs.sp_offset;
9868 : :
9869 : 235740 : add_reg_note (insn, REG_CFA_DEF_CFA,
9870 : 235740 : plus_constant (Pmode, stack_pointer_rtx,
9871 : 235740 : m->fs.sp_offset));
9872 : 235740 : RTX_FRAME_RELATED_P (insn) = 1;
9873 : : }
9874 : 238728 : ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
9875 : : m->fs.fp_offset);
9876 : 238728 : }
9877 : :
9878 : : /* Emit code to restore saved registers using MOV insns.
9879 : : First register is restored from CFA - CFA_OFFSET. */
9880 : : static void
9881 : 97707 : ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
9882 : : bool maybe_eh_return)
9883 : : {
9884 : 97707 : struct machine_function *m = cfun->machine;
9885 : 97707 : unsigned int regno;
9886 : :
9887 : 9086751 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9888 : 8989044 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
9889 : : {
9890 : :
9891 : : /* Skip registers, already processed by shrink wrap separate. */
9892 : 273941 : if (!cfun->machine->reg_is_wrapped_separately[regno])
9893 : : {
9894 : 143596 : rtx reg = gen_rtx_REG (word_mode, regno);
9895 : 143596 : rtx mem;
9896 : 143596 : rtx_insn *insn;
9897 : :
9898 : 143596 : mem = choose_baseaddr (cfa_offset, NULL);
9899 : 143596 : mem = gen_frame_mem (word_mode, mem);
9900 : 143596 : insn = emit_move_insn (reg, mem);
9901 : :
9902 : 143596 : if (m->fs.cfa_reg == crtl->drap_reg
9903 : 143596 : && regno == REGNO (crtl->drap_reg))
9904 : : {
9905 : : /* Previously we'd represented the CFA as an expression
9906 : : like *(%ebp - 8). We've just popped that value from
9907 : : the stack, which means we need to reset the CFA to
9908 : : the drap register. This will remain until we restore
9909 : : the stack pointer. */
9910 : 2988 : add_reg_note (insn, REG_CFA_DEF_CFA, reg);
9911 : 2988 : RTX_FRAME_RELATED_P (insn) = 1;
9912 : :
9913 : : /* DRAP register is valid for addressing. */
9914 : 2988 : m->fs.drap_valid = true;
9915 : : }
9916 : : else
9917 : 140608 : ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
9918 : : }
9919 : 293195 : cfa_offset -= UNITS_PER_WORD;
9920 : : }
9921 : 97707 : }
9922 : :
9923 : : /* Emit code to restore saved registers using MOV insns.
9924 : : First register is restored from CFA - CFA_OFFSET. */
9925 : : static void
9926 : 33927 : ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
9927 : : bool maybe_eh_return)
9928 : : {
9929 : 33927 : unsigned int regno;
9930 : :
9931 : 3155211 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9932 : 3121284 : if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
9933 : : {
9934 : 339285 : rtx reg = gen_rtx_REG (V4SFmode, regno);
9935 : 339285 : rtx mem;
9936 : 339285 : unsigned int align = GET_MODE_ALIGNMENT (V4SFmode);
9937 : :
9938 : 339285 : mem = choose_baseaddr (cfa_offset, &align);
9939 : 339285 : mem = gen_rtx_MEM (V4SFmode, mem);
9940 : :
9941 : : /* The location aligment depends upon the base register. */
9942 : 339285 : align = MIN (GET_MODE_ALIGNMENT (V4SFmode), align);
9943 : 339285 : gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
9944 : 339285 : set_mem_align (mem, align);
9945 : 339285 : emit_insn (gen_rtx_SET (reg, mem));
9946 : :
9947 : 339285 : ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
9948 : :
9949 : 339285 : cfa_offset -= GET_MODE_SIZE (V4SFmode);
9950 : : }
9951 : 33927 : }
9952 : :
9953 : : static void
9954 : 7621 : ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
9955 : : bool use_call, int style)
9956 : : {
9957 : 7621 : struct machine_function *m = cfun->machine;
9958 : 7621 : const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
9959 : 7621 : + m->call_ms2sysv_extra_regs;
9960 : 7621 : rtvec v;
9961 : 7621 : unsigned int elems_needed, align, i, vi = 0;
9962 : 7621 : rtx_insn *insn;
9963 : 7621 : rtx sym, tmp;
9964 : 7621 : rtx rsi = gen_rtx_REG (word_mode, SI_REG);
9965 : 7621 : rtx r10 = NULL_RTX;
9966 : 7621 : const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
9967 : 7621 : HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
9968 : 7621 : HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
9969 : 7621 : rtx rsi_frame_load = NULL_RTX;
9970 : 7621 : HOST_WIDE_INT rsi_restore_offset = (HOST_WIDE_INT)-1;
9971 : 7621 : enum xlogue_stub stub;
9972 : :
9973 : 7621 : gcc_assert (!m->fs.fp_valid || frame_pointer_needed);
9974 : :
9975 : : /* If using a realigned stack, we should never start with padding. */
9976 : 7621 : gcc_assert (!stack_realign_fp || !xlogue.get_stack_align_off_in ());
9977 : :
9978 : : /* Setup RSI as the stub's base pointer. */
9979 : 7621 : align = GET_MODE_ALIGNMENT (V4SFmode);
9980 : 7621 : tmp = choose_baseaddr (rsi_offset, &align, SI_REG);
9981 : 7621 : gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
9982 : :
9983 : 7621 : emit_insn (gen_rtx_SET (rsi, tmp));
9984 : :
9985 : : /* Get a symbol for the stub. */
9986 : 7621 : if (frame_pointer_needed)
9987 : 5955 : stub = use_call ? XLOGUE_STUB_RESTORE_HFP
9988 : : : XLOGUE_STUB_RESTORE_HFP_TAIL;
9989 : : else
9990 : 1666 : stub = use_call ? XLOGUE_STUB_RESTORE
9991 : : : XLOGUE_STUB_RESTORE_TAIL;
9992 : 7621 : sym = xlogue.get_stub_rtx (stub);
9993 : :
9994 : 7621 : elems_needed = ncregs;
9995 : 7621 : if (use_call)
9996 : 6498 : elems_needed += 1;
9997 : : else
9998 : 1275 : elems_needed += frame_pointer_needed ? 5 : 3;
9999 : 7621 : v = rtvec_alloc (elems_needed);
10000 : :
10001 : : /* We call the epilogue stub when we need to pop incoming args or we are
10002 : : doing a sibling call as the tail. Otherwise, we will emit a jmp to the
10003 : : epilogue stub and it is the tail-call. */
10004 : 7621 : if (use_call)
10005 : 6498 : RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
10006 : : else
10007 : : {
10008 : 1123 : RTVEC_ELT (v, vi++) = ret_rtx;
10009 : 1123 : RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
10010 : 1123 : if (frame_pointer_needed)
10011 : : {
10012 : 971 : rtx rbp = gen_rtx_REG (DImode, BP_REG);
10013 : 971 : gcc_assert (m->fs.fp_valid);
10014 : 971 : gcc_assert (m->fs.cfa_reg == hard_frame_pointer_rtx);
10015 : :
10016 : 971 : tmp = plus_constant (DImode, rbp, 8);
10017 : 971 : RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, tmp);
10018 : 971 : RTVEC_ELT (v, vi++) = gen_rtx_SET (rbp, gen_rtx_MEM (DImode, rbp));
10019 : 971 : tmp = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
10020 : 971 : RTVEC_ELT (v, vi++) = gen_rtx_CLOBBER (VOIDmode, tmp);
10021 : : }
10022 : : else
10023 : : {
10024 : : /* If no hard frame pointer, we set R10 to the SP restore value. */
10025 : 152 : gcc_assert (!m->fs.fp_valid);
10026 : 152 : gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
10027 : 152 : gcc_assert (m->fs.sp_valid);
10028 : :
10029 : 152 : r10 = gen_rtx_REG (DImode, R10_REG);
10030 : 152 : tmp = plus_constant (Pmode, rsi, stub_ptr_offset);
10031 : 152 : emit_insn (gen_rtx_SET (r10, tmp));
10032 : :
10033 : 152 : RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, r10);
10034 : : }
10035 : : }
10036 : :
10037 : : /* Generate frame load insns and restore notes. */
10038 : 107954 : for (i = 0; i < ncregs; ++i)
10039 : : {
10040 : 100333 : const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
10041 : 100333 : machine_mode mode = SSE_REGNO_P (r.regno) ? V4SFmode : word_mode;
10042 : 100333 : rtx reg, frame_load;
10043 : :
10044 : 100333 : reg = gen_rtx_REG (mode, r.regno);
10045 : 100333 : frame_load = gen_frame_load (reg, rsi, r.offset);
10046 : :
10047 : : /* Save RSI frame load insn & note to add last. */
10048 : 100333 : if (r.regno == SI_REG)
10049 : : {
10050 : 7621 : gcc_assert (!rsi_frame_load);
10051 : 7621 : rsi_frame_load = frame_load;
10052 : 7621 : rsi_restore_offset = r.offset;
10053 : : }
10054 : : else
10055 : : {
10056 : 92712 : RTVEC_ELT (v, vi++) = frame_load;
10057 : 92712 : ix86_add_cfa_restore_note (NULL, reg, r.offset);
10058 : : }
10059 : : }
10060 : :
10061 : : /* Add RSI frame load & restore note at the end. */
10062 : 7621 : gcc_assert (rsi_frame_load);
10063 : 7621 : gcc_assert (rsi_restore_offset != (HOST_WIDE_INT)-1);
10064 : 7621 : RTVEC_ELT (v, vi++) = rsi_frame_load;
10065 : 7621 : ix86_add_cfa_restore_note (NULL, gen_rtx_REG (DImode, SI_REG),
10066 : : rsi_restore_offset);
10067 : :
10068 : : /* Finally, for tail-call w/o a hard frame pointer, set SP to R10. */
10069 : 7621 : if (!use_call && !frame_pointer_needed)
10070 : : {
10071 : 152 : gcc_assert (m->fs.sp_valid);
10072 : 152 : gcc_assert (!m->fs.sp_realigned);
10073 : :
10074 : : /* At this point, R10 should point to frame.stack_realign_offset. */
10075 : 152 : if (m->fs.cfa_reg == stack_pointer_rtx)
10076 : 152 : m->fs.cfa_offset += m->fs.sp_offset - frame.stack_realign_offset;
10077 : 152 : m->fs.sp_offset = frame.stack_realign_offset;
10078 : : }
10079 : :
10080 : 7621 : gcc_assert (vi == (unsigned int)GET_NUM_ELEM (v));
10081 : 7621 : tmp = gen_rtx_PARALLEL (VOIDmode, v);
10082 : 7621 : if (use_call)
10083 : 6498 : insn = emit_insn (tmp);
10084 : : else
10085 : : {
10086 : 1123 : insn = emit_jump_insn (tmp);
10087 : 1123 : JUMP_LABEL (insn) = ret_rtx;
10088 : :
10089 : 1123 : if (frame_pointer_needed)
10090 : 971 : ix86_emit_leave (insn);
10091 : : else
10092 : : {
10093 : : /* Need CFA adjust note. */
10094 : 152 : tmp = gen_rtx_SET (stack_pointer_rtx, r10);
10095 : 152 : add_reg_note (insn, REG_CFA_ADJUST_CFA, tmp);
10096 : : }
10097 : : }
10098 : :
10099 : 7621 : RTX_FRAME_RELATED_P (insn) = true;
10100 : 7621 : ix86_add_queued_cfa_restore_notes (insn);
10101 : :
10102 : : /* If we're not doing a tail-call, we need to adjust the stack. */
10103 : 7621 : if (use_call && m->fs.sp_valid)
10104 : : {
10105 : 3706 : HOST_WIDE_INT dealloc = m->fs.sp_offset - frame.stack_realign_offset;
10106 : 3706 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10107 : : GEN_INT (dealloc), style,
10108 : 3706 : m->fs.cfa_reg == stack_pointer_rtx);
10109 : : }
10110 : 7621 : }
10111 : :
10112 : : /* Restore function stack, frame, and registers. */
10113 : :
10114 : : void
10115 : 1616372 : ix86_expand_epilogue (int style)
10116 : : {
10117 : 1616372 : struct machine_function *m = cfun->machine;
10118 : 1616372 : struct machine_frame_state frame_state_save = m->fs;
10119 : 1616372 : bool restore_regs_via_mov;
10120 : 1616372 : bool using_drap;
10121 : 1616372 : bool restore_stub_is_tail = false;
10122 : :
10123 : 1616372 : if (ix86_function_naked (current_function_decl))
10124 : : {
10125 : : /* The program should not reach this point. */
10126 : 74 : emit_insn (gen_ud2 ());
10127 : 121276 : return;
10128 : : }
10129 : :
10130 : 1616298 : ix86_finalize_stack_frame_flags ();
10131 : 1616298 : const struct ix86_frame &frame = cfun->machine->frame;
10132 : :
10133 : 1616298 : m->fs.sp_realigned = stack_realign_fp;
10134 : 31439 : m->fs.sp_valid = stack_realign_fp
10135 : 1591869 : || !frame_pointer_needed
10136 : 2060349 : || crtl->sp_is_unchanging;
10137 : 1616298 : gcc_assert (!m->fs.sp_valid
10138 : : || m->fs.sp_offset == frame.stack_pointer_offset);
10139 : :
10140 : : /* The FP must be valid if the frame pointer is present. */
10141 : 1616298 : gcc_assert (frame_pointer_needed == m->fs.fp_valid);
10142 : 1616298 : gcc_assert (!m->fs.fp_valid
10143 : : || m->fs.fp_offset == frame.hard_frame_pointer_offset);
10144 : :
10145 : : /* We must have *some* valid pointer to the stack frame. */
10146 : 1616298 : gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
10147 : :
10148 : : /* The DRAP is never valid at this point. */
10149 : 1616298 : gcc_assert (!m->fs.drap_valid);
10150 : :
10151 : : /* See the comment about red zone and frame
10152 : : pointer usage in ix86_expand_prologue. */
10153 : 1616298 : if (frame_pointer_needed && frame.red_zone_size)
10154 : 124577 : emit_insn (gen_memory_blockage ());
10155 : :
10156 : 1616298 : using_drap = crtl->drap_reg && crtl->stack_realign_needed;
10157 : 7010 : gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
10158 : :
10159 : : /* Determine the CFA offset of the end of the red-zone. */
10160 : 1616298 : m->fs.red_zone_offset = 0;
10161 : 1616298 : if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
10162 : : {
10163 : : /* The red-zone begins below return address and error code in
10164 : : exception handler. */
10165 : 1440352 : m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
10166 : :
10167 : : /* When the register save area is in the aligned portion of
10168 : : the stack, determine the maximum runtime displacement that
10169 : : matches up with the aligned frame. */
10170 : 1440352 : if (stack_realign_drap)
10171 : 8298 : m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
10172 : 4149 : + UNITS_PER_WORD);
10173 : : }
10174 : :
10175 : 1616298 : HOST_WIDE_INT reg_save_offset = frame.reg_save_offset;
10176 : :
10177 : : /* Special care must be taken for the normal return case of a function
10178 : : using eh_return: the eax and edx registers are marked as saved, but
10179 : : not restored along this path. Adjust the save location to match. */
10180 : 1616298 : if (crtl->calls_eh_return && style != 2)
10181 : 37 : reg_save_offset -= 2 * UNITS_PER_WORD;
10182 : :
10183 : : /* EH_RETURN requires the use of moves to function properly. */
10184 : 1616298 : if (crtl->calls_eh_return)
10185 : : restore_regs_via_mov = true;
10186 : : /* SEH requires the use of pops to identify the epilogue. */
10187 : 1616240 : else if (TARGET_SEH)
10188 : : restore_regs_via_mov = false;
10189 : : /* If we already save reg with pushp, don't use move at epilogue. */
10190 : 1616240 : else if (m->fs.apx_ppx_used)
10191 : : restore_regs_via_mov = false;
10192 : : /* If we're only restoring one register and sp cannot be used then
10193 : : using a move instruction to restore the register since it's
10194 : : less work than reloading sp and popping the register. */
10195 : 1616155 : else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
10196 : : restore_regs_via_mov = true;
10197 : 1556173 : else if (crtl->shrink_wrapped_separate
10198 : 1500878 : || (TARGET_EPILOGUE_USING_MOVE
10199 : 56639 : && cfun->machine->use_fast_prologue_epilogue
10200 : 56583 : && (frame.nregs > 1
10201 : 56570 : || m->fs.sp_offset != reg_save_offset)))
10202 : : restore_regs_via_mov = true;
10203 : 1500642 : else if (frame_pointer_needed
10204 : 405982 : && !frame.nregs
10205 : 313353 : && m->fs.sp_offset != reg_save_offset)
10206 : : restore_regs_via_mov = true;
10207 : 1352726 : else if (frame_pointer_needed
10208 : 258066 : && TARGET_USE_LEAVE
10209 : 257991 : && cfun->machine->use_fast_prologue_epilogue
10210 : 202243 : && frame.nregs == 1)
10211 : : restore_regs_via_mov = true;
10212 : : else
10213 : 1616298 : restore_regs_via_mov = false;
10214 : :
10215 : 1616298 : if (crtl->shrink_wrapped_separate)
10216 : 55318 : gcc_assert (restore_regs_via_mov);
10217 : :
10218 : 1560980 : if (restore_regs_via_mov || frame.nsseregs)
10219 : : {
10220 : : /* Ensure that the entire register save area is addressable via
10221 : : the stack pointer, if we will restore SSE regs via sp. */
10222 : 325648 : if (TARGET_64BIT
10223 : 313414 : && m->fs.sp_offset > 0x7fffffff
10224 : 26 : && sp_valid_at (frame.stack_realign_offset + 1)
10225 : 325673 : && (frame.nsseregs + frame.nregs) != 0)
10226 : : {
10227 : 6 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10228 : 6 : GEN_INT (m->fs.sp_offset
10229 : : - frame.sse_reg_save_offset),
10230 : : style,
10231 : 6 : m->fs.cfa_reg == stack_pointer_rtx);
10232 : : }
10233 : : }
10234 : :
10235 : : /* If there are any SSE registers to restore, then we have to do it
10236 : : via moves, since there's obviously no pop for SSE regs. */
10237 : 1616298 : if (frame.nsseregs)
10238 : 33927 : ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
10239 : : style == 2);
10240 : :
10241 : 1616298 : if (m->call_ms2sysv)
10242 : : {
10243 : 7621 : int pop_incoming_args = crtl->args.pops_args && crtl->args.size;
10244 : :
10245 : : /* We cannot use a tail-call for the stub if:
10246 : : 1. We have to pop incoming args,
10247 : : 2. We have additional int regs to restore, or
10248 : : 3. A sibling call will be the tail-call, or
10249 : : 4. We are emitting an eh_return_internal epilogue.
10250 : :
10251 : : TODO: Item 4 has not yet tested!
10252 : :
10253 : : If any of the above are true, we will call the stub rather than
10254 : : jump to it. */
10255 : 7621 : restore_stub_is_tail = !(pop_incoming_args || frame.nregs || style != 1);
10256 : 7621 : ix86_emit_outlined_ms2sysv_restore (frame, !restore_stub_is_tail, style);
10257 : : }
10258 : :
10259 : : /* If using out-of-line stub that is a tail-call, then...*/
10260 : 1616298 : if (m->call_ms2sysv && restore_stub_is_tail)
10261 : : {
10262 : : /* TODO: parinoid tests. (remove eventually) */
10263 : 1123 : gcc_assert (m->fs.sp_valid);
10264 : 1123 : gcc_assert (!m->fs.sp_realigned);
10265 : 1123 : gcc_assert (!m->fs.fp_valid);
10266 : 1123 : gcc_assert (!m->fs.realigned);
10267 : 1123 : gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
10268 : 1123 : gcc_assert (!crtl->drap_reg);
10269 : 1123 : gcc_assert (!frame.nregs);
10270 : 1123 : gcc_assert (!crtl->shrink_wrapped_separate);
10271 : : }
10272 : 1615175 : else if (restore_regs_via_mov)
10273 : : {
10274 : 290951 : rtx t;
10275 : :
10276 : 290951 : if (frame.nregs)
10277 : 97707 : ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2);
10278 : :
10279 : : /* eh_return epilogues need %ecx added to the stack pointer. */
10280 : 290951 : if (style == 2)
10281 : : {
10282 : 37 : rtx sa = EH_RETURN_STACKADJ_RTX;
10283 : 29 : rtx_insn *insn;
10284 : :
10285 : 29 : gcc_assert (!crtl->shrink_wrapped_separate);
10286 : :
10287 : : /* Stack realignment doesn't work with eh_return. */
10288 : 29 : if (crtl->stack_realign_needed)
10289 : 0 : sorry ("Stack realignment not supported with "
10290 : : "%<__builtin_eh_return%>");
10291 : :
10292 : : /* regparm nested functions don't work with eh_return. */
10293 : 29 : if (ix86_static_chain_on_stack)
10294 : 0 : sorry ("regparm nested function not supported with "
10295 : : "%<__builtin_eh_return%>");
10296 : :
10297 : 29 : if (frame_pointer_needed)
10298 : : {
10299 : 35 : t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
10300 : 43 : t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
10301 : 27 : emit_insn (gen_rtx_SET (sa, t));
10302 : :
10303 : : /* NB: eh_return epilogues must restore the frame pointer
10304 : : in word_mode since the upper 32 bits of RBP register
10305 : : can have any values. */
10306 : 27 : t = gen_frame_mem (word_mode, hard_frame_pointer_rtx);
10307 : 27 : rtx frame_reg = gen_rtx_REG (word_mode,
10308 : : HARD_FRAME_POINTER_REGNUM);
10309 : 27 : insn = emit_move_insn (frame_reg, t);
10310 : :
10311 : : /* Note that we use SA as a temporary CFA, as the return
10312 : : address is at the proper place relative to it. We
10313 : : pretend this happens at the FP restore insn because
10314 : : prior to this insn the FP would be stored at the wrong
10315 : : offset relative to SA, and after this insn we have no
10316 : : other reasonable register to use for the CFA. We don't
10317 : : bother resetting the CFA to the SP for the duration of
10318 : : the return insn, unless the control flow instrumentation
10319 : : is done. In this case the SP is used later and we have
10320 : : to reset CFA to SP. */
10321 : 27 : add_reg_note (insn, REG_CFA_DEF_CFA,
10322 : 35 : plus_constant (Pmode, sa, UNITS_PER_WORD));
10323 : 27 : ix86_add_queued_cfa_restore_notes (insn);
10324 : 27 : add_reg_note (insn, REG_CFA_RESTORE, frame_reg);
10325 : 27 : RTX_FRAME_RELATED_P (insn) = 1;
10326 : :
10327 : 27 : m->fs.cfa_reg = sa;
10328 : 27 : m->fs.cfa_offset = UNITS_PER_WORD;
10329 : 27 : m->fs.fp_valid = false;
10330 : :
10331 : 27 : pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
10332 : : const0_rtx, style,
10333 : 27 : flag_cf_protection);
10334 : : }
10335 : : else
10336 : : {
10337 : 2 : t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
10338 : 2 : t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
10339 : 2 : insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, t));
10340 : 2 : ix86_add_queued_cfa_restore_notes (insn);
10341 : :
10342 : 2 : gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
10343 : 2 : if (m->fs.cfa_offset != UNITS_PER_WORD)
10344 : : {
10345 : 2 : m->fs.cfa_offset = UNITS_PER_WORD;
10346 : 2 : add_reg_note (insn, REG_CFA_DEF_CFA,
10347 : 2 : plus_constant (Pmode, stack_pointer_rtx,
10348 : 2 : UNITS_PER_WORD));
10349 : 2 : RTX_FRAME_RELATED_P (insn) = 1;
10350 : : }
10351 : : }
10352 : 29 : m->fs.sp_offset = UNITS_PER_WORD;
10353 : 29 : m->fs.sp_valid = true;
10354 : 29 : m->fs.sp_realigned = false;
10355 : : }
10356 : : }
10357 : : else
10358 : : {
10359 : : /* SEH requires that the function end with (1) a stack adjustment
10360 : : if necessary, (2) a sequence of pops, and (3) a return or
10361 : : jump instruction. Prevent insns from the function body from
10362 : : being scheduled into this sequence. */
10363 : 1324224 : if (TARGET_SEH)
10364 : : {
10365 : : /* Prevent a catch region from being adjacent to the standard
10366 : : epilogue sequence. Unfortunately neither crtl->uses_eh_lsda
10367 : : nor several other flags that would be interesting to test are
10368 : : set up yet. */
10369 : : if (flag_non_call_exceptions)
10370 : : emit_insn (gen_nops (const1_rtx));
10371 : : else
10372 : : emit_insn (gen_blockage ());
10373 : : }
10374 : :
10375 : : /* First step is to deallocate the stack frame so that we can
10376 : : pop the registers. If the stack pointer was realigned, it needs
10377 : : to be restored now. Also do it on SEH target for very large
10378 : : frame as the emitted instructions aren't allowed by the ABI
10379 : : in epilogues. */
10380 : 1324224 : if (!m->fs.sp_valid || m->fs.sp_realigned
10381 : : || (TARGET_SEH
10382 : : && (m->fs.sp_offset - reg_save_offset
10383 : : >= SEH_MAX_FRAME_SIZE)))
10384 : : {
10385 : 29118 : pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
10386 : 29118 : GEN_INT (m->fs.fp_offset
10387 : : - reg_save_offset),
10388 : : style, false);
10389 : : }
10390 : 1295106 : else if (m->fs.sp_offset != reg_save_offset)
10391 : : {
10392 : 608952 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10393 : : GEN_INT (m->fs.sp_offset
10394 : : - reg_save_offset),
10395 : : style,
10396 : 608952 : m->fs.cfa_reg == stack_pointer_rtx);
10397 : : }
10398 : :
10399 : 1324224 : if (TARGET_APX_PUSH2POP2
10400 : 550 : && ix86_can_use_push2pop2 ()
10401 : 1324772 : && m->func_type == TYPE_NORMAL)
10402 : 547 : ix86_emit_restore_regs_using_pop2 ();
10403 : : else
10404 : 1323677 : ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
10405 : : }
10406 : :
10407 : : /* If we used a stack pointer and haven't already got rid of it,
10408 : : then do so now. */
10409 : 1616298 : if (m->fs.fp_valid)
10410 : : {
10411 : : /* If the stack pointer is valid and pointing at the frame
10412 : : pointer store address, then we only need a pop. */
10413 : 467482 : if (sp_valid_at (frame.hfp_save_offset)
10414 : 467482 : && m->fs.sp_offset == frame.hfp_save_offset)
10415 : 229713 : ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
10416 : : /* Leave results in shorter dependency chains on CPUs that are
10417 : : able to grok it fast. */
10418 : 237769 : else if (TARGET_USE_LEAVE
10419 : 12 : || optimize_bb_for_size_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
10420 : 237781 : || !cfun->machine->use_fast_prologue_epilogue)
10421 : 237757 : ix86_emit_leave (NULL);
10422 : : else
10423 : : {
10424 : 12 : pro_epilogue_adjust_stack (stack_pointer_rtx,
10425 : : hard_frame_pointer_rtx,
10426 : 12 : const0_rtx, style, !using_drap);
10427 : 12 : ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
10428 : : }
10429 : : }
10430 : :
10431 : 1616298 : if (using_drap)
10432 : : {
10433 : 7010 : int param_ptr_offset = UNITS_PER_WORD;
10434 : 7010 : rtx_insn *insn;
10435 : :
10436 : 7010 : gcc_assert (stack_realign_drap);
10437 : :
10438 : 7010 : if (ix86_static_chain_on_stack)
10439 : 0 : param_ptr_offset += UNITS_PER_WORD;
10440 : 7010 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
10441 : 230 : param_ptr_offset += UNITS_PER_WORD;
10442 : :
10443 : 7311 : insn = emit_insn (gen_rtx_SET
10444 : : (stack_pointer_rtx,
10445 : : plus_constant (Pmode, crtl->drap_reg,
10446 : : -param_ptr_offset)));
10447 : 7010 : m->fs.cfa_reg = stack_pointer_rtx;
10448 : 7010 : m->fs.cfa_offset = param_ptr_offset;
10449 : 7010 : m->fs.sp_offset = param_ptr_offset;
10450 : 7010 : m->fs.realigned = false;
10451 : :
10452 : 7311 : add_reg_note (insn, REG_CFA_DEF_CFA,
10453 : 7010 : plus_constant (Pmode, stack_pointer_rtx,
10454 : 7010 : param_ptr_offset));
10455 : 7010 : RTX_FRAME_RELATED_P (insn) = 1;
10456 : :
10457 : 7010 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
10458 : 230 : ix86_emit_restore_reg_using_pop (crtl->drap_reg);
10459 : : }
10460 : :
10461 : : /* At this point the stack pointer must be valid, and we must have
10462 : : restored all of the registers. We may not have deallocated the
10463 : : entire stack frame. We've delayed this until now because it may
10464 : : be possible to merge the local stack deallocation with the
10465 : : deallocation forced by ix86_static_chain_on_stack. */
10466 : 1616298 : gcc_assert (m->fs.sp_valid);
10467 : 1616298 : gcc_assert (!m->fs.sp_realigned);
10468 : 1616298 : gcc_assert (!m->fs.fp_valid);
10469 : 1616298 : gcc_assert (!m->fs.realigned);
10470 : 1750535 : if (m->fs.sp_offset != UNITS_PER_WORD)
10471 : : {
10472 : 53138 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10473 : : GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
10474 : : style, true);
10475 : : }
10476 : : else
10477 : 1563160 : ix86_add_queued_cfa_restore_notes (get_last_insn ());
10478 : :
10479 : : /* Sibcall epilogues don't want a return instruction. */
10480 : 1616298 : if (style == 0)
10481 : : {
10482 : 121128 : m->fs = frame_state_save;
10483 : 121128 : return;
10484 : : }
10485 : :
10486 : 1495170 : if (cfun->machine->func_type != TYPE_NORMAL)
10487 : 118 : emit_jump_insn (gen_interrupt_return ());
10488 : 1495052 : else if (crtl->args.pops_args && crtl->args.size)
10489 : : {
10490 : 25892 : rtx popc = GEN_INT (crtl->args.pops_args);
10491 : :
10492 : : /* i386 can only pop 64K bytes. If asked to pop more, pop return
10493 : : address, do explicit add, and jump indirectly to the caller. */
10494 : :
10495 : 25892 : if (crtl->args.pops_args >= 65536)
10496 : : {
10497 : 0 : rtx ecx = gen_rtx_REG (SImode, CX_REG);
10498 : 0 : rtx_insn *insn;
10499 : :
10500 : : /* There is no "pascal" calling convention in any 64bit ABI. */
10501 : 0 : gcc_assert (!TARGET_64BIT);
10502 : :
10503 : 0 : insn = emit_insn (gen_pop (ecx));
10504 : 0 : m->fs.cfa_offset -= UNITS_PER_WORD;
10505 : 0 : m->fs.sp_offset -= UNITS_PER_WORD;
10506 : :
10507 : 0 : rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
10508 : 0 : x = gen_rtx_SET (stack_pointer_rtx, x);
10509 : 0 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
10510 : 0 : add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
10511 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
10512 : :
10513 : 0 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10514 : : popc, -1, true);
10515 : 0 : emit_jump_insn (gen_simple_return_indirect_internal (ecx));
10516 : : }
10517 : : else
10518 : 25892 : emit_jump_insn (gen_simple_return_pop_internal (popc));
10519 : : }
10520 : 1469160 : else if (!m->call_ms2sysv || !restore_stub_is_tail)
10521 : : {
10522 : : /* In case of return from EH a simple return cannot be used
10523 : : as a return address will be compared with a shadow stack
10524 : : return address. Use indirect jump instead. */
10525 : 1468037 : if (style == 2 && flag_cf_protection)
10526 : : {
10527 : : /* Register used in indirect jump must be in word_mode. But
10528 : : Pmode may not be the same as word_mode for x32. */
10529 : 17 : rtx ecx = gen_rtx_REG (word_mode, CX_REG);
10530 : 17 : rtx_insn *insn;
10531 : :
10532 : 17 : insn = emit_insn (gen_pop (ecx));
10533 : 17 : m->fs.cfa_offset -= UNITS_PER_WORD;
10534 : 17 : m->fs.sp_offset -= UNITS_PER_WORD;
10535 : :
10536 : 33 : rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
10537 : 17 : x = gen_rtx_SET (stack_pointer_rtx, x);
10538 : 17 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
10539 : 17 : add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
10540 : 17 : RTX_FRAME_RELATED_P (insn) = 1;
10541 : :
10542 : 17 : emit_jump_insn (gen_simple_return_indirect_internal (ecx));
10543 : 17 : }
10544 : : else
10545 : 1468020 : emit_jump_insn (gen_simple_return_internal ());
10546 : : }
10547 : :
10548 : : /* Restore the state back to the state from the prologue,
10549 : : so that it's correct for the next epilogue. */
10550 : 1495170 : m->fs = frame_state_save;
10551 : : }
10552 : :
10553 : : /* Reset from the function's potential modifications. */
10554 : :
10555 : : static void
10556 : 1454406 : ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
10557 : : {
10558 : 1454406 : if (pic_offset_table_rtx
10559 : 1454406 : && !ix86_use_pseudo_pic_reg ())
10560 : 0 : SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
10561 : :
10562 : 1454406 : if (TARGET_MACHO)
10563 : : {
10564 : : rtx_insn *insn = get_last_insn ();
10565 : : rtx_insn *deleted_debug_label = NULL;
10566 : :
10567 : : /* Mach-O doesn't support labels at the end of objects, so if
10568 : : it looks like we might want one, take special action.
10569 : : First, collect any sequence of deleted debug labels. */
10570 : : while (insn
10571 : : && NOTE_P (insn)
10572 : : && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
10573 : : {
10574 : : /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
10575 : : notes only, instead set their CODE_LABEL_NUMBER to -1,
10576 : : otherwise there would be code generation differences
10577 : : in between -g and -g0. */
10578 : : if (NOTE_P (insn) && NOTE_KIND (insn)
10579 : : == NOTE_INSN_DELETED_DEBUG_LABEL)
10580 : : deleted_debug_label = insn;
10581 : : insn = PREV_INSN (insn);
10582 : : }
10583 : :
10584 : : /* If we have:
10585 : : label:
10586 : : barrier
10587 : : then this needs to be detected, so skip past the barrier. */
10588 : :
10589 : : if (insn && BARRIER_P (insn))
10590 : : insn = PREV_INSN (insn);
10591 : :
10592 : : /* Up to now we've only seen notes or barriers. */
10593 : : if (insn)
10594 : : {
10595 : : if (LABEL_P (insn)
10596 : : || (NOTE_P (insn)
10597 : : && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
10598 : : /* Trailing label. */
10599 : : fputs ("\tnop\n", file);
10600 : : else if (cfun && ! cfun->is_thunk)
10601 : : {
10602 : : /* See if we have a completely empty function body, skipping
10603 : : the special case of the picbase thunk emitted as asm. */
10604 : : while (insn && ! INSN_P (insn))
10605 : : insn = PREV_INSN (insn);
10606 : : /* If we don't find any insns, we've got an empty function body;
10607 : : I.e. completely empty - without a return or branch. This is
10608 : : taken as the case where a function body has been removed
10609 : : because it contains an inline __builtin_unreachable(). GCC
10610 : : declares that reaching __builtin_unreachable() means UB so
10611 : : we're not obliged to do anything special; however, we want
10612 : : non-zero-sized function bodies. To meet this, and help the
10613 : : user out, let's trap the case. */
10614 : : if (insn == NULL)
10615 : : fputs ("\tud2\n", file);
10616 : : }
10617 : : }
10618 : : else if (deleted_debug_label)
10619 : : for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
10620 : : if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
10621 : : CODE_LABEL_NUMBER (insn) = -1;
10622 : : }
10623 : 1454406 : }
10624 : :
10625 : : /* Implement TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY. */
10626 : :
10627 : : void
10628 : 59 : ix86_print_patchable_function_entry (FILE *file,
10629 : : unsigned HOST_WIDE_INT patch_area_size,
10630 : : bool record_p)
10631 : : {
10632 : 59 : if (cfun->machine->function_label_emitted)
10633 : : {
10634 : : /* NB: When ix86_print_patchable_function_entry is called after
10635 : : function table has been emitted, we have inserted or queued
10636 : : a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
10637 : : place. There is nothing to do here. */
10638 : : return;
10639 : : }
10640 : :
10641 : 8 : default_print_patchable_function_entry (file, patch_area_size,
10642 : : record_p);
10643 : : }
10644 : :
10645 : : /* Output patchable area. NB: default_print_patchable_function_entry
10646 : : isn't available in i386.md. */
10647 : :
10648 : : void
10649 : 51 : ix86_output_patchable_area (unsigned int patch_area_size,
10650 : : bool record_p)
10651 : : {
10652 : 51 : default_print_patchable_function_entry (asm_out_file,
10653 : : patch_area_size,
10654 : : record_p);
10655 : 51 : }
10656 : :
10657 : : /* Return a scratch register to use in the split stack prologue. The
10658 : : split stack prologue is used for -fsplit-stack. It is the first
10659 : : instructions in the function, even before the regular prologue.
10660 : : The scratch register can be any caller-saved register which is not
10661 : : used for parameters or for the static chain. */
10662 : :
10663 : : static unsigned int
10664 : 25148 : split_stack_prologue_scratch_regno (void)
10665 : : {
10666 : 25148 : if (TARGET_64BIT)
10667 : : return R11_REG;
10668 : : else
10669 : : {
10670 : 7120 : bool is_fastcall, is_thiscall;
10671 : 7120 : int regparm;
10672 : :
10673 : 7120 : is_fastcall = (lookup_attribute ("fastcall",
10674 : 7120 : TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
10675 : : != NULL);
10676 : 7120 : is_thiscall = (lookup_attribute ("thiscall",
10677 : 7120 : TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
10678 : : != NULL);
10679 : 7120 : regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
10680 : :
10681 : 7120 : if (is_fastcall)
10682 : : {
10683 : 0 : if (DECL_STATIC_CHAIN (cfun->decl))
10684 : : {
10685 : 0 : sorry ("%<-fsplit-stack%> does not support fastcall with "
10686 : : "nested function");
10687 : 0 : return INVALID_REGNUM;
10688 : : }
10689 : : return AX_REG;
10690 : : }
10691 : 7120 : else if (is_thiscall)
10692 : : {
10693 : 0 : if (!DECL_STATIC_CHAIN (cfun->decl))
10694 : : return DX_REG;
10695 : 0 : return AX_REG;
10696 : : }
10697 : 7120 : else if (regparm < 3)
10698 : : {
10699 : 7120 : if (!DECL_STATIC_CHAIN (cfun->decl))
10700 : : return CX_REG;
10701 : : else
10702 : : {
10703 : 465 : if (regparm >= 2)
10704 : : {
10705 : 0 : sorry ("%<-fsplit-stack%> does not support 2 register "
10706 : : "parameters for a nested function");
10707 : 0 : return INVALID_REGNUM;
10708 : : }
10709 : : return DX_REG;
10710 : : }
10711 : : }
10712 : : else
10713 : : {
10714 : : /* FIXME: We could make this work by pushing a register
10715 : : around the addition and comparison. */
10716 : 0 : sorry ("%<-fsplit-stack%> does not support 3 register parameters");
10717 : 0 : return INVALID_REGNUM;
10718 : : }
10719 : : }
10720 : : }
10721 : :
10722 : : /* A SYMBOL_REF for the function which allocates new stackspace for
10723 : : -fsplit-stack. */
10724 : :
10725 : : static GTY(()) rtx split_stack_fn;
10726 : :
10727 : : /* A SYMBOL_REF for the more stack function when using the large
10728 : : model. */
10729 : :
10730 : : static GTY(()) rtx split_stack_fn_large;
10731 : :
10732 : : /* Return location of the stack guard value in the TLS block. */
10733 : :
10734 : : rtx
10735 : 259815 : ix86_split_stack_guard (void)
10736 : : {
10737 : 259815 : int offset;
10738 : 259815 : addr_space_t as = DEFAULT_TLS_SEG_REG;
10739 : 259815 : rtx r;
10740 : :
10741 : 259815 : gcc_assert (flag_split_stack);
10742 : :
10743 : : #ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
10744 : 259815 : offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
10745 : : #else
10746 : : gcc_unreachable ();
10747 : : #endif
10748 : :
10749 : 259815 : r = GEN_INT (offset);
10750 : 357723 : r = gen_const_mem (Pmode, r);
10751 : 259815 : set_mem_addr_space (r, as);
10752 : :
10753 : 259815 : return r;
10754 : : }
10755 : :
10756 : : /* Handle -fsplit-stack. These are the first instructions in the
10757 : : function, even before the regular prologue. */
10758 : :
10759 : : void
10760 : 259805 : ix86_expand_split_stack_prologue (void)
10761 : : {
10762 : 259805 : HOST_WIDE_INT allocate;
10763 : 259805 : unsigned HOST_WIDE_INT args_size;
10764 : 259805 : rtx_code_label *label;
10765 : 259805 : rtx limit, current, allocate_rtx, call_fusage;
10766 : 259805 : rtx_insn *call_insn;
10767 : 259805 : unsigned int scratch_regno = INVALID_REGNUM;
10768 : 259805 : rtx scratch_reg = NULL_RTX;
10769 : 259805 : rtx_code_label *varargs_label = NULL;
10770 : 259805 : rtx fn;
10771 : :
10772 : 259805 : gcc_assert (flag_split_stack && reload_completed);
10773 : :
10774 : 259805 : ix86_finalize_stack_frame_flags ();
10775 : 259805 : struct ix86_frame &frame = cfun->machine->frame;
10776 : 259805 : allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
10777 : :
10778 : : /* This is the label we will branch to if we have enough stack
10779 : : space. We expect the basic block reordering pass to reverse this
10780 : : branch if optimizing, so that we branch in the unlikely case. */
10781 : 259805 : label = gen_label_rtx ();
10782 : :
10783 : : /* We need to compare the stack pointer minus the frame size with
10784 : : the stack boundary in the TCB. The stack boundary always gives
10785 : : us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
10786 : : can compare directly. Otherwise we need to do an addition. */
10787 : :
10788 : 259805 : limit = ix86_split_stack_guard ();
10789 : :
10790 : 259805 : if (allocate >= SPLIT_STACK_AVAILABLE
10791 : 234820 : || flag_force_indirect_call)
10792 : : {
10793 : 25000 : scratch_regno = split_stack_prologue_scratch_regno ();
10794 : 25000 : if (scratch_regno == INVALID_REGNUM)
10795 : 0 : return;
10796 : : }
10797 : :
10798 : 259805 : if (allocate >= SPLIT_STACK_AVAILABLE)
10799 : : {
10800 : 24985 : rtx offset;
10801 : :
10802 : : /* We need a scratch register to hold the stack pointer minus
10803 : : the required frame size. Since this is the very start of the
10804 : : function, the scratch register can be any caller-saved
10805 : : register which is not used for parameters. */
10806 : 24985 : offset = GEN_INT (- allocate);
10807 : :
10808 : 32051 : scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
10809 : 24985 : if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
10810 : : {
10811 : : /* We don't use gen_add in this case because it will
10812 : : want to split to lea, but when not optimizing the insn
10813 : : will not be split after this point. */
10814 : 32051 : emit_insn (gen_rtx_SET (scratch_reg,
10815 : : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
10816 : : offset)));
10817 : : }
10818 : : else
10819 : : {
10820 : 0 : emit_move_insn (scratch_reg, offset);
10821 : 0 : emit_insn (gen_add2_insn (scratch_reg, stack_pointer_rtx));
10822 : : }
10823 : : current = scratch_reg;
10824 : : }
10825 : : else
10826 : 234820 : current = stack_pointer_rtx;
10827 : :
10828 : 259805 : ix86_expand_branch (GEU, current, limit, label);
10829 : 259805 : rtx_insn *jump_insn = get_last_insn ();
10830 : 259805 : JUMP_LABEL (jump_insn) = label;
10831 : :
10832 : : /* Mark the jump as very likely to be taken. */
10833 : 259805 : add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
10834 : :
10835 : 259805 : if (split_stack_fn == NULL_RTX)
10836 : : {
10837 : 5451 : split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
10838 : 4347 : SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
10839 : : }
10840 : 259805 : fn = split_stack_fn;
10841 : :
10842 : : /* Get more stack space. We pass in the desired stack space and the
10843 : : size of the arguments to copy to the new stack. In 32-bit mode
10844 : : we push the parameters; __morestack will return on a new stack
10845 : : anyhow. In 64-bit mode we pass the parameters in r10 and
10846 : : r11. */
10847 : 259805 : allocate_rtx = GEN_INT (allocate);
10848 : 259805 : args_size = crtl->args.size >= 0 ? (HOST_WIDE_INT) crtl->args.size : 0;
10849 : 259805 : call_fusage = NULL_RTX;
10850 : 259805 : rtx pop = NULL_RTX;
10851 : 259805 : if (TARGET_64BIT)
10852 : : {
10853 : 161897 : rtx reg10, reg11;
10854 : :
10855 : 161897 : reg10 = gen_rtx_REG (DImode, R10_REG);
10856 : 161897 : reg11 = gen_rtx_REG (DImode, R11_REG);
10857 : :
10858 : : /* If this function uses a static chain, it will be in %r10.
10859 : : Preserve it across the call to __morestack. */
10860 : 161897 : if (DECL_STATIC_CHAIN (cfun->decl))
10861 : : {
10862 : 7505 : rtx rax;
10863 : :
10864 : 7505 : rax = gen_rtx_REG (word_mode, AX_REG);
10865 : 7505 : emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
10866 : 7505 : use_reg (&call_fusage, rax);
10867 : : }
10868 : :
10869 : 161897 : if (flag_force_indirect_call
10870 : 161882 : || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
10871 : : {
10872 : 16 : HOST_WIDE_INT argval;
10873 : :
10874 : 16 : if (split_stack_fn_large == NULL_RTX)
10875 : : {
10876 : 7 : split_stack_fn_large
10877 : 7 : = gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
10878 : 7 : SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
10879 : : }
10880 : :
10881 : 16 : fn = split_stack_fn_large;
10882 : :
10883 : 16 : if (ix86_cmodel == CM_LARGE_PIC)
10884 : : {
10885 : 3 : rtx_code_label *label;
10886 : 3 : rtx x;
10887 : :
10888 : 3 : gcc_assert (Pmode == DImode);
10889 : :
10890 : 3 : label = gen_label_rtx ();
10891 : 3 : emit_label (label);
10892 : 3 : LABEL_PRESERVE_P (label) = 1;
10893 : 3 : emit_insn (gen_set_rip_rex64 (reg10, label));
10894 : 3 : emit_insn (gen_set_got_offset_rex64 (reg11, label));
10895 : 3 : emit_insn (gen_add2_insn (reg10, reg11));
10896 : 3 : x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
10897 : 3 : x = gen_rtx_CONST (Pmode, x);
10898 : 3 : emit_move_insn (reg11, x);
10899 : 3 : x = gen_rtx_PLUS (Pmode, reg10, reg11);
10900 : 3 : x = gen_const_mem (Pmode, x);
10901 : 3 : fn = copy_to_suggested_reg (x, reg11, Pmode);
10902 : : }
10903 : 13 : else if (ix86_cmodel == CM_LARGE)
10904 : 1 : fn = copy_to_suggested_reg (fn, reg11, Pmode);
10905 : :
10906 : : /* When using the large model we need to load the address
10907 : : into a register, and we've run out of registers. So we
10908 : : switch to a different calling convention, and we call a
10909 : : different function: __morestack_large. We pass the
10910 : : argument size in the upper 32 bits of r10 and pass the
10911 : : frame size in the lower 32 bits. */
10912 : 16 : gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
10913 : 16 : gcc_assert ((args_size & 0xffffffff) == args_size);
10914 : :
10915 : 16 : argval = ((args_size << 16) << 16) + allocate;
10916 : 16 : emit_move_insn (reg10, GEN_INT (argval));
10917 : 16 : }
10918 : : else
10919 : : {
10920 : 161881 : emit_move_insn (reg10, allocate_rtx);
10921 : 161881 : emit_move_insn (reg11, GEN_INT (args_size));
10922 : 161881 : use_reg (&call_fusage, reg11);
10923 : : }
10924 : :
10925 : 161897 : use_reg (&call_fusage, reg10);
10926 : : }
10927 : : else
10928 : : {
10929 : 97908 : if (flag_force_indirect_call && flag_pic)
10930 : : {
10931 : 0 : rtx x;
10932 : :
10933 : 0 : gcc_assert (Pmode == SImode);
10934 : :
10935 : 0 : scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
10936 : :
10937 : 0 : emit_insn (gen_set_got (scratch_reg));
10938 : 0 : x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
10939 : : UNSPEC_GOT);
10940 : 0 : x = gen_rtx_CONST (Pmode, x);
10941 : 0 : x = gen_rtx_PLUS (Pmode, scratch_reg, x);
10942 : 0 : x = gen_const_mem (Pmode, x);
10943 : 0 : fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
10944 : : }
10945 : :
10946 : 97908 : rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
10947 : 195816 : add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
10948 : 97908 : insn = emit_insn (gen_push (allocate_rtx));
10949 : 195816 : add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
10950 : 195816 : pop = GEN_INT (2 * UNITS_PER_WORD);
10951 : : }
10952 : :
10953 : 259805 : if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
10954 : : {
10955 : 12 : scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
10956 : :
10957 : 12 : if (GET_MODE (fn) != word_mode)
10958 : 0 : fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
10959 : :
10960 : 12 : fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
10961 : : }
10962 : :
10963 : 259805 : call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
10964 : 259805 : GEN_INT (UNITS_PER_WORD), constm1_rtx,
10965 : : pop, false);
10966 : 259805 : add_function_usage_to (call_insn, call_fusage);
10967 : 259805 : if (!TARGET_64BIT)
10968 : 97908 : add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (0));
10969 : : /* Indicate that this function can't jump to non-local gotos. */
10970 : 259805 : make_reg_eh_region_note_nothrow_nononlocal (call_insn);
10971 : :
10972 : : /* In order to make call/return prediction work right, we now need
10973 : : to execute a return instruction. See
10974 : : libgcc/config/i386/morestack.S for the details on how this works.
10975 : :
10976 : : For flow purposes gcc must not see this as a return
10977 : : instruction--we need control flow to continue at the subsequent
10978 : : label. Therefore, we use an unspec. */
10979 : 259805 : gcc_assert (crtl->args.pops_args < 65536);
10980 : 259805 : rtx_insn *ret_insn
10981 : 259805 : = emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
10982 : :
10983 : 259805 : if ((flag_cf_protection & CF_BRANCH))
10984 : : {
10985 : : /* Insert ENDBR since __morestack will jump back here via indirect
10986 : : call. */
10987 : 21 : rtx cet_eb = gen_nop_endbr ();
10988 : 21 : emit_insn_after (cet_eb, ret_insn);
10989 : : }
10990 : :
10991 : : /* If we are in 64-bit mode and this function uses a static chain,
10992 : : we saved %r10 in %rax before calling _morestack. */
10993 : 259805 : if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
10994 : 7505 : emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
10995 : : gen_rtx_REG (word_mode, AX_REG));
10996 : :
10997 : : /* If this function calls va_start, we need to store a pointer to
10998 : : the arguments on the old stack, because they may not have been
10999 : : all copied to the new stack. At this point the old stack can be
11000 : : found at the frame pointer value used by __morestack, because
11001 : : __morestack has set that up before calling back to us. Here we
11002 : : store that pointer in a scratch register, and in
11003 : : ix86_expand_prologue we store the scratch register in a stack
11004 : : slot. */
11005 : 259805 : if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11006 : : {
11007 : 12 : rtx frame_reg;
11008 : 12 : int words;
11009 : :
11010 : 12 : scratch_regno = split_stack_prologue_scratch_regno ();
11011 : 16 : scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
11012 : 16 : frame_reg = gen_rtx_REG (Pmode, BP_REG);
11013 : :
11014 : : /* 64-bit:
11015 : : fp -> old fp value
11016 : : return address within this function
11017 : : return address of caller of this function
11018 : : stack arguments
11019 : : So we add three words to get to the stack arguments.
11020 : :
11021 : : 32-bit:
11022 : : fp -> old fp value
11023 : : return address within this function
11024 : : first argument to __morestack
11025 : : second argument to __morestack
11026 : : return address of caller of this function
11027 : : stack arguments
11028 : : So we add five words to get to the stack arguments.
11029 : : */
11030 : 12 : words = TARGET_64BIT ? 3 : 5;
11031 : 20 : emit_insn (gen_rtx_SET (scratch_reg,
11032 : : plus_constant (Pmode, frame_reg,
11033 : : words * UNITS_PER_WORD)));
11034 : :
11035 : 12 : varargs_label = gen_label_rtx ();
11036 : 12 : emit_jump_insn (gen_jump (varargs_label));
11037 : 12 : JUMP_LABEL (get_last_insn ()) = varargs_label;
11038 : :
11039 : 12 : emit_barrier ();
11040 : : }
11041 : :
11042 : 259805 : emit_label (label);
11043 : 259805 : LABEL_NUSES (label) = 1;
11044 : :
11045 : : /* If this function calls va_start, we now have to set the scratch
11046 : : register for the case where we do not call __morestack. In this
11047 : : case we need to set it based on the stack pointer. */
11048 : 259805 : if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11049 : : {
11050 : 20 : emit_insn (gen_rtx_SET (scratch_reg,
11051 : : plus_constant (Pmode, stack_pointer_rtx,
11052 : : UNITS_PER_WORD)));
11053 : :
11054 : 12 : emit_label (varargs_label);
11055 : 12 : LABEL_NUSES (varargs_label) = 1;
11056 : : }
11057 : : }
11058 : :
11059 : : /* We may have to tell the dataflow pass that the split stack prologue
11060 : : is initializing a scratch register. */
11061 : :
11062 : : static void
11063 : 15541403 : ix86_live_on_entry (bitmap regs)
11064 : : {
11065 : 15541403 : if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
11066 : : {
11067 : 124 : gcc_assert (flag_split_stack);
11068 : 124 : bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
11069 : : }
11070 : 15541403 : }
11071 : :
11072 : : /* Extract the parts of an RTL expression that is a valid memory address
11073 : : for an instruction. Return false if the structure of the address is
11074 : : grossly off. */
11075 : :
11076 : : bool
11077 : 4294222091 : ix86_decompose_address (rtx addr, struct ix86_address *out)
11078 : : {
11079 : 4294222091 : rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
11080 : 4294222091 : rtx base_reg, index_reg;
11081 : 4294222091 : HOST_WIDE_INT scale = 1;
11082 : 4294222091 : rtx scale_rtx = NULL_RTX;
11083 : 4294222091 : rtx tmp;
11084 : 4294222091 : addr_space_t seg = ADDR_SPACE_GENERIC;
11085 : :
11086 : : /* Allow zero-extended SImode addresses,
11087 : : they will be emitted with addr32 prefix. */
11088 : 4294222091 : if (TARGET_64BIT && GET_MODE (addr) == DImode)
11089 : : {
11090 : 2245358878 : if (GET_CODE (addr) == ZERO_EXTEND
11091 : 2383104 : && GET_MODE (XEXP (addr, 0)) == SImode)
11092 : : {
11093 : 2279692 : addr = XEXP (addr, 0);
11094 : 2279692 : if (CONST_INT_P (addr))
11095 : : return false;
11096 : : }
11097 : 2243079186 : else if (GET_CODE (addr) == AND)
11098 : : {
11099 : 2637651 : rtx mask = XEXP (addr, 1);
11100 : 2637651 : rtx shift_val;
11101 : :
11102 : 2637651 : if (const_32bit_mask (mask, DImode)
11103 : : /* For ASHIFT inside AND, combine will not generate
11104 : : canonical zero-extend. Merge mask for AND and shift_count
11105 : : to check if it is canonical zero-extend. */
11106 : 2637651 : || (CONST_INT_P (mask)
11107 : 1745529 : && GET_CODE (XEXP (addr, 0)) == ASHIFT
11108 : 159179 : && CONST_INT_P (shift_val = XEXP (XEXP (addr, 0), 1))
11109 : 153581 : && ((UINTVAL (mask)
11110 : 153581 : | ((HOST_WIDE_INT_1U << INTVAL (shift_val)) - 1))
11111 : : == HOST_WIDE_INT_UC (0xffffffff))))
11112 : : {
11113 : 91685 : addr = lowpart_subreg (SImode, XEXP (addr, 0), DImode);
11114 : 91685 : if (addr == NULL_RTX)
11115 : : return false;
11116 : :
11117 : 91685 : if (CONST_INT_P (addr))
11118 : : return false;
11119 : : }
11120 : : }
11121 : : }
11122 : :
11123 : : /* Allow SImode subregs of DImode addresses,
11124 : : they will be emitted with addr32 prefix. */
11125 : 4294222091 : if (TARGET_64BIT && GET_MODE (addr) == SImode)
11126 : : {
11127 : 18096206 : if (SUBREG_P (addr)
11128 : 235437 : && GET_MODE (SUBREG_REG (addr)) == DImode)
11129 : : {
11130 : 213519 : addr = SUBREG_REG (addr);
11131 : 213519 : if (CONST_INT_P (addr))
11132 : : return false;
11133 : : }
11134 : : }
11135 : :
11136 : 4294222091 : if (REG_P (addr))
11137 : : base = addr;
11138 : : else if (SUBREG_P (addr))
11139 : : {
11140 : 481962 : if (REG_P (SUBREG_REG (addr)))
11141 : : base = addr;
11142 : : else
11143 : : return false;
11144 : : }
11145 : : else if (GET_CODE (addr) == PLUS)
11146 : : {
11147 : : rtx addends[4], op;
11148 : : int n = 0, i;
11149 : :
11150 : : op = addr;
11151 : 3151922684 : do
11152 : : {
11153 : 3151922684 : if (n >= 4)
11154 : 644118305 : return false;
11155 : 3151918748 : addends[n++] = XEXP (op, 1);
11156 : 3151918748 : op = XEXP (op, 0);
11157 : : }
11158 : 3151918748 : while (GET_CODE (op) == PLUS);
11159 : 3092592785 : if (n >= 4)
11160 : : return false;
11161 : 3092586648 : addends[n] = op;
11162 : :
11163 : 8051747166 : for (i = n; i >= 0; --i)
11164 : : {
11165 : 5603268750 : op = addends[i];
11166 : 5603268750 : switch (GET_CODE (op))
11167 : : {
11168 : 60015467 : case MULT:
11169 : 60015467 : if (index)
11170 : : return false;
11171 : 59976012 : index = XEXP (op, 0);
11172 : 59976012 : scale_rtx = XEXP (op, 1);
11173 : 59976012 : break;
11174 : :
11175 : 12624601 : case ASHIFT:
11176 : 12624601 : if (index)
11177 : : return false;
11178 : 12554495 : index = XEXP (op, 0);
11179 : 12554495 : tmp = XEXP (op, 1);
11180 : 12554495 : if (!CONST_INT_P (tmp))
11181 : : return false;
11182 : 12540070 : scale = INTVAL (tmp);
11183 : 12540070 : if ((unsigned HOST_WIDE_INT) scale > 3)
11184 : : return false;
11185 : 12130241 : scale = 1 << scale;
11186 : 12130241 : break;
11187 : :
11188 : 1003582 : case ZERO_EXTEND:
11189 : 1003582 : op = XEXP (op, 0);
11190 : 1003582 : if (GET_CODE (op) != UNSPEC)
11191 : : return false;
11192 : : /* FALLTHRU */
11193 : :
11194 : 623622 : case UNSPEC:
11195 : 623622 : if (XINT (op, 1) == UNSPEC_TP
11196 : 616291 : && TARGET_TLS_DIRECT_SEG_REFS
11197 : 616291 : && seg == ADDR_SPACE_GENERIC)
11198 : 616291 : seg = DEFAULT_TLS_SEG_REG;
11199 : : else
11200 : : return false;
11201 : : break;
11202 : :
11203 : 516385 : case SUBREG:
11204 : 516385 : if (!REG_P (SUBREG_REG (op)))
11205 : : return false;
11206 : : /* FALLTHRU */
11207 : :
11208 : 2515164119 : case REG:
11209 : 2515164119 : if (!base)
11210 : : base = op;
11211 : 78446603 : else if (!index)
11212 : : index = op;
11213 : : else
11214 : : return false;
11215 : : break;
11216 : :
11217 : 2372050296 : case CONST:
11218 : 2372050296 : case CONST_INT:
11219 : 2372050296 : case SYMBOL_REF:
11220 : 2372050296 : case LABEL_REF:
11221 : 2372050296 : if (disp)
11222 : : return false;
11223 : : disp = op;
11224 : : break;
11225 : :
11226 : : default:
11227 : : return false;
11228 : : }
11229 : : }
11230 : : }
11231 : : else if (GET_CODE (addr) == MULT)
11232 : : {
11233 : 3432520 : index = XEXP (addr, 0); /* index*scale */
11234 : 3432520 : scale_rtx = XEXP (addr, 1);
11235 : : }
11236 : : else if (GET_CODE (addr) == ASHIFT)
11237 : : {
11238 : : /* We're called for lea too, which implements ashift on occasion. */
11239 : 3290948 : index = XEXP (addr, 0);
11240 : 3290948 : tmp = XEXP (addr, 1);
11241 : 3290948 : if (!CONST_INT_P (tmp))
11242 : : return false;
11243 : 2897985 : scale = INTVAL (tmp);
11244 : 2897985 : if ((unsigned HOST_WIDE_INT) scale > 3)
11245 : : return false;
11246 : 2136136 : scale = 1 << scale;
11247 : : }
11248 : : else
11249 : : disp = addr; /* displacement */
11250 : :
11251 : 2454047072 : if (index)
11252 : : {
11253 : 146671720 : if (REG_P (index))
11254 : : ;
11255 : 3768339 : else if (SUBREG_P (index)
11256 : 269699 : && REG_P (SUBREG_REG (index)))
11257 : : ;
11258 : : else
11259 : : return false;
11260 : : }
11261 : :
11262 : : /* Extract the integral value of scale. */
11263 : 3645388949 : if (scale_rtx)
11264 : : {
11265 : 55380417 : if (!CONST_INT_P (scale_rtx))
11266 : : return false;
11267 : 54817395 : scale = INTVAL (scale_rtx);
11268 : : }
11269 : :
11270 : 3644825927 : base_reg = base && SUBREG_P (base) ? SUBREG_REG (base) : base;
11271 : 3644825927 : index_reg = index && SUBREG_P (index) ? SUBREG_REG (index) : index;
11272 : :
11273 : : /* Avoid useless 0 displacement. */
11274 : 3644825927 : if (disp == const0_rtx && (base || index))
11275 : 3644825927 : disp = NULL_RTX;
11276 : :
11277 : : /* Allow arg pointer and stack pointer as index if there is not scaling. */
11278 : 2668824328 : if (base_reg && index_reg && scale == 1
11279 : 3721848473 : && (REGNO (index_reg) == ARG_POINTER_REGNUM
11280 : : || REGNO (index_reg) == FRAME_POINTER_REGNUM
11281 : : || REGNO (index_reg) == SP_REG))
11282 : : {
11283 : : std::swap (base, index);
11284 : : std::swap (base_reg, index_reg);
11285 : : }
11286 : :
11287 : : /* Special case: %ebp cannot be encoded as a base without a displacement.
11288 : : Similarly %r13. */
11289 : 314744228 : if (!disp && base_reg
11290 : 3955497884 : && (REGNO (base_reg) == ARG_POINTER_REGNUM
11291 : : || REGNO (base_reg) == FRAME_POINTER_REGNUM
11292 : : || REGNO (base_reg) == BP_REG
11293 : : || REGNO (base_reg) == R13_REG))
11294 : : disp = const0_rtx;
11295 : :
11296 : : /* Special case: on K6, [%esi] makes the instruction vector decoded.
11297 : : Avoid this by transforming to [%esi+0].
11298 : : Reload calls address legitimization without cfun defined, so we need
11299 : : to test cfun for being non-NULL. */
11300 : 0 : if (TARGET_CPU_P (K6) && cfun && optimize_function_for_speed_p (cfun)
11301 : 0 : && base_reg && !index_reg && !disp
11302 : 3644825927 : && REGNO (base_reg) == SI_REG)
11303 : 0 : disp = const0_rtx;
11304 : :
11305 : : /* Special case: encode reg+reg instead of reg*2. */
11306 : 3644825927 : if (!base && index && scale == 2)
11307 : 976001599 : base = index, base_reg = index_reg, scale = 1;
11308 : :
11309 : : /* Special case: scaling cannot be encoded without base or displacement. */
11310 : 976001599 : if (!base && !disp && index && scale != 1)
11311 : 3175992 : disp = const0_rtx;
11312 : :
11313 : 3644825927 : out->base = base;
11314 : 3644825927 : out->index = index;
11315 : 3644825927 : out->disp = disp;
11316 : 3644825927 : out->scale = scale;
11317 : 3644825927 : out->seg = seg;
11318 : :
11319 : 3644825927 : return true;
11320 : : }
11321 : :
11322 : : /* Return cost of the memory address x.
11323 : : For i386, it is better to use a complex address than let gcc copy
11324 : : the address into a reg and make a new pseudo. But not if the address
11325 : : requires to two regs - that would mean more pseudos with longer
11326 : : lifetimes. */
11327 : : static int
11328 : 10349002 : ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
11329 : : {
11330 : 10349002 : struct ix86_address parts;
11331 : 10349002 : int cost = 1;
11332 : 10349002 : int ok = ix86_decompose_address (x, &parts);
11333 : :
11334 : 10349002 : gcc_assert (ok);
11335 : :
11336 : 10349002 : if (parts.base && SUBREG_P (parts.base))
11337 : 483 : parts.base = SUBREG_REG (parts.base);
11338 : 10349002 : if (parts.index && SUBREG_P (parts.index))
11339 : 20 : parts.index = SUBREG_REG (parts.index);
11340 : :
11341 : : /* Attempt to minimize number of registers in the address by increasing
11342 : : address cost for each used register. We don't increase address cost
11343 : : for "pic_offset_table_rtx". When a memopt with "pic_offset_table_rtx"
11344 : : is not invariant itself it most likely means that base or index is not
11345 : : invariant. Therefore only "pic_offset_table_rtx" could be hoisted out,
11346 : : which is not profitable for x86. */
11347 : 10349002 : if (parts.base
11348 : 9017872 : && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
11349 : 19093924 : && (current_pass->type == GIMPLE_PASS
11350 : 2494393 : || !pic_offset_table_rtx
11351 : 132297 : || !REG_P (parts.base)
11352 : 132297 : || REGNO (pic_offset_table_rtx) != REGNO (parts.base)))
11353 : : cost++;
11354 : :
11355 : 10349002 : if (parts.index
11356 : 5114570 : && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
11357 : 15450081 : && (current_pass->type == GIMPLE_PASS
11358 : 606736 : || !pic_offset_table_rtx
11359 : 57246 : || !REG_P (parts.index)
11360 : 57246 : || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
11361 : 5099872 : cost++;
11362 : :
11363 : : /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
11364 : : since it's predecode logic can't detect the length of instructions
11365 : : and it degenerates to vector decoded. Increase cost of such
11366 : : addresses here. The penalty is minimally 2 cycles. It may be worthwhile
11367 : : to split such addresses or even refuse such addresses at all.
11368 : :
11369 : : Following addressing modes are affected:
11370 : : [base+scale*index]
11371 : : [scale*index+disp]
11372 : : [base+index]
11373 : :
11374 : : The first and last case may be avoidable by explicitly coding the zero in
11375 : : memory address, but I don't have AMD-K6 machine handy to check this
11376 : : theory. */
11377 : :
11378 : 10349002 : if (TARGET_CPU_P (K6)
11379 : 0 : && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
11380 : 0 : || (parts.disp && !parts.base && parts.index && parts.scale != 1)
11381 : 0 : || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
11382 : 0 : cost += 10;
11383 : :
11384 : 10349002 : return cost;
11385 : : }
11386 : :
11387 : : /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
11388 : : this is used for to form addresses to local data when -fPIC is in
11389 : : use. */
11390 : :
11391 : : static bool
11392 : 0 : darwin_local_data_pic (rtx disp)
11393 : : {
11394 : 0 : return (GET_CODE (disp) == UNSPEC
11395 : 0 : && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
11396 : : }
11397 : :
11398 : : /* True if the function symbol operand X should be loaded from GOT.
11399 : : If CALL_P is true, X is a call operand.
11400 : :
11401 : : NB: -mno-direct-extern-access doesn't force load from GOT for
11402 : : call.
11403 : :
11404 : : NB: In 32-bit mode, only non-PIC is allowed in inline assembly
11405 : : statements, since a PIC register could not be available at the
11406 : : call site. */
11407 : :
11408 : : bool
11409 : 1809145239 : ix86_force_load_from_GOT_p (rtx x, bool call_p)
11410 : : {
11411 : 94516906 : return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X))
11412 : : && !TARGET_PECOFF && !TARGET_MACHO
11413 : 1806334520 : && (!flag_pic || this_is_asm_operands)
11414 : 1786652460 : && ix86_cmodel != CM_LARGE
11415 : 1786646680 : && ix86_cmodel != CM_LARGE_PIC
11416 : 1786646679 : && GET_CODE (x) == SYMBOL_REF
11417 : 1786646677 : && ((!call_p
11418 : 1781248530 : && (!ix86_direct_extern_access
11419 : 1781247166 : || (SYMBOL_REF_DECL (x)
11420 : 1594706617 : && lookup_attribute ("nodirect_extern_access",
11421 : 1594706617 : DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))
11422 : 1786644868 : || (SYMBOL_REF_FUNCTION_P (x)
11423 : 670723410 : && (!flag_plt
11424 : 670719091 : || (SYMBOL_REF_DECL (x)
11425 : 670719091 : && lookup_attribute ("noplt",
11426 : 670719091 : DECL_ATTRIBUTES (SYMBOL_REF_DECL (x)))))))
11427 : 1809151758 : && !SYMBOL_REF_LOCAL_P (x));
11428 : : }
11429 : :
11430 : : /* Determine if a given RTX is a valid constant. We already know this
11431 : : satisfies CONSTANT_P. */
11432 : :
11433 : : static bool
11434 : 1535950696 : ix86_legitimate_constant_p (machine_mode mode, rtx x)
11435 : : {
11436 : 1535950696 : switch (GET_CODE (x))
11437 : : {
11438 : 132961880 : case CONST:
11439 : 132961880 : x = XEXP (x, 0);
11440 : :
11441 : 132961880 : if (GET_CODE (x) == PLUS)
11442 : : {
11443 : 132848092 : if (!CONST_INT_P (XEXP (x, 1)))
11444 : : return false;
11445 : 132848092 : x = XEXP (x, 0);
11446 : : }
11447 : :
11448 : 132961880 : if (TARGET_MACHO && darwin_local_data_pic (x))
11449 : : return true;
11450 : :
11451 : : /* Only some unspecs are valid as "constants". */
11452 : 132961880 : if (GET_CODE (x) == UNSPEC)
11453 : 476502 : switch (XINT (x, 1))
11454 : : {
11455 : 20680 : case UNSPEC_GOT:
11456 : 20680 : case UNSPEC_GOTOFF:
11457 : 20680 : case UNSPEC_PLTOFF:
11458 : 20680 : return TARGET_64BIT;
11459 : 454982 : case UNSPEC_TPOFF:
11460 : 454982 : case UNSPEC_NTPOFF:
11461 : 454982 : x = XVECEXP (x, 0, 0);
11462 : 454982 : return (GET_CODE (x) == SYMBOL_REF
11463 : 454982 : && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
11464 : 754 : case UNSPEC_DTPOFF:
11465 : 754 : x = XVECEXP (x, 0, 0);
11466 : 754 : return (GET_CODE (x) == SYMBOL_REF
11467 : 754 : && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
11468 : 0 : case UNSPEC_SECREL32:
11469 : 0 : x = XVECEXP (x, 0, 0);
11470 : 0 : return GET_CODE (x) == SYMBOL_REF;
11471 : : default:
11472 : : return false;
11473 : : }
11474 : :
11475 : : /* We must have drilled down to a symbol. */
11476 : 132485378 : if (GET_CODE (x) == LABEL_REF)
11477 : : return true;
11478 : 132481392 : if (GET_CODE (x) != SYMBOL_REF)
11479 : : return false;
11480 : : /* FALLTHRU */
11481 : :
11482 : 906380440 : case SYMBOL_REF:
11483 : : /* TLS symbols are never valid. */
11484 : 906380440 : if (SYMBOL_REF_TLS_MODEL (x))
11485 : : return false;
11486 : :
11487 : : /* DLLIMPORT symbols are never valid. */
11488 : 906285453 : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
11489 : : && SYMBOL_REF_DLLIMPORT_P (x))
11490 : : return false;
11491 : :
11492 : : #if TARGET_MACHO
11493 : : /* mdynamic-no-pic */
11494 : : if (MACHO_DYNAMIC_NO_PIC_P)
11495 : : return machopic_symbol_defined_p (x);
11496 : : #endif
11497 : :
11498 : : /* External function address should be loaded
11499 : : via the GOT slot to avoid PLT. */
11500 : 906285453 : if (ix86_force_load_from_GOT_p (x))
11501 : : return false;
11502 : :
11503 : : break;
11504 : :
11505 : 608631562 : CASE_CONST_SCALAR_INT:
11506 : 608631562 : if (ix86_endbr_immediate_operand (x, VOIDmode))
11507 : : return false;
11508 : :
11509 : 608631361 : switch (mode)
11510 : : {
11511 : 1570294 : case E_TImode:
11512 : 1570294 : if (TARGET_64BIT)
11513 : : return true;
11514 : : /* FALLTHRU */
11515 : 21509 : case E_OImode:
11516 : 21509 : case E_XImode:
11517 : 21509 : if (!standard_sse_constant_p (x, mode)
11518 : 34591 : && GET_MODE_SIZE (TARGET_AVX512F
11519 : : ? XImode
11520 : : : (TARGET_AVX
11521 : : ? OImode
11522 : : : (TARGET_SSE2
11523 : 13082 : ? TImode : DImode))) < GET_MODE_SIZE (mode))
11524 : : return false;
11525 : : default:
11526 : : break;
11527 : : }
11528 : : break;
11529 : :
11530 : 8253517 : case CONST_VECTOR:
11531 : 8253517 : if (!standard_sse_constant_p (x, mode))
11532 : : return false;
11533 : : break;
11534 : :
11535 : 7660824 : case CONST_DOUBLE:
11536 : 7660824 : if (mode == E_BFmode)
11537 : : return false;
11538 : :
11539 : : default:
11540 : : break;
11541 : : }
11542 : :
11543 : : /* Otherwise we handle everything else in the move patterns. */
11544 : : return true;
11545 : : }
11546 : :
11547 : : /* Determine if it's legal to put X into the constant pool. This
11548 : : is not possible for the address of thread-local symbols, which
11549 : : is checked above. */
11550 : :
11551 : : static bool
11552 : 61539037 : ix86_cannot_force_const_mem (machine_mode mode, rtx x)
11553 : : {
11554 : : /* We can put any immediate constant in memory. */
11555 : 61539037 : switch (GET_CODE (x))
11556 : : {
11557 : : CASE_CONST_ANY:
11558 : : return false;
11559 : :
11560 : 1759284 : default:
11561 : 1759284 : break;
11562 : : }
11563 : :
11564 : 1759284 : return !ix86_legitimate_constant_p (mode, x);
11565 : : }
11566 : :
11567 : : /* Return a unique alias set for the GOT. */
11568 : :
11569 : : alias_set_type
11570 : 184245 : ix86_GOT_alias_set (void)
11571 : : {
11572 : 184245 : static alias_set_type set = -1;
11573 : 184245 : if (set == -1)
11574 : 2883 : set = new_alias_set ();
11575 : 184245 : return set;
11576 : : }
11577 : :
11578 : : /* Nonzero if the constant value X is a legitimate general operand
11579 : : when generating PIC code. It is given that flag_pic is on and
11580 : : that X satisfies CONSTANT_P. */
11581 : :
11582 : : bool
11583 : 123198464 : legitimate_pic_operand_p (rtx x)
11584 : : {
11585 : 123198464 : rtx inner;
11586 : :
11587 : 123198464 : switch (GET_CODE (x))
11588 : : {
11589 : 2455996 : case CONST:
11590 : 2455996 : inner = XEXP (x, 0);
11591 : 2455996 : if (GET_CODE (inner) == PLUS
11592 : 350628 : && CONST_INT_P (XEXP (inner, 1)))
11593 : 350628 : inner = XEXP (inner, 0);
11594 : :
11595 : : /* Only some unspecs are valid as "constants". */
11596 : 2455996 : if (GET_CODE (inner) == UNSPEC)
11597 : 2211608 : switch (XINT (inner, 1))
11598 : : {
11599 : 2151117 : case UNSPEC_GOT:
11600 : 2151117 : case UNSPEC_GOTOFF:
11601 : 2151117 : case UNSPEC_PLTOFF:
11602 : 2151117 : return TARGET_64BIT;
11603 : 0 : case UNSPEC_TPOFF:
11604 : 0 : x = XVECEXP (inner, 0, 0);
11605 : 0 : return (GET_CODE (x) == SYMBOL_REF
11606 : 0 : && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
11607 : 0 : case UNSPEC_SECREL32:
11608 : 0 : x = XVECEXP (inner, 0, 0);
11609 : 0 : return GET_CODE (x) == SYMBOL_REF;
11610 : 0 : case UNSPEC_MACHOPIC_OFFSET:
11611 : 0 : return legitimate_pic_address_disp_p (x);
11612 : : default:
11613 : : return false;
11614 : : }
11615 : : /* FALLTHRU */
11616 : :
11617 : 6722931 : case SYMBOL_REF:
11618 : 6722931 : case LABEL_REF:
11619 : 6722931 : return legitimate_pic_address_disp_p (x);
11620 : :
11621 : : default:
11622 : : return true;
11623 : : }
11624 : : }
11625 : :
11626 : : /* Determine if a given CONST RTX is a valid memory displacement
11627 : : in PIC mode. */
11628 : :
11629 : : bool
11630 : 62274447 : legitimate_pic_address_disp_p (rtx disp)
11631 : : {
11632 : 62274447 : bool saw_plus;
11633 : :
11634 : : /* In 64bit mode we can allow direct addresses of symbols and labels
11635 : : when they are not dynamic symbols. */
11636 : 62274447 : if (TARGET_64BIT)
11637 : : {
11638 : 38128620 : rtx op0 = disp, op1;
11639 : :
11640 : 38128620 : switch (GET_CODE (disp))
11641 : : {
11642 : : case LABEL_REF:
11643 : : return true;
11644 : :
11645 : 10543825 : case CONST:
11646 : 10543825 : if (GET_CODE (XEXP (disp, 0)) != PLUS)
11647 : : break;
11648 : 1141099 : op0 = XEXP (XEXP (disp, 0), 0);
11649 : 1141099 : op1 = XEXP (XEXP (disp, 0), 1);
11650 : 1141099 : if (!CONST_INT_P (op1))
11651 : : break;
11652 : 1141099 : if (GET_CODE (op0) == UNSPEC
11653 : 293 : && (XINT (op0, 1) == UNSPEC_DTPOFF
11654 : 293 : || XINT (op0, 1) == UNSPEC_NTPOFF)
11655 : 1141392 : && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
11656 : : return true;
11657 : 1140806 : if (INTVAL (op1) >= 16*1024*1024
11658 : 1140806 : || INTVAL (op1) < -16*1024*1024)
11659 : : break;
11660 : 1140718 : if (GET_CODE (op0) == LABEL_REF)
11661 : : return true;
11662 : 1140718 : if (GET_CODE (op0) == CONST
11663 : 0 : && GET_CODE (XEXP (op0, 0)) == UNSPEC
11664 : 0 : && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
11665 : : return true;
11666 : 1140718 : if (GET_CODE (op0) == UNSPEC
11667 : 0 : && XINT (op0, 1) == UNSPEC_PCREL)
11668 : : return true;
11669 : 1140718 : if (GET_CODE (op0) != SYMBOL_REF)
11670 : : break;
11671 : : /* FALLTHRU */
11672 : :
11673 : 28510606 : case SYMBOL_REF:
11674 : : /* TLS references should always be enclosed in UNSPEC.
11675 : : The dllimported symbol needs always to be resolved. */
11676 : 28510606 : if (SYMBOL_REF_TLS_MODEL (op0)
11677 : : || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
11678 : : return false;
11679 : :
11680 : 28360889 : if (TARGET_PECOFF)
11681 : : {
11682 : : #if TARGET_PECOFF
11683 : : if (is_imported_p (op0))
11684 : : return true;
11685 : : #endif
11686 : :
11687 : : if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
11688 : : break;
11689 : :
11690 : : /* Non-external-weak function symbols need to be resolved only
11691 : : for the large model. Non-external symbols don't need to be
11692 : : resolved for large and medium models. For the small model,
11693 : : we don't need to resolve anything here. */
11694 : : if ((ix86_cmodel != CM_LARGE_PIC
11695 : : && SYMBOL_REF_FUNCTION_P (op0)
11696 : : && !(SYMBOL_REF_EXTERNAL_P (op0) && SYMBOL_REF_WEAK (op0)))
11697 : : || !SYMBOL_REF_EXTERNAL_P (op0)
11698 : : || ix86_cmodel == CM_SMALL_PIC)
11699 : : return true;
11700 : : }
11701 : 28360889 : else if (!SYMBOL_REF_FAR_ADDR_P (op0)
11702 : 28360885 : && (SYMBOL_REF_LOCAL_P (op0)
11703 : 17170624 : || ((ix86_direct_extern_access
11704 : 34130018 : && !(SYMBOL_REF_DECL (op0)
11705 : 16959553 : && lookup_attribute ("nodirect_extern_access",
11706 : 16959553 : DECL_ATTRIBUTES (SYMBOL_REF_DECL (op0)))))
11707 : : && HAVE_LD_PIE_COPYRELOC
11708 : 17170306 : && flag_pie
11709 : 37248 : && !SYMBOL_REF_WEAK (op0)
11710 : 36860 : && !SYMBOL_REF_FUNCTION_P (op0)))
11711 : 39558892 : && ix86_cmodel != CM_LARGE_PIC)
11712 : : return true;
11713 : : break;
11714 : :
11715 : : default:
11716 : : break;
11717 : : }
11718 : : }
11719 : 50715225 : if (GET_CODE (disp) != CONST)
11720 : : return false;
11721 : 14507903 : disp = XEXP (disp, 0);
11722 : :
11723 : 14507903 : if (TARGET_64BIT)
11724 : : {
11725 : : /* We are unsafe to allow PLUS expressions. This limit allowed distance
11726 : : of GOT tables. We should not need these anyway. */
11727 : 9453274 : if (GET_CODE (disp) != UNSPEC
11728 : 9402726 : || (XINT (disp, 1) != UNSPEC_GOTPCREL
11729 : 9402726 : && XINT (disp, 1) != UNSPEC_GOTOFF
11730 : : && XINT (disp, 1) != UNSPEC_PCREL
11731 : : && XINT (disp, 1) != UNSPEC_PLTOFF))
11732 : : return false;
11733 : :
11734 : 9402726 : if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
11735 : 9402726 : && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
11736 : : return false;
11737 : : return true;
11738 : : }
11739 : :
11740 : 5054629 : saw_plus = false;
11741 : 5054629 : if (GET_CODE (disp) == PLUS)
11742 : : {
11743 : 579225 : if (!CONST_INT_P (XEXP (disp, 1)))
11744 : : return false;
11745 : 579225 : disp = XEXP (disp, 0);
11746 : 579225 : saw_plus = true;
11747 : : }
11748 : :
11749 : 5054629 : if (TARGET_MACHO && darwin_local_data_pic (disp))
11750 : : return true;
11751 : :
11752 : 5054629 : if (GET_CODE (disp) != UNSPEC)
11753 : : return false;
11754 : :
11755 : 4893871 : switch (XINT (disp, 1))
11756 : : {
11757 : 2222541 : case UNSPEC_GOT:
11758 : 2222541 : if (saw_plus)
11759 : : return false;
11760 : : /* We need to check for both symbols and labels because VxWorks loads
11761 : : text labels with @GOT rather than @GOTOFF. See gotoff_operand for
11762 : : details. */
11763 : 2222540 : return (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
11764 : 2222540 : || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF);
11765 : 2671330 : case UNSPEC_GOTOFF:
11766 : : /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
11767 : : While ABI specify also 32bit relocation but we don't produce it in
11768 : : small PIC model at all. */
11769 : 2671330 : if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
11770 : 2671330 : || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
11771 : : && !TARGET_64BIT)
11772 : 5342660 : return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
11773 : : return false;
11774 : 0 : case UNSPEC_GOTTPOFF:
11775 : 0 : case UNSPEC_GOTNTPOFF:
11776 : 0 : case UNSPEC_INDNTPOFF:
11777 : 0 : if (saw_plus)
11778 : : return false;
11779 : 0 : disp = XVECEXP (disp, 0, 0);
11780 : 0 : return (GET_CODE (disp) == SYMBOL_REF
11781 : 0 : && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
11782 : 0 : case UNSPEC_NTPOFF:
11783 : 0 : disp = XVECEXP (disp, 0, 0);
11784 : 0 : return (GET_CODE (disp) == SYMBOL_REF
11785 : 0 : && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
11786 : 0 : case UNSPEC_DTPOFF:
11787 : 0 : disp = XVECEXP (disp, 0, 0);
11788 : 0 : return (GET_CODE (disp) == SYMBOL_REF
11789 : 0 : && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
11790 : 0 : case UNSPEC_SECREL32:
11791 : 0 : disp = XVECEXP (disp, 0, 0);
11792 : 0 : return GET_CODE (disp) == SYMBOL_REF;
11793 : : }
11794 : :
11795 : : return false;
11796 : : }
11797 : :
11798 : : /* Determine if op is suitable RTX for an address register.
11799 : : Return naked register if a register or a register subreg is
11800 : : found, otherwise return NULL_RTX. */
11801 : :
11802 : : static rtx
11803 : 1356929902 : ix86_validate_address_register (rtx op)
11804 : : {
11805 : 1356929902 : machine_mode mode = GET_MODE (op);
11806 : :
11807 : : /* Only SImode or DImode registers can form the address. */
11808 : 1356929902 : if (mode != SImode && mode != DImode)
11809 : : return NULL_RTX;
11810 : :
11811 : 1356922398 : if (REG_P (op))
11812 : : return op;
11813 : 730934 : else if (SUBREG_P (op))
11814 : : {
11815 : 730934 : rtx reg = SUBREG_REG (op);
11816 : :
11817 : 730934 : if (!REG_P (reg))
11818 : : return NULL_RTX;
11819 : :
11820 : 730934 : mode = GET_MODE (reg);
11821 : :
11822 : : /* Don't allow SUBREGs that span more than a word. It can
11823 : : lead to spill failures when the register is one word out
11824 : : of a two word structure. */
11825 : 1506718 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
11826 : : return NULL_RTX;
11827 : :
11828 : : /* Allow only SUBREGs of non-eliminable hard registers. */
11829 : 218699 : if (register_no_elim_operand (reg, mode))
11830 : : return reg;
11831 : : }
11832 : :
11833 : : /* Op is not a register. */
11834 : : return NULL_RTX;
11835 : : }
11836 : :
11837 : : /* Determine which memory address register set insn can use. */
11838 : :
11839 : : static enum attr_addr
11840 : 253028782 : ix86_memory_address_reg_class (rtx_insn* insn)
11841 : : {
11842 : : /* LRA can do some initialization with NULL insn,
11843 : : return maximum register class in this case. */
11844 : 253028782 : enum attr_addr addr_rclass = ADDR_GPR32;
11845 : :
11846 : 253028782 : if (!insn)
11847 : : return addr_rclass;
11848 : :
11849 : 71932443 : if (asm_noperands (PATTERN (insn)) >= 0
11850 : 71932443 : || GET_CODE (PATTERN (insn)) == ASM_INPUT)
11851 : 60230 : return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
11852 : :
11853 : : /* Return maximum register class for unrecognized instructions. */
11854 : 71902328 : if (INSN_CODE (insn) < 0)
11855 : : return addr_rclass;
11856 : :
11857 : : /* Try to recognize the insn before calling get_attr_addr.
11858 : : Save current recog_data and current alternative. */
11859 : 71902328 : struct recog_data_d saved_recog_data = recog_data;
11860 : 71902328 : int saved_alternative = which_alternative;
11861 : :
11862 : : /* Update recog_data for processing of alternatives. */
11863 : 71902328 : extract_insn_cached (insn);
11864 : :
11865 : : /* If current alternative is not set, loop throught enabled
11866 : : alternatives and get the most limited register class. */
11867 : 71902328 : if (saved_alternative == -1)
11868 : : {
11869 : 71902328 : alternative_mask enabled = get_enabled_alternatives (insn);
11870 : :
11871 : 1239994921 : for (int i = 0; i < recog_data.n_alternatives; i++)
11872 : : {
11873 : 1168092593 : if (!TEST_BIT (enabled, i))
11874 : 345400350 : continue;
11875 : :
11876 : 822692243 : which_alternative = i;
11877 : 822692243 : addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
11878 : : }
11879 : : }
11880 : : else
11881 : : {
11882 : 0 : which_alternative = saved_alternative;
11883 : 0 : addr_rclass = get_attr_addr (insn);
11884 : : }
11885 : :
11886 : 71902328 : recog_data = saved_recog_data;
11887 : 71902328 : which_alternative = saved_alternative;
11888 : :
11889 : 71902328 : return addr_rclass;
11890 : : }
11891 : :
11892 : : /* Return memory address register class insn can use. */
11893 : :
11894 : : enum reg_class
11895 : 212811435 : ix86_insn_base_reg_class (rtx_insn* insn)
11896 : : {
11897 : 212811435 : switch (ix86_memory_address_reg_class (insn))
11898 : : {
11899 : : case ADDR_GPR8:
11900 : : return LEGACY_GENERAL_REGS;
11901 : : case ADDR_GPR16:
11902 : : return GENERAL_GPR16;
11903 : : case ADDR_GPR32:
11904 : : break;
11905 : 0 : default:
11906 : 0 : gcc_unreachable ();
11907 : : }
11908 : :
11909 : : return BASE_REG_CLASS;
11910 : : }
11911 : :
11912 : : bool
11913 : 1212392 : ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
11914 : : {
11915 : 1212392 : switch (ix86_memory_address_reg_class (insn))
11916 : : {
11917 : 0 : case ADDR_GPR8:
11918 : 0 : return LEGACY_INT_REGNO_P (regno);
11919 : 0 : case ADDR_GPR16:
11920 : 0 : return GENERAL_GPR16_REGNO_P (regno);
11921 : 1212392 : case ADDR_GPR32:
11922 : 1212392 : break;
11923 : 0 : default:
11924 : 0 : gcc_unreachable ();
11925 : : }
11926 : :
11927 : 1212392 : return GENERAL_REGNO_P (regno);
11928 : : }
11929 : :
11930 : : enum reg_class
11931 : 39004955 : ix86_insn_index_reg_class (rtx_insn* insn)
11932 : : {
11933 : 39004955 : switch (ix86_memory_address_reg_class (insn))
11934 : : {
11935 : : case ADDR_GPR8:
11936 : : return LEGACY_INDEX_REGS;
11937 : : case ADDR_GPR16:
11938 : : return INDEX_GPR16;
11939 : : case ADDR_GPR32:
11940 : : break;
11941 : 0 : default:
11942 : 0 : gcc_unreachable ();
11943 : : }
11944 : :
11945 : : return INDEX_REG_CLASS;
11946 : : }
11947 : :
11948 : : /* Recognizes RTL expressions that are valid memory addresses for an
11949 : : instruction. The MODE argument is the machine mode for the MEM
11950 : : expression that wants to use this address.
11951 : :
11952 : : It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
11953 : : convert common non-canonical forms to canonical form so that they will
11954 : : be recognized. */
11955 : :
11956 : : static bool
11957 : 2211625900 : ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
11958 : : code_helper = ERROR_MARK)
11959 : : {
11960 : 2211625900 : struct ix86_address parts;
11961 : 2211625900 : rtx base, index, disp;
11962 : 2211625900 : HOST_WIDE_INT scale;
11963 : 2211625900 : addr_space_t seg;
11964 : :
11965 : 2211625900 : if (ix86_decompose_address (addr, &parts) == 0)
11966 : : /* Decomposition failed. */
11967 : : return false;
11968 : :
11969 : 2200210600 : base = parts.base;
11970 : 2200210600 : index = parts.index;
11971 : 2200210600 : disp = parts.disp;
11972 : 2200210600 : scale = parts.scale;
11973 : 2200210600 : seg = parts.seg;
11974 : :
11975 : : /* Validate base register. */
11976 : 2200210600 : if (base)
11977 : : {
11978 : 1272897733 : rtx reg = ix86_validate_address_register (base);
11979 : :
11980 : 1272897733 : if (reg == NULL_RTX)
11981 : : return false;
11982 : :
11983 : 1272435550 : unsigned int regno = REGNO (reg);
11984 : 1272435550 : if ((strict && !REGNO_OK_FOR_BASE_P (regno))
11985 : 1268053688 : || (!strict && !REGNO_OK_FOR_BASE_NONSTRICT_P (regno)))
11986 : : /* Base is not valid. */
11987 : : return false;
11988 : : }
11989 : :
11990 : : /* Validate index register. */
11991 : 2198421695 : if (index)
11992 : : {
11993 : 84032169 : rtx reg = ix86_validate_address_register (index);
11994 : :
11995 : 84032169 : if (reg == NULL_RTX)
11996 : : return false;
11997 : :
11998 : 83974433 : unsigned int regno = REGNO (reg);
11999 : 83974433 : if ((strict && !REGNO_OK_FOR_INDEX_P (regno))
12000 : 83965782 : || (!strict && !REGNO_OK_FOR_INDEX_NONSTRICT_P (regno)))
12001 : : /* Index is not valid. */
12002 : : return false;
12003 : : }
12004 : :
12005 : : /* Index and base should have the same mode. */
12006 : 2198362833 : if (base && index
12007 : 74441907 : && GET_MODE (base) != GET_MODE (index))
12008 : : return false;
12009 : :
12010 : : /* Address override works only on the (%reg) part of %fs:(%reg). */
12011 : 2198143872 : if (seg != ADDR_SPACE_GENERIC
12012 : 2198143872 : && ((base && GET_MODE (base) != word_mode)
12013 : 304092 : || (index && GET_MODE (index) != word_mode)))
12014 : : return false;
12015 : :
12016 : : /* Validate scale factor. */
12017 : 2198143843 : if (scale != 1)
12018 : : {
12019 : 39359964 : if (!index)
12020 : : /* Scale without index. */
12021 : : return false;
12022 : :
12023 : 39359964 : if (scale != 2 && scale != 4 && scale != 8)
12024 : : /* Scale is not a valid multiplier. */
12025 : : return false;
12026 : : }
12027 : :
12028 : : /* Validate displacement. */
12029 : 2195013466 : if (disp)
12030 : : {
12031 : 1975049200 : if (ix86_endbr_immediate_operand (disp, VOIDmode))
12032 : : return false;
12033 : :
12034 : 1975049157 : if (GET_CODE (disp) == CONST
12035 : 142665268 : && GET_CODE (XEXP (disp, 0)) == UNSPEC
12036 : 14814455 : && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
12037 : 14814455 : switch (XINT (XEXP (disp, 0), 1))
12038 : : {
12039 : : /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
12040 : : when used. While ABI specify also 32bit relocations, we
12041 : : don't produce them at all and use IP relative instead.
12042 : : Allow GOT in 32bit mode for both PIC and non-PIC if symbol
12043 : : should be loaded via GOT. */
12044 : 2222591 : case UNSPEC_GOT:
12045 : 2222591 : if (!TARGET_64BIT
12046 : 2222591 : && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
12047 : 0 : goto is_legitimate_pic;
12048 : : /* FALLTHRU */
12049 : 4475506 : case UNSPEC_GOTOFF:
12050 : 4475506 : gcc_assert (flag_pic);
12051 : 4475506 : if (!TARGET_64BIT)
12052 : 4475404 : goto is_legitimate_pic;
12053 : :
12054 : : /* 64bit address unspec. */
12055 : : return false;
12056 : :
12057 : 9402698 : case UNSPEC_GOTPCREL:
12058 : 9402698 : if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
12059 : 2484 : goto is_legitimate_pic;
12060 : : /* FALLTHRU */
12061 : 9400214 : case UNSPEC_PCREL:
12062 : 9400214 : gcc_assert (flag_pic);
12063 : 9400214 : goto is_legitimate_pic;
12064 : :
12065 : : case UNSPEC_GOTTPOFF:
12066 : : case UNSPEC_GOTNTPOFF:
12067 : : case UNSPEC_INDNTPOFF:
12068 : : case UNSPEC_NTPOFF:
12069 : : case UNSPEC_DTPOFF:
12070 : : case UNSPEC_SECREL32:
12071 : : break;
12072 : :
12073 : : default:
12074 : : /* Invalid address unspec. */
12075 : : return false;
12076 : : }
12077 : :
12078 : 1252130035 : else if (SYMBOLIC_CONST (disp)
12079 : 2088085515 : && (flag_pic
12080 : : #if TARGET_MACHO
12081 : : || (MACHOPIC_INDIRECT
12082 : : && !machopic_operand_p (disp))
12083 : : #endif
12084 : : ))
12085 : : {
12086 : :
12087 : 55393438 : is_legitimate_pic:
12088 : 55393438 : if (TARGET_64BIT && (index || base))
12089 : : {
12090 : : /* foo@dtpoff(%rX) is ok. */
12091 : 35916 : if (GET_CODE (disp) != CONST
12092 : 6791 : || GET_CODE (XEXP (disp, 0)) != PLUS
12093 : 6791 : || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
12094 : 4439 : || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
12095 : 4439 : || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
12096 : 4439 : && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF
12097 : 0 : && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_SECREL32))
12098 : : /* Non-constant pic memory reference. */
12099 : : return false;
12100 : : }
12101 : 55357522 : else if ((!TARGET_MACHO || flag_pic)
12102 : 55357522 : && ! legitimate_pic_address_disp_p (disp))
12103 : : /* Displacement is an invalid pic construct. */
12104 : : return false;
12105 : : #if TARGET_MACHO
12106 : : else if (MACHO_DYNAMIC_NO_PIC_P
12107 : : && !ix86_legitimate_constant_p (Pmode, disp))
12108 : : /* displacment must be referenced via non_lazy_pointer */
12109 : : return false;
12110 : : #endif
12111 : :
12112 : : /* This code used to verify that a symbolic pic displacement
12113 : : includes the pic_offset_table_rtx register.
12114 : :
12115 : : While this is good idea, unfortunately these constructs may
12116 : : be created by "adds using lea" optimization for incorrect
12117 : : code like:
12118 : :
12119 : : int a;
12120 : : int foo(int i)
12121 : : {
12122 : : return *(&a+i);
12123 : : }
12124 : :
12125 : : This code is nonsensical, but results in addressing
12126 : : GOT table with pic_offset_table_rtx base. We can't
12127 : : just refuse it easily, since it gets matched by
12128 : : "addsi3" pattern, that later gets split to lea in the
12129 : : case output register differs from input. While this
12130 : : can be handled by separate addsi pattern for this case
12131 : : that never results in lea, this seems to be easier and
12132 : : correct fix for crash to disable this test. */
12133 : : }
12134 : 1918719366 : else if (GET_CODE (disp) != LABEL_REF
12135 : 1918469787 : && !CONST_INT_P (disp)
12136 : 851993649 : && (GET_CODE (disp) != CONST
12137 : 129245447 : || !ix86_legitimate_constant_p (Pmode, disp))
12138 : 2644348466 : && (GET_CODE (disp) != SYMBOL_REF
12139 : 731355387 : || !ix86_legitimate_constant_p (Pmode, disp)))
12140 : : /* Displacement is not constant. */
12141 : 57873285 : return false;
12142 : 1860846081 : else if (TARGET_64BIT
12143 : 1860846081 : && !x86_64_immediate_operand (disp, VOIDmode))
12144 : : /* Displacement is out of range. */
12145 : : return false;
12146 : : /* In x32 mode, constant addresses are sign extended to 64bit, so
12147 : : we have to prevent addresses from 0x80000000 to 0xffffffff. */
12148 : 45575 : else if (TARGET_X32 && !(index || base)
12149 : 16755 : && CONST_INT_P (disp)
12150 : 1860379365 : && val_signbit_known_set_p (SImode, INTVAL (disp)))
12151 : : return false;
12152 : : }
12153 : :
12154 : : /* Everything looks valid. */
12155 : : return true;
12156 : : }
12157 : :
12158 : : /* Determine if a given RTX is a valid constant address. */
12159 : :
12160 : : bool
12161 : 2645067458 : constant_address_p (rtx x)
12162 : : {
12163 : 2722990442 : return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
12164 : : }
12165 : :
12166 : :
12167 : : /* Return a legitimate reference for ORIG (an address) using the
12168 : : register REG. If REG is 0, a new pseudo is generated.
12169 : :
12170 : : There are two types of references that must be handled:
12171 : :
12172 : : 1. Global data references must load the address from the GOT, via
12173 : : the PIC reg. An insn is emitted to do this load, and the reg is
12174 : : returned.
12175 : :
12176 : : 2. Static data references, constant pool addresses, and code labels
12177 : : compute the address as an offset from the GOT, whose base is in
12178 : : the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
12179 : : differentiate them from global data objects. The returned
12180 : : address is the PIC reg + an unspec constant.
12181 : :
12182 : : TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
12183 : : reg also appears in the address. */
12184 : :
12185 : : rtx
12186 : 390990 : legitimize_pic_address (rtx orig, rtx reg)
12187 : : {
12188 : 390990 : rtx addr = orig;
12189 : 390990 : rtx new_rtx = orig;
12190 : :
12191 : : #if TARGET_MACHO
12192 : : if (TARGET_MACHO && !TARGET_64BIT)
12193 : : {
12194 : : if (reg == 0)
12195 : : reg = gen_reg_rtx (Pmode);
12196 : : /* Use the generic Mach-O PIC machinery. */
12197 : : return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
12198 : : }
12199 : : #endif
12200 : :
12201 : 390990 : if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
12202 : : {
12203 : : #if TARGET_PECOFF
12204 : : rtx tmp = legitimize_pe_coff_symbol (addr, true);
12205 : : if (tmp)
12206 : : return tmp;
12207 : : #endif
12208 : : }
12209 : :
12210 : 390990 : if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
12211 : : new_rtx = addr;
12212 : 296690 : else if ((!TARGET_64BIT
12213 : 99694 : || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
12214 : : && !TARGET_PECOFF
12215 : 493765 : && gotoff_operand (addr, Pmode))
12216 : : {
12217 : : /* This symbol may be referenced via a displacement
12218 : : from the PIC base address (@GOTOFF). */
12219 : 95202 : if (GET_CODE (addr) == CONST)
12220 : 2971 : addr = XEXP (addr, 0);
12221 : :
12222 : 95202 : if (GET_CODE (addr) == PLUS)
12223 : : {
12224 : 5942 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
12225 : : UNSPEC_GOTOFF);
12226 : 5942 : new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
12227 : : }
12228 : : else
12229 : 184450 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
12230 : :
12231 : 190392 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
12232 : :
12233 : 95202 : if (TARGET_64BIT)
12234 : 12 : new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
12235 : :
12236 : 95202 : if (reg != 0)
12237 : : {
12238 : 3 : gcc_assert (REG_P (reg));
12239 : 3 : new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
12240 : : new_rtx, reg, 1, OPTAB_DIRECT);
12241 : : }
12242 : : else
12243 : 190389 : new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
12244 : : }
12245 : 376132 : else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
12246 : : /* We can't always use @GOTOFF for text labels
12247 : : on VxWorks, see gotoff_operand. */
12248 : 201488 : || (TARGET_VXWORKS_VAROFF && GET_CODE (addr) == LABEL_REF))
12249 : : {
12250 : : #if TARGET_PECOFF
12251 : : rtx tmp = legitimize_pe_coff_symbol (addr, true);
12252 : : if (tmp)
12253 : : return tmp;
12254 : : #endif
12255 : :
12256 : : /* For x64 PE-COFF there is no GOT table,
12257 : : so we use address directly. */
12258 : 174641 : if (TARGET_64BIT && TARGET_PECOFF)
12259 : : {
12260 : : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
12261 : : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
12262 : : }
12263 : 174641 : else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
12264 : : {
12265 : 92558 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
12266 : : UNSPEC_GOTPCREL);
12267 : 92558 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
12268 : 92558 : new_rtx = gen_const_mem (Pmode, new_rtx);
12269 : 92555 : set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
12270 : : }
12271 : : else
12272 : : {
12273 : : /* This symbol must be referenced via a load
12274 : : from the Global Offset Table (@GOT). */
12275 : 164150 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
12276 : 164150 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
12277 : :
12278 : 82086 : if (TARGET_64BIT)
12279 : 22 : new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
12280 : :
12281 : 82086 : if (reg != 0)
12282 : : {
12283 : 0 : gcc_assert (REG_P (reg));
12284 : 0 : new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
12285 : : new_rtx, reg, 1, OPTAB_DIRECT);
12286 : : }
12287 : : else
12288 : 164150 : new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
12289 : :
12290 : 164150 : new_rtx = gen_const_mem (Pmode, new_rtx);
12291 : 82086 : set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
12292 : : }
12293 : :
12294 : 256708 : new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
12295 : : }
12296 : : else
12297 : : {
12298 : 26847 : if (CONST_INT_P (addr)
12299 : 26847 : && !x86_64_immediate_operand (addr, VOIDmode))
12300 : 8 : new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
12301 : 26839 : else if (GET_CODE (addr) == CONST)
12302 : : {
12303 : 16608 : addr = XEXP (addr, 0);
12304 : :
12305 : : /* We must match stuff we generate before. Assume the only
12306 : : unspecs that can get here are ours. Not that we could do
12307 : : anything with them anyway.... */
12308 : 16608 : if (GET_CODE (addr) == UNSPEC
12309 : 8832 : || (GET_CODE (addr) == PLUS
12310 : 8832 : && GET_CODE (XEXP (addr, 0)) == UNSPEC))
12311 : : return orig;
12312 : 6726 : gcc_assert (GET_CODE (addr) == PLUS);
12313 : : }
12314 : :
12315 : 16965 : if (GET_CODE (addr) == PLUS)
12316 : : {
12317 : 8483 : rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
12318 : :
12319 : : /* Check first to see if this is a constant
12320 : : offset from a @GOTOFF symbol reference. */
12321 : 8483 : if (!TARGET_PECOFF
12322 : 13413 : && gotoff_operand (op0, Pmode)
12323 : 8483 : && CONST_INT_P (op1))
12324 : : {
12325 : 4 : if (!TARGET_64BIT)
12326 : : {
12327 : 0 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
12328 : : UNSPEC_GOTOFF);
12329 : 0 : new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
12330 : 0 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
12331 : :
12332 : 0 : if (reg != 0)
12333 : : {
12334 : 0 : gcc_assert (REG_P (reg));
12335 : 0 : new_rtx = expand_simple_binop (Pmode, PLUS,
12336 : : pic_offset_table_rtx,
12337 : : new_rtx, reg, 1,
12338 : : OPTAB_DIRECT);
12339 : : }
12340 : : else
12341 : 0 : new_rtx
12342 : 0 : = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
12343 : : }
12344 : : else
12345 : : {
12346 : 4 : if (INTVAL (op1) < -16*1024*1024
12347 : 4 : || INTVAL (op1) >= 16*1024*1024)
12348 : : {
12349 : 4 : if (!x86_64_immediate_operand (op1, Pmode))
12350 : 4 : op1 = force_reg (Pmode, op1);
12351 : :
12352 : 4 : new_rtx
12353 : 4 : = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
12354 : : }
12355 : : }
12356 : : }
12357 : : else
12358 : : {
12359 : 8479 : rtx base = legitimize_pic_address (op0, reg);
12360 : 8479 : machine_mode mode = GET_MODE (base);
12361 : 8479 : new_rtx
12362 : 8479 : = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
12363 : :
12364 : 8479 : if (CONST_INT_P (new_rtx))
12365 : : {
12366 : 6714 : if (INTVAL (new_rtx) < -16*1024*1024
12367 : 6714 : || INTVAL (new_rtx) >= 16*1024*1024)
12368 : : {
12369 : 0 : if (!x86_64_immediate_operand (new_rtx, mode))
12370 : 0 : new_rtx = force_reg (mode, new_rtx);
12371 : :
12372 : 0 : new_rtx
12373 : 0 : = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
12374 : : }
12375 : : else
12376 : 6714 : new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
12377 : : }
12378 : : else
12379 : : {
12380 : : /* For %rip addressing, we have to use
12381 : : just disp32, not base nor index. */
12382 : 1765 : if (TARGET_64BIT
12383 : 99 : && (GET_CODE (base) == SYMBOL_REF
12384 : 99 : || GET_CODE (base) == LABEL_REF))
12385 : 7 : base = force_reg (mode, base);
12386 : 1765 : if (GET_CODE (new_rtx) == PLUS
12387 : 1644 : && CONSTANT_P (XEXP (new_rtx, 1)))
12388 : : {
12389 : 1640 : base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
12390 : 1640 : new_rtx = XEXP (new_rtx, 1);
12391 : : }
12392 : 1765 : new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
12393 : : }
12394 : : }
12395 : : }
12396 : : }
12397 : : return new_rtx;
12398 : : }
12399 : :
12400 : : /* Load the thread pointer. If TO_REG is true, force it into a register. */
12401 : :
12402 : : static rtx
12403 : 22473 : get_thread_pointer (machine_mode tp_mode, bool to_reg)
12404 : : {
12405 : 22473 : rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
12406 : :
12407 : 22473 : if (GET_MODE (tp) != tp_mode)
12408 : : {
12409 : 11 : gcc_assert (GET_MODE (tp) == SImode);
12410 : 11 : gcc_assert (tp_mode == DImode);
12411 : :
12412 : 11 : tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
12413 : : }
12414 : :
12415 : 22473 : if (to_reg)
12416 : 7769 : tp = copy_to_mode_reg (tp_mode, tp);
12417 : :
12418 : 22473 : return tp;
12419 : : }
12420 : :
12421 : : /* Construct the SYMBOL_REF for the _tls_index symbol. */
12422 : :
12423 : : static GTY(()) rtx ix86_tls_index_symbol;
12424 : :
12425 : : #if TARGET_WIN32_TLS
12426 : : static rtx
12427 : : ix86_tls_index (void)
12428 : : {
12429 : : if (!ix86_tls_index_symbol)
12430 : : ix86_tls_index_symbol = gen_rtx_SYMBOL_REF (SImode, "_tls_index");
12431 : :
12432 : : if (flag_pic)
12433 : : return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_index_symbol), UNSPEC_PCREL));
12434 : : else
12435 : : return ix86_tls_index_symbol;
12436 : : }
12437 : : #endif
12438 : :
12439 : : /* Construct the SYMBOL_REF for the tls_get_addr function. */
12440 : :
12441 : : static GTY(()) rtx ix86_tls_symbol;
12442 : :
12443 : : static rtx
12444 : 6565 : ix86_tls_get_addr (void)
12445 : : {
12446 : 6565 : if (!ix86_tls_symbol)
12447 : : {
12448 : 333 : const char *sym
12449 : 370 : = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
12450 : 370 : ? "___tls_get_addr" : "__tls_get_addr");
12451 : :
12452 : 407 : ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
12453 : : }
12454 : :
12455 : 6565 : if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
12456 : : {
12457 : 2 : rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
12458 : : UNSPEC_PLTOFF);
12459 : 2 : return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
12460 : : gen_rtx_CONST (Pmode, unspec));
12461 : : }
12462 : :
12463 : 6563 : return ix86_tls_symbol;
12464 : : }
12465 : :
12466 : : /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
12467 : :
12468 : : static GTY(()) rtx ix86_tls_module_base_symbol;
12469 : :
12470 : : rtx
12471 : 18 : ix86_tls_module_base (void)
12472 : : {
12473 : 18 : if (!ix86_tls_module_base_symbol)
12474 : : {
12475 : 3 : ix86_tls_module_base_symbol
12476 : 3 : = gen_rtx_SYMBOL_REF (ptr_mode, "_TLS_MODULE_BASE_");
12477 : :
12478 : 3 : SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
12479 : 3 : |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
12480 : : }
12481 : :
12482 : 18 : return ix86_tls_module_base_symbol;
12483 : : }
12484 : :
12485 : : /* A subroutine of ix86_legitimize_address and ix86_expand_move. FOR_MOV is
12486 : : false if we expect this to be used for a memory address and true if
12487 : : we expect to load the address into a register. */
12488 : :
12489 : : rtx
12490 : 29038 : legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
12491 : : {
12492 : 29038 : rtx dest, base, off;
12493 : 29038 : rtx pic = NULL_RTX, tp = NULL_RTX;
12494 : 29038 : machine_mode tp_mode = Pmode;
12495 : 29038 : int type;
12496 : :
12497 : : #if TARGET_WIN32_TLS
12498 : : off = gen_const_mem (SImode, ix86_tls_index ());
12499 : : set_mem_alias_set (off, GOT_ALIAS_SET);
12500 : :
12501 : : tp = gen_const_mem (Pmode, GEN_INT (TARGET_64BIT ? 88 : 44));
12502 : : set_mem_addr_space (tp, DEFAULT_TLS_SEG_REG);
12503 : :
12504 : : if (TARGET_64BIT)
12505 : : off = convert_to_mode (Pmode, off, 1);
12506 : :
12507 : : base = force_reg (Pmode, off);
12508 : : tp = copy_to_mode_reg (Pmode, tp);
12509 : :
12510 : : tp = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, tp, gen_rtx_MULT (Pmode, base, GEN_INT (UNITS_PER_WORD))));
12511 : : set_mem_alias_set (tp, GOT_ALIAS_SET);
12512 : :
12513 : : base = force_reg (Pmode, tp);
12514 : :
12515 : : return gen_rtx_PLUS (Pmode, base, gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, x), UNSPEC_SECREL32)));
12516 : : #else
12517 : : /* Fall back to global dynamic model if tool chain cannot support local
12518 : : dynamic. */
12519 : 29038 : if (TARGET_SUN_TLS && !TARGET_64BIT
12520 : : && !HAVE_AS_IX86_TLSLDMPLT && !HAVE_AS_IX86_TLSLDM
12521 : : && model == TLS_MODEL_LOCAL_DYNAMIC)
12522 : : model = TLS_MODEL_GLOBAL_DYNAMIC;
12523 : :
12524 : 29038 : switch (model)
12525 : : {
12526 : 6143 : case TLS_MODEL_GLOBAL_DYNAMIC:
12527 : 6143 : if (!TARGET_64BIT)
12528 : : {
12529 : 1901 : if (flag_pic && !TARGET_PECOFF)
12530 : 1901 : pic = pic_offset_table_rtx;
12531 : : else
12532 : : {
12533 : 0 : pic = gen_reg_rtx (Pmode);
12534 : 0 : emit_insn (gen_set_got (pic));
12535 : : }
12536 : : }
12537 : :
12538 : 6143 : if (TARGET_GNU2_TLS)
12539 : : {
12540 : 14 : dest = gen_reg_rtx (ptr_mode);
12541 : 14 : if (TARGET_64BIT)
12542 : 14 : emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, dest, x));
12543 : : else
12544 : 0 : emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
12545 : :
12546 : 14 : tp = get_thread_pointer (ptr_mode, true);
12547 : 14 : dest = gen_rtx_PLUS (ptr_mode, tp, dest);
12548 : 22 : if (GET_MODE (dest) != Pmode)
12549 : 6 : dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
12550 : 22 : dest = force_reg (Pmode, dest);
12551 : :
12552 : 22 : if (GET_MODE (x) != Pmode)
12553 : 3 : x = gen_rtx_ZERO_EXTEND (Pmode, x);
12554 : :
12555 : 14 : set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
12556 : : }
12557 : : else
12558 : : {
12559 : 6129 : rtx caddr = ix86_tls_get_addr ();
12560 : :
12561 : 8030 : dest = gen_reg_rtx (Pmode);
12562 : 6129 : if (TARGET_64BIT)
12563 : : {
12564 : 4228 : rtx rax = gen_rtx_REG (Pmode, AX_REG);
12565 : 4228 : rtx rdi = gen_rtx_REG (Pmode, DI_REG);
12566 : 4228 : rtx_insn *insns;
12567 : :
12568 : 4228 : start_sequence ();
12569 : 4228 : emit_call_insn
12570 : 4228 : (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr, rdi));
12571 : 4228 : insns = end_sequence ();
12572 : :
12573 : 4228 : if (GET_MODE (x) != Pmode)
12574 : 1 : x = gen_rtx_ZERO_EXTEND (Pmode, x);
12575 : :
12576 : 4228 : RTL_CONST_CALL_P (insns) = 1;
12577 : 4228 : emit_libcall_block (insns, dest, rax, x);
12578 : : }
12579 : : else
12580 : 1901 : emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
12581 : : }
12582 : : break;
12583 : :
12584 : 444 : case TLS_MODEL_LOCAL_DYNAMIC:
12585 : 444 : if (!TARGET_64BIT)
12586 : : {
12587 : 110 : if (flag_pic)
12588 : 110 : pic = pic_offset_table_rtx;
12589 : : else
12590 : : {
12591 : 0 : pic = gen_reg_rtx (Pmode);
12592 : 0 : emit_insn (gen_set_got (pic));
12593 : : }
12594 : : }
12595 : :
12596 : 444 : if (TARGET_GNU2_TLS)
12597 : : {
12598 : 8 : rtx tmp = ix86_tls_module_base ();
12599 : :
12600 : 8 : base = gen_reg_rtx (ptr_mode);
12601 : 8 : if (TARGET_64BIT)
12602 : 8 : emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
12603 : : else
12604 : 0 : emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
12605 : :
12606 : 8 : tp = get_thread_pointer (ptr_mode, true);
12607 : 14 : if (GET_MODE (base) != Pmode)
12608 : 2 : base = gen_rtx_ZERO_EXTEND (Pmode, base);
12609 : 14 : base = force_reg (Pmode, base);
12610 : : }
12611 : : else
12612 : : {
12613 : 436 : rtx caddr = ix86_tls_get_addr ();
12614 : :
12615 : 546 : base = gen_reg_rtx (Pmode);
12616 : 436 : if (TARGET_64BIT)
12617 : : {
12618 : 326 : rtx rax = gen_rtx_REG (Pmode, AX_REG);
12619 : 326 : rtx rdi = gen_rtx_REG (Pmode, DI_REG);
12620 : 326 : rtx_insn *insns;
12621 : 326 : rtx eqv;
12622 : :
12623 : 326 : start_sequence ();
12624 : 326 : emit_call_insn
12625 : 326 : (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr, rdi));
12626 : 326 : insns = end_sequence ();
12627 : :
12628 : : /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
12629 : : share the LD_BASE result with other LD model accesses. */
12630 : 326 : eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12631 : : UNSPEC_TLS_LD_BASE);
12632 : :
12633 : 326 : RTL_CONST_CALL_P (insns) = 1;
12634 : 326 : emit_libcall_block (insns, base, rax, eqv);
12635 : : }
12636 : : else
12637 : 110 : emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
12638 : : }
12639 : :
12640 : 560 : off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
12641 : 560 : off = gen_rtx_CONST (Pmode, off);
12642 : :
12643 : 676 : dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
12644 : :
12645 : 444 : if (TARGET_GNU2_TLS)
12646 : : {
12647 : 14 : if (GET_MODE (tp) != Pmode)
12648 : : {
12649 : 2 : dest = lowpart_subreg (ptr_mode, dest, Pmode);
12650 : 2 : dest = gen_rtx_PLUS (ptr_mode, tp, dest);
12651 : 2 : dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
12652 : : }
12653 : : else
12654 : 6 : dest = gen_rtx_PLUS (Pmode, tp, dest);
12655 : 14 : dest = force_reg (Pmode, dest);
12656 : :
12657 : 14 : if (GET_MODE (x) != Pmode)
12658 : 1 : x = gen_rtx_ZERO_EXTEND (Pmode, x);
12659 : :
12660 : 8 : set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
12661 : : }
12662 : : break;
12663 : :
12664 : 9584 : case TLS_MODEL_INITIAL_EXEC:
12665 : 9584 : if (TARGET_64BIT)
12666 : : {
12667 : : /* Generate DImode references to avoid %fs:(%reg32)
12668 : : problems and linker IE->LE relaxation bug. */
12669 : : tp_mode = DImode;
12670 : : pic = NULL;
12671 : : type = UNSPEC_GOTNTPOFF;
12672 : : }
12673 : 744 : else if (flag_pic)
12674 : : {
12675 : 743 : pic = pic_offset_table_rtx;
12676 : 743 : type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
12677 : : }
12678 : 1 : else if (!TARGET_ANY_GNU_TLS)
12679 : : {
12680 : 0 : pic = gen_reg_rtx (Pmode);
12681 : 0 : emit_insn (gen_set_got (pic));
12682 : 0 : type = UNSPEC_GOTTPOFF;
12683 : : }
12684 : : else
12685 : : {
12686 : : pic = NULL;
12687 : : type = UNSPEC_INDNTPOFF;
12688 : : }
12689 : :
12690 : 9584 : off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
12691 : 9584 : off = gen_rtx_CONST (tp_mode, off);
12692 : 9584 : if (pic)
12693 : 743 : off = gen_rtx_PLUS (tp_mode, pic, off);
12694 : 9584 : off = gen_const_mem (tp_mode, off);
12695 : 9584 : set_mem_alias_set (off, GOT_ALIAS_SET);
12696 : :
12697 : 9584 : if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
12698 : : {
12699 : 9584 : base = get_thread_pointer (tp_mode,
12700 : 9584 : for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
12701 : 9584 : off = force_reg (tp_mode, off);
12702 : 9584 : dest = gen_rtx_PLUS (tp_mode, base, off);
12703 : 10332 : if (tp_mode != Pmode)
12704 : 4 : dest = convert_to_mode (Pmode, dest, 1);
12705 : : }
12706 : : else
12707 : : {
12708 : 0 : base = get_thread_pointer (Pmode, true);
12709 : 0 : dest = gen_reg_rtx (Pmode);
12710 : 0 : emit_insn (gen_sub3_insn (dest, base, off));
12711 : : }
12712 : : break;
12713 : :
12714 : 12867 : case TLS_MODEL_LOCAL_EXEC:
12715 : 26485 : off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
12716 : : (TARGET_64BIT || TARGET_ANY_GNU_TLS)
12717 : : ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
12718 : 13618 : off = gen_rtx_CONST (Pmode, off);
12719 : :
12720 : 12867 : if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
12721 : : {
12722 : 13618 : base = get_thread_pointer (Pmode,
12723 : 12867 : for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
12724 : 13618 : return gen_rtx_PLUS (Pmode, base, off);
12725 : : }
12726 : : else
12727 : : {
12728 : 0 : base = get_thread_pointer (Pmode, true);
12729 : 0 : dest = gen_reg_rtx (Pmode);
12730 : 0 : emit_insn (gen_sub3_insn (dest, base, off));
12731 : : }
12732 : 0 : break;
12733 : :
12734 : 0 : default:
12735 : 0 : gcc_unreachable ();
12736 : : }
12737 : :
12738 : : return dest;
12739 : : #endif
12740 : : }
12741 : :
12742 : : /* Return true if the TLS address requires insn using integer registers.
12743 : : It's used to prevent KMOV/VMOV in TLS code sequences which require integer
12744 : : MOV instructions, refer to PR103275. */
12745 : : bool
12746 : 15411182 : ix86_gpr_tls_address_pattern_p (rtx mem)
12747 : : {
12748 : 15411182 : gcc_assert (MEM_P (mem));
12749 : :
12750 : 15411182 : rtx addr = XEXP (mem, 0);
12751 : 15411182 : subrtx_var_iterator::array_type array;
12752 : 53626083 : FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
12753 : : {
12754 : 38221808 : rtx op = *iter;
12755 : 38221808 : if (GET_CODE (op) == UNSPEC)
12756 : 197425 : switch (XINT (op, 1))
12757 : : {
12758 : : case UNSPEC_GOTNTPOFF:
12759 : 6907 : return true;
12760 : 0 : case UNSPEC_TPOFF:
12761 : 0 : if (!TARGET_64BIT)
12762 : : return true;
12763 : : break;
12764 : : default:
12765 : : break;
12766 : : }
12767 : : }
12768 : :
12769 : 15404275 : return false;
12770 : 15411182 : }
12771 : :
12772 : : /* Return true if OP refers to a TLS address. */
12773 : : bool
12774 : 231486709 : ix86_tls_address_pattern_p (rtx op)
12775 : : {
12776 : 231486709 : subrtx_var_iterator::array_type array;
12777 : 1372283667 : FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
12778 : : {
12779 : 1140813221 : rtx op = *iter;
12780 : 1140813221 : if (MEM_P (op))
12781 : : {
12782 : 103635733 : rtx *x = &XEXP (op, 0);
12783 : 164307003 : while (GET_CODE (*x) == PLUS)
12784 : : {
12785 : : int i;
12786 : 182030096 : for (i = 0; i < 2; i++)
12787 : : {
12788 : 121358826 : rtx u = XEXP (*x, i);
12789 : 121358826 : if (GET_CODE (u) == ZERO_EXTEND)
12790 : 126168 : u = XEXP (u, 0);
12791 : 121358826 : if (GET_CODE (u) == UNSPEC
12792 : 16285 : && XINT (u, 1) == UNSPEC_TP)
12793 : 16263 : return true;
12794 : : }
12795 : 60671270 : x = &XEXP (*x, 0);
12796 : : }
12797 : :
12798 : 103619470 : iter.skip_subrtxes ();
12799 : : }
12800 : : }
12801 : :
12802 : 231470446 : return false;
12803 : 231486709 : }
12804 : :
12805 : : /* Rewrite *LOC so that it refers to a default TLS address space. */
12806 : : static void
12807 : 16263 : ix86_rewrite_tls_address_1 (rtx *loc)
12808 : : {
12809 : 16263 : subrtx_ptr_iterator::array_type array;
12810 : 48957 : FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
12811 : : {
12812 : 48957 : rtx *loc = *iter;
12813 : 48957 : if (MEM_P (*loc))
12814 : : {
12815 : 16444 : rtx addr = XEXP (*loc, 0);
12816 : 16444 : rtx *x = &addr;
12817 : 21187 : while (GET_CODE (*x) == PLUS)
12818 : : {
12819 : : int i;
12820 : 30515 : for (i = 0; i < 2; i++)
12821 : : {
12822 : 25772 : rtx u = XEXP (*x, i);
12823 : 25772 : if (GET_CODE (u) == ZERO_EXTEND)
12824 : 19 : u = XEXP (u, 0);
12825 : 25772 : if (GET_CODE (u) == UNSPEC
12826 : 16263 : && XINT (u, 1) == UNSPEC_TP)
12827 : : {
12828 : : /* NB: Since address override only applies to the
12829 : : (reg32) part in fs:(reg32), return if address
12830 : : override is used. */
12831 : 17832 : if (Pmode != word_mode
12832 : 16263 : && REG_P (XEXP (*x, 1 - i)))
12833 : 16263 : return;
12834 : :
12835 : 16261 : addr_space_t as = DEFAULT_TLS_SEG_REG;
12836 : :
12837 : 16261 : *x = XEXP (*x, 1 - i);
12838 : :
12839 : 16261 : *loc = replace_equiv_address_nv (*loc, addr, true);
12840 : 16261 : set_mem_addr_space (*loc, as);
12841 : 16261 : return;
12842 : : }
12843 : : }
12844 : 4743 : x = &XEXP (*x, 0);
12845 : : }
12846 : :
12847 : 181 : iter.skip_subrtxes ();
12848 : : }
12849 : : }
12850 : 16263 : }
12851 : :
12852 : : /* Rewrite instruction pattern involvning TLS address
12853 : : so that it refers to a default TLS address space. */
12854 : : rtx
12855 : 16263 : ix86_rewrite_tls_address (rtx pattern)
12856 : : {
12857 : 16263 : pattern = copy_insn (pattern);
12858 : 16263 : ix86_rewrite_tls_address_1 (&pattern);
12859 : 16263 : return pattern;
12860 : : }
12861 : :
12862 : : /* Try machine-dependent ways of modifying an illegitimate address
12863 : : to be legitimate. If we find one, return the new, valid address.
12864 : : This macro is used in only one place: `memory_address' in explow.cc.
12865 : :
12866 : : OLDX is the address as it was before break_out_memory_refs was called.
12867 : : In some cases it is useful to look at this to decide what needs to be done.
12868 : :
12869 : : It is always safe for this macro to do nothing. It exists to recognize
12870 : : opportunities to optimize the output.
12871 : :
12872 : : For the 80386, we handle X+REG by loading X into a register R and
12873 : : using R+REG. R will go in a general reg and indexing will be used.
12874 : : However, if REG is a broken-out memory address or multiplication,
12875 : : nothing needs to be done because REG can certainly go in a general reg.
12876 : :
12877 : : When -fpic is used, special handling is needed for symbolic references.
12878 : : See comments by legitimize_pic_address in i386.cc for details. */
12879 : :
12880 : : static rtx
12881 : 629621 : ix86_legitimize_address (rtx x, rtx, machine_mode mode)
12882 : : {
12883 : 629621 : bool changed = false;
12884 : 629621 : unsigned log;
12885 : :
12886 : 629621 : log = GET_CODE (x) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (x) : 0;
12887 : 148707 : if (log)
12888 : 19210 : return legitimize_tls_address (x, (enum tls_model) log, false);
12889 : 610411 : if (GET_CODE (x) == CONST
12890 : 507 : && GET_CODE (XEXP (x, 0)) == PLUS
12891 : 507 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
12892 : 610918 : && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
12893 : : {
12894 : 4 : rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
12895 : : (enum tls_model) log, false);
12896 : 5 : return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
12897 : : }
12898 : :
12899 : 610407 : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
12900 : : {
12901 : : #if TARGET_PECOFF
12902 : : rtx tmp = legitimize_pe_coff_symbol (x, true);
12903 : : if (tmp)
12904 : : return tmp;
12905 : : #endif
12906 : : }
12907 : :
12908 : 610407 : if (flag_pic && SYMBOLIC_CONST (x))
12909 : 129881 : return legitimize_pic_address (x, 0);
12910 : :
12911 : : #if TARGET_MACHO
12912 : : if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
12913 : : return machopic_indirect_data_reference (x, 0);
12914 : : #endif
12915 : :
12916 : : /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
12917 : 480526 : if (GET_CODE (x) == ASHIFT
12918 : 0 : && CONST_INT_P (XEXP (x, 1))
12919 : 0 : && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
12920 : : {
12921 : 0 : changed = true;
12922 : 0 : log = INTVAL (XEXP (x, 1));
12923 : 0 : x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
12924 : : GEN_INT (1 << log));
12925 : : }
12926 : :
12927 : 480526 : if (GET_CODE (x) == PLUS)
12928 : : {
12929 : : /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
12930 : :
12931 : 152493 : if (GET_CODE (XEXP (x, 0)) == ASHIFT
12932 : 512 : && CONST_INT_P (XEXP (XEXP (x, 0), 1))
12933 : 512 : && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
12934 : : {
12935 : 512 : changed = true;
12936 : 512 : log = INTVAL (XEXP (XEXP (x, 0), 1));
12937 : 1492 : XEXP (x, 0) = gen_rtx_MULT (Pmode,
12938 : : force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
12939 : : GEN_INT (1 << log));
12940 : : }
12941 : :
12942 : 152493 : if (GET_CODE (XEXP (x, 1)) == ASHIFT
12943 : 0 : && CONST_INT_P (XEXP (XEXP (x, 1), 1))
12944 : 0 : && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
12945 : : {
12946 : 0 : changed = true;
12947 : 0 : log = INTVAL (XEXP (XEXP (x, 1), 1));
12948 : 0 : XEXP (x, 1) = gen_rtx_MULT (Pmode,
12949 : : force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
12950 : : GEN_INT (1 << log));
12951 : : }
12952 : :
12953 : : /* Put multiply first if it isn't already. */
12954 : 152493 : if (GET_CODE (XEXP (x, 1)) == MULT)
12955 : : {
12956 : 0 : std::swap (XEXP (x, 0), XEXP (x, 1));
12957 : 0 : changed = true;
12958 : : }
12959 : :
12960 : : /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
12961 : : into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
12962 : : created by virtual register instantiation, register elimination, and
12963 : : similar optimizations. */
12964 : 152493 : if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
12965 : : {
12966 : 9771 : changed = true;
12967 : 15389 : x = gen_rtx_PLUS (Pmode,
12968 : : gen_rtx_PLUS (Pmode, XEXP (x, 0),
12969 : : XEXP (XEXP (x, 1), 0)),
12970 : : XEXP (XEXP (x, 1), 1));
12971 : : }
12972 : :
12973 : : /* Canonicalize
12974 : : (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
12975 : : into (plus (plus (mult (reg) (const)) (reg)) (const)). */
12976 : 142722 : else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
12977 : 94612 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
12978 : 45259 : && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
12979 : 0 : && CONSTANT_P (XEXP (x, 1)))
12980 : : {
12981 : 0 : rtx constant;
12982 : 0 : rtx other = NULL_RTX;
12983 : :
12984 : 0 : if (CONST_INT_P (XEXP (x, 1)))
12985 : : {
12986 : 0 : constant = XEXP (x, 1);
12987 : 0 : other = XEXP (XEXP (XEXP (x, 0), 1), 1);
12988 : : }
12989 : 0 : else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
12990 : : {
12991 : : constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
12992 : : other = XEXP (x, 1);
12993 : : }
12994 : : else
12995 : : constant = 0;
12996 : :
12997 : 0 : if (constant)
12998 : : {
12999 : 0 : changed = true;
13000 : 0 : x = gen_rtx_PLUS (Pmode,
13001 : : gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
13002 : : XEXP (XEXP (XEXP (x, 0), 1), 0)),
13003 : : plus_constant (Pmode, other,
13004 : : INTVAL (constant)));
13005 : : }
13006 : : }
13007 : :
13008 : 152493 : if (changed && ix86_legitimate_address_p (mode, x, false))
13009 : 9806 : return x;
13010 : :
13011 : 142687 : if (GET_CODE (XEXP (x, 0)) == MULT)
13012 : : {
13013 : 18793 : changed = true;
13014 : 18793 : XEXP (x, 0) = copy_addr_to_reg (XEXP (x, 0));
13015 : : }
13016 : :
13017 : 142687 : if (GET_CODE (XEXP (x, 1)) == MULT)
13018 : : {
13019 : 0 : changed = true;
13020 : 0 : XEXP (x, 1) = copy_addr_to_reg (XEXP (x, 1));
13021 : : }
13022 : :
13023 : 142687 : if (changed
13024 : 18802 : && REG_P (XEXP (x, 1))
13025 : 15315 : && REG_P (XEXP (x, 0)))
13026 : : return x;
13027 : :
13028 : 127373 : if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
13029 : : {
13030 : 1757 : changed = true;
13031 : 1757 : x = legitimize_pic_address (x, 0);
13032 : : }
13033 : :
13034 : 127373 : if (changed && ix86_legitimate_address_p (mode, x, false))
13035 : 3762 : return x;
13036 : :
13037 : 123611 : if (REG_P (XEXP (x, 0)))
13038 : : {
13039 : 30586 : rtx temp = gen_reg_rtx (Pmode);
13040 : 28540 : rtx val = force_operand (XEXP (x, 1), temp);
13041 : 28540 : if (val != temp)
13042 : : {
13043 : 21269 : val = convert_to_mode (Pmode, val, 1);
13044 : 20990 : emit_move_insn (temp, val);
13045 : : }
13046 : :
13047 : 28540 : XEXP (x, 1) = temp;
13048 : 28540 : return x;
13049 : : }
13050 : :
13051 : 95071 : else if (REG_P (XEXP (x, 1)))
13052 : : {
13053 : 3481 : rtx temp = gen_reg_rtx (Pmode);
13054 : 2753 : rtx val = force_operand (XEXP (x, 0), temp);
13055 : 2753 : if (val != temp)
13056 : : {
13057 : 0 : val = convert_to_mode (Pmode, val, 1);
13058 : 0 : emit_move_insn (temp, val);
13059 : : }
13060 : :
13061 : 2753 : XEXP (x, 0) = temp;
13062 : 2753 : return x;
13063 : : }
13064 : : }
13065 : :
13066 : : return x;
13067 : : }
13068 : :
13069 : : /* Print an integer constant expression in assembler syntax. Addition
13070 : : and subtraction are the only arithmetic that may appear in these
13071 : : expressions. FILE is the stdio stream to write to, X is the rtx, and
13072 : : CODE is the operand print code from the output string. */
13073 : :
13074 : : static void
13075 : 3620257 : output_pic_addr_const (FILE *file, rtx x, int code)
13076 : : {
13077 : 3845868 : char buf[256];
13078 : :
13079 : 3845868 : switch (GET_CODE (x))
13080 : : {
13081 : 0 : case PC:
13082 : 0 : gcc_assert (flag_pic);
13083 : 0 : putc ('.', file);
13084 : 0 : break;
13085 : :
13086 : 847084 : case SYMBOL_REF:
13087 : 847084 : if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
13088 : 847084 : output_addr_const (file, x);
13089 : : else
13090 : : {
13091 : : const char *name = XSTR (x, 0);
13092 : :
13093 : : /* Mark the decl as referenced so that cgraph will
13094 : : output the function. */
13095 : : if (SYMBOL_REF_DECL (x))
13096 : : mark_decl_referenced (SYMBOL_REF_DECL (x));
13097 : :
13098 : : #if TARGET_MACHO
13099 : : if (MACHOPIC_INDIRECT
13100 : : && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
13101 : : name = machopic_indirection_name (x, /*stub_p=*/true);
13102 : : #endif
13103 : : assemble_name (file, name);
13104 : : }
13105 : 847084 : if (!TARGET_MACHO && !(TARGET_64BIT && TARGET_PECOFF)
13106 : 847084 : && code == 'P' && ix86_call_use_plt_p (x))
13107 : 385004 : fputs ("@PLT", file);
13108 : : break;
13109 : :
13110 : 2480 : case LABEL_REF:
13111 : 2480 : x = XEXP (x, 0);
13112 : : /* FALLTHRU */
13113 : 2480 : case CODE_LABEL:
13114 : 2480 : ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
13115 : 2480 : assemble_name (asm_out_file, buf);
13116 : 2480 : break;
13117 : :
13118 : 2573549 : CASE_CONST_SCALAR_INT:
13119 : 2573549 : output_addr_const (file, x);
13120 : 2573549 : break;
13121 : :
13122 : 206686 : case CONST:
13123 : : /* This used to output parentheses around the expression,
13124 : : but that does not work on the 386 (either ATT or BSD assembler). */
13125 : 206686 : output_pic_addr_const (file, XEXP (x, 0), code);
13126 : 206686 : break;
13127 : :
13128 : 0 : case CONST_DOUBLE:
13129 : : /* We can't handle floating point constants;
13130 : : TARGET_PRINT_OPERAND must handle them. */
13131 : 0 : output_operand_lossage ("floating constant misused");
13132 : 0 : break;
13133 : :
13134 : 18925 : case PLUS:
13135 : : /* Some assemblers need integer constants to appear first. */
13136 : 18925 : if (CONST_INT_P (XEXP (x, 0)))
13137 : : {
13138 : 0 : output_pic_addr_const (file, XEXP (x, 0), code);
13139 : 0 : putc ('+', file);
13140 : 0 : output_pic_addr_const (file, XEXP (x, 1), code);
13141 : : }
13142 : : else
13143 : : {
13144 : 18925 : gcc_assert (CONST_INT_P (XEXP (x, 1)));
13145 : 18925 : output_pic_addr_const (file, XEXP (x, 1), code);
13146 : 18925 : putc ('+', file);
13147 : 18925 : output_pic_addr_const (file, XEXP (x, 0), code);
13148 : : }
13149 : : break;
13150 : :
13151 : 0 : case MINUS:
13152 : 0 : if (!TARGET_MACHO)
13153 : 0 : putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
13154 : 0 : output_pic_addr_const (file, XEXP (x, 0), code);
13155 : 0 : putc ('-', file);
13156 : 0 : output_pic_addr_const (file, XEXP (x, 1), code);
13157 : 0 : if (!TARGET_MACHO)
13158 : 0 : putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
13159 : 0 : break;
13160 : :
13161 : 197144 : case UNSPEC:
13162 : 197144 : gcc_assert (XVECLEN (x, 0) == 1);
13163 : 197144 : output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
13164 : 197144 : switch (XINT (x, 1))
13165 : : {
13166 : 42356 : case UNSPEC_GOT:
13167 : 42356 : fputs ("@GOT", file);
13168 : 42356 : break;
13169 : 76631 : case UNSPEC_GOTOFF:
13170 : 76631 : fputs ("@GOTOFF", file);
13171 : 76631 : break;
13172 : 33 : case UNSPEC_PLTOFF:
13173 : 33 : fputs ("@PLTOFF", file);
13174 : 33 : break;
13175 : 0 : case UNSPEC_PCREL:
13176 : 0 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
13177 : : "(%rip)" : "[rip]", file);
13178 : 0 : break;
13179 : 74110 : case UNSPEC_GOTPCREL:
13180 : 74110 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
13181 : : "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
13182 : 74110 : break;
13183 : 0 : case UNSPEC_GOTTPOFF:
13184 : : /* FIXME: This might be @TPOFF in Sun ld too. */
13185 : 0 : fputs ("@gottpoff", file);
13186 : 0 : break;
13187 : 0 : case UNSPEC_TPOFF:
13188 : 0 : fputs ("@tpoff", file);
13189 : 0 : break;
13190 : 1353 : case UNSPEC_NTPOFF:
13191 : 1353 : if (TARGET_64BIT)
13192 : 1353 : fputs ("@tpoff", file);
13193 : : else
13194 : 0 : fputs ("@ntpoff", file);
13195 : : break;
13196 : 334 : case UNSPEC_DTPOFF:
13197 : 334 : fputs ("@dtpoff", file);
13198 : 334 : break;
13199 : 2327 : case UNSPEC_GOTNTPOFF:
13200 : 2327 : if (TARGET_64BIT)
13201 : 2079 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
13202 : : "@gottpoff(%rip)": "@gottpoff[rip]", file);
13203 : : else
13204 : 248 : fputs ("@gotntpoff", file);
13205 : : break;
13206 : 0 : case UNSPEC_INDNTPOFF:
13207 : 0 : fputs ("@indntpoff", file);
13208 : 0 : break;
13209 : 0 : case UNSPEC_SECREL32:
13210 : 0 : fputs ("@secrel32", file);
13211 : 0 : break;
13212 : : #if TARGET_MACHO
13213 : : case UNSPEC_MACHOPIC_OFFSET:
13214 : : putc ('-', file);
13215 : : machopic_output_function_base_name (file);
13216 : : break;
13217 : : #endif
13218 : 0 : default:
13219 : 0 : output_operand_lossage ("invalid UNSPEC as operand");
13220 : 0 : break;
13221 : : }
13222 : : break;
13223 : :
13224 : 0 : default:
13225 : 0 : output_operand_lossage ("invalid expression as operand");
13226 : : }
13227 : 3620257 : }
13228 : :
13229 : : /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
13230 : : We need to emit DTP-relative relocations. */
13231 : :
13232 : : static void ATTRIBUTE_UNUSED
13233 : 699 : i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
13234 : : {
13235 : 699 : fputs (ASM_LONG, file);
13236 : 699 : output_addr_const (file, x);
13237 : : #if TARGET_WIN32_TLS
13238 : : fputs ("@secrel32", file);
13239 : : #else
13240 : 699 : fputs ("@dtpoff", file);
13241 : : #endif
13242 : 699 : switch (size)
13243 : : {
13244 : : case 4:
13245 : : break;
13246 : 536 : case 8:
13247 : 536 : fputs (", 0", file);
13248 : 536 : break;
13249 : 0 : default:
13250 : 0 : gcc_unreachable ();
13251 : : }
13252 : 699 : }
13253 : :
13254 : : /* Return true if X is a representation of the PIC register. This copes
13255 : : with calls from ix86_find_base_term, where the register might have
13256 : : been replaced by a cselib value. */
13257 : :
13258 : : static bool
13259 : 26811610 : ix86_pic_register_p (rtx x)
13260 : : {
13261 : 26811610 : if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
13262 : 764758 : return (pic_offset_table_rtx
13263 : 764758 : && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
13264 : 26046852 : else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SET_GOT)
13265 : : return true;
13266 : 26045427 : else if (!REG_P (x))
13267 : : return false;
13268 : 25433913 : else if (pic_offset_table_rtx)
13269 : : {
13270 : 25413302 : if (REGNO (x) == REGNO (pic_offset_table_rtx))
13271 : : return true;
13272 : 381388 : if (HARD_REGISTER_P (x)
13273 : 361005 : && !HARD_REGISTER_P (pic_offset_table_rtx)
13274 : 742393 : && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
13275 : : return true;
13276 : : return false;
13277 : : }
13278 : : else
13279 : 20611 : return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
13280 : : }
13281 : :
13282 : : /* Helper function for ix86_delegitimize_address.
13283 : : Attempt to delegitimize TLS local-exec accesses. */
13284 : :
13285 : : static rtx
13286 : 3495330264 : ix86_delegitimize_tls_address (rtx orig_x)
13287 : : {
13288 : 3495330264 : rtx x = orig_x, unspec;
13289 : 3495330264 : struct ix86_address addr;
13290 : :
13291 : 3495330264 : if (!TARGET_TLS_DIRECT_SEG_REFS)
13292 : : return orig_x;
13293 : 3495330264 : if (MEM_P (x))
13294 : 42484789 : x = XEXP (x, 0);
13295 : 5032065452 : if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
13296 : : return orig_x;
13297 : 1688007819 : if (ix86_decompose_address (x, &addr) == 0
13298 : 1953081595 : || addr.seg != DEFAULT_TLS_SEG_REG
13299 : 246560 : || addr.disp == NULL_RTX
13300 : 1688206721 : || GET_CODE (addr.disp) != CONST)
13301 : : return orig_x;
13302 : 107417 : unspec = XEXP (addr.disp, 0);
13303 : 107417 : if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
13304 : 65695 : unspec = XEXP (unspec, 0);
13305 : 107417 : if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
13306 : : return orig_x;
13307 : 107364 : x = XVECEXP (unspec, 0, 0);
13308 : 107364 : gcc_assert (GET_CODE (x) == SYMBOL_REF);
13309 : 107364 : if (unspec != XEXP (addr.disp, 0))
13310 : 86566 : x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
13311 : 107364 : if (addr.index)
13312 : : {
13313 : 187 : rtx idx = addr.index;
13314 : 187 : if (addr.scale != 1)
13315 : 187 : idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
13316 : 187 : x = gen_rtx_PLUS (Pmode, idx, x);
13317 : : }
13318 : 107364 : if (addr.base)
13319 : 2 : x = gen_rtx_PLUS (Pmode, addr.base, x);
13320 : 107364 : if (MEM_P (orig_x))
13321 : 198 : x = replace_equiv_address_nv (orig_x, x);
13322 : : return x;
13323 : : }
13324 : :
13325 : : /* In the name of slightly smaller debug output, and to cater to
13326 : : general assembler lossage, recognize PIC+GOTOFF and turn it back
13327 : : into a direct symbol reference.
13328 : :
13329 : : On Darwin, this is necessary to avoid a crash, because Darwin
13330 : : has a different PIC label for each routine but the DWARF debugging
13331 : : information is not associated with any particular routine, so it's
13332 : : necessary to remove references to the PIC label from RTL stored by
13333 : : the DWARF output code.
13334 : :
13335 : : This helper is used in the normal ix86_delegitimize_address
13336 : : entrypoint (e.g. used in the target delegitimization hook) and
13337 : : in ix86_find_base_term. As compile time memory optimization, we
13338 : : avoid allocating rtxes that will not change anything on the outcome
13339 : : of the callers (find_base_value and find_base_term). */
13340 : :
13341 : : static inline rtx
13342 : 3520103934 : ix86_delegitimize_address_1 (rtx x, bool base_term_p)
13343 : : {
13344 : 3520103934 : rtx orig_x = delegitimize_mem_from_attrs (x);
13345 : : /* addend is NULL or some rtx if x is something+GOTOFF where
13346 : : something doesn't include the PIC register. */
13347 : 3520103934 : rtx addend = NULL_RTX;
13348 : : /* reg_addend is NULL or a multiple of some register. */
13349 : 3520103934 : rtx reg_addend = NULL_RTX;
13350 : : /* const_addend is NULL or a const_int. */
13351 : 3520103934 : rtx const_addend = NULL_RTX;
13352 : : /* This is the result, or NULL. */
13353 : 3520103934 : rtx result = NULL_RTX;
13354 : :
13355 : 3520103934 : x = orig_x;
13356 : :
13357 : 3520103934 : if (MEM_P (x))
13358 : 61633138 : x = XEXP (x, 0);
13359 : :
13360 : 3520103934 : if (TARGET_64BIT)
13361 : : {
13362 : 241902148 : if (GET_CODE (x) == CONST
13363 : 8271762 : && GET_CODE (XEXP (x, 0)) == PLUS
13364 : 6512468 : && GET_MODE (XEXP (x, 0)) == Pmode
13365 : 6512419 : && CONST_INT_P (XEXP (XEXP (x, 0), 1))
13366 : 6512419 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
13367 : 241906719 : && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
13368 : : {
13369 : : /* find_base_{value,term} only care about MEMs with arg_pointer_rtx
13370 : : base. A CONST can't be arg_pointer_rtx based. */
13371 : 0 : if (base_term_p && MEM_P (orig_x))
13372 : : return orig_x;
13373 : 0 : rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
13374 : 0 : x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
13375 : 0 : if (MEM_P (orig_x))
13376 : 0 : x = replace_equiv_address_nv (orig_x, x);
13377 : 0 : return x;
13378 : : }
13379 : :
13380 : 241902148 : if (GET_CODE (x) == CONST
13381 : 8271762 : && GET_CODE (XEXP (x, 0)) == UNSPEC
13382 : 1759343 : && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
13383 : 572437 : || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
13384 : 1186906 : && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
13385 : : {
13386 : 258165 : x = XVECEXP (XEXP (x, 0), 0, 0);
13387 : 258165 : if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
13388 : : {
13389 : 9 : x = lowpart_subreg (GET_MODE (orig_x), x, GET_MODE (x));
13390 : 9 : if (x == NULL_RTX)
13391 : : return orig_x;
13392 : : }
13393 : 258165 : return x;
13394 : : }
13395 : :
13396 : 241643983 : if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
13397 : 241642863 : return ix86_delegitimize_tls_address (orig_x);
13398 : :
13399 : : /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
13400 : : and -mcmodel=medium -fpic. */
13401 : : }
13402 : :
13403 : 3278202906 : if (GET_CODE (x) != PLUS
13404 : 1561250126 : || GET_CODE (XEXP (x, 1)) != CONST)
13405 : 3251945337 : return ix86_delegitimize_tls_address (orig_x);
13406 : :
13407 : 26257569 : if (ix86_pic_register_p (XEXP (x, 0)))
13408 : : /* %ebx + GOT/GOTOFF */
13409 : : ;
13410 : 1300692 : else if (GET_CODE (XEXP (x, 0)) == PLUS)
13411 : : {
13412 : : /* %ebx + %reg * scale + GOT/GOTOFF */
13413 : 480050 : reg_addend = XEXP (x, 0);
13414 : 480050 : if (ix86_pic_register_p (XEXP (reg_addend, 0)))
13415 : 406059 : reg_addend = XEXP (reg_addend, 1);
13416 : 73991 : else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
13417 : 42715 : reg_addend = XEXP (reg_addend, 0);
13418 : : else
13419 : : {
13420 : 31276 : reg_addend = NULL_RTX;
13421 : 31276 : addend = XEXP (x, 0);
13422 : : }
13423 : : }
13424 : : else
13425 : : addend = XEXP (x, 0);
13426 : :
13427 : 26257569 : x = XEXP (XEXP (x, 1), 0);
13428 : 26257569 : if (GET_CODE (x) == PLUS
13429 : 1468192 : && CONST_INT_P (XEXP (x, 1)))
13430 : : {
13431 : 1468192 : const_addend = XEXP (x, 1);
13432 : 1468192 : x = XEXP (x, 0);
13433 : : }
13434 : :
13435 : 26257569 : if (GET_CODE (x) == UNSPEC
13436 : 25568271 : && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
13437 : 6678087 : || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
13438 : 1052770 : || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
13439 : 4 : && !MEM_P (orig_x) && !addend)))
13440 : 24515505 : result = XVECEXP (x, 0, 0);
13441 : :
13442 : 24515505 : if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
13443 : : && !MEM_P (orig_x))
13444 : : result = XVECEXP (x, 0, 0);
13445 : :
13446 : 24515505 : if (! result)
13447 : 1742064 : return ix86_delegitimize_tls_address (orig_x);
13448 : :
13449 : : /* For (PLUS something CONST_INT) both find_base_{value,term} just
13450 : : recurse on the first operand. */
13451 : 24515505 : if (const_addend && !base_term_p)
13452 : 346155 : result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
13453 : 24515505 : if (reg_addend)
13454 : 875674 : result = gen_rtx_PLUS (Pmode, reg_addend, result);
13455 : 24515505 : if (addend)
13456 : : {
13457 : : /* If the rest of original X doesn't involve the PIC register, add
13458 : : addend and subtract pic_offset_table_rtx. This can happen e.g.
13459 : : for code like:
13460 : : leal (%ebx, %ecx, 4), %ecx
13461 : : ...
13462 : : movl foo@GOTOFF(%ecx), %edx
13463 : : in which case we return (%ecx - %ebx) + foo
13464 : : or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
13465 : : and reload has completed. Don't do the latter for debug,
13466 : : as _GLOBAL_OFFSET_TABLE_ can't be expressed in the assembly. */
13467 : 135156 : if (pic_offset_table_rtx
13468 : 135156 : && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
13469 : 2334 : result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
13470 : : pic_offset_table_rtx),
13471 : : result);
13472 : 134378 : else if (base_term_p
13473 : 129309 : && pic_offset_table_rtx
13474 : : && !TARGET_MACHO
13475 : : && !TARGET_VXWORKS_VAROFF)
13476 : : {
13477 : 258618 : rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
13478 : 258618 : tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
13479 : 258618 : result = gen_rtx_PLUS (Pmode, tmp, result);
13480 : 129309 : }
13481 : : else
13482 : : return orig_x;
13483 : : }
13484 : 49020829 : if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
13485 : : {
13486 : 0 : result = lowpart_subreg (GET_MODE (orig_x), result, Pmode);
13487 : 0 : if (result == NULL_RTX)
13488 : : return orig_x;
13489 : : }
13490 : : return result;
13491 : : }
13492 : :
13493 : : /* The normal instantiation of the above template. */
13494 : :
13495 : : static rtx
13496 : 311112446 : ix86_delegitimize_address (rtx x)
13497 : : {
13498 : 311112446 : return ix86_delegitimize_address_1 (x, false);
13499 : : }
13500 : :
13501 : : /* If X is a machine specific address (i.e. a symbol or label being
13502 : : referenced as a displacement from the GOT implemented using an
13503 : : UNSPEC), then return the base term. Otherwise return X. */
13504 : :
13505 : : rtx
13506 : 6673129665 : ix86_find_base_term (rtx x)
13507 : : {
13508 : 6673129665 : rtx term;
13509 : :
13510 : 6673129665 : if (TARGET_64BIT)
13511 : : {
13512 : 3464138177 : if (GET_CODE (x) != CONST)
13513 : : return x;
13514 : 39981760 : term = XEXP (x, 0);
13515 : 39981760 : if (GET_CODE (term) == PLUS
13516 : 39967141 : && CONST_INT_P (XEXP (term, 1)))
13517 : 39967141 : term = XEXP (term, 0);
13518 : 39981760 : if (GET_CODE (term) != UNSPEC
13519 : 40414 : || (XINT (term, 1) != UNSPEC_GOTPCREL
13520 : 40414 : && XINT (term, 1) != UNSPEC_PCREL))
13521 : : return x;
13522 : :
13523 : 0 : return XVECEXP (term, 0, 0);
13524 : : }
13525 : :
13526 : 3208991488 : return ix86_delegitimize_address_1 (x, true);
13527 : : }
13528 : :
13529 : : /* Return true if X shouldn't be emitted into the debug info.
13530 : : Disallow UNSPECs other than @gotoff - we can't emit _GLOBAL_OFFSET_TABLE_
13531 : : symbol easily into the .debug_info section, so we need not to
13532 : : delegitimize, but instead assemble as @gotoff.
13533 : : Disallow _GLOBAL_OFFSET_TABLE_ SYMBOL_REF - the assembler magically
13534 : : assembles that as _GLOBAL_OFFSET_TABLE_-. expression. */
13535 : :
13536 : : static bool
13537 : 1802210 : ix86_const_not_ok_for_debug_p (rtx x)
13538 : : {
13539 : 1802210 : if (GET_CODE (x) == UNSPEC && XINT (x, 1) != UNSPEC_GOTOFF)
13540 : : return true;
13541 : :
13542 : 1802188 : if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
13543 : 0 : return true;
13544 : :
13545 : : return false;
13546 : : }
13547 : :
13548 : : static void
13549 : 7027899 : put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
13550 : : bool fp, FILE *file)
13551 : : {
13552 : 7027899 : const char *suffix;
13553 : :
13554 : 7027899 : if (mode == CCFPmode)
13555 : : {
13556 : 558203 : code = ix86_fp_compare_code_to_integer (code);
13557 : 558203 : mode = CCmode;
13558 : : }
13559 : 7027899 : if (reverse)
13560 : 195143 : code = reverse_condition (code);
13561 : :
13562 : 7027899 : switch (code)
13563 : : {
13564 : 2753859 : case EQ:
13565 : 2753859 : gcc_assert (mode != CCGZmode);
13566 : 2753859 : switch (mode)
13567 : : {
13568 : : case E_CCAmode:
13569 : : suffix = "a";
13570 : : break;
13571 : : case E_CCCmode:
13572 : 28060 : suffix = "c";
13573 : : break;
13574 : : case E_CCOmode:
13575 : 7027899 : suffix = "o";
13576 : : break;
13577 : : case E_CCPmode:
13578 : 232013 : suffix = "p";
13579 : : break;
13580 : : case E_CCSmode:
13581 : 118540 : suffix = "s";
13582 : : break;
13583 : 2733820 : default:
13584 : 2733820 : suffix = "e";
13585 : 2733820 : break;
13586 : : }
13587 : : break;
13588 : 2277906 : case NE:
13589 : 2277906 : gcc_assert (mode != CCGZmode);
13590 : 2277906 : switch (mode)
13591 : : {
13592 : : case E_CCAmode:
13593 : : suffix = "na";
13594 : : break;
13595 : : case E_CCCmode:
13596 : 14354 : suffix = "nc";
13597 : : break;
13598 : 10762 : case E_CCOmode:
13599 : 10762 : suffix = "no";
13600 : 10762 : break;
13601 : : case E_CCPmode:
13602 : 4386 : suffix = "np";
13603 : : break;
13604 : : case E_CCSmode:
13605 : 49099 : suffix = "ns";
13606 : : break;
13607 : 2266268 : default:
13608 : 2266268 : suffix = "ne";
13609 : 2266268 : break;
13610 : : }
13611 : : break;
13612 : 244918 : case GT:
13613 : 244918 : gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
13614 : : suffix = "g";
13615 : : break;
13616 : 165078 : case GTU:
13617 : : /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
13618 : : Those same assemblers have the same but opposite lossage on cmov. */
13619 : 165078 : if (mode == CCmode)
13620 : 165140 : suffix = fp ? "nbe" : "a";
13621 : : else
13622 : 0 : gcc_unreachable ();
13623 : : break;
13624 : 232230 : case LT:
13625 : 232230 : switch (mode)
13626 : : {
13627 : : case E_CCNOmode:
13628 : : case E_CCGOCmode:
13629 : : suffix = "s";
13630 : : break;
13631 : :
13632 : : case E_CCmode:
13633 : : case E_CCGCmode:
13634 : : case E_CCGZmode:
13635 : 7027899 : suffix = "l";
13636 : : break;
13637 : :
13638 : 0 : default:
13639 : 0 : gcc_unreachable ();
13640 : : }
13641 : : break;
13642 : 429925 : case LTU:
13643 : 429925 : if (mode == CCmode || mode == CCGZmode)
13644 : : suffix = "b";
13645 : 26776 : else if (mode == CCCmode)
13646 : 28060 : suffix = fp ? "b" : "c";
13647 : : else
13648 : 0 : gcc_unreachable ();
13649 : : break;
13650 : 140841 : case GE:
13651 : 140841 : switch (mode)
13652 : : {
13653 : : case E_CCNOmode:
13654 : : case E_CCGOCmode:
13655 : : suffix = "ns";
13656 : : break;
13657 : :
13658 : : case E_CCmode:
13659 : : case E_CCGCmode:
13660 : : case E_CCGZmode:
13661 : 7027899 : suffix = "ge";
13662 : : break;
13663 : :
13664 : 0 : default:
13665 : 0 : gcc_unreachable ();
13666 : : }
13667 : : break;
13668 : 191300 : case GEU:
13669 : 191300 : if (mode == CCmode || mode == CCGZmode)
13670 : : suffix = "nb";
13671 : 13498 : else if (mode == CCCmode)
13672 : 14354 : suffix = fp ? "nb" : "nc";
13673 : : else
13674 : 0 : gcc_unreachable ();
13675 : : break;
13676 : 243307 : case LE:
13677 : 243307 : gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
13678 : : suffix = "le";
13679 : : break;
13680 : 112136 : case LEU:
13681 : 112136 : if (mode == CCmode)
13682 : : suffix = "be";
13683 : : else
13684 : 0 : gcc_unreachable ();
13685 : : break;
13686 : 232012 : case UNORDERED:
13687 : 232019 : suffix = fp ? "u" : "p";
13688 : : break;
13689 : 4387 : case ORDERED:
13690 : 4392 : suffix = fp ? "nu" : "np";
13691 : : break;
13692 : 0 : default:
13693 : 0 : gcc_unreachable ();
13694 : : }
13695 : 7027899 : fputs (suffix, file);
13696 : 7027899 : }
13697 : :
13698 : : /* Print the name of register X to FILE based on its machine mode and number.
13699 : : If CODE is 'w', pretend the mode is HImode.
13700 : : If CODE is 'b', pretend the mode is QImode.
13701 : : If CODE is 'k', pretend the mode is SImode.
13702 : : If CODE is 'q', pretend the mode is DImode.
13703 : : If CODE is 'x', pretend the mode is V4SFmode.
13704 : : If CODE is 't', pretend the mode is V8SFmode.
13705 : : If CODE is 'g', pretend the mode is V16SFmode.
13706 : : If CODE is 'h', pretend the reg is the 'high' byte register.
13707 : : If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
13708 : : If CODE is 'd', duplicate the operand for AVX instruction.
13709 : : If CODE is 'V', print naked full integer register name without %.
13710 : : */
13711 : :
13712 : : void
13713 : 122226667 : print_reg (rtx x, int code, FILE *file)
13714 : : {
13715 : 122226667 : const char *reg;
13716 : 122226667 : int msize;
13717 : 122226667 : unsigned int regno;
13718 : 122226667 : bool duplicated;
13719 : :
13720 : 122226667 : if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
13721 : 122224459 : putc ('%', file);
13722 : :
13723 : 122226667 : if (x == pc_rtx)
13724 : : {
13725 : 5657499 : gcc_assert (TARGET_64BIT);
13726 : 5657499 : fputs ("rip", file);
13727 : 5657499 : return;
13728 : : }
13729 : :
13730 : 116569168 : if (code == 'y' && STACK_TOP_P (x))
13731 : : {
13732 : 298233 : fputs ("st(0)", file);
13733 : 298233 : return;
13734 : : }
13735 : :
13736 : 116270935 : if (code == 'w')
13737 : : msize = 2;
13738 : : else if (code == 'b')
13739 : : msize = 1;
13740 : : else if (code == 'k')
13741 : : msize = 4;
13742 : : else if (code == 'q')
13743 : : msize = 8;
13744 : : else if (code == 'h')
13745 : : msize = 0;
13746 : : else if (code == 'x')
13747 : : msize = 16;
13748 : : else if (code == 't')
13749 : : msize = 32;
13750 : : else if (code == 'g')
13751 : : msize = 64;
13752 : : else
13753 : 198387922 : msize = GET_MODE_SIZE (GET_MODE (x));
13754 : :
13755 : 116270935 : regno = REGNO (x);
13756 : :
13757 : 116270935 : if (regno == ARG_POINTER_REGNUM
13758 : 116270935 : || regno == FRAME_POINTER_REGNUM
13759 : 116270935 : || regno == FPSR_REG)
13760 : : {
13761 : 0 : output_operand_lossage
13762 : 0 : ("invalid use of register '%s'", reg_names[regno]);
13763 : 0 : return;
13764 : : }
13765 : 116270935 : else if (regno == FLAGS_REG)
13766 : : {
13767 : 1 : output_operand_lossage ("invalid use of asm flag output");
13768 : 1 : return;
13769 : : }
13770 : :
13771 : 116270934 : if (code == 'V')
13772 : : {
13773 : 1 : if (GENERAL_REGNO_P (regno))
13774 : 2 : msize = GET_MODE_SIZE (word_mode);
13775 : : else
13776 : 0 : error ("%<V%> modifier on non-integer register");
13777 : : }
13778 : :
13779 : 116270934 : duplicated = code == 'd' && TARGET_AVX;
13780 : :
13781 : 116270934 : switch (msize)
13782 : : {
13783 : 76675412 : case 16:
13784 : 76675412 : case 12:
13785 : 76675412 : case 8:
13786 : 143536981 : if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
13787 : 5 : warning (0, "unsupported size for integer register");
13788 : : /* FALLTHRU */
13789 : 112821909 : case 4:
13790 : 112821909 : if (LEGACY_INT_REGNO_P (regno))
13791 : 122511673 : putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
13792 : : /* FALLTHRU */
13793 : 113718168 : case 2:
13794 : 21892350 : normal:
13795 : 113718168 : reg = hi_reg_name[regno];
13796 : 113718168 : break;
13797 : 2313434 : case 1:
13798 : 2313434 : if (regno >= ARRAY_SIZE (qi_reg_name))
13799 : 286382 : goto normal;
13800 : 2027052 : if (!ANY_QI_REGNO_P (regno))
13801 : 0 : error ("unsupported size for integer register");
13802 : 2027052 : reg = qi_reg_name[regno];
13803 : 2027052 : break;
13804 : 26885 : case 0:
13805 : 26885 : if (regno >= ARRAY_SIZE (qi_high_reg_name))
13806 : 0 : goto normal;
13807 : 26885 : reg = qi_high_reg_name[regno];
13808 : 26885 : break;
13809 : 498829 : case 32:
13810 : 498829 : case 64:
13811 : 498829 : if (SSE_REGNO_P (regno))
13812 : : {
13813 : 498829 : gcc_assert (!duplicated);
13814 : 695086 : putc (msize == 32 ? 'y' : 'z', file);
13815 : 498829 : reg = hi_reg_name[regno] + 1;
13816 : 498829 : break;
13817 : : }
13818 : 0 : goto normal;
13819 : 0 : default:
13820 : 0 : gcc_unreachable ();
13821 : : }
13822 : :
13823 : 116270934 : fputs (reg, file);
13824 : :
13825 : : /* Irritatingly, AMD extended registers use
13826 : : different naming convention: "r%d[bwd]" */
13827 : 116270934 : if (REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
13828 : : {
13829 : 10346249 : gcc_assert (TARGET_64BIT);
13830 : 10346249 : switch (msize)
13831 : : {
13832 : 0 : case 0:
13833 : 0 : error ("extended registers have no high halves");
13834 : 0 : break;
13835 : 202247 : case 1:
13836 : 202247 : putc ('b', file);
13837 : 202247 : break;
13838 : 29485 : case 2:
13839 : 29485 : putc ('w', file);
13840 : 29485 : break;
13841 : 2600393 : case 4:
13842 : 2600393 : putc ('d', file);
13843 : 2600393 : break;
13844 : : case 8:
13845 : : /* no suffix */
13846 : : break;
13847 : 0 : default:
13848 : 0 : error ("unsupported operand size for extended register");
13849 : 0 : break;
13850 : : }
13851 : 10346249 : return;
13852 : : }
13853 : :
13854 : 105924685 : if (duplicated)
13855 : : {
13856 : 16758 : if (ASSEMBLER_DIALECT == ASM_ATT)
13857 : 16737 : fprintf (file, ", %%%s", reg);
13858 : : else
13859 : 21 : fprintf (file, ", %s", reg);
13860 : : }
13861 : : }
13862 : :
13863 : : /* Meaning of CODE:
13864 : : L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
13865 : : C -- print opcode suffix for set/cmov insn.
13866 : : c -- like C, but print reversed condition
13867 : : F,f -- likewise, but for floating-point.
13868 : : O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
13869 : : otherwise nothing
13870 : : R -- print embedded rounding and sae.
13871 : : r -- print only sae.
13872 : : z -- print the opcode suffix for the size of the current operand.
13873 : : Z -- likewise, with special suffixes for x87 instructions.
13874 : : * -- print a star (in certain assembler syntax)
13875 : : A -- print an absolute memory reference.
13876 : : E -- print address with DImode register names if TARGET_64BIT.
13877 : : w -- print the operand as if it's a "word" (HImode) even if it isn't.
13878 : : s -- print a shift double count, followed by the assemblers argument
13879 : : delimiter.
13880 : : b -- print the QImode name of the register for the indicated operand.
13881 : : %b0 would print %al if operands[0] is reg 0.
13882 : : w -- likewise, print the HImode name of the register.
13883 : : k -- likewise, print the SImode name of the register.
13884 : : q -- likewise, print the DImode name of the register.
13885 : : x -- likewise, print the V4SFmode name of the register.
13886 : : t -- likewise, print the V8SFmode name of the register.
13887 : : g -- likewise, print the V16SFmode name of the register.
13888 : : h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
13889 : : y -- print "st(0)" instead of "st" as a register.
13890 : : d -- print duplicated register operand for AVX instruction.
13891 : : D -- print condition for SSE cmp instruction.
13892 : : P -- if PIC, print an @PLT suffix. For -fno-plt, load function
13893 : : address from GOT.
13894 : : p -- print raw symbol name.
13895 : : X -- don't print any sort of PIC '@' suffix for a symbol.
13896 : : & -- print some in-use local-dynamic symbol name.
13897 : : H -- print a memory address offset by 8; used for sse high-parts
13898 : : Y -- print condition for XOP pcom* instruction.
13899 : : V -- print naked full integer register name without %.
13900 : : v -- print segment override prefix
13901 : : + -- print a branch hint as 'cs' or 'ds' prefix
13902 : : ; -- print a semicolon (after prefixes due to bug in older gas).
13903 : : ~ -- print "i" if TARGET_AVX2, "f" otherwise.
13904 : : ^ -- print addr32 prefix if Pmode != word_mode
13905 : : M -- print addr32 prefix for TARGET_X32 with VSIB address.
13906 : : ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
13907 : : N -- print maskz if it's constant 0 operand.
13908 : : G -- print embedded flag for ccmp/ctest.
13909 : : */
13910 : :
13911 : : void
13912 : 175031043 : ix86_print_operand (FILE *file, rtx x, int code)
13913 : : {
13914 : 175230498 : if (code)
13915 : : {
13916 : 61669696 : switch (code)
13917 : : {
13918 : 199451 : case 'A':
13919 : 199451 : switch (ASSEMBLER_DIALECT)
13920 : : {
13921 : 199451 : case ASM_ATT:
13922 : 199451 : putc ('*', file);
13923 : 199451 : break;
13924 : :
13925 : 0 : case ASM_INTEL:
13926 : : /* Intel syntax. For absolute addresses, registers should not
13927 : : be surrounded by braces. */
13928 : 0 : if (!REG_P (x))
13929 : : {
13930 : 0 : putc ('[', file);
13931 : 0 : ix86_print_operand (file, x, 0);
13932 : 0 : putc (']', file);
13933 : 0 : return;
13934 : : }
13935 : : break;
13936 : :
13937 : 0 : default:
13938 : 0 : gcc_unreachable ();
13939 : : }
13940 : :
13941 : 199451 : ix86_print_operand (file, x, 0);
13942 : 199451 : return;
13943 : :
13944 : 3535395 : case 'E':
13945 : : /* Wrap address in an UNSPEC to declare special handling. */
13946 : 3535395 : if (TARGET_64BIT)
13947 : 3057840 : x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
13948 : :
13949 : 3535395 : output_address (VOIDmode, x);
13950 : 3535395 : return;
13951 : :
13952 : 0 : case 'L':
13953 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13954 : 0 : putc ('l', file);
13955 : 0 : return;
13956 : :
13957 : 0 : case 'W':
13958 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13959 : 0 : putc ('w', file);
13960 : 0 : return;
13961 : :
13962 : 0 : case 'B':
13963 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13964 : 0 : putc ('b', file);
13965 : 0 : return;
13966 : :
13967 : 0 : case 'Q':
13968 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13969 : 0 : putc ('l', file);
13970 : 0 : return;
13971 : :
13972 : 0 : case 'S':
13973 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13974 : 0 : putc ('s', file);
13975 : 0 : return;
13976 : :
13977 : 0 : case 'T':
13978 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13979 : 0 : putc ('t', file);
13980 : 0 : return;
13981 : :
13982 : : case 'O':
13983 : : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
13984 : : if (ASSEMBLER_DIALECT != ASM_ATT)
13985 : : return;
13986 : :
13987 : : switch (GET_MODE_SIZE (GET_MODE (x)))
13988 : : {
13989 : : case 2:
13990 : : putc ('w', file);
13991 : : break;
13992 : :
13993 : : case 4:
13994 : : putc ('l', file);
13995 : : break;
13996 : :
13997 : : case 8:
13998 : : putc ('q', file);
13999 : : break;
14000 : :
14001 : : default:
14002 : : output_operand_lossage ("invalid operand size for operand "
14003 : : "code 'O'");
14004 : : return;
14005 : : }
14006 : :
14007 : : putc ('.', file);
14008 : : #endif
14009 : : return;
14010 : :
14011 : 37345 : case 'z':
14012 : 37345 : if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
14013 : : {
14014 : : /* Opcodes don't get size suffixes if using Intel opcodes. */
14015 : 37343 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14016 : : return;
14017 : :
14018 : 74686 : switch (GET_MODE_SIZE (GET_MODE (x)))
14019 : : {
14020 : 6 : case 1:
14021 : 6 : putc ('b', file);
14022 : 6 : return;
14023 : :
14024 : 6 : case 2:
14025 : 6 : putc ('w', file);
14026 : 6 : return;
14027 : :
14028 : 36839 : case 4:
14029 : 36839 : putc ('l', file);
14030 : 36839 : return;
14031 : :
14032 : 492 : case 8:
14033 : 492 : putc ('q', file);
14034 : 492 : return;
14035 : :
14036 : 0 : default:
14037 : 0 : output_operand_lossage ("invalid operand size for operand "
14038 : : "code 'z'");
14039 : 0 : return;
14040 : : }
14041 : : }
14042 : :
14043 : 2 : if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
14044 : : {
14045 : 1 : if (this_is_asm_operands)
14046 : 1 : warning_for_asm (this_is_asm_operands,
14047 : : "non-integer operand used with operand code %<z%>");
14048 : : else
14049 : 0 : warning (0, "non-integer operand used with operand code %<z%>");
14050 : : }
14051 : : /* FALLTHRU */
14052 : :
14053 : 386400 : case 'Z':
14054 : : /* 387 opcodes don't get size suffixes if using Intel opcodes. */
14055 : 386400 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14056 : : return;
14057 : :
14058 : 386400 : if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
14059 : : {
14060 : 29060 : switch (GET_MODE_SIZE (GET_MODE (x)))
14061 : : {
14062 : 3501 : case 2:
14063 : : #ifdef HAVE_AS_IX86_FILDS
14064 : 3501 : putc ('s', file);
14065 : : #endif
14066 : 3501 : return;
14067 : :
14068 : 3920 : case 4:
14069 : 3920 : putc ('l', file);
14070 : 3920 : return;
14071 : :
14072 : 7109 : case 8:
14073 : : #ifdef HAVE_AS_IX86_FILDQ
14074 : 7109 : putc ('q', file);
14075 : : #else
14076 : : fputs ("ll", file);
14077 : : #endif
14078 : 7109 : return;
14079 : :
14080 : : default:
14081 : : break;
14082 : : }
14083 : : }
14084 : 371870 : else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
14085 : : {
14086 : : /* 387 opcodes don't get size suffixes
14087 : : if the operands are registers. */
14088 : 371868 : if (STACK_REG_P (x))
14089 : : return;
14090 : :
14091 : 697318 : switch (GET_MODE_SIZE (GET_MODE (x)))
14092 : : {
14093 : 23105 : case 4:
14094 : 23105 : putc ('s', file);
14095 : 23105 : return;
14096 : :
14097 : 32333 : case 8:
14098 : 32333 : putc ('l', file);
14099 : 32333 : return;
14100 : :
14101 : 293219 : case 12:
14102 : 293219 : case 16:
14103 : 293219 : putc ('t', file);
14104 : 293219 : return;
14105 : :
14106 : : default:
14107 : : break;
14108 : : }
14109 : : }
14110 : : else
14111 : : {
14112 : 2 : output_operand_lossage ("invalid operand type used with "
14113 : : "operand code '%c'", code);
14114 : 2 : return;
14115 : : }
14116 : :
14117 : 2 : output_operand_lossage ("invalid operand size for operand code '%c'",
14118 : : code);
14119 : 2 : return;
14120 : :
14121 : : case 'd':
14122 : : case 'b':
14123 : : case 'w':
14124 : : case 'k':
14125 : : case 'q':
14126 : : case 'h':
14127 : : case 't':
14128 : : case 'g':
14129 : : case 'y':
14130 : : case 'x':
14131 : : case 'X':
14132 : : case 'P':
14133 : : case 'p':
14134 : : case 'V':
14135 : : break;
14136 : :
14137 : 0 : case 's':
14138 : 0 : if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
14139 : : {
14140 : 0 : ix86_print_operand (file, x, 0);
14141 : 0 : fputs (", ", file);
14142 : : }
14143 : 0 : return;
14144 : :
14145 : 494 : case 'Y':
14146 : 494 : switch (GET_CODE (x))
14147 : : {
14148 : 182 : case NE:
14149 : 182 : fputs ("neq", file);
14150 : 182 : break;
14151 : 32 : case EQ:
14152 : 32 : fputs ("eq", file);
14153 : 32 : break;
14154 : 64 : case GE:
14155 : 64 : case GEU:
14156 : 64 : fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
14157 : 64 : break;
14158 : 40 : case GT:
14159 : 40 : case GTU:
14160 : 40 : fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
14161 : 40 : break;
14162 : 64 : case LE:
14163 : 64 : case LEU:
14164 : 64 : fputs ("le", file);
14165 : 64 : break;
14166 : 112 : case LT:
14167 : 112 : case LTU:
14168 : 112 : fputs ("lt", file);
14169 : 112 : break;
14170 : 0 : case UNORDERED:
14171 : 0 : fputs ("unord", file);
14172 : 0 : break;
14173 : 0 : case ORDERED:
14174 : 0 : fputs ("ord", file);
14175 : 0 : break;
14176 : 0 : case UNEQ:
14177 : 0 : fputs ("ueq", file);
14178 : 0 : break;
14179 : 0 : case UNGE:
14180 : 0 : fputs ("nlt", file);
14181 : 0 : break;
14182 : 0 : case UNGT:
14183 : 0 : fputs ("nle", file);
14184 : 0 : break;
14185 : 0 : case UNLE:
14186 : 0 : fputs ("ule", file);
14187 : 0 : break;
14188 : 0 : case UNLT:
14189 : 0 : fputs ("ult", file);
14190 : 0 : break;
14191 : 0 : case LTGT:
14192 : 0 : fputs ("une", file);
14193 : 0 : break;
14194 : 0 : default:
14195 : 0 : output_operand_lossage ("operand is not a condition code, "
14196 : : "invalid operand code 'Y'");
14197 : 0 : return;
14198 : : }
14199 : 494 : return;
14200 : :
14201 : 9237 : case 'D':
14202 : : /* Little bit of braindamage here. The SSE compare instructions
14203 : : does use completely different names for the comparisons that the
14204 : : fp conditional moves. */
14205 : 9237 : switch (GET_CODE (x))
14206 : : {
14207 : 3 : case UNEQ:
14208 : 3 : if (TARGET_AVX)
14209 : : {
14210 : 3 : fputs ("eq_us", file);
14211 : 3 : break;
14212 : : }
14213 : : /* FALLTHRU */
14214 : 4327 : case EQ:
14215 : 4327 : fputs ("eq", file);
14216 : 4327 : break;
14217 : 0 : case UNLT:
14218 : 0 : if (TARGET_AVX)
14219 : : {
14220 : 0 : fputs ("nge", file);
14221 : 0 : break;
14222 : : }
14223 : : /* FALLTHRU */
14224 : 1885 : case LT:
14225 : 1885 : fputs ("lt", file);
14226 : 1885 : break;
14227 : 0 : case UNLE:
14228 : 0 : if (TARGET_AVX)
14229 : : {
14230 : 0 : fputs ("ngt", file);
14231 : 0 : break;
14232 : : }
14233 : : /* FALLTHRU */
14234 : 682 : case LE:
14235 : 682 : fputs ("le", file);
14236 : 682 : break;
14237 : 92 : case UNORDERED:
14238 : 92 : fputs ("unord", file);
14239 : 92 : break;
14240 : 24 : case LTGT:
14241 : 24 : if (TARGET_AVX)
14242 : : {
14243 : 24 : fputs ("neq_oq", file);
14244 : 24 : break;
14245 : : }
14246 : : /* FALLTHRU */
14247 : 982 : case NE:
14248 : 982 : fputs ("neq", file);
14249 : 982 : break;
14250 : 0 : case GE:
14251 : 0 : if (TARGET_AVX)
14252 : : {
14253 : 0 : fputs ("ge", file);
14254 : 0 : break;
14255 : : }
14256 : : /* FALLTHRU */
14257 : 405 : case UNGE:
14258 : 405 : fputs ("nlt", file);
14259 : 405 : break;
14260 : 0 : case GT:
14261 : 0 : if (TARGET_AVX)
14262 : : {
14263 : 0 : fputs ("gt", file);
14264 : 0 : break;
14265 : : }
14266 : : /* FALLTHRU */
14267 : 754 : case UNGT:
14268 : 754 : fputs ("nle", file);
14269 : 754 : break;
14270 : 83 : case ORDERED:
14271 : 83 : fputs ("ord", file);
14272 : 83 : break;
14273 : 0 : default:
14274 : 0 : output_operand_lossage ("operand is not a condition code, "
14275 : : "invalid operand code 'D'");
14276 : 0 : return;
14277 : : }
14278 : 9237 : return;
14279 : :
14280 : 7027899 : case 'F':
14281 : 7027899 : case 'f':
14282 : : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
14283 : : if (ASSEMBLER_DIALECT == ASM_ATT)
14284 : : putc ('.', file);
14285 : : gcc_fallthrough ();
14286 : : #endif
14287 : :
14288 : 7027899 : case 'C':
14289 : 7027899 : case 'c':
14290 : 7027899 : if (!COMPARISON_P (x))
14291 : : {
14292 : 0 : output_operand_lossage ("operand is not a condition code, "
14293 : : "invalid operand code '%c'", code);
14294 : 0 : return;
14295 : : }
14296 : 7027899 : put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
14297 : 7027899 : code == 'c' || code == 'f',
14298 : 7027899 : code == 'F' || code == 'f',
14299 : : file);
14300 : 7027899 : return;
14301 : :
14302 : 21 : case 'G':
14303 : 21 : {
14304 : 21 : int dfv = INTVAL (x);
14305 : 21 : const char *dfv_suffix = ix86_ccmp_dfv_mapping[dfv];
14306 : 21 : fputs (dfv_suffix, file);
14307 : : }
14308 : 21 : return;
14309 : :
14310 : 1255 : case 'H':
14311 : 1255 : if (!offsettable_memref_p (x))
14312 : : {
14313 : 1 : output_operand_lossage ("operand is not an offsettable memory "
14314 : : "reference, invalid operand code 'H'");
14315 : 1 : return;
14316 : : }
14317 : : /* It doesn't actually matter what mode we use here, as we're
14318 : : only going to use this for printing. */
14319 : 1254 : x = adjust_address_nv (x, DImode, 8);
14320 : : /* Output 'qword ptr' for intel assembler dialect. */
14321 : 1254 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14322 : 0 : code = 'q';
14323 : : break;
14324 : :
14325 : 76515 : case 'K':
14326 : 76515 : if (!CONST_INT_P (x))
14327 : : {
14328 : 1 : output_operand_lossage ("operand is not an integer, invalid "
14329 : : "operand code 'K'");
14330 : 1 : return;
14331 : : }
14332 : :
14333 : 76514 : if (INTVAL (x) & IX86_HLE_ACQUIRE)
14334 : : #ifdef HAVE_AS_IX86_HLE
14335 : 22 : fputs ("xacquire ", file);
14336 : : #else
14337 : : fputs ("\n" ASM_BYTE "0xf2\n\t", file);
14338 : : #endif
14339 : 76492 : else if (INTVAL (x) & IX86_HLE_RELEASE)
14340 : : #ifdef HAVE_AS_IX86_HLE
14341 : 24 : fputs ("xrelease ", file);
14342 : : #else
14343 : : fputs ("\n" ASM_BYTE "0xf3\n\t", file);
14344 : : #endif
14345 : : /* We do not want to print value of the operand. */
14346 : 76514 : return;
14347 : :
14348 : 41093 : case 'N':
14349 : 41093 : if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
14350 : 14461 : fputs ("{z}", file);
14351 : 41093 : return;
14352 : :
14353 : 4008 : case 'r':
14354 : 4008 : if (!CONST_INT_P (x) || INTVAL (x) != ROUND_SAE)
14355 : : {
14356 : 2 : output_operand_lossage ("operand is not a specific integer, "
14357 : : "invalid operand code 'r'");
14358 : 2 : return;
14359 : : }
14360 : :
14361 : 4006 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14362 : 1 : fputs (", ", file);
14363 : :
14364 : 4006 : fputs ("{sae}", file);
14365 : :
14366 : 4006 : if (ASSEMBLER_DIALECT == ASM_ATT)
14367 : 4005 : fputs (", ", file);
14368 : :
14369 : 4006 : return;
14370 : :
14371 : 6026 : case 'R':
14372 : 6026 : if (!CONST_INT_P (x))
14373 : : {
14374 : 1 : output_operand_lossage ("operand is not an integer, invalid "
14375 : : "operand code 'R'");
14376 : 1 : return;
14377 : : }
14378 : :
14379 : 6025 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14380 : 2 : fputs (", ", file);
14381 : :
14382 : 6025 : switch (INTVAL (x))
14383 : : {
14384 : 5214 : case ROUND_NEAREST_INT | ROUND_SAE:
14385 : 5214 : fputs ("{rn-sae}", file);
14386 : 5214 : break;
14387 : 637 : case ROUND_NEG_INF | ROUND_SAE:
14388 : 637 : fputs ("{rd-sae}", file);
14389 : 637 : break;
14390 : 52 : case ROUND_POS_INF | ROUND_SAE:
14391 : 52 : fputs ("{ru-sae}", file);
14392 : 52 : break;
14393 : 121 : case ROUND_ZERO | ROUND_SAE:
14394 : 121 : fputs ("{rz-sae}", file);
14395 : 121 : break;
14396 : 1 : default:
14397 : 1 : output_operand_lossage ("operand is not a specific integer, "
14398 : : "invalid operand code 'R'");
14399 : : }
14400 : :
14401 : 6025 : if (ASSEMBLER_DIALECT == ASM_ATT)
14402 : 6023 : fputs (", ", file);
14403 : :
14404 : 6025 : return;
14405 : :
14406 : 8233 : case 'v':
14407 : 8233 : if (MEM_P (x))
14408 : : {
14409 : 8380 : switch (MEM_ADDR_SPACE (x))
14410 : : {
14411 : : case ADDR_SPACE_GENERIC:
14412 : : break;
14413 : 0 : case ADDR_SPACE_SEG_FS:
14414 : 0 : fputs ("fs ", file);
14415 : 0 : break;
14416 : 0 : case ADDR_SPACE_SEG_GS:
14417 : 0 : fputs ("gs ", file);
14418 : 0 : break;
14419 : 0 : default:
14420 : 0 : gcc_unreachable ();
14421 : : }
14422 : : }
14423 : : else
14424 : 0 : output_operand_lossage ("operand is not a memory reference, "
14425 : : "invalid operand code 'v'");
14426 : 8233 : return;
14427 : :
14428 : 0 : case '*':
14429 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
14430 : 0 : putc ('*', file);
14431 : 0 : return;
14432 : :
14433 : 272 : case '&':
14434 : 272 : {
14435 : 272 : const char *name = get_some_local_dynamic_name ();
14436 : 272 : if (name == NULL)
14437 : 1 : output_operand_lossage ("'%%&' used without any "
14438 : : "local dynamic TLS references");
14439 : : else
14440 : 271 : assemble_name (file, name);
14441 : 272 : return;
14442 : : }
14443 : :
14444 : 6406721 : case '+':
14445 : 6406721 : {
14446 : 6406721 : rtx x;
14447 : :
14448 : 6406721 : if (!optimize
14449 : 5011682 : || optimize_function_for_size_p (cfun)
14450 : 11234042 : || (!TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN
14451 : 4827321 : && !TARGET_BRANCH_PREDICTION_HINTS_TAKEN))
14452 : 6406721 : return;
14453 : :
14454 : 0 : x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
14455 : 0 : if (x)
14456 : : {
14457 : 0 : int pred_val = profile_probability::from_reg_br_prob_note
14458 : 0 : (XINT (x, 0)).to_reg_br_prob_base ();
14459 : :
14460 : 0 : bool taken = pred_val > REG_BR_PROB_BASE / 2;
14461 : : /* We use 3e (DS) prefix for taken branches and
14462 : : 2e (CS) prefix for not taken branches. */
14463 : 0 : if (taken && TARGET_BRANCH_PREDICTION_HINTS_TAKEN)
14464 : 0 : fputs ("ds ; ", file);
14465 : 0 : else if (!taken && TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN)
14466 : 0 : fputs ("cs ; ", file);
14467 : : }
14468 : 0 : return;
14469 : : }
14470 : :
14471 : : case ';':
14472 : : #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
14473 : : putc (';', file);
14474 : : #endif
14475 : : return;
14476 : :
14477 : 3511 : case '~':
14478 : 3511 : putc (TARGET_AVX2 ? 'i' : 'f', file);
14479 : 3511 : return;
14480 : :
14481 : 1693 : case 'M':
14482 : 1693 : if (TARGET_X32)
14483 : : {
14484 : : /* NB: 32-bit indices in VSIB address are sign-extended
14485 : : to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
14486 : : sign-extended to 0xfffffffff7fa3010 which is invalid
14487 : : address. Add addr32 prefix if there is no base
14488 : : register nor symbol. */
14489 : 40 : bool ok;
14490 : 40 : struct ix86_address parts;
14491 : 40 : ok = ix86_decompose_address (x, &parts);
14492 : 40 : gcc_assert (ok && parts.index == NULL_RTX);
14493 : 40 : if (parts.base == NULL_RTX
14494 : 40 : && (parts.disp == NULL_RTX
14495 : 34 : || !symbolic_operand (parts.disp,
14496 : 34 : GET_MODE (parts.disp))))
14497 : 34 : fputs ("addr32 ", file);
14498 : : }
14499 : 1693 : return;
14500 : :
14501 : 17105 : case '^':
14502 : 20266 : if (Pmode != word_mode)
14503 : 0 : fputs ("addr32 ", file);
14504 : 17105 : return;
14505 : :
14506 : 14710696 : case '!':
14507 : 14710696 : if (ix86_notrack_prefixed_insn_p (current_output_insn))
14508 : 6677 : fputs ("notrack ", file);
14509 : 14710696 : return;
14510 : :
14511 : 1 : default:
14512 : 1 : output_operand_lossage ("invalid operand code '%c'", code);
14513 : : }
14514 : : }
14515 : :
14516 : 142389308 : if (REG_P (x))
14517 : 84908935 : print_reg (x, code, file);
14518 : :
14519 : 57480373 : else if (MEM_P (x))
14520 : : {
14521 : 32917227 : rtx addr = XEXP (x, 0);
14522 : :
14523 : : /* No `byte ptr' prefix for call instructions ... */
14524 : 32917227 : if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
14525 : : {
14526 : 267 : machine_mode mode = GET_MODE (x);
14527 : 267 : const char *size;
14528 : :
14529 : : /* Check for explicit size override codes. */
14530 : 267 : if (code == 'b')
14531 : : size = "BYTE";
14532 : : else if (code == 'w')
14533 : : size = "WORD";
14534 : : else if (code == 'k')
14535 : : size = "DWORD";
14536 : : else if (code == 'q')
14537 : : size = "QWORD";
14538 : : else if (code == 'x')
14539 : : size = "XMMWORD";
14540 : : else if (code == 't')
14541 : : size = "YMMWORD";
14542 : : else if (code == 'g')
14543 : : size = "ZMMWORD";
14544 : 192 : else if (mode == BLKmode)
14545 : : /* ... or BLKmode operands, when not overridden. */
14546 : : size = NULL;
14547 : : else
14548 : 380 : switch (GET_MODE_SIZE (mode))
14549 : : {
14550 : : case 1: size = "BYTE"; break;
14551 : : case 2: size = "WORD"; break;
14552 : : case 4: size = "DWORD"; break;
14553 : : case 8: size = "QWORD"; break;
14554 : : case 12: size = "TBYTE"; break;
14555 : 4 : case 16:
14556 : 4 : if (mode == XFmode)
14557 : : size = "TBYTE";
14558 : : else
14559 : : size = "XMMWORD";
14560 : : break;
14561 : : case 32: size = "YMMWORD"; break;
14562 : : case 64: size = "ZMMWORD"; break;
14563 : 0 : default:
14564 : 0 : gcc_unreachable ();
14565 : : }
14566 : : if (size)
14567 : : {
14568 : 265 : fputs (size, file);
14569 : 265 : fputs (" PTR ", file);
14570 : : }
14571 : : }
14572 : :
14573 : 32917227 : if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
14574 : 0 : output_operand_lossage ("invalid constraints for operand");
14575 : : else
14576 : 32917227 : ix86_print_operand_address_as
14577 : 33415726 : (file, addr, MEM_ADDR_SPACE (x), code == 'p' || code == 'P');
14578 : : }
14579 : :
14580 : 24563146 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == HFmode)
14581 : : {
14582 : 753 : long l = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
14583 : 753 : REAL_MODE_FORMAT (HFmode));
14584 : 753 : if (ASSEMBLER_DIALECT == ASM_ATT)
14585 : 753 : putc ('$', file);
14586 : 753 : fprintf (file, "0x%04x", (unsigned int) l);
14587 : 753 : }
14588 : :
14589 : 24562393 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
14590 : : {
14591 : 21553 : long l;
14592 : :
14593 : 21553 : REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
14594 : :
14595 : 21553 : if (ASSEMBLER_DIALECT == ASM_ATT)
14596 : 21553 : putc ('$', file);
14597 : : /* Sign extend 32bit SFmode immediate to 8 bytes. */
14598 : 21553 : if (code == 'q')
14599 : 355 : fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
14600 : : (unsigned long long) (int) l);
14601 : : else
14602 : 21198 : fprintf (file, "0x%08x", (unsigned int) l);
14603 : : }
14604 : :
14605 : 24540840 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == DFmode)
14606 : : {
14607 : 3554 : long l[2];
14608 : :
14609 : 3554 : REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
14610 : :
14611 : 3554 : if (ASSEMBLER_DIALECT == ASM_ATT)
14612 : 3554 : putc ('$', file);
14613 : 3554 : fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
14614 : 3554 : }
14615 : :
14616 : : /* These float cases don't actually occur as immediate operands. */
14617 : 24537286 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == XFmode)
14618 : : {
14619 : 0 : char dstr[30];
14620 : :
14621 : 0 : real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
14622 : 0 : fputs (dstr, file);
14623 : 0 : }
14624 : :
14625 : : /* Print bcst_mem_operand. */
14626 : 24537286 : else if (GET_CODE (x) == VEC_DUPLICATE)
14627 : : {
14628 : 313 : machine_mode vmode = GET_MODE (x);
14629 : : /* Must be bcst_memory_operand. */
14630 : 313 : gcc_assert (bcst_mem_operand (x, vmode));
14631 : :
14632 : 313 : rtx mem = XEXP (x,0);
14633 : 313 : ix86_print_operand (file, mem, 0);
14634 : :
14635 : 313 : switch (vmode)
14636 : : {
14637 : 28 : case E_V2DImode:
14638 : 28 : case E_V2DFmode:
14639 : 28 : fputs ("{1to2}", file);
14640 : 28 : break;
14641 : 74 : case E_V4SImode:
14642 : 74 : case E_V4SFmode:
14643 : 74 : case E_V4DImode:
14644 : 74 : case E_V4DFmode:
14645 : 74 : fputs ("{1to4}", file);
14646 : 74 : break;
14647 : 93 : case E_V8SImode:
14648 : 93 : case E_V8SFmode:
14649 : 93 : case E_V8DFmode:
14650 : 93 : case E_V8DImode:
14651 : 93 : case E_V8HFmode:
14652 : 93 : fputs ("{1to8}", file);
14653 : 93 : break;
14654 : 110 : case E_V16SFmode:
14655 : 110 : case E_V16SImode:
14656 : 110 : case E_V16HFmode:
14657 : 110 : fputs ("{1to16}", file);
14658 : 110 : break;
14659 : 8 : case E_V32HFmode:
14660 : 8 : fputs ("{1to32}", file);
14661 : 8 : break;
14662 : 0 : default:
14663 : 0 : gcc_unreachable ();
14664 : : }
14665 : : }
14666 : :
14667 : : else
14668 : : {
14669 : : /* We have patterns that allow zero sets of memory, for instance.
14670 : : In 64-bit mode, we should probably support all 8-byte vectors,
14671 : : since we can in fact encode that into an immediate. */
14672 : 24536973 : if (GET_CODE (x) == CONST_VECTOR)
14673 : : {
14674 : 114 : if (x != CONST0_RTX (GET_MODE (x)))
14675 : 2 : output_operand_lossage ("invalid vector immediate");
14676 : 114 : x = const0_rtx;
14677 : : }
14678 : :
14679 : 24536973 : if (code == 'P')
14680 : : {
14681 : 5878408 : if (ix86_force_load_from_GOT_p (x, true))
14682 : : {
14683 : : /* For inline assembly statement, load function address
14684 : : from GOT with 'P' operand modifier to avoid PLT. */
14685 : 4 : x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
14686 : : (TARGET_64BIT
14687 : : ? UNSPEC_GOTPCREL
14688 : : : UNSPEC_GOT));
14689 : 4 : x = gen_rtx_CONST (Pmode, x);
14690 : 4 : x = gen_const_mem (Pmode, x);
14691 : 4 : ix86_print_operand (file, x, 'A');
14692 : 4 : return;
14693 : : }
14694 : : }
14695 : 18658565 : else if (code != 'p')
14696 : : {
14697 : 18658456 : if (CONST_INT_P (x))
14698 : : {
14699 : 15379471 : if (ASSEMBLER_DIALECT == ASM_ATT)
14700 : 15379249 : putc ('$', file);
14701 : : }
14702 : 3278985 : else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
14703 : 9389 : || GET_CODE (x) == LABEL_REF)
14704 : : {
14705 : 3278983 : if (ASSEMBLER_DIALECT == ASM_ATT)
14706 : 3278959 : putc ('$', file);
14707 : : else
14708 : 24 : fputs ("OFFSET FLAT:", file);
14709 : : }
14710 : : }
14711 : 24536969 : if (CONST_INT_P (x))
14712 : 15379557 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
14713 : 9157412 : else if (flag_pic || MACHOPIC_INDIRECT)
14714 : 514183 : output_pic_addr_const (file, x, code);
14715 : : else
14716 : 8643229 : output_addr_const (file, x);
14717 : : }
14718 : : }
14719 : :
14720 : : static bool
14721 : 21214652 : ix86_print_operand_punct_valid_p (unsigned char code)
14722 : : {
14723 : 21214652 : return (code == '*' || code == '+' || code == '&' || code == ';'
14724 : 14727801 : || code == '~' || code == '^' || code == '!');
14725 : : }
14726 : :
14727 : : /* Print a memory operand whose address is ADDR. */
14728 : :
14729 : : static void
14730 : 36454875 : ix86_print_operand_address_as (FILE *file, rtx addr,
14731 : : addr_space_t as, bool raw)
14732 : : {
14733 : 36454875 : struct ix86_address parts;
14734 : 36454875 : rtx base, index, disp;
14735 : 36454875 : int scale;
14736 : 36454875 : int ok;
14737 : 36454875 : bool vsib = false;
14738 : 36454875 : int code = 0;
14739 : :
14740 : 36454875 : if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
14741 : : {
14742 : 1693 : ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
14743 : 1693 : gcc_assert (parts.index == NULL_RTX);
14744 : 1693 : parts.index = XVECEXP (addr, 0, 1);
14745 : 1693 : parts.scale = INTVAL (XVECEXP (addr, 0, 2));
14746 : 1693 : addr = XVECEXP (addr, 0, 0);
14747 : 1693 : vsib = true;
14748 : : }
14749 : 36453182 : else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
14750 : : {
14751 : 3057840 : gcc_assert (TARGET_64BIT);
14752 : 3057840 : ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
14753 : 3057840 : code = 'q';
14754 : : }
14755 : : else
14756 : 33395342 : ok = ix86_decompose_address (addr, &parts);
14757 : :
14758 : 36454875 : gcc_assert (ok);
14759 : :
14760 : 36454875 : base = parts.base;
14761 : 36454875 : index = parts.index;
14762 : 36454875 : disp = parts.disp;
14763 : 36454875 : scale = parts.scale;
14764 : :
14765 : 36454875 : if (ADDR_SPACE_GENERIC_P (as))
14766 : 36175304 : as = parts.seg;
14767 : : else
14768 : 279571 : gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg));
14769 : :
14770 : 36454875 : if (!ADDR_SPACE_GENERIC_P (as) && !raw)
14771 : : {
14772 : 279587 : if (ASSEMBLER_DIALECT == ASM_ATT)
14773 : 279585 : putc ('%', file);
14774 : :
14775 : 279587 : switch (as)
14776 : : {
14777 : 180026 : case ADDR_SPACE_SEG_FS:
14778 : 180026 : fputs ("fs:", file);
14779 : 180026 : break;
14780 : 99561 : case ADDR_SPACE_SEG_GS:
14781 : 99561 : fputs ("gs:", file);
14782 : 99561 : break;
14783 : 0 : default:
14784 : 0 : gcc_unreachable ();
14785 : : }
14786 : : }
14787 : :
14788 : : /* Use one byte shorter RIP relative addressing for 64bit mode. */
14789 : 36454875 : if (TARGET_64BIT && !base && !index && !raw)
14790 : : {
14791 : 5916196 : rtx symbol = disp;
14792 : :
14793 : 5916196 : if (GET_CODE (disp) == CONST
14794 : 2128280 : && GET_CODE (XEXP (disp, 0)) == PLUS
14795 : 2046183 : && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
14796 : 2046183 : symbol = XEXP (XEXP (disp, 0), 0);
14797 : :
14798 : 5916196 : if (GET_CODE (symbol) == LABEL_REF
14799 : 5916196 : || (GET_CODE (symbol) == SYMBOL_REF
14800 : 5658480 : && SYMBOL_REF_TLS_MODEL (symbol) == 0))
14801 : 5657499 : base = pc_rtx;
14802 : : }
14803 : :
14804 : 36454875 : if (!base && !index)
14805 : : {
14806 : : /* Displacement only requires special attention. */
14807 : 597734 : if (CONST_INT_P (disp))
14808 : : {
14809 : 268852 : if (ASSEMBLER_DIALECT == ASM_INTEL && ADDR_SPACE_GENERIC_P (as))
14810 : 1 : fputs ("ds:", file);
14811 : 268852 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
14812 : : }
14813 : : /* Load the external function address via the GOT slot to avoid PLT. */
14814 : 328882 : else if (GET_CODE (disp) == CONST
14815 : 110009 : && GET_CODE (XEXP (disp, 0)) == UNSPEC
14816 : 82336 : && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
14817 : 8226 : || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
14818 : 402992 : && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
14819 : 24 : output_pic_addr_const (file, disp, 0);
14820 : 328858 : else if (flag_pic)
14821 : 112933 : output_pic_addr_const (file, disp, 0);
14822 : : else
14823 : 215925 : output_addr_const (file, disp);
14824 : : }
14825 : : else
14826 : : {
14827 : : /* Print SImode register names to force addr32 prefix. */
14828 : 35857141 : if (SImode_address_operand (addr, VOIDmode))
14829 : : {
14830 : 37 : if (flag_checking)
14831 : : {
14832 : 37 : gcc_assert (TARGET_64BIT);
14833 : 37 : switch (GET_CODE (addr))
14834 : : {
14835 : 0 : case SUBREG:
14836 : 0 : gcc_assert (GET_MODE (addr) == SImode);
14837 : 0 : gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
14838 : : break;
14839 : 37 : case ZERO_EXTEND:
14840 : 37 : case AND:
14841 : 37 : gcc_assert (GET_MODE (addr) == DImode);
14842 : : break;
14843 : 0 : default:
14844 : 0 : gcc_unreachable ();
14845 : : }
14846 : : }
14847 : 37 : gcc_assert (!code);
14848 : : code = 'k';
14849 : : }
14850 : 35857104 : else if (code == 0
14851 : 32801677 : && TARGET_X32
14852 : 483 : && disp
14853 : 411 : && CONST_INT_P (disp)
14854 : 314 : && INTVAL (disp) < -16*1024*1024)
14855 : : {
14856 : : /* X32 runs in 64-bit mode, where displacement, DISP, in
14857 : : address DISP(%r64), is encoded as 32-bit immediate sign-
14858 : : extended from 32-bit to 64-bit. For -0x40000300(%r64),
14859 : : address is %r64 + 0xffffffffbffffd00. When %r64 <
14860 : : 0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
14861 : : which is invalid for x32. The correct address is %r64
14862 : : - 0x40000300 == 0xf7ffdd64. To properly encode
14863 : : -0x40000300(%r64) for x32, we zero-extend negative
14864 : : displacement by forcing addr32 prefix which truncates
14865 : : 0xfffffffff7ffdd64 to 0xf7ffdd64. In theory, we should
14866 : : zero-extend all negative displacements, including -1(%rsp).
14867 : : However, for small negative displacements, sign-extension
14868 : : won't cause overflow. We only zero-extend negative
14869 : : displacements if they < -16*1024*1024, which is also used
14870 : : to check legitimate address displacements for PIC. */
14871 : 38 : code = 'k';
14872 : : }
14873 : :
14874 : : /* Since the upper 32 bits of RSP are always zero for x32,
14875 : : we can encode %esp as %rsp to avoid 0x67 prefix if
14876 : : there is no index register. */
14877 : 978 : if (TARGET_X32 && Pmode == SImode
14878 : 35857546 : && !index && base && REG_P (base) && REGNO (base) == SP_REG)
14879 : : code = 'q';
14880 : :
14881 : 35857141 : if (ASSEMBLER_DIALECT == ASM_ATT)
14882 : : {
14883 : 35856825 : if (disp)
14884 : : {
14885 : 31885266 : if (flag_pic)
14886 : 2777048 : output_pic_addr_const (file, disp, 0);
14887 : 29108218 : else if (GET_CODE (disp) == LABEL_REF)
14888 : 8143 : output_asm_label (disp);
14889 : : else
14890 : 29100075 : output_addr_const (file, disp);
14891 : : }
14892 : :
14893 : 35856825 : putc ('(', file);
14894 : 35856825 : if (base)
14895 : 35443253 : print_reg (base, code, file);
14896 : 35856825 : if (index)
14897 : : {
14898 : 1874110 : putc (',', file);
14899 : 3746575 : print_reg (index, vsib ? 0 : code, file);
14900 : 1874110 : if (scale != 1 || vsib)
14901 : 1013793 : fprintf (file, ",%d", scale);
14902 : : }
14903 : 35856825 : putc (')', file);
14904 : : }
14905 : : else
14906 : : {
14907 : 316 : rtx offset = NULL_RTX;
14908 : :
14909 : 316 : if (disp)
14910 : : {
14911 : : /* Pull out the offset of a symbol; print any symbol itself. */
14912 : 257 : if (GET_CODE (disp) == CONST
14913 : 19 : && GET_CODE (XEXP (disp, 0)) == PLUS
14914 : 19 : && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
14915 : : {
14916 : 19 : offset = XEXP (XEXP (disp, 0), 1);
14917 : 19 : disp = gen_rtx_CONST (VOIDmode,
14918 : : XEXP (XEXP (disp, 0), 0));
14919 : : }
14920 : :
14921 : 257 : if (flag_pic)
14922 : 0 : output_pic_addr_const (file, disp, 0);
14923 : 257 : else if (GET_CODE (disp) == LABEL_REF)
14924 : 0 : output_asm_label (disp);
14925 : 257 : else if (CONST_INT_P (disp))
14926 : : offset = disp;
14927 : : else
14928 : 123 : output_addr_const (file, disp);
14929 : : }
14930 : :
14931 : 316 : putc ('[', file);
14932 : 316 : if (base)
14933 : : {
14934 : 273 : print_reg (base, code, file);
14935 : 273 : if (offset)
14936 : : {
14937 : 153 : if (INTVAL (offset) >= 0)
14938 : 19 : putc ('+', file);
14939 : 153 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
14940 : : }
14941 : : }
14942 : 43 : else if (offset)
14943 : 0 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
14944 : : else
14945 : 43 : putc ('0', file);
14946 : :
14947 : 316 : if (index)
14948 : : {
14949 : 96 : putc ('+', file);
14950 : 144 : print_reg (index, vsib ? 0 : code, file);
14951 : 96 : if (scale != 1 || vsib)
14952 : 94 : fprintf (file, "*%d", scale);
14953 : : }
14954 : 316 : putc (']', file);
14955 : : }
14956 : : }
14957 : 36454875 : }
14958 : :
14959 : : static void
14960 : 3537649 : ix86_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
14961 : : {
14962 : 3537649 : if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
14963 : 1 : output_operand_lossage ("invalid constraints for operand");
14964 : : else
14965 : 3537648 : ix86_print_operand_address_as (file, addr, ADDR_SPACE_GENERIC, false);
14966 : 3537649 : }
14967 : :
14968 : : /* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
14969 : :
14970 : : static bool
14971 : 13775 : i386_asm_output_addr_const_extra (FILE *file, rtx x)
14972 : : {
14973 : 13775 : rtx op;
14974 : :
14975 : 13775 : if (GET_CODE (x) != UNSPEC)
14976 : : return false;
14977 : :
14978 : 13775 : op = XVECEXP (x, 0, 0);
14979 : 13775 : switch (XINT (x, 1))
14980 : : {
14981 : 1272 : case UNSPEC_GOTOFF:
14982 : 1272 : output_addr_const (file, op);
14983 : 1272 : fputs ("@gotoff", file);
14984 : 1272 : break;
14985 : 0 : case UNSPEC_GOTTPOFF:
14986 : 0 : output_addr_const (file, op);
14987 : : /* FIXME: This might be @TPOFF in Sun ld. */
14988 : 0 : fputs ("@gottpoff", file);
14989 : 0 : break;
14990 : 0 : case UNSPEC_TPOFF:
14991 : 0 : output_addr_const (file, op);
14992 : 0 : fputs ("@tpoff", file);
14993 : 0 : break;
14994 : 10301 : case UNSPEC_NTPOFF:
14995 : 10301 : output_addr_const (file, op);
14996 : 10301 : if (TARGET_64BIT)
14997 : 9573 : fputs ("@tpoff", file);
14998 : : else
14999 : 728 : fputs ("@ntpoff", file);
15000 : : break;
15001 : 30 : case UNSPEC_DTPOFF:
15002 : 30 : output_addr_const (file, op);
15003 : 30 : fputs ("@dtpoff", file);
15004 : 30 : break;
15005 : 2171 : case UNSPEC_GOTNTPOFF:
15006 : 2171 : output_addr_const (file, op);
15007 : 2171 : if (TARGET_64BIT)
15008 : 2171 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
15009 : : "@gottpoff(%rip)" : "@gottpoff[rip]", file);
15010 : : else
15011 : 0 : fputs ("@gotntpoff", file);
15012 : : break;
15013 : 1 : case UNSPEC_INDNTPOFF:
15014 : 1 : output_addr_const (file, op);
15015 : 1 : fputs ("@indntpoff", file);
15016 : 1 : break;
15017 : 0 : case UNSPEC_SECREL32:
15018 : 0 : output_addr_const (file, op);
15019 : 0 : fputs ("@secrel32", file);
15020 : 0 : break;
15021 : : #if TARGET_MACHO
15022 : : case UNSPEC_MACHOPIC_OFFSET:
15023 : : output_addr_const (file, op);
15024 : : putc ('-', file);
15025 : : machopic_output_function_base_name (file);
15026 : : break;
15027 : : #endif
15028 : :
15029 : : default:
15030 : : return false;
15031 : : }
15032 : :
15033 : : return true;
15034 : : }
15035 : :
15036 : :
15037 : : /* Output code to perform a 387 binary operation in INSN, one of PLUS,
15038 : : MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
15039 : : is the expression of the binary operation. The output may either be
15040 : : emitted here, or returned to the caller, like all output_* functions.
15041 : :
15042 : : There is no guarantee that the operands are the same mode, as they
15043 : : might be within FLOAT or FLOAT_EXTEND expressions. */
15044 : :
15045 : : #ifndef SYSV386_COMPAT
15046 : : /* Set to 1 for compatibility with brain-damaged assemblers. No-one
15047 : : wants to fix the assemblers because that causes incompatibility
15048 : : with gcc. No-one wants to fix gcc because that causes
15049 : : incompatibility with assemblers... You can use the option of
15050 : : -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way. */
15051 : : #define SYSV386_COMPAT 1
15052 : : #endif
15053 : :
15054 : : const char *
15055 : 606410 : output_387_binary_op (rtx_insn *insn, rtx *operands)
15056 : : {
15057 : 606410 : static char buf[40];
15058 : 606410 : const char *p;
15059 : 606410 : bool is_sse
15060 : 606410 : = (SSE_REG_P (operands[0])
15061 : 661483 : || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]));
15062 : :
15063 : 55073 : if (is_sse)
15064 : : p = "%v";
15065 : 55073 : else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
15066 : 55066 : || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
15067 : : p = "fi";
15068 : : else
15069 : 606410 : p = "f";
15070 : :
15071 : 606410 : strcpy (buf, p);
15072 : :
15073 : 606410 : switch (GET_CODE (operands[3]))
15074 : : {
15075 : : case PLUS:
15076 : : p = "add"; break;
15077 : : case MINUS:
15078 : : p = "sub"; break;
15079 : 95101 : case MULT:
15080 : 95101 : p = "mul"; break;
15081 : 27877 : case DIV:
15082 : 27877 : p = "div"; break;
15083 : 0 : default:
15084 : 0 : gcc_unreachable ();
15085 : : }
15086 : :
15087 : 606410 : strcat (buf, p);
15088 : :
15089 : 606410 : if (is_sse)
15090 : : {
15091 : 551337 : p = GET_MODE (operands[0]) == SFmode ? "ss" : "sd";
15092 : 551337 : strcat (buf, p);
15093 : :
15094 : 551337 : if (TARGET_AVX)
15095 : : p = "\t{%2, %1, %0|%0, %1, %2}";
15096 : : else
15097 : 533164 : p = "\t{%2, %0|%0, %2}";
15098 : :
15099 : 551337 : strcat (buf, p);
15100 : 551337 : return buf;
15101 : : }
15102 : :
15103 : : /* Even if we do not want to check the inputs, this documents input
15104 : : constraints. Which helps in understanding the following code. */
15105 : 55073 : if (flag_checking)
15106 : : {
15107 : 55072 : if (STACK_REG_P (operands[0])
15108 : 55072 : && ((REG_P (operands[1])
15109 : 53472 : && REGNO (operands[0]) == REGNO (operands[1])
15110 : 49381 : && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
15111 : 5691 : || (REG_P (operands[2])
15112 : 5691 : && REGNO (operands[0]) == REGNO (operands[2])
15113 : 5691 : && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
15114 : 110144 : && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
15115 : : ; /* ok */
15116 : : else
15117 : 0 : gcc_unreachable ();
15118 : : }
15119 : :
15120 : 55073 : switch (GET_CODE (operands[3]))
15121 : : {
15122 : 40417 : case MULT:
15123 : 40417 : case PLUS:
15124 : 40417 : if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
15125 : 2007 : std::swap (operands[1], operands[2]);
15126 : :
15127 : : /* know operands[0] == operands[1]. */
15128 : :
15129 : 40417 : if (MEM_P (operands[2]))
15130 : : {
15131 : : p = "%Z2\t%2";
15132 : : break;
15133 : : }
15134 : :
15135 : 36119 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
15136 : : {
15137 : 21118 : if (STACK_TOP_P (operands[0]))
15138 : : /* How is it that we are storing to a dead operand[2]?
15139 : : Well, presumably operands[1] is dead too. We can't
15140 : : store the result to st(0) as st(0) gets popped on this
15141 : : instruction. Instead store to operands[2] (which I
15142 : : think has to be st(1)). st(1) will be popped later.
15143 : : gcc <= 2.8.1 didn't have this check and generated
15144 : : assembly code that the Unixware assembler rejected. */
15145 : : p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
15146 : : else
15147 : : p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
15148 : : break;
15149 : : }
15150 : :
15151 : 15001 : if (STACK_TOP_P (operands[0]))
15152 : : p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
15153 : : else
15154 : : p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
15155 : : break;
15156 : :
15157 : 14656 : case MINUS:
15158 : 14656 : case DIV:
15159 : 14656 : if (MEM_P (operands[1]))
15160 : : {
15161 : : p = "r%Z1\t%1";
15162 : : break;
15163 : : }
15164 : :
15165 : 14218 : if (MEM_P (operands[2]))
15166 : : {
15167 : : p = "%Z2\t%2";
15168 : : break;
15169 : : }
15170 : :
15171 : 12713 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
15172 : : {
15173 : : #if SYSV386_COMPAT
15174 : : /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
15175 : : derived assemblers, confusingly reverse the direction of
15176 : : the operation for fsub{r} and fdiv{r} when the
15177 : : destination register is not st(0). The Intel assembler
15178 : : doesn't have this brain damage. Read !SYSV386_COMPAT to
15179 : : figure out what the hardware really does. */
15180 : 6048 : if (STACK_TOP_P (operands[0]))
15181 : : p = "{p\t%0, %2|rp\t%2, %0}";
15182 : : else
15183 : : p = "{rp\t%2, %0|p\t%0, %2}";
15184 : : #else
15185 : : if (STACK_TOP_P (operands[0]))
15186 : : /* As above for fmul/fadd, we can't store to st(0). */
15187 : : p = "rp\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
15188 : : else
15189 : : p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
15190 : : #endif
15191 : : break;
15192 : : }
15193 : :
15194 : 6665 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
15195 : : {
15196 : : #if SYSV386_COMPAT
15197 : 3147 : if (STACK_TOP_P (operands[0]))
15198 : : p = "{rp\t%0, %1|p\t%1, %0}";
15199 : : else
15200 : : p = "{p\t%1, %0|rp\t%0, %1}";
15201 : : #else
15202 : : if (STACK_TOP_P (operands[0]))
15203 : : p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
15204 : : else
15205 : : p = "rp\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2); pop */
15206 : : #endif
15207 : : break;
15208 : : }
15209 : :
15210 : 3518 : if (STACK_TOP_P (operands[0]))
15211 : : {
15212 : 2679 : if (STACK_TOP_P (operands[1]))
15213 : : p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
15214 : : else
15215 : : p = "r\t{%y1, %0|%0, %y1}"; /* st(0) = st(r1) op st(0) */
15216 : : break;
15217 : : }
15218 : 839 : else if (STACK_TOP_P (operands[1]))
15219 : : {
15220 : : #if SYSV386_COMPAT
15221 : : p = "{\t%1, %0|r\t%0, %1}";
15222 : : #else
15223 : : p = "r\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2) */
15224 : : #endif
15225 : : }
15226 : : else
15227 : : {
15228 : : #if SYSV386_COMPAT
15229 : : p = "{r\t%2, %0|\t%0, %2}";
15230 : : #else
15231 : : p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
15232 : : #endif
15233 : : }
15234 : : break;
15235 : :
15236 : 0 : default:
15237 : 0 : gcc_unreachable ();
15238 : : }
15239 : :
15240 : 55073 : strcat (buf, p);
15241 : 55073 : return buf;
15242 : : }
15243 : :
15244 : : /* Return needed mode for entity in optimize_mode_switching pass. */
15245 : :
15246 : : static int
15247 : 1637 : ix86_dirflag_mode_needed (rtx_insn *insn)
15248 : : {
15249 : 1637 : if (CALL_P (insn))
15250 : : {
15251 : 337 : if (cfun->machine->func_type == TYPE_NORMAL)
15252 : : return X86_DIRFLAG_ANY;
15253 : : else
15254 : : /* No need to emit CLD in interrupt handler for TARGET_CLD. */
15255 : 337 : return TARGET_CLD ? X86_DIRFLAG_ANY : X86_DIRFLAG_RESET;
15256 : : }
15257 : :
15258 : 1300 : if (recog_memoized (insn) < 0)
15259 : : return X86_DIRFLAG_ANY;
15260 : :
15261 : 1298 : if (get_attr_type (insn) == TYPE_STR)
15262 : : {
15263 : : /* Emit cld instruction if stringops are used in the function. */
15264 : 1 : if (cfun->machine->func_type == TYPE_NORMAL)
15265 : 0 : return TARGET_CLD ? X86_DIRFLAG_RESET : X86_DIRFLAG_ANY;
15266 : : else
15267 : : return X86_DIRFLAG_RESET;
15268 : : }
15269 : :
15270 : : return X86_DIRFLAG_ANY;
15271 : : }
15272 : :
15273 : : /* Check if a 256bit or 512 bit AVX register is referenced inside of EXP. */
15274 : :
15275 : : static bool
15276 : 2138818 : ix86_check_avx_upper_register (const_rtx exp)
15277 : : {
15278 : : /* construct_container may return a parallel with expr_list
15279 : : which contains the real reg and mode */
15280 : 2138818 : subrtx_iterator::array_type array;
15281 : 8144917 : FOR_EACH_SUBRTX (iter, array, exp, NONCONST)
15282 : : {
15283 : 6162468 : const_rtx x = *iter;
15284 : 2484524 : if (SSE_REG_P (x)
15285 : 806856 : && !EXT_REX_SSE_REG_P (x)
15286 : 7764342 : && GET_MODE_BITSIZE (GET_MODE (x)) > 128)
15287 : 156369 : return true;
15288 : : }
15289 : :
15290 : 1982449 : return false;
15291 : 2138818 : }
15292 : :
15293 : : /* Check if a 256bit or 512bit AVX register is referenced in stores. */
15294 : :
15295 : : static void
15296 : 48714 : ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
15297 : : {
15298 : 48714 : if (SSE_REG_P (dest)
15299 : 12479 : && !EXT_REX_SSE_REG_P (dest)
15300 : 73672 : && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
15301 : : {
15302 : 724 : bool *used = (bool *) data;
15303 : 724 : *used = true;
15304 : : }
15305 : 48714 : }
15306 : :
15307 : : /* Return needed mode for entity in optimize_mode_switching pass. */
15308 : :
15309 : : static int
15310 : 2007203 : ix86_avx_u128_mode_needed (rtx_insn *insn)
15311 : : {
15312 : 2007203 : if (DEBUG_INSN_P (insn))
15313 : : return AVX_U128_ANY;
15314 : :
15315 : 2007203 : if (CALL_P (insn))
15316 : : {
15317 : 46754 : rtx link;
15318 : :
15319 : : /* Needed mode is set to AVX_U128_CLEAN if there are
15320 : : no 256bit or 512bit modes used in function arguments. */
15321 : 46754 : for (link = CALL_INSN_FUNCTION_USAGE (insn);
15322 : 118940 : link;
15323 : 72186 : link = XEXP (link, 1))
15324 : : {
15325 : 73227 : if (GET_CODE (XEXP (link, 0)) == USE)
15326 : : {
15327 : 71839 : rtx arg = XEXP (XEXP (link, 0), 0);
15328 : :
15329 : 71839 : if (ix86_check_avx_upper_register (arg))
15330 : : return AVX_U128_DIRTY;
15331 : : }
15332 : : }
15333 : :
15334 : : /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit
15335 : : nor 512bit registers used in the function return register. */
15336 : 45713 : bool avx_upper_reg_found = false;
15337 : 45713 : note_stores (insn, ix86_check_avx_upper_stores,
15338 : : &avx_upper_reg_found);
15339 : 45713 : if (avx_upper_reg_found)
15340 : : return AVX_U128_DIRTY;
15341 : :
15342 : : /* If the function is known to preserve some SSE registers,
15343 : : RA and previous passes can legitimately rely on that for
15344 : : modes wider than 256 bits. It's only safe to issue a
15345 : : vzeroupper if all SSE registers are clobbered. */
15346 : 45542 : const function_abi &abi = insn_callee_abi (insn);
15347 : 45542 : if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
15348 : : /* Should be safe to issue an vzeroupper before sibling_call_p.
15349 : : Also there not mode_exit for sibling_call, so there could be
15350 : : missing vzeroupper for that. */
15351 : 45542 : || !(SIBLING_CALL_P (insn)
15352 : 44324 : || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
15353 : 44324 : abi.mode_clobbers (V4DImode))))
15354 : 9144 : return AVX_U128_ANY;
15355 : :
15356 : 36398 : return AVX_U128_CLEAN;
15357 : : }
15358 : :
15359 : 1960449 : rtx set = single_set (insn);
15360 : 1960449 : if (set)
15361 : : {
15362 : 1891835 : rtx dest = SET_DEST (set);
15363 : 1891835 : rtx src = SET_SRC (set);
15364 : 1415617 : if (SSE_REG_P (dest)
15365 : 536827 : && !EXT_REX_SSE_REG_P (dest)
15366 : 2953997 : && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
15367 : : {
15368 : : /* This is an YMM/ZMM load. Return AVX_U128_DIRTY if the
15369 : : source isn't zero. */
15370 : 165655 : if (standard_sse_constant_p (src, GET_MODE (dest)) != 1)
15371 : : return AVX_U128_DIRTY;
15372 : : else
15373 : : return AVX_U128_ANY;
15374 : : }
15375 : : else
15376 : : {
15377 : 1726180 : if (ix86_check_avx_upper_register (src))
15378 : : return AVX_U128_DIRTY;
15379 : : }
15380 : :
15381 : : /* This isn't YMM/ZMM load/store. */
15382 : : return AVX_U128_ANY;
15383 : : }
15384 : :
15385 : : /* Require DIRTY mode if a 256bit or 512bit AVX register is referenced.
15386 : : Hardware changes state only when a 256bit register is written to,
15387 : : but we need to prevent the compiler from moving optimal insertion
15388 : : point above eventual read from 256bit or 512 bit register. */
15389 : 68614 : if (ix86_check_avx_upper_register (PATTERN (insn)))
15390 : : return AVX_U128_DIRTY;
15391 : :
15392 : : return AVX_U128_ANY;
15393 : : }
15394 : :
15395 : : /* Return mode that i387 must be switched into
15396 : : prior to the execution of insn. */
15397 : :
15398 : : static int
15399 : 449311 : ix86_i387_mode_needed (int entity, rtx_insn *insn)
15400 : : {
15401 : 449311 : enum attr_i387_cw mode;
15402 : :
15403 : : /* The mode UNINITIALIZED is used to store control word after a
15404 : : function call or ASM pattern. The mode ANY specify that function
15405 : : has no requirements on the control word and make no changes in the
15406 : : bits we are interested in. */
15407 : :
15408 : 449311 : if (CALL_P (insn)
15409 : 449311 : || (NONJUMP_INSN_P (insn)
15410 : 369179 : && (asm_noperands (PATTERN (insn)) >= 0
15411 : 369179 : || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
15412 : 15389 : return I387_CW_UNINITIALIZED;
15413 : :
15414 : 433922 : if (recog_memoized (insn) < 0)
15415 : : return I387_CW_ANY;
15416 : :
15417 : 433032 : mode = get_attr_i387_cw (insn);
15418 : :
15419 : 433032 : switch (entity)
15420 : : {
15421 : 0 : case I387_ROUNDEVEN:
15422 : 0 : if (mode == I387_CW_ROUNDEVEN)
15423 : : return mode;
15424 : : break;
15425 : :
15426 : 427040 : case I387_TRUNC:
15427 : 427040 : if (mode == I387_CW_TRUNC)
15428 : : return mode;
15429 : : break;
15430 : :
15431 : 4573 : case I387_FLOOR:
15432 : 4573 : if (mode == I387_CW_FLOOR)
15433 : : return mode;
15434 : : break;
15435 : :
15436 : 1419 : case I387_CEIL:
15437 : 1419 : if (mode == I387_CW_CEIL)
15438 : : return mode;
15439 : : break;
15440 : :
15441 : 0 : default:
15442 : 0 : gcc_unreachable ();
15443 : : }
15444 : :
15445 : : return I387_CW_ANY;
15446 : : }
15447 : :
15448 : : /* Return mode that entity must be switched into
15449 : : prior to the execution of insn. */
15450 : :
15451 : : static int
15452 : 2458151 : ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
15453 : : {
15454 : 2458151 : switch (entity)
15455 : : {
15456 : 1637 : case X86_DIRFLAG:
15457 : 1637 : return ix86_dirflag_mode_needed (insn);
15458 : 2007203 : case AVX_U128:
15459 : 2007203 : return ix86_avx_u128_mode_needed (insn);
15460 : 449311 : case I387_ROUNDEVEN:
15461 : 449311 : case I387_TRUNC:
15462 : 449311 : case I387_FLOOR:
15463 : 449311 : case I387_CEIL:
15464 : 449311 : return ix86_i387_mode_needed (entity, insn);
15465 : 0 : default:
15466 : 0 : gcc_unreachable ();
15467 : : }
15468 : : return 0;
15469 : : }
15470 : :
15471 : : /* Calculate mode of upper 128bit AVX registers after the insn. */
15472 : :
15473 : : static int
15474 : 2007203 : ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
15475 : : {
15476 : 2007203 : rtx pat = PATTERN (insn);
15477 : :
15478 : 2007203 : if (vzeroupper_pattern (pat, VOIDmode)
15479 : 2007203 : || vzeroall_pattern (pat, VOIDmode))
15480 : 196 : return AVX_U128_CLEAN;
15481 : :
15482 : : /* We know that state is clean after CALL insn if there are no
15483 : : 256bit or 512bit registers used in the function return register. */
15484 : 2007007 : if (CALL_P (insn))
15485 : : {
15486 : 46708 : bool avx_upper_reg_found = false;
15487 : 46708 : note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found);
15488 : :
15489 : 46708 : if (avx_upper_reg_found)
15490 : : return AVX_U128_DIRTY;
15491 : :
15492 : : /* If the function desn't clobber any sse registers or only clobber
15493 : : 128-bit part, Then vzeroupper isn't issued before the function exit.
15494 : : the status not CLEAN but ANY after the function. */
15495 : 46155 : const function_abi &abi = insn_callee_abi (insn);
15496 : 46155 : if (!(SIBLING_CALL_P (insn)
15497 : 44942 : || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
15498 : 44942 : abi.mode_clobbers (V4DImode))))
15499 : 9440 : return AVX_U128_ANY;
15500 : :
15501 : 36715 : return AVX_U128_CLEAN;
15502 : : }
15503 : :
15504 : : /* Otherwise, return current mode. Remember that if insn
15505 : : references AVX 256bit or 512bit registers, the mode was already
15506 : : changed to DIRTY from MODE_NEEDED. */
15507 : : return mode;
15508 : : }
15509 : :
15510 : : /* Return the mode that an insn results in. */
15511 : :
15512 : : static int
15513 : 2457347 : ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
15514 : : {
15515 : 2457347 : switch (entity)
15516 : : {
15517 : : case X86_DIRFLAG:
15518 : : return mode;
15519 : 2007203 : case AVX_U128:
15520 : 2007203 : return ix86_avx_u128_mode_after (mode, insn);
15521 : : case I387_ROUNDEVEN:
15522 : : case I387_TRUNC:
15523 : : case I387_FLOOR:
15524 : : case I387_CEIL:
15525 : : return mode;
15526 : 0 : default:
15527 : 0 : gcc_unreachable ();
15528 : : }
15529 : : }
15530 : :
15531 : : static int
15532 : 118 : ix86_dirflag_mode_entry (void)
15533 : : {
15534 : : /* For TARGET_CLD or in the interrupt handler we can't assume
15535 : : direction flag state at function entry. */
15536 : 118 : if (TARGET_CLD
15537 : 116 : || cfun->machine->func_type != TYPE_NORMAL)
15538 : 118 : return X86_DIRFLAG_ANY;
15539 : :
15540 : : return X86_DIRFLAG_RESET;
15541 : : }
15542 : :
15543 : : static int
15544 : 119240 : ix86_avx_u128_mode_entry (void)
15545 : : {
15546 : 119240 : tree arg;
15547 : :
15548 : : /* Entry mode is set to AVX_U128_DIRTY if there are
15549 : : 256bit or 512bit modes used in function arguments. */
15550 : 300679 : for (arg = DECL_ARGUMENTS (current_function_decl); arg;
15551 : 181439 : arg = TREE_CHAIN (arg))
15552 : : {
15553 : 215292 : rtx incoming = DECL_INCOMING_RTL (arg);
15554 : :
15555 : 215292 : if (incoming && ix86_check_avx_upper_register (incoming))
15556 : : return AVX_U128_DIRTY;
15557 : : }
15558 : :
15559 : : return AVX_U128_CLEAN;
15560 : : }
15561 : :
15562 : : /* Return a mode that ENTITY is assumed to be
15563 : : switched to at function entry. */
15564 : :
15565 : : static int
15566 : 73865 : ix86_mode_entry (int entity)
15567 : : {
15568 : 73865 : switch (entity)
15569 : : {
15570 : 118 : case X86_DIRFLAG:
15571 : 118 : return ix86_dirflag_mode_entry ();
15572 : 72643 : case AVX_U128:
15573 : 72643 : return ix86_avx_u128_mode_entry ();
15574 : : case I387_ROUNDEVEN:
15575 : : case I387_TRUNC:
15576 : : case I387_FLOOR:
15577 : : case I387_CEIL:
15578 : : return I387_CW_ANY;
15579 : 0 : default:
15580 : 0 : gcc_unreachable ();
15581 : : }
15582 : : }
15583 : :
15584 : : static int
15585 : 71450 : ix86_avx_u128_mode_exit (void)
15586 : : {
15587 : 71450 : rtx reg = crtl->return_rtx;
15588 : :
15589 : : /* Exit mode is set to AVX_U128_DIRTY if there are 256bit
15590 : : or 512 bit modes used in the function return register. */
15591 : 71450 : if (reg && ix86_check_avx_upper_register (reg))
15592 : : return AVX_U128_DIRTY;
15593 : :
15594 : : /* Exit mode is set to AVX_U128_DIRTY if there are 256bit or 512bit
15595 : : modes used in function arguments, otherwise return AVX_U128_CLEAN.
15596 : : */
15597 : 46597 : return ix86_avx_u128_mode_entry ();
15598 : : }
15599 : :
15600 : : /* Return a mode that ENTITY is assumed to be
15601 : : switched to at function exit. */
15602 : :
15603 : : static int
15604 : 72527 : ix86_mode_exit (int entity)
15605 : : {
15606 : 72527 : switch (entity)
15607 : : {
15608 : : case X86_DIRFLAG:
15609 : : return X86_DIRFLAG_ANY;
15610 : 71450 : case AVX_U128:
15611 : 71450 : return ix86_avx_u128_mode_exit ();
15612 : 1045 : case I387_ROUNDEVEN:
15613 : 1045 : case I387_TRUNC:
15614 : 1045 : case I387_FLOOR:
15615 : 1045 : case I387_CEIL:
15616 : 1045 : return I387_CW_ANY;
15617 : 0 : default:
15618 : 0 : gcc_unreachable ();
15619 : : }
15620 : : }
15621 : :
15622 : : static int
15623 : 2159425 : ix86_mode_priority (int, int n)
15624 : : {
15625 : 2159425 : return n;
15626 : : }
15627 : :
15628 : : /* Output code to initialize control word copies used by trunc?f?i and
15629 : : rounding patterns. CURRENT_MODE is set to current control word,
15630 : : while NEW_MODE is set to new control word. */
15631 : :
15632 : : static void
15633 : 3244 : emit_i387_cw_initialization (int mode)
15634 : : {
15635 : 3244 : rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
15636 : 3244 : rtx new_mode;
15637 : :
15638 : 3244 : enum ix86_stack_slot slot;
15639 : :
15640 : 3244 : rtx reg = gen_reg_rtx (HImode);
15641 : :
15642 : 3244 : emit_insn (gen_x86_fnstcw_1 (stored_mode));
15643 : 3244 : emit_move_insn (reg, copy_rtx (stored_mode));
15644 : :
15645 : 3244 : switch (mode)
15646 : : {
15647 : 0 : case I387_CW_ROUNDEVEN:
15648 : : /* round to nearest */
15649 : 0 : emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
15650 : 0 : slot = SLOT_CW_ROUNDEVEN;
15651 : 0 : break;
15652 : :
15653 : 3024 : case I387_CW_TRUNC:
15654 : : /* round toward zero (truncate) */
15655 : 3024 : emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
15656 : 3024 : slot = SLOT_CW_TRUNC;
15657 : 3024 : break;
15658 : :
15659 : 153 : case I387_CW_FLOOR:
15660 : : /* round down toward -oo */
15661 : 153 : emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
15662 : 153 : emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
15663 : 153 : slot = SLOT_CW_FLOOR;
15664 : 153 : break;
15665 : :
15666 : 67 : case I387_CW_CEIL:
15667 : : /* round up toward +oo */
15668 : 67 : emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
15669 : 67 : emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
15670 : 67 : slot = SLOT_CW_CEIL;
15671 : 67 : break;
15672 : :
15673 : 0 : default:
15674 : 0 : gcc_unreachable ();
15675 : : }
15676 : :
15677 : 3244 : gcc_assert (slot < MAX_386_STACK_LOCALS);
15678 : :
15679 : 3244 : new_mode = assign_386_stack_local (HImode, slot);
15680 : 3244 : emit_move_insn (new_mode, reg);
15681 : 3244 : }
15682 : :
15683 : : /* Generate one or more insns to set ENTITY to MODE. */
15684 : :
15685 : : static void
15686 : 45692 : ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
15687 : : HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
15688 : : {
15689 : 45692 : switch (entity)
15690 : : {
15691 : 263 : case X86_DIRFLAG:
15692 : 263 : if (mode == X86_DIRFLAG_RESET)
15693 : 263 : emit_insn (gen_cld ());
15694 : : break;
15695 : 37285 : case AVX_U128:
15696 : 37285 : if (mode == AVX_U128_CLEAN)
15697 : 18113 : ix86_expand_avx_vzeroupper ();
15698 : : break;
15699 : 8144 : case I387_ROUNDEVEN:
15700 : 8144 : case I387_TRUNC:
15701 : 8144 : case I387_FLOOR:
15702 : 8144 : case I387_CEIL:
15703 : 8144 : if (mode != I387_CW_ANY
15704 : 8144 : && mode != I387_CW_UNINITIALIZED)
15705 : 3244 : emit_i387_cw_initialization (mode);
15706 : : break;
15707 : 0 : default:
15708 : 0 : gcc_unreachable ();
15709 : : }
15710 : 45692 : }
15711 : :
15712 : : /* Output code for INSN to convert a float to a signed int. OPERANDS
15713 : : are the insn operands. The output may be [HSD]Imode and the input
15714 : : operand may be [SDX]Fmode. */
15715 : :
15716 : : const char *
15717 : 7376 : output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
15718 : : {
15719 : 7376 : bool stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
15720 : 7376 : bool dimode_p = GET_MODE (operands[0]) == DImode;
15721 : 7376 : int round_mode = get_attr_i387_cw (insn);
15722 : :
15723 : 7376 : static char buf[40];
15724 : 7376 : const char *p;
15725 : :
15726 : : /* Jump through a hoop or two for DImode, since the hardware has no
15727 : : non-popping instruction. We used to do this a different way, but
15728 : : that was somewhat fragile and broke with post-reload splitters. */
15729 : 7376 : if ((dimode_p || fisttp) && !stack_top_dies)
15730 : 25 : output_asm_insn ("fld\t%y1", operands);
15731 : :
15732 : 7376 : gcc_assert (STACK_TOP_P (operands[1]));
15733 : 7376 : gcc_assert (MEM_P (operands[0]));
15734 : 7376 : gcc_assert (GET_MODE (operands[1]) != TFmode);
15735 : :
15736 : 7376 : if (fisttp)
15737 : : return "fisttp%Z0\t%0";
15738 : :
15739 : 7375 : strcpy (buf, "fist");
15740 : :
15741 : 7375 : if (round_mode != I387_CW_ANY)
15742 : 7327 : output_asm_insn ("fldcw\t%3", operands);
15743 : :
15744 : 7375 : p = "p%Z0\t%0";
15745 : 7375 : strcat (buf, p + !(stack_top_dies || dimode_p));
15746 : :
15747 : 7375 : output_asm_insn (buf, operands);
15748 : :
15749 : 7375 : if (round_mode != I387_CW_ANY)
15750 : 7327 : output_asm_insn ("fldcw\t%2", operands);
15751 : :
15752 : : return "";
15753 : : }
15754 : :
15755 : : /* Output code for x87 ffreep insn. The OPNO argument, which may only
15756 : : have the values zero or one, indicates the ffreep insn's operand
15757 : : from the OPERANDS array. */
15758 : :
15759 : : static const char *
15760 : 282656 : output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
15761 : : {
15762 : 0 : if (TARGET_USE_FFREEP)
15763 : : #ifdef HAVE_AS_IX86_FFREEP
15764 : 0 : return opno ? "ffreep\t%y1" : "ffreep\t%y0";
15765 : : #else
15766 : : {
15767 : : static char retval[32];
15768 : : int regno = REGNO (operands[opno]);
15769 : :
15770 : : gcc_assert (STACK_REGNO_P (regno));
15771 : :
15772 : : regno -= FIRST_STACK_REG;
15773 : :
15774 : : snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
15775 : : return retval;
15776 : : }
15777 : : #endif
15778 : :
15779 : 0 : return opno ? "fstp\t%y1" : "fstp\t%y0";
15780 : : }
15781 : :
15782 : :
15783 : : /* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi
15784 : : should be used. UNORDERED_P is true when fucom should be used. */
15785 : :
15786 : : const char *
15787 : 107809 : output_fp_compare (rtx_insn *insn, rtx *operands,
15788 : : bool eflags_p, bool unordered_p)
15789 : : {
15790 : 107809 : rtx *xops = eflags_p ? &operands[0] : &operands[1];
15791 : 107809 : bool stack_top_dies;
15792 : :
15793 : 107809 : static char buf[40];
15794 : 107809 : const char *p;
15795 : :
15796 : 107809 : gcc_assert (STACK_TOP_P (xops[0]));
15797 : :
15798 : 107809 : stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
15799 : :
15800 : 107809 : if (eflags_p)
15801 : : {
15802 : 107809 : p = unordered_p ? "fucomi" : "fcomi";
15803 : 107809 : strcpy (buf, p);
15804 : :
15805 : 107809 : p = "p\t{%y1, %0|%0, %y1}";
15806 : 107809 : strcat (buf, p + !stack_top_dies);
15807 : :
15808 : 107809 : return buf;
15809 : : }
15810 : :
15811 : 0 : if (STACK_REG_P (xops[1])
15812 : 0 : && stack_top_dies
15813 : 0 : && find_regno_note (insn, REG_DEAD, FIRST_STACK_REG + 1))
15814 : : {
15815 : 0 : gcc_assert (REGNO (xops[1]) == FIRST_STACK_REG + 1);
15816 : :
15817 : : /* If both the top of the 387 stack die, and the other operand
15818 : : is also a stack register that dies, then this must be a
15819 : : `fcompp' float compare. */
15820 : 0 : p = unordered_p ? "fucompp" : "fcompp";
15821 : 0 : strcpy (buf, p);
15822 : : }
15823 : 0 : else if (const0_operand (xops[1], VOIDmode))
15824 : : {
15825 : 0 : gcc_assert (!unordered_p);
15826 : 0 : strcpy (buf, "ftst");
15827 : : }
15828 : : else
15829 : : {
15830 : 0 : if (GET_MODE_CLASS (GET_MODE (xops[1])) == MODE_INT)
15831 : : {
15832 : 0 : gcc_assert (!unordered_p);
15833 : : p = "ficom";
15834 : : }
15835 : : else
15836 : 0 : p = unordered_p ? "fucom" : "fcom";
15837 : :
15838 : 0 : strcpy (buf, p);
15839 : :
15840 : 0 : p = "p%Z2\t%y2";
15841 : 0 : strcat (buf, p + !stack_top_dies);
15842 : : }
15843 : :
15844 : 0 : output_asm_insn (buf, operands);
15845 : 0 : return "fnstsw\t%0";
15846 : : }
15847 : :
15848 : : void
15849 : 162051 : ix86_output_addr_vec_elt (FILE *file, int value)
15850 : : {
15851 : 162051 : const char *directive = ASM_LONG;
15852 : :
15853 : : #ifdef ASM_QUAD
15854 : 162051 : if (TARGET_LP64)
15855 : 150481 : directive = ASM_QUAD;
15856 : : #else
15857 : : gcc_assert (!TARGET_64BIT);
15858 : : #endif
15859 : :
15860 : 162051 : fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
15861 : 162051 : }
15862 : :
15863 : : void
15864 : 22713 : ix86_output_addr_diff_elt (FILE *file, int value, int rel)
15865 : : {
15866 : 22713 : const char *directive = ASM_LONG;
15867 : :
15868 : : #ifdef ASM_QUAD
15869 : 33912 : if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
15870 : : directive = ASM_QUAD;
15871 : : #else
15872 : : gcc_assert (!TARGET_64BIT);
15873 : : #endif
15874 : : /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand. */
15875 : 22713 : if (TARGET_64BIT || TARGET_VXWORKS_VAROFF)
15876 : 11199 : fprintf (file, "%s%s%d-%s%d\n",
15877 : : directive, LPREFIX, value, LPREFIX, rel);
15878 : : #if TARGET_MACHO
15879 : : else if (TARGET_MACHO)
15880 : : {
15881 : : fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
15882 : : machopic_output_function_base_name (file);
15883 : : putc ('\n', file);
15884 : : }
15885 : : #endif
15886 : 11514 : else if (HAVE_AS_GOTOFF_IN_DATA)
15887 : 11514 : fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
15888 : : else
15889 : : asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
15890 : : GOT_SYMBOL_NAME, LPREFIX, value);
15891 : 22713 : }
15892 : :
15893 : : #define LEA_MAX_STALL (3)
15894 : : #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
15895 : :
15896 : : /* Increase given DISTANCE in half-cycles according to
15897 : : dependencies between PREV and NEXT instructions.
15898 : : Add 1 half-cycle if there is no dependency and
15899 : : go to next cycle if there is some dependecy. */
15900 : :
15901 : : static unsigned int
15902 : 2144 : increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
15903 : : {
15904 : 2144 : df_ref def, use;
15905 : :
15906 : 2144 : if (!prev || !next)
15907 : 758 : return distance + (distance & 1) + 2;
15908 : :
15909 : 1386 : if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
15910 : 225 : return distance + 1;
15911 : :
15912 : 1932 : FOR_EACH_INSN_USE (use, next)
15913 : 2461 : FOR_EACH_INSN_DEF (def, prev)
15914 : 1690 : if (!DF_REF_IS_ARTIFICIAL (def)
15915 : 1690 : && DF_REF_REGNO (use) == DF_REF_REGNO (def))
15916 : 737 : return distance + (distance & 1) + 2;
15917 : :
15918 : 424 : return distance + 1;
15919 : : }
15920 : :
15921 : : /* Function checks if instruction INSN defines register number
15922 : : REGNO1 or REGNO2. */
15923 : :
15924 : : bool
15925 : 2091 : insn_defines_reg (unsigned int regno1, unsigned int regno2,
15926 : : rtx_insn *insn)
15927 : : {
15928 : 2091 : df_ref def;
15929 : :
15930 : 3783 : FOR_EACH_INSN_DEF (def, insn)
15931 : 2090 : if (DF_REF_REG_DEF_P (def)
15932 : 2090 : && !DF_REF_IS_ARTIFICIAL (def)
15933 : 2090 : && (regno1 == DF_REF_REGNO (def)
15934 : 1706 : || regno2 == DF_REF_REGNO (def)))
15935 : : return true;
15936 : :
15937 : : return false;
15938 : : }
15939 : :
15940 : : /* Function checks if instruction INSN uses register number
15941 : : REGNO as a part of address expression. */
15942 : :
15943 : : static bool
15944 : 1190 : insn_uses_reg_mem (unsigned int regno, rtx insn)
15945 : : {
15946 : 1190 : df_ref use;
15947 : :
15948 : 2500 : FOR_EACH_INSN_USE (use, insn)
15949 : 1398 : if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
15950 : : return true;
15951 : :
15952 : : return false;
15953 : : }
15954 : :
15955 : : /* Search backward for non-agu definition of register number REGNO1
15956 : : or register number REGNO2 in basic block starting from instruction
15957 : : START up to head of basic block or instruction INSN.
15958 : :
15959 : : Function puts true value into *FOUND var if definition was found
15960 : : and false otherwise.
15961 : :
15962 : : Distance in half-cycles between START and found instruction or head
15963 : : of BB is added to DISTANCE and returned. */
15964 : :
15965 : : static int
15966 : 625 : distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
15967 : : rtx_insn *insn, int distance,
15968 : : rtx_insn *start, bool *found)
15969 : : {
15970 : 625 : basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
15971 : 625 : rtx_insn *prev = start;
15972 : 625 : rtx_insn *next = NULL;
15973 : :
15974 : 625 : *found = false;
15975 : :
15976 : 625 : while (prev
15977 : 1877 : && prev != insn
15978 : 1877 : && distance < LEA_SEARCH_THRESHOLD)
15979 : : {
15980 : 1673 : if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
15981 : : {
15982 : 954 : distance = increase_distance (prev, next, distance);
15983 : 954 : if (insn_defines_reg (regno1, regno2, prev))
15984 : : {
15985 : 236 : if (recog_memoized (prev) < 0
15986 : 236 : || get_attr_type (prev) != TYPE_LEA)
15987 : : {
15988 : 200 : *found = true;
15989 : 200 : return distance;
15990 : : }
15991 : : }
15992 : :
15993 : : next = prev;
15994 : : }
15995 : 1473 : if (prev == BB_HEAD (bb))
15996 : : break;
15997 : :
15998 : 1252 : prev = PREV_INSN (prev);
15999 : : }
16000 : :
16001 : : return distance;
16002 : : }
16003 : :
16004 : : /* Search backward for non-agu definition of register number REGNO1
16005 : : or register number REGNO2 in INSN's basic block until
16006 : : 1. Pass LEA_SEARCH_THRESHOLD instructions, or
16007 : : 2. Reach neighbor BBs boundary, or
16008 : : 3. Reach agu definition.
16009 : : Returns the distance between the non-agu definition point and INSN.
16010 : : If no definition point, returns -1. */
16011 : :
16012 : : static int
16013 : 428 : distance_non_agu_define (unsigned int regno1, unsigned int regno2,
16014 : : rtx_insn *insn)
16015 : : {
16016 : 428 : basic_block bb = BLOCK_FOR_INSN (insn);
16017 : 428 : int distance = 0;
16018 : 428 : bool found = false;
16019 : :
16020 : 428 : if (insn != BB_HEAD (bb))
16021 : 428 : distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
16022 : : distance, PREV_INSN (insn),
16023 : : &found);
16024 : :
16025 : 428 : if (!found && distance < LEA_SEARCH_THRESHOLD)
16026 : : {
16027 : 166 : edge e;
16028 : 166 : edge_iterator ei;
16029 : 166 : bool simple_loop = false;
16030 : :
16031 : 337 : FOR_EACH_EDGE (e, ei, bb->preds)
16032 : 208 : if (e->src == bb)
16033 : : {
16034 : : simple_loop = true;
16035 : : break;
16036 : : }
16037 : :
16038 : 166 : if (simple_loop)
16039 : 37 : distance = distance_non_agu_define_in_bb (regno1, regno2,
16040 : : insn, distance,
16041 : 37 : BB_END (bb), &found);
16042 : : else
16043 : : {
16044 : 129 : int shortest_dist = -1;
16045 : 129 : bool found_in_bb = false;
16046 : :
16047 : 289 : FOR_EACH_EDGE (e, ei, bb->preds)
16048 : : {
16049 : 160 : int bb_dist
16050 : 320 : = distance_non_agu_define_in_bb (regno1, regno2,
16051 : : insn, distance,
16052 : 160 : BB_END (e->src),
16053 : : &found_in_bb);
16054 : 160 : if (found_in_bb)
16055 : : {
16056 : 24 : if (shortest_dist < 0)
16057 : : shortest_dist = bb_dist;
16058 : 0 : else if (bb_dist > 0)
16059 : 0 : shortest_dist = MIN (bb_dist, shortest_dist);
16060 : :
16061 : 24 : found = true;
16062 : : }
16063 : : }
16064 : :
16065 : 129 : distance = shortest_dist;
16066 : : }
16067 : : }
16068 : :
16069 : 428 : if (!found)
16070 : : return -1;
16071 : :
16072 : 200 : return distance >> 1;
16073 : : }
16074 : :
16075 : : /* Return the distance in half-cycles between INSN and the next
16076 : : insn that uses register number REGNO in memory address added
16077 : : to DISTANCE. Return -1 if REGNO0 is set.
16078 : :
16079 : : Put true value into *FOUND if register usage was found and
16080 : : false otherwise.
16081 : : Put true value into *REDEFINED if register redefinition was
16082 : : found and false otherwise. */
16083 : :
16084 : : static int
16085 : 764 : distance_agu_use_in_bb (unsigned int regno,
16086 : : rtx_insn *insn, int distance, rtx_insn *start,
16087 : : bool *found, bool *redefined)
16088 : : {
16089 : 764 : basic_block bb = NULL;
16090 : 764 : rtx_insn *next = start;
16091 : 764 : rtx_insn *prev = NULL;
16092 : :
16093 : 764 : *found = false;
16094 : 764 : *redefined = false;
16095 : :
16096 : 764 : if (start != NULL_RTX)
16097 : : {
16098 : 747 : bb = BLOCK_FOR_INSN (start);
16099 : 747 : if (start != BB_HEAD (bb))
16100 : : /* If insn and start belong to the same bb, set prev to insn,
16101 : : so the call to increase_distance will increase the distance
16102 : : between insns by 1. */
16103 : 407 : prev = insn;
16104 : : }
16105 : :
16106 : 2578 : while (next
16107 : 2578 : && next != insn
16108 : 2578 : && distance < LEA_SEARCH_THRESHOLD)
16109 : : {
16110 : 2381 : if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
16111 : : {
16112 : 1190 : distance = increase_distance(prev, next, distance);
16113 : 1190 : if (insn_uses_reg_mem (regno, next))
16114 : : {
16115 : : /* Return DISTANCE if OP0 is used in memory
16116 : : address in NEXT. */
16117 : 88 : *found = true;
16118 : 88 : return distance;
16119 : : }
16120 : :
16121 : 1102 : if (insn_defines_reg (regno, INVALID_REGNUM, next))
16122 : : {
16123 : : /* Return -1 if OP0 is set in NEXT. */
16124 : 157 : *redefined = true;
16125 : 157 : return -1;
16126 : : }
16127 : :
16128 : : prev = next;
16129 : : }
16130 : :
16131 : 2136 : if (next == BB_END (bb))
16132 : : break;
16133 : :
16134 : 1814 : next = NEXT_INSN (next);
16135 : : }
16136 : :
16137 : : return distance;
16138 : : }
16139 : :
16140 : : /* Return the distance between INSN and the next insn that uses
16141 : : register number REGNO0 in memory address. Return -1 if no such
16142 : : a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set. */
16143 : :
16144 : : static int
16145 : 428 : distance_agu_use (unsigned int regno0, rtx_insn *insn)
16146 : : {
16147 : 428 : basic_block bb = BLOCK_FOR_INSN (insn);
16148 : 428 : int distance = 0;
16149 : 428 : bool found = false;
16150 : 428 : bool redefined = false;
16151 : :
16152 : 428 : if (insn != BB_END (bb))
16153 : 407 : distance = distance_agu_use_in_bb (regno0, insn, distance,
16154 : : NEXT_INSN (insn),
16155 : : &found, &redefined);
16156 : :
16157 : 428 : if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
16158 : : {
16159 : 249 : edge e;
16160 : 249 : edge_iterator ei;
16161 : 249 : bool simple_loop = false;
16162 : :
16163 : 536 : FOR_EACH_EDGE (e, ei, bb->succs)
16164 : 357 : if (e->dest == bb)
16165 : : {
16166 : : simple_loop = true;
16167 : : break;
16168 : : }
16169 : :
16170 : 249 : if (simple_loop)
16171 : 70 : distance = distance_agu_use_in_bb (regno0, insn,
16172 : : distance, BB_HEAD (bb),
16173 : : &found, &redefined);
16174 : : else
16175 : : {
16176 : 179 : int shortest_dist = -1;
16177 : 179 : bool found_in_bb = false;
16178 : 179 : bool redefined_in_bb = false;
16179 : :
16180 : 466 : FOR_EACH_EDGE (e, ei, bb->succs)
16181 : : {
16182 : 287 : int bb_dist
16183 : 574 : = distance_agu_use_in_bb (regno0, insn,
16184 : 287 : distance, BB_HEAD (e->dest),
16185 : : &found_in_bb, &redefined_in_bb);
16186 : 287 : if (found_in_bb)
16187 : : {
16188 : 17 : if (shortest_dist < 0)
16189 : : shortest_dist = bb_dist;
16190 : 2 : else if (bb_dist > 0)
16191 : 2 : shortest_dist = MIN (bb_dist, shortest_dist);
16192 : :
16193 : 17 : found = true;
16194 : : }
16195 : : }
16196 : :
16197 : 179 : distance = shortest_dist;
16198 : : }
16199 : : }
16200 : :
16201 : 428 : if (!found || redefined)
16202 : : return -1;
16203 : :
16204 : 86 : return distance >> 1;
16205 : : }
16206 : :
16207 : : /* Define this macro to tune LEA priority vs ADD, it take effect when
16208 : : there is a dilemma of choosing LEA or ADD
16209 : : Negative value: ADD is more preferred than LEA
16210 : : Zero: Neutral
16211 : : Positive value: LEA is more preferred than ADD. */
16212 : : #define IX86_LEA_PRIORITY 0
16213 : :
16214 : : /* Return true if usage of lea INSN has performance advantage
16215 : : over a sequence of instructions. Instructions sequence has
16216 : : SPLIT_COST cycles higher latency than lea latency. */
16217 : :
16218 : : static bool
16219 : 1624 : ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
16220 : : unsigned int regno2, int split_cost, bool has_scale)
16221 : : {
16222 : 1624 : int dist_define, dist_use;
16223 : :
16224 : : /* For Atom processors newer than Bonnell, if using a 2-source or
16225 : : 3-source LEA for non-destructive destination purposes, or due to
16226 : : wanting ability to use SCALE, the use of LEA is justified. */
16227 : 1624 : if (!TARGET_CPU_P (BONNELL))
16228 : : {
16229 : 1196 : if (has_scale)
16230 : : return true;
16231 : 1177 : if (split_cost < 1)
16232 : : return false;
16233 : 406 : if (regno0 == regno1 || regno0 == regno2)
16234 : : return false;
16235 : : return true;
16236 : : }
16237 : :
16238 : : /* Remember recog_data content. */
16239 : 428 : struct recog_data_d recog_data_save = recog_data;
16240 : :
16241 : 428 : dist_define = distance_non_agu_define (regno1, regno2, insn);
16242 : 428 : dist_use = distance_agu_use (regno0, insn);
16243 : :
16244 : : /* distance_non_agu_define can call get_attr_type which can call
16245 : : recog_memoized, restore recog_data back to previous content. */
16246 : 428 : recog_data = recog_data_save;
16247 : :
16248 : 428 : if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
16249 : : {
16250 : : /* If there is no non AGU operand definition, no AGU
16251 : : operand usage and split cost is 0 then both lea
16252 : : and non lea variants have same priority. Currently
16253 : : we prefer lea for 64 bit code and non lea on 32 bit
16254 : : code. */
16255 : 230 : if (dist_use < 0 && split_cost == 0)
16256 : 100 : return TARGET_64BIT || IX86_LEA_PRIORITY;
16257 : : else
16258 : : return true;
16259 : : }
16260 : :
16261 : : /* With longer definitions distance lea is more preferable.
16262 : : Here we change it to take into account splitting cost and
16263 : : lea priority. */
16264 : 198 : dist_define += split_cost + IX86_LEA_PRIORITY;
16265 : :
16266 : : /* If there is no use in memory addess then we just check
16267 : : that split cost exceeds AGU stall. */
16268 : 198 : if (dist_use < 0)
16269 : 195 : return dist_define > LEA_MAX_STALL;
16270 : :
16271 : : /* If this insn has both backward non-agu dependence and forward
16272 : : agu dependence, the one with short distance takes effect. */
16273 : 3 : return dist_define >= dist_use;
16274 : : }
16275 : :
16276 : : /* Return true if we need to split op0 = op1 + op2 into a sequence of
16277 : : move and add to avoid AGU stalls. */
16278 : :
16279 : : bool
16280 : 8997239 : ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
16281 : : {
16282 : 8997239 : unsigned int regno0, regno1, regno2;
16283 : :
16284 : : /* Check if we need to optimize. */
16285 : 8997239 : if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
16286 : 8996423 : return false;
16287 : :
16288 : 816 : regno0 = true_regnum (operands[0]);
16289 : 816 : regno1 = true_regnum (operands[1]);
16290 : 816 : regno2 = true_regnum (operands[2]);
16291 : :
16292 : : /* We need to split only adds with non destructive
16293 : : destination operand. */
16294 : 816 : if (regno0 == regno1 || regno0 == regno2)
16295 : : return false;
16296 : : else
16297 : 245 : return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
16298 : : }
16299 : :
16300 : : /* Return true if we should emit lea instruction instead of mov
16301 : : instruction. */
16302 : :
16303 : : bool
16304 : 29203303 : ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
16305 : : {
16306 : 29203303 : unsigned int regno0, regno1;
16307 : :
16308 : : /* Check if we need to optimize. */
16309 : 29203303 : if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
16310 : 29201026 : return false;
16311 : :
16312 : : /* Use lea for reg to reg moves only. */
16313 : 2277 : if (!REG_P (operands[0]) || !REG_P (operands[1]))
16314 : : return false;
16315 : :
16316 : 460 : regno0 = true_regnum (operands[0]);
16317 : 460 : regno1 = true_regnum (operands[1]);
16318 : :
16319 : 460 : return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
16320 : : }
16321 : :
16322 : : /* Return true if we need to split lea into a sequence of
16323 : : instructions to avoid AGU stalls during peephole2. */
16324 : :
16325 : : bool
16326 : 11218255 : ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
16327 : : {
16328 : 11218255 : unsigned int regno0, regno1, regno2;
16329 : 11218255 : int split_cost;
16330 : 11218255 : struct ix86_address parts;
16331 : 11218255 : int ok;
16332 : :
16333 : : /* The "at least two components" test below might not catch simple
16334 : : move or zero extension insns if parts.base is non-NULL and parts.disp
16335 : : is const0_rtx as the only components in the address, e.g. if the
16336 : : register is %rbp or %r13. As this test is much cheaper and moves or
16337 : : zero extensions are the common case, do this check first. */
16338 : 11218255 : if (REG_P (operands[1])
16339 : 11218255 : || (SImode_address_operand (operands[1], VOIDmode)
16340 : 146473 : && REG_P (XEXP (operands[1], 0))))
16341 : 4126422 : return false;
16342 : :
16343 : 7091833 : ok = ix86_decompose_address (operands[1], &parts);
16344 : 7091833 : gcc_assert (ok);
16345 : :
16346 : : /* There should be at least two components in the address. */
16347 : 7091833 : if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
16348 : 7091833 : + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
16349 : : return false;
16350 : :
16351 : : /* We should not split into add if non legitimate pic
16352 : : operand is used as displacement. */
16353 : 2686728 : if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
16354 : : return false;
16355 : :
16356 : 2637638 : regno0 = true_regnum (operands[0]) ;
16357 : 2637638 : regno1 = INVALID_REGNUM;
16358 : 2637638 : regno2 = INVALID_REGNUM;
16359 : :
16360 : 2637638 : if (parts.base)
16361 : 2567541 : regno1 = true_regnum (parts.base);
16362 : 2637638 : if (parts.index)
16363 : 470733 : regno2 = true_regnum (parts.index);
16364 : :
16365 : : /* Use add for a = a + b and a = b + a since it is faster and shorter
16366 : : than lea for most processors. For the processors like BONNELL, if
16367 : : the destination register of LEA holds an actual address which will
16368 : : be used soon, LEA is better and otherwise ADD is better. */
16369 : 2637638 : if (!TARGET_CPU_P (BONNELL)
16370 : 2637511 : && parts.scale == 1
16371 : 2401996 : && (!parts.disp || parts.disp == const0_rtx)
16372 : 172359 : && (regno0 == regno1 || regno0 == regno2))
16373 : : return true;
16374 : :
16375 : : /* Split with -Oz if the encoding requires fewer bytes. */
16376 : 2631182 : if (optimize_size > 1
16377 : 27 : && parts.scale > 1
16378 : 4 : && !parts.base
16379 : 4 : && (!parts.disp || parts.disp == const0_rtx))
16380 : : return true;
16381 : :
16382 : : /* Check we need to optimize. */
16383 : 2631178 : if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
16384 : 2630839 : return false;
16385 : :
16386 : 339 : split_cost = 0;
16387 : :
16388 : : /* Compute how many cycles we will add to execution time
16389 : : if split lea into a sequence of instructions. */
16390 : 339 : if (parts.base || parts.index)
16391 : : {
16392 : : /* Have to use mov instruction if non desctructive
16393 : : destination form is used. */
16394 : 339 : if (regno1 != regno0 && regno2 != regno0)
16395 : 259 : split_cost += 1;
16396 : :
16397 : : /* Have to add index to base if both exist. */
16398 : 339 : if (parts.base && parts.index)
16399 : 54 : split_cost += 1;
16400 : :
16401 : : /* Have to use shift and adds if scale is 2 or greater. */
16402 : 339 : if (parts.scale > 1)
16403 : : {
16404 : 29 : if (regno0 != regno1)
16405 : 22 : split_cost += 1;
16406 : 7 : else if (regno2 == regno0)
16407 : 1 : split_cost += 4;
16408 : : else
16409 : 6 : split_cost += parts.scale;
16410 : : }
16411 : :
16412 : : /* Have to use add instruction with immediate if
16413 : : disp is non zero. */
16414 : 339 : if (parts.disp && parts.disp != const0_rtx)
16415 : 278 : split_cost += 1;
16416 : :
16417 : : /* Subtract the price of lea. */
16418 : 339 : split_cost -= 1;
16419 : : }
16420 : :
16421 : 339 : return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
16422 : 339 : parts.scale > 1);
16423 : : }
16424 : :
16425 : : /* Return true if it is ok to optimize an ADD operation to LEA
16426 : : operation to avoid flag register consumation. For most processors,
16427 : : ADD is faster than LEA. For the processors like BONNELL, if the
16428 : : destination register of LEA holds an actual address which will be
16429 : : used soon, LEA is better and otherwise ADD is better. */
16430 : :
16431 : : bool
16432 : 9062794 : ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
16433 : : {
16434 : 9062794 : unsigned int regno0 = true_regnum (operands[0]);
16435 : 9062794 : unsigned int regno1 = true_regnum (operands[1]);
16436 : 9062794 : unsigned int regno2 = true_regnum (operands[2]);
16437 : :
16438 : : /* If a = b + c, (a!=b && a!=c), must use lea form. */
16439 : 9062794 : if (regno0 != regno1 && regno0 != regno2)
16440 : : return true;
16441 : :
16442 : 7031706 : if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
16443 : 7031126 : return false;
16444 : :
16445 : 580 : return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
16446 : : }
16447 : :
16448 : : /* Return true if destination reg of SET_BODY is shift count of
16449 : : USE_BODY. */
16450 : :
16451 : : static bool
16452 : 94 : ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
16453 : : {
16454 : 94 : rtx set_dest;
16455 : 94 : rtx shift_rtx;
16456 : 94 : int i;
16457 : :
16458 : : /* Retrieve destination of SET_BODY. */
16459 : 94 : switch (GET_CODE (set_body))
16460 : : {
16461 : 76 : case SET:
16462 : 76 : set_dest = SET_DEST (set_body);
16463 : 76 : if (!set_dest || !REG_P (set_dest))
16464 : : return false;
16465 : 75 : break;
16466 : 9 : case PARALLEL:
16467 : 27 : for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
16468 : 18 : if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
16469 : : use_body))
16470 : : return true;
16471 : : /* FALLTHROUGH */
16472 : : default:
16473 : : return false;
16474 : : }
16475 : :
16476 : : /* Retrieve shift count of USE_BODY. */
16477 : 75 : switch (GET_CODE (use_body))
16478 : : {
16479 : 25 : case SET:
16480 : 25 : shift_rtx = XEXP (use_body, 1);
16481 : 25 : break;
16482 : 25 : case PARALLEL:
16483 : 75 : for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
16484 : 50 : if (ix86_dep_by_shift_count_body (set_body,
16485 : 50 : XVECEXP (use_body, 0, i)))
16486 : : return true;
16487 : : /* FALLTHROUGH */
16488 : : default:
16489 : : return false;
16490 : : }
16491 : :
16492 : 25 : if (shift_rtx
16493 : 25 : && (GET_CODE (shift_rtx) == ASHIFT
16494 : 21 : || GET_CODE (shift_rtx) == LSHIFTRT
16495 : 5 : || GET_CODE (shift_rtx) == ASHIFTRT
16496 : 0 : || GET_CODE (shift_rtx) == ROTATE
16497 : 0 : || GET_CODE (shift_rtx) == ROTATERT))
16498 : : {
16499 : 25 : rtx shift_count = XEXP (shift_rtx, 1);
16500 : :
16501 : : /* Return true if shift count is dest of SET_BODY. */
16502 : 25 : if (REG_P (shift_count))
16503 : : {
16504 : : /* Add check since it can be invoked before register
16505 : : allocation in pre-reload schedule. */
16506 : 0 : if (reload_completed
16507 : 0 : && true_regnum (set_dest) == true_regnum (shift_count))
16508 : : return true;
16509 : 0 : else if (REGNO(set_dest) == REGNO(shift_count))
16510 : : return true;
16511 : : }
16512 : : }
16513 : :
16514 : : return false;
16515 : : }
16516 : :
16517 : : /* Return true if destination reg of SET_INSN is shift count of
16518 : : USE_INSN. */
16519 : :
16520 : : bool
16521 : 26 : ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
16522 : : {
16523 : 26 : return ix86_dep_by_shift_count_body (PATTERN (set_insn),
16524 : 26 : PATTERN (use_insn));
16525 : : }
16526 : :
16527 : : /* Return TRUE if the operands to a vec_interleave_{high,low}v2df
16528 : : are ok, keeping in mind the possible movddup alternative. */
16529 : :
16530 : : bool
16531 : 86074 : ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
16532 : : {
16533 : 86074 : if (MEM_P (operands[0]))
16534 : 2091 : return rtx_equal_p (operands[0], operands[1 + high]);
16535 : 83983 : if (MEM_P (operands[1]) && MEM_P (operands[2]))
16536 : 896 : return false;
16537 : : return true;
16538 : : }
16539 : :
16540 : : /* A subroutine of ix86_build_signbit_mask. If VECT is true,
16541 : : then replicate the value for all elements of the vector
16542 : : register. */
16543 : :
16544 : : rtx
16545 : 74784 : ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
16546 : : {
16547 : 74784 : int i, n_elt;
16548 : 74784 : rtvec v;
16549 : 74784 : machine_mode scalar_mode;
16550 : :
16551 : 74784 : switch (mode)
16552 : : {
16553 : 1036 : case E_V64QImode:
16554 : 1036 : case E_V32QImode:
16555 : 1036 : case E_V16QImode:
16556 : 1036 : case E_V32HImode:
16557 : 1036 : case E_V16HImode:
16558 : 1036 : case E_V8HImode:
16559 : 1036 : case E_V16SImode:
16560 : 1036 : case E_V8SImode:
16561 : 1036 : case E_V4SImode:
16562 : 1036 : case E_V2SImode:
16563 : 1036 : case E_V8DImode:
16564 : 1036 : case E_V4DImode:
16565 : 1036 : case E_V2DImode:
16566 : 1036 : gcc_assert (vect);
16567 : : /* FALLTHRU */
16568 : 74784 : case E_V2HFmode:
16569 : 74784 : case E_V4HFmode:
16570 : 74784 : case E_V8HFmode:
16571 : 74784 : case E_V16HFmode:
16572 : 74784 : case E_V32HFmode:
16573 : 74784 : case E_V16SFmode:
16574 : 74784 : case E_V8SFmode:
16575 : 74784 : case E_V4SFmode:
16576 : 74784 : case E_V2SFmode:
16577 : 74784 : case E_V8DFmode:
16578 : 74784 : case E_V4DFmode:
16579 : 74784 : case E_V2DFmode:
16580 : 74784 : case E_V32BFmode:
16581 : 74784 : case E_V16BFmode:
16582 : 74784 : case E_V8BFmode:
16583 : 74784 : case E_V4BFmode:
16584 : 74784 : case E_V2BFmode:
16585 : 74784 : n_elt = GET_MODE_NUNITS (mode);
16586 : 74784 : v = rtvec_alloc (n_elt);
16587 : 74784 : scalar_mode = GET_MODE_INNER (mode);
16588 : :
16589 : 74784 : RTVEC_ELT (v, 0) = value;
16590 : :
16591 : 231476 : for (i = 1; i < n_elt; ++i)
16592 : 156692 : RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
16593 : :
16594 : 74784 : return gen_rtx_CONST_VECTOR (mode, v);
16595 : :
16596 : 0 : default:
16597 : 0 : gcc_unreachable ();
16598 : : }
16599 : : }
16600 : :
16601 : : /* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
16602 : : and ix86_expand_int_vcond. Create a mask for the sign bit in MODE
16603 : : for an SSE register. If VECT is true, then replicate the mask for
16604 : : all elements of the vector register. If INVERT is true, then create
16605 : : a mask excluding the sign bit. */
16606 : :
16607 : : rtx
16608 : 53893 : ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
16609 : : {
16610 : 53893 : machine_mode vec_mode, imode;
16611 : 53893 : wide_int w;
16612 : 53893 : rtx mask, v;
16613 : :
16614 : 53893 : switch (mode)
16615 : : {
16616 : : case E_V2HFmode:
16617 : : case E_V4HFmode:
16618 : : case E_V8HFmode:
16619 : : case E_V16HFmode:
16620 : : case E_V32HFmode:
16621 : : case E_V32BFmode:
16622 : : case E_V16BFmode:
16623 : : case E_V8BFmode:
16624 : : case E_V4BFmode:
16625 : : case E_V2BFmode:
16626 : : vec_mode = mode;
16627 : : imode = HImode;
16628 : : break;
16629 : :
16630 : 23153 : case E_V16SImode:
16631 : 23153 : case E_V16SFmode:
16632 : 23153 : case E_V8SImode:
16633 : 23153 : case E_V4SImode:
16634 : 23153 : case E_V8SFmode:
16635 : 23153 : case E_V4SFmode:
16636 : 23153 : case E_V2SFmode:
16637 : 23153 : case E_V2SImode:
16638 : 23153 : vec_mode = mode;
16639 : 23153 : imode = SImode;
16640 : 23153 : break;
16641 : :
16642 : 27734 : case E_V8DImode:
16643 : 27734 : case E_V4DImode:
16644 : 27734 : case E_V2DImode:
16645 : 27734 : case E_V8DFmode:
16646 : 27734 : case E_V4DFmode:
16647 : 27734 : case E_V2DFmode:
16648 : 27734 : vec_mode = mode;
16649 : 27734 : imode = DImode;
16650 : 27734 : break;
16651 : :
16652 : 2606 : case E_TImode:
16653 : 2606 : case E_TFmode:
16654 : 2606 : vec_mode = VOIDmode;
16655 : 2606 : imode = TImode;
16656 : 2606 : break;
16657 : :
16658 : 0 : default:
16659 : 0 : gcc_unreachable ();
16660 : : }
16661 : :
16662 : 53893 : machine_mode inner_mode = GET_MODE_INNER (mode);
16663 : 107786 : w = wi::set_bit_in_zero (GET_MODE_BITSIZE (inner_mode) - 1,
16664 : 107786 : GET_MODE_BITSIZE (inner_mode));
16665 : 53893 : if (invert)
16666 : 17613 : w = wi::bit_not (w);
16667 : :
16668 : : /* Force this value into the low part of a fp vector constant. */
16669 : 53893 : mask = immed_wide_int_const (w, imode);
16670 : 53893 : mask = gen_lowpart (inner_mode, mask);
16671 : :
16672 : 53893 : if (vec_mode == VOIDmode)
16673 : 2606 : return force_reg (inner_mode, mask);
16674 : :
16675 : 51287 : v = ix86_build_const_vector (vec_mode, vect, mask);
16676 : 51287 : return force_reg (vec_mode, v);
16677 : 53893 : }
16678 : :
16679 : : /* Return HOST_WIDE_INT for const vector OP in MODE. */
16680 : :
16681 : : HOST_WIDE_INT
16682 : 158364 : ix86_convert_const_vector_to_integer (rtx op, machine_mode mode)
16683 : : {
16684 : 338278 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
16685 : 0 : gcc_unreachable ();
16686 : :
16687 : 158364 : int nunits = GET_MODE_NUNITS (mode);
16688 : 316728 : wide_int val = wi::zero (GET_MODE_BITSIZE (mode));
16689 : 158364 : machine_mode innermode = GET_MODE_INNER (mode);
16690 : 158364 : unsigned int innermode_bits = GET_MODE_BITSIZE (innermode);
16691 : :
16692 : 158364 : switch (mode)
16693 : : {
16694 : : case E_V2QImode:
16695 : : case E_V4QImode:
16696 : : case E_V2HImode:
16697 : : case E_V8QImode:
16698 : : case E_V4HImode:
16699 : : case E_V2SImode:
16700 : 522888 : for (int i = 0; i < nunits; ++i)
16701 : : {
16702 : 366766 : int v = INTVAL (XVECEXP (op, 0, i));
16703 : 366766 : wide_int wv = wi::shwi (v, innermode_bits);
16704 : 366766 : val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
16705 : 366766 : }
16706 : : break;
16707 : : case E_V2HFmode:
16708 : : case E_V2BFmode:
16709 : : case E_V4HFmode:
16710 : : case E_V4BFmode:
16711 : : case E_V2SFmode:
16712 : 6736 : for (int i = 0; i < nunits; ++i)
16713 : : {
16714 : 4494 : rtx x = XVECEXP (op, 0, i);
16715 : 4494 : int v = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
16716 : 4494 : REAL_MODE_FORMAT (innermode));
16717 : 4494 : wide_int wv = wi::shwi (v, innermode_bits);
16718 : 4494 : val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
16719 : 4494 : }
16720 : : break;
16721 : 0 : default:
16722 : 0 : gcc_unreachable ();
16723 : : }
16724 : :
16725 : 158364 : return val.to_shwi ();
16726 : 158364 : }
16727 : :
16728 : 32 : int ix86_get_flags_cc (rtx_code code)
16729 : : {
16730 : 32 : switch (code)
16731 : : {
16732 : : case NE: return X86_CCNE;
16733 : : case EQ: return X86_CCE;
16734 : : case GE: return X86_CCNL;
16735 : : case GT: return X86_CCNLE;
16736 : : case LE: return X86_CCLE;
16737 : : case LT: return X86_CCL;
16738 : : case GEU: return X86_CCNB;
16739 : : case GTU: return X86_CCNBE;
16740 : : case LEU: return X86_CCBE;
16741 : : case LTU: return X86_CCB;
16742 : : default: return -1;
16743 : : }
16744 : : }
16745 : :
16746 : : /* Return TRUE or FALSE depending on whether the first SET in INSN
16747 : : has source and destination with matching CC modes, and that the
16748 : : CC mode is at least as constrained as REQ_MODE. */
16749 : :
16750 : : bool
16751 : 54090665 : ix86_match_ccmode (rtx insn, machine_mode req_mode)
16752 : : {
16753 : 54090665 : rtx set;
16754 : 54090665 : machine_mode set_mode;
16755 : :
16756 : 54090665 : set = PATTERN (insn);
16757 : 54090665 : if (GET_CODE (set) == PARALLEL)
16758 : 468018 : set = XVECEXP (set, 0, 0);
16759 : 54090665 : gcc_assert (GET_CODE (set) == SET);
16760 : 54090665 : gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
16761 : :
16762 : 54090665 : set_mode = GET_MODE (SET_DEST (set));
16763 : 54090665 : switch (set_mode)
16764 : : {
16765 : 1369054 : case E_CCNOmode:
16766 : 1369054 : if (req_mode != CCNOmode
16767 : 73606 : && (req_mode != CCmode
16768 : 0 : || XEXP (SET_SRC (set), 1) != const0_rtx))
16769 : : return false;
16770 : : break;
16771 : 5350735 : case E_CCmode:
16772 : 5350735 : if (req_mode == CCGCmode)
16773 : : return false;
16774 : : /* FALLTHRU */
16775 : 9027899 : case E_CCGCmode:
16776 : 9027899 : if (req_mode == CCGOCmode || req_mode == CCNOmode)
16777 : : return false;
16778 : : /* FALLTHRU */
16779 : 10065910 : case E_CCGOCmode:
16780 : 10065910 : if (req_mode == CCZmode)
16781 : : return false;
16782 : : /* FALLTHRU */
16783 : : case E_CCZmode:
16784 : : break;
16785 : :
16786 : 0 : case E_CCGZmode:
16787 : :
16788 : 0 : case E_CCAmode:
16789 : 0 : case E_CCCmode:
16790 : 0 : case E_CCOmode:
16791 : 0 : case E_CCPmode:
16792 : 0 : case E_CCSmode:
16793 : 0 : if (set_mode != req_mode)
16794 : : return false;
16795 : : break;
16796 : :
16797 : 0 : default:
16798 : 0 : gcc_unreachable ();
16799 : : }
16800 : :
16801 : 54008252 : return GET_MODE (SET_SRC (set)) == set_mode;
16802 : : }
16803 : :
16804 : : machine_mode
16805 : 13454614 : ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
16806 : : {
16807 : 13454614 : machine_mode mode = GET_MODE (op0);
16808 : :
16809 : 13454614 : if (SCALAR_FLOAT_MODE_P (mode))
16810 : : {
16811 : 133600 : gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
16812 : : return CCFPmode;
16813 : : }
16814 : :
16815 : 13321014 : switch (code)
16816 : : {
16817 : : /* Only zero flag is needed. */
16818 : : case EQ: /* ZF=0 */
16819 : : case NE: /* ZF!=0 */
16820 : : return CCZmode;
16821 : : /* Codes needing carry flag. */
16822 : 969540 : case GEU: /* CF=0 */
16823 : 969540 : case LTU: /* CF=1 */
16824 : 969540 : rtx geu;
16825 : : /* Detect overflow checks. They need just the carry flag. */
16826 : 969540 : if (GET_CODE (op0) == PLUS
16827 : 969540 : && (rtx_equal_p (op1, XEXP (op0, 0))
16828 : 119386 : || rtx_equal_p (op1, XEXP (op0, 1))))
16829 : 17122 : return CCCmode;
16830 : : /* Similarly for *setcc_qi_addqi3_cconly_overflow_1_* patterns.
16831 : : Match LTU of op0
16832 : : (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
16833 : : and op1
16834 : : (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
16835 : : where CC_CCC is either CC or CCC. */
16836 : 952418 : else if (code == LTU
16837 : 368366 : && GET_CODE (op0) == NEG
16838 : 5041 : && GET_CODE (geu = XEXP (op0, 0)) == GEU
16839 : 3664 : && REG_P (XEXP (geu, 0))
16840 : 3345 : && (GET_MODE (XEXP (geu, 0)) == CCCmode
16841 : 37 : || GET_MODE (XEXP (geu, 0)) == CCmode)
16842 : 3334 : && REGNO (XEXP (geu, 0)) == FLAGS_REG
16843 : 3334 : && XEXP (geu, 1) == const0_rtx
16844 : 3334 : && GET_CODE (op1) == LTU
16845 : 3334 : && REG_P (XEXP (op1, 0))
16846 : 3334 : && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
16847 : 3334 : && REGNO (XEXP (op1, 0)) == FLAGS_REG
16848 : 955752 : && XEXP (op1, 1) == const0_rtx)
16849 : : return CCCmode;
16850 : : /* Similarly for *x86_cmc pattern.
16851 : : Match LTU of op0 (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
16852 : : and op1 (geu:QI (reg:CCC FLAGS_REG) (const_int 0)).
16853 : : It is sufficient to test that the operand modes are CCCmode. */
16854 : 949084 : else if (code == LTU
16855 : 365032 : && GET_CODE (op0) == NEG
16856 : 1707 : && GET_CODE (XEXP (op0, 0)) == LTU
16857 : 377 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
16858 : 3 : && GET_CODE (op1) == GEU
16859 : 3 : && GET_MODE (XEXP (op1, 0)) == CCCmode)
16860 : : return CCCmode;
16861 : : /* Similarly for the comparison of addcarry/subborrow pattern. */
16862 : 365029 : else if (code == LTU
16863 : 365029 : && GET_CODE (op0) == ZERO_EXTEND
16864 : 15860 : && GET_CODE (op1) == PLUS
16865 : 9959 : && ix86_carry_flag_operator (XEXP (op1, 0), VOIDmode)
16866 : 9959 : && GET_CODE (XEXP (op1, 1)) == ZERO_EXTEND)
16867 : : return CCCmode;
16868 : : else
16869 : 939122 : return CCmode;
16870 : : case GTU: /* CF=0 & ZF=0 */
16871 : : case LEU: /* CF=1 | ZF=1 */
16872 : : return CCmode;
16873 : : /* Codes possibly doable only with sign flag when
16874 : : comparing against zero. */
16875 : 782585 : case GE: /* SF=OF or SF=0 */
16876 : 782585 : case LT: /* SF<>OF or SF=1 */
16877 : 782585 : if (op1 == const0_rtx)
16878 : : return CCGOCmode;
16879 : : else
16880 : : /* For other cases Carry flag is not required. */
16881 : 442815 : return CCGCmode;
16882 : : /* Codes doable only with sign flag when comparing
16883 : : against zero, but we miss jump instruction for it
16884 : : so we need to use relational tests against overflow
16885 : : that thus needs to be zero. */
16886 : 904293 : case GT: /* ZF=0 & SF=OF */
16887 : 904293 : case LE: /* ZF=1 | SF<>OF */
16888 : 904293 : if (op1 == const0_rtx)
16889 : : return CCNOmode;
16890 : : else
16891 : 611308 : return CCGCmode;
16892 : : default:
16893 : : /* CCmode should be used in all other cases. */
16894 : : return CCmode;
16895 : : }
16896 : : }
16897 : :
16898 : : /* Return TRUE or FALSE depending on whether the ptest instruction
16899 : : INSN has source and destination with suitable matching CC modes. */
16900 : :
16901 : : bool
16902 : 40741 : ix86_match_ptest_ccmode (rtx insn)
16903 : : {
16904 : 40741 : rtx set, src;
16905 : 40741 : machine_mode set_mode;
16906 : :
16907 : 40741 : set = PATTERN (insn);
16908 : 40741 : gcc_assert (GET_CODE (set) == SET);
16909 : 40741 : src = SET_SRC (set);
16910 : 40741 : gcc_assert (GET_CODE (src) == UNSPEC
16911 : : && XINT (src, 1) == UNSPEC_PTEST);
16912 : :
16913 : 40741 : set_mode = GET_MODE (src);
16914 : 40741 : if (set_mode != CCZmode
16915 : : && set_mode != CCCmode
16916 : : && set_mode != CCmode)
16917 : : return false;
16918 : 40741 : return GET_MODE (SET_DEST (set)) == set_mode;
16919 : : }
16920 : :
16921 : : /* Return the fixed registers used for condition codes. */
16922 : :
16923 : : static bool
16924 : 10223864 : ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
16925 : : {
16926 : 10223864 : *p1 = FLAGS_REG;
16927 : 10223864 : *p2 = INVALID_REGNUM;
16928 : 10223864 : return true;
16929 : : }
16930 : :
16931 : : /* If two condition code modes are compatible, return a condition code
16932 : : mode which is compatible with both. Otherwise, return
16933 : : VOIDmode. */
16934 : :
16935 : : static machine_mode
16936 : 30924 : ix86_cc_modes_compatible (machine_mode m1, machine_mode m2)
16937 : : {
16938 : 30924 : if (m1 == m2)
16939 : : return m1;
16940 : :
16941 : 30319 : if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
16942 : : return VOIDmode;
16943 : :
16944 : 30319 : if ((m1 == CCGCmode && m2 == CCGOCmode)
16945 : 30319 : || (m1 == CCGOCmode && m2 == CCGCmode))
16946 : : return CCGCmode;
16947 : :
16948 : 30319 : if ((m1 == CCNOmode && m2 == CCGOCmode)
16949 : 30129 : || (m1 == CCGOCmode && m2 == CCNOmode))
16950 : : return CCNOmode;
16951 : :
16952 : 29999 : if (m1 == CCZmode
16953 : 17464 : && (m2 == CCGCmode || m2 == CCGOCmode || m2 == CCNOmode))
16954 : : return m2;
16955 : 15981 : else if (m2 == CCZmode
16956 : 12283 : && (m1 == CCGCmode || m1 == CCGOCmode || m1 == CCNOmode))
16957 : : return m1;
16958 : :
16959 : 5381 : switch (m1)
16960 : : {
16961 : 0 : default:
16962 : 0 : gcc_unreachable ();
16963 : :
16964 : 5381 : case E_CCmode:
16965 : 5381 : case E_CCGCmode:
16966 : 5381 : case E_CCGOCmode:
16967 : 5381 : case E_CCNOmode:
16968 : 5381 : case E_CCAmode:
16969 : 5381 : case E_CCCmode:
16970 : 5381 : case E_CCOmode:
16971 : 5381 : case E_CCPmode:
16972 : 5381 : case E_CCSmode:
16973 : 5381 : case E_CCZmode:
16974 : 5381 : switch (m2)
16975 : : {
16976 : : default:
16977 : : return VOIDmode;
16978 : :
16979 : : case E_CCmode:
16980 : : case E_CCGCmode:
16981 : : case E_CCGOCmode:
16982 : : case E_CCNOmode:
16983 : : case E_CCAmode:
16984 : : case E_CCCmode:
16985 : : case E_CCOmode:
16986 : : case E_CCPmode:
16987 : : case E_CCSmode:
16988 : : case E_CCZmode:
16989 : : return CCmode;
16990 : : }
16991 : :
16992 : : case E_CCFPmode:
16993 : : /* These are only compatible with themselves, which we already
16994 : : checked above. */
16995 : : return VOIDmode;
16996 : : }
16997 : : }
16998 : :
16999 : : /* Return strategy to use for floating-point. We assume that fcomi is always
17000 : : preferrable where available, since that is also true when looking at size
17001 : : (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test). */
17002 : :
17003 : : enum ix86_fpcmp_strategy
17004 : 5551555 : ix86_fp_comparison_strategy (enum rtx_code)
17005 : : {
17006 : : /* Do fcomi/sahf based test when profitable. */
17007 : :
17008 : 5551555 : if (TARGET_CMOVE)
17009 : : return IX86_FPCMP_COMI;
17010 : :
17011 : 0 : if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
17012 : 0 : return IX86_FPCMP_SAHF;
17013 : :
17014 : : return IX86_FPCMP_ARITH;
17015 : : }
17016 : :
17017 : : /* Convert comparison codes we use to represent FP comparison to integer
17018 : : code that will result in proper branch. Return UNKNOWN if no such code
17019 : : is available. */
17020 : :
17021 : : enum rtx_code
17022 : 582239 : ix86_fp_compare_code_to_integer (enum rtx_code code)
17023 : : {
17024 : 582239 : switch (code)
17025 : : {
17026 : : case GT:
17027 : : return GTU;
17028 : 18855 : case GE:
17029 : 18855 : return GEU;
17030 : : case ORDERED:
17031 : : case UNORDERED:
17032 : : return code;
17033 : 118199 : case UNEQ:
17034 : 118199 : return EQ;
17035 : 21335 : case UNLT:
17036 : 21335 : return LTU;
17037 : 31036 : case UNLE:
17038 : 31036 : return LEU;
17039 : 112347 : case LTGT:
17040 : 112347 : return NE;
17041 : 19 : case EQ:
17042 : 19 : case NE:
17043 : 19 : if (TARGET_AVX10_2)
17044 : : return code;
17045 : : /* FALLTHRU. */
17046 : 206 : default:
17047 : 206 : return UNKNOWN;
17048 : : }
17049 : : }
17050 : :
17051 : : /* Zero extend possibly SImode EXP to Pmode register. */
17052 : : rtx
17053 : 40140 : ix86_zero_extend_to_Pmode (rtx exp)
17054 : : {
17055 : 52100 : return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
17056 : : }
17057 : :
17058 : : /* Return true if the function is called via PLT. */
17059 : :
17060 : : bool
17061 : 965276 : ix86_call_use_plt_p (rtx call_op)
17062 : : {
17063 : 965276 : if (SYMBOL_REF_LOCAL_P (call_op))
17064 : : {
17065 : 192354 : if (SYMBOL_REF_DECL (call_op)
17066 : 192354 : && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
17067 : : {
17068 : : /* NB: All ifunc functions must be called via PLT. */
17069 : 109255 : cgraph_node *node
17070 : 109255 : = cgraph_node::get (SYMBOL_REF_DECL (call_op));
17071 : 109255 : if (node && node->ifunc_resolver)
17072 : : return true;
17073 : : }
17074 : 192334 : return false;
17075 : : }
17076 : : return true;
17077 : : }
17078 : :
17079 : : /* Implement TARGET_IFUNC_REF_LOCAL_OK. If this hook returns true,
17080 : : the PLT entry will be used as the function address for local IFUNC
17081 : : functions. When the PIC register is needed for PLT call, indirect
17082 : : call via the PLT entry will fail since the PIC register may not be
17083 : : set up properly for indirect call. In this case, we should return
17084 : : false. */
17085 : :
17086 : : static bool
17087 : 749122300 : ix86_ifunc_ref_local_ok (void)
17088 : : {
17089 : 749122300 : return !flag_pic || (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC);
17090 : : }
17091 : :
17092 : : /* Return true if the function being called was marked with attribute
17093 : : "noplt" or using -fno-plt and we are compiling for non-PIC. We need
17094 : : to handle the non-PIC case in the backend because there is no easy
17095 : : interface for the front-end to force non-PLT calls to use the GOT.
17096 : : This is currently used only with 64-bit or 32-bit GOT32X ELF targets
17097 : : to call the function marked "noplt" indirectly. */
17098 : :
17099 : : bool
17100 : 5861735 : ix86_nopic_noplt_attribute_p (rtx call_op)
17101 : : {
17102 : 5384919 : if (flag_pic || ix86_cmodel == CM_LARGE
17103 : : || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
17104 : : || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
17105 : 11246654 : || SYMBOL_REF_LOCAL_P (call_op))
17106 : : return false;
17107 : :
17108 : 3759002 : tree symbol_decl = SYMBOL_REF_DECL (call_op);
17109 : :
17110 : 3759002 : if (!flag_plt
17111 : 3759002 : || (symbol_decl != NULL_TREE
17112 : 3758970 : && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl))))
17113 : 34 : return true;
17114 : :
17115 : : return false;
17116 : : }
17117 : :
17118 : : /* Helper to output the jmp/call. */
17119 : : static void
17120 : 33 : ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno)
17121 : : {
17122 : 33 : if (thunk_name != NULL)
17123 : : {
17124 : 22 : if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
17125 : 1 : && ix86_indirect_branch_cs_prefix)
17126 : 1 : fprintf (asm_out_file, "\tcs\n");
17127 : 22 : fprintf (asm_out_file, "\tjmp\t");
17128 : 22 : assemble_name (asm_out_file, thunk_name);
17129 : 22 : putc ('\n', asm_out_file);
17130 : 22 : if ((ix86_harden_sls & harden_sls_indirect_jmp))
17131 : 2 : fputs ("\tint3\n", asm_out_file);
17132 : : }
17133 : : else
17134 : 11 : output_indirect_thunk (regno);
17135 : 33 : }
17136 : :
17137 : : /* Output indirect branch via a call and return thunk. CALL_OP is a
17138 : : register which contains the branch target. XASM is the assembly
17139 : : template for CALL_OP. Branch is a tail call if SIBCALL_P is true.
17140 : : A normal call is converted to:
17141 : :
17142 : : call __x86_indirect_thunk_reg
17143 : :
17144 : : and a tail call is converted to:
17145 : :
17146 : : jmp __x86_indirect_thunk_reg
17147 : : */
17148 : :
17149 : : static void
17150 : 50 : ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
17151 : : {
17152 : 50 : char thunk_name_buf[32];
17153 : 50 : char *thunk_name;
17154 : 50 : enum indirect_thunk_prefix need_prefix
17155 : 50 : = indirect_thunk_need_prefix (current_output_insn);
17156 : 50 : int regno = REGNO (call_op);
17157 : :
17158 : 50 : if (cfun->machine->indirect_branch_type
17159 : 50 : != indirect_branch_thunk_inline)
17160 : : {
17161 : 39 : if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
17162 : 16 : SET_HARD_REG_BIT (indirect_thunks_used, regno);
17163 : :
17164 : 39 : indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
17165 : 39 : thunk_name = thunk_name_buf;
17166 : : }
17167 : : else
17168 : : thunk_name = NULL;
17169 : :
17170 : 50 : if (sibcall_p)
17171 : 27 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
17172 : : else
17173 : : {
17174 : 23 : if (thunk_name != NULL)
17175 : : {
17176 : 17 : if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
17177 : 1 : && ix86_indirect_branch_cs_prefix)
17178 : 1 : fprintf (asm_out_file, "\tcs\n");
17179 : 17 : fprintf (asm_out_file, "\tcall\t");
17180 : 17 : assemble_name (asm_out_file, thunk_name);
17181 : 17 : putc ('\n', asm_out_file);
17182 : 17 : return;
17183 : : }
17184 : :
17185 : 6 : char indirectlabel1[32];
17186 : 6 : char indirectlabel2[32];
17187 : :
17188 : 6 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
17189 : : INDIRECT_LABEL,
17190 : : indirectlabelno++);
17191 : 6 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
17192 : : INDIRECT_LABEL,
17193 : : indirectlabelno++);
17194 : :
17195 : : /* Jump. */
17196 : 6 : fputs ("\tjmp\t", asm_out_file);
17197 : 6 : assemble_name_raw (asm_out_file, indirectlabel2);
17198 : 6 : fputc ('\n', asm_out_file);
17199 : :
17200 : 6 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
17201 : :
17202 : 6 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
17203 : :
17204 : 6 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
17205 : :
17206 : : /* Call. */
17207 : 6 : fputs ("\tcall\t", asm_out_file);
17208 : 6 : assemble_name_raw (asm_out_file, indirectlabel1);
17209 : 6 : fputc ('\n', asm_out_file);
17210 : : }
17211 : : }
17212 : :
17213 : : /* Output indirect branch via a call and return thunk. CALL_OP is
17214 : : the branch target. XASM is the assembly template for CALL_OP.
17215 : : Branch is a tail call if SIBCALL_P is true. A normal call is
17216 : : converted to:
17217 : :
17218 : : jmp L2
17219 : : L1:
17220 : : push CALL_OP
17221 : : jmp __x86_indirect_thunk
17222 : : L2:
17223 : : call L1
17224 : :
17225 : : and a tail call is converted to:
17226 : :
17227 : : push CALL_OP
17228 : : jmp __x86_indirect_thunk
17229 : : */
17230 : :
17231 : : static void
17232 : 0 : ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
17233 : : bool sibcall_p)
17234 : : {
17235 : 0 : char thunk_name_buf[32];
17236 : 0 : char *thunk_name;
17237 : 0 : char push_buf[64];
17238 : 0 : enum indirect_thunk_prefix need_prefix
17239 : 0 : = indirect_thunk_need_prefix (current_output_insn);
17240 : 0 : int regno = -1;
17241 : :
17242 : 0 : if (cfun->machine->indirect_branch_type
17243 : 0 : != indirect_branch_thunk_inline)
17244 : : {
17245 : 0 : if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
17246 : 0 : indirect_thunk_needed = true;
17247 : 0 : indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
17248 : 0 : thunk_name = thunk_name_buf;
17249 : : }
17250 : : else
17251 : : thunk_name = NULL;
17252 : :
17253 : 0 : snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
17254 : 0 : TARGET_64BIT ? 'q' : 'l', xasm);
17255 : :
17256 : 0 : if (sibcall_p)
17257 : : {
17258 : 0 : output_asm_insn (push_buf, &call_op);
17259 : 0 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
17260 : : }
17261 : : else
17262 : : {
17263 : 0 : char indirectlabel1[32];
17264 : 0 : char indirectlabel2[32];
17265 : :
17266 : 0 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
17267 : : INDIRECT_LABEL,
17268 : : indirectlabelno++);
17269 : 0 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
17270 : : INDIRECT_LABEL,
17271 : : indirectlabelno++);
17272 : :
17273 : : /* Jump. */
17274 : 0 : fputs ("\tjmp\t", asm_out_file);
17275 : 0 : assemble_name_raw (asm_out_file, indirectlabel2);
17276 : 0 : fputc ('\n', asm_out_file);
17277 : :
17278 : 0 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
17279 : :
17280 : : /* An external function may be called via GOT, instead of PLT. */
17281 : 0 : if (MEM_P (call_op))
17282 : : {
17283 : 0 : struct ix86_address parts;
17284 : 0 : rtx addr = XEXP (call_op, 0);
17285 : 0 : if (ix86_decompose_address (addr, &parts)
17286 : 0 : && parts.base == stack_pointer_rtx)
17287 : : {
17288 : : /* Since call will adjust stack by -UNITS_PER_WORD,
17289 : : we must convert "disp(stack, index, scale)" to
17290 : : "disp+UNITS_PER_WORD(stack, index, scale)". */
17291 : 0 : if (parts.index)
17292 : : {
17293 : 0 : addr = gen_rtx_MULT (Pmode, parts.index,
17294 : : GEN_INT (parts.scale));
17295 : 0 : addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
17296 : : addr);
17297 : : }
17298 : : else
17299 : : addr = stack_pointer_rtx;
17300 : :
17301 : 0 : rtx disp;
17302 : 0 : if (parts.disp != NULL_RTX)
17303 : 0 : disp = plus_constant (Pmode, parts.disp,
17304 : 0 : UNITS_PER_WORD);
17305 : : else
17306 : 0 : disp = GEN_INT (UNITS_PER_WORD);
17307 : :
17308 : 0 : addr = gen_rtx_PLUS (Pmode, addr, disp);
17309 : 0 : call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
17310 : : }
17311 : : }
17312 : :
17313 : 0 : output_asm_insn (push_buf, &call_op);
17314 : :
17315 : 0 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
17316 : :
17317 : 0 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
17318 : :
17319 : : /* Call. */
17320 : 0 : fputs ("\tcall\t", asm_out_file);
17321 : 0 : assemble_name_raw (asm_out_file, indirectlabel1);
17322 : 0 : fputc ('\n', asm_out_file);
17323 : : }
17324 : 0 : }
17325 : :
17326 : : /* Output indirect branch via a call and return thunk. CALL_OP is
17327 : : the branch target. XASM is the assembly template for CALL_OP.
17328 : : Branch is a tail call if SIBCALL_P is true. */
17329 : :
17330 : : static void
17331 : 50 : ix86_output_indirect_branch (rtx call_op, const char *xasm,
17332 : : bool sibcall_p)
17333 : : {
17334 : 50 : if (REG_P (call_op))
17335 : 50 : ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
17336 : : else
17337 : 0 : ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
17338 : 50 : }
17339 : :
17340 : : /* Output indirect jump. CALL_OP is the jump target. */
17341 : :
17342 : : const char *
17343 : 10414 : ix86_output_indirect_jmp (rtx call_op)
17344 : : {
17345 : 10414 : if (cfun->machine->indirect_branch_type != indirect_branch_keep)
17346 : : {
17347 : : /* We can't have red-zone since "call" in the indirect thunk
17348 : : pushes the return address onto stack, destroying red-zone. */
17349 : 4 : if (ix86_red_zone_used)
17350 : 0 : gcc_unreachable ();
17351 : :
17352 : 4 : ix86_output_indirect_branch (call_op, "%0", true);
17353 : : }
17354 : : else
17355 : 10410 : output_asm_insn ("%!jmp\t%A0", &call_op);
17356 : 10414 : return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
17357 : : }
17358 : :
17359 : : /* Output return instrumentation for current function if needed. */
17360 : :
17361 : : static void
17362 : 1690410 : output_return_instrumentation (void)
17363 : : {
17364 : 1690410 : if (ix86_instrument_return != instrument_return_none
17365 : 6 : && flag_fentry
17366 : 1690416 : && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
17367 : : {
17368 : 5 : if (ix86_flag_record_return)
17369 : 5 : fprintf (asm_out_file, "1:\n");
17370 : 5 : switch (ix86_instrument_return)
17371 : : {
17372 : 2 : case instrument_return_call:
17373 : 2 : fprintf (asm_out_file, "\tcall\t__return__\n");
17374 : 2 : break;
17375 : 3 : case instrument_return_nop5:
17376 : : /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
17377 : 3 : fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
17378 : 3 : break;
17379 : : case instrument_return_none:
17380 : : break;
17381 : : }
17382 : :
17383 : 5 : if (ix86_flag_record_return)
17384 : : {
17385 : 5 : fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
17386 : 5 : fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
17387 : 5 : fprintf (asm_out_file, "\t.previous\n");
17388 : : }
17389 : : }
17390 : 1690410 : }
17391 : :
17392 : : /* Output function return. CALL_OP is the jump target. Add a REP
17393 : : prefix to RET if LONG_P is true and function return is kept. */
17394 : :
17395 : : const char *
17396 : 1563970 : ix86_output_function_return (bool long_p)
17397 : : {
17398 : 1563970 : output_return_instrumentation ();
17399 : :
17400 : 1563970 : if (cfun->machine->function_return_type != indirect_branch_keep)
17401 : : {
17402 : 17 : char thunk_name[32];
17403 : 17 : enum indirect_thunk_prefix need_prefix
17404 : 17 : = indirect_thunk_need_prefix (current_output_insn);
17405 : :
17406 : 17 : if (cfun->machine->function_return_type
17407 : 17 : != indirect_branch_thunk_inline)
17408 : : {
17409 : 12 : bool need_thunk = (cfun->machine->function_return_type
17410 : : == indirect_branch_thunk);
17411 : 12 : indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
17412 : : true);
17413 : 12 : indirect_return_needed |= need_thunk;
17414 : 12 : fprintf (asm_out_file, "\tjmp\t");
17415 : 12 : assemble_name (asm_out_file, thunk_name);
17416 : 12 : putc ('\n', asm_out_file);
17417 : : }
17418 : : else
17419 : 5 : output_indirect_thunk (INVALID_REGNUM);
17420 : :
17421 : 17 : return "";
17422 : : }
17423 : :
17424 : 3127423 : output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr);
17425 : 1563953 : return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
17426 : : }
17427 : :
17428 : : /* Output indirect function return. RET_OP is the function return
17429 : : target. */
17430 : :
17431 : : const char *
17432 : 17 : ix86_output_indirect_function_return (rtx ret_op)
17433 : : {
17434 : 17 : if (cfun->machine->function_return_type != indirect_branch_keep)
17435 : : {
17436 : 0 : char thunk_name[32];
17437 : 0 : enum indirect_thunk_prefix need_prefix
17438 : 0 : = indirect_thunk_need_prefix (current_output_insn);
17439 : 0 : unsigned int regno = REGNO (ret_op);
17440 : 0 : gcc_assert (regno == CX_REG);
17441 : :
17442 : 0 : if (cfun->machine->function_return_type
17443 : 0 : != indirect_branch_thunk_inline)
17444 : : {
17445 : 0 : bool need_thunk = (cfun->machine->function_return_type
17446 : : == indirect_branch_thunk);
17447 : 0 : indirect_thunk_name (thunk_name, regno, need_prefix, true);
17448 : :
17449 : 0 : if (need_thunk)
17450 : : {
17451 : 0 : indirect_return_via_cx = true;
17452 : 0 : SET_HARD_REG_BIT (indirect_thunks_used, CX_REG);
17453 : : }
17454 : 0 : fprintf (asm_out_file, "\tjmp\t");
17455 : 0 : assemble_name (asm_out_file, thunk_name);
17456 : 0 : putc ('\n', asm_out_file);
17457 : : }
17458 : : else
17459 : 0 : output_indirect_thunk (regno);
17460 : : }
17461 : : else
17462 : : {
17463 : 17 : output_asm_insn ("%!jmp\t%A0", &ret_op);
17464 : 17 : if (ix86_harden_sls & harden_sls_indirect_jmp)
17465 : 1 : fputs ("\tint3\n", asm_out_file);
17466 : : }
17467 : 17 : return "";
17468 : : }
17469 : :
17470 : : /* Output the assembly for a call instruction. */
17471 : :
17472 : : const char *
17473 : 6049779 : ix86_output_call_insn (rtx_insn *insn, rtx call_op)
17474 : : {
17475 : 6049779 : bool direct_p = constant_call_address_operand (call_op, VOIDmode);
17476 : 6049779 : bool output_indirect_p
17477 : : = (!TARGET_SEH
17478 : 6049779 : && cfun->machine->indirect_branch_type != indirect_branch_keep);
17479 : 6049779 : bool seh_nop_p = false;
17480 : 6049779 : const char *xasm;
17481 : :
17482 : 6049779 : if (SIBLING_CALL_P (insn))
17483 : : {
17484 : 126440 : output_return_instrumentation ();
17485 : 126440 : if (direct_p)
17486 : : {
17487 : 117393 : if (ix86_nopic_noplt_attribute_p (call_op))
17488 : : {
17489 : 4 : direct_p = false;
17490 : 4 : if (TARGET_64BIT)
17491 : : {
17492 : 4 : if (output_indirect_p)
17493 : : xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17494 : : else
17495 : 4 : xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17496 : : }
17497 : : else
17498 : : {
17499 : 0 : if (output_indirect_p)
17500 : : xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
17501 : : else
17502 : 0 : xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
17503 : : }
17504 : : }
17505 : : else
17506 : : xasm = "%!jmp\t%P0";
17507 : : }
17508 : : /* SEH epilogue detection requires the indirect branch case
17509 : : to include REX.W. */
17510 : 9047 : else if (TARGET_SEH)
17511 : : xasm = "%!rex.W jmp\t%A0";
17512 : : else
17513 : : {
17514 : 9047 : if (output_indirect_p)
17515 : : xasm = "%0";
17516 : : else
17517 : 9024 : xasm = "%!jmp\t%A0";
17518 : : }
17519 : :
17520 : 126440 : if (output_indirect_p && !direct_p)
17521 : 23 : ix86_output_indirect_branch (call_op, xasm, true);
17522 : : else
17523 : : {
17524 : 126417 : output_asm_insn (xasm, &call_op);
17525 : 126417 : if (!direct_p
17526 : 9028 : && (ix86_harden_sls & harden_sls_indirect_jmp))
17527 : : return "int3";
17528 : : }
17529 : 126439 : return "";
17530 : : }
17531 : :
17532 : : /* SEH unwinding can require an extra nop to be emitted in several
17533 : : circumstances. Determine if we have one of those. */
17534 : 5923339 : if (TARGET_SEH)
17535 : : {
17536 : : rtx_insn *i;
17537 : :
17538 : : for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
17539 : : {
17540 : : /* Prevent a catch region from being adjacent to a jump that would
17541 : : be interpreted as an epilogue sequence by the unwinder. */
17542 : : if (JUMP_P(i) && CROSSING_JUMP_P (i))
17543 : : {
17544 : : seh_nop_p = true;
17545 : : break;
17546 : : }
17547 : :
17548 : : /* If we get to another real insn, we don't need the nop. */
17549 : : if (INSN_P (i))
17550 : : break;
17551 : :
17552 : : /* If we get to the epilogue note, prevent a catch region from
17553 : : being adjacent to the standard epilogue sequence. Note that,
17554 : : if non-call exceptions are enabled, we already did it during
17555 : : epilogue expansion, or else, if the insn can throw internally,
17556 : : we already did it during the reorg pass. */
17557 : : if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
17558 : : && !flag_non_call_exceptions
17559 : : && !can_throw_internal (insn))
17560 : : {
17561 : : seh_nop_p = true;
17562 : : break;
17563 : : }
17564 : : }
17565 : :
17566 : : /* If we didn't find a real insn following the call, prevent the
17567 : : unwinder from looking into the next function. */
17568 : : if (i == NULL)
17569 : : seh_nop_p = true;
17570 : : }
17571 : :
17572 : 5923339 : if (direct_p)
17573 : : {
17574 : 5743320 : if (ix86_nopic_noplt_attribute_p (call_op))
17575 : : {
17576 : 6 : direct_p = false;
17577 : 6 : if (TARGET_64BIT)
17578 : : {
17579 : 6 : if (output_indirect_p)
17580 : : xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17581 : : else
17582 : 6 : xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17583 : : }
17584 : : else
17585 : : {
17586 : 0 : if (output_indirect_p)
17587 : : xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
17588 : : else
17589 : 0 : xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
17590 : : }
17591 : : }
17592 : : else
17593 : : xasm = "%!call\t%P0";
17594 : : }
17595 : : else
17596 : : {
17597 : 180019 : if (output_indirect_p)
17598 : : xasm = "%0";
17599 : : else
17600 : 179996 : xasm = "%!call\t%A0";
17601 : : }
17602 : :
17603 : 5923339 : if (output_indirect_p && !direct_p)
17604 : 23 : ix86_output_indirect_branch (call_op, xasm, false);
17605 : : else
17606 : 5923316 : output_asm_insn (xasm, &call_op);
17607 : :
17608 : : if (seh_nop_p)
17609 : : return "nop";
17610 : :
17611 : : return "";
17612 : : }
17613 : :
17614 : : /* Return a MEM corresponding to a stack slot with mode MODE.
17615 : : Allocate a new slot if necessary.
17616 : :
17617 : : The RTL for a function can have several slots available: N is
17618 : : which slot to use. */
17619 : :
17620 : : rtx
17621 : 22160 : assign_386_stack_local (machine_mode mode, enum ix86_stack_slot n)
17622 : : {
17623 : 22160 : struct stack_local_entry *s;
17624 : :
17625 : 22160 : gcc_assert (n < MAX_386_STACK_LOCALS);
17626 : :
17627 : 33418 : for (s = ix86_stack_locals; s; s = s->next)
17628 : 30897 : if (s->mode == mode && s->n == n)
17629 : 19639 : return validize_mem (copy_rtx (s->rtl));
17630 : :
17631 : 2521 : int align = 0;
17632 : : /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
17633 : : alignment with -m32 -mpreferred-stack-boundary=2. */
17634 : 2521 : if (mode == DImode
17635 : 329 : && !TARGET_64BIT
17636 : 329 : && n == SLOT_FLOATxFDI_387
17637 : 2850 : && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
17638 : : align = 32;
17639 : 2521 : s = ggc_alloc<stack_local_entry> ();
17640 : 2521 : s->n = n;
17641 : 2521 : s->mode = mode;
17642 : 5042 : s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
17643 : :
17644 : 2521 : s->next = ix86_stack_locals;
17645 : 2521 : ix86_stack_locals = s;
17646 : 2521 : return validize_mem (copy_rtx (s->rtl));
17647 : : }
17648 : :
17649 : : static void
17650 : 1449055 : ix86_instantiate_decls (void)
17651 : : {
17652 : 1449055 : struct stack_local_entry *s;
17653 : :
17654 : 1449055 : for (s = ix86_stack_locals; s; s = s->next)
17655 : 0 : if (s->rtl != NULL_RTX)
17656 : 0 : instantiate_decl_rtl (s->rtl);
17657 : 1449055 : }
17658 : :
17659 : : /* Check whether x86 address PARTS is a pc-relative address. */
17660 : :
17661 : : bool
17662 : 25438057 : ix86_rip_relative_addr_p (struct ix86_address *parts)
17663 : : {
17664 : 25438057 : rtx base, index, disp;
17665 : :
17666 : 25438057 : base = parts->base;
17667 : 25438057 : index = parts->index;
17668 : 25438057 : disp = parts->disp;
17669 : :
17670 : 25438057 : if (disp && !base && !index)
17671 : : {
17672 : 24827684 : if (TARGET_64BIT)
17673 : : {
17674 : 23344951 : rtx symbol = disp;
17675 : :
17676 : 23344951 : if (GET_CODE (disp) == CONST)
17677 : 7459668 : symbol = XEXP (disp, 0);
17678 : 23344951 : if (GET_CODE (symbol) == PLUS
17679 : 6967115 : && CONST_INT_P (XEXP (symbol, 1)))
17680 : 6967115 : symbol = XEXP (symbol, 0);
17681 : :
17682 : 23344951 : if (GET_CODE (symbol) == LABEL_REF
17683 : 23338061 : || (GET_CODE (symbol) == SYMBOL_REF
17684 : 22235951 : && SYMBOL_REF_TLS_MODEL (symbol) == 0)
17685 : 24447061 : || (GET_CODE (symbol) == UNSPEC
17686 : 511254 : && (XINT (symbol, 1) == UNSPEC_GOTPCREL
17687 : : || XINT (symbol, 1) == UNSPEC_PCREL
17688 : : || XINT (symbol, 1) == UNSPEC_GOTNTPOFF)))
17689 : 22727867 : return true;
17690 : : }
17691 : : }
17692 : : return false;
17693 : : }
17694 : :
17695 : : /* Calculate the length of the memory address in the instruction encoding.
17696 : : Includes addr32 prefix, does not include the one-byte modrm, opcode,
17697 : : or other prefixes. We never generate addr32 prefix for LEA insn. */
17698 : :
17699 : : int
17700 : 269476489 : memory_address_length (rtx addr, bool lea)
17701 : : {
17702 : 269476489 : struct ix86_address parts;
17703 : 269476489 : rtx base, index, disp;
17704 : 269476489 : int len;
17705 : 269476489 : int ok;
17706 : :
17707 : 269476489 : if (GET_CODE (addr) == PRE_DEC
17708 : 260986319 : || GET_CODE (addr) == POST_INC
17709 : 256377325 : || GET_CODE (addr) == PRE_MODIFY
17710 : 256377325 : || GET_CODE (addr) == POST_MODIFY)
17711 : : return 0;
17712 : :
17713 : 256377325 : ok = ix86_decompose_address (addr, &parts);
17714 : 256377325 : gcc_assert (ok);
17715 : :
17716 : 256377325 : len = (parts.seg == ADDR_SPACE_GENERIC) ? 0 : 1;
17717 : :
17718 : : /* If this is not LEA instruction, add the length of addr32 prefix. */
17719 : 217488119 : if (TARGET_64BIT && !lea
17720 : 448611677 : && (SImode_address_operand (addr, VOIDmode)
17721 : 192234199 : || (parts.base && GET_MODE (parts.base) == SImode)
17722 : 192223813 : || (parts.index && GET_MODE (parts.index) == SImode)))
17723 : 10539 : len++;
17724 : :
17725 : 256377325 : base = parts.base;
17726 : 256377325 : index = parts.index;
17727 : 256377325 : disp = parts.disp;
17728 : :
17729 : 256377325 : if (base && SUBREG_P (base))
17730 : 2 : base = SUBREG_REG (base);
17731 : 256377325 : if (index && SUBREG_P (index))
17732 : 0 : index = SUBREG_REG (index);
17733 : :
17734 : 256377325 : gcc_assert (base == NULL_RTX || REG_P (base));
17735 : 256377325 : gcc_assert (index == NULL_RTX || REG_P (index));
17736 : :
17737 : : /* Rule of thumb:
17738 : : - esp as the base always wants an index,
17739 : : - ebp as the base always wants a displacement,
17740 : : - r12 as the base always wants an index,
17741 : : - r13 as the base always wants a displacement. */
17742 : :
17743 : : /* Register Indirect. */
17744 : 256377325 : if (base && !index && !disp)
17745 : : {
17746 : : /* esp (for its index) and ebp (for its displacement) need
17747 : : the two-byte modrm form. Similarly for r12 and r13 in 64-bit
17748 : : code. */
17749 : 16294774 : if (base == arg_pointer_rtx
17750 : 16294774 : || base == frame_pointer_rtx
17751 : 16294774 : || REGNO (base) == SP_REG
17752 : 9747440 : || REGNO (base) == BP_REG
17753 : 9747440 : || REGNO (base) == R12_REG
17754 : 25587860 : || REGNO (base) == R13_REG)
17755 : 7001688 : len++;
17756 : : }
17757 : :
17758 : : /* Direct Addressing. In 64-bit mode mod 00 r/m 5
17759 : : is not disp32, but disp32(%rip), so for disp32
17760 : : SIB byte is needed, unless print_operand_address
17761 : : optimizes it into disp32(%rip) or (%rip) is implied
17762 : : by UNSPEC. */
17763 : 240082551 : else if (disp && !base && !index)
17764 : : {
17765 : 24516282 : len += 4;
17766 : 24516282 : if (!ix86_rip_relative_addr_p (&parts))
17767 : 1856757 : len++;
17768 : : }
17769 : : else
17770 : : {
17771 : : /* Find the length of the displacement constant. */
17772 : 215566269 : if (disp)
17773 : : {
17774 : 211391099 : if (base && satisfies_constraint_K (disp))
17775 : 121554529 : len += 1;
17776 : : else
17777 : 89836570 : len += 4;
17778 : : }
17779 : : /* ebp always wants a displacement. Similarly r13. */
17780 : 4175170 : else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
17781 : 6389 : len++;
17782 : :
17783 : : /* An index requires the two-byte modrm form.... */
17784 : 215566269 : if (index
17785 : : /* ...like esp (or r12), which always wants an index. */
17786 : 205239927 : || base == arg_pointer_rtx
17787 : 205239927 : || base == frame_pointer_rtx
17788 : 420806196 : || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
17789 : 155023471 : len++;
17790 : : }
17791 : :
17792 : : return len;
17793 : : }
17794 : :
17795 : : /* Compute default value for "length_immediate" attribute. When SHORTFORM
17796 : : is set, expect that insn have 8bit immediate alternative. */
17797 : : int
17798 : 314569238 : ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
17799 : : {
17800 : 314569238 : int len = 0;
17801 : 314569238 : int i;
17802 : 314569238 : extract_insn_cached (insn);
17803 : 981302969 : for (i = recog_data.n_operands - 1; i >= 0; --i)
17804 : 666733731 : if (CONSTANT_P (recog_data.operand[i]))
17805 : : {
17806 : 137322554 : enum attr_mode mode = get_attr_mode (insn);
17807 : :
17808 : 137322554 : gcc_assert (!len);
17809 : 137322554 : if (shortform && CONST_INT_P (recog_data.operand[i]))
17810 : : {
17811 : 35292345 : HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
17812 : 35292345 : switch (mode)
17813 : : {
17814 : 1203491 : case MODE_QI:
17815 : 1203491 : len = 1;
17816 : 1203491 : continue;
17817 : 368335 : case MODE_HI:
17818 : 368335 : ival = trunc_int_for_mode (ival, HImode);
17819 : 368335 : break;
17820 : 15443037 : case MODE_SI:
17821 : 15443037 : ival = trunc_int_for_mode (ival, SImode);
17822 : 15443037 : break;
17823 : : default:
17824 : : break;
17825 : : }
17826 : 34088854 : if (IN_RANGE (ival, -128, 127))
17827 : : {
17828 : 30330480 : len = 1;
17829 : 30330480 : continue;
17830 : : }
17831 : : }
17832 : 105788583 : switch (mode)
17833 : : {
17834 : : case MODE_QI:
17835 : : len = 1;
17836 : : break;
17837 : : case MODE_HI:
17838 : 666733731 : len = 2;
17839 : : break;
17840 : : case MODE_SI:
17841 : 100125335 : len = 4;
17842 : : break;
17843 : : /* Immediates for DImode instructions are encoded
17844 : : as 32bit sign extended values. */
17845 : : case MODE_DI:
17846 : 100125335 : len = 4;
17847 : : break;
17848 : 0 : default:
17849 : 0 : fatal_insn ("unknown insn mode", insn);
17850 : : }
17851 : : }
17852 : 314569238 : return len;
17853 : : }
17854 : :
17855 : : /* Compute default value for "length_address" attribute. */
17856 : : int
17857 : 441954021 : ix86_attr_length_address_default (rtx_insn *insn)
17858 : : {
17859 : 441954021 : int i;
17860 : :
17861 : 441954021 : if (get_attr_type (insn) == TYPE_LEA)
17862 : : {
17863 : 27945518 : rtx set = PATTERN (insn), addr;
17864 : :
17865 : 27945518 : if (GET_CODE (set) == PARALLEL)
17866 : 87102 : set = XVECEXP (set, 0, 0);
17867 : :
17868 : 27945518 : gcc_assert (GET_CODE (set) == SET);
17869 : :
17870 : 27945518 : addr = SET_SRC (set);
17871 : :
17872 : 27945518 : return memory_address_length (addr, true);
17873 : : }
17874 : :
17875 : 414008503 : extract_insn_cached (insn);
17876 : 949872122 : for (i = recog_data.n_operands - 1; i >= 0; --i)
17877 : : {
17878 : 777114883 : rtx op = recog_data.operand[i];
17879 : 777114883 : if (MEM_P (op))
17880 : : {
17881 : 241522648 : constrain_operands_cached (insn, reload_completed);
17882 : 241522648 : if (which_alternative != -1)
17883 : : {
17884 : 241522648 : const char *constraints = recog_data.constraints[i];
17885 : 241522648 : int alt = which_alternative;
17886 : :
17887 : 382304255 : while (*constraints == '=' || *constraints == '+')
17888 : 140781607 : constraints++;
17889 : 1095788587 : while (alt-- > 0)
17890 : 2098204187 : while (*constraints++ != ',')
17891 : : ;
17892 : : /* Skip ignored operands. */
17893 : 241522648 : if (*constraints == 'X')
17894 : 271384 : continue;
17895 : : }
17896 : :
17897 : 241251264 : int len = memory_address_length (XEXP (op, 0), false);
17898 : :
17899 : : /* Account for segment prefix for non-default addr spaces. */
17900 : 252798349 : if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)))
17901 : 777790 : len++;
17902 : :
17903 : 241251264 : return len;
17904 : : }
17905 : : }
17906 : : return 0;
17907 : : }
17908 : :
17909 : : /* Compute default value for "length_vex" attribute. It includes
17910 : : 2 or 3 byte VEX prefix and 1 opcode byte. */
17911 : :
17912 : : int
17913 : 4969419 : ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
17914 : : bool has_vex_w)
17915 : : {
17916 : 4969419 : int i, reg_only = 2 + 1;
17917 : 4969419 : bool has_mem = false;
17918 : :
17919 : : /* Only 0f opcode can use 2 byte VEX prefix and VEX W bit uses 3
17920 : : byte VEX prefix. */
17921 : 4969419 : if (!has_0f_opcode || has_vex_w)
17922 : : return 3 + 1;
17923 : :
17924 : : /* We can always use 2 byte VEX prefix in 32bit. */
17925 : 4575483 : if (!TARGET_64BIT)
17926 : : return 2 + 1;
17927 : :
17928 : 3476286 : extract_insn_cached (insn);
17929 : :
17930 : 10807170 : for (i = recog_data.n_operands - 1; i >= 0; --i)
17931 : 7671986 : if (REG_P (recog_data.operand[i]))
17932 : : {
17933 : : /* REX.W bit uses 3 byte VEX prefix.
17934 : : REX2 with vex use extended EVEX prefix length is 4-byte. */
17935 : 5010147 : if (GET_MODE (recog_data.operand[i]) == DImode
17936 : 5010147 : && GENERAL_REG_P (recog_data.operand[i]))
17937 : : return 3 + 1;
17938 : :
17939 : : /* REX.B bit requires 3-byte VEX. Right here we don't know which
17940 : : operand will be encoded using VEX.B, so be conservative.
17941 : : REX2 with vex use extended EVEX prefix length is 4-byte. */
17942 : 4994606 : if (REX_INT_REGNO_P (recog_data.operand[i])
17943 : 4994606 : || REX2_INT_REGNO_P (recog_data.operand[i])
17944 : 4994606 : || REX_SSE_REGNO_P (recog_data.operand[i]))
17945 : 0 : reg_only = 3 + 1;
17946 : : }
17947 : 2661839 : else if (MEM_P (recog_data.operand[i]))
17948 : : {
17949 : : /* REX2.X or REX2.B bits use 3 byte VEX prefix. */
17950 : 2082854 : if (x86_extended_rex2reg_mentioned_p (recog_data.operand[i]))
17951 : : return 4;
17952 : :
17953 : : /* REX.X or REX.B bits use 3 byte VEX prefix. */
17954 : 2082600 : if (x86_extended_reg_mentioned_p (recog_data.operand[i]))
17955 : : return 3 + 1;
17956 : :
17957 : : has_mem = true;
17958 : : }
17959 : :
17960 : 3135184 : return has_mem ? 2 + 1 : reg_only;
17961 : : }
17962 : :
17963 : :
17964 : : static bool
17965 : : ix86_class_likely_spilled_p (reg_class_t);
17966 : :
17967 : : /* Returns true if lhs of insn is HW function argument register and set up
17968 : : is_spilled to true if it is likely spilled HW register. */
17969 : : static bool
17970 : 1132 : insn_is_function_arg (rtx insn, bool* is_spilled)
17971 : : {
17972 : 1132 : rtx dst;
17973 : :
17974 : 1132 : if (!NONDEBUG_INSN_P (insn))
17975 : : return false;
17976 : : /* Call instructions are not movable, ignore it. */
17977 : 1132 : if (CALL_P (insn))
17978 : : return false;
17979 : 1068 : insn = PATTERN (insn);
17980 : 1068 : if (GET_CODE (insn) == PARALLEL)
17981 : 75 : insn = XVECEXP (insn, 0, 0);
17982 : 1068 : if (GET_CODE (insn) != SET)
17983 : : return false;
17984 : 1068 : dst = SET_DEST (insn);
17985 : 964 : if (REG_P (dst) && HARD_REGISTER_P (dst)
17986 : 1924 : && ix86_function_arg_regno_p (REGNO (dst)))
17987 : : {
17988 : : /* Is it likely spilled HW register? */
17989 : 856 : if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
17990 : 856 : && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
17991 : 812 : *is_spilled = true;
17992 : 856 : return true;
17993 : : }
17994 : : return false;
17995 : : }
17996 : :
17997 : : /* Add output dependencies for chain of function adjacent arguments if only
17998 : : there is a move to likely spilled HW register. Return first argument
17999 : : if at least one dependence was added or NULL otherwise. */
18000 : : static rtx_insn *
18001 : 412 : add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
18002 : : {
18003 : 412 : rtx_insn *insn;
18004 : 412 : rtx_insn *last = call;
18005 : 412 : rtx_insn *first_arg = NULL;
18006 : 412 : bool is_spilled = false;
18007 : :
18008 : 412 : head = PREV_INSN (head);
18009 : :
18010 : : /* Find nearest to call argument passing instruction. */
18011 : 412 : while (true)
18012 : : {
18013 : 412 : last = PREV_INSN (last);
18014 : 412 : if (last == head)
18015 : : return NULL;
18016 : 412 : if (!NONDEBUG_INSN_P (last))
18017 : 0 : continue;
18018 : 412 : if (insn_is_function_arg (last, &is_spilled))
18019 : : break;
18020 : : return NULL;
18021 : : }
18022 : :
18023 : : first_arg = last;
18024 : 1123 : while (true)
18025 : : {
18026 : 1123 : insn = PREV_INSN (last);
18027 : 1123 : if (!INSN_P (insn))
18028 : : break;
18029 : 1028 : if (insn == head)
18030 : : break;
18031 : 987 : if (!NONDEBUG_INSN_P (insn))
18032 : : {
18033 : 267 : last = insn;
18034 : 267 : continue;
18035 : : }
18036 : 720 : if (insn_is_function_arg (insn, &is_spilled))
18037 : : {
18038 : : /* Add output depdendence between two function arguments if chain
18039 : : of output arguments contains likely spilled HW registers. */
18040 : 451 : if (is_spilled)
18041 : 451 : add_dependence (first_arg, insn, REG_DEP_OUTPUT);
18042 : : first_arg = last = insn;
18043 : : }
18044 : : else
18045 : : break;
18046 : : }
18047 : 405 : if (!is_spilled)
18048 : : return NULL;
18049 : : return first_arg;
18050 : : }
18051 : :
18052 : : /* Add output or anti dependency from insn to first_arg to restrict its code
18053 : : motion. */
18054 : : static void
18055 : 2445 : avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
18056 : : {
18057 : 2445 : rtx set;
18058 : 2445 : rtx tmp;
18059 : :
18060 : 2445 : set = single_set (insn);
18061 : 2445 : if (!set)
18062 : : return;
18063 : 1470 : tmp = SET_DEST (set);
18064 : 1470 : if (REG_P (tmp))
18065 : : {
18066 : : /* Add output dependency to the first function argument. */
18067 : 1267 : add_dependence (first_arg, insn, REG_DEP_OUTPUT);
18068 : 1267 : return;
18069 : : }
18070 : : /* Add anti dependency. */
18071 : 203 : add_dependence (first_arg, insn, REG_DEP_ANTI);
18072 : : }
18073 : :
18074 : : /* Avoid cross block motion of function argument through adding dependency
18075 : : from the first non-jump instruction in bb. */
18076 : : static void
18077 : 68 : add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
18078 : : {
18079 : 68 : rtx_insn *insn = BB_END (bb);
18080 : :
18081 : 134 : while (insn)
18082 : : {
18083 : 134 : if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
18084 : : {
18085 : 67 : rtx set = single_set (insn);
18086 : 67 : if (set)
18087 : : {
18088 : 67 : avoid_func_arg_motion (arg, insn);
18089 : 67 : return;
18090 : : }
18091 : : }
18092 : 67 : if (insn == BB_HEAD (bb))
18093 : : return;
18094 : 66 : insn = PREV_INSN (insn);
18095 : : }
18096 : : }
18097 : :
18098 : : /* Hook for pre-reload schedule - avoid motion of function arguments
18099 : : passed in likely spilled HW registers. */
18100 : : static void
18101 : 10242710 : ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
18102 : : {
18103 : 10242710 : rtx_insn *insn;
18104 : 10242710 : rtx_insn *first_arg = NULL;
18105 : 10242710 : if (reload_completed)
18106 : : return;
18107 : 1563 : while (head != tail && DEBUG_INSN_P (head))
18108 : 365 : head = NEXT_INSN (head);
18109 : 9205 : for (insn = tail; insn != head; insn = PREV_INSN (insn))
18110 : 8140 : if (INSN_P (insn) && CALL_P (insn))
18111 : : {
18112 : 412 : first_arg = add_parameter_dependencies (insn, head);
18113 : 412 : if (first_arg)
18114 : : {
18115 : : /* Add dependee for first argument to predecessors if only
18116 : : region contains more than one block. */
18117 : 405 : basic_block bb = BLOCK_FOR_INSN (insn);
18118 : 405 : int rgn = CONTAINING_RGN (bb->index);
18119 : 405 : int nr_blks = RGN_NR_BLOCKS (rgn);
18120 : : /* Skip trivial regions and region head blocks that can have
18121 : : predecessors outside of region. */
18122 : 405 : if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
18123 : : {
18124 : 67 : edge e;
18125 : 67 : edge_iterator ei;
18126 : :
18127 : : /* Regions are SCCs with the exception of selective
18128 : : scheduling with pipelining of outer blocks enabled.
18129 : : So also check that immediate predecessors of a non-head
18130 : : block are in the same region. */
18131 : 137 : FOR_EACH_EDGE (e, ei, bb->preds)
18132 : : {
18133 : : /* Avoid creating of loop-carried dependencies through
18134 : : using topological ordering in the region. */
18135 : 70 : if (rgn == CONTAINING_RGN (e->src->index)
18136 : 69 : && BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
18137 : 68 : add_dependee_for_func_arg (first_arg, e->src);
18138 : : }
18139 : : }
18140 : 405 : insn = first_arg;
18141 : 405 : if (insn == head)
18142 : : break;
18143 : : }
18144 : : }
18145 : 7728 : else if (first_arg)
18146 : 2378 : avoid_func_arg_motion (first_arg, insn);
18147 : : }
18148 : :
18149 : : /* Hook for pre-reload schedule - set priority of moves from likely spilled
18150 : : HW registers to maximum, to schedule them at soon as possible. These are
18151 : : moves from function argument registers at the top of the function entry
18152 : : and moves from function return value registers after call. */
18153 : : static int
18154 : 106315317 : ix86_adjust_priority (rtx_insn *insn, int priority)
18155 : : {
18156 : 106315317 : rtx set;
18157 : :
18158 : 106315317 : if (reload_completed)
18159 : : return priority;
18160 : :
18161 : 12531 : if (!NONDEBUG_INSN_P (insn))
18162 : : return priority;
18163 : :
18164 : 10809 : set = single_set (insn);
18165 : 10809 : if (set)
18166 : : {
18167 : 10301 : rtx tmp = SET_SRC (set);
18168 : 10301 : if (REG_P (tmp)
18169 : 2298 : && HARD_REGISTER_P (tmp)
18170 : 496 : && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
18171 : 10301 : && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
18172 : 446 : return current_sched_info->sched_max_insns_priority;
18173 : : }
18174 : :
18175 : : return priority;
18176 : : }
18177 : :
18178 : : /* Prepare for scheduling pass. */
18179 : : static void
18180 : 950641 : ix86_sched_init_global (FILE *, int, int)
18181 : : {
18182 : : /* Install scheduling hooks for current CPU. Some of these hooks are used
18183 : : in time-critical parts of the scheduler, so we only set them up when
18184 : : they are actually used. */
18185 : 950641 : switch (ix86_tune)
18186 : : {
18187 : 904239 : case PROCESSOR_CORE2:
18188 : 904239 : case PROCESSOR_NEHALEM:
18189 : 904239 : case PROCESSOR_SANDYBRIDGE:
18190 : 904239 : case PROCESSOR_HASWELL:
18191 : 904239 : case PROCESSOR_TREMONT:
18192 : 904239 : case PROCESSOR_ALDERLAKE:
18193 : 904239 : case PROCESSOR_GENERIC:
18194 : : /* Do not perform multipass scheduling for pre-reload schedule
18195 : : to save compile time. */
18196 : 904239 : if (reload_completed)
18197 : : {
18198 : 903939 : ix86_core2i7_init_hooks ();
18199 : 903939 : break;
18200 : : }
18201 : : /* Fall through. */
18202 : 46702 : default:
18203 : 46702 : targetm.sched.dfa_post_advance_cycle = NULL;
18204 : 46702 : targetm.sched.first_cycle_multipass_init = NULL;
18205 : 46702 : targetm.sched.first_cycle_multipass_begin = NULL;
18206 : 46702 : targetm.sched.first_cycle_multipass_issue = NULL;
18207 : 46702 : targetm.sched.first_cycle_multipass_backtrack = NULL;
18208 : 46702 : targetm.sched.first_cycle_multipass_end = NULL;
18209 : 46702 : targetm.sched.first_cycle_multipass_fini = NULL;
18210 : 46702 : break;
18211 : : }
18212 : 950641 : }
18213 : :
18214 : :
18215 : : /* Implement TARGET_STATIC_RTX_ALIGNMENT. */
18216 : :
18217 : : static HOST_WIDE_INT
18218 : 710119 : ix86_static_rtx_alignment (machine_mode mode)
18219 : : {
18220 : 710119 : if (mode == DFmode)
18221 : : return 64;
18222 : : if (ALIGN_MODE_128 (mode))
18223 : 153873 : return MAX (128, GET_MODE_ALIGNMENT (mode));
18224 : 472148 : return GET_MODE_ALIGNMENT (mode);
18225 : : }
18226 : :
18227 : : /* Implement TARGET_CONSTANT_ALIGNMENT. */
18228 : :
18229 : : static HOST_WIDE_INT
18230 : 6802112 : ix86_constant_alignment (const_tree exp, HOST_WIDE_INT align)
18231 : : {
18232 : 6802112 : if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
18233 : : || TREE_CODE (exp) == INTEGER_CST)
18234 : : {
18235 : 360691 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
18236 : 360691 : HOST_WIDE_INT mode_align = ix86_static_rtx_alignment (mode);
18237 : 360691 : return MAX (mode_align, align);
18238 : : }
18239 : 6301396 : else if (!optimize_size && TREE_CODE (exp) == STRING_CST
18240 : 9503820 : && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
18241 : : return BITS_PER_WORD;
18242 : :
18243 : : return align;
18244 : : }
18245 : :
18246 : : /* Implement TARGET_EMPTY_RECORD_P. */
18247 : :
18248 : : static bool
18249 : 1284633687 : ix86_is_empty_record (const_tree type)
18250 : : {
18251 : 1284633687 : if (!TARGET_64BIT)
18252 : : return false;
18253 : 1255071333 : return default_is_empty_record (type);
18254 : : }
18255 : :
18256 : : /* Implement TARGET_WARN_PARAMETER_PASSING_ABI. */
18257 : :
18258 : : static void
18259 : 15221517 : ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
18260 : : {
18261 : 15221517 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
18262 : :
18263 : 15221517 : if (!cum->warn_empty)
18264 : : return;
18265 : :
18266 : 12907799 : if (!TYPE_EMPTY_P (type))
18267 : : return;
18268 : :
18269 : : /* Don't warn if the function isn't visible outside of the TU. */
18270 : 14185 : if (cum->decl && !TREE_PUBLIC (cum->decl))
18271 : : return;
18272 : :
18273 : 12727 : tree decl = cum->decl;
18274 : 12727 : if (!decl)
18275 : : /* If we don't know the target, look at the current TU. */
18276 : 39 : decl = current_function_decl;
18277 : :
18278 : 12727 : const_tree ctx = get_ultimate_context (decl);
18279 : 12727 : if (ctx == NULL_TREE
18280 : 25419 : || !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
18281 : : return;
18282 : :
18283 : : /* If the actual size of the type is zero, then there is no change
18284 : : in how objects of this size are passed. */
18285 : 72 : if (int_size_in_bytes (type) == 0)
18286 : : return;
18287 : :
18288 : 66 : warning (OPT_Wabi, "empty class %qT parameter passing ABI "
18289 : : "changes in %<-fabi-version=12%> (GCC 8)", type);
18290 : :
18291 : : /* Only warn once. */
18292 : 66 : cum->warn_empty = false;
18293 : : }
18294 : :
18295 : : /* This hook returns name of multilib ABI. */
18296 : :
18297 : : static const char *
18298 : 3305343 : ix86_get_multilib_abi_name (void)
18299 : : {
18300 : 3305343 : if (!(TARGET_64BIT_P (ix86_isa_flags)))
18301 : : return "i386";
18302 : 3261387 : else if (TARGET_X32_P (ix86_isa_flags))
18303 : : return "x32";
18304 : : else
18305 : 3261387 : return "x86_64";
18306 : : }
18307 : :
18308 : : /* Compute the alignment for a variable for Intel MCU psABI. TYPE is
18309 : : the data type, and ALIGN is the alignment that the object would
18310 : : ordinarily have. */
18311 : :
18312 : : static int
18313 : 0 : iamcu_alignment (tree type, int align)
18314 : : {
18315 : 0 : machine_mode mode;
18316 : :
18317 : 0 : if (align < 32 || TYPE_USER_ALIGN (type))
18318 : : return align;
18319 : :
18320 : : /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4
18321 : : bytes. */
18322 : 0 : type = strip_array_types (type);
18323 : 0 : if (TYPE_ATOMIC (type))
18324 : : return align;
18325 : :
18326 : 0 : mode = TYPE_MODE (type);
18327 : 0 : switch (GET_MODE_CLASS (mode))
18328 : : {
18329 : : case MODE_INT:
18330 : : case MODE_COMPLEX_INT:
18331 : : case MODE_COMPLEX_FLOAT:
18332 : : case MODE_FLOAT:
18333 : : case MODE_DECIMAL_FLOAT:
18334 : : return 32;
18335 : : default:
18336 : : return align;
18337 : : }
18338 : : }
18339 : :
18340 : : /* Compute the alignment for a static variable.
18341 : : TYPE is the data type, and ALIGN is the alignment that
18342 : : the object would ordinarily have. The value of this function is used
18343 : : instead of that alignment to align the object. */
18344 : :
18345 : : int
18346 : 11907266 : ix86_data_alignment (tree type, unsigned int align, bool opt)
18347 : : {
18348 : : /* GCC 4.8 and earlier used to incorrectly assume this alignment even
18349 : : for symbols from other compilation units or symbols that don't need
18350 : : to bind locally. In order to preserve some ABI compatibility with
18351 : : those compilers, ensure we don't decrease alignment from what we
18352 : : used to assume. */
18353 : :
18354 : 11907266 : unsigned int max_align_compat = MIN (256, MAX_OFILE_ALIGNMENT);
18355 : :
18356 : : /* A data structure, equal or greater than the size of a cache line
18357 : : (64 bytes in the Pentium 4 and other recent Intel processors, including
18358 : : processors based on Intel Core microarchitecture) should be aligned
18359 : : so that its base address is a multiple of a cache line size. */
18360 : :
18361 : 23814532 : unsigned int max_align
18362 : 11907266 : = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
18363 : :
18364 : 14488101 : if (max_align < BITS_PER_WORD)
18365 : 0 : max_align = BITS_PER_WORD;
18366 : :
18367 : 11907266 : switch (ix86_align_data_type)
18368 : : {
18369 : 11907266 : case ix86_align_data_type_abi: opt = false; break;
18370 : 11907246 : case ix86_align_data_type_compat: max_align = BITS_PER_WORD; break;
18371 : : case ix86_align_data_type_cacheline: break;
18372 : : }
18373 : :
18374 : 11907266 : if (TARGET_IAMCU)
18375 : 0 : align = iamcu_alignment (type, align);
18376 : :
18377 : 11907266 : if (opt
18378 : 5743879 : && AGGREGATE_TYPE_P (type)
18379 : 3682338 : && TYPE_SIZE (type)
18380 : 15589572 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
18381 : : {
18382 : 6667167 : if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align_compat)
18383 : 3682306 : && align < max_align_compat)
18384 : 697445 : align = max_align_compat;
18385 : 7303493 : if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align)
18386 : 3682306 : && align < max_align)
18387 : 61119 : align = max_align;
18388 : : }
18389 : :
18390 : : /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
18391 : : to 16byte boundary. */
18392 : 11907266 : if (TARGET_64BIT)
18393 : : {
18394 : 4872299 : if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
18395 : 3223469 : && TYPE_SIZE (type)
18396 : 3223427 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
18397 : 10743783 : && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
18398 : 11349649 : && align < 128)
18399 : 605866 : return 128;
18400 : : }
18401 : :
18402 : 11301400 : if (!opt)
18403 : 5971748 : return align;
18404 : :
18405 : 5329652 : if (TREE_CODE (type) == ARRAY_TYPE)
18406 : : {
18407 : 1090110 : if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
18408 : : return 64;
18409 : 1090110 : if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
18410 : : return 128;
18411 : : }
18412 : 4239542 : else if (TREE_CODE (type) == COMPLEX_TYPE)
18413 : : {
18414 : :
18415 : 12861 : if (TYPE_MODE (type) == DCmode && align < 64)
18416 : : return 64;
18417 : 12861 : if ((TYPE_MODE (type) == XCmode
18418 : 12861 : || TYPE_MODE (type) == TCmode) && align < 128)
18419 : : return 128;
18420 : : }
18421 : 4226681 : else if (RECORD_OR_UNION_TYPE_P (type)
18422 : 4226681 : && TYPE_FIELDS (type))
18423 : : {
18424 : 2176325 : if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
18425 : : return 64;
18426 : 2176325 : if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
18427 : : return 128;
18428 : : }
18429 : 2050356 : else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
18430 : : || TREE_CODE (type) == INTEGER_TYPE)
18431 : : {
18432 : 1909436 : if (TYPE_MODE (type) == DFmode && align < 64)
18433 : : return 64;
18434 : 1909436 : if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
18435 : : return 128;
18436 : : }
18437 : :
18438 : 5329539 : return align;
18439 : : }
18440 : :
18441 : : /* Implememnt TARGET_LOWER_LOCAL_DECL_ALIGNMENT. */
18442 : : static void
18443 : 30383224 : ix86_lower_local_decl_alignment (tree decl)
18444 : : {
18445 : 30383224 : unsigned int new_align = ix86_local_alignment (decl, VOIDmode,
18446 : 30383224 : DECL_ALIGN (decl), true);
18447 : 30383224 : if (new_align < DECL_ALIGN (decl))
18448 : 0 : SET_DECL_ALIGN (decl, new_align);
18449 : 30383224 : }
18450 : :
18451 : : /* Compute the alignment for a local variable or a stack slot. EXP is
18452 : : the data type or decl itself, MODE is the widest mode available and
18453 : : ALIGN is the alignment that the object would ordinarily have. The
18454 : : value of this macro is used instead of that alignment to align the
18455 : : object. */
18456 : :
18457 : : unsigned int
18458 : 47584753 : ix86_local_alignment (tree exp, machine_mode mode,
18459 : : unsigned int align, bool may_lower)
18460 : : {
18461 : 47584753 : tree type, decl;
18462 : :
18463 : 47584753 : if (exp && DECL_P (exp))
18464 : : {
18465 : 45490750 : type = TREE_TYPE (exp);
18466 : 45490750 : decl = exp;
18467 : : }
18468 : : else
18469 : : {
18470 : : type = exp;
18471 : : decl = NULL;
18472 : : }
18473 : :
18474 : : /* Don't do dynamic stack realignment for long long objects with
18475 : : -mpreferred-stack-boundary=2. */
18476 : 47584753 : if (may_lower
18477 : 30383224 : && !TARGET_64BIT
18478 : 236857 : && align == 64
18479 : 37814 : && ix86_preferred_stack_boundary < 64
18480 : 0 : && (mode == DImode || (type && TYPE_MODE (type) == DImode))
18481 : 0 : && (!type || (!TYPE_USER_ALIGN (type)
18482 : 0 : && !TYPE_ATOMIC (strip_array_types (type))))
18483 : 47584753 : && (!decl || !DECL_USER_ALIGN (decl)))
18484 : : align = 32;
18485 : :
18486 : : /* If TYPE is NULL, we are allocating a stack slot for caller-save
18487 : : register in MODE. We will return the largest alignment of XF
18488 : : and DF. */
18489 : 47584753 : if (!type)
18490 : : {
18491 : 1365519 : if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
18492 : 1468 : align = GET_MODE_ALIGNMENT (DFmode);
18493 : 1365519 : return align;
18494 : : }
18495 : :
18496 : : /* Don't increase alignment for Intel MCU psABI. */
18497 : 46219234 : if (TARGET_IAMCU)
18498 : : return align;
18499 : :
18500 : : /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
18501 : : to 16byte boundary. Exact wording is:
18502 : :
18503 : : An array uses the same alignment as its elements, except that a local or
18504 : : global array variable of length at least 16 bytes or
18505 : : a C99 variable-length array variable always has alignment of at least 16 bytes.
18506 : :
18507 : : This was added to allow use of aligned SSE instructions at arrays. This
18508 : : rule is meant for static storage (where compiler cannot do the analysis
18509 : : by itself). We follow it for automatic variables only when convenient.
18510 : : We fully control everything in the function compiled and functions from
18511 : : other unit cannot rely on the alignment.
18512 : :
18513 : : Exclude va_list type. It is the common case of local array where
18514 : : we cannot benefit from the alignment.
18515 : :
18516 : : TODO: Probably one should optimize for size only when var is not escaping. */
18517 : 43392915 : if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
18518 : 89273231 : && TARGET_SSE)
18519 : : {
18520 : 43015390 : if (AGGREGATE_TYPE_P (type)
18521 : 8954349 : && (va_list_type_node == NULL_TREE
18522 : 8954349 : || (TYPE_MAIN_VARIANT (type)
18523 : 8954349 : != TYPE_MAIN_VARIANT (va_list_type_node)))
18524 : 8857124 : && TYPE_SIZE (type)
18525 : 8857124 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
18526 : 44034770 : && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
18527 : 49603074 : && align < 128)
18528 : 5568304 : return 128;
18529 : : }
18530 : 40650930 : if (TREE_CODE (type) == ARRAY_TYPE)
18531 : : {
18532 : 787130 : if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
18533 : : return 64;
18534 : 787130 : if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
18535 : : return 128;
18536 : : }
18537 : 39863800 : else if (TREE_CODE (type) == COMPLEX_TYPE)
18538 : : {
18539 : 153057 : if (TYPE_MODE (type) == DCmode && align < 64)
18540 : : return 64;
18541 : 153057 : if ((TYPE_MODE (type) == XCmode
18542 : 153057 : || TYPE_MODE (type) == TCmode) && align < 128)
18543 : : return 128;
18544 : : }
18545 : 39710743 : else if (RECORD_OR_UNION_TYPE_P (type)
18546 : 39710743 : && TYPE_FIELDS (type))
18547 : : {
18548 : 4593869 : if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
18549 : : return 64;
18550 : 4590665 : if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
18551 : : return 128;
18552 : : }
18553 : 35116874 : else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
18554 : : || TREE_CODE (type) == INTEGER_TYPE)
18555 : : {
18556 : :
18557 : 29125499 : if (TYPE_MODE (type) == DFmode && align < 64)
18558 : : return 64;
18559 : 29125499 : if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
18560 : : return 128;
18561 : : }
18562 : : return align;
18563 : : }
18564 : :
18565 : : /* Compute the minimum required alignment for dynamic stack realignment
18566 : : purposes for a local variable, parameter or a stack slot. EXP is
18567 : : the data type or decl itself, MODE is its mode and ALIGN is the
18568 : : alignment that the object would ordinarily have. */
18569 : :
18570 : : unsigned int
18571 : 47554236 : ix86_minimum_alignment (tree exp, machine_mode mode,
18572 : : unsigned int align)
18573 : : {
18574 : 47554236 : tree type, decl;
18575 : :
18576 : 47554236 : if (exp && DECL_P (exp))
18577 : : {
18578 : 15149369 : type = TREE_TYPE (exp);
18579 : 15149369 : decl = exp;
18580 : : }
18581 : : else
18582 : : {
18583 : : type = exp;
18584 : : decl = NULL;
18585 : : }
18586 : :
18587 : 47554236 : if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
18588 : : return align;
18589 : :
18590 : : /* Don't do dynamic stack realignment for long long objects with
18591 : : -mpreferred-stack-boundary=2. */
18592 : 0 : if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
18593 : 0 : && (!type || (!TYPE_USER_ALIGN (type)
18594 : 0 : && !TYPE_ATOMIC (strip_array_types (type))))
18595 : 0 : && (!decl || !DECL_USER_ALIGN (decl)))
18596 : : {
18597 : 0 : gcc_checking_assert (!TARGET_STV);
18598 : : return 32;
18599 : : }
18600 : :
18601 : : return align;
18602 : : }
18603 : :
18604 : : /* Find a location for the static chain incoming to a nested function.
18605 : : This is a register, unless all free registers are used by arguments. */
18606 : :
18607 : : static rtx
18608 : 267632 : ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
18609 : : {
18610 : 267632 : unsigned regno;
18611 : :
18612 : 267632 : if (TARGET_64BIT)
18613 : : {
18614 : : /* We always use R10 in 64-bit mode. */
18615 : : regno = R10_REG;
18616 : : }
18617 : : else
18618 : : {
18619 : 88482 : const_tree fntype, fndecl;
18620 : 88482 : unsigned int ccvt;
18621 : :
18622 : : /* By default in 32-bit mode we use ECX to pass the static chain. */
18623 : 88482 : regno = CX_REG;
18624 : :
18625 : 88482 : if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
18626 : : {
18627 : 78560 : fntype = TREE_TYPE (fndecl_or_type);
18628 : 78560 : fndecl = fndecl_or_type;
18629 : : }
18630 : : else
18631 : : {
18632 : : fntype = fndecl_or_type;
18633 : : fndecl = NULL;
18634 : : }
18635 : :
18636 : 88482 : ccvt = ix86_get_callcvt (fntype);
18637 : 88482 : if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
18638 : : {
18639 : : /* Fastcall functions use ecx/edx for arguments, which leaves
18640 : : us with EAX for the static chain.
18641 : : Thiscall functions use ecx for arguments, which also
18642 : : leaves us with EAX for the static chain. */
18643 : : regno = AX_REG;
18644 : : }
18645 : 88482 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
18646 : : {
18647 : : /* Thiscall functions use ecx for arguments, which leaves
18648 : : us with EAX and EDX for the static chain.
18649 : : We are using for abi-compatibility EAX. */
18650 : : regno = AX_REG;
18651 : : }
18652 : 88482 : else if (ix86_function_regparm (fntype, fndecl) == 3)
18653 : : {
18654 : : /* For regparm 3, we have no free call-clobbered registers in
18655 : : which to store the static chain. In order to implement this,
18656 : : we have the trampoline push the static chain to the stack.
18657 : : However, we can't push a value below the return address when
18658 : : we call the nested function directly, so we have to use an
18659 : : alternate entry point. For this we use ESI, and have the
18660 : : alternate entry point push ESI, so that things appear the
18661 : : same once we're executing the nested function. */
18662 : 0 : if (incoming_p)
18663 : : {
18664 : 0 : if (fndecl == current_function_decl
18665 : 0 : && !ix86_static_chain_on_stack)
18666 : : {
18667 : 0 : gcc_assert (!reload_completed);
18668 : 0 : ix86_static_chain_on_stack = true;
18669 : : }
18670 : 0 : return gen_frame_mem (SImode,
18671 : 0 : plus_constant (Pmode,
18672 : : arg_pointer_rtx, -8));
18673 : : }
18674 : : regno = SI_REG;
18675 : : }
18676 : : }
18677 : :
18678 : 356127 : return gen_rtx_REG (Pmode, regno);
18679 : : }
18680 : :
18681 : : /* Emit RTL insns to initialize the variable parts of a trampoline.
18682 : : FNDECL is the decl of the target address; M_TRAMP is a MEM for
18683 : : the trampoline, and CHAIN_VALUE is an RTX for the static chain
18684 : : to be passed to the target function. */
18685 : :
18686 : : static void
18687 : 290 : ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
18688 : : {
18689 : 290 : rtx mem, fnaddr;
18690 : 290 : int opcode;
18691 : 290 : int offset = 0;
18692 : 290 : bool need_endbr = (flag_cf_protection & CF_BRANCH);
18693 : :
18694 : 290 : fnaddr = XEXP (DECL_RTL (fndecl), 0);
18695 : :
18696 : 290 : if (TARGET_64BIT)
18697 : : {
18698 : 290 : int size;
18699 : :
18700 : 290 : if (need_endbr)
18701 : : {
18702 : : /* Insert ENDBR64. */
18703 : 1 : mem = adjust_address (m_tramp, SImode, offset);
18704 : 1 : emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
18705 : 1 : offset += 4;
18706 : : }
18707 : :
18708 : : /* Load the function address to r11. Try to load address using
18709 : : the shorter movl instead of movabs. We may want to support
18710 : : movq for kernel mode, but kernel does not use trampolines at
18711 : : the moment. FNADDR is a 32bit address and may not be in
18712 : : DImode when ptr_mode == SImode. Always use movl in this
18713 : : case. */
18714 : 290 : if (ptr_mode == SImode
18715 : 290 : || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
18716 : : {
18717 : 258 : fnaddr = copy_addr_to_reg (fnaddr);
18718 : :
18719 : 258 : mem = adjust_address (m_tramp, HImode, offset);
18720 : 258 : emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
18721 : :
18722 : 258 : mem = adjust_address (m_tramp, SImode, offset + 2);
18723 : 258 : emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
18724 : 258 : offset += 6;
18725 : : }
18726 : : else
18727 : : {
18728 : 32 : mem = adjust_address (m_tramp, HImode, offset);
18729 : 32 : emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
18730 : :
18731 : 32 : mem = adjust_address (m_tramp, DImode, offset + 2);
18732 : 32 : emit_move_insn (mem, fnaddr);
18733 : 32 : offset += 10;
18734 : : }
18735 : :
18736 : : /* Load static chain using movabs to r10. Use the shorter movl
18737 : : instead of movabs when ptr_mode == SImode. */
18738 : 290 : if (ptr_mode == SImode)
18739 : : {
18740 : : opcode = 0xba41;
18741 : : size = 6;
18742 : : }
18743 : : else
18744 : : {
18745 : 290 : opcode = 0xba49;
18746 : 290 : size = 10;
18747 : : }
18748 : :
18749 : 290 : mem = adjust_address (m_tramp, HImode, offset);
18750 : 290 : emit_move_insn (mem, gen_int_mode (opcode, HImode));
18751 : :
18752 : 290 : mem = adjust_address (m_tramp, ptr_mode, offset + 2);
18753 : 290 : emit_move_insn (mem, chain_value);
18754 : 290 : offset += size;
18755 : :
18756 : : /* Jump to r11; the last (unused) byte is a nop, only there to
18757 : : pad the write out to a single 32-bit store. */
18758 : 290 : mem = adjust_address (m_tramp, SImode, offset);
18759 : 290 : emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
18760 : 290 : offset += 4;
18761 : : }
18762 : : else
18763 : : {
18764 : 0 : rtx disp, chain;
18765 : :
18766 : : /* Depending on the static chain location, either load a register
18767 : : with a constant, or push the constant to the stack. All of the
18768 : : instructions are the same size. */
18769 : 0 : chain = ix86_static_chain (fndecl, true);
18770 : 0 : if (REG_P (chain))
18771 : : {
18772 : 0 : switch (REGNO (chain))
18773 : : {
18774 : : case AX_REG:
18775 : : opcode = 0xb8; break;
18776 : 0 : case CX_REG:
18777 : 0 : opcode = 0xb9; break;
18778 : 0 : default:
18779 : 0 : gcc_unreachable ();
18780 : : }
18781 : : }
18782 : : else
18783 : : opcode = 0x68;
18784 : :
18785 : 0 : if (need_endbr)
18786 : : {
18787 : : /* Insert ENDBR32. */
18788 : 0 : mem = adjust_address (m_tramp, SImode, offset);
18789 : 0 : emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
18790 : 0 : offset += 4;
18791 : : }
18792 : :
18793 : 0 : mem = adjust_address (m_tramp, QImode, offset);
18794 : 0 : emit_move_insn (mem, gen_int_mode (opcode, QImode));
18795 : :
18796 : 0 : mem = adjust_address (m_tramp, SImode, offset + 1);
18797 : 0 : emit_move_insn (mem, chain_value);
18798 : 0 : offset += 5;
18799 : :
18800 : 0 : mem = adjust_address (m_tramp, QImode, offset);
18801 : 0 : emit_move_insn (mem, gen_int_mode (0xe9, QImode));
18802 : :
18803 : 0 : mem = adjust_address (m_tramp, SImode, offset + 1);
18804 : :
18805 : : /* Compute offset from the end of the jmp to the target function.
18806 : : In the case in which the trampoline stores the static chain on
18807 : : the stack, we need to skip the first insn which pushes the
18808 : : (call-saved) register static chain; this push is 1 byte. */
18809 : 0 : offset += 5;
18810 : 0 : int skip = MEM_P (chain) ? 1 : 0;
18811 : : /* Skip ENDBR32 at the entry of the target function. */
18812 : 0 : if (need_endbr
18813 : 0 : && !cgraph_node::get (fndecl)->only_called_directly_p ())
18814 : 0 : skip += 4;
18815 : 0 : disp = expand_binop (SImode, sub_optab, fnaddr,
18816 : 0 : plus_constant (Pmode, XEXP (m_tramp, 0),
18817 : 0 : offset - skip),
18818 : : NULL_RTX, 1, OPTAB_DIRECT);
18819 : 0 : emit_move_insn (mem, disp);
18820 : : }
18821 : :
18822 : 290 : gcc_assert (offset <= TRAMPOLINE_SIZE);
18823 : :
18824 : : #ifdef HAVE_ENABLE_EXECUTE_STACK
18825 : : #ifdef CHECK_EXECUTE_STACK_ENABLED
18826 : : if (CHECK_EXECUTE_STACK_ENABLED)
18827 : : #endif
18828 : : emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
18829 : : LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
18830 : : #endif
18831 : 290 : }
18832 : :
18833 : : static bool
18834 : 53724774 : ix86_allocate_stack_slots_for_args (void)
18835 : : {
18836 : : /* Naked functions should not allocate stack slots for arguments. */
18837 : 53724774 : return !ix86_function_naked (current_function_decl);
18838 : : }
18839 : :
18840 : : static bool
18841 : 33019238 : ix86_warn_func_return (tree decl)
18842 : : {
18843 : : /* Naked functions are implemented entirely in assembly, including the
18844 : : return sequence, so suppress warnings about this. */
18845 : 33019238 : return !ix86_function_naked (decl);
18846 : : }
18847 : :
18848 : : /* Return the shift count of a vector by scalar shift builtin second argument
18849 : : ARG1. */
18850 : : static tree
18851 : 14142 : ix86_vector_shift_count (tree arg1)
18852 : : {
18853 : 14142 : if (tree_fits_uhwi_p (arg1))
18854 : : return arg1;
18855 : 8316 : else if (TREE_CODE (arg1) == VECTOR_CST && CHAR_BIT == 8)
18856 : : {
18857 : : /* The count argument is weird, passed in as various 128-bit
18858 : : (or 64-bit) vectors, the low 64 bits from it are the count. */
18859 : 162 : unsigned char buf[16];
18860 : 162 : int len = native_encode_expr (arg1, buf, 16);
18861 : 162 : if (len == 0)
18862 : 162 : return NULL_TREE;
18863 : 162 : tree t = native_interpret_expr (uint64_type_node, buf, len);
18864 : 162 : if (t && tree_fits_uhwi_p (t))
18865 : : return t;
18866 : : }
18867 : : return NULL_TREE;
18868 : : }
18869 : :
18870 : : /* Return true if arg_mask is all ones, ELEMS is elements number of
18871 : : corresponding vector. */
18872 : : static bool
18873 : 25032 : ix86_masked_all_ones (unsigned HOST_WIDE_INT elems, tree arg_mask)
18874 : : {
18875 : 25032 : if (TREE_CODE (arg_mask) != INTEGER_CST)
18876 : : return false;
18877 : :
18878 : 7452 : unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg_mask);
18879 : 7452 : if (elems == HOST_BITS_PER_WIDE_INT)
18880 : 33 : return mask == HOST_WIDE_INT_M1U;
18881 : 7419 : if ((mask | (HOST_WIDE_INT_M1U << elems)) != HOST_WIDE_INT_M1U)
18882 : 2671 : return false;
18883 : :
18884 : : return true;
18885 : : }
18886 : :
18887 : : static tree
18888 : 66006177 : ix86_fold_builtin (tree fndecl, int n_args,
18889 : : tree *args, bool ignore ATTRIBUTE_UNUSED)
18890 : : {
18891 : 66006177 : if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
18892 : : {
18893 : 66006177 : enum ix86_builtins fn_code
18894 : 66006177 : = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
18895 : 66006177 : enum rtx_code rcode;
18896 : 66006177 : bool is_vshift;
18897 : 66006177 : enum tree_code tcode;
18898 : 66006177 : bool is_scalar;
18899 : 66006177 : unsigned HOST_WIDE_INT mask;
18900 : :
18901 : 66006177 : switch (fn_code)
18902 : : {
18903 : 8362 : case IX86_BUILTIN_CPU_IS:
18904 : 8362 : case IX86_BUILTIN_CPU_SUPPORTS:
18905 : 8362 : gcc_assert (n_args == 1);
18906 : 8362 : return fold_builtin_cpu (fndecl, args);
18907 : :
18908 : 21907 : case IX86_BUILTIN_NANQ:
18909 : 21907 : case IX86_BUILTIN_NANSQ:
18910 : 21907 : {
18911 : 21907 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18912 : 21907 : const char *str = c_getstr (*args);
18913 : 21907 : int quiet = fn_code == IX86_BUILTIN_NANQ;
18914 : 21907 : REAL_VALUE_TYPE real;
18915 : :
18916 : 21907 : if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
18917 : 21907 : return build_real (type, real);
18918 : 0 : return NULL_TREE;
18919 : : }
18920 : :
18921 : 108 : case IX86_BUILTIN_INFQ:
18922 : 108 : case IX86_BUILTIN_HUGE_VALQ:
18923 : 108 : {
18924 : 108 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18925 : 108 : REAL_VALUE_TYPE inf;
18926 : 108 : real_inf (&inf);
18927 : 108 : return build_real (type, inf);
18928 : : }
18929 : :
18930 : 60497 : case IX86_BUILTIN_TZCNT16:
18931 : 60497 : case IX86_BUILTIN_CTZS:
18932 : 60497 : case IX86_BUILTIN_TZCNT32:
18933 : 60497 : case IX86_BUILTIN_TZCNT64:
18934 : 60497 : gcc_assert (n_args == 1);
18935 : 60497 : if (TREE_CODE (args[0]) == INTEGER_CST)
18936 : : {
18937 : 45 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18938 : 45 : tree arg = args[0];
18939 : 45 : if (fn_code == IX86_BUILTIN_TZCNT16
18940 : 45 : || fn_code == IX86_BUILTIN_CTZS)
18941 : 3 : arg = fold_convert (short_unsigned_type_node, arg);
18942 : 45 : if (integer_zerop (arg))
18943 : 6 : return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
18944 : : else
18945 : 39 : return fold_const_call (CFN_CTZ, type, arg);
18946 : : }
18947 : : break;
18948 : :
18949 : 50345 : case IX86_BUILTIN_LZCNT16:
18950 : 50345 : case IX86_BUILTIN_CLZS:
18951 : 50345 : case IX86_BUILTIN_LZCNT32:
18952 : 50345 : case IX86_BUILTIN_LZCNT64:
18953 : 50345 : gcc_assert (n_args == 1);
18954 : 50345 : if (TREE_CODE (args[0]) == INTEGER_CST)
18955 : : {
18956 : 54 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18957 : 54 : tree arg = args[0];
18958 : 54 : if (fn_code == IX86_BUILTIN_LZCNT16
18959 : 54 : || fn_code == IX86_BUILTIN_CLZS)
18960 : 18 : arg = fold_convert (short_unsigned_type_node, arg);
18961 : 54 : if (integer_zerop (arg))
18962 : 3 : return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
18963 : : else
18964 : 51 : return fold_const_call (CFN_CLZ, type, arg);
18965 : : }
18966 : : break;
18967 : :
18968 : 59433 : case IX86_BUILTIN_BEXTR32:
18969 : 59433 : case IX86_BUILTIN_BEXTR64:
18970 : 59433 : case IX86_BUILTIN_BEXTRI32:
18971 : 59433 : case IX86_BUILTIN_BEXTRI64:
18972 : 59433 : gcc_assert (n_args == 2);
18973 : 59433 : if (tree_fits_uhwi_p (args[1]))
18974 : : {
18975 : 152 : unsigned HOST_WIDE_INT res = 0;
18976 : 152 : unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
18977 : 152 : unsigned int start = tree_to_uhwi (args[1]);
18978 : 152 : unsigned int len = (start & 0xff00) >> 8;
18979 : 152 : tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
18980 : 152 : start &= 0xff;
18981 : 152 : if (start >= prec || len == 0)
18982 : 111 : return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
18983 : : args[0]);
18984 : 41 : else if (!tree_fits_uhwi_p (args[0]))
18985 : : break;
18986 : : else
18987 : 24 : res = tree_to_uhwi (args[0]) >> start;
18988 : 24 : if (len > prec)
18989 : : len = prec;
18990 : 24 : if (len < HOST_BITS_PER_WIDE_INT)
18991 : 15 : res &= (HOST_WIDE_INT_1U << len) - 1;
18992 : 24 : return build_int_cstu (lhs_type, res);
18993 : : }
18994 : : break;
18995 : :
18996 : 20384 : case IX86_BUILTIN_BZHI32:
18997 : 20384 : case IX86_BUILTIN_BZHI64:
18998 : 20384 : gcc_assert (n_args == 2);
18999 : 20384 : if (tree_fits_uhwi_p (args[1]))
19000 : : {
19001 : 190 : unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
19002 : 190 : tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
19003 : 190 : if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
19004 : : return args[0];
19005 : 190 : if (idx == 0)
19006 : 52 : return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
19007 : : args[0]);
19008 : 138 : if (!tree_fits_uhwi_p (args[0]))
19009 : : break;
19010 : 12 : unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
19011 : 12 : res &= ~(HOST_WIDE_INT_M1U << idx);
19012 : 12 : return build_int_cstu (lhs_type, res);
19013 : : }
19014 : : break;
19015 : :
19016 : 20142 : case IX86_BUILTIN_PDEP32:
19017 : 20142 : case IX86_BUILTIN_PDEP64:
19018 : 20142 : gcc_assert (n_args == 2);
19019 : 20142 : if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
19020 : : {
19021 : 46 : unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
19022 : 46 : unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
19023 : 46 : unsigned HOST_WIDE_INT res = 0;
19024 : 46 : unsigned HOST_WIDE_INT m, k = 1;
19025 : 2990 : for (m = 1; m; m <<= 1)
19026 : 2944 : if ((mask & m) != 0)
19027 : : {
19028 : 1440 : if ((src & k) != 0)
19029 : 789 : res |= m;
19030 : 1440 : k <<= 1;
19031 : : }
19032 : 46 : return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
19033 : : }
19034 : : break;
19035 : :
19036 : 20144 : case IX86_BUILTIN_PEXT32:
19037 : 20144 : case IX86_BUILTIN_PEXT64:
19038 : 20144 : gcc_assert (n_args == 2);
19039 : 20144 : if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
19040 : : {
19041 : 46 : unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
19042 : 46 : unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
19043 : 46 : unsigned HOST_WIDE_INT res = 0;
19044 : 46 : unsigned HOST_WIDE_INT m, k = 1;
19045 : 2990 : for (m = 1; m; m <<= 1)
19046 : 2944 : if ((mask & m) != 0)
19047 : : {
19048 : 2016 : if ((src & m) != 0)
19049 : 1063 : res |= k;
19050 : 2016 : k <<= 1;
19051 : : }
19052 : 46 : return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
19053 : : }
19054 : : break;
19055 : :
19056 : 78970 : case IX86_BUILTIN_MOVMSKPS:
19057 : 78970 : case IX86_BUILTIN_PMOVMSKB:
19058 : 78970 : case IX86_BUILTIN_MOVMSKPD:
19059 : 78970 : case IX86_BUILTIN_PMOVMSKB128:
19060 : 78970 : case IX86_BUILTIN_MOVMSKPD256:
19061 : 78970 : case IX86_BUILTIN_MOVMSKPS256:
19062 : 78970 : case IX86_BUILTIN_PMOVMSKB256:
19063 : 78970 : gcc_assert (n_args == 1);
19064 : 78970 : if (TREE_CODE (args[0]) == VECTOR_CST)
19065 : : {
19066 : : HOST_WIDE_INT res = 0;
19067 : 139 : for (unsigned i = 0; i < VECTOR_CST_NELTS (args[0]); ++i)
19068 : : {
19069 : 124 : tree e = VECTOR_CST_ELT (args[0], i);
19070 : 124 : if (TREE_CODE (e) == INTEGER_CST && !TREE_OVERFLOW (e))
19071 : : {
19072 : 80 : if (wi::neg_p (wi::to_wide (e)))
19073 : 31 : res |= HOST_WIDE_INT_1 << i;
19074 : : }
19075 : 44 : else if (TREE_CODE (e) == REAL_CST && !TREE_OVERFLOW (e))
19076 : : {
19077 : 44 : if (TREE_REAL_CST (e).sign)
19078 : 19 : res |= HOST_WIDE_INT_1 << i;
19079 : : }
19080 : : else
19081 : : return NULL_TREE;
19082 : : }
19083 : 15 : return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
19084 : : }
19085 : : break;
19086 : :
19087 : 641054 : case IX86_BUILTIN_PSLLD:
19088 : 641054 : case IX86_BUILTIN_PSLLD128:
19089 : 641054 : case IX86_BUILTIN_PSLLD128_MASK:
19090 : 641054 : case IX86_BUILTIN_PSLLD256:
19091 : 641054 : case IX86_BUILTIN_PSLLD256_MASK:
19092 : 641054 : case IX86_BUILTIN_PSLLD512:
19093 : 641054 : case IX86_BUILTIN_PSLLDI:
19094 : 641054 : case IX86_BUILTIN_PSLLDI128:
19095 : 641054 : case IX86_BUILTIN_PSLLDI128_MASK:
19096 : 641054 : case IX86_BUILTIN_PSLLDI256:
19097 : 641054 : case IX86_BUILTIN_PSLLDI256_MASK:
19098 : 641054 : case IX86_BUILTIN_PSLLDI512:
19099 : 641054 : case IX86_BUILTIN_PSLLQ:
19100 : 641054 : case IX86_BUILTIN_PSLLQ128:
19101 : 641054 : case IX86_BUILTIN_PSLLQ128_MASK:
19102 : 641054 : case IX86_BUILTIN_PSLLQ256:
19103 : 641054 : case IX86_BUILTIN_PSLLQ256_MASK:
19104 : 641054 : case IX86_BUILTIN_PSLLQ512:
19105 : 641054 : case IX86_BUILTIN_PSLLQI:
19106 : 641054 : case IX86_BUILTIN_PSLLQI128:
19107 : 641054 : case IX86_BUILTIN_PSLLQI128_MASK:
19108 : 641054 : case IX86_BUILTIN_PSLLQI256:
19109 : 641054 : case IX86_BUILTIN_PSLLQI256_MASK:
19110 : 641054 : case IX86_BUILTIN_PSLLQI512:
19111 : 641054 : case IX86_BUILTIN_PSLLW:
19112 : 641054 : case IX86_BUILTIN_PSLLW128:
19113 : 641054 : case IX86_BUILTIN_PSLLW128_MASK:
19114 : 641054 : case IX86_BUILTIN_PSLLW256:
19115 : 641054 : case IX86_BUILTIN_PSLLW256_MASK:
19116 : 641054 : case IX86_BUILTIN_PSLLW512_MASK:
19117 : 641054 : case IX86_BUILTIN_PSLLWI:
19118 : 641054 : case IX86_BUILTIN_PSLLWI128:
19119 : 641054 : case IX86_BUILTIN_PSLLWI128_MASK:
19120 : 641054 : case IX86_BUILTIN_PSLLWI256:
19121 : 641054 : case IX86_BUILTIN_PSLLWI256_MASK:
19122 : 641054 : case IX86_BUILTIN_PSLLWI512_MASK:
19123 : 641054 : rcode = ASHIFT;
19124 : 641054 : is_vshift = false;
19125 : 641054 : goto do_shift;
19126 : 584849 : case IX86_BUILTIN_PSRAD:
19127 : 584849 : case IX86_BUILTIN_PSRAD128:
19128 : 584849 : case IX86_BUILTIN_PSRAD128_MASK:
19129 : 584849 : case IX86_BUILTIN_PSRAD256:
19130 : 584849 : case IX86_BUILTIN_PSRAD256_MASK:
19131 : 584849 : case IX86_BUILTIN_PSRAD512:
19132 : 584849 : case IX86_BUILTIN_PSRADI:
19133 : 584849 : case IX86_BUILTIN_PSRADI128:
19134 : 584849 : case IX86_BUILTIN_PSRADI128_MASK:
19135 : 584849 : case IX86_BUILTIN_PSRADI256:
19136 : 584849 : case IX86_BUILTIN_PSRADI256_MASK:
19137 : 584849 : case IX86_BUILTIN_PSRADI512:
19138 : 584849 : case IX86_BUILTIN_PSRAQ128_MASK:
19139 : 584849 : case IX86_BUILTIN_PSRAQ256_MASK:
19140 : 584849 : case IX86_BUILTIN_PSRAQ512:
19141 : 584849 : case IX86_BUILTIN_PSRAQI128_MASK:
19142 : 584849 : case IX86_BUILTIN_PSRAQI256_MASK:
19143 : 584849 : case IX86_BUILTIN_PSRAQI512:
19144 : 584849 : case IX86_BUILTIN_PSRAW:
19145 : 584849 : case IX86_BUILTIN_PSRAW128:
19146 : 584849 : case IX86_BUILTIN_PSRAW128_MASK:
19147 : 584849 : case IX86_BUILTIN_PSRAW256:
19148 : 584849 : case IX86_BUILTIN_PSRAW256_MASK:
19149 : 584849 : case IX86_BUILTIN_PSRAW512:
19150 : 584849 : case IX86_BUILTIN_PSRAWI:
19151 : 584849 : case IX86_BUILTIN_PSRAWI128:
19152 : 584849 : case IX86_BUILTIN_PSRAWI128_MASK:
19153 : 584849 : case IX86_BUILTIN_PSRAWI256:
19154 : 584849 : case IX86_BUILTIN_PSRAWI256_MASK:
19155 : 584849 : case IX86_BUILTIN_PSRAWI512:
19156 : 584849 : rcode = ASHIFTRT;
19157 : 584849 : is_vshift = false;
19158 : 584849 : goto do_shift;
19159 : 616243 : case IX86_BUILTIN_PSRLD:
19160 : 616243 : case IX86_BUILTIN_PSRLD128:
19161 : 616243 : case IX86_BUILTIN_PSRLD128_MASK:
19162 : 616243 : case IX86_BUILTIN_PSRLD256:
19163 : 616243 : case IX86_BUILTIN_PSRLD256_MASK:
19164 : 616243 : case IX86_BUILTIN_PSRLD512:
19165 : 616243 : case IX86_BUILTIN_PSRLDI:
19166 : 616243 : case IX86_BUILTIN_PSRLDI128:
19167 : 616243 : case IX86_BUILTIN_PSRLDI128_MASK:
19168 : 616243 : case IX86_BUILTIN_PSRLDI256:
19169 : 616243 : case IX86_BUILTIN_PSRLDI256_MASK:
19170 : 616243 : case IX86_BUILTIN_PSRLDI512:
19171 : 616243 : case IX86_BUILTIN_PSRLQ:
19172 : 616243 : case IX86_BUILTIN_PSRLQ128:
19173 : 616243 : case IX86_BUILTIN_PSRLQ128_MASK:
19174 : 616243 : case IX86_BUILTIN_PSRLQ256:
19175 : 616243 : case IX86_BUILTIN_PSRLQ256_MASK:
19176 : 616243 : case IX86_BUILTIN_PSRLQ512:
19177 : 616243 : case IX86_BUILTIN_PSRLQI:
19178 : 616243 : case IX86_BUILTIN_PSRLQI128:
19179 : 616243 : case IX86_BUILTIN_PSRLQI128_MASK:
19180 : 616243 : case IX86_BUILTIN_PSRLQI256:
19181 : 616243 : case IX86_BUILTIN_PSRLQI256_MASK:
19182 : 616243 : case IX86_BUILTIN_PSRLQI512:
19183 : 616243 : case IX86_BUILTIN_PSRLW:
19184 : 616243 : case IX86_BUILTIN_PSRLW128:
19185 : 616243 : case IX86_BUILTIN_PSRLW128_MASK:
19186 : 616243 : case IX86_BUILTIN_PSRLW256:
19187 : 616243 : case IX86_BUILTIN_PSRLW256_MASK:
19188 : 616243 : case IX86_BUILTIN_PSRLW512:
19189 : 616243 : case IX86_BUILTIN_PSRLWI:
19190 : 616243 : case IX86_BUILTIN_PSRLWI128:
19191 : 616243 : case IX86_BUILTIN_PSRLWI128_MASK:
19192 : 616243 : case IX86_BUILTIN_PSRLWI256:
19193 : 616243 : case IX86_BUILTIN_PSRLWI256_MASK:
19194 : 616243 : case IX86_BUILTIN_PSRLWI512:
19195 : 616243 : rcode = LSHIFTRT;
19196 : 616243 : is_vshift = false;
19197 : 616243 : goto do_shift;
19198 : 267582 : case IX86_BUILTIN_PSLLVV16HI:
19199 : 267582 : case IX86_BUILTIN_PSLLVV16SI:
19200 : 267582 : case IX86_BUILTIN_PSLLVV2DI:
19201 : 267582 : case IX86_BUILTIN_PSLLVV2DI_MASK:
19202 : 267582 : case IX86_BUILTIN_PSLLVV32HI:
19203 : 267582 : case IX86_BUILTIN_PSLLVV4DI:
19204 : 267582 : case IX86_BUILTIN_PSLLVV4DI_MASK:
19205 : 267582 : case IX86_BUILTIN_PSLLVV4SI:
19206 : 267582 : case IX86_BUILTIN_PSLLVV4SI_MASK:
19207 : 267582 : case IX86_BUILTIN_PSLLVV8DI:
19208 : 267582 : case IX86_BUILTIN_PSLLVV8HI:
19209 : 267582 : case IX86_BUILTIN_PSLLVV8SI:
19210 : 267582 : case IX86_BUILTIN_PSLLVV8SI_MASK:
19211 : 267582 : rcode = ASHIFT;
19212 : 267582 : is_vshift = true;
19213 : 267582 : goto do_shift;
19214 : 267203 : case IX86_BUILTIN_PSRAVQ128:
19215 : 267203 : case IX86_BUILTIN_PSRAVQ256:
19216 : 267203 : case IX86_BUILTIN_PSRAVV16HI:
19217 : 267203 : case IX86_BUILTIN_PSRAVV16SI:
19218 : 267203 : case IX86_BUILTIN_PSRAVV32HI:
19219 : 267203 : case IX86_BUILTIN_PSRAVV4SI:
19220 : 267203 : case IX86_BUILTIN_PSRAVV4SI_MASK:
19221 : 267203 : case IX86_BUILTIN_PSRAVV8DI:
19222 : 267203 : case IX86_BUILTIN_PSRAVV8HI:
19223 : 267203 : case IX86_BUILTIN_PSRAVV8SI:
19224 : 267203 : case IX86_BUILTIN_PSRAVV8SI_MASK:
19225 : 267203 : rcode = ASHIFTRT;
19226 : 267203 : is_vshift = true;
19227 : 267203 : goto do_shift;
19228 : 267573 : case IX86_BUILTIN_PSRLVV16HI:
19229 : 267573 : case IX86_BUILTIN_PSRLVV16SI:
19230 : 267573 : case IX86_BUILTIN_PSRLVV2DI:
19231 : 267573 : case IX86_BUILTIN_PSRLVV2DI_MASK:
19232 : 267573 : case IX86_BUILTIN_PSRLVV32HI:
19233 : 267573 : case IX86_BUILTIN_PSRLVV4DI:
19234 : 267573 : case IX86_BUILTIN_PSRLVV4DI_MASK:
19235 : 267573 : case IX86_BUILTIN_PSRLVV4SI:
19236 : 267573 : case IX86_BUILTIN_PSRLVV4SI_MASK:
19237 : 267573 : case IX86_BUILTIN_PSRLVV8DI:
19238 : 267573 : case IX86_BUILTIN_PSRLVV8HI:
19239 : 267573 : case IX86_BUILTIN_PSRLVV8SI:
19240 : 267573 : case IX86_BUILTIN_PSRLVV8SI_MASK:
19241 : 267573 : rcode = LSHIFTRT;
19242 : 267573 : is_vshift = true;
19243 : 267573 : goto do_shift;
19244 : :
19245 : 2644504 : do_shift:
19246 : 2644504 : gcc_assert (n_args >= 2);
19247 : 2644504 : if (TREE_CODE (args[0]) != VECTOR_CST)
19248 : : break;
19249 : 916 : mask = HOST_WIDE_INT_M1U;
19250 : 916 : if (n_args > 2)
19251 : : {
19252 : : /* This is masked shift. */
19253 : 667 : if (!tree_fits_uhwi_p (args[n_args - 1])
19254 : 667 : || TREE_SIDE_EFFECTS (args[n_args - 2]))
19255 : : break;
19256 : 667 : mask = tree_to_uhwi (args[n_args - 1]);
19257 : 667 : unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
19258 : 667 : mask |= HOST_WIDE_INT_M1U << elems;
19259 : 667 : if (mask != HOST_WIDE_INT_M1U
19260 : 556 : && TREE_CODE (args[n_args - 2]) != VECTOR_CST)
19261 : : break;
19262 : 633 : if (mask == (HOST_WIDE_INT_M1U << elems))
19263 : : return args[n_args - 2];
19264 : : }
19265 : 879 : if (is_vshift && TREE_CODE (args[1]) != VECTOR_CST)
19266 : : break;
19267 : 879 : if (tree tem = (is_vshift ? integer_one_node
19268 : 879 : : ix86_vector_shift_count (args[1])))
19269 : : {
19270 : 558 : unsigned HOST_WIDE_INT count = tree_to_uhwi (tem);
19271 : 558 : unsigned HOST_WIDE_INT prec
19272 : 558 : = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (args[0])));
19273 : 558 : if (count == 0 && mask == HOST_WIDE_INT_M1U)
19274 : : return args[0];
19275 : 558 : if (count >= prec)
19276 : : {
19277 : 72 : if (rcode == ASHIFTRT)
19278 : 27 : count = prec - 1;
19279 : 45 : else if (mask == HOST_WIDE_INT_M1U)
19280 : 3 : return build_zero_cst (TREE_TYPE (args[0]));
19281 : : }
19282 : 555 : tree countt = NULL_TREE;
19283 : 555 : if (!is_vshift)
19284 : : {
19285 : 377 : if (count >= prec)
19286 : 42 : countt = integer_zero_node;
19287 : : else
19288 : 335 : countt = build_int_cst (integer_type_node, count);
19289 : : }
19290 : 555 : tree_vector_builder builder;
19291 : 555 : if (mask != HOST_WIDE_INT_M1U || is_vshift)
19292 : 392 : builder.new_vector (TREE_TYPE (args[0]),
19293 : 784 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0])),
19294 : : 1);
19295 : : else
19296 : 163 : builder.new_unary_operation (TREE_TYPE (args[0]), args[0],
19297 : : false);
19298 : 555 : unsigned int cnt = builder.encoded_nelts ();
19299 : 5967 : for (unsigned int i = 0; i < cnt; ++i)
19300 : : {
19301 : 5412 : tree elt = VECTOR_CST_ELT (args[0], i);
19302 : 5412 : if (TREE_CODE (elt) != INTEGER_CST || TREE_OVERFLOW (elt))
19303 : 0 : return NULL_TREE;
19304 : 5412 : tree type = TREE_TYPE (elt);
19305 : 5412 : if (rcode == LSHIFTRT)
19306 : 2040 : elt = fold_convert (unsigned_type_for (type), elt);
19307 : 5412 : if (is_vshift)
19308 : : {
19309 : 1846 : countt = VECTOR_CST_ELT (args[1], i);
19310 : 1846 : if (TREE_CODE (countt) != INTEGER_CST
19311 : 1846 : || TREE_OVERFLOW (countt))
19312 : : return NULL_TREE;
19313 : 1846 : if (wi::neg_p (wi::to_wide (countt))
19314 : 3610 : || wi::to_widest (countt) >= prec)
19315 : : {
19316 : 325 : if (rcode == ASHIFTRT)
19317 : 108 : countt = build_int_cst (TREE_TYPE (countt),
19318 : 108 : prec - 1);
19319 : : else
19320 : : {
19321 : 217 : elt = build_zero_cst (TREE_TYPE (elt));
19322 : 217 : countt = build_zero_cst (TREE_TYPE (countt));
19323 : : }
19324 : : }
19325 : : }
19326 : 3566 : else if (count >= prec)
19327 : 504 : elt = build_zero_cst (TREE_TYPE (elt));
19328 : 8950 : elt = const_binop (rcode == ASHIFT
19329 : : ? LSHIFT_EXPR : RSHIFT_EXPR,
19330 : 5412 : TREE_TYPE (elt), elt, countt);
19331 : 5412 : if (!elt || TREE_CODE (elt) != INTEGER_CST)
19332 : : return NULL_TREE;
19333 : 5412 : if (rcode == LSHIFTRT)
19334 : 2040 : elt = fold_convert (type, elt);
19335 : 5412 : if ((mask & (HOST_WIDE_INT_1U << i)) == 0)
19336 : : {
19337 : 1566 : elt = VECTOR_CST_ELT (args[n_args - 2], i);
19338 : 1566 : if (TREE_CODE (elt) != INTEGER_CST
19339 : 1566 : || TREE_OVERFLOW (elt))
19340 : : return NULL_TREE;
19341 : : }
19342 : 5412 : builder.quick_push (elt);
19343 : : }
19344 : 555 : return builder.build ();
19345 : 555 : }
19346 : : break;
19347 : :
19348 : 31770 : case IX86_BUILTIN_MINSS:
19349 : 31770 : case IX86_BUILTIN_MINSH_MASK:
19350 : 31770 : tcode = LT_EXPR;
19351 : 31770 : is_scalar = true;
19352 : 31770 : goto do_minmax;
19353 : :
19354 : 31770 : case IX86_BUILTIN_MAXSS:
19355 : 31770 : case IX86_BUILTIN_MAXSH_MASK:
19356 : 31770 : tcode = GT_EXPR;
19357 : 31770 : is_scalar = true;
19358 : 31770 : goto do_minmax;
19359 : :
19360 : 339753 : case IX86_BUILTIN_MINPS:
19361 : 339753 : case IX86_BUILTIN_MINPD:
19362 : 339753 : case IX86_BUILTIN_MINPS256:
19363 : 339753 : case IX86_BUILTIN_MINPD256:
19364 : 339753 : case IX86_BUILTIN_MINPS512:
19365 : 339753 : case IX86_BUILTIN_MINPD512:
19366 : 339753 : case IX86_BUILTIN_MINPS128_MASK:
19367 : 339753 : case IX86_BUILTIN_MINPD128_MASK:
19368 : 339753 : case IX86_BUILTIN_MINPS256_MASK:
19369 : 339753 : case IX86_BUILTIN_MINPD256_MASK:
19370 : 339753 : case IX86_BUILTIN_MINPH128_MASK:
19371 : 339753 : case IX86_BUILTIN_MINPH256_MASK:
19372 : 339753 : case IX86_BUILTIN_MINPH512_MASK:
19373 : 339753 : tcode = LT_EXPR;
19374 : 339753 : is_scalar = false;
19375 : 339753 : goto do_minmax;
19376 : :
19377 : : case IX86_BUILTIN_MAXPS:
19378 : : case IX86_BUILTIN_MAXPD:
19379 : : case IX86_BUILTIN_MAXPS256:
19380 : : case IX86_BUILTIN_MAXPD256:
19381 : : case IX86_BUILTIN_MAXPS512:
19382 : : case IX86_BUILTIN_MAXPD512:
19383 : : case IX86_BUILTIN_MAXPS128_MASK:
19384 : : case IX86_BUILTIN_MAXPD128_MASK:
19385 : : case IX86_BUILTIN_MAXPS256_MASK:
19386 : : case IX86_BUILTIN_MAXPD256_MASK:
19387 : : case IX86_BUILTIN_MAXPH128_MASK:
19388 : : case IX86_BUILTIN_MAXPH256_MASK:
19389 : : case IX86_BUILTIN_MAXPH512_MASK:
19390 : : tcode = GT_EXPR;
19391 : : is_scalar = false;
19392 : 743066 : do_minmax:
19393 : 743066 : gcc_assert (n_args >= 2);
19394 : 743066 : if (TREE_CODE (args[0]) != VECTOR_CST
19395 : 76 : || TREE_CODE (args[1]) != VECTOR_CST)
19396 : : break;
19397 : 76 : mask = HOST_WIDE_INT_M1U;
19398 : 76 : if (n_args > 2)
19399 : : {
19400 : 36 : gcc_assert (n_args >= 4);
19401 : : /* This is masked minmax. */
19402 : 36 : if (TREE_CODE (args[3]) != INTEGER_CST
19403 : 36 : || TREE_SIDE_EFFECTS (args[2]))
19404 : : break;
19405 : 36 : mask = TREE_INT_CST_LOW (args[3]);
19406 : 36 : unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
19407 : 36 : mask |= HOST_WIDE_INT_M1U << elems;
19408 : 36 : if (mask != HOST_WIDE_INT_M1U
19409 : 32 : && TREE_CODE (args[2]) != VECTOR_CST)
19410 : : break;
19411 : 36 : if (n_args >= 5)
19412 : : {
19413 : 20 : if (!tree_fits_uhwi_p (args[4]))
19414 : : break;
19415 : 20 : if (tree_to_uhwi (args[4]) != 4
19416 : 0 : && tree_to_uhwi (args[4]) != 8)
19417 : : break;
19418 : : }
19419 : 36 : if (mask == (HOST_WIDE_INT_M1U << elems))
19420 : : return args[2];
19421 : : }
19422 : : /* Punt on NaNs, unless exceptions are disabled. */
19423 : 76 : if (HONOR_NANS (args[0])
19424 : 76 : && (n_args < 5 || tree_to_uhwi (args[4]) != 8))
19425 : 184 : for (int i = 0; i < 2; ++i)
19426 : : {
19427 : 134 : unsigned count = vector_cst_encoded_nelts (args[i]);
19428 : 957 : for (unsigned j = 0; j < count; ++j)
19429 : 849 : if (tree_expr_nan_p (VECTOR_CST_ENCODED_ELT (args[i], j)))
19430 : : return NULL_TREE;
19431 : : }
19432 : 50 : {
19433 : 50 : tree res = const_binop (tcode,
19434 : 50 : truth_type_for (TREE_TYPE (args[0])),
19435 : : args[0], args[1]);
19436 : 50 : if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
19437 : : break;
19438 : 50 : res = fold_ternary (VEC_COND_EXPR, TREE_TYPE (args[0]), res,
19439 : : args[0], args[1]);
19440 : 50 : if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
19441 : : break;
19442 : 50 : if (mask != HOST_WIDE_INT_M1U)
19443 : : {
19444 : 32 : unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
19445 : 32 : vec_perm_builder sel (nelts, nelts, 1);
19446 : 328 : for (unsigned int i = 0; i < nelts; i++)
19447 : 296 : if (mask & (HOST_WIDE_INT_1U << i))
19448 : 160 : sel.quick_push (i);
19449 : : else
19450 : 136 : sel.quick_push (nelts + i);
19451 : 32 : vec_perm_indices indices (sel, 2, nelts);
19452 : 32 : res = fold_vec_perm (TREE_TYPE (args[0]), res, args[2],
19453 : : indices);
19454 : 32 : if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
19455 : : break;
19456 : 32 : }
19457 : 50 : if (is_scalar)
19458 : : {
19459 : 10 : unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
19460 : 10 : vec_perm_builder sel (nelts, nelts, 1);
19461 : 10 : sel.quick_push (0);
19462 : 40 : for (unsigned int i = 1; i < nelts; i++)
19463 : 30 : sel.quick_push (nelts + i);
19464 : 10 : vec_perm_indices indices (sel, 2, nelts);
19465 : 10 : res = fold_vec_perm (TREE_TYPE (args[0]), res, args[0],
19466 : : indices);
19467 : 10 : if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
19468 : : break;
19469 : 10 : }
19470 : 50 : return res;
19471 : : }
19472 : :
19473 : : default:
19474 : : break;
19475 : : }
19476 : : }
19477 : :
19478 : : #ifdef SUBTARGET_FOLD_BUILTIN
19479 : : return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
19480 : : #endif
19481 : :
19482 : : return NULL_TREE;
19483 : : }
19484 : :
19485 : : /* Fold a MD builtin (use ix86_fold_builtin for folding into
19486 : : constant) in GIMPLE. */
19487 : :
19488 : : bool
19489 : 1077364 : ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
19490 : : {
19491 : 1077364 : gimple *stmt = gsi_stmt (*gsi), *g;
19492 : 1077364 : gimple_seq stmts = NULL;
19493 : 1077364 : tree fndecl = gimple_call_fndecl (stmt);
19494 : 1077364 : gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
19495 : 1077364 : int n_args = gimple_call_num_args (stmt);
19496 : 1077364 : enum ix86_builtins fn_code
19497 : 1077364 : = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
19498 : 1077364 : tree decl = NULL_TREE;
19499 : 1077364 : tree arg0, arg1, arg2;
19500 : 1077364 : enum rtx_code rcode;
19501 : 1077364 : enum tree_code tcode;
19502 : 1077364 : unsigned HOST_WIDE_INT count;
19503 : 1077364 : bool is_vshift;
19504 : 1077364 : unsigned HOST_WIDE_INT elems;
19505 : 1077364 : location_t loc;
19506 : :
19507 : : /* Don't fold when there's isa mismatch. */
19508 : 1077364 : if (!ix86_check_builtin_isa_match (fn_code, NULL, NULL))
19509 : : return false;
19510 : :
19511 : 1077237 : switch (fn_code)
19512 : : {
19513 : 288 : case IX86_BUILTIN_TZCNT32:
19514 : 288 : decl = builtin_decl_implicit (BUILT_IN_CTZ);
19515 : 288 : goto fold_tzcnt_lzcnt;
19516 : :
19517 : 237 : case IX86_BUILTIN_TZCNT64:
19518 : 237 : decl = builtin_decl_implicit (BUILT_IN_CTZLL);
19519 : 237 : goto fold_tzcnt_lzcnt;
19520 : :
19521 : 215 : case IX86_BUILTIN_LZCNT32:
19522 : 215 : decl = builtin_decl_implicit (BUILT_IN_CLZ);
19523 : 215 : goto fold_tzcnt_lzcnt;
19524 : :
19525 : 224 : case IX86_BUILTIN_LZCNT64:
19526 : 224 : decl = builtin_decl_implicit (BUILT_IN_CLZLL);
19527 : 224 : goto fold_tzcnt_lzcnt;
19528 : :
19529 : 964 : fold_tzcnt_lzcnt:
19530 : 964 : gcc_assert (n_args == 1);
19531 : 964 : arg0 = gimple_call_arg (stmt, 0);
19532 : 964 : if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
19533 : : {
19534 : 799 : int prec = TYPE_PRECISION (TREE_TYPE (arg0));
19535 : : /* If arg0 is provably non-zero, optimize into generic
19536 : : __builtin_c[tl]z{,ll} function the middle-end handles
19537 : : better. */
19538 : 799 : if (!expr_not_equal_to (arg0, wi::zero (prec)))
19539 : : return false;
19540 : :
19541 : 9 : loc = gimple_location (stmt);
19542 : 9 : g = gimple_build_call (decl, 1, arg0);
19543 : 9 : gimple_set_location (g, loc);
19544 : 9 : tree lhs = make_ssa_name (integer_type_node);
19545 : 9 : gimple_call_set_lhs (g, lhs);
19546 : 9 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
19547 : 9 : g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
19548 : 9 : gimple_set_location (g, loc);
19549 : 9 : gsi_replace (gsi, g, false);
19550 : 9 : return true;
19551 : : }
19552 : : break;
19553 : :
19554 : 491 : case IX86_BUILTIN_BZHI32:
19555 : 491 : case IX86_BUILTIN_BZHI64:
19556 : 491 : gcc_assert (n_args == 2);
19557 : 491 : arg1 = gimple_call_arg (stmt, 1);
19558 : 491 : if (tree_fits_uhwi_p (arg1) && gimple_call_lhs (stmt))
19559 : : {
19560 : 195 : unsigned int idx = tree_to_uhwi (arg1) & 0xff;
19561 : 195 : arg0 = gimple_call_arg (stmt, 0);
19562 : 195 : if (idx < TYPE_PRECISION (TREE_TYPE (arg0)))
19563 : : break;
19564 : 31 : loc = gimple_location (stmt);
19565 : 31 : g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
19566 : 31 : gimple_set_location (g, loc);
19567 : 31 : gsi_replace (gsi, g, false);
19568 : 31 : return true;
19569 : : }
19570 : : break;
19571 : :
19572 : 502 : case IX86_BUILTIN_PDEP32:
19573 : 502 : case IX86_BUILTIN_PDEP64:
19574 : 502 : case IX86_BUILTIN_PEXT32:
19575 : 502 : case IX86_BUILTIN_PEXT64:
19576 : 502 : gcc_assert (n_args == 2);
19577 : 502 : arg1 = gimple_call_arg (stmt, 1);
19578 : 502 : if (integer_all_onesp (arg1) && gimple_call_lhs (stmt))
19579 : : {
19580 : 4 : loc = gimple_location (stmt);
19581 : 4 : arg0 = gimple_call_arg (stmt, 0);
19582 : 4 : g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
19583 : 4 : gimple_set_location (g, loc);
19584 : 4 : gsi_replace (gsi, g, false);
19585 : 4 : return true;
19586 : : }
19587 : : break;
19588 : :
19589 : 145 : case IX86_BUILTIN_PBLENDVB256:
19590 : 145 : case IX86_BUILTIN_BLENDVPS256:
19591 : 145 : case IX86_BUILTIN_BLENDVPD256:
19592 : : /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
19593 : : to scalar operations and not combined back. */
19594 : 145 : if (!TARGET_AVX2)
19595 : : break;
19596 : :
19597 : : /* FALLTHRU. */
19598 : 112 : case IX86_BUILTIN_BLENDVPD:
19599 : : /* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
19600 : : w/o sse4.2, it's veclowered to scalar operations and
19601 : : not combined back. */
19602 : 112 : if (!TARGET_SSE4_2)
19603 : : break;
19604 : : /* FALLTHRU. */
19605 : 151 : case IX86_BUILTIN_PBLENDVB128:
19606 : 151 : case IX86_BUILTIN_BLENDVPS:
19607 : 151 : gcc_assert (n_args == 3);
19608 : 151 : arg0 = gimple_call_arg (stmt, 0);
19609 : 151 : arg1 = gimple_call_arg (stmt, 1);
19610 : 151 : arg2 = gimple_call_arg (stmt, 2);
19611 : 151 : if (gimple_call_lhs (stmt))
19612 : : {
19613 : 151 : loc = gimple_location (stmt);
19614 : 151 : tree type = TREE_TYPE (arg2);
19615 : 151 : if (VECTOR_FLOAT_TYPE_P (type))
19616 : : {
19617 : 73 : tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
19618 : 73 : ? intSI_type_node : intDI_type_node;
19619 : 73 : type = get_same_sized_vectype (itype, type);
19620 : : }
19621 : : else
19622 : 78 : type = signed_type_for (type);
19623 : 151 : arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
19624 : 151 : tree zero_vec = build_zero_cst (type);
19625 : 151 : tree cmp_type = truth_type_for (type);
19626 : 151 : tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
19627 : 151 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
19628 : 151 : g = gimple_build_assign (gimple_call_lhs (stmt),
19629 : : VEC_COND_EXPR, cmp,
19630 : : arg1, arg0);
19631 : 151 : gimple_set_location (g, loc);
19632 : 151 : gsi_replace (gsi, g, false);
19633 : : }
19634 : : else
19635 : 0 : gsi_replace (gsi, gimple_build_nop (), false);
19636 : : return true;
19637 : :
19638 : :
19639 : 16 : case IX86_BUILTIN_PCMPEQB128:
19640 : 16 : case IX86_BUILTIN_PCMPEQW128:
19641 : 16 : case IX86_BUILTIN_PCMPEQD128:
19642 : 16 : case IX86_BUILTIN_PCMPEQQ:
19643 : 16 : case IX86_BUILTIN_PCMPEQB256:
19644 : 16 : case IX86_BUILTIN_PCMPEQW256:
19645 : 16 : case IX86_BUILTIN_PCMPEQD256:
19646 : 16 : case IX86_BUILTIN_PCMPEQQ256:
19647 : 16 : tcode = EQ_EXPR;
19648 : 16 : goto do_cmp;
19649 : :
19650 : : case IX86_BUILTIN_PCMPGTB128:
19651 : : case IX86_BUILTIN_PCMPGTW128:
19652 : : case IX86_BUILTIN_PCMPGTD128:
19653 : : case IX86_BUILTIN_PCMPGTQ:
19654 : : case IX86_BUILTIN_PCMPGTB256:
19655 : : case IX86_BUILTIN_PCMPGTW256:
19656 : : case IX86_BUILTIN_PCMPGTD256:
19657 : : case IX86_BUILTIN_PCMPGTQ256:
19658 : : tcode = GT_EXPR;
19659 : :
19660 : 33 : do_cmp:
19661 : 33 : gcc_assert (n_args == 2);
19662 : 33 : arg0 = gimple_call_arg (stmt, 0);
19663 : 33 : arg1 = gimple_call_arg (stmt, 1);
19664 : 33 : if (gimple_call_lhs (stmt))
19665 : : {
19666 : 32 : loc = gimple_location (stmt);
19667 : 32 : tree type = TREE_TYPE (arg0);
19668 : 32 : tree zero_vec = build_zero_cst (type);
19669 : 32 : tree minus_one_vec = build_minus_one_cst (type);
19670 : 32 : tree cmp_type = truth_type_for (type);
19671 : 32 : tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1);
19672 : 32 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
19673 : 32 : g = gimple_build_assign (gimple_call_lhs (stmt),
19674 : : VEC_COND_EXPR, cmp,
19675 : : minus_one_vec, zero_vec);
19676 : 32 : gimple_set_location (g, loc);
19677 : 32 : gsi_replace (gsi, g, false);
19678 : : }
19679 : : else
19680 : 1 : gsi_replace (gsi, gimple_build_nop (), false);
19681 : : return true;
19682 : :
19683 : 9297 : case IX86_BUILTIN_PSLLD:
19684 : 9297 : case IX86_BUILTIN_PSLLD128:
19685 : 9297 : case IX86_BUILTIN_PSLLD128_MASK:
19686 : 9297 : case IX86_BUILTIN_PSLLD256:
19687 : 9297 : case IX86_BUILTIN_PSLLD256_MASK:
19688 : 9297 : case IX86_BUILTIN_PSLLD512:
19689 : 9297 : case IX86_BUILTIN_PSLLDI:
19690 : 9297 : case IX86_BUILTIN_PSLLDI128:
19691 : 9297 : case IX86_BUILTIN_PSLLDI128_MASK:
19692 : 9297 : case IX86_BUILTIN_PSLLDI256:
19693 : 9297 : case IX86_BUILTIN_PSLLDI256_MASK:
19694 : 9297 : case IX86_BUILTIN_PSLLDI512:
19695 : 9297 : case IX86_BUILTIN_PSLLQ:
19696 : 9297 : case IX86_BUILTIN_PSLLQ128:
19697 : 9297 : case IX86_BUILTIN_PSLLQ128_MASK:
19698 : 9297 : case IX86_BUILTIN_PSLLQ256:
19699 : 9297 : case IX86_BUILTIN_PSLLQ256_MASK:
19700 : 9297 : case IX86_BUILTIN_PSLLQ512:
19701 : 9297 : case IX86_BUILTIN_PSLLQI:
19702 : 9297 : case IX86_BUILTIN_PSLLQI128:
19703 : 9297 : case IX86_BUILTIN_PSLLQI128_MASK:
19704 : 9297 : case IX86_BUILTIN_PSLLQI256:
19705 : 9297 : case IX86_BUILTIN_PSLLQI256_MASK:
19706 : 9297 : case IX86_BUILTIN_PSLLQI512:
19707 : 9297 : case IX86_BUILTIN_PSLLW:
19708 : 9297 : case IX86_BUILTIN_PSLLW128:
19709 : 9297 : case IX86_BUILTIN_PSLLW128_MASK:
19710 : 9297 : case IX86_BUILTIN_PSLLW256:
19711 : 9297 : case IX86_BUILTIN_PSLLW256_MASK:
19712 : 9297 : case IX86_BUILTIN_PSLLW512_MASK:
19713 : 9297 : case IX86_BUILTIN_PSLLWI:
19714 : 9297 : case IX86_BUILTIN_PSLLWI128:
19715 : 9297 : case IX86_BUILTIN_PSLLWI128_MASK:
19716 : 9297 : case IX86_BUILTIN_PSLLWI256:
19717 : 9297 : case IX86_BUILTIN_PSLLWI256_MASK:
19718 : 9297 : case IX86_BUILTIN_PSLLWI512_MASK:
19719 : 9297 : rcode = ASHIFT;
19720 : 9297 : is_vshift = false;
19721 : 9297 : goto do_shift;
19722 : 6495 : case IX86_BUILTIN_PSRAD:
19723 : 6495 : case IX86_BUILTIN_PSRAD128:
19724 : 6495 : case IX86_BUILTIN_PSRAD128_MASK:
19725 : 6495 : case IX86_BUILTIN_PSRAD256:
19726 : 6495 : case IX86_BUILTIN_PSRAD256_MASK:
19727 : 6495 : case IX86_BUILTIN_PSRAD512:
19728 : 6495 : case IX86_BUILTIN_PSRADI:
19729 : 6495 : case IX86_BUILTIN_PSRADI128:
19730 : 6495 : case IX86_BUILTIN_PSRADI128_MASK:
19731 : 6495 : case IX86_BUILTIN_PSRADI256:
19732 : 6495 : case IX86_BUILTIN_PSRADI256_MASK:
19733 : 6495 : case IX86_BUILTIN_PSRADI512:
19734 : 6495 : case IX86_BUILTIN_PSRAQ128_MASK:
19735 : 6495 : case IX86_BUILTIN_PSRAQ256_MASK:
19736 : 6495 : case IX86_BUILTIN_PSRAQ512:
19737 : 6495 : case IX86_BUILTIN_PSRAQI128_MASK:
19738 : 6495 : case IX86_BUILTIN_PSRAQI256_MASK:
19739 : 6495 : case IX86_BUILTIN_PSRAQI512:
19740 : 6495 : case IX86_BUILTIN_PSRAW:
19741 : 6495 : case IX86_BUILTIN_PSRAW128:
19742 : 6495 : case IX86_BUILTIN_PSRAW128_MASK:
19743 : 6495 : case IX86_BUILTIN_PSRAW256:
19744 : 6495 : case IX86_BUILTIN_PSRAW256_MASK:
19745 : 6495 : case IX86_BUILTIN_PSRAW512:
19746 : 6495 : case IX86_BUILTIN_PSRAWI:
19747 : 6495 : case IX86_BUILTIN_PSRAWI128:
19748 : 6495 : case IX86_BUILTIN_PSRAWI128_MASK:
19749 : 6495 : case IX86_BUILTIN_PSRAWI256:
19750 : 6495 : case IX86_BUILTIN_PSRAWI256_MASK:
19751 : 6495 : case IX86_BUILTIN_PSRAWI512:
19752 : 6495 : rcode = ASHIFTRT;
19753 : 6495 : is_vshift = false;
19754 : 6495 : goto do_shift;
19755 : 7950 : case IX86_BUILTIN_PSRLD:
19756 : 7950 : case IX86_BUILTIN_PSRLD128:
19757 : 7950 : case IX86_BUILTIN_PSRLD128_MASK:
19758 : 7950 : case IX86_BUILTIN_PSRLD256:
19759 : 7950 : case IX86_BUILTIN_PSRLD256_MASK:
19760 : 7950 : case IX86_BUILTIN_PSRLD512:
19761 : 7950 : case IX86_BUILTIN_PSRLDI:
19762 : 7950 : case IX86_BUILTIN_PSRLDI128:
19763 : 7950 : case IX86_BUILTIN_PSRLDI128_MASK:
19764 : 7950 : case IX86_BUILTIN_PSRLDI256:
19765 : 7950 : case IX86_BUILTIN_PSRLDI256_MASK:
19766 : 7950 : case IX86_BUILTIN_PSRLDI512:
19767 : 7950 : case IX86_BUILTIN_PSRLQ:
19768 : 7950 : case IX86_BUILTIN_PSRLQ128:
19769 : 7950 : case IX86_BUILTIN_PSRLQ128_MASK:
19770 : 7950 : case IX86_BUILTIN_PSRLQ256:
19771 : 7950 : case IX86_BUILTIN_PSRLQ256_MASK:
19772 : 7950 : case IX86_BUILTIN_PSRLQ512:
19773 : 7950 : case IX86_BUILTIN_PSRLQI:
19774 : 7950 : case IX86_BUILTIN_PSRLQI128:
19775 : 7950 : case IX86_BUILTIN_PSRLQI128_MASK:
19776 : 7950 : case IX86_BUILTIN_PSRLQI256:
19777 : 7950 : case IX86_BUILTIN_PSRLQI256_MASK:
19778 : 7950 : case IX86_BUILTIN_PSRLQI512:
19779 : 7950 : case IX86_BUILTIN_PSRLW:
19780 : 7950 : case IX86_BUILTIN_PSRLW128:
19781 : 7950 : case IX86_BUILTIN_PSRLW128_MASK:
19782 : 7950 : case IX86_BUILTIN_PSRLW256:
19783 : 7950 : case IX86_BUILTIN_PSRLW256_MASK:
19784 : 7950 : case IX86_BUILTIN_PSRLW512:
19785 : 7950 : case IX86_BUILTIN_PSRLWI:
19786 : 7950 : case IX86_BUILTIN_PSRLWI128:
19787 : 7950 : case IX86_BUILTIN_PSRLWI128_MASK:
19788 : 7950 : case IX86_BUILTIN_PSRLWI256:
19789 : 7950 : case IX86_BUILTIN_PSRLWI256_MASK:
19790 : 7950 : case IX86_BUILTIN_PSRLWI512:
19791 : 7950 : rcode = LSHIFTRT;
19792 : 7950 : is_vshift = false;
19793 : 7950 : goto do_shift;
19794 : 2384 : case IX86_BUILTIN_PSLLVV16HI:
19795 : 2384 : case IX86_BUILTIN_PSLLVV16SI:
19796 : 2384 : case IX86_BUILTIN_PSLLVV2DI:
19797 : 2384 : case IX86_BUILTIN_PSLLVV2DI_MASK:
19798 : 2384 : case IX86_BUILTIN_PSLLVV32HI:
19799 : 2384 : case IX86_BUILTIN_PSLLVV4DI:
19800 : 2384 : case IX86_BUILTIN_PSLLVV4DI_MASK:
19801 : 2384 : case IX86_BUILTIN_PSLLVV4SI:
19802 : 2384 : case IX86_BUILTIN_PSLLVV4SI_MASK:
19803 : 2384 : case IX86_BUILTIN_PSLLVV8DI:
19804 : 2384 : case IX86_BUILTIN_PSLLVV8HI:
19805 : 2384 : case IX86_BUILTIN_PSLLVV8SI:
19806 : 2384 : case IX86_BUILTIN_PSLLVV8SI_MASK:
19807 : 2384 : rcode = ASHIFT;
19808 : 2384 : is_vshift = true;
19809 : 2384 : goto do_shift;
19810 : 2341 : case IX86_BUILTIN_PSRAVQ128:
19811 : 2341 : case IX86_BUILTIN_PSRAVQ256:
19812 : 2341 : case IX86_BUILTIN_PSRAVV16HI:
19813 : 2341 : case IX86_BUILTIN_PSRAVV16SI:
19814 : 2341 : case IX86_BUILTIN_PSRAVV32HI:
19815 : 2341 : case IX86_BUILTIN_PSRAVV4SI:
19816 : 2341 : case IX86_BUILTIN_PSRAVV4SI_MASK:
19817 : 2341 : case IX86_BUILTIN_PSRAVV8DI:
19818 : 2341 : case IX86_BUILTIN_PSRAVV8HI:
19819 : 2341 : case IX86_BUILTIN_PSRAVV8SI:
19820 : 2341 : case IX86_BUILTIN_PSRAVV8SI_MASK:
19821 : 2341 : rcode = ASHIFTRT;
19822 : 2341 : is_vshift = true;
19823 : 2341 : goto do_shift;
19824 : 2380 : case IX86_BUILTIN_PSRLVV16HI:
19825 : 2380 : case IX86_BUILTIN_PSRLVV16SI:
19826 : 2380 : case IX86_BUILTIN_PSRLVV2DI:
19827 : 2380 : case IX86_BUILTIN_PSRLVV2DI_MASK:
19828 : 2380 : case IX86_BUILTIN_PSRLVV32HI:
19829 : 2380 : case IX86_BUILTIN_PSRLVV4DI:
19830 : 2380 : case IX86_BUILTIN_PSRLVV4DI_MASK:
19831 : 2380 : case IX86_BUILTIN_PSRLVV4SI:
19832 : 2380 : case IX86_BUILTIN_PSRLVV4SI_MASK:
19833 : 2380 : case IX86_BUILTIN_PSRLVV8DI:
19834 : 2380 : case IX86_BUILTIN_PSRLVV8HI:
19835 : 2380 : case IX86_BUILTIN_PSRLVV8SI:
19836 : 2380 : case IX86_BUILTIN_PSRLVV8SI_MASK:
19837 : 2380 : rcode = LSHIFTRT;
19838 : 2380 : is_vshift = true;
19839 : 2380 : goto do_shift;
19840 : :
19841 : 30847 : do_shift:
19842 : 30847 : gcc_assert (n_args >= 2);
19843 : 30847 : if (!gimple_call_lhs (stmt))
19844 : : {
19845 : 1 : gsi_replace (gsi, gimple_build_nop (), false);
19846 : 1 : return true;
19847 : : }
19848 : 30846 : arg0 = gimple_call_arg (stmt, 0);
19849 : 30846 : arg1 = gimple_call_arg (stmt, 1);
19850 : 30846 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
19851 : : /* For masked shift, only optimize if the mask is all ones. */
19852 : 30846 : if (n_args > 2
19853 : 30846 : && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
19854 : : break;
19855 : 16081 : if (is_vshift)
19856 : : {
19857 : 2640 : if (TREE_CODE (arg1) != VECTOR_CST)
19858 : : break;
19859 : 69 : count = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0)));
19860 : 69 : if (integer_zerop (arg1))
19861 : 27 : count = 0;
19862 : 42 : else if (rcode == ASHIFTRT)
19863 : : break;
19864 : : else
19865 : 230 : for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg1); ++i)
19866 : : {
19867 : 212 : tree elt = VECTOR_CST_ELT (arg1, i);
19868 : 212 : if (!wi::neg_p (wi::to_wide (elt))
19869 : 375 : && wi::to_widest (elt) < count)
19870 : 16 : return false;
19871 : : }
19872 : : }
19873 : : else
19874 : : {
19875 : 13441 : arg1 = ix86_vector_shift_count (arg1);
19876 : 13441 : if (!arg1)
19877 : : break;
19878 : 5608 : count = tree_to_uhwi (arg1);
19879 : : }
19880 : 5653 : if (count == 0)
19881 : : {
19882 : : /* Just return the first argument for shift by 0. */
19883 : 93 : loc = gimple_location (stmt);
19884 : 93 : g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
19885 : 93 : gimple_set_location (g, loc);
19886 : 93 : gsi_replace (gsi, g, false);
19887 : 93 : return true;
19888 : : }
19889 : 5560 : if (rcode != ASHIFTRT
19890 : 5560 : && count >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0))))
19891 : : {
19892 : : /* For shift counts equal or greater than precision, except for
19893 : : arithmetic right shift the result is zero. */
19894 : 78 : loc = gimple_location (stmt);
19895 : 78 : g = gimple_build_assign (gimple_call_lhs (stmt),
19896 : 78 : build_zero_cst (TREE_TYPE (arg0)));
19897 : 78 : gimple_set_location (g, loc);
19898 : 78 : gsi_replace (gsi, g, false);
19899 : 78 : return true;
19900 : : }
19901 : : break;
19902 : :
19903 : 531 : case IX86_BUILTIN_SHUFPD512:
19904 : 531 : case IX86_BUILTIN_SHUFPS512:
19905 : 531 : case IX86_BUILTIN_SHUFPD:
19906 : 531 : case IX86_BUILTIN_SHUFPD256:
19907 : 531 : case IX86_BUILTIN_SHUFPS:
19908 : 531 : case IX86_BUILTIN_SHUFPS256:
19909 : 531 : arg0 = gimple_call_arg (stmt, 0);
19910 : 531 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
19911 : : /* This is masked shuffle. Only optimize if the mask is all ones. */
19912 : 531 : if (n_args > 3
19913 : 895 : && !ix86_masked_all_ones (elems,
19914 : 364 : gimple_call_arg (stmt, n_args - 1)))
19915 : : break;
19916 : 203 : arg2 = gimple_call_arg (stmt, 2);
19917 : 203 : if (TREE_CODE (arg2) == INTEGER_CST && gimple_call_lhs (stmt))
19918 : : {
19919 : 146 : unsigned HOST_WIDE_INT shuffle_mask = TREE_INT_CST_LOW (arg2);
19920 : : /* Check valid imm, refer to gcc.target/i386/testimm-10.c. */
19921 : 146 : if (shuffle_mask > 255)
19922 : : return false;
19923 : :
19924 : 144 : machine_mode imode = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (arg0)));
19925 : 144 : loc = gimple_location (stmt);
19926 : 144 : tree itype = (imode == E_DFmode
19927 : 144 : ? long_long_integer_type_node : integer_type_node);
19928 : 144 : tree vtype = build_vector_type (itype, elems);
19929 : 144 : tree_vector_builder elts (vtype, elems, 1);
19930 : :
19931 : :
19932 : : /* Transform integer shuffle_mask to vector perm_mask which
19933 : : is used by vec_perm_expr, refer to shuflp[sd]256/512 in sse.md. */
19934 : 840 : for (unsigned i = 0; i != elems; i++)
19935 : : {
19936 : 696 : unsigned sel_idx;
19937 : : /* Imm[1:0](if VL > 128, then use Imm[3:2],Imm[5:4],Imm[7:6])
19938 : : provide 2 select constrols for each element of the
19939 : : destination. */
19940 : 696 : if (imode == E_DFmode)
19941 : 240 : sel_idx = (i & 1) * elems + (i & ~1)
19942 : 240 : + ((shuffle_mask >> i) & 1);
19943 : : else
19944 : : {
19945 : : /* Imm[7:0](if VL > 128, also use Imm[7:0]) provide 4 select
19946 : : controls for each element of the destination. */
19947 : 456 : unsigned j = i % 4;
19948 : 456 : sel_idx = ((i >> 1) & 1) * elems + (i & ~3)
19949 : 456 : + ((shuffle_mask >> 2 * j) & 3);
19950 : : }
19951 : 696 : elts.quick_push (build_int_cst (itype, sel_idx));
19952 : : }
19953 : :
19954 : 144 : tree perm_mask = elts.build ();
19955 : 144 : arg1 = gimple_call_arg (stmt, 1);
19956 : 144 : g = gimple_build_assign (gimple_call_lhs (stmt),
19957 : : VEC_PERM_EXPR,
19958 : : arg0, arg1, perm_mask);
19959 : 144 : gimple_set_location (g, loc);
19960 : 144 : gsi_replace (gsi, g, false);
19961 : 144 : return true;
19962 : 144 : }
19963 : : // Do not error yet, the constant could be propagated later?
19964 : : break;
19965 : :
19966 : 48 : case IX86_BUILTIN_PABSB:
19967 : 48 : case IX86_BUILTIN_PABSW:
19968 : 48 : case IX86_BUILTIN_PABSD:
19969 : : /* 64-bit vector abs<mode>2 is only supported under TARGET_MMX_WITH_SSE. */
19970 : 48 : if (!TARGET_MMX_WITH_SSE)
19971 : : break;
19972 : : /* FALLTHRU. */
19973 : 2191 : case IX86_BUILTIN_PABSB128:
19974 : 2191 : case IX86_BUILTIN_PABSB256:
19975 : 2191 : case IX86_BUILTIN_PABSB512:
19976 : 2191 : case IX86_BUILTIN_PABSW128:
19977 : 2191 : case IX86_BUILTIN_PABSW256:
19978 : 2191 : case IX86_BUILTIN_PABSW512:
19979 : 2191 : case IX86_BUILTIN_PABSD128:
19980 : 2191 : case IX86_BUILTIN_PABSD256:
19981 : 2191 : case IX86_BUILTIN_PABSD512:
19982 : 2191 : case IX86_BUILTIN_PABSQ128:
19983 : 2191 : case IX86_BUILTIN_PABSQ256:
19984 : 2191 : case IX86_BUILTIN_PABSQ512:
19985 : 2191 : case IX86_BUILTIN_PABSB128_MASK:
19986 : 2191 : case IX86_BUILTIN_PABSB256_MASK:
19987 : 2191 : case IX86_BUILTIN_PABSW128_MASK:
19988 : 2191 : case IX86_BUILTIN_PABSW256_MASK:
19989 : 2191 : case IX86_BUILTIN_PABSD128_MASK:
19990 : 2191 : case IX86_BUILTIN_PABSD256_MASK:
19991 : 2191 : gcc_assert (n_args >= 1);
19992 : 2191 : if (!gimple_call_lhs (stmt))
19993 : : {
19994 : 1 : gsi_replace (gsi, gimple_build_nop (), false);
19995 : 1 : return true;
19996 : : }
19997 : 2190 : arg0 = gimple_call_arg (stmt, 0);
19998 : 2190 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
19999 : : /* For masked ABS, only optimize if the mask is all ones. */
20000 : 2190 : if (n_args > 1
20001 : 2190 : && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
20002 : : break;
20003 : 230 : {
20004 : 230 : tree utype, ures, vce;
20005 : 230 : utype = unsigned_type_for (TREE_TYPE (arg0));
20006 : : /* PABSB/W/D/Q store the unsigned result in dst, use ABSU_EXPR
20007 : : instead of ABS_EXPR to hanlde overflow case(TYPE_MIN). */
20008 : 230 : ures = gimple_build (&stmts, ABSU_EXPR, utype, arg0);
20009 : 230 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
20010 : 230 : loc = gimple_location (stmt);
20011 : 230 : vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg0), ures);
20012 : 230 : g = gimple_build_assign (gimple_call_lhs (stmt),
20013 : : VIEW_CONVERT_EXPR, vce);
20014 : 230 : gsi_replace (gsi, g, false);
20015 : : }
20016 : 230 : return true;
20017 : :
20018 : 2225 : case IX86_BUILTIN_MINPS:
20019 : 2225 : case IX86_BUILTIN_MINPD:
20020 : 2225 : case IX86_BUILTIN_MINPS256:
20021 : 2225 : case IX86_BUILTIN_MINPD256:
20022 : 2225 : case IX86_BUILTIN_MINPS512:
20023 : 2225 : case IX86_BUILTIN_MINPD512:
20024 : 2225 : case IX86_BUILTIN_MINPS128_MASK:
20025 : 2225 : case IX86_BUILTIN_MINPD128_MASK:
20026 : 2225 : case IX86_BUILTIN_MINPS256_MASK:
20027 : 2225 : case IX86_BUILTIN_MINPD256_MASK:
20028 : 2225 : case IX86_BUILTIN_MINPH128_MASK:
20029 : 2225 : case IX86_BUILTIN_MINPH256_MASK:
20030 : 2225 : case IX86_BUILTIN_MINPH512_MASK:
20031 : 2225 : tcode = LT_EXPR;
20032 : 2225 : goto do_minmax;
20033 : :
20034 : : case IX86_BUILTIN_MAXPS:
20035 : : case IX86_BUILTIN_MAXPD:
20036 : : case IX86_BUILTIN_MAXPS256:
20037 : : case IX86_BUILTIN_MAXPD256:
20038 : : case IX86_BUILTIN_MAXPS512:
20039 : : case IX86_BUILTIN_MAXPD512:
20040 : : case IX86_BUILTIN_MAXPS128_MASK:
20041 : : case IX86_BUILTIN_MAXPD128_MASK:
20042 : : case IX86_BUILTIN_MAXPS256_MASK:
20043 : : case IX86_BUILTIN_MAXPD256_MASK:
20044 : : case IX86_BUILTIN_MAXPH128_MASK:
20045 : : case IX86_BUILTIN_MAXPH256_MASK:
20046 : : case IX86_BUILTIN_MAXPH512_MASK:
20047 : : tcode = GT_EXPR;
20048 : 4435 : do_minmax:
20049 : 4435 : gcc_assert (n_args >= 2);
20050 : : /* Without SSE4.1 we often aren't able to pattern match it back to the
20051 : : desired instruction. */
20052 : 4435 : if (!gimple_call_lhs (stmt) || !optimize || !TARGET_SSE4_1)
20053 : : break;
20054 : 3865 : arg0 = gimple_call_arg (stmt, 0);
20055 : 3865 : arg1 = gimple_call_arg (stmt, 1);
20056 : 3865 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
20057 : : /* For masked minmax, only optimize if the mask is all ones. */
20058 : 3865 : if (n_args > 2
20059 : 3865 : && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, 3)))
20060 : : break;
20061 : 647 : if (n_args >= 5)
20062 : : {
20063 : 436 : tree arg4 = gimple_call_arg (stmt, 4);
20064 : 436 : if (!tree_fits_uhwi_p (arg4))
20065 : : break;
20066 : 424 : if (tree_to_uhwi (arg4) == 4)
20067 : : /* Ok. */;
20068 : 416 : else if (tree_to_uhwi (arg4) != 8)
20069 : : /* Invalid round argument. */
20070 : : break;
20071 : 416 : else if (HONOR_NANS (arg0))
20072 : : /* Lowering to comparison would raise exceptions which
20073 : : shouldn't be raised. */
20074 : : break;
20075 : : }
20076 : 219 : {
20077 : 219 : tree type = truth_type_for (TREE_TYPE (arg0));
20078 : 219 : tree cmpres = gimple_build (&stmts, tcode, type, arg0, arg1);
20079 : 219 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
20080 : 219 : g = gimple_build_assign (gimple_call_lhs (stmt),
20081 : : VEC_COND_EXPR, cmpres, arg0, arg1);
20082 : 219 : gsi_replace (gsi, g, false);
20083 : : }
20084 : 219 : return true;
20085 : :
20086 : : default:
20087 : : break;
20088 : : }
20089 : :
20090 : : return false;
20091 : : }
20092 : :
20093 : : /* Handler for an SVML-style interface to
20094 : : a library with vectorized intrinsics. */
20095 : :
20096 : : tree
20097 : 10 : ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
20098 : : {
20099 : 10 : char name[20];
20100 : 10 : tree fntype, new_fndecl, args;
20101 : 10 : unsigned arity;
20102 : 10 : const char *bname;
20103 : 10 : machine_mode el_mode, in_mode;
20104 : 10 : int n, in_n;
20105 : :
20106 : : /* The SVML is suitable for unsafe math only. */
20107 : 10 : if (!flag_unsafe_math_optimizations)
20108 : : return NULL_TREE;
20109 : :
20110 : 10 : el_mode = TYPE_MODE (TREE_TYPE (type_out));
20111 : 10 : n = TYPE_VECTOR_SUBPARTS (type_out);
20112 : 10 : in_mode = TYPE_MODE (TREE_TYPE (type_in));
20113 : 10 : in_n = TYPE_VECTOR_SUBPARTS (type_in);
20114 : 10 : if (el_mode != in_mode
20115 : 10 : || n != in_n)
20116 : : return NULL_TREE;
20117 : :
20118 : 10 : switch (fn)
20119 : : {
20120 : 10 : CASE_CFN_EXP:
20121 : 10 : CASE_CFN_LOG:
20122 : 10 : CASE_CFN_LOG10:
20123 : 10 : CASE_CFN_POW:
20124 : 10 : CASE_CFN_TANH:
20125 : 10 : CASE_CFN_TAN:
20126 : 10 : CASE_CFN_ATAN:
20127 : 10 : CASE_CFN_ATAN2:
20128 : 10 : CASE_CFN_ATANH:
20129 : 10 : CASE_CFN_CBRT:
20130 : 10 : CASE_CFN_SINH:
20131 : 10 : CASE_CFN_SIN:
20132 : 10 : CASE_CFN_ASINH:
20133 : 10 : CASE_CFN_ASIN:
20134 : 10 : CASE_CFN_COSH:
20135 : 10 : CASE_CFN_COS:
20136 : 10 : CASE_CFN_ACOSH:
20137 : 10 : CASE_CFN_ACOS:
20138 : 10 : if ((el_mode != DFmode || n != 2)
20139 : 8 : && (el_mode != SFmode || n != 4))
20140 : : return NULL_TREE;
20141 : 6 : break;
20142 : :
20143 : : default:
20144 : : return NULL_TREE;
20145 : : }
20146 : :
20147 : 6 : tree fndecl = mathfn_built_in (el_mode == DFmode
20148 : : ? double_type_node : float_type_node, fn);
20149 : 6 : bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
20150 : :
20151 : 6 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
20152 : 2 : strcpy (name, "vmlsLn4");
20153 : 4 : else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
20154 : 0 : strcpy (name, "vmldLn2");
20155 : 4 : else if (n == 4)
20156 : : {
20157 : 2 : sprintf (name, "vmls%s", bname+10);
20158 : 2 : name[strlen (name)-1] = '4';
20159 : : }
20160 : : else
20161 : 2 : sprintf (name, "vmld%s2", bname+10);
20162 : :
20163 : : /* Convert to uppercase. */
20164 : 6 : name[4] &= ~0x20;
20165 : :
20166 : 6 : arity = 0;
20167 : 6 : for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
20168 : 0 : arity++;
20169 : :
20170 : 6 : if (arity == 1)
20171 : 0 : fntype = build_function_type_list (type_out, type_in, NULL);
20172 : : else
20173 : 6 : fntype = build_function_type_list (type_out, type_in, type_in, NULL);
20174 : :
20175 : : /* Build a function declaration for the vectorized function. */
20176 : 6 : new_fndecl = build_decl (BUILTINS_LOCATION,
20177 : : FUNCTION_DECL, get_identifier (name), fntype);
20178 : 6 : TREE_PUBLIC (new_fndecl) = 1;
20179 : 6 : DECL_EXTERNAL (new_fndecl) = 1;
20180 : 6 : DECL_IS_NOVOPS (new_fndecl) = 1;
20181 : 6 : TREE_READONLY (new_fndecl) = 1;
20182 : :
20183 : 6 : return new_fndecl;
20184 : : }
20185 : :
20186 : : /* Handler for an ACML-style interface to
20187 : : a library with vectorized intrinsics. */
20188 : :
20189 : : tree
20190 : 3 : ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
20191 : : {
20192 : 3 : char name[20] = "__vr.._";
20193 : 3 : tree fntype, new_fndecl, args;
20194 : 3 : unsigned arity;
20195 : 3 : const char *bname;
20196 : 3 : machine_mode el_mode, in_mode;
20197 : 3 : int n, in_n;
20198 : :
20199 : : /* The ACML is 64bits only and suitable for unsafe math only as
20200 : : it does not correctly support parts of IEEE with the required
20201 : : precision such as denormals. */
20202 : 3 : if (!TARGET_64BIT
20203 : 3 : || !flag_unsafe_math_optimizations)
20204 : : return NULL_TREE;
20205 : :
20206 : 3 : el_mode = TYPE_MODE (TREE_TYPE (type_out));
20207 : 3 : n = TYPE_VECTOR_SUBPARTS (type_out);
20208 : 3 : in_mode = TYPE_MODE (TREE_TYPE (type_in));
20209 : 3 : in_n = TYPE_VECTOR_SUBPARTS (type_in);
20210 : 3 : if (el_mode != in_mode
20211 : 3 : || n != in_n)
20212 : : return NULL_TREE;
20213 : :
20214 : 3 : switch (fn)
20215 : : {
20216 : 3 : CASE_CFN_SIN:
20217 : 3 : CASE_CFN_COS:
20218 : 3 : CASE_CFN_EXP:
20219 : 3 : CASE_CFN_LOG:
20220 : 3 : CASE_CFN_LOG2:
20221 : 3 : CASE_CFN_LOG10:
20222 : 3 : if (el_mode == DFmode && n == 2)
20223 : : {
20224 : 3 : name[4] = 'd';
20225 : 3 : name[5] = '2';
20226 : : }
20227 : 0 : else if (el_mode == SFmode && n == 4)
20228 : : {
20229 : 0 : name[4] = 's';
20230 : 0 : name[5] = '4';
20231 : : }
20232 : : else
20233 : : return NULL_TREE;
20234 : 3 : break;
20235 : :
20236 : : default:
20237 : : return NULL_TREE;
20238 : : }
20239 : :
20240 : 3 : tree fndecl = mathfn_built_in (el_mode == DFmode
20241 : : ? double_type_node : float_type_node, fn);
20242 : 3 : bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
20243 : 3 : sprintf (name + 7, "%s", bname+10);
20244 : :
20245 : 3 : arity = 0;
20246 : 3 : for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
20247 : 0 : arity++;
20248 : :
20249 : 3 : if (arity == 1)
20250 : 0 : fntype = build_function_type_list (type_out, type_in, NULL);
20251 : : else
20252 : 3 : fntype = build_function_type_list (type_out, type_in, type_in, NULL);
20253 : :
20254 : : /* Build a function declaration for the vectorized function. */
20255 : 3 : new_fndecl = build_decl (BUILTINS_LOCATION,
20256 : : FUNCTION_DECL, get_identifier (name), fntype);
20257 : 3 : TREE_PUBLIC (new_fndecl) = 1;
20258 : 3 : DECL_EXTERNAL (new_fndecl) = 1;
20259 : 3 : DECL_IS_NOVOPS (new_fndecl) = 1;
20260 : 3 : TREE_READONLY (new_fndecl) = 1;
20261 : :
20262 : 3 : return new_fndecl;
20263 : : }
20264 : :
20265 : : /* Handler for an AOCL-LibM-style interface to
20266 : : a library with vectorized intrinsics. */
20267 : :
20268 : : tree
20269 : 220 : ix86_veclibabi_aocl (combined_fn fn, tree type_out, tree type_in)
20270 : : {
20271 : 220 : char name[20] = "amd_vr";
20272 : 220 : int name_len = 6;
20273 : 220 : tree fntype, new_fndecl, args;
20274 : 220 : unsigned arity;
20275 : 220 : const char *bname;
20276 : 220 : machine_mode el_mode, in_mode;
20277 : 220 : int n, in_n;
20278 : :
20279 : : /* AOCL-LibM is 64bits only. It is also only suitable for unsafe math only
20280 : : as it trades off some accuracy for increased performance. */
20281 : 220 : if (!TARGET_64BIT
20282 : 220 : || !flag_unsafe_math_optimizations)
20283 : : return NULL_TREE;
20284 : :
20285 : 220 : el_mode = TYPE_MODE (TREE_TYPE (type_out));
20286 : 220 : n = TYPE_VECTOR_SUBPARTS (type_out);
20287 : 220 : in_mode = TYPE_MODE (TREE_TYPE (type_in));
20288 : 220 : in_n = TYPE_VECTOR_SUBPARTS (type_in);
20289 : 220 : if (el_mode != in_mode
20290 : 220 : || n != in_n)
20291 : : return NULL_TREE;
20292 : :
20293 : 220 : gcc_checking_assert (n > 0);
20294 : :
20295 : : /* Decide whether there exists a function for the combination of FN, the mode
20296 : : and the vector width. Return early if it doesn't. */
20297 : :
20298 : 220 : if (el_mode != DFmode && el_mode != SFmode)
20299 : : return NULL_TREE;
20300 : :
20301 : : /* Supported vector widths for given FN and single/double precision. Zeros
20302 : : are used to fill out unused positions in the arrays. */
20303 : 220 : static const int supported_n[][2][3] = {
20304 : : /* Single prec. , Double prec. */
20305 : : { { 16, 0, 0 }, { 2, 4, 8 } }, /* TAN. */
20306 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* EXP. */
20307 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* EXP2. */
20308 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* LOG. */
20309 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* LOG2. */
20310 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* COS. */
20311 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* SIN. */
20312 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* POW. */
20313 : : { { 4, 8, 16 }, { 2, 4, 8 } }, /* ERF. */
20314 : : { { 4, 8, 16 }, { 2, 8, 0 } }, /* ATAN. */
20315 : : { { 4, 8, 16 }, { 2, 0, 0 } }, /* LOG10. */
20316 : : { { 4, 0, 0 }, { 2, 0, 0 } }, /* EXP10. */
20317 : : { { 4, 0, 0 }, { 2, 0, 0 } }, /* LOG1P. */
20318 : : { { 4, 8, 16 }, { 8, 0, 0 } }, /* ASIN. */
20319 : : { { 4, 16, 0 }, { 0, 0, 0 } }, /* ACOS. */
20320 : : { { 4, 8, 16 }, { 0, 0, 0 } }, /* TANH. */
20321 : : { { 4, 0, 0 }, { 0, 0, 0 } }, /* EXPM1. */
20322 : : { { 4, 8, 0 }, { 0, 0, 0 } }, /* COSH. */
20323 : : };
20324 : :
20325 : : /* We cannot simply index the supported_n array with FN since multiple FNs
20326 : : may correspond to a single operation (see the definitions of these
20327 : : CASE_CFN_* macros). */
20328 : 220 : int i;
20329 : 220 : switch (fn)
20330 : : {
20331 : : CASE_CFN_TAN : i = 0; break;
20332 : 16 : CASE_CFN_EXP : i = 1; break;
20333 : 16 : CASE_CFN_EXP2 : i = 2; break;
20334 : 16 : CASE_CFN_LOG : i = 3; break;
20335 : 16 : CASE_CFN_LOG2 : i = 4; break;
20336 : 16 : CASE_CFN_COS : i = 5; break;
20337 : 16 : CASE_CFN_SIN : i = 6; break;
20338 : 16 : CASE_CFN_POW : i = 7; break;
20339 : 16 : CASE_CFN_ERF : i = 8; break;
20340 : 13 : CASE_CFN_ATAN : i = 9; break;
20341 : 11 : CASE_CFN_LOG10 : i = 10; break;
20342 : 8 : CASE_CFN_EXP10 : i = 11; break;
20343 : 8 : CASE_CFN_LOG1P : i = 12; break;
20344 : 11 : CASE_CFN_ASIN : i = 13; break;
20345 : 7 : CASE_CFN_ACOS : i = 14; break;
20346 : 9 : CASE_CFN_TANH : i = 15; break;
20347 : 7 : CASE_CFN_EXPM1 : i = 16; break;
20348 : 9 : CASE_CFN_COSH : i = 17; break;
20349 : : default: return NULL_TREE;
20350 : : }
20351 : :
20352 : 220 : int j = el_mode == DFmode;
20353 : 220 : bool n_is_supported = false;
20354 : 489 : for (unsigned k = 0; k < 3; k++)
20355 : 470 : if (supported_n[i][j][k] == n)
20356 : : {
20357 : : n_is_supported = true;
20358 : : break;
20359 : : }
20360 : 220 : if (!n_is_supported)
20361 : : return NULL_TREE;
20362 : :
20363 : : /* Append the precision and the vector width to the function name we are
20364 : : constructing. */
20365 : 201 : name[name_len++] = el_mode == DFmode ? 'd' : 's';
20366 : 201 : switch (n)
20367 : : {
20368 : 148 : case 2:
20369 : 148 : case 4:
20370 : 148 : case 8:
20371 : 148 : name[name_len++] = '0' + n;
20372 : 148 : break;
20373 : 53 : case 16:
20374 : 53 : name[name_len++] = '1';
20375 : 53 : name[name_len++] = '6';
20376 : 53 : break;
20377 : 0 : default:
20378 : 0 : gcc_unreachable ();
20379 : : }
20380 : 201 : name[name_len++] = '_';
20381 : :
20382 : : /* Append the operation name (steal it from the name of a builtin). */
20383 : 201 : tree fndecl = mathfn_built_in (el_mode == DFmode
20384 : : ? double_type_node : float_type_node, fn);
20385 : 201 : bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
20386 : 201 : sprintf (name + name_len, "%s", bname + 10);
20387 : :
20388 : 201 : arity = 0;
20389 : 201 : for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
20390 : 0 : arity++;
20391 : :
20392 : 201 : if (arity == 1)
20393 : 0 : fntype = build_function_type_list (type_out, type_in, NULL);
20394 : : else
20395 : 201 : fntype = build_function_type_list (type_out, type_in, type_in, NULL);
20396 : :
20397 : : /* Build a function declaration for the vectorized function. */
20398 : 201 : new_fndecl = build_decl (BUILTINS_LOCATION,
20399 : : FUNCTION_DECL, get_identifier (name), fntype);
20400 : 201 : TREE_PUBLIC (new_fndecl) = 1;
20401 : 201 : DECL_EXTERNAL (new_fndecl) = 1;
20402 : 201 : TREE_READONLY (new_fndecl) = 1;
20403 : :
20404 : 201 : return new_fndecl;
20405 : : }
20406 : :
20407 : : /* Returns a decl of a function that implements scatter store with
20408 : : register type VECTYPE and index type INDEX_TYPE and SCALE.
20409 : : Return NULL_TREE if it is not available. */
20410 : :
20411 : : static tree
20412 : 91872 : ix86_vectorize_builtin_scatter (const_tree vectype,
20413 : : const_tree index_type, int scale)
20414 : : {
20415 : 91872 : bool si;
20416 : 91872 : enum ix86_builtins code;
20417 : :
20418 : 91872 : if (!TARGET_AVX512F)
20419 : : return NULL_TREE;
20420 : :
20421 : 3361 : if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 2u)
20422 : 6086 : ? !TARGET_USE_SCATTER_2PARTS
20423 : 6086 : : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
20424 : 2725 : ? !TARGET_USE_SCATTER_4PARTS
20425 : 1883 : : !TARGET_USE_SCATTER_8PARTS))
20426 : : return NULL_TREE;
20427 : :
20428 : 3361 : if ((TREE_CODE (index_type) != INTEGER_TYPE
20429 : 442 : && !POINTER_TYPE_P (index_type))
20430 : 3803 : || (TYPE_MODE (index_type) != SImode
20431 : 1363 : && TYPE_MODE (index_type) != DImode))
20432 : 0 : return NULL_TREE;
20433 : :
20434 : 3573 : if (TYPE_PRECISION (index_type) > POINTER_SIZE)
20435 : : return NULL_TREE;
20436 : :
20437 : : /* v*scatter* insn sign extends index to pointer mode. */
20438 : 3361 : if (TYPE_PRECISION (index_type) < POINTER_SIZE
20439 : 3361 : && TYPE_UNSIGNED (index_type))
20440 : : return NULL_TREE;
20441 : :
20442 : : /* Scale can be 1, 2, 4 or 8. */
20443 : 3361 : if (scale <= 0
20444 : 3361 : || scale > 8
20445 : 3335 : || (scale & (scale - 1)) != 0)
20446 : : return NULL_TREE;
20447 : :
20448 : 3335 : si = TYPE_MODE (index_type) == SImode;
20449 : 3335 : switch (TYPE_MODE (vectype))
20450 : : {
20451 : 197 : case E_V8DFmode:
20452 : 197 : code = si ? IX86_BUILTIN_SCATTERALTSIV8DF : IX86_BUILTIN_SCATTERDIV8DF;
20453 : : break;
20454 : 125 : case E_V8DImode:
20455 : 125 : code = si ? IX86_BUILTIN_SCATTERALTSIV8DI : IX86_BUILTIN_SCATTERDIV8DI;
20456 : : break;
20457 : 214 : case E_V16SFmode:
20458 : 214 : code = si ? IX86_BUILTIN_SCATTERSIV16SF : IX86_BUILTIN_SCATTERALTDIV16SF;
20459 : : break;
20460 : 244 : case E_V16SImode:
20461 : 244 : code = si ? IX86_BUILTIN_SCATTERSIV16SI : IX86_BUILTIN_SCATTERALTDIV16SI;
20462 : : break;
20463 : 141 : case E_V4DFmode:
20464 : 141 : if (TARGET_AVX512VL)
20465 : 42 : code = si ? IX86_BUILTIN_SCATTERALTSIV4DF : IX86_BUILTIN_SCATTERDIV4DF;
20466 : : else
20467 : : return NULL_TREE;
20468 : : break;
20469 : 127 : case E_V4DImode:
20470 : 127 : if (TARGET_AVX512VL)
20471 : 42 : code = si ? IX86_BUILTIN_SCATTERALTSIV4DI : IX86_BUILTIN_SCATTERDIV4DI;
20472 : : else
20473 : : return NULL_TREE;
20474 : : break;
20475 : 148 : case E_V8SFmode:
20476 : 148 : if (TARGET_AVX512VL)
20477 : 48 : code = si ? IX86_BUILTIN_SCATTERSIV8SF : IX86_BUILTIN_SCATTERALTDIV8SF;
20478 : : else
20479 : : return NULL_TREE;
20480 : : break;
20481 : 228 : case E_V8SImode:
20482 : 228 : if (TARGET_AVX512VL)
20483 : 100 : code = si ? IX86_BUILTIN_SCATTERSIV8SI : IX86_BUILTIN_SCATTERALTDIV8SI;
20484 : : else
20485 : : return NULL_TREE;
20486 : : break;
20487 : 173 : case E_V2DFmode:
20488 : 173 : if (TARGET_AVX512VL)
20489 : 80 : code = si ? IX86_BUILTIN_SCATTERALTSIV2DF : IX86_BUILTIN_SCATTERDIV2DF;
20490 : : else
20491 : : return NULL_TREE;
20492 : : break;
20493 : 159 : case E_V2DImode:
20494 : 159 : if (TARGET_AVX512VL)
20495 : 80 : code = si ? IX86_BUILTIN_SCATTERALTSIV2DI : IX86_BUILTIN_SCATTERDIV2DI;
20496 : : else
20497 : : return NULL_TREE;
20498 : : break;
20499 : 176 : case E_V4SFmode:
20500 : 176 : if (TARGET_AVX512VL)
20501 : 84 : code = si ? IX86_BUILTIN_SCATTERSIV4SF : IX86_BUILTIN_SCATTERALTDIV4SF;
20502 : : else
20503 : : return NULL_TREE;
20504 : : break;
20505 : 260 : case E_V4SImode:
20506 : 260 : if (TARGET_AVX512VL)
20507 : 136 : code = si ? IX86_BUILTIN_SCATTERSIV4SI : IX86_BUILTIN_SCATTERALTDIV4SI;
20508 : : else
20509 : : return NULL_TREE;
20510 : : break;
20511 : : default:
20512 : : return NULL_TREE;
20513 : : }
20514 : :
20515 : 1392 : return get_ix86_builtin (code);
20516 : : }
20517 : :
20518 : : /* Return true if it is safe to use the rsqrt optabs to optimize
20519 : : 1.0/sqrt. */
20520 : :
20521 : : static bool
20522 : 84 : use_rsqrt_p (machine_mode mode)
20523 : : {
20524 : 84 : return ((mode == HFmode
20525 : 36 : || (TARGET_SSE && TARGET_SSE_MATH))
20526 : 84 : && flag_finite_math_only
20527 : 83 : && !flag_trapping_math
20528 : 149 : && flag_unsafe_math_optimizations);
20529 : : }
20530 : :
20531 : : /* Helper for avx_vpermilps256_operand et al. This is also used by
20532 : : the expansion functions to turn the parallel back into a mask.
20533 : : The return value is 0 for no match and the imm8+1 for a match. */
20534 : :
20535 : : int
20536 : 29704 : avx_vpermilp_parallel (rtx par, machine_mode mode)
20537 : : {
20538 : 29704 : unsigned i, nelt = GET_MODE_NUNITS (mode);
20539 : 29704 : unsigned mask = 0;
20540 : 29704 : unsigned char ipar[16] = {}; /* Silence -Wuninitialized warning. */
20541 : :
20542 : 29704 : if (XVECLEN (par, 0) != (int) nelt)
20543 : : return 0;
20544 : :
20545 : : /* Validate that all of the elements are constants, and not totally
20546 : : out of range. Copy the data into an integral array to make the
20547 : : subsequent checks easier. */
20548 : 175494 : for (i = 0; i < nelt; ++i)
20549 : : {
20550 : 145790 : rtx er = XVECEXP (par, 0, i);
20551 : 145790 : unsigned HOST_WIDE_INT ei;
20552 : :
20553 : 145790 : if (!CONST_INT_P (er))
20554 : : return 0;
20555 : 145790 : ei = INTVAL (er);
20556 : 145790 : if (ei >= nelt)
20557 : : return 0;
20558 : 145790 : ipar[i] = ei;
20559 : : }
20560 : :
20561 : 29704 : switch (mode)
20562 : : {
20563 : : case E_V8DFmode:
20564 : : /* In the 512-bit DFmode case, we can only move elements within
20565 : : a 128-bit lane. First fill the second part of the mask,
20566 : : then fallthru. */
20567 : 2070 : for (i = 4; i < 6; ++i)
20568 : : {
20569 : 1438 : if (ipar[i] < 4 || ipar[i] >= 6)
20570 : : return 0;
20571 : 1332 : mask |= (ipar[i] - 4) << i;
20572 : : }
20573 : 1470 : for (i = 6; i < 8; ++i)
20574 : : {
20575 : 1051 : if (ipar[i] < 6)
20576 : : return 0;
20577 : 838 : mask |= (ipar[i] - 6) << i;
20578 : : }
20579 : : /* FALLTHRU */
20580 : :
20581 : : case E_V4DFmode:
20582 : : /* In the 256-bit DFmode case, we can only move elements within
20583 : : a 128-bit lane. */
20584 : 22025 : for (i = 0; i < 2; ++i)
20585 : : {
20586 : 19095 : if (ipar[i] >= 2)
20587 : : return 0;
20588 : 12306 : mask |= ipar[i] << i;
20589 : : }
20590 : 7412 : for (i = 2; i < 4; ++i)
20591 : : {
20592 : 5171 : if (ipar[i] < 2)
20593 : : return 0;
20594 : 4482 : mask |= (ipar[i] - 2) << i;
20595 : : }
20596 : : break;
20597 : :
20598 : : case E_V16SFmode:
20599 : : /* In 512 bit SFmode case, permutation in the upper 256 bits
20600 : : must mirror the permutation in the lower 256-bits. */
20601 : 3705 : for (i = 0; i < 8; ++i)
20602 : 3295 : if (ipar[i] + 8 != ipar[i + 8])
20603 : : return 0;
20604 : : /* FALLTHRU */
20605 : :
20606 : : case E_V8SFmode:
20607 : : /* In 256 bit SFmode case, we have full freedom of
20608 : : movement within the low 128-bit lane, but the high 128-bit
20609 : : lane must mirror the exact same pattern. */
20610 : 27211 : for (i = 0; i < 4; ++i)
20611 : 23745 : if (ipar[i] + 4 != ipar[i + 4])
20612 : : return 0;
20613 : : nelt = 4;
20614 : : /* FALLTHRU */
20615 : :
20616 : 14399 : case E_V2DFmode:
20617 : 14399 : case E_V4SFmode:
20618 : : /* In the 128-bit case, we've full freedom in the placement of
20619 : : the elements from the source operand. */
20620 : 57685 : for (i = 0; i < nelt; ++i)
20621 : 43286 : mask |= ipar[i] << (i * (nelt / 2));
20622 : : break;
20623 : :
20624 : 0 : default:
20625 : 0 : gcc_unreachable ();
20626 : : }
20627 : :
20628 : : /* Make sure success has a non-zero value by adding one. */
20629 : 16640 : return mask + 1;
20630 : : }
20631 : :
20632 : : /* Helper for avx_vperm2f128_v4df_operand et al. This is also used by
20633 : : the expansion functions to turn the parallel back into a mask.
20634 : : The return value is 0 for no match and the imm8+1 for a match. */
20635 : :
20636 : : int
20637 : 52057 : avx_vperm2f128_parallel (rtx par, machine_mode mode)
20638 : : {
20639 : 52057 : unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
20640 : 52057 : unsigned mask = 0;
20641 : 52057 : unsigned char ipar[8] = {}; /* Silence -Wuninitialized warning. */
20642 : :
20643 : 52057 : if (XVECLEN (par, 0) != (int) nelt)
20644 : : return 0;
20645 : :
20646 : : /* Validate that all of the elements are constants, and not totally
20647 : : out of range. Copy the data into an integral array to make the
20648 : : subsequent checks easier. */
20649 : 418705 : for (i = 0; i < nelt; ++i)
20650 : : {
20651 : 366648 : rtx er = XVECEXP (par, 0, i);
20652 : 366648 : unsigned HOST_WIDE_INT ei;
20653 : :
20654 : 366648 : if (!CONST_INT_P (er))
20655 : : return 0;
20656 : 366648 : ei = INTVAL (er);
20657 : 366648 : if (ei >= 2 * nelt)
20658 : : return 0;
20659 : 366648 : ipar[i] = ei;
20660 : : }
20661 : :
20662 : : /* Validate that the halves of the permute are halves. */
20663 : 99292 : for (i = 0; i < nelt2 - 1; ++i)
20664 : 80695 : if (ipar[i] + 1 != ipar[i + 1])
20665 : : return 0;
20666 : 55450 : for (i = nelt2; i < nelt - 1; ++i)
20667 : 38355 : if (ipar[i] + 1 != ipar[i + 1])
20668 : : return 0;
20669 : :
20670 : : /* Reconstruct the mask. */
20671 : 51247 : for (i = 0; i < 2; ++i)
20672 : : {
20673 : 34173 : unsigned e = ipar[i * nelt2];
20674 : 34173 : if (e % nelt2)
20675 : : return 0;
20676 : 34152 : e /= nelt2;
20677 : 34152 : mask |= e << (i * 4);
20678 : : }
20679 : :
20680 : : /* Make sure success has a non-zero value by adding one. */
20681 : 17074 : return mask + 1;
20682 : : }
20683 : :
20684 : : /* Return a mask of VPTERNLOG operands that do not affect output. */
20685 : :
20686 : : int
20687 : 2420 : vpternlog_redundant_operand_mask (rtx pternlog_imm)
20688 : : {
20689 : 2420 : int mask = 0;
20690 : 2420 : int imm8 = INTVAL (pternlog_imm);
20691 : :
20692 : 2420 : if (((imm8 >> 4) & 0x0F) == (imm8 & 0x0F))
20693 : 6 : mask |= 1;
20694 : 2420 : if (((imm8 >> 2) & 0x33) == (imm8 & 0x33))
20695 : 6 : mask |= 2;
20696 : 2420 : if (((imm8 >> 1) & 0x55) == (imm8 & 0x55))
20697 : 147 : mask |= 4;
20698 : :
20699 : 2420 : return mask;
20700 : : }
20701 : :
20702 : : /* Eliminate false dependencies on operands that do not affect output
20703 : : by substituting other operands of a VPTERNLOG. */
20704 : :
20705 : : void
20706 : 77 : substitute_vpternlog_operands (rtx *operands)
20707 : : {
20708 : 77 : int mask = vpternlog_redundant_operand_mask (operands[4]);
20709 : :
20710 : 77 : if (mask & 1) /* The first operand is redundant. */
20711 : 2 : operands[1] = operands[2];
20712 : :
20713 : 77 : if (mask & 2) /* The second operand is redundant. */
20714 : 2 : operands[2] = operands[1];
20715 : :
20716 : 77 : if (mask & 4) /* The third operand is redundant. */
20717 : 73 : operands[3] = operands[1];
20718 : 4 : else if (REG_P (operands[3]))
20719 : : {
20720 : 0 : if (mask & 1)
20721 : 0 : operands[1] = operands[3];
20722 : 0 : if (mask & 2)
20723 : 0 : operands[2] = operands[3];
20724 : : }
20725 : 77 : }
20726 : :
20727 : : /* Return a register priority for hard reg REGNO. */
20728 : : static int
20729 : 58028683 : ix86_register_priority (int hard_regno)
20730 : : {
20731 : : /* ebp and r13 as the base always wants a displacement, r12 as the
20732 : : base always wants an index. So discourage their usage in an
20733 : : address. */
20734 : 58028683 : if (hard_regno == R12_REG || hard_regno == R13_REG)
20735 : : return 0;
20736 : 53513538 : if (hard_regno == BP_REG)
20737 : : return 1;
20738 : : /* New x86-64 int registers result in bigger code size. Discourage them. */
20739 : 51628572 : if (REX_INT_REGNO_P (hard_regno))
20740 : : return 2;
20741 : 35044272 : if (REX2_INT_REGNO_P (hard_regno))
20742 : : return 2;
20743 : : /* New x86-64 SSE registers result in bigger code size. Discourage them. */
20744 : 35041892 : if (REX_SSE_REGNO_P (hard_regno))
20745 : : return 2;
20746 : 29112813 : if (EXT_REX_SSE_REGNO_P (hard_regno))
20747 : : return 1;
20748 : : /* Usage of AX register results in smaller code. Prefer it. */
20749 : 28865298 : if (hard_regno == AX_REG)
20750 : 3810410 : return 4;
20751 : : return 3;
20752 : : }
20753 : :
20754 : : /* Implement TARGET_PREFERRED_RELOAD_CLASS.
20755 : :
20756 : : Put float CONST_DOUBLE in the constant pool instead of fp regs.
20757 : : QImode must go into class Q_REGS.
20758 : : Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
20759 : : movdf to do mem-to-mem moves through integer regs. */
20760 : :
20761 : : static reg_class_t
20762 : 544786295 : ix86_preferred_reload_class (rtx x, reg_class_t regclass)
20763 : : {
20764 : 544786295 : machine_mode mode = GET_MODE (x);
20765 : :
20766 : : /* We're only allowed to return a subclass of CLASS. Many of the
20767 : : following checks fail for NO_REGS, so eliminate that early. */
20768 : 544786295 : if (regclass == NO_REGS)
20769 : : return NO_REGS;
20770 : :
20771 : : /* All classes can load zeros. */
20772 : 543944051 : if (x == CONST0_RTX (mode))
20773 : : return regclass;
20774 : :
20775 : : /* Force constants into memory if we are loading a (nonzero) constant into
20776 : : an MMX, SSE or MASK register. This is because there are no MMX/SSE/MASK
20777 : : instructions to load from a constant. */
20778 : 519086992 : if (CONSTANT_P (x)
20779 : 519086992 : && (MAYBE_MMX_CLASS_P (regclass)
20780 : 151714531 : || MAYBE_SSE_CLASS_P (regclass)
20781 : 121903339 : || MAYBE_MASK_CLASS_P (regclass)))
20782 : 29936692 : return NO_REGS;
20783 : :
20784 : : /* Floating-point constants need more complex checks. */
20785 : 489150300 : if (CONST_DOUBLE_P (x))
20786 : : {
20787 : : /* General regs can load everything. */
20788 : 290220 : if (INTEGER_CLASS_P (regclass))
20789 : : return regclass;
20790 : :
20791 : : /* Floats can load 0 and 1 plus some others. Note that we eliminated
20792 : : zero above. We only want to wind up preferring 80387 registers if
20793 : : we plan on doing computation with them. */
20794 : 177273 : if (IS_STACK_MODE (mode)
20795 : 236005 : && standard_80387_constant_p (x) > 0)
20796 : : {
20797 : : /* Limit class to FP regs. */
20798 : 40470 : if (FLOAT_CLASS_P (regclass))
20799 : : return FLOAT_REGS;
20800 : : }
20801 : :
20802 : 136803 : return NO_REGS;
20803 : : }
20804 : :
20805 : : /* Prefer SSE if we can use them for math. Also allow integer regs
20806 : : when moves between register units are cheap. */
20807 : 488860080 : if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
20808 : : {
20809 : 31512126 : if (TARGET_INTER_UNIT_MOVES_FROM_VEC
20810 : 31497213 : && TARGET_INTER_UNIT_MOVES_TO_VEC
20811 : 94495464 : && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
20812 : 31271516 : return INT_SSE_CLASS_P (regclass) ? regclass : NO_REGS;
20813 : : else
20814 : 240610 : return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
20815 : : }
20816 : :
20817 : : /* Generally when we see PLUS here, it's the function invariant
20818 : : (plus soft-fp const_int). Which can only be computed into general
20819 : : regs. */
20820 : 457347954 : if (GET_CODE (x) == PLUS)
20821 : 1910828 : return INTEGER_CLASS_P (regclass) ? regclass : NO_REGS;
20822 : :
20823 : : /* QImode constants are easy to load, but non-constant QImode data
20824 : : must go into Q_REGS or ALL_MASK_REGS. */
20825 : 455437126 : if (GET_MODE (x) == QImode && !CONSTANT_P (x))
20826 : : {
20827 : 24978388 : if (Q_CLASS_P (regclass))
20828 : : return regclass;
20829 : 20185822 : else if (reg_class_subset_p (Q_REGS, regclass))
20830 : : return Q_REGS;
20831 : 53632 : else if (MASK_CLASS_P (regclass))
20832 : : return regclass;
20833 : : else
20834 : : return NO_REGS;
20835 : : }
20836 : :
20837 : : return regclass;
20838 : : }
20839 : :
20840 : : /* Discourage putting floating-point values in SSE registers unless
20841 : : SSE math is being used, and likewise for the 387 registers. */
20842 : : static reg_class_t
20843 : 73694225 : ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
20844 : : {
20845 : : /* Restrict the output reload class to the register bank that we are doing
20846 : : math on. If we would like not to return a subset of CLASS, reject this
20847 : : alternative: if reload cannot do this, it will still use its choice. */
20848 : 73694225 : machine_mode mode = GET_MODE (x);
20849 : 73694225 : if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
20850 : 7210752 : return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
20851 : :
20852 : 66483473 : if (IS_STACK_MODE (mode))
20853 : 205051 : return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
20854 : :
20855 : : return regclass;
20856 : : }
20857 : :
20858 : : static reg_class_t
20859 : 384247332 : ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
20860 : : machine_mode mode, secondary_reload_info *sri)
20861 : : {
20862 : : /* Double-word spills from general registers to non-offsettable memory
20863 : : references (zero-extended addresses) require special handling. */
20864 : 384247332 : if (TARGET_64BIT
20865 : 331514958 : && MEM_P (x)
20866 : 179390723 : && GET_MODE_SIZE (mode) > UNITS_PER_WORD
20867 : 18466788 : && INTEGER_CLASS_P (rclass)
20868 : 386946653 : && !offsettable_memref_p (x))
20869 : : {
20870 : 2456908 : sri->icode = (in_p
20871 : 1228454 : ? CODE_FOR_reload_noff_load
20872 : : : CODE_FOR_reload_noff_store);
20873 : : /* Add the cost of moving address to a temporary. */
20874 : 1228454 : sri->extra_cost = 1;
20875 : :
20876 : 1228454 : return NO_REGS;
20877 : : }
20878 : :
20879 : : /* QImode spills from non-QI registers require
20880 : : intermediate register on 32bit targets. */
20881 : 383018878 : if (mode == QImode
20882 : 383018878 : && ((!TARGET_64BIT && !in_p
20883 : 571670 : && INTEGER_CLASS_P (rclass)
20884 : 571626 : && MAYBE_NON_Q_CLASS_P (rclass))
20885 : 22710500 : || (!TARGET_AVX512DQ
20886 : 22518029 : && MAYBE_MASK_CLASS_P (rclass))))
20887 : : {
20888 : 6179 : int regno = true_regnum (x);
20889 : :
20890 : : /* Return Q_REGS if the operand is in memory. */
20891 : 6179 : if (regno == -1)
20892 : : return Q_REGS;
20893 : :
20894 : : return NO_REGS;
20895 : : }
20896 : :
20897 : : /* Require movement to gpr, and then store to memory. */
20898 : 383012699 : if ((mode == HFmode || mode == HImode || mode == V2QImode
20899 : : || mode == BFmode)
20900 : 3597696 : && !TARGET_SSE4_1
20901 : 3015010 : && SSE_CLASS_P (rclass)
20902 : 187870 : && !in_p && MEM_P (x))
20903 : : {
20904 : 88808 : sri->extra_cost = 1;
20905 : 88808 : return GENERAL_REGS;
20906 : : }
20907 : :
20908 : : /* This condition handles corner case where an expression involving
20909 : : pointers gets vectorized. We're trying to use the address of a
20910 : : stack slot as a vector initializer.
20911 : :
20912 : : (set (reg:V2DI 74 [ vect_cst_.2 ])
20913 : : (vec_duplicate:V2DI (reg/f:DI 20 frame)))
20914 : :
20915 : : Eventually frame gets turned into sp+offset like this:
20916 : :
20917 : : (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20918 : : (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
20919 : : (const_int 392 [0x188]))))
20920 : :
20921 : : That later gets turned into:
20922 : :
20923 : : (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20924 : : (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
20925 : : (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
20926 : :
20927 : : We'll have the following reload recorded:
20928 : :
20929 : : Reload 0: reload_in (DI) =
20930 : : (plus:DI (reg/f:DI 7 sp)
20931 : : (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
20932 : : reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20933 : : SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
20934 : : reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
20935 : : reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20936 : : reload_reg_rtx: (reg:V2DI 22 xmm1)
20937 : :
20938 : : Which isn't going to work since SSE instructions can't handle scalar
20939 : : additions. Returning GENERAL_REGS forces the addition into integer
20940 : : register and reload can handle subsequent reloads without problems. */
20941 : :
20942 : 221682801 : if (in_p && GET_CODE (x) == PLUS
20943 : 2 : && SSE_CLASS_P (rclass)
20944 : 382923891 : && SCALAR_INT_MODE_P (mode))
20945 : : return GENERAL_REGS;
20946 : :
20947 : : return NO_REGS;
20948 : : }
20949 : :
20950 : : /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
20951 : :
20952 : : static bool
20953 : 711543084 : ix86_class_likely_spilled_p (reg_class_t rclass)
20954 : : {
20955 : 701593322 : switch (rclass)
20956 : : {
20957 : : case AREG:
20958 : : case DREG:
20959 : : case CREG:
20960 : : case BREG:
20961 : : case AD_REGS:
20962 : : case SIREG:
20963 : : case DIREG:
20964 : : case SSE_FIRST_REG:
20965 : : case FP_TOP_REG:
20966 : : case FP_SECOND_REG:
20967 : : return true;
20968 : :
20969 : 679943660 : default:
20970 : 679943660 : break;
20971 : : }
20972 : :
20973 : 679943660 : return false;
20974 : : }
20975 : :
20976 : : /* Implement TARGET_CALLEE_SAVE_COST. */
20977 : :
20978 : : static int
20979 : 83651950 : ix86_callee_save_cost (spill_cost_type, unsigned int hard_regno, machine_mode,
20980 : : unsigned int, int mem_cost, const HARD_REG_SET &, bool)
20981 : : {
20982 : : /* Account for the fact that push and pop are shorter and do their
20983 : : own allocation and deallocation. */
20984 : 83651950 : if (GENERAL_REGNO_P (hard_regno))
20985 : : {
20986 : : /* push is 1 byte while typical spill is 4-5 bytes.
20987 : : ??? We probably should adjust size costs accordingly.
20988 : : Costs are relative to reg-reg move that has 2 bytes for 32bit
20989 : : and 3 bytes otherwise. Be sure that no cost table sets cost
20990 : : to 2, so we end up with 0. */
20991 : 83642632 : if (mem_cost <= 2 || optimize_function_for_size_p (cfun))
20992 : 3579952 : return 1;
20993 : 80062680 : return mem_cost - 2;
20994 : : }
20995 : : return mem_cost;
20996 : : }
20997 : :
20998 : : /* Return true if a set of DST by the expression SRC should be allowed.
20999 : : This prevents complex sets of likely_spilled hard regs before split1. */
21000 : :
21001 : : bool
21002 : 615997347 : ix86_hardreg_mov_ok (rtx dst, rtx src)
21003 : : {
21004 : : /* Avoid complex sets of likely_spilled hard registers before reload. */
21005 : 501846765 : if (REG_P (dst) && HARD_REGISTER_P (dst)
21006 : 292998755 : && !REG_P (src) && !MEM_P (src)
21007 : 96538635 : && !(VECTOR_MODE_P (GET_MODE (dst))
21008 : 96538635 : ? standard_sse_constant_p (src, GET_MODE (dst))
21009 : 48036843 : : x86_64_immediate_operand (src, GET_MODE (dst)))
21010 : 9949762 : && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
21011 : 624697847 : && ix86_pre_reload_split ())
21012 : : return false;
21013 : : return true;
21014 : : }
21015 : :
21016 : : /* If we are copying between registers from different register sets
21017 : : (e.g. FP and integer), we may need a memory location.
21018 : :
21019 : : The function can't work reliably when one of the CLASSES is a class
21020 : : containing registers from multiple sets. We avoid this by never combining
21021 : : different sets in a single alternative in the machine description.
21022 : : Ensure that this constraint holds to avoid unexpected surprises.
21023 : :
21024 : : When STRICT is false, we are being called from REGISTER_MOVE_COST,
21025 : : so do not enforce these sanity checks.
21026 : :
21027 : : To optimize register_move_cost performance, define inline variant. */
21028 : :
21029 : : static inline bool
21030 : 5556453049 : inline_secondary_memory_needed (machine_mode mode, reg_class_t class1,
21031 : : reg_class_t class2, int strict)
21032 : : {
21033 : 5556453049 : if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
21034 : : return false;
21035 : :
21036 : 5524421553 : if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
21037 : 4707931821 : || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
21038 : 4020495274 : || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
21039 : 3836026132 : || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
21040 : 3661452579 : || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
21041 : 3661452579 : || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
21042 : 3661452579 : || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
21043 : 9019523038 : || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
21044 : : {
21045 : 2187834043 : gcc_assert (!strict || lra_in_progress);
21046 : : return true;
21047 : : }
21048 : :
21049 : 3336587510 : if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
21050 : : return true;
21051 : :
21052 : : /* ??? This is a lie. We do have moves between mmx/general, and for
21053 : : mmx/sse2. But by saying we need secondary memory we discourage the
21054 : : register allocator from using the mmx registers unless needed. */
21055 : 3190624048 : if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
21056 : : return true;
21057 : :
21058 : : /* Between mask and general, we have moves no larger than word size. */
21059 : 3096291918 : if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
21060 : : {
21061 : 2514131 : if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2))
21062 : 3294148 : || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21063 : 183377 : return true;
21064 : : }
21065 : :
21066 : 3096108541 : if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
21067 : : {
21068 : : /* SSE1 doesn't have any direct moves from other classes. */
21069 : 672703524 : if (!TARGET_SSE2)
21070 : : return true;
21071 : :
21072 : 670130520 : if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)))
21073 : : return true;
21074 : :
21075 : : /* If the target says that inter-unit moves are more expensive
21076 : : than moving through memory, then don't generate them. */
21077 : 1004779276 : if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC)
21078 : 1004312263 : || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC))
21079 : 1283489 : return true;
21080 : :
21081 : : /* With SSE4.1, *mov{ti,di}_internal supports moves between
21082 : : SSE_REGS and GENERAL_REGS using pinsr{q,d} or pextr{q,d}. */
21083 : 668847031 : if (TARGET_SSE4_1
21084 : 35890296 : && (TARGET_64BIT ? mode == TImode : mode == DImode))
21085 : : return false;
21086 : :
21087 : 667289473 : int msize = GET_MODE_SIZE (mode);
21088 : :
21089 : : /* Between SSE and general, we have moves no larger than word size. */
21090 : 683533246 : if (msize > UNITS_PER_WORD)
21091 : : return true;
21092 : :
21093 : : /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
21094 : : Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16. */
21095 : 577135633 : int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
21096 : :
21097 : 577135633 : if (msize < minsize)
21098 : : return true;
21099 : : }
21100 : :
21101 : : return false;
21102 : : }
21103 : :
21104 : : /* Implement TARGET_SECONDARY_MEMORY_NEEDED. */
21105 : :
21106 : : static bool
21107 : 70844032 : ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1,
21108 : : reg_class_t class2)
21109 : : {
21110 : 70844032 : return inline_secondary_memory_needed (mode, class1, class2, true);
21111 : : }
21112 : :
21113 : : /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
21114 : :
21115 : : get_secondary_mem widens integral modes to BITS_PER_WORD.
21116 : : There is no need to emit full 64 bit move on 64 bit targets
21117 : : for integral modes that can be moved using 32 bit move. */
21118 : :
21119 : : static machine_mode
21120 : 13793 : ix86_secondary_memory_needed_mode (machine_mode mode)
21121 : : {
21122 : 27586 : if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
21123 : 16 : return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
21124 : : return mode;
21125 : : }
21126 : :
21127 : : /* Implement the TARGET_CLASS_MAX_NREGS hook.
21128 : :
21129 : : On the 80386, this is the size of MODE in words,
21130 : : except in the FP regs, where a single reg is always enough. */
21131 : :
21132 : : static unsigned char
21133 : 6114704256 : ix86_class_max_nregs (reg_class_t rclass, machine_mode mode)
21134 : : {
21135 : 6114704256 : if (MAYBE_INTEGER_CLASS_P (rclass))
21136 : : {
21137 : 4105954930 : if (mode == XFmode)
21138 : 143069145 : return (TARGET_64BIT ? 2 : 3);
21139 : 3962885785 : else if (mode == XCmode)
21140 : 143068776 : return (TARGET_64BIT ? 4 : 6);
21141 : : else
21142 : 7747253013 : return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
21143 : : }
21144 : : else
21145 : : {
21146 : 2008749326 : if (COMPLEX_MODE_P (mode))
21147 : : return 2;
21148 : : else
21149 : 1727060639 : return 1;
21150 : : }
21151 : : }
21152 : :
21153 : : /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
21154 : :
21155 : : static bool
21156 : 39596467 : ix86_can_change_mode_class (machine_mode from, machine_mode to,
21157 : : reg_class_t regclass)
21158 : : {
21159 : 39596467 : if (from == to)
21160 : : return true;
21161 : :
21162 : : /* x87 registers can't do subreg at all, as all values are reformatted
21163 : : to extended precision.
21164 : :
21165 : : ??? middle-end queries mode changes for ALL_REGS and this makes
21166 : : vec_series_lowpart_p to always return false. We probably should
21167 : : restrict this to modes supported by i387 and check if it is enabled. */
21168 : 38312987 : if (MAYBE_FLOAT_CLASS_P (regclass))
21169 : : return false;
21170 : :
21171 : 33891367 : if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
21172 : : {
21173 : : /* Vector registers do not support QI or HImode loads. If we don't
21174 : : disallow a change to these modes, reload will assume it's ok to
21175 : : drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
21176 : : the vec_dupv4hi pattern.
21177 : : NB: SSE2 can load 16bit data to sse register via pinsrw. */
21178 : 16560183 : int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
21179 : 16560183 : if (GET_MODE_SIZE (from) < mov_size
21180 : 33120094 : || GET_MODE_SIZE (to) < mov_size)
21181 : : return false;
21182 : : }
21183 : :
21184 : : return true;
21185 : : }
21186 : :
21187 : : /* Return index of MODE in the sse load/store tables. */
21188 : :
21189 : : static inline int
21190 : 766496900 : sse_store_index (machine_mode mode)
21191 : : {
21192 : : /* NB: Use SFmode cost for HFmode instead of adding HFmode load/store
21193 : : costs to processor_costs, which requires changes to all entries in
21194 : : processor cost table. */
21195 : 766496900 : if (mode == E_HFmode)
21196 : 134063450 : mode = E_SFmode;
21197 : :
21198 : 1532993800 : switch (GET_MODE_SIZE (mode))
21199 : : {
21200 : : case 4:
21201 : : return 0;
21202 : : case 8:
21203 : : return 1;
21204 : : case 16:
21205 : : return 2;
21206 : : case 32:
21207 : : return 3;
21208 : : case 64:
21209 : : return 4;
21210 : : default:
21211 : : return -1;
21212 : : }
21213 : : }
21214 : :
21215 : : /* Return the cost of moving data of mode M between a
21216 : : register and memory. A value of 2 is the default; this cost is
21217 : : relative to those in `REGISTER_MOVE_COST'.
21218 : :
21219 : : This function is used extensively by register_move_cost that is used to
21220 : : build tables at startup. Make it inline in this case.
21221 : : When IN is 2, return maximum of in and out move cost.
21222 : :
21223 : : If moving between registers and memory is more expensive than
21224 : : between two registers, you should define this macro to express the
21225 : : relative cost.
21226 : :
21227 : : Model also increased moving costs of QImode registers in non
21228 : : Q_REGS classes.
21229 : : */
21230 : : static inline int
21231 : 6844832676 : inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
21232 : : {
21233 : 6844832676 : int cost;
21234 : :
21235 : 6844832676 : if (FLOAT_CLASS_P (regclass))
21236 : : {
21237 : 352914371 : int index;
21238 : 352914371 : switch (mode)
21239 : : {
21240 : : case E_SFmode:
21241 : : index = 0;
21242 : : break;
21243 : : case E_DFmode:
21244 : : index = 1;
21245 : : break;
21246 : : case E_XFmode:
21247 : : index = 2;
21248 : : break;
21249 : : default:
21250 : : return 100;
21251 : : }
21252 : 103207799 : if (in == 2)
21253 : 99355111 : return MAX (ix86_cost->hard_register.fp_load [index],
21254 : : ix86_cost->hard_register.fp_store [index]);
21255 : 3852688 : return in ? ix86_cost->hard_register.fp_load [index]
21256 : 3852688 : : ix86_cost->hard_register.fp_store [index];
21257 : : }
21258 : 6491918305 : if (SSE_CLASS_P (regclass))
21259 : : {
21260 : 640685574 : int index = sse_store_index (mode);
21261 : 640685574 : if (index == -1)
21262 : : return 100;
21263 : 548327444 : if (in == 2)
21264 : 388592980 : return MAX (ix86_cost->hard_register.sse_load [index],
21265 : : ix86_cost->hard_register.sse_store [index]);
21266 : 159734464 : return in ? ix86_cost->hard_register.sse_load [index]
21267 : 159734464 : : ix86_cost->hard_register.sse_store [index];
21268 : : }
21269 : 5851232731 : if (MASK_CLASS_P (regclass))
21270 : : {
21271 : 110960346 : int index;
21272 : 221920692 : switch (GET_MODE_SIZE (mode))
21273 : : {
21274 : : case 1:
21275 : : index = 0;
21276 : : break;
21277 : 8736409 : case 2:
21278 : 8736409 : index = 1;
21279 : 8736409 : break;
21280 : : /* DImode loads and stores assumed to cost the same as SImode. */
21281 : 39283545 : case 4:
21282 : 39283545 : case 8:
21283 : 39283545 : index = 2;
21284 : 39283545 : break;
21285 : : default:
21286 : : return 100;
21287 : : }
21288 : :
21289 : 51518586 : if (in == 2)
21290 : 568467 : return MAX (ix86_cost->hard_register.mask_load[index],
21291 : : ix86_cost->hard_register.mask_store[index]);
21292 : 50950119 : return in ? ix86_cost->hard_register.mask_load[2]
21293 : 50950119 : : ix86_cost->hard_register.mask_store[2];
21294 : : }
21295 : 5740272385 : if (MMX_CLASS_P (regclass))
21296 : : {
21297 : 171123967 : int index;
21298 : 342247934 : switch (GET_MODE_SIZE (mode))
21299 : : {
21300 : : case 4:
21301 : : index = 0;
21302 : : break;
21303 : 98936459 : case 8:
21304 : 98936459 : index = 1;
21305 : 98936459 : break;
21306 : : default:
21307 : : return 100;
21308 : : }
21309 : 135458911 : if (in == 2)
21310 : 115928025 : return MAX (ix86_cost->hard_register.mmx_load [index],
21311 : : ix86_cost->hard_register.mmx_store [index]);
21312 : 19530886 : return in ? ix86_cost->hard_register.mmx_load [index]
21313 : 19530886 : : ix86_cost->hard_register.mmx_store [index];
21314 : : }
21315 : 11138296836 : switch (GET_MODE_SIZE (mode))
21316 : : {
21317 : 121992631 : case 1:
21318 : 121992631 : if (Q_CLASS_P (regclass) || TARGET_64BIT)
21319 : : {
21320 : 119389401 : if (!in)
21321 : 19151084 : return ix86_cost->hard_register.int_store[0];
21322 : 100238317 : if (TARGET_PARTIAL_REG_DEPENDENCY
21323 : 100238317 : && optimize_function_for_speed_p (cfun))
21324 : 93513418 : cost = ix86_cost->hard_register.movzbl_load;
21325 : : else
21326 : 6724899 : cost = ix86_cost->hard_register.int_load[0];
21327 : 100238317 : if (in == 2)
21328 : 81052290 : return MAX (cost, ix86_cost->hard_register.int_store[0]);
21329 : : return cost;
21330 : : }
21331 : : else
21332 : : {
21333 : 2603230 : if (in == 2)
21334 : 1843550 : return MAX (ix86_cost->hard_register.movzbl_load,
21335 : : ix86_cost->hard_register.int_store[0] + 4);
21336 : 759680 : if (in)
21337 : 379900 : return ix86_cost->hard_register.movzbl_load;
21338 : : else
21339 : 379780 : return ix86_cost->hard_register.int_store[0] + 4;
21340 : : }
21341 : 629669324 : break;
21342 : 629669324 : case 2:
21343 : 629669324 : {
21344 : 629669324 : int cost;
21345 : 629669324 : if (in == 2)
21346 : 531993368 : cost = MAX (ix86_cost->hard_register.int_load[1],
21347 : : ix86_cost->hard_register.int_store[1]);
21348 : : else
21349 : 97675956 : cost = in ? ix86_cost->hard_register.int_load[1]
21350 : : : ix86_cost->hard_register.int_store[1];
21351 : :
21352 : 629669324 : if (mode == E_HFmode)
21353 : : {
21354 : : /* Prefer SSE over GPR for HFmode. */
21355 : 122014382 : int sse_cost;
21356 : 122014382 : int index = sse_store_index (mode);
21357 : 122014382 : if (in == 2)
21358 : 112248888 : sse_cost = MAX (ix86_cost->hard_register.sse_load[index],
21359 : : ix86_cost->hard_register.sse_store[index]);
21360 : : else
21361 : 19530988 : sse_cost = (in
21362 : 9765494 : ? ix86_cost->hard_register.sse_load [index]
21363 : : : ix86_cost->hard_register.sse_store [index]);
21364 : 122014382 : if (sse_cost >= cost)
21365 : 122014382 : cost = sse_cost + 1;
21366 : : }
21367 : : return cost;
21368 : : }
21369 : 4817486463 : default:
21370 : 4817486463 : if (in == 2)
21371 : 3684299163 : cost = MAX (ix86_cost->hard_register.int_load[2],
21372 : : ix86_cost->hard_register.int_store[2]);
21373 : 1133187300 : else if (in)
21374 : 566792244 : cost = ix86_cost->hard_register.int_load[2];
21375 : : else
21376 : 566395056 : cost = ix86_cost->hard_register.int_store[2];
21377 : : /* Multiply with the number of GPR moves needed. */
21378 : 9754326688 : return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
21379 : : }
21380 : : }
21381 : :
21382 : : static int
21383 : 1822131886 : ix86_memory_move_cost (machine_mode mode, reg_class_t regclass, bool in)
21384 : : {
21385 : 2732864566 : return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
21386 : : }
21387 : :
21388 : :
21389 : : /* Return the cost of moving data from a register in class CLASS1 to
21390 : : one in class CLASS2.
21391 : :
21392 : : It is not required that the cost always equal 2 when FROM is the same as TO;
21393 : : on some machines it is expensive to move between registers if they are not
21394 : : general registers. */
21395 : :
21396 : : static int
21397 : 5485609017 : ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
21398 : : reg_class_t class2_i)
21399 : : {
21400 : 5485609017 : enum reg_class class1 = (enum reg_class) class1_i;
21401 : 5485609017 : enum reg_class class2 = (enum reg_class) class2_i;
21402 : :
21403 : : /* In case we require secondary memory, compute cost of the store followed
21404 : : by load. In order to avoid bad register allocation choices, we need
21405 : : for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */
21406 : :
21407 : 5485609017 : if (inline_secondary_memory_needed (mode, class1, class2, false))
21408 : : {
21409 : 2511350395 : int cost = 1;
21410 : :
21411 : 2511350395 : cost += inline_memory_move_cost (mode, class1, 2);
21412 : 2511350395 : cost += inline_memory_move_cost (mode, class2, 2);
21413 : :
21414 : : /* In case of copying from general_purpose_register we may emit multiple
21415 : : stores followed by single load causing memory size mismatch stall.
21416 : : Count this as arbitrarily high cost of 20. */
21417 : 5022700790 : if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD
21418 : 752105279 : && TARGET_MEMORY_MISMATCH_STALL
21419 : 4015560953 : && targetm.class_max_nregs (class1, mode)
21420 : 752105279 : > targetm.class_max_nregs (class2, mode))
21421 : 143134961 : cost += 20;
21422 : :
21423 : : /* In the case of FP/MMX moves, the registers actually overlap, and we
21424 : : have to switch modes in order to treat them differently. */
21425 : 57964049 : if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
21426 : 2560185888 : || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
21427 : 18257112 : cost += 20;
21428 : :
21429 : 2511350395 : return cost;
21430 : : }
21431 : :
21432 : : /* Moves between MMX and non-MMX units require secondary memory. */
21433 : 2974258622 : if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
21434 : 0 : gcc_unreachable ();
21435 : :
21436 : 2974258622 : if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
21437 : 569232464 : return (SSE_CLASS_P (class1)
21438 : 569232464 : ? ix86_cost->hard_register.sse_to_integer
21439 : 569232464 : : ix86_cost->hard_register.integer_to_sse);
21440 : :
21441 : : /* Moves between mask register and GPR. */
21442 : 2405026158 : if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
21443 : : {
21444 : 1027875 : return (MASK_CLASS_P (class1)
21445 : 1027875 : ? ix86_cost->hard_register.mask_to_integer
21446 : 1027875 : : ix86_cost->hard_register.integer_to_mask);
21447 : : }
21448 : : /* Moving between mask registers. */
21449 : 2403998283 : if (MASK_CLASS_P (class1) && MASK_CLASS_P (class2))
21450 : 99180 : return ix86_cost->hard_register.mask_move;
21451 : :
21452 : 2403899103 : if (MAYBE_FLOAT_CLASS_P (class1))
21453 : 11539645 : return ix86_cost->hard_register.fp_move;
21454 : 2392359458 : if (MAYBE_SSE_CLASS_P (class1))
21455 : : {
21456 : 224588592 : if (GET_MODE_BITSIZE (mode) <= 128)
21457 : 109860853 : return ix86_cost->hard_register.xmm_move;
21458 : 4866886 : if (GET_MODE_BITSIZE (mode) <= 256)
21459 : 1544971 : return ix86_cost->hard_register.ymm_move;
21460 : 888472 : return ix86_cost->hard_register.zmm_move;
21461 : : }
21462 : 2280065162 : if (MAYBE_MMX_CLASS_P (class1))
21463 : 2122972 : return ix86_cost->hard_register.mmx_move;
21464 : : return 2;
21465 : : }
21466 : :
21467 : : /* Implement TARGET_HARD_REGNO_NREGS. This is ordinarily the length in
21468 : : words of a value of mode MODE but can be less for certain modes in
21469 : : special long registers.
21470 : :
21471 : : Actually there are no two word move instructions for consecutive
21472 : : registers. And only registers 0-3 may have mov byte instructions
21473 : : applied to them. */
21474 : :
21475 : : static unsigned int
21476 : 9357492040 : ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
21477 : : {
21478 : 9357492040 : if (GENERAL_REGNO_P (regno))
21479 : : {
21480 : 3254779840 : if (mode == XFmode)
21481 : 25510656 : return TARGET_64BIT ? 2 : 3;
21482 : 3229743072 : if (mode == XCmode)
21483 : 25510656 : return TARGET_64BIT ? 4 : 6;
21484 : 6470070272 : return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
21485 : : }
21486 : 6102712200 : if (COMPLEX_MODE_P (mode))
21487 : : return 2;
21488 : : /* Register pair for mask registers. */
21489 : 5351609160 : if (mode == P2QImode || mode == P2HImode)
21490 : : return 2;
21491 : 5257721280 : if (mode == V64SFmode || mode == V64SImode)
21492 : 93887880 : return 4;
21493 : : return 1;
21494 : : }
21495 : :
21496 : : /* Implement REGMODE_NATURAL_SIZE(MODE). */
21497 : : unsigned int
21498 : 106611594 : ix86_regmode_natural_size (machine_mode mode)
21499 : : {
21500 : 106611594 : if (mode == P2HImode || mode == P2QImode)
21501 : 2468 : return GET_MODE_SIZE (mode) / 2;
21502 : 106610360 : return UNITS_PER_WORD;
21503 : : }
21504 : :
21505 : : /* Implement TARGET_HARD_REGNO_MODE_OK. */
21506 : :
21507 : : static bool
21508 : 56473301068 : ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
21509 : : {
21510 : : /* Flags and only flags can only hold CCmode values. */
21511 : 56473301068 : if (CC_REGNO_P (regno))
21512 : 451030890 : return GET_MODE_CLASS (mode) == MODE_CC;
21513 : 56022270178 : if (GET_MODE_CLASS (mode) == MODE_CC
21514 : : || GET_MODE_CLASS (mode) == MODE_RANDOM)
21515 : : return false;
21516 : 50524602596 : if (STACK_REGNO_P (regno))
21517 : 4923640586 : return VALID_FP_MODE_P (mode);
21518 : 45600962010 : if (MASK_REGNO_P (regno))
21519 : : {
21520 : : /* Register pair only starts at even register number. */
21521 : 3859211299 : if ((mode == P2QImode || mode == P2HImode))
21522 : 51054426 : return MASK_PAIR_REGNO_P(regno);
21523 : :
21524 : 1070119217 : return ((TARGET_AVX512F && VALID_MASK_REG_MODE (mode))
21525 : 4857691659 : || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
21526 : : }
21527 : :
21528 : 41741750711 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
21529 : : return false;
21530 : :
21531 : 40769770728 : if (SSE_REGNO_P (regno))
21532 : : {
21533 : : /* We implement the move patterns for all vector modes into and
21534 : : out of SSE registers, even when no operation instructions
21535 : : are available. */
21536 : :
21537 : : /* For AVX-512 we allow, regardless of regno:
21538 : : - XI mode
21539 : : - any of 512-bit wide vector mode
21540 : : - any scalar mode. */
21541 : 17676060174 : if (TARGET_AVX512F
21542 : : && ((VALID_AVX512F_REG_OR_XI_MODE (mode))
21543 : : || VALID_AVX512F_SCALAR_MODE (mode)))
21544 : : return true;
21545 : :
21546 : : /* TODO check for QI/HI scalars. */
21547 : : /* AVX512VL allows sse regs16+ for 128/256 bit modes. */
21548 : 16976848797 : if (TARGET_AVX512VL
21549 : 1887661486 : && (VALID_AVX256_REG_OR_OI_MODE (mode)
21550 : 1673360943 : || VALID_AVX512VL_128_REG_MODE (mode)))
21551 : : return true;
21552 : :
21553 : : /* xmm16-xmm31 are only available for AVX-512. */
21554 : 16526070053 : if (EXT_REX_SSE_REGNO_P (regno))
21555 : : return false;
21556 : :
21557 : : /* OImode and AVX modes are available only when AVX is enabled. */
21558 : 9535360671 : return ((TARGET_AVX
21559 : 2137037976 : && VALID_AVX256_REG_OR_OI_MODE (mode))
21560 : : || VALID_SSE_REG_MODE (mode)
21561 : : || VALID_SSE2_REG_MODE (mode)
21562 : : || VALID_MMX_REG_MODE (mode)
21563 : 9535360671 : || VALID_MMX_REG_MODE_3DNOW (mode));
21564 : : }
21565 : 23093710554 : if (MMX_REGNO_P (regno))
21566 : : {
21567 : : /* We implement the move patterns for 3DNOW modes even in MMX mode,
21568 : : so if the register is available at all, then we can move data of
21569 : : the given mode into or out of it. */
21570 : 4142037207 : return (VALID_MMX_REG_MODE (mode)
21571 : : || VALID_MMX_REG_MODE_3DNOW (mode));
21572 : : }
21573 : :
21574 : 18951673347 : if (mode == QImode)
21575 : : {
21576 : : /* Take care for QImode values - they can be in non-QI regs,
21577 : : but then they do cause partial register stalls. */
21578 : 205032674 : if (ANY_QI_REGNO_P (regno))
21579 : : return true;
21580 : 14245952 : if (!TARGET_PARTIAL_REG_STALL)
21581 : : return true;
21582 : : /* LRA checks if the hard register is OK for the given mode.
21583 : : QImode values can live in non-QI regs, so we allow all
21584 : : registers here. */
21585 : 0 : if (lra_in_progress)
21586 : : return true;
21587 : 0 : return !can_create_pseudo_p ();
21588 : : }
21589 : : /* We handle both integer and floats in the general purpose registers. */
21590 : 18746640673 : else if (VALID_INT_MODE_P (mode)
21591 : 13971394684 : || VALID_FP_MODE_P (mode))
21592 : : return true;
21593 : : /* Lots of MMX code casts 8 byte vector modes to DImode. If we then go
21594 : : on to use that value in smaller contexts, this can easily force a
21595 : : pseudo to be allocated to GENERAL_REGS. Since this is no worse than
21596 : : supporting DImode, allow it. */
21597 : 12921742324 : else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
21598 : : return true;
21599 : :
21600 : : return false;
21601 : : }
21602 : :
21603 : : /* Implement TARGET_INSN_CALLEE_ABI. */
21604 : :
21605 : : const predefined_function_abi &
21606 : 247883605 : ix86_insn_callee_abi (const rtx_insn *insn)
21607 : : {
21608 : 247883605 : unsigned int abi_id = 0;
21609 : 247883605 : rtx pat = PATTERN (insn);
21610 : 247883605 : if (vzeroupper_pattern (pat, VOIDmode))
21611 : 317255 : abi_id = ABI_VZEROUPPER;
21612 : :
21613 : 247883605 : return function_abis[abi_id];
21614 : : }
21615 : :
21616 : : /* Initialize function_abis with corresponding abi_id,
21617 : : currently only handle vzeroupper. */
21618 : : void
21619 : 18165 : ix86_initialize_callee_abi (unsigned int abi_id)
21620 : : {
21621 : 18165 : gcc_assert (abi_id == ABI_VZEROUPPER);
21622 : 18165 : predefined_function_abi &vzeroupper_abi = function_abis[abi_id];
21623 : 18165 : if (!vzeroupper_abi.initialized_p ())
21624 : : {
21625 : : HARD_REG_SET full_reg_clobbers;
21626 : 4069 : CLEAR_HARD_REG_SET (full_reg_clobbers);
21627 : 4069 : vzeroupper_abi.initialize (ABI_VZEROUPPER, full_reg_clobbers);
21628 : : }
21629 : 18165 : }
21630 : :
21631 : : void
21632 : 18165 : ix86_expand_avx_vzeroupper (void)
21633 : : {
21634 : : /* Initialize vzeroupper_abi here. */
21635 : 18165 : ix86_initialize_callee_abi (ABI_VZEROUPPER);
21636 : 18165 : rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
21637 : : /* Return false for non-local goto in can_nonlocal_goto. */
21638 : 18165 : make_reg_eh_region_note (insn, 0, INT_MIN);
21639 : : /* Flag used for call_insn indicates it's a fake call. */
21640 : 18165 : RTX_FLAG (insn, used) = 1;
21641 : 18165 : }
21642 : :
21643 : :
21644 : : /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The only ABI that
21645 : : saves SSE registers across calls is Win64 (thus no need to check the
21646 : : current ABI here), and with AVX enabled Win64 only guarantees that
21647 : : the low 16 bytes are saved. */
21648 : :
21649 : : static bool
21650 : 2041951499 : ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
21651 : : machine_mode mode)
21652 : : {
21653 : : /* Special ABI for vzeroupper which only clobber higher part of sse regs. */
21654 : 2041951499 : if (abi_id == ABI_VZEROUPPER)
21655 : 29342449 : return (GET_MODE_SIZE (mode) > 16
21656 : 29342449 : && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
21657 : 4467874 : || LEGACY_SSE_REGNO_P (regno)));
21658 : :
21659 : 2650676746 : return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
21660 : : }
21661 : :
21662 : : /* A subroutine of ix86_modes_tieable_p. Return true if MODE is a
21663 : : tieable integer mode. */
21664 : :
21665 : : static bool
21666 : 51368446 : ix86_tieable_integer_mode_p (machine_mode mode)
21667 : : {
21668 : 51368446 : switch (mode)
21669 : : {
21670 : : case E_HImode:
21671 : : case E_SImode:
21672 : : return true;
21673 : :
21674 : 5229859 : case E_QImode:
21675 : 5229859 : return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
21676 : :
21677 : 10152887 : case E_DImode:
21678 : 10152887 : return TARGET_64BIT;
21679 : :
21680 : : default:
21681 : : return false;
21682 : : }
21683 : : }
21684 : :
21685 : : /* Implement TARGET_MODES_TIEABLE_P.
21686 : :
21687 : : Return true if MODE1 is accessible in a register that can hold MODE2
21688 : : without copying. That is, all register classes that can hold MODE2
21689 : : can also hold MODE1. */
21690 : :
21691 : : static bool
21692 : 33203186 : ix86_modes_tieable_p (machine_mode mode1, machine_mode mode2)
21693 : : {
21694 : 33203186 : if (mode1 == mode2)
21695 : : return true;
21696 : :
21697 : 33111894 : if (ix86_tieable_integer_mode_p (mode1)
21698 : 33111894 : && ix86_tieable_integer_mode_p (mode2))
21699 : : return true;
21700 : :
21701 : : /* MODE2 being XFmode implies fp stack or general regs, which means we
21702 : : can tie any smaller floating point modes to it. Note that we do not
21703 : : tie this with TFmode. */
21704 : 24342065 : if (mode2 == XFmode)
21705 : 4373 : return mode1 == SFmode || mode1 == DFmode;
21706 : :
21707 : : /* MODE2 being DFmode implies fp stack, general or sse regs, which means
21708 : : that we can tie it with SFmode. */
21709 : 24337692 : if (mode2 == DFmode)
21710 : 257647 : return mode1 == SFmode;
21711 : :
21712 : : /* If MODE2 is only appropriate for an SSE register, then tie with
21713 : : any vector modes or scalar floating point modes acceptable to SSE
21714 : : registers, excluding scalar integer modes with SUBREG:
21715 : : (subreg:QI (reg:TI 99) 0))
21716 : : (subreg:HI (reg:TI 99) 0))
21717 : : (subreg:SI (reg:TI 99) 0))
21718 : : (subreg:DI (reg:TI 99) 0))
21719 : : to avoid unnecessary move from SSE register to integer register.
21720 : : */
21721 : 24080045 : if (GET_MODE_SIZE (mode2) >= 16
21722 : 37766034 : && (GET_MODE_SIZE (mode1) == GET_MODE_SIZE (mode2)
21723 : 13424490 : || ((VECTOR_MODE_P (mode1) || SCALAR_FLOAT_MODE_P (mode1))
21724 : 447802 : && GET_MODE_SIZE (mode1) <= GET_MODE_SIZE (mode2)))
21725 : 29761884 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
21726 : 5258303 : return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1);
21727 : :
21728 : : /* If MODE2 is appropriate for an MMX register, then tie
21729 : : with any other mode acceptable to MMX registers. */
21730 : 18821742 : if (GET_MODE_SIZE (mode2) == 8
21731 : 18821742 : && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
21732 : 3228056 : return (GET_MODE_SIZE (mode1) == 8
21733 : 3228056 : && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
21734 : :
21735 : : /* SCmode and DImode can be tied. */
21736 : 15593686 : if ((mode1 == E_SCmode && mode2 == E_DImode)
21737 : 15593686 : || (mode1 == E_DImode && mode2 == E_SCmode))
21738 : 108 : return TARGET_64BIT;
21739 : :
21740 : : /* [SD]Cmode and V2[SD]Fmode modes can be tied. */
21741 : 15593578 : if ((mode1 == E_SCmode && mode2 == E_V2SFmode)
21742 : 15593578 : || (mode1 == E_V2SFmode && mode2 == E_SCmode)
21743 : 15593578 : || (mode1 == E_DCmode && mode2 == E_V2DFmode)
21744 : 15593578 : || (mode1 == E_V2DFmode && mode2 == E_DCmode))
21745 : 0 : return true;
21746 : :
21747 : : return false;
21748 : : }
21749 : :
21750 : : /* Return the cost of moving between two registers of mode MODE. */
21751 : :
21752 : : static int
21753 : 31210279 : ix86_set_reg_reg_cost (machine_mode mode)
21754 : : {
21755 : 31210279 : unsigned int units = UNITS_PER_WORD;
21756 : :
21757 : 31210279 : switch (GET_MODE_CLASS (mode))
21758 : : {
21759 : : default:
21760 : : break;
21761 : :
21762 : : case MODE_CC:
21763 : 31210279 : units = GET_MODE_SIZE (CCmode);
21764 : : break;
21765 : :
21766 : 1147117 : case MODE_FLOAT:
21767 : 1147117 : if ((TARGET_SSE && mode == TFmode)
21768 : 672532 : || (TARGET_80387 && mode == XFmode)
21769 : 209387 : || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
21770 : 141692 : || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
21771 : 2264690 : units = GET_MODE_SIZE (mode);
21772 : : break;
21773 : :
21774 : 1278400 : case MODE_COMPLEX_FLOAT:
21775 : 1278400 : if ((TARGET_SSE && mode == TCmode)
21776 : 857136 : || (TARGET_80387 && mode == XCmode)
21777 : 435746 : || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
21778 : 14342 : || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
21779 : 2550456 : units = GET_MODE_SIZE (mode);
21780 : : break;
21781 : :
21782 : 20832143 : case MODE_VECTOR_INT:
21783 : 20832143 : case MODE_VECTOR_FLOAT:
21784 : 20832143 : if ((TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
21785 : 20737492 : || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
21786 : 20567442 : || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
21787 : 17996298 : || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
21788 : 16717338 : || ((TARGET_MMX || TARGET_MMX_WITH_SSE)
21789 : 16666460 : && VALID_MMX_REG_MODE (mode)))
21790 : 8335378 : units = GET_MODE_SIZE (mode);
21791 : : }
21792 : :
21793 : : /* Return the cost of moving between two registers of mode MODE,
21794 : : assuming that the move will be in pieces of at most UNITS bytes. */
21795 : 31210279 : return COSTS_N_INSNS (CEIL (GET_MODE_SIZE (mode), units));
21796 : : }
21797 : :
21798 : : /* Return cost of vector operation in MODE given that scalar version has
21799 : : COST. */
21800 : :
21801 : : static int
21802 : 2861361064 : ix86_vec_cost (machine_mode mode, int cost)
21803 : : {
21804 : 2861361064 : if (!VECTOR_MODE_P (mode))
21805 : : return cost;
21806 : :
21807 : 2860933625 : if (GET_MODE_BITSIZE (mode) == 128
21808 : 2860933625 : && TARGET_SSE_SPLIT_REGS)
21809 : 2801674 : return cost * GET_MODE_BITSIZE (mode) / 64;
21810 : 2859532788 : else if (GET_MODE_BITSIZE (mode) > 128
21811 : 2859532788 : && TARGET_AVX256_SPLIT_REGS)
21812 : 1724294 : return cost * GET_MODE_BITSIZE (mode) / 128;
21813 : 2858670641 : else if (GET_MODE_BITSIZE (mode) > 256
21814 : 2858670641 : && TARGET_AVX512_SPLIT_REGS)
21815 : 199286 : return cost * GET_MODE_BITSIZE (mode) / 256;
21816 : : return cost;
21817 : : }
21818 : :
21819 : : /* Return cost of vec_widen_<s>mult_hi/lo_<mode>,
21820 : : vec_widen_<s>mul_hi/lo_<mode> is only available for VI124_AVX2. */
21821 : : static int
21822 : 1726 : ix86_widen_mult_cost (const struct processor_costs *cost,
21823 : : enum machine_mode mode, bool uns_p)
21824 : : {
21825 : 1726 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
21826 : 1726 : int extra_cost = 0;
21827 : 1726 : int basic_cost = 0;
21828 : 1726 : switch (mode)
21829 : : {
21830 : 135 : case V8HImode:
21831 : 135 : case V16HImode:
21832 : 135 : if (!uns_p || mode == V16HImode)
21833 : 31 : extra_cost = cost->sse_op * 2;
21834 : 135 : basic_cost = cost->mulss * 2 + cost->sse_op * 4;
21835 : 135 : break;
21836 : 234 : case V4SImode:
21837 : 234 : case V8SImode:
21838 : : /* pmulhw/pmullw can be used. */
21839 : 234 : basic_cost = cost->mulss * 2 + cost->sse_op * 2;
21840 : 234 : break;
21841 : 1251 : case V2DImode:
21842 : : /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
21843 : : require extra 4 mul, 4 add, 4 cmp and 2 shift. */
21844 : 1251 : if (!TARGET_SSE4_1 && !uns_p)
21845 : 784 : extra_cost = (cost->mulss + cost->sse_op + cost->sse_op) * 4
21846 : 784 : + cost->sse_op * 2;
21847 : : /* Fallthru. */
21848 : 1333 : case V4DImode:
21849 : 1333 : basic_cost = cost->mulss * 2 + cost->sse_op * 4;
21850 : 1333 : break;
21851 : : default:
21852 : : /* Not implemented. */
21853 : : return 100;
21854 : : }
21855 : 1702 : return ix86_vec_cost (mode, basic_cost + extra_cost);
21856 : : }
21857 : :
21858 : : /* Return cost of multiplication in MODE. */
21859 : :
21860 : : static int
21861 : 1221312380 : ix86_multiplication_cost (const struct processor_costs *cost,
21862 : : enum machine_mode mode)
21863 : : {
21864 : 1221312380 : machine_mode inner_mode = mode;
21865 : 1221312380 : if (VECTOR_MODE_P (mode))
21866 : 1220352095 : inner_mode = GET_MODE_INNER (mode);
21867 : :
21868 : 1221312380 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
21869 : 724687 : return inner_mode == DFmode ? cost->mulsd : cost->mulss;
21870 : 1220587693 : else if (X87_FLOAT_MODE_P (mode))
21871 : 163068 : return cost->fmul;
21872 : 1220424625 : else if (FLOAT_MODE_P (mode))
21873 : 190194 : return ix86_vec_cost (mode,
21874 : 190194 : inner_mode == DFmode ? cost->mulsd : cost->mulss);
21875 : 1220234431 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
21876 : : {
21877 : 1220186151 : int nmults, nops;
21878 : : /* Cost of reading the memory. */
21879 : 1220186151 : int extra;
21880 : :
21881 : 1220186151 : switch (mode)
21882 : : {
21883 : 18588256 : case V4QImode:
21884 : 18588256 : case V8QImode:
21885 : : /* Partial V*QImode is emulated with 4-6 insns. */
21886 : 18588256 : nmults = 1;
21887 : 18588256 : nops = 3;
21888 : 18588256 : extra = 0;
21889 : :
21890 : 18588256 : if (TARGET_AVX512BW && TARGET_AVX512VL)
21891 : : ;
21892 : 18494331 : else if (TARGET_AVX2)
21893 : : nops += 2;
21894 : 17986731 : else if (TARGET_XOP)
21895 : 9680 : extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
21896 : : else
21897 : : {
21898 : 17977051 : nops += 1;
21899 : 17977051 : extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
21900 : : }
21901 : 18588256 : goto do_qimode;
21902 : :
21903 : 9295320 : case V16QImode:
21904 : : /* V*QImode is emulated with 4-11 insns. */
21905 : 9295320 : nmults = 1;
21906 : 9295320 : nops = 3;
21907 : 9295320 : extra = 0;
21908 : :
21909 : 9295320 : if (TARGET_AVX2 && !TARGET_PREFER_AVX128)
21910 : : {
21911 : 299037 : if (!(TARGET_AVX512BW && TARGET_AVX512VL))
21912 : 252389 : nops += 3;
21913 : : }
21914 : 8996283 : else if (TARGET_XOP)
21915 : : {
21916 : 5288 : nmults += 1;
21917 : 5288 : nops += 2;
21918 : 5288 : extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
21919 : : }
21920 : : else
21921 : : {
21922 : 8990995 : nmults += 1;
21923 : 8990995 : nops += 4;
21924 : 8990995 : extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
21925 : : }
21926 : 9295320 : goto do_qimode;
21927 : :
21928 : 9294011 : case V32QImode:
21929 : 9294011 : nmults = 1;
21930 : 9294011 : nops = 3;
21931 : 9294011 : extra = 0;
21932 : :
21933 : 9294011 : if (!TARGET_AVX512BW || TARGET_PREFER_AVX256)
21934 : : {
21935 : 9216330 : nmults += 1;
21936 : 9216330 : nops += 4;
21937 : : /* 2 loads, so no division by 2. */
21938 : 9216330 : extra += COSTS_N_INSNS (cost->sse_load[3]);
21939 : : }
21940 : 9294011 : goto do_qimode;
21941 : :
21942 : 9293388 : case V64QImode:
21943 : 9293388 : nmults = 2;
21944 : 9293388 : nops = 9;
21945 : : /* 2 loads of each size, so no division by 2. */
21946 : 9293388 : extra = COSTS_N_INSNS (cost->sse_load[3] + cost->sse_load[4]);
21947 : :
21948 : 46470975 : do_qimode:
21949 : 46470975 : return ix86_vec_cost (mode, cost->mulss * nmults
21950 : 46470975 : + cost->sse_op * nops) + extra;
21951 : :
21952 : 39741532 : case V4SImode:
21953 : : /* pmulld is used in this case. No emulation is needed. */
21954 : 39741532 : if (TARGET_SSE4_1)
21955 : 2191358 : goto do_native;
21956 : : /* V4SImode is emulated with 7 insns. */
21957 : : else
21958 : 37550174 : return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 5);
21959 : :
21960 : 160638078 : case V2DImode:
21961 : 160638078 : case V4DImode:
21962 : : /* vpmullq is used in this case. No emulation is needed. */
21963 : 160638078 : if (TARGET_AVX512DQ && TARGET_AVX512VL)
21964 : 478914 : goto do_native;
21965 : : /* V*DImode is emulated with 6-8 insns. */
21966 : 160159164 : else if (TARGET_XOP && mode == V2DImode)
21967 : 53290 : return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 4);
21968 : : /* FALLTHRU */
21969 : 240368462 : case V8DImode:
21970 : : /* vpmullq is used in this case. No emulation is needed. */
21971 : 240368462 : if (TARGET_AVX512DQ && mode == V8DImode)
21972 : 334094 : goto do_native;
21973 : : else
21974 : 240034368 : return ix86_vec_cost (mode, cost->mulss * 3 + cost->sse_op * 5);
21975 : :
21976 : 896077344 : default:
21977 : 896077344 : do_native:
21978 : 896077344 : return ix86_vec_cost (mode, cost->mulss);
21979 : : }
21980 : : }
21981 : : else
21982 : 96560 : return (cost->mult_init[MODE_INDEX (mode)] + cost->mult_bit * 7);
21983 : : }
21984 : :
21985 : : /* Return cost of multiplication in MODE. */
21986 : :
21987 : : static int
21988 : 72671430 : ix86_division_cost (const struct processor_costs *cost,
21989 : : enum machine_mode mode)
21990 : : {
21991 : 72671430 : machine_mode inner_mode = mode;
21992 : 72671430 : if (VECTOR_MODE_P (mode))
21993 : 54083530 : inner_mode = GET_MODE_INNER (mode);
21994 : :
21995 : 72671430 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
21996 : 250955 : return inner_mode == DFmode ? cost->divsd : cost->divss;
21997 : 72420475 : else if (X87_FLOAT_MODE_P (mode))
21998 : 44936 : return cost->fdiv;
21999 : 72375539 : else if (FLOAT_MODE_P (mode))
22000 : 16660 : return ix86_vec_cost (mode,
22001 : 16660 : inner_mode == DFmode ? cost->divsd : cost->divss);
22002 : : else
22003 : 80511152 : return cost->divide[MODE_INDEX (mode)];
22004 : : }
22005 : :
22006 : : /* Return cost of shift in MODE.
22007 : : If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
22008 : : AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE
22009 : : if op1 is a result of subreg.
22010 : :
22011 : : SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored. */
22012 : :
22013 : : static int
22014 : 771678308 : ix86_shift_rotate_cost (const struct processor_costs *cost,
22015 : : enum rtx_code code,
22016 : : enum machine_mode mode, bool constant_op1,
22017 : : HOST_WIDE_INT op1_val,
22018 : : bool and_in_op1,
22019 : : bool shift_and_truncate,
22020 : : bool *skip_op0, bool *skip_op1)
22021 : : {
22022 : 771678308 : if (skip_op0)
22023 : 771641563 : *skip_op0 = *skip_op1 = false;
22024 : :
22025 : 771678308 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
22026 : : {
22027 : 402766635 : int count;
22028 : : /* Cost of reading the memory. */
22029 : 402766635 : int extra;
22030 : :
22031 : 402766635 : switch (mode)
22032 : : {
22033 : 5913912 : case V4QImode:
22034 : 5913912 : case V8QImode:
22035 : 5913912 : if (TARGET_AVX2)
22036 : : /* Use vpbroadcast. */
22037 : 191220 : extra = cost->sse_op;
22038 : : else
22039 : 5722692 : extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
22040 : :
22041 : 5913912 : if (constant_op1)
22042 : : {
22043 : 5913884 : if (code == ASHIFTRT)
22044 : : {
22045 : 20 : count = 4;
22046 : 20 : extra *= 2;
22047 : : }
22048 : : else
22049 : : count = 2;
22050 : : }
22051 : 28 : else if (TARGET_AVX512BW && TARGET_AVX512VL)
22052 : 28 : return ix86_vec_cost (mode, cost->sse_op * 4);
22053 : 0 : else if (TARGET_SSE4_1)
22054 : : count = 5;
22055 : 0 : else if (code == ASHIFTRT)
22056 : : count = 6;
22057 : : else
22058 : 0 : count = 5;
22059 : 5913884 : return ix86_vec_cost (mode, cost->sse_op * count) + extra;
22060 : :
22061 : 2959105 : case V16QImode:
22062 : 2959105 : if (TARGET_XOP)
22063 : : {
22064 : : /* For XOP we use vpshab, which requires a broadcast of the
22065 : : value to the variable shift insn. For constants this
22066 : : means a V16Q const in mem; even when we can perform the
22067 : : shift with one insn set the cost to prefer paddb. */
22068 : 3388 : if (constant_op1)
22069 : : {
22070 : 2456 : extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
22071 : 2456 : return ix86_vec_cost (mode, cost->sse_op) + extra;
22072 : : }
22073 : : else
22074 : : {
22075 : 932 : count = (code == ASHIFT) ? 3 : 4;
22076 : 932 : return ix86_vec_cost (mode, cost->sse_op * count);
22077 : : }
22078 : : }
22079 : : /* FALLTHRU */
22080 : 5912685 : case V32QImode:
22081 : 5912685 : if (TARGET_AVX2)
22082 : : /* Use vpbroadcast. */
22083 : 190704 : extra = cost->sse_op;
22084 : : else
22085 : 5721981 : extra = COSTS_N_INSNS (mode == V16QImode
22086 : : ? cost->sse_load[2]
22087 : 5721981 : : cost->sse_load[3]) / 2;
22088 : :
22089 : 5912685 : if (constant_op1)
22090 : : {
22091 : 5912582 : if (code == ASHIFTRT)
22092 : : {
22093 : 104 : count = 4;
22094 : 104 : extra *= 2;
22095 : : }
22096 : : else
22097 : : count = 2;
22098 : : }
22099 : 103 : else if (TARGET_AVX512BW
22100 : 75 : && ((mode == V32QImode && !TARGET_PREFER_AVX256)
22101 : 37 : || (mode == V16QImode && TARGET_AVX512VL
22102 : 37 : && !TARGET_PREFER_AVX128)))
22103 : 75 : return ix86_vec_cost (mode, cost->sse_op * 4);
22104 : 28 : else if (TARGET_AVX2
22105 : 0 : && mode == V16QImode && !TARGET_PREFER_AVX128)
22106 : : count = 6;
22107 : 28 : else if (TARGET_SSE4_1)
22108 : : count = 9;
22109 : 28 : else if (code == ASHIFTRT)
22110 : : count = 10;
22111 : : else
22112 : 28 : count = 9;
22113 : 5912610 : return ix86_vec_cost (mode, cost->sse_op * count) + extra;
22114 : :
22115 : 53309370 : case V2DImode:
22116 : 53309370 : case V4DImode:
22117 : : /* V*DImode arithmetic right shift is emulated. */
22118 : 53309370 : if (code == ASHIFTRT && !TARGET_AVX512VL)
22119 : : {
22120 : 1169 : if (constant_op1)
22121 : : {
22122 : 478 : if (op1_val == 63)
22123 : 401 : count = TARGET_SSE4_2 ? 1 : 2;
22124 : 376 : else if (TARGET_XOP)
22125 : : count = 2;
22126 : 77 : else if (TARGET_SSE4_1)
22127 : : count = 3;
22128 : : else
22129 : 75 : count = 4;
22130 : : }
22131 : 691 : else if (TARGET_XOP)
22132 : : count = 3;
22133 : 10 : else if (TARGET_SSE4_2)
22134 : : count = 4;
22135 : : else
22136 : 1169 : count = 5;
22137 : :
22138 : 1169 : return ix86_vec_cost (mode, cost->sse_op * count);
22139 : : }
22140 : : /* FALLTHRU */
22141 : 390935481 : default:
22142 : 390935481 : return ix86_vec_cost (mode, cost->sse_op);
22143 : : }
22144 : : }
22145 : :
22146 : 746443327 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22147 : : {
22148 : 188809920 : if (constant_op1)
22149 : : {
22150 : 188775032 : if (op1_val > 32)
22151 : 134102309 : return cost->shift_const + COSTS_N_INSNS (2);
22152 : : else
22153 : 54672723 : return cost->shift_const * 2;
22154 : : }
22155 : : else
22156 : : {
22157 : 34888 : if (and_in_op1)
22158 : 63 : return cost->shift_var * 2;
22159 : : else
22160 : 34825 : return cost->shift_var * 6 + COSTS_N_INSNS (2);
22161 : : }
22162 : : }
22163 : : else
22164 : : {
22165 : 180101753 : if (constant_op1)
22166 : 179365851 : return cost->shift_const;
22167 : 735902 : else if (shift_and_truncate)
22168 : : {
22169 : 22722 : if (skip_op0)
22170 : 22722 : *skip_op0 = *skip_op1 = true;
22171 : : /* Return the cost after shift-and truncation. */
22172 : 22722 : return cost->shift_var;
22173 : : }
22174 : : else
22175 : 713180 : return cost->shift_var;
22176 : : }
22177 : : }
22178 : :
22179 : : static int
22180 : 144268622 : ix86_insn_cost (rtx_insn *insn, bool speed)
22181 : : {
22182 : 144268622 : int insn_cost = 0;
22183 : : /* Add extra cost to avoid post_reload late_combine revert
22184 : : the optimization did in pass_rpad. */
22185 : 144268622 : if (reload_completed
22186 : 4538577 : && ix86_rpad_gate ()
22187 : 270247 : && recog_memoized (insn) >= 0
22188 : 144538721 : && get_attr_avx_partial_xmm_update (insn)
22189 : : == AVX_PARTIAL_XMM_UPDATE_TRUE)
22190 : : insn_cost += COSTS_N_INSNS (3);
22191 : :
22192 : 144268622 : return insn_cost + pattern_cost (PATTERN (insn), speed);
22193 : : }
22194 : :
22195 : : /* Return cost of SSE/AVX FP->FP conversion (extensions and truncates). */
22196 : :
22197 : : static int
22198 : 736404 : vec_fp_conversion_cost (const struct processor_costs *cost, int size)
22199 : : {
22200 : 736404 : if (size < 128)
22201 : 733228 : return cost->cvtss2sd;
22202 : 3176 : else if (size < 256)
22203 : : {
22204 : 1379 : if (TARGET_SSE_SPLIT_REGS)
22205 : 0 : return cost->cvtss2sd * size / 64;
22206 : 1379 : return cost->cvtss2sd;
22207 : : }
22208 : 1797 : if (size < 512)
22209 : 658 : return cost->vcvtps2pd256;
22210 : : else
22211 : 1139 : return cost->vcvtps2pd512;
22212 : : }
22213 : :
22214 : : /* Return true of X is UNSPEC with UNSPEC_PCMP or UNSPEC_UNSIGNED_PCMP. */
22215 : :
22216 : : static bool
22217 : 231462 : unspec_pcmp_p (rtx x)
22218 : : {
22219 : 231462 : return GET_CODE (x) == UNSPEC
22220 : 231462 : && (XINT (x, 1) == UNSPEC_PCMP || XINT (x, 1) == UNSPEC_UNSIGNED_PCMP);
22221 : : }
22222 : :
22223 : : /* Compute a (partial) cost for rtx X. Return true if the complete
22224 : : cost has been computed, and false if subexpressions should be
22225 : : scanned. In either case, *TOTAL contains the cost result. */
22226 : :
22227 : : static bool
22228 : 7695527738 : ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
22229 : : int *total, bool speed)
22230 : : {
22231 : 7695527738 : rtx mask;
22232 : 7695527738 : enum rtx_code code = GET_CODE (x);
22233 : 7695527738 : enum rtx_code outer_code = (enum rtx_code) outer_code_i;
22234 : 4117004699 : const struct processor_costs *cost
22235 : 7695527738 : = speed ? ix86_tune_cost : &ix86_size_cost;
22236 : 7695527738 : int src_cost;
22237 : :
22238 : : /* Handling different vternlog variants. */
22239 : 7695527738 : if ((GET_MODE_SIZE (mode) == 64
22240 : 7695527738 : ? TARGET_AVX512F
22241 : 6537035177 : : (TARGET_AVX512VL
22242 : 6479352851 : || (TARGET_AVX512F && !TARGET_PREFER_AVX256)))
22243 : 178011908 : && GET_MODE_SIZE (mode) >= 16
22244 : 122490238 : && outer_code_i == SET
22245 : 7742700513 : && ternlog_operand (x, mode))
22246 : : {
22247 : 32714 : rtx args[3];
22248 : :
22249 : 32714 : args[0] = NULL_RTX;
22250 : 32714 : args[1] = NULL_RTX;
22251 : 32714 : args[2] = NULL_RTX;
22252 : 32714 : int idx = ix86_ternlog_idx (x, args);
22253 : 32714 : gcc_assert (idx >= 0);
22254 : :
22255 : 32714 : *total = cost->sse_op;
22256 : 130856 : for (int i = 0; i != 3; i++)
22257 : 98142 : if (args[i])
22258 : 69660 : *total += rtx_cost (args[i], GET_MODE (args[i]), UNSPEC, i, speed);
22259 : 32714 : return true;
22260 : : }
22261 : :
22262 : :
22263 : 7695495024 : switch (code)
22264 : : {
22265 : 50083065 : case SET:
22266 : 50083065 : if (register_operand (SET_DEST (x), VOIDmode)
22267 : 50083065 : && register_operand (SET_SRC (x), VOIDmode))
22268 : : {
22269 : 31210279 : *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
22270 : 31210279 : return true;
22271 : : }
22272 : :
22273 : 18872786 : if (register_operand (SET_SRC (x), VOIDmode))
22274 : : /* Avoid potentially incorrect high cost from rtx_costs
22275 : : for non-tieable SUBREGs. */
22276 : : src_cost = 0;
22277 : : else
22278 : : {
22279 : 16148099 : src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed);
22280 : :
22281 : 16148099 : if (CONSTANT_P (SET_SRC (x)))
22282 : : /* Constant costs assume a base value of COSTS_N_INSNS (1) and add
22283 : : a small value, possibly zero for cheap constants. */
22284 : 7115194 : src_cost += COSTS_N_INSNS (1);
22285 : : }
22286 : :
22287 : 18872786 : *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed);
22288 : 18872786 : return true;
22289 : :
22290 : 2833188266 : case CONST_INT:
22291 : 2833188266 : case CONST:
22292 : 2833188266 : case LABEL_REF:
22293 : 2833188266 : case SYMBOL_REF:
22294 : 2833188266 : if (x86_64_immediate_operand (x, VOIDmode))
22295 : 2240407566 : *total = 0;
22296 : 592780700 : else if (TARGET_64BIT && x86_64_zext_immediate_operand (x, VOIDmode))
22297 : : /* Consider the zext constants slightly more expensive, as they
22298 : : can't appear in most instructions. */
22299 : 28692971 : *total = 1;
22300 : : else
22301 : : /* movabsq is slightly more expensive than a simple instruction. */
22302 : 564087729 : *total = COSTS_N_INSNS (1) + 1;
22303 : : return true;
22304 : :
22305 : 7542872 : case CONST_DOUBLE:
22306 : 7542872 : if (IS_STACK_MODE (mode))
22307 : 1311549 : switch (standard_80387_constant_p (x))
22308 : : {
22309 : : case -1:
22310 : : case 0:
22311 : : break;
22312 : 280316 : case 1: /* 0.0 */
22313 : 280316 : *total = 1;
22314 : 280316 : return true;
22315 : 485534 : default: /* Other constants */
22316 : 485534 : *total = 2;
22317 : 485534 : return true;
22318 : : }
22319 : : /* FALLTHRU */
22320 : :
22321 : 14114611 : case CONST_VECTOR:
22322 : 14114611 : switch (standard_sse_constant_p (x, mode))
22323 : : {
22324 : : case 0:
22325 : : break;
22326 : 4010991 : case 1: /* 0: xor eliminates false dependency */
22327 : 4010991 : *total = 0;
22328 : 4010991 : return true;
22329 : 156187 : default: /* -1: cmp contains false dependency */
22330 : 156187 : *total = 1;
22331 : 156187 : return true;
22332 : : }
22333 : : /* FALLTHRU */
22334 : :
22335 : 10951059 : case CONST_WIDE_INT:
22336 : : /* Fall back to (MEM (SYMBOL_REF)), since that's where
22337 : : it'll probably end up. Add a penalty for size. */
22338 : 21902118 : *total = (COSTS_N_INSNS (1)
22339 : 21676307 : + (!TARGET_64BIT && flag_pic)
22340 : 21902118 : + (GET_MODE_SIZE (mode) <= 4
22341 : 19142890 : ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
22342 : 10951059 : return true;
22343 : :
22344 : 22305303 : case ZERO_EXTEND:
22345 : : /* The zero extensions is often completely free on x86_64, so make
22346 : : it as cheap as possible. */
22347 : 22305303 : if (TARGET_64BIT && mode == DImode
22348 : 4981175 : && GET_MODE (XEXP (x, 0)) == SImode)
22349 : 3013914 : *total = 1;
22350 : 19291389 : else if (TARGET_ZERO_EXTEND_WITH_AND)
22351 : 0 : *total = cost->add;
22352 : : else
22353 : 19291389 : *total = cost->movzx;
22354 : : return false;
22355 : :
22356 : 3109401 : case SIGN_EXTEND:
22357 : 3109401 : *total = cost->movsx;
22358 : 3109401 : return false;
22359 : :
22360 : 637144031 : case ASHIFT:
22361 : 637144031 : if (SCALAR_INT_MODE_P (mode)
22362 : 241244335 : && GET_MODE_SIZE (mode) < UNITS_PER_WORD
22363 : 679424628 : && CONST_INT_P (XEXP (x, 1)))
22364 : : {
22365 : 42117126 : HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
22366 : 42117126 : if (value == 1)
22367 : : {
22368 : 2461606 : *total = cost->add;
22369 : 2461606 : return false;
22370 : : }
22371 : 39655520 : if ((value == 2 || value == 3)
22372 : 4489047 : && cost->lea <= cost->shift_const)
22373 : : {
22374 : 2101212 : *total = cost->lea;
22375 : 2101212 : return false;
22376 : : }
22377 : : }
22378 : : /* FALLTHRU */
22379 : :
22380 : 771641563 : case ROTATE:
22381 : 771641563 : case ASHIFTRT:
22382 : 771641563 : case LSHIFTRT:
22383 : 771641563 : case ROTATERT:
22384 : 771641563 : bool skip_op0, skip_op1;
22385 : 771641563 : *total = ix86_shift_rotate_cost (cost, code, mode,
22386 : 771641563 : CONSTANT_P (XEXP (x, 1)),
22387 : : CONST_INT_P (XEXP (x, 1))
22388 : : ? INTVAL (XEXP (x, 1)) : -1,
22389 : : GET_CODE (XEXP (x, 1)) == AND,
22390 : 771641563 : SUBREG_P (XEXP (x, 1))
22391 : 771641563 : && GET_CODE (XEXP (XEXP (x, 1),
22392 : : 0)) == AND,
22393 : : &skip_op0, &skip_op1);
22394 : 771641563 : if (skip_op0 || skip_op1)
22395 : : {
22396 : 22722 : if (!skip_op0)
22397 : 0 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
22398 : 22722 : if (!skip_op1)
22399 : 0 : *total += rtx_cost (XEXP (x, 1), mode, code, 0, speed);
22400 : 22722 : return true;
22401 : : }
22402 : : return false;
22403 : :
22404 : 219780 : case FMA:
22405 : 219780 : {
22406 : 219780 : rtx sub;
22407 : :
22408 : 219780 : gcc_assert (FLOAT_MODE_P (mode));
22409 : 219780 : gcc_assert (TARGET_FMA || TARGET_FMA4 || TARGET_AVX512F);
22410 : :
22411 : 439560 : *total = ix86_vec_cost (mode,
22412 : 219780 : GET_MODE_INNER (mode) == SFmode
22413 : : ? cost->fmass : cost->fmasd);
22414 : 219780 : *total += rtx_cost (XEXP (x, 1), mode, FMA, 1, speed);
22415 : :
22416 : : /* Negate in op0 or op2 is free: FMS, FNMA, FNMS. */
22417 : 219780 : sub = XEXP (x, 0);
22418 : 219780 : if (GET_CODE (sub) == NEG)
22419 : 53324 : sub = XEXP (sub, 0);
22420 : 219780 : *total += rtx_cost (sub, mode, FMA, 0, speed);
22421 : :
22422 : 219780 : sub = XEXP (x, 2);
22423 : 219780 : if (GET_CODE (sub) == NEG)
22424 : 40050 : sub = XEXP (sub, 0);
22425 : 219780 : *total += rtx_cost (sub, mode, FMA, 2, speed);
22426 : 219780 : return true;
22427 : : }
22428 : :
22429 : 1760935387 : case MULT:
22430 : 1760935387 : if (!FLOAT_MODE_P (mode) && !VECTOR_MODE_P (mode))
22431 : : {
22432 : 539776286 : rtx op0 = XEXP (x, 0);
22433 : 539776286 : rtx op1 = XEXP (x, 1);
22434 : 539776286 : int nbits;
22435 : 539776286 : if (CONST_INT_P (XEXP (x, 1)))
22436 : : {
22437 : 521964572 : unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
22438 : 1060022263 : for (nbits = 0; value != 0; value &= value - 1)
22439 : 538057691 : nbits++;
22440 : : }
22441 : : else
22442 : : /* This is arbitrary. */
22443 : : nbits = 7;
22444 : :
22445 : : /* Compute costs correctly for widening multiplication. */
22446 : 539776286 : if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
22447 : 545182506 : && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
22448 : 5406220 : == GET_MODE_SIZE (mode))
22449 : : {
22450 : 5402131 : int is_mulwiden = 0;
22451 : 5402131 : machine_mode inner_mode = GET_MODE (op0);
22452 : :
22453 : 5402131 : if (GET_CODE (op0) == GET_CODE (op1))
22454 : 5316014 : is_mulwiden = 1, op1 = XEXP (op1, 0);
22455 : 86117 : else if (CONST_INT_P (op1))
22456 : : {
22457 : 76019 : if (GET_CODE (op0) == SIGN_EXTEND)
22458 : 22312 : is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
22459 : 22312 : == INTVAL (op1);
22460 : : else
22461 : 53707 : is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
22462 : : }
22463 : :
22464 : 5392033 : if (is_mulwiden)
22465 : 5392033 : op0 = XEXP (op0, 0), mode = GET_MODE (op0);
22466 : : }
22467 : :
22468 : 539776286 : int mult_init;
22469 : : // Double word multiplication requires 3 mults and 2 adds.
22470 : 1095087720 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22471 : : {
22472 : 324904406 : mult_init = 3 * cost->mult_init[MODE_INDEX (word_mode)]
22473 : 324904406 : + 2 * cost->add;
22474 : 324904406 : nbits *= 3;
22475 : : }
22476 : 370606360 : else mult_init = cost->mult_init[MODE_INDEX (mode)];
22477 : :
22478 : 1079552572 : *total = (mult_init
22479 : 539776286 : + nbits * cost->mult_bit
22480 : 539776286 : + rtx_cost (op0, mode, outer_code, opno, speed)
22481 : 539776286 : + rtx_cost (op1, mode, outer_code, opno, speed));
22482 : :
22483 : 539776286 : return true;
22484 : : }
22485 : 1221159101 : *total = ix86_multiplication_cost (cost, mode);
22486 : 1221159101 : return false;
22487 : :
22488 : 72664300 : case DIV:
22489 : 72664300 : case UDIV:
22490 : 72664300 : case MOD:
22491 : 72664300 : case UMOD:
22492 : 72664300 : *total = ix86_division_cost (cost, mode);
22493 : 72664300 : return false;
22494 : :
22495 : 689148636 : case PLUS:
22496 : 689148636 : if (GET_MODE_CLASS (mode) == MODE_INT
22497 : 941355421 : && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
22498 : : {
22499 : 140389853 : if (GET_CODE (XEXP (x, 0)) == PLUS
22500 : 3572156 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
22501 : 841846 : && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
22502 : 841837 : && CONSTANT_P (XEXP (x, 1)))
22503 : : {
22504 : 841764 : HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
22505 : 841764 : if (val == 2 || val == 4 || val == 8)
22506 : : {
22507 : 841660 : *total = cost->lea;
22508 : 841660 : *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
22509 : : outer_code, opno, speed);
22510 : 841660 : *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0), mode,
22511 : : outer_code, opno, speed);
22512 : 841660 : *total += rtx_cost (XEXP (x, 1), mode,
22513 : : outer_code, opno, speed);
22514 : 841660 : return true;
22515 : : }
22516 : : }
22517 : 139548089 : else if (GET_CODE (XEXP (x, 0)) == MULT
22518 : 51269258 : && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
22519 : : {
22520 : 51215637 : HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
22521 : 51215637 : if (val == 2 || val == 4 || val == 8)
22522 : : {
22523 : 7855957 : *total = cost->lea;
22524 : 7855957 : *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22525 : : outer_code, opno, speed);
22526 : 7855957 : *total += rtx_cost (XEXP (x, 1), mode,
22527 : : outer_code, opno, speed);
22528 : 7855957 : return true;
22529 : : }
22530 : : }
22531 : 88332452 : else if (GET_CODE (XEXP (x, 0)) == PLUS)
22532 : : {
22533 : 2730392 : rtx op = XEXP (XEXP (x, 0), 0);
22534 : :
22535 : : /* Add with carry, ignore the cost of adding a carry flag. */
22536 : 2730392 : if (ix86_carry_flag_operator (op, mode)
22537 : 2730392 : || ix86_carry_flag_unset_operator (op, mode))
22538 : 78493 : *total = cost->add;
22539 : : else
22540 : : {
22541 : 2651899 : *total = cost->lea;
22542 : 2651899 : *total += rtx_cost (op, mode,
22543 : : outer_code, opno, speed);
22544 : : }
22545 : :
22546 : 2730392 : *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
22547 : : outer_code, opno, speed);
22548 : 2730392 : *total += rtx_cost (XEXP (x, 1), mode,
22549 : : outer_code, opno, speed);
22550 : 2730392 : return true;
22551 : : }
22552 : : }
22553 : : /* FALLTHRU */
22554 : :
22555 : 1838021220 : case MINUS:
22556 : : /* Subtract with borrow, ignore the cost of subtracting a carry flag. */
22557 : 1838021220 : if (GET_MODE_CLASS (mode) == MODE_INT
22558 : 510236533 : && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
22559 : 231004345 : && GET_CODE (XEXP (x, 0)) == MINUS
22560 : 1838063003 : && (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode)
22561 : 12776 : || ix86_carry_flag_unset_operator (XEXP (XEXP (x, 0), 1), mode)))
22562 : : {
22563 : 29007 : *total = cost->add;
22564 : 29007 : *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22565 : : outer_code, opno, speed);
22566 : 29007 : *total += rtx_cost (XEXP (x, 1), mode,
22567 : : outer_code, opno, speed);
22568 : 29007 : return true;
22569 : : }
22570 : :
22571 : 1837992213 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22572 : 2412726 : *total = cost->addss;
22573 : 1835579487 : else if (X87_FLOAT_MODE_P (mode))
22574 : 218598 : *total = cost->fadd;
22575 : 1835360889 : else if (FLOAT_MODE_P (mode))
22576 : 402649 : *total = ix86_vec_cost (mode, cost->addss);
22577 : 1834958240 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
22578 : 1220782772 : *total = ix86_vec_cost (mode, cost->sse_op);
22579 : 1267482188 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22580 : 324062730 : *total = cost->add * 2;
22581 : : else
22582 : 290112738 : *total = cost->add;
22583 : : return false;
22584 : :
22585 : 4356217 : case IOR:
22586 : 4356217 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
22587 : 4121309 : || SSE_FLOAT_MODE_P (mode))
22588 : : {
22589 : : /* (ior (not ...) ...) can be a single insn in AVX512. */
22590 : 0 : if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
22591 : 244745 : && (GET_MODE_SIZE (mode) == 64
22592 : 0 : || (TARGET_AVX512VL
22593 : 0 : && (GET_MODE_SIZE (mode) == 32
22594 : 0 : || GET_MODE_SIZE (mode) == 16))))
22595 : : {
22596 : 0 : rtx right = GET_CODE (XEXP (x, 1)) != NOT
22597 : 0 : ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
22598 : :
22599 : 0 : *total = ix86_vec_cost (mode, cost->sse_op)
22600 : 0 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22601 : : outer_code, opno, speed)
22602 : 0 : + rtx_cost (right, mode, outer_code, opno, speed);
22603 : 0 : return true;
22604 : : }
22605 : 244745 : *total = ix86_vec_cost (mode, cost->sse_op);
22606 : 244745 : }
22607 : 4111472 : else if (TARGET_64BIT
22608 : 3821671 : && mode == TImode
22609 : 1741477 : && GET_CODE (XEXP (x, 0)) == ASHIFT
22610 : 267911 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
22611 : 265915 : && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == DImode
22612 : 265914 : && CONST_INT_P (XEXP (XEXP (x, 0), 1))
22613 : 265914 : && INTVAL (XEXP (XEXP (x, 0), 1)) == 64
22614 : 265914 : && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
22615 : 240721 : && GET_MODE (XEXP (XEXP (x, 1), 0)) == DImode)
22616 : : {
22617 : : /* *concatditi3 is cheap. */
22618 : 240721 : rtx op0 = XEXP (XEXP (XEXP (x, 0), 0), 0);
22619 : 240721 : rtx op1 = XEXP (XEXP (x, 1), 0);
22620 : 1380 : *total = (SUBREG_P (op0) && GET_MODE (SUBREG_REG (op0)) == DFmode)
22621 : 240721 : ? COSTS_N_INSNS (1) /* movq. */
22622 : 239341 : : set_src_cost (op0, DImode, speed);
22623 : 2282 : *total += (SUBREG_P (op1) && GET_MODE (SUBREG_REG (op1)) == DFmode)
22624 : 240721 : ? COSTS_N_INSNS (1) /* movq. */
22625 : 238452 : : set_src_cost (op1, DImode, speed);
22626 : 240721 : return true;
22627 : : }
22628 : 3870751 : else if (TARGET_64BIT
22629 : 3580950 : && mode == TImode
22630 : 1500756 : && GET_CODE (XEXP (x, 0)) == AND
22631 : 1452435 : && REG_P (XEXP (XEXP (x, 0), 0))
22632 : 1446644 : && CONST_WIDE_INT_P (XEXP (XEXP (x, 0), 1))
22633 : 1446644 : && CONST_WIDE_INT_NUNITS (XEXP (XEXP (x, 0), 1)) == 2
22634 : 1446644 : && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 0) == -1
22635 : 947485 : && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 1) == 0
22636 : 947485 : && GET_CODE (XEXP (x, 1)) == ASHIFT
22637 : 946140 : && GET_CODE (XEXP (XEXP (x, 1), 0)) == ZERO_EXTEND
22638 : 946140 : && GET_MODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == DImode
22639 : 946132 : && CONST_INT_P (XEXP (XEXP (x, 1), 1))
22640 : 4816883 : && INTVAL (XEXP (XEXP (x, 1), 1)) == 64)
22641 : : {
22642 : : /* *insvti_highpart is cheap. */
22643 : 946132 : rtx op = XEXP (XEXP (XEXP (x, 1), 0), 0);
22644 : 946132 : *total = COSTS_N_INSNS (1) + 1;
22645 : 1302 : *total += (SUBREG_P (op) && GET_MODE (SUBREG_REG (op)) == DFmode)
22646 : 946132 : ? COSTS_N_INSNS (1) /* movq. */
22647 : 945270 : : set_src_cost (op, DImode, speed);
22648 : 946132 : return true;
22649 : : }
22650 : 6139039 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22651 : 878722 : *total = cost->add * 2;
22652 : : else
22653 : 2045897 : *total = cost->add;
22654 : : return false;
22655 : :
22656 : 565444 : case XOR:
22657 : 565444 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
22658 : 486917 : || SSE_FLOAT_MODE_P (mode))
22659 : 78527 : *total = ix86_vec_cost (mode, cost->sse_op);
22660 : 1038414 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22661 : 16447 : *total = cost->add * 2;
22662 : : else
22663 : 470470 : *total = cost->add;
22664 : : return false;
22665 : :
22666 : 7297990 : case AND:
22667 : 7297990 : if (address_no_seg_operand (x, mode))
22668 : : {
22669 : 14709 : *total = cost->lea;
22670 : 14709 : return true;
22671 : : }
22672 : 7283281 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
22673 : 6932567 : || SSE_FLOAT_MODE_P (mode))
22674 : : {
22675 : : /* pandn is a single instruction. */
22676 : 385013 : if (GET_CODE (XEXP (x, 0)) == NOT)
22677 : : {
22678 : 48644 : rtx right = XEXP (x, 1);
22679 : :
22680 : : /* (and (not ...) (not ...)) can be a single insn in AVX512. */
22681 : 376 : if (GET_CODE (right) == NOT && TARGET_AVX512F
22682 : 48644 : && (GET_MODE_SIZE (mode) == 64
22683 : 0 : || (TARGET_AVX512VL
22684 : 0 : && (GET_MODE_SIZE (mode) == 32
22685 : 0 : || GET_MODE_SIZE (mode) == 16))))
22686 : 0 : right = XEXP (right, 0);
22687 : :
22688 : 48644 : *total = ix86_vec_cost (mode, cost->sse_op)
22689 : 48644 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22690 : : outer_code, opno, speed)
22691 : 48644 : + rtx_cost (right, mode, outer_code, opno, speed);
22692 : 48644 : return true;
22693 : : }
22694 : 336369 : else if (GET_CODE (XEXP (x, 1)) == NOT)
22695 : : {
22696 : 754 : *total = ix86_vec_cost (mode, cost->sse_op)
22697 : 754 : + rtx_cost (XEXP (x, 0), mode,
22698 : : outer_code, opno, speed)
22699 : 754 : + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
22700 : : outer_code, opno, speed);
22701 : 754 : return true;
22702 : : }
22703 : 335615 : *total = ix86_vec_cost (mode, cost->sse_op);
22704 : 335615 : }
22705 : 14483062 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22706 : : {
22707 : 1023535 : if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
22708 : : {
22709 : 1556 : *total = cost->add * 2
22710 : 778 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22711 : : outer_code, opno, speed)
22712 : 778 : + rtx_cost (XEXP (x, 1), mode,
22713 : : outer_code, opno, speed);
22714 : 778 : return true;
22715 : : }
22716 : 1022757 : else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT)
22717 : : {
22718 : 0 : *total = cost->add * 2
22719 : 0 : + rtx_cost (XEXP (x, 0), mode,
22720 : : outer_code, opno, speed)
22721 : 0 : + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
22722 : : outer_code, opno, speed);
22723 : 0 : return true;
22724 : : }
22725 : 1022757 : *total = cost->add * 2;
22726 : : }
22727 : 5874733 : else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
22728 : : {
22729 : 746 : *total = cost->add
22730 : 373 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22731 : : outer_code, opno, speed)
22732 : 373 : + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
22733 : 373 : return true;
22734 : : }
22735 : 5874360 : else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT)
22736 : : {
22737 : 112 : *total = cost->add
22738 : 56 : + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
22739 : 56 : + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
22740 : : outer_code, opno, speed);
22741 : 56 : return true;
22742 : : }
22743 : : else
22744 : 5874304 : *total = cost->add;
22745 : : return false;
22746 : :
22747 : 519821 : case NOT:
22748 : 519821 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
22749 : : {
22750 : : /* (not (xor ...)) can be a single insn in AVX512. */
22751 : 0 : if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
22752 : 5551 : && (GET_MODE_SIZE (mode) == 64
22753 : 0 : || (TARGET_AVX512VL
22754 : 0 : && (GET_MODE_SIZE (mode) == 32
22755 : 0 : || GET_MODE_SIZE (mode) == 16))))
22756 : : {
22757 : 0 : *total = ix86_vec_cost (mode, cost->sse_op)
22758 : 0 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
22759 : : outer_code, opno, speed)
22760 : 0 : + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
22761 : : outer_code, opno, speed);
22762 : 0 : return true;
22763 : : }
22764 : :
22765 : : // vnot is pxor -1.
22766 : 5551 : *total = ix86_vec_cost (mode, cost->sse_op) + 1;
22767 : : }
22768 : 1174258 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22769 : 68700 : *total = cost->add * 2;
22770 : : else
22771 : 445570 : *total = cost->add;
22772 : : return false;
22773 : :
22774 : 18214472 : case NEG:
22775 : 18214472 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22776 : 53657 : *total = cost->sse_op;
22777 : 18160815 : else if (X87_FLOAT_MODE_P (mode))
22778 : 15233 : *total = cost->fchs;
22779 : 18145582 : else if (FLOAT_MODE_P (mode))
22780 : 26783 : *total = ix86_vec_cost (mode, cost->sse_op);
22781 : 18118799 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
22782 : 13529351 : *total = ix86_vec_cost (mode, cost->sse_op);
22783 : 9325414 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22784 : 1726359 : *total = cost->add * 3;
22785 : : else
22786 : 2863089 : *total = cost->add;
22787 : : return false;
22788 : :
22789 : 54309993 : case COMPARE:
22790 : 54309993 : rtx op0, op1;
22791 : 54309993 : op0 = XEXP (x, 0);
22792 : 54309993 : op1 = XEXP (x, 1);
22793 : 54309993 : if (GET_CODE (op0) == ZERO_EXTRACT
22794 : 181207 : && XEXP (op0, 1) == const1_rtx
22795 : 162939 : && CONST_INT_P (XEXP (op0, 2))
22796 : 162837 : && op1 == const0_rtx)
22797 : : {
22798 : : /* This kind of construct is implemented using test[bwl].
22799 : : Treat it as if we had an AND. */
22800 : 162837 : mode = GET_MODE (XEXP (op0, 0));
22801 : 325674 : *total = (cost->add
22802 : 162837 : + rtx_cost (XEXP (op0, 0), mode, outer_code,
22803 : : opno, speed)
22804 : 162837 : + rtx_cost (const1_rtx, mode, outer_code, opno, speed));
22805 : 162837 : return true;
22806 : : }
22807 : :
22808 : 54147156 : if (GET_CODE (op0) == PLUS && rtx_equal_p (XEXP (op0, 0), op1))
22809 : : {
22810 : : /* This is an overflow detection, count it as a normal compare. */
22811 : 141528 : *total = rtx_cost (op0, GET_MODE (op0), COMPARE, 0, speed);
22812 : 141528 : return true;
22813 : : }
22814 : :
22815 : 54005628 : rtx geu;
22816 : : /* Match x
22817 : : (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
22818 : : (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))) */
22819 : 54005628 : if (mode == CCCmode
22820 : 412336 : && GET_CODE (op0) == NEG
22821 : 7992 : && GET_CODE (geu = XEXP (op0, 0)) == GEU
22822 : 7989 : && REG_P (XEXP (geu, 0))
22823 : 7989 : && (GET_MODE (XEXP (geu, 0)) == CCCmode
22824 : 755 : || GET_MODE (XEXP (geu, 0)) == CCmode)
22825 : 7989 : && REGNO (XEXP (geu, 0)) == FLAGS_REG
22826 : 7989 : && XEXP (geu, 1) == const0_rtx
22827 : 7989 : && GET_CODE (op1) == LTU
22828 : 7989 : && REG_P (XEXP (op1, 0))
22829 : 7989 : && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
22830 : 7989 : && REGNO (XEXP (op1, 0)) == FLAGS_REG
22831 : 54013617 : && XEXP (op1, 1) == const0_rtx)
22832 : : {
22833 : : /* This is *setcc_qi_addqi3_cconly_overflow_1_* patterns, a nop. */
22834 : 7989 : *total = 0;
22835 : 7989 : return true;
22836 : : }
22837 : : /* Match x
22838 : : (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
22839 : : (geu:QI (reg:CCC FLAGS_REG) (const_int 0))) */
22840 : 53997639 : if (mode == CCCmode
22841 : 404347 : && GET_CODE (op0) == NEG
22842 : 3 : && GET_CODE (XEXP (op0, 0)) == LTU
22843 : 3 : && REG_P (XEXP (XEXP (op0, 0), 0))
22844 : 3 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
22845 : 3 : && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
22846 : 3 : && XEXP (XEXP (op0, 0), 1) == const0_rtx
22847 : 3 : && GET_CODE (op1) == GEU
22848 : 3 : && REG_P (XEXP (op1, 0))
22849 : 3 : && GET_MODE (XEXP (op1, 0)) == CCCmode
22850 : 3 : && REGNO (XEXP (op1, 0)) == FLAGS_REG
22851 : 53997642 : && XEXP (op1, 1) == const0_rtx)
22852 : : {
22853 : : /* This is *x86_cmc. */
22854 : 3 : if (!speed)
22855 : 0 : *total = COSTS_N_BYTES (1);
22856 : 3 : else if (TARGET_SLOW_STC)
22857 : 0 : *total = COSTS_N_INSNS (2);
22858 : : else
22859 : 3 : *total = COSTS_N_INSNS (1);
22860 : 3 : return true;
22861 : : }
22862 : :
22863 : 53997636 : if (SCALAR_INT_MODE_P (GET_MODE (op0))
22864 : 112425780 : && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
22865 : : {
22866 : 794423 : if (op1 == const0_rtx)
22867 : 253594 : *total = cost->add
22868 : 126797 : + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed);
22869 : : else
22870 : 1335252 : *total = 3*cost->add
22871 : 667626 : + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed)
22872 : 667626 : + rtx_cost (op1, GET_MODE (op0), outer_code, opno, speed);
22873 : 794423 : return true;
22874 : : }
22875 : :
22876 : : /* The embedded comparison operand is completely free. */
22877 : 53203213 : if (!general_operand (op0, GET_MODE (op0)) && op1 == const0_rtx)
22878 : 376154 : *total = 0;
22879 : :
22880 : : return false;
22881 : :
22882 : 1358557 : case FLOAT_EXTEND:
22883 : : /* x87 represents all values extended to 80bit. */
22884 : 1358557 : if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22885 : 663774 : *total = 0;
22886 : : else
22887 : 1389566 : *total = vec_fp_conversion_cost (cost, GET_MODE_BITSIZE (mode));
22888 : : return false;
22889 : :
22890 : 82714 : case FLOAT_TRUNCATE:
22891 : 82714 : if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22892 : 58527 : *total = cost->fadd;
22893 : : else
22894 : 48374 : *total = vec_fp_conversion_cost (cost, GET_MODE_BITSIZE (mode));
22895 : : return false;
22896 : 680999 : case FLOAT:
22897 : 680999 : case UNSIGNED_FLOAT:
22898 : 680999 : if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22899 : : /* TODO: We do not have cost tables for x87. */
22900 : 92454 : *total = cost->fadd;
22901 : 588545 : else if (VECTOR_MODE_P (mode))
22902 : 0 : *total = ix86_vec_cost (mode, cost->cvtpi2ps);
22903 : : else
22904 : 588545 : *total = cost->cvtsi2ss;
22905 : : return false;
22906 : :
22907 : 274789 : case FIX:
22908 : 274789 : case UNSIGNED_FIX:
22909 : 274789 : if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22910 : : /* TODO: We do not have cost tables for x87. */
22911 : 274789 : *total = cost->fadd;
22912 : 0 : else if (VECTOR_MODE_P (mode))
22913 : 0 : *total = ix86_vec_cost (mode, cost->cvtps2pi);
22914 : : else
22915 : 0 : *total = cost->cvtss2si;
22916 : : return false;
22917 : :
22918 : 380011 : case ABS:
22919 : : /* SSE requires memory load for the constant operand. It may make
22920 : : sense to account for this. Of course the constant operand may or
22921 : : may not be reused. */
22922 : 380011 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22923 : 266251 : *total = cost->sse_op;
22924 : 113760 : else if (X87_FLOAT_MODE_P (mode))
22925 : 36964 : *total = cost->fabs;
22926 : 76796 : else if (FLOAT_MODE_P (mode))
22927 : 33878 : *total = ix86_vec_cost (mode, cost->sse_op);
22928 : 42918 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
22929 : 5796 : *total = cost->sse_op;
22930 : : return false;
22931 : :
22932 : 28200 : case SQRT:
22933 : 28200 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
22934 : 18076 : *total = mode == SFmode ? cost->sqrtss : cost->sqrtsd;
22935 : 10124 : else if (X87_FLOAT_MODE_P (mode))
22936 : 4269 : *total = cost->fsqrt;
22937 : 5855 : else if (FLOAT_MODE_P (mode))
22938 : 5855 : *total = ix86_vec_cost (mode,
22939 : : mode == SFmode ? cost->sqrtss : cost->sqrtsd);
22940 : : return false;
22941 : :
22942 : 3776408 : case UNSPEC:
22943 : 3776408 : if (XINT (x, 1) == UNSPEC_TP)
22944 : 116481 : *total = 0;
22945 : 3659927 : else if (XINT (x, 1) == UNSPEC_VTERNLOG)
22946 : : {
22947 : 5228 : *total = cost->sse_op;
22948 : 5228 : *total += rtx_cost (XVECEXP (x, 0, 0), mode, code, 0, speed);
22949 : 5228 : *total += rtx_cost (XVECEXP (x, 0, 1), mode, code, 1, speed);
22950 : 5228 : *total += rtx_cost (XVECEXP (x, 0, 2), mode, code, 2, speed);
22951 : 5228 : return true;
22952 : : }
22953 : 3654699 : else if (XINT (x, 1) == UNSPEC_PTEST)
22954 : : {
22955 : 44760 : *total = cost->sse_op;
22956 : 44760 : rtx test_op0 = XVECEXP (x, 0, 0);
22957 : 44760 : if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
22958 : : return false;
22959 : 44083 : if (GET_CODE (test_op0) == AND)
22960 : : {
22961 : 23 : rtx and_op0 = XEXP (test_op0, 0);
22962 : 23 : if (GET_CODE (and_op0) == NOT)
22963 : 0 : and_op0 = XEXP (and_op0, 0);
22964 : 23 : *total += rtx_cost (and_op0, GET_MODE (and_op0),
22965 : : AND, 0, speed)
22966 : 23 : + rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
22967 : : AND, 1, speed);
22968 : : }
22969 : : else
22970 : 44060 : *total = rtx_cost (test_op0, GET_MODE (test_op0),
22971 : : UNSPEC, 0, speed);
22972 : 44083 : return true;
22973 : : }
22974 : : return false;
22975 : :
22976 : 2061587 : case VEC_CONCAT:
22977 : : /* ??? Assume all of these vector manipulation patterns are
22978 : : recognizable. In which case they all pretty much have the
22979 : : same cost.
22980 : : ??? We should still recruse when computing cost. */
22981 : 2061587 : *total = cost->sse_op;
22982 : 2061587 : return true;
22983 : :
22984 : 2307068 : case VEC_SELECT:
22985 : : /* Special case extracting lower part from the vector.
22986 : : This by itself needs to code and most of SSE/AVX instructions have
22987 : : packed and single forms where the single form may be represented
22988 : : by such VEC_SELECT.
22989 : :
22990 : : Use cost 1 (despite the fact that functionally equivalent SUBREG has
22991 : : cost 0). Making VEC_SELECT completely free, for example instructs CSE
22992 : : to forward propagate VEC_SELECT into
22993 : :
22994 : : (set (reg eax) (reg src))
22995 : :
22996 : : which then prevents fwprop and combining. See i.e.
22997 : : gcc.target/i386/pr91103-1.c.
22998 : :
22999 : : ??? rtvec_series_p test should be, for valid patterns, equivalent to
23000 : : vec_series_lowpart_p but is not, since the latter calls
23001 : : can_cange_mode_class on ALL_REGS and this return false since x87 does
23002 : : not support subregs at all. */
23003 : 2307068 : if (rtvec_series_p (XVEC (XEXP (x, 1), 0), 0))
23004 : 742323 : *total = rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
23005 : 742323 : outer_code, opno, speed) + 1;
23006 : : else
23007 : : /* ??? We should still recruse when computing cost. */
23008 : 1564745 : *total = cost->sse_op;
23009 : : return true;
23010 : :
23011 : 1184406 : case VEC_DUPLICATE:
23012 : 2368812 : *total = rtx_cost (XEXP (x, 0),
23013 : 1184406 : GET_MODE (XEXP (x, 0)),
23014 : : VEC_DUPLICATE, 0, speed);
23015 : : /* It's broadcast instruction, not embedded broadcasting. */
23016 : 1184406 : if (outer_code == SET)
23017 : 1139579 : *total += cost->sse_op;
23018 : :
23019 : : return true;
23020 : :
23021 : 649014 : case VEC_MERGE:
23022 : 649014 : mask = XEXP (x, 2);
23023 : : /* Scalar versions of SSE instructions may be represented as:
23024 : :
23025 : : (vec_merge (vec_duplicate (operation ....))
23026 : : (register or memory)
23027 : : (const_int 1))
23028 : :
23029 : : In this case vec_merge and vec_duplicate is for free.
23030 : : Just recurse into operation and second operand. */
23031 : 649014 : if (mask == const1_rtx
23032 : 185488 : && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)
23033 : : {
23034 : 69511 : *total = rtx_cost (XEXP (XEXP (x, 0), 0), mode,
23035 : : outer_code, opno, speed)
23036 : 69511 : + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
23037 : 69511 : return true;
23038 : : }
23039 : : /* This is masked instruction, assume the same cost,
23040 : : as nonmasked variant. */
23041 : 579503 : else if (TARGET_AVX512F
23042 : 579503 : && (register_operand (mask, GET_MODE (mask))
23043 : : /* Redunduant clean up of high bits for kmask with VL=2/4
23044 : : .i.e (vec_merge op0, op1, (and op3 15)). */
23045 : 107892 : || (GET_CODE (mask) == AND
23046 : 328 : && register_operand (XEXP (mask, 0), GET_MODE (mask))
23047 : 328 : && CONST_INT_P (XEXP (mask, 1))
23048 : 328 : && ((INTVAL (XEXP (mask, 1)) == 3
23049 : 131 : && GET_MODE_NUNITS (mode) == 2)
23050 : 197 : || (INTVAL (XEXP (mask, 1)) == 15
23051 : 197 : && GET_MODE_NUNITS (mode) == 4)))))
23052 : : {
23053 : 345827 : *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
23054 : 345827 : + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
23055 : 345827 : return true;
23056 : : }
23057 : : /* Combination of the two above:
23058 : :
23059 : : (vec_merge (vec_merge (vec_duplicate (operation ...))
23060 : : (register or memory)
23061 : : (reg:QI mask))
23062 : : (register or memory)
23063 : : (const_int 1))
23064 : :
23065 : : i.e. avx512fp16_vcvtss2sh_mask. */
23066 : 233676 : else if (TARGET_AVX512F
23067 : 107564 : && mask == const1_rtx
23068 : 44831 : && GET_CODE (XEXP (x, 0)) == VEC_MERGE
23069 : 26723 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == VEC_DUPLICATE
23070 : 235902 : && register_operand (XEXP (XEXP (x, 0), 2),
23071 : 2226 : GET_MODE (XEXP (XEXP (x, 0), 2))))
23072 : : {
23073 : 2214 : *total = rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
23074 : : mode, outer_code, opno, speed)
23075 : 2214 : + rtx_cost (XEXP (XEXP (x, 0), 1),
23076 : : mode, outer_code, opno, speed)
23077 : 2214 : + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
23078 : 2214 : return true;
23079 : : }
23080 : : /* vcmp. */
23081 : 231462 : else if (unspec_pcmp_p (mask)
23082 : 231462 : || (GET_CODE (mask) == NOT
23083 : 0 : && unspec_pcmp_p (XEXP (mask, 0))))
23084 : : {
23085 : 1905 : rtx uns = GET_CODE (mask) == NOT ? XEXP (mask, 0) : mask;
23086 : 1905 : rtx unsop0 = XVECEXP (uns, 0, 0);
23087 : : /* Make (subreg:V4SI (not:V16QI (reg:V16QI ..)) 0)
23088 : : cost the same as register.
23089 : : This is used by avx_cmp<mode>3_ltint_not. */
23090 : 1905 : if (GET_CODE (unsop0) == SUBREG)
23091 : 417 : unsop0 = XEXP (unsop0, 0);
23092 : 1905 : if (GET_CODE (unsop0) == NOT)
23093 : 18 : unsop0 = XEXP (unsop0, 0);
23094 : 1905 : *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
23095 : 1905 : + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed)
23096 : 1905 : + rtx_cost (unsop0, mode, UNSPEC, opno, speed)
23097 : 1905 : + rtx_cost (XVECEXP (uns, 0, 1), mode, UNSPEC, opno, speed)
23098 : 1905 : + cost->sse_op;
23099 : 1905 : return true;
23100 : : }
23101 : : else
23102 : 229557 : *total = cost->sse_op;
23103 : 229557 : return false;
23104 : :
23105 : 106665224 : case MEM:
23106 : : /* CONST_VECTOR_DUPLICATE_P in constant_pool is just broadcast.
23107 : : or variants in ix86_vector_duplicate_simode_const. */
23108 : :
23109 : 106665224 : if (GET_MODE_SIZE (mode) >= 16
23110 : 17548117 : && VECTOR_MODE_P (mode)
23111 : 11481483 : && SYMBOL_REF_P (XEXP (x, 0))
23112 : 2161072 : && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))
23113 : 108627634 : && ix86_broadcast_from_constant (mode, x))
23114 : : {
23115 : 415665 : *total = COSTS_N_INSNS (2) + speed;
23116 : 415665 : return true;
23117 : : }
23118 : :
23119 : : /* An insn that accesses memory is slightly more expensive
23120 : : than one that does not. */
23121 : 106249559 : if (speed)
23122 : : {
23123 : 94959932 : *total += 1;
23124 : 94959932 : rtx addr = XEXP (x, 0);
23125 : : /* For MEM, rtx_cost iterates each subrtx, and adds up the costs,
23126 : : so for MEM (reg) and MEM (reg + 4), the former costs 5,
23127 : : the latter costs 9, it is not accurate for x86. Ideally
23128 : : address_cost should be used, but it reduce cost too much.
23129 : : So current solution is make constant disp as cheap as possible. */
23130 : 94959932 : if (GET_CODE (addr) == PLUS
23131 : 78524070 : && x86_64_immediate_operand (XEXP (addr, 1), Pmode)
23132 : : /* Only hanlde (reg + disp) since other forms of addr are mostly LEA,
23133 : : there's no additional cost for the plus of disp. */
23134 : 167856134 : && register_operand (XEXP (addr, 0), Pmode))
23135 : : {
23136 : 56897806 : *total += 1;
23137 : 69832980 : *total += rtx_cost (XEXP (addr, 0), Pmode, PLUS, 0, speed);
23138 : 56897806 : return true;
23139 : : }
23140 : : }
23141 : :
23142 : : return false;
23143 : :
23144 : 55799 : case ZERO_EXTRACT:
23145 : 55799 : if (XEXP (x, 1) == const1_rtx
23146 : 13270 : && GET_CODE (XEXP (x, 2)) == ZERO_EXTEND
23147 : 0 : && GET_MODE (XEXP (x, 2)) == SImode
23148 : 0 : && GET_MODE (XEXP (XEXP (x, 2), 0)) == QImode)
23149 : : {
23150 : : /* Ignore cost of zero extension and masking of last argument. */
23151 : 0 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
23152 : 0 : *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
23153 : 0 : *total += rtx_cost (XEXP (XEXP (x, 2), 0), mode, code, 2, speed);
23154 : 0 : return true;
23155 : : }
23156 : : return false;
23157 : :
23158 : 27368649 : case IF_THEN_ELSE:
23159 : 27368649 : if (TARGET_XOP
23160 : 17129 : && VECTOR_MODE_P (mode)
23161 : 27374343 : && (GET_MODE_SIZE (mode) == 16 || GET_MODE_SIZE (mode) == 32))
23162 : : {
23163 : : /* vpcmov. */
23164 : 5018 : *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (6);
23165 : 5018 : if (!REG_P (XEXP (x, 0)))
23166 : 4840 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
23167 : 5018 : if (!REG_P (XEXP (x, 1)))
23168 : 4804 : *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
23169 : 5018 : if (!REG_P (XEXP (x, 2)))
23170 : 4806 : *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
23171 : 5018 : return true;
23172 : : }
23173 : 0 : else if (TARGET_CMOVE
23174 : 27363631 : && SCALAR_INT_MODE_P (mode)
23175 : 29792853 : && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
23176 : : {
23177 : : /* cmov. */
23178 : 2250831 : *total = COSTS_N_INSNS (1);
23179 : 2250831 : if (!COMPARISON_P (XEXP (x, 0)) && !REG_P (XEXP (x, 0)))
23180 : 0 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
23181 : 2250831 : if (!REG_P (XEXP (x, 1)))
23182 : 125865 : *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
23183 : 2250831 : if (!REG_P (XEXP (x, 2)))
23184 : 677362 : *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
23185 : 2250831 : return true;
23186 : : }
23187 : : return false;
23188 : :
23189 : : default:
23190 : : return false;
23191 : : }
23192 : : }
23193 : :
23194 : : #if TARGET_MACHO
23195 : :
23196 : : static int current_machopic_label_num;
23197 : :
23198 : : /* Given a symbol name and its associated stub, write out the
23199 : : definition of the stub. */
23200 : :
23201 : : void
23202 : : machopic_output_stub (FILE *file, const char *symb, const char *stub)
23203 : : {
23204 : : unsigned int length;
23205 : : char *binder_name, *symbol_name, lazy_ptr_name[32];
23206 : : int label = ++current_machopic_label_num;
23207 : :
23208 : : /* For 64-bit we shouldn't get here. */
23209 : : gcc_assert (!TARGET_64BIT);
23210 : :
23211 : : /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
23212 : : symb = targetm.strip_name_encoding (symb);
23213 : :
23214 : : length = strlen (stub);
23215 : : binder_name = XALLOCAVEC (char, length + 32);
23216 : : GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
23217 : :
23218 : : length = strlen (symb);
23219 : : symbol_name = XALLOCAVEC (char, length + 32);
23220 : : GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
23221 : :
23222 : : sprintf (lazy_ptr_name, "L%d$lz", label);
23223 : :
23224 : : if (MACHOPIC_ATT_STUB)
23225 : : switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
23226 : : else if (MACHOPIC_PURE)
23227 : : switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
23228 : : else
23229 : : switch_to_section (darwin_sections[machopic_symbol_stub_section]);
23230 : :
23231 : : fprintf (file, "%s:\n", stub);
23232 : : fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23233 : :
23234 : : if (MACHOPIC_ATT_STUB)
23235 : : {
23236 : : fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
23237 : : }
23238 : : else if (MACHOPIC_PURE)
23239 : : {
23240 : : /* PIC stub. */
23241 : : /* 25-byte PIC stub using "CALL get_pc_thunk". */
23242 : : rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
23243 : : output_set_got (tmp, NULL_RTX); /* "CALL ___<cpu>.get_pc_thunk.cx". */
23244 : : fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
23245 : : label, lazy_ptr_name, label);
23246 : : fprintf (file, "\tjmp\t*%%ecx\n");
23247 : : }
23248 : : else
23249 : : fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
23250 : :
23251 : : /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
23252 : : it needs no stub-binding-helper. */
23253 : : if (MACHOPIC_ATT_STUB)
23254 : : return;
23255 : :
23256 : : fprintf (file, "%s:\n", binder_name);
23257 : :
23258 : : if (MACHOPIC_PURE)
23259 : : {
23260 : : fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
23261 : : fprintf (file, "\tpushl\t%%ecx\n");
23262 : : }
23263 : : else
23264 : : fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
23265 : :
23266 : : fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
23267 : :
23268 : : /* N.B. Keep the correspondence of these
23269 : : 'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
23270 : : old-pic/new-pic/non-pic stubs; altering this will break
23271 : : compatibility with existing dylibs. */
23272 : : if (MACHOPIC_PURE)
23273 : : {
23274 : : /* 25-byte PIC stub using "CALL get_pc_thunk". */
23275 : : switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
23276 : : }
23277 : : else
23278 : : /* 16-byte -mdynamic-no-pic stub. */
23279 : : switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
23280 : :
23281 : : fprintf (file, "%s:\n", lazy_ptr_name);
23282 : : fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
23283 : : fprintf (file, ASM_LONG "%s\n", binder_name);
23284 : : }
23285 : : #endif /* TARGET_MACHO */
23286 : :
23287 : : /* Order the registers for register allocator. */
23288 : :
23289 : : void
23290 : 212292 : x86_order_regs_for_local_alloc (void)
23291 : : {
23292 : 212292 : int pos = 0;
23293 : 212292 : int i;
23294 : :
23295 : : /* First allocate the local general purpose registers. */
23296 : 19743156 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
23297 : 26324208 : if (GENERAL_REGNO_P (i) && call_used_or_fixed_reg_p (i))
23298 : 5528977 : reg_alloc_order [pos++] = i;
23299 : :
23300 : : /* Global general purpose registers. */
23301 : 19743156 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
23302 : 22671616 : if (GENERAL_REGNO_P (i) && !call_used_or_fixed_reg_p (i))
23303 : 1264367 : reg_alloc_order [pos++] = i;
23304 : :
23305 : : /* x87 registers come first in case we are doing FP math
23306 : : using them. */
23307 : 212292 : if (!TARGET_SSE_MATH)
23308 : 56943 : for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
23309 : 50616 : reg_alloc_order [pos++] = i;
23310 : :
23311 : : /* SSE registers. */
23312 : 1910628 : for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
23313 : 1698336 : reg_alloc_order [pos++] = i;
23314 : 1910628 : for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
23315 : 1698336 : reg_alloc_order [pos++] = i;
23316 : :
23317 : : /* Extended REX SSE registers. */
23318 : 3608964 : for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
23319 : 3396672 : reg_alloc_order [pos++] = i;
23320 : :
23321 : : /* Mask register. */
23322 : 1910628 : for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
23323 : 1698336 : reg_alloc_order [pos++] = i;
23324 : :
23325 : : /* x87 registers. */
23326 : 212292 : if (TARGET_SSE_MATH)
23327 : 1853685 : for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
23328 : 1647720 : reg_alloc_order [pos++] = i;
23329 : :
23330 : 1910628 : for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
23331 : 1698336 : reg_alloc_order [pos++] = i;
23332 : :
23333 : : /* Initialize the rest of array as we do not allocate some registers
23334 : : at all. */
23335 : 1061460 : while (pos < FIRST_PSEUDO_REGISTER)
23336 : 849168 : reg_alloc_order [pos++] = 0;
23337 : 212292 : }
23338 : :
23339 : : static bool
23340 : 207394638 : ix86_ms_bitfield_layout_p (const_tree record_type)
23341 : : {
23342 : 207394638 : return ((TARGET_MS_BITFIELD_LAYOUT
23343 : 215 : && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
23344 : 207394638 : || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
23345 : : }
23346 : :
23347 : : /* Returns an expression indicating where the this parameter is
23348 : : located on entry to the FUNCTION. */
23349 : :
23350 : : static rtx
23351 : 1761 : x86_this_parameter (tree function)
23352 : : {
23353 : 1761 : tree type = TREE_TYPE (function);
23354 : 1761 : bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
23355 : 1761 : int nregs;
23356 : :
23357 : 1761 : if (TARGET_64BIT)
23358 : : {
23359 : 1759 : const int *parm_regs;
23360 : :
23361 : 1759 : if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type)))
23362 : : parm_regs = x86_64_preserve_none_int_parameter_registers;
23363 : 1759 : else if (ix86_function_type_abi (type) == MS_ABI)
23364 : : parm_regs = x86_64_ms_abi_int_parameter_registers;
23365 : : else
23366 : 1759 : parm_regs = x86_64_int_parameter_registers;
23367 : 1759 : return gen_rtx_REG (Pmode, parm_regs[aggr]);
23368 : : }
23369 : :
23370 : 2 : nregs = ix86_function_regparm (type, function);
23371 : :
23372 : 2 : if (nregs > 0 && !stdarg_p (type))
23373 : : {
23374 : 0 : int regno;
23375 : 0 : unsigned int ccvt = ix86_get_callcvt (type);
23376 : :
23377 : 0 : if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
23378 : 0 : regno = aggr ? DX_REG : CX_REG;
23379 : 0 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
23380 : : {
23381 : 0 : regno = CX_REG;
23382 : 0 : if (aggr)
23383 : 0 : return gen_rtx_MEM (SImode,
23384 : 0 : plus_constant (Pmode, stack_pointer_rtx, 4));
23385 : : }
23386 : : else
23387 : : {
23388 : 0 : regno = AX_REG;
23389 : 0 : if (aggr)
23390 : : {
23391 : 0 : regno = DX_REG;
23392 : 0 : if (nregs == 1)
23393 : 0 : return gen_rtx_MEM (SImode,
23394 : 0 : plus_constant (Pmode,
23395 : : stack_pointer_rtx, 4));
23396 : : }
23397 : : }
23398 : 0 : return gen_rtx_REG (SImode, regno);
23399 : : }
23400 : :
23401 : 4 : return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
23402 : 4 : aggr ? 8 : 4));
23403 : : }
23404 : :
23405 : : /* Determine whether x86_output_mi_thunk can succeed. */
23406 : :
23407 : : static bool
23408 : 4929 : x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
23409 : : const_tree function)
23410 : : {
23411 : : /* 64-bit can handle anything. */
23412 : 4929 : if (TARGET_64BIT)
23413 : : return true;
23414 : :
23415 : : /* For 32-bit, everything's fine if we have one free register. */
23416 : 76 : if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
23417 : : return true;
23418 : :
23419 : : /* Need a free register for vcall_offset. */
23420 : 0 : if (vcall_offset)
23421 : : return false;
23422 : :
23423 : : /* Need a free register for GOT references. */
23424 : 0 : if (flag_pic && !targetm.binds_local_p (function))
23425 : : return false;
23426 : :
23427 : : /* Otherwise ok. */
23428 : : return true;
23429 : : }
23430 : :
23431 : : /* Output the assembler code for a thunk function. THUNK_DECL is the
23432 : : declaration for the thunk function itself, FUNCTION is the decl for
23433 : : the target function. DELTA is an immediate constant offset to be
23434 : : added to THIS. If VCALL_OFFSET is nonzero, the word at
23435 : : *(*this + vcall_offset) should be added to THIS. */
23436 : :
23437 : : static void
23438 : 1761 : x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
23439 : : HOST_WIDE_INT vcall_offset, tree function)
23440 : : {
23441 : 1761 : const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
23442 : 1761 : rtx this_param = x86_this_parameter (function);
23443 : 1761 : rtx this_reg, tmp, fnaddr;
23444 : 1761 : unsigned int tmp_regno;
23445 : 1761 : rtx_insn *insn;
23446 : 1761 : int saved_flag_force_indirect_call = flag_force_indirect_call;
23447 : :
23448 : 1761 : if (TARGET_64BIT)
23449 : : tmp_regno = R10_REG;
23450 : : else
23451 : : {
23452 : 2 : unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
23453 : 2 : if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
23454 : : tmp_regno = AX_REG;
23455 : 2 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
23456 : : tmp_regno = DX_REG;
23457 : : else
23458 : 2 : tmp_regno = CX_REG;
23459 : :
23460 : 2 : if (flag_pic)
23461 : 2 : flag_force_indirect_call = 0;
23462 : : }
23463 : :
23464 : 1761 : emit_note (NOTE_INSN_PROLOGUE_END);
23465 : :
23466 : : /* CET is enabled, insert EB instruction. */
23467 : 1761 : if ((flag_cf_protection & CF_BRANCH))
23468 : 20 : emit_insn (gen_nop_endbr ());
23469 : :
23470 : : /* If VCALL_OFFSET, we'll need THIS in a register. Might as well
23471 : : pull it in now and let DELTA benefit. */
23472 : 1761 : if (REG_P (this_param))
23473 : : this_reg = this_param;
23474 : 2 : else if (vcall_offset)
23475 : : {
23476 : : /* Put the this parameter into %eax. */
23477 : 2 : this_reg = gen_rtx_REG (Pmode, AX_REG);
23478 : 1 : emit_move_insn (this_reg, this_param);
23479 : : }
23480 : : else
23481 : : this_reg = NULL_RTX;
23482 : :
23483 : : /* Adjust the this parameter by a fixed constant. */
23484 : 1761 : if (delta)
23485 : : {
23486 : 826 : rtx delta_rtx = GEN_INT (delta);
23487 : 826 : rtx delta_dst = this_reg ? this_reg : this_param;
23488 : :
23489 : 826 : if (TARGET_64BIT)
23490 : : {
23491 : 825 : if (!x86_64_general_operand (delta_rtx, Pmode))
23492 : : {
23493 : 0 : tmp = gen_rtx_REG (Pmode, tmp_regno);
23494 : 0 : emit_move_insn (tmp, delta_rtx);
23495 : 0 : delta_rtx = tmp;
23496 : : }
23497 : : }
23498 : :
23499 : 827 : ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
23500 : : }
23501 : :
23502 : : /* Adjust the this parameter by a value stored in the vtable. */
23503 : 1761 : if (vcall_offset)
23504 : : {
23505 : 986 : rtx vcall_addr, vcall_mem, this_mem;
23506 : :
23507 : 987 : tmp = gen_rtx_REG (Pmode, tmp_regno);
23508 : :
23509 : 986 : this_mem = gen_rtx_MEM (ptr_mode, this_reg);
23510 : 987 : if (Pmode != ptr_mode)
23511 : 0 : this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
23512 : 986 : emit_move_insn (tmp, this_mem);
23513 : :
23514 : : /* Adjust the this parameter. */
23515 : 987 : vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
23516 : 986 : if (TARGET_64BIT
23517 : 986 : && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
23518 : : {
23519 : 0 : rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
23520 : 0 : emit_move_insn (tmp2, GEN_INT (vcall_offset));
23521 : 0 : vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
23522 : : }
23523 : :
23524 : 986 : vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
23525 : 987 : if (Pmode != ptr_mode)
23526 : 0 : emit_insn (gen_addsi_1_zext (this_reg,
23527 : : gen_rtx_REG (ptr_mode,
23528 : : REGNO (this_reg)),
23529 : : vcall_mem));
23530 : : else
23531 : 986 : ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
23532 : : }
23533 : :
23534 : : /* If necessary, drop THIS back to its stack slot. */
23535 : 1761 : if (this_reg && this_reg != this_param)
23536 : 1 : emit_move_insn (this_param, this_reg);
23537 : :
23538 : 1761 : fnaddr = XEXP (DECL_RTL (function), 0);
23539 : 1761 : if (TARGET_64BIT)
23540 : : {
23541 : 25 : if (!flag_pic || targetm.binds_local_p (function)
23542 : 1784 : || TARGET_PECOFF)
23543 : : ;
23544 : : else
23545 : : {
23546 : 0 : tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
23547 : 0 : tmp = gen_rtx_CONST (Pmode, tmp);
23548 : 0 : fnaddr = gen_const_mem (Pmode, tmp);
23549 : : }
23550 : : }
23551 : : else
23552 : : {
23553 : 2 : if (!flag_pic || targetm.binds_local_p (function))
23554 : : ;
23555 : : #if TARGET_MACHO
23556 : : else if (TARGET_MACHO)
23557 : : {
23558 : : fnaddr = machopic_indirect_call_target (DECL_RTL (function));
23559 : : fnaddr = XEXP (fnaddr, 0);
23560 : : }
23561 : : #endif /* TARGET_MACHO */
23562 : : else
23563 : : {
23564 : 0 : tmp = gen_rtx_REG (Pmode, CX_REG);
23565 : 0 : output_set_got (tmp, NULL_RTX);
23566 : :
23567 : 0 : fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
23568 : 0 : fnaddr = gen_rtx_CONST (Pmode, fnaddr);
23569 : 0 : fnaddr = gen_rtx_PLUS (Pmode, tmp, fnaddr);
23570 : 0 : fnaddr = gen_const_mem (Pmode, fnaddr);
23571 : : }
23572 : : }
23573 : :
23574 : : /* Our sibling call patterns do not allow memories, because we have no
23575 : : predicate that can distinguish between frame and non-frame memory.
23576 : : For our purposes here, we can get away with (ab)using a jump pattern,
23577 : : because we're going to do no optimization. */
23578 : 1761 : if (MEM_P (fnaddr))
23579 : : {
23580 : 0 : if (sibcall_insn_operand (fnaddr, word_mode))
23581 : : {
23582 : 0 : fnaddr = XEXP (DECL_RTL (function), 0);
23583 : 0 : tmp = gen_rtx_MEM (QImode, fnaddr);
23584 : 0 : tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
23585 : 0 : tmp = emit_call_insn (tmp);
23586 : 0 : SIBLING_CALL_P (tmp) = 1;
23587 : : }
23588 : : else
23589 : 0 : emit_jump_insn (gen_indirect_jump (fnaddr));
23590 : : }
23591 : : else
23592 : : {
23593 : 1761 : if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
23594 : : {
23595 : : // CM_LARGE_PIC always uses pseudo PIC register which is
23596 : : // uninitialized. Since FUNCTION is local and calling it
23597 : : // doesn't go through PLT, we use scratch register %r11 as
23598 : : // PIC register and initialize it here.
23599 : 3 : pic_offset_table_rtx = gen_rtx_REG (Pmode, R11_REG);
23600 : 3 : ix86_init_large_pic_reg (tmp_regno);
23601 : 3 : fnaddr = legitimize_pic_address (fnaddr,
23602 : 3 : gen_rtx_REG (Pmode, tmp_regno));
23603 : : }
23604 : :
23605 : 1761 : if (!sibcall_insn_operand (fnaddr, word_mode))
23606 : : {
23607 : 9 : tmp = gen_rtx_REG (word_mode, tmp_regno);
23608 : 9 : if (GET_MODE (fnaddr) != word_mode)
23609 : 0 : fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
23610 : 9 : emit_move_insn (tmp, fnaddr);
23611 : 9 : fnaddr = tmp;
23612 : : }
23613 : :
23614 : 1761 : tmp = gen_rtx_MEM (QImode, fnaddr);
23615 : 1761 : tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
23616 : 1761 : tmp = emit_call_insn (tmp);
23617 : 1761 : SIBLING_CALL_P (tmp) = 1;
23618 : : }
23619 : 1761 : emit_barrier ();
23620 : :
23621 : : /* Emit just enough of rest_of_compilation to get the insns emitted. */
23622 : 1761 : insn = get_insns ();
23623 : 1761 : shorten_branches (insn);
23624 : 1761 : assemble_start_function (thunk_fndecl, fnname);
23625 : 1761 : final_start_function (insn, file, 1);
23626 : 1761 : final (insn, file, 1);
23627 : 1761 : final_end_function ();
23628 : 1761 : assemble_end_function (thunk_fndecl, fnname);
23629 : :
23630 : 1761 : flag_force_indirect_call = saved_flag_force_indirect_call;
23631 : 1761 : }
23632 : :
23633 : : static void
23634 : 269382 : x86_file_start (void)
23635 : : {
23636 : 269382 : default_file_start ();
23637 : 269382 : if (TARGET_16BIT)
23638 : 5 : fputs ("\t.code16gcc\n", asm_out_file);
23639 : : #if TARGET_MACHO
23640 : : darwin_file_start ();
23641 : : #endif
23642 : 269382 : if (X86_FILE_START_VERSION_DIRECTIVE)
23643 : : fputs ("\t.version\t\"01.01\"\n", asm_out_file);
23644 : 269382 : if (X86_FILE_START_FLTUSED)
23645 : : fputs ("\t.global\t__fltused\n", asm_out_file);
23646 : 269382 : if (ix86_asm_dialect == ASM_INTEL)
23647 : 60 : fputs ("\t.intel_syntax noprefix\n", asm_out_file);
23648 : 269382 : }
23649 : :
23650 : : int
23651 : 91151480 : x86_field_alignment (tree type, int computed)
23652 : : {
23653 : 91151480 : machine_mode mode;
23654 : :
23655 : 91151480 : if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
23656 : : return computed;
23657 : 8962435 : if (TARGET_IAMCU)
23658 : 0 : return iamcu_alignment (type, computed);
23659 : 8962435 : type = strip_array_types (type);
23660 : 8962435 : mode = TYPE_MODE (type);
23661 : 8962435 : if (mode == DFmode || mode == DCmode
23662 : 8858753 : || GET_MODE_CLASS (mode) == MODE_INT
23663 : 3059284 : || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
23664 : : {
23665 : 5903151 : if (TYPE_ATOMIC (type) && computed > 32)
23666 : : {
23667 : 0 : static bool warned;
23668 : :
23669 : 0 : if (!warned && warn_psabi)
23670 : : {
23671 : 0 : const char *url
23672 : : = CHANGES_ROOT_URL "gcc-11/changes.html#ia32_atomic";
23673 : :
23674 : 0 : warned = true;
23675 : 0 : inform (input_location, "the alignment of %<_Atomic %T%> "
23676 : : "fields changed in %{GCC 11.1%}",
23677 : 0 : TYPE_MAIN_VARIANT (type), url);
23678 : : }
23679 : : }
23680 : : else
23681 : 5903151 : return MIN (32, computed);
23682 : : }
23683 : : return computed;
23684 : : }
23685 : :
23686 : : /* Print call to TARGET to FILE. */
23687 : :
23688 : : static void
23689 : 343 : x86_print_call_or_nop (FILE *file, const char *target,
23690 : : const char *label)
23691 : : {
23692 : 343 : if (flag_nop_mcount || !strcmp (target, "nop"))
23693 : : /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
23694 : 8 : fprintf (file, "%s" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n",
23695 : : label);
23696 : 335 : else if (!TARGET_PECOFF && flag_pic)
23697 : : {
23698 : 8 : gcc_assert (flag_plt);
23699 : :
23700 : 8 : fprintf (file, "%s\tcall\t%s@PLT\n", label, target);
23701 : : }
23702 : : else
23703 : 327 : fprintf (file, "%s\tcall\t%s\n", label, target);
23704 : 343 : }
23705 : :
23706 : : static bool
23707 : 363 : current_fentry_name (const char **name)
23708 : : {
23709 : 363 : tree attr = lookup_attribute ("fentry_name",
23710 : 363 : DECL_ATTRIBUTES (current_function_decl));
23711 : 363 : if (!attr)
23712 : : return false;
23713 : 2 : *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
23714 : 2 : return true;
23715 : : }
23716 : :
23717 : : static bool
23718 : 16 : current_fentry_section (const char **name)
23719 : : {
23720 : 16 : tree attr = lookup_attribute ("fentry_section",
23721 : 16 : DECL_ATTRIBUTES (current_function_decl));
23722 : 16 : if (!attr)
23723 : : return false;
23724 : 2 : *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
23725 : 2 : return true;
23726 : : }
23727 : :
23728 : : /* Return a caller-saved register which isn't live or a callee-saved
23729 : : register which has been saved on stack in the prologue at entry for
23730 : : profile. */
23731 : :
23732 : : static int
23733 : 17 : x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
23734 : : {
23735 : : /* Use %r10 if the profiler is emitted before the prologue or it isn't
23736 : : used by DRAP. */
23737 : 17 : if (ix86_profile_before_prologue ()
23738 : 13 : || !crtl->drap_reg
23739 : 20 : || REGNO (crtl->drap_reg) != R10_REG)
23740 : : return R10_REG;
23741 : :
23742 : : /* The profiler is emitted after the prologue. If there is a
23743 : : caller-saved register which isn't live or a callee-saved
23744 : : register saved on stack in the prologue, use it. */
23745 : :
23746 : 3 : bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
23747 : :
23748 : 3 : int i;
23749 : 88 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
23750 : 56 : if (GENERAL_REGNO_P (i)
23751 : 29 : && i != R10_REG
23752 : : #ifdef NO_PROFILE_COUNTERS
23753 : 27 : && (r11_ok || i != R11_REG)
23754 : : #else
23755 : : && i != R11_REG
23756 : : #endif
23757 : 26 : && TEST_HARD_REG_BIT (accessible_reg_set, i)
23758 : 111 : && (ix86_save_reg (i, true, true)
23759 : 25 : || (call_used_regs[i]
23760 : 18 : && !fixed_regs[i]
23761 : 16 : && !REGNO_REG_SET_P (reg_live, i))))
23762 : 3 : return i;
23763 : :
23764 : 0 : sorry ("no register available for profiling %<-mcmodel=large%s%>",
23765 : 0 : ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
23766 : :
23767 : 0 : return R10_REG;
23768 : : }
23769 : :
23770 : : /* Output assembler code to FILE to increment profiler label # LABELNO
23771 : : for profiling a function entry. */
23772 : : void
23773 : 363 : x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
23774 : : {
23775 : 363 : if (cfun->machine->insn_queued_at_entrance)
23776 : : {
23777 : 5 : if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
23778 : 4 : fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
23779 : 5 : unsigned int patch_area_size
23780 : 5 : = crtl->patch_area_size - crtl->patch_area_entry;
23781 : 5 : if (patch_area_size)
23782 : 2 : ix86_output_patchable_area (patch_area_size,
23783 : : crtl->patch_area_entry == 0);
23784 : : }
23785 : :
23786 : 363 : const char *mcount_name = MCOUNT_NAME;
23787 : :
23788 : 363 : bool fentry_section_p
23789 : 363 : = (flag_record_mcount
23790 : 711 : || lookup_attribute ("fentry_section",
23791 : 348 : DECL_ATTRIBUTES (current_function_decl)));
23792 : :
23793 : : const char *label = fentry_section_p ? "1:" : "";
23794 : :
23795 : 363 : if (current_fentry_name (&mcount_name))
23796 : : ;
23797 : 361 : else if (fentry_name)
23798 : 1 : mcount_name = fentry_name;
23799 : 360 : else if (flag_fentry)
23800 : 21 : mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
23801 : :
23802 : 363 : if (TARGET_64BIT)
23803 : : {
23804 : : #ifndef NO_PROFILE_COUNTERS
23805 : : if (ASSEMBLER_DIALECT == ASM_INTEL)
23806 : : fprintf (file, "\tlea\tr11, %sP%d[rip]\n", LPREFIX, labelno);
23807 : : else
23808 : : fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
23809 : : #endif
23810 : :
23811 : 363 : int scratch;
23812 : 363 : const char *reg;
23813 : 363 : char legacy_reg[4] = { 0 };
23814 : :
23815 : 363 : if (!TARGET_PECOFF)
23816 : : {
23817 : 363 : switch (ix86_cmodel)
23818 : : {
23819 : 7 : case CM_LARGE:
23820 : 7 : scratch = x86_64_select_profile_regnum (true);
23821 : 7 : reg = hi_reg_name[scratch];
23822 : 7 : if (LEGACY_INT_REGNO_P (scratch))
23823 : : {
23824 : 0 : legacy_reg[0] = 'r';
23825 : 0 : legacy_reg[1] = reg[0];
23826 : 0 : legacy_reg[2] = reg[1];
23827 : 0 : reg = legacy_reg;
23828 : : }
23829 : 7 : if (ASSEMBLER_DIALECT == ASM_INTEL)
23830 : 1 : fprintf (file, "%s\tmovabs\t%s, OFFSET FLAT:%s\n"
23831 : : "\tcall\t%s\n", label, reg, mcount_name,
23832 : : reg);
23833 : : else
23834 : 6 : fprintf (file, "%s\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n",
23835 : : label, mcount_name, reg, reg);
23836 : : break;
23837 : 10 : case CM_LARGE_PIC:
23838 : : #ifdef NO_PROFILE_COUNTERS
23839 : 10 : scratch = x86_64_select_profile_regnum (false);
23840 : 10 : reg = hi_reg_name[scratch];
23841 : 10 : if (LEGACY_INT_REGNO_P (scratch))
23842 : : {
23843 : 1 : legacy_reg[0] = 'r';
23844 : 1 : legacy_reg[1] = reg[0];
23845 : 1 : legacy_reg[2] = reg[1];
23846 : 1 : reg = legacy_reg;
23847 : : }
23848 : 10 : if (ASSEMBLER_DIALECT == ASM_INTEL)
23849 : : {
23850 : 1 : fprintf (file, "1:movabs\tr11, "
23851 : : "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
23852 : 1 : fprintf (file, "\tlea\t%s, 1b[rip]\n", reg);
23853 : 1 : fprintf (file, "\tadd\t%s, r11\n", reg);
23854 : 1 : fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
23855 : : mcount_name);
23856 : 1 : fprintf (file, "\tadd\t%s, r11\n", reg);
23857 : 1 : fprintf (file, "\tcall\t%s\n", reg);
23858 : 1 : break;
23859 : : }
23860 : 9 : fprintf (file,
23861 : : "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
23862 : 9 : fprintf (file, "\tleaq\t1b(%%rip), %%%s\n", reg);
23863 : 9 : fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
23864 : 9 : fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
23865 : 9 : fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
23866 : 9 : fprintf (file, "\tcall\t*%%%s\n", reg);
23867 : : #else
23868 : : sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
23869 : : #endif
23870 : 9 : break;
23871 : 12 : case CM_SMALL_PIC:
23872 : 12 : case CM_MEDIUM_PIC:
23873 : 12 : if (!flag_plt)
23874 : : {
23875 : 3 : if (ASSEMBLER_DIALECT == ASM_INTEL)
23876 : 0 : fprintf (file, "%s\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n",
23877 : : label, mcount_name);
23878 : : else
23879 : 3 : fprintf (file, "%s\tcall\t*%s@GOTPCREL(%%rip)\n",
23880 : : label, mcount_name);
23881 : : break;
23882 : : }
23883 : : /* fall through */
23884 : 343 : default:
23885 : 343 : x86_print_call_or_nop (file, mcount_name, label);
23886 : 343 : break;
23887 : : }
23888 : : }
23889 : : else
23890 : : x86_print_call_or_nop (file, mcount_name, label);
23891 : : }
23892 : 0 : else if (flag_pic)
23893 : : {
23894 : : #ifndef NO_PROFILE_COUNTERS
23895 : : if (ASSEMBLER_DIALECT == ASM_INTEL)
23896 : : fprintf (file,
23897 : : "\tlea\t" PROFILE_COUNT_REGISTER ", %sP%d@GOTOFF[ebx]\n",
23898 : : LPREFIX, labelno);
23899 : : else
23900 : : fprintf (file,
23901 : : "\tleal\t%sP%d@GOTOFF(%%ebx), %%" PROFILE_COUNT_REGISTER "\n",
23902 : : LPREFIX, labelno);
23903 : : #endif
23904 : 0 : if (flag_plt)
23905 : 0 : x86_print_call_or_nop (file, mcount_name, label);
23906 : 0 : else if (ASSEMBLER_DIALECT == ASM_INTEL)
23907 : 0 : fprintf (file, "%s\tcall\t[DWORD PTR %s@GOT[ebx]]\n",
23908 : : label, mcount_name);
23909 : : else
23910 : 0 : fprintf (file, "%s\tcall\t*%s@GOT(%%ebx)\n",
23911 : : label, mcount_name);
23912 : : }
23913 : : else
23914 : : {
23915 : : #ifndef NO_PROFILE_COUNTERS
23916 : : if (ASSEMBLER_DIALECT == ASM_INTEL)
23917 : : fprintf (file,
23918 : : "\tmov\t" PROFILE_COUNT_REGISTER ", OFFSET FLAT:%sP%d\n",
23919 : : LPREFIX, labelno);
23920 : : else
23921 : : fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n",
23922 : : LPREFIX, labelno);
23923 : : #endif
23924 : 0 : x86_print_call_or_nop (file, mcount_name, label);
23925 : : }
23926 : :
23927 : 363 : if (fentry_section_p)
23928 : : {
23929 : 16 : const char *sname = "__mcount_loc";
23930 : :
23931 : 16 : if (current_fentry_section (&sname))
23932 : : ;
23933 : 14 : else if (fentry_section)
23934 : 1 : sname = fentry_section;
23935 : :
23936 : 16 : fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
23937 : 16 : fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
23938 : 16 : fprintf (file, "\t.previous\n");
23939 : : }
23940 : 363 : }
23941 : :
23942 : : /* We don't have exact information about the insn sizes, but we may assume
23943 : : quite safely that we are informed about all 1 byte insns and memory
23944 : : address sizes. This is enough to eliminate unnecessary padding in
23945 : : 99% of cases. */
23946 : :
23947 : : int
23948 : 381522069 : ix86_min_insn_size (rtx_insn *insn)
23949 : : {
23950 : 381522069 : int l = 0, len;
23951 : :
23952 : 381522069 : if (!INSN_P (insn) || !active_insn_p (insn))
23953 : 499084 : return 0;
23954 : :
23955 : : /* Discard alignments we've emit and jump instructions. */
23956 : 381022985 : if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
23957 : 381022985 : && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
23958 : : return 0;
23959 : :
23960 : : /* Important case - calls are always 5 bytes.
23961 : : It is common to have many calls in the row. */
23962 : 381022980 : if (CALL_P (insn)
23963 : 9059923 : && symbolic_reference_mentioned_p (PATTERN (insn))
23964 : 389733354 : && !SIBLING_CALL_P (insn))
23965 : : return 5;
23966 : 372545395 : len = get_attr_length (insn);
23967 : 372545395 : if (len <= 1)
23968 : : return 1;
23969 : :
23970 : : /* For normal instructions we rely on get_attr_length being exact,
23971 : : with a few exceptions. */
23972 : 363881966 : if (!JUMP_P (insn))
23973 : : {
23974 : 358575173 : enum attr_type type = get_attr_type (insn);
23975 : :
23976 : 358575173 : switch (type)
23977 : : {
23978 : 93437 : case TYPE_MULTI:
23979 : 93437 : if (GET_CODE (PATTERN (insn)) == ASM_INPUT
23980 : 93437 : || asm_noperands (PATTERN (insn)) >= 0)
23981 : 502 : return 0;
23982 : : break;
23983 : : case TYPE_OTHER:
23984 : : case TYPE_FCMP:
23985 : : break;
23986 : : default:
23987 : : /* Otherwise trust get_attr_length. */
23988 : : return len;
23989 : : }
23990 : :
23991 : 468250 : l = get_attr_length_address (insn);
23992 : 468250 : if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
23993 : : l = 4;
23994 : : }
23995 : 378190 : if (l)
23996 : 90060 : return 1+l;
23997 : : else
23998 : 5684983 : return 2;
23999 : : }
24000 : :
24001 : : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
24002 : :
24003 : : /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
24004 : : window. */
24005 : :
24006 : : static void
24007 : 45346 : ix86_avoid_jump_mispredicts (void)
24008 : : {
24009 : 45346 : rtx_insn *insn, *start = get_insns ();
24010 : 45346 : int nbytes = 0, njumps = 0;
24011 : 45346 : bool isjump = false;
24012 : :
24013 : : /* Look for all minimal intervals of instructions containing 4 jumps.
24014 : : The intervals are bounded by START and INSN. NBYTES is the total
24015 : : size of instructions in the interval including INSN and not including
24016 : : START. When the NBYTES is smaller than 16 bytes, it is possible
24017 : : that the end of START and INSN ends up in the same 16byte page.
24018 : :
24019 : : The smallest offset in the page INSN can start is the case where START
24020 : : ends on the offset 0. Offset of INSN is then NBYTES - sizeof (INSN).
24021 : : We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
24022 : :
24023 : : Don't consider asm goto as jump, while it can contain a jump, it doesn't
24024 : : have to, control transfer to label(s) can be performed through other
24025 : : means, and also we estimate minimum length of all asm stmts as 0. */
24026 : 699346 : for (insn = start; insn; insn = NEXT_INSN (insn))
24027 : : {
24028 : 654000 : int min_size;
24029 : :
24030 : 654000 : if (LABEL_P (insn))
24031 : : {
24032 : 940 : align_flags alignment = label_to_alignment (insn);
24033 : 940 : int align = alignment.levels[0].log;
24034 : 940 : int max_skip = alignment.levels[0].maxskip;
24035 : :
24036 : 940 : if (max_skip > 15)
24037 : : max_skip = 15;
24038 : : /* If align > 3, only up to 16 - max_skip - 1 bytes can be
24039 : : already in the current 16 byte page, because otherwise
24040 : : ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
24041 : : bytes to reach 16 byte boundary. */
24042 : 940 : if (align <= 0
24043 : 313 : || (align <= 3 && max_skip != (1 << align) - 1))
24044 : 940 : max_skip = 0;
24045 : 940 : if (dump_file)
24046 : 0 : fprintf (dump_file, "Label %i with max_skip %i\n",
24047 : 0 : INSN_UID (insn), max_skip);
24048 : 940 : if (max_skip)
24049 : : {
24050 : 5975 : while (nbytes + max_skip >= 16)
24051 : : {
24052 : 5662 : start = NEXT_INSN (start);
24053 : 298 : if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
24054 : 5677 : || CALL_P (start))
24055 : 331 : njumps--, isjump = true;
24056 : : else
24057 : : isjump = false;
24058 : 5662 : nbytes -= ix86_min_insn_size (start);
24059 : : }
24060 : : }
24061 : 940 : continue;
24062 : 940 : }
24063 : :
24064 : 653060 : min_size = ix86_min_insn_size (insn);
24065 : 653060 : nbytes += min_size;
24066 : 653060 : if (dump_file)
24067 : 0 : fprintf (dump_file, "Insn %i estimated to %i bytes\n",
24068 : 0 : INSN_UID (insn), min_size);
24069 : 46487 : if ((JUMP_P (insn) && asm_noperands (PATTERN (insn)) < 0)
24070 : 653080 : || CALL_P (insn))
24071 : 47504 : njumps++;
24072 : : else
24073 : 605556 : continue;
24074 : :
24075 : 55952 : while (njumps > 3)
24076 : : {
24077 : 8448 : start = NEXT_INSN (start);
24078 : 542 : if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
24079 : 8448 : || CALL_P (start))
24080 : 1247 : njumps--, isjump = true;
24081 : : else
24082 : : isjump = false;
24083 : 8448 : nbytes -= ix86_min_insn_size (start);
24084 : : }
24085 : 47504 : gcc_assert (njumps >= 0);
24086 : 47504 : if (dump_file)
24087 : 0 : fprintf (dump_file, "Interval %i to %i has %i bytes\n",
24088 : 0 : INSN_UID (start), INSN_UID (insn), nbytes);
24089 : :
24090 : 47504 : if (njumps == 3 && isjump && nbytes < 16)
24091 : : {
24092 : 40 : int padsize = 15 - nbytes + ix86_min_insn_size (insn);
24093 : :
24094 : 40 : if (dump_file)
24095 : 0 : fprintf (dump_file, "Padding insn %i by %i bytes!\n",
24096 : 0 : INSN_UID (insn), padsize);
24097 : 40 : emit_insn_before (gen_max_skip_align (GEN_INT (4), GEN_INT (padsize)), insn);
24098 : : }
24099 : : }
24100 : 45346 : }
24101 : : #endif
24102 : :
24103 : : /* AMD Athlon works faster
24104 : : when RET is not destination of conditional jump or directly preceded
24105 : : by other jump instruction. We avoid the penalty by inserting NOP just
24106 : : before the RET instructions in such cases. */
24107 : : static void
24108 : 45066 : ix86_pad_returns (void)
24109 : : {
24110 : 45066 : edge e;
24111 : 45066 : edge_iterator ei;
24112 : :
24113 : 90156 : FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
24114 : : {
24115 : 45090 : basic_block bb = e->src;
24116 : 45090 : rtx_insn *ret = BB_END (bb);
24117 : 45090 : rtx_insn *prev;
24118 : 45090 : bool replace = false;
24119 : :
24120 : 45080 : if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
24121 : 90170 : || optimize_bb_for_size_p (bb))
24122 : 23 : continue;
24123 : 179362 : for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
24124 : 133883 : if (active_insn_p (prev) || LABEL_P (prev))
24125 : : break;
24126 : 45067 : if (prev && LABEL_P (prev))
24127 : : {
24128 : 43 : edge e;
24129 : 43 : edge_iterator ei;
24130 : :
24131 : 56 : FOR_EACH_EDGE (e, ei, bb->preds)
24132 : 146 : if (EDGE_FREQUENCY (e) && e->src->index >= 0
24133 : 97 : && !(e->flags & EDGE_FALLTHRU))
24134 : : {
24135 : : replace = true;
24136 : : break;
24137 : : }
24138 : : }
24139 : 43 : if (!replace)
24140 : : {
24141 : 45031 : prev = prev_active_insn (ret);
24142 : 45031 : if (prev
24143 : 45031 : && ((JUMP_P (prev) && any_condjump_p (prev))
24144 : 44601 : || CALL_P (prev)))
24145 : : replace = true;
24146 : : /* Empty functions get branch mispredict even when
24147 : : the jump destination is not visible to us. */
24148 : 45031 : if (!prev && !optimize_function_for_size_p (cfun))
24149 : : replace = true;
24150 : : }
24151 : 44619 : if (replace)
24152 : : {
24153 : 483 : emit_jump_insn_before (gen_simple_return_internal_long (), ret);
24154 : 483 : delete_insn (ret);
24155 : : }
24156 : : }
24157 : 45066 : }
24158 : :
24159 : : /* Count the minimum number of instructions in BB. Return 4 if the
24160 : : number of instructions >= 4. */
24161 : :
24162 : : static int
24163 : 42 : ix86_count_insn_bb (basic_block bb)
24164 : : {
24165 : 42 : rtx_insn *insn;
24166 : 42 : int insn_count = 0;
24167 : :
24168 : : /* Count number of instructions in this block. Return 4 if the number
24169 : : of instructions >= 4. */
24170 : 308 : FOR_BB_INSNS (bb, insn)
24171 : : {
24172 : : /* Only happen in exit blocks. */
24173 : 302 : if (JUMP_P (insn)
24174 : 302 : && ANY_RETURN_P (PATTERN (insn)))
24175 : : break;
24176 : :
24177 : 278 : if (NONDEBUG_INSN_P (insn)
24178 : 102 : && GET_CODE (PATTERN (insn)) != USE
24179 : 362 : && GET_CODE (PATTERN (insn)) != CLOBBER)
24180 : : {
24181 : 84 : insn_count++;
24182 : 84 : if (insn_count >= 4)
24183 : : return insn_count;
24184 : : }
24185 : : }
24186 : :
24187 : : return insn_count;
24188 : : }
24189 : :
24190 : :
24191 : : /* Count the minimum number of instructions in code path in BB.
24192 : : Return 4 if the number of instructions >= 4. */
24193 : :
24194 : : static int
24195 : 62 : ix86_count_insn (basic_block bb)
24196 : : {
24197 : 62 : edge e;
24198 : 62 : edge_iterator ei;
24199 : 62 : int min_prev_count;
24200 : :
24201 : : /* Only bother counting instructions along paths with no
24202 : : more than 2 basic blocks between entry and exit. Given
24203 : : that BB has an edge to exit, determine if a predecessor
24204 : : of BB has an edge from entry. If so, compute the number
24205 : : of instructions in the predecessor block. If there
24206 : : happen to be multiple such blocks, compute the minimum. */
24207 : 62 : min_prev_count = 4;
24208 : 143 : FOR_EACH_EDGE (e, ei, bb->preds)
24209 : : {
24210 : 107 : edge prev_e;
24211 : 107 : edge_iterator prev_ei;
24212 : :
24213 : 107 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
24214 : : {
24215 : 26 : min_prev_count = 0;
24216 : 26 : break;
24217 : : }
24218 : 178 : FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
24219 : : {
24220 : 107 : if (prev_e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
24221 : : {
24222 : 10 : int count = ix86_count_insn_bb (e->src);
24223 : 10 : if (count < min_prev_count)
24224 : 81 : min_prev_count = count;
24225 : : break;
24226 : : }
24227 : : }
24228 : : }
24229 : :
24230 : 62 : if (min_prev_count < 4)
24231 : 32 : min_prev_count += ix86_count_insn_bb (bb);
24232 : :
24233 : 62 : return min_prev_count;
24234 : : }
24235 : :
24236 : : /* Pad short function to 4 instructions. */
24237 : :
24238 : : static void
24239 : 63 : ix86_pad_short_function (void)
24240 : : {
24241 : 63 : edge e;
24242 : 63 : edge_iterator ei;
24243 : :
24244 : 128 : FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
24245 : : {
24246 : 65 : rtx_insn *ret = BB_END (e->src);
24247 : 65 : if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
24248 : : {
24249 : 62 : int insn_count = ix86_count_insn (e->src);
24250 : :
24251 : : /* Pad short function. */
24252 : 62 : if (insn_count < 4)
24253 : : {
24254 : : rtx_insn *insn = ret;
24255 : :
24256 : : /* Find epilogue. */
24257 : : while (insn
24258 : 54 : && (!NOTE_P (insn)
24259 : 25 : || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
24260 : 31 : insn = PREV_INSN (insn);
24261 : :
24262 : 23 : if (!insn)
24263 : 0 : insn = ret;
24264 : :
24265 : : /* Two NOPs count as one instruction. */
24266 : 23 : insn_count = 2 * (4 - insn_count);
24267 : 23 : emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
24268 : : }
24269 : : }
24270 : : }
24271 : 63 : }
24272 : :
24273 : : /* Fix up a Windows system unwinder issue. If an EH region falls through into
24274 : : the epilogue, the Windows system unwinder will apply epilogue logic and
24275 : : produce incorrect offsets. This can be avoided by adding a nop between
24276 : : the last insn that can throw and the first insn of the epilogue. */
24277 : :
24278 : : static void
24279 : 0 : ix86_seh_fixup_eh_fallthru (void)
24280 : : {
24281 : 0 : edge e;
24282 : 0 : edge_iterator ei;
24283 : :
24284 : 0 : FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
24285 : : {
24286 : 0 : rtx_insn *insn, *next;
24287 : :
24288 : : /* Find the beginning of the epilogue. */
24289 : 0 : for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
24290 : 0 : if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
24291 : : break;
24292 : 0 : if (insn == NULL)
24293 : 0 : continue;
24294 : :
24295 : : /* We only care about preceding insns that can throw. */
24296 : 0 : insn = prev_active_insn (insn);
24297 : 0 : if (insn == NULL || !can_throw_internal (insn))
24298 : 0 : continue;
24299 : :
24300 : : /* Do not separate calls from their debug information. */
24301 : 0 : for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next))
24302 : 0 : if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION)
24303 : 0 : insn = next;
24304 : : else
24305 : : break;
24306 : :
24307 : 0 : emit_insn_after (gen_nops (const1_rtx), insn);
24308 : : }
24309 : 0 : }
24310 : : /* Split vector load from parm_decl to elemental loads to avoid STLF
24311 : : stalls. */
24312 : : static void
24313 : 961505 : ix86_split_stlf_stall_load ()
24314 : : {
24315 : 961505 : rtx_insn* insn, *start = get_insns ();
24316 : 961505 : unsigned window = 0;
24317 : :
24318 : 26935879 : for (insn = start; insn; insn = NEXT_INSN (insn))
24319 : : {
24320 : 26935046 : if (!NONDEBUG_INSN_P (insn))
24321 : 15275575 : continue;
24322 : 11659471 : window++;
24323 : : /* Insert 64 vaddps %xmm18, %xmm19, %xmm20(no dependence between each
24324 : : other, just emulate for pipeline) before stalled load, stlf stall
24325 : : case is as fast as no stall cases on CLX.
24326 : : Since CFG is freed before machine_reorg, just do a rough
24327 : : calculation of the window according to the layout. */
24328 : 11659471 : if (window > (unsigned) x86_stlf_window_ninsns)
24329 : : return;
24330 : :
24331 : 11641620 : if (any_uncondjump_p (insn)
24332 : 11605913 : || ANY_RETURN_P (PATTERN (insn))
24333 : 22881938 : || CALL_P (insn))
24334 : : return;
24335 : :
24336 : 10698799 : rtx set = single_set (insn);
24337 : 10698799 : if (!set)
24338 : 388694 : continue;
24339 : 10310105 : rtx src = SET_SRC (set);
24340 : 20620048 : if (!MEM_P (src)
24341 : : /* Only handle V2DFmode load since it doesn't need any scratch
24342 : : register. */
24343 : 1493889 : || GET_MODE (src) != E_V2DFmode
24344 : 5384 : || !MEM_EXPR (src)
24345 : 10314026 : || TREE_CODE (get_base_address (MEM_EXPR (src))) != PARM_DECL)
24346 : 10309943 : continue;
24347 : :
24348 : 162 : rtx zero = CONST0_RTX (V2DFmode);
24349 : 162 : rtx dest = SET_DEST (set);
24350 : 162 : rtx m = adjust_address (src, DFmode, 0);
24351 : 162 : rtx loadlpd = gen_sse2_loadlpd (dest, zero, m);
24352 : 162 : emit_insn_before (loadlpd, insn);
24353 : 162 : m = adjust_address (src, DFmode, 8);
24354 : 162 : rtx loadhpd = gen_sse2_loadhpd (dest, dest, m);
24355 : 162 : if (dump_file && (dump_flags & TDF_DETAILS))
24356 : : {
24357 : 0 : fputs ("Due to potential STLF stall, split instruction:\n",
24358 : : dump_file);
24359 : 0 : print_rtl_single (dump_file, insn);
24360 : 0 : fputs ("To:\n", dump_file);
24361 : 0 : print_rtl_single (dump_file, loadlpd);
24362 : 0 : print_rtl_single (dump_file, loadhpd);
24363 : : }
24364 : 162 : PATTERN (insn) = loadhpd;
24365 : 162 : INSN_CODE (insn) = -1;
24366 : 162 : gcc_assert (recog_memoized (insn) != -1);
24367 : : }
24368 : : }
24369 : :
24370 : : /* Implement machine specific optimizations. We implement padding of returns
24371 : : for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window. */
24372 : : static void
24373 : 1449061 : ix86_reorg (void)
24374 : : {
24375 : : /* We are freeing block_for_insn in the toplev to keep compatibility
24376 : : with old MDEP_REORGS that are not CFG based. Recompute it now. */
24377 : 1449061 : compute_bb_for_insn ();
24378 : :
24379 : 1449061 : if (TARGET_SEH && current_function_has_exception_handlers ())
24380 : : ix86_seh_fixup_eh_fallthru ();
24381 : :
24382 : 1449061 : if (optimize && optimize_function_for_speed_p (cfun))
24383 : : {
24384 : 963792 : if (TARGET_SSE2)
24385 : 961505 : ix86_split_stlf_stall_load ();
24386 : 963792 : if (TARGET_PAD_SHORT_FUNCTION)
24387 : 63 : ix86_pad_short_function ();
24388 : 963729 : else if (TARGET_PAD_RETURNS)
24389 : 45066 : ix86_pad_returns ();
24390 : : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
24391 : 963792 : if (TARGET_FOUR_JUMP_LIMIT)
24392 : 45346 : ix86_avoid_jump_mispredicts ();
24393 : : #endif
24394 : : }
24395 : 1449061 : }
24396 : :
24397 : : /* Return nonzero when QImode register that must be represented via REX prefix
24398 : : is used. */
24399 : : bool
24400 : 9434089 : x86_extended_QIreg_mentioned_p (rtx_insn *insn)
24401 : : {
24402 : 9434089 : int i;
24403 : 9434089 : extract_insn_cached (insn);
24404 : 35687055 : for (i = 0; i < recog_data.n_operands; i++)
24405 : 5005155 : if (GENERAL_REG_P (recog_data.operand[i])
24406 : 23535109 : && !QI_REGNO_P (REGNO (recog_data.operand[i])))
24407 : : return true;
24408 : : return false;
24409 : : }
24410 : :
24411 : : /* Return true when INSN mentions register that must be encoded using REX
24412 : : prefix. */
24413 : : bool
24414 : 196079968 : x86_extended_reg_mentioned_p (rtx insn)
24415 : : {
24416 : 196079968 : subrtx_iterator::array_type array;
24417 : 1023978621 : FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
24418 : : {
24419 : 876245321 : const_rtx x = *iter;
24420 : 876245321 : if (REG_P (x)
24421 : 876245321 : && (REX_INT_REGNO_P (REGNO (x)) || REX_SSE_REGNO_P (REGNO (x))
24422 : 251667466 : || REX2_INT_REGNO_P (REGNO (x))))
24423 : 48346668 : return true;
24424 : : }
24425 : 147733300 : return false;
24426 : 196079968 : }
24427 : :
24428 : : /* Return true when INSN mentions register that must be encoded using REX2
24429 : : prefix. */
24430 : : bool
24431 : 2085583 : x86_extended_rex2reg_mentioned_p (rtx insn)
24432 : : {
24433 : 2085583 : subrtx_iterator::array_type array;
24434 : 9691108 : FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
24435 : : {
24436 : 7606192 : const_rtx x = *iter;
24437 : 7606192 : if (REG_P (x) && REX2_INT_REGNO_P (REGNO (x)))
24438 : 667 : return true;
24439 : : }
24440 : 2084916 : return false;
24441 : 2085583 : }
24442 : :
24443 : : /* Return true when rtx operands mentions register that must be encoded using
24444 : : evex prefix. */
24445 : : bool
24446 : 8 : x86_evex_reg_mentioned_p (rtx operands[], int nops)
24447 : : {
24448 : 8 : int i;
24449 : 20 : for (i = 0; i < nops; i++)
24450 : 16 : if (EXT_REX_SSE_REG_P (operands[i])
24451 : 28 : || x86_extended_rex2reg_mentioned_p (operands[i]))
24452 : 4 : return true;
24453 : : return false;
24454 : : }
24455 : :
24456 : : /* If profitable, negate (without causing overflow) integer constant
24457 : : of mode MODE at location LOC. Return true in this case. */
24458 : : bool
24459 : 5802020 : x86_maybe_negate_const_int (rtx *loc, machine_mode mode)
24460 : : {
24461 : 5802020 : HOST_WIDE_INT val;
24462 : :
24463 : 5802020 : if (!CONST_INT_P (*loc))
24464 : : return false;
24465 : :
24466 : 4920902 : switch (mode)
24467 : : {
24468 : 2778028 : case E_DImode:
24469 : : /* DImode x86_64 constants must fit in 32 bits. */
24470 : 2778028 : gcc_assert (x86_64_immediate_operand (*loc, mode));
24471 : :
24472 : : mode = SImode;
24473 : : break;
24474 : :
24475 : : case E_SImode:
24476 : : case E_HImode:
24477 : : case E_QImode:
24478 : : break;
24479 : :
24480 : 0 : default:
24481 : 0 : gcc_unreachable ();
24482 : : }
24483 : :
24484 : : /* Avoid overflows. */
24485 : 4920902 : if (mode_signbit_p (mode, *loc))
24486 : : return false;
24487 : :
24488 : 4920482 : val = INTVAL (*loc);
24489 : :
24490 : : /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
24491 : : Exceptions: -128 encodes smaller than 128, so swap sign and op. */
24492 : 4920482 : if ((val < 0 && val != -128)
24493 : 3234343 : || val == 128)
24494 : : {
24495 : 1697006 : *loc = GEN_INT (-val);
24496 : 1697006 : return true;
24497 : : }
24498 : :
24499 : : return false;
24500 : : }
24501 : :
24502 : : /* Generate an unsigned DImode/SImode to FP conversion. This is the same code
24503 : : optabs would emit if we didn't have TFmode patterns. */
24504 : :
24505 : : void
24506 : 4656 : x86_emit_floatuns (rtx operands[2])
24507 : : {
24508 : 4656 : rtx_code_label *neglab, *donelab;
24509 : 4656 : rtx i0, i1, f0, in, out;
24510 : 4656 : machine_mode mode, inmode;
24511 : :
24512 : 4656 : inmode = GET_MODE (operands[1]);
24513 : 4656 : gcc_assert (inmode == SImode || inmode == DImode);
24514 : :
24515 : 4656 : out = operands[0];
24516 : 4656 : in = force_reg (inmode, operands[1]);
24517 : 4656 : mode = GET_MODE (out);
24518 : 4656 : neglab = gen_label_rtx ();
24519 : 4656 : donelab = gen_label_rtx ();
24520 : 4656 : f0 = gen_reg_rtx (mode);
24521 : :
24522 : 4656 : emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
24523 : :
24524 : 4656 : expand_float (out, in, 0);
24525 : :
24526 : 4656 : emit_jump_insn (gen_jump (donelab));
24527 : 4656 : emit_barrier ();
24528 : :
24529 : 4656 : emit_label (neglab);
24530 : :
24531 : 4656 : i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
24532 : : 1, OPTAB_DIRECT);
24533 : 4656 : i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
24534 : : 1, OPTAB_DIRECT);
24535 : 4656 : i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
24536 : :
24537 : 4656 : expand_float (f0, i0, 0);
24538 : :
24539 : 4656 : emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
24540 : :
24541 : 4656 : emit_label (donelab);
24542 : 4656 : }
24543 : :
24544 : : /* Return the diagnostic message string if conversion from FROMTYPE to
24545 : : TOTYPE is not allowed, NULL otherwise. */
24546 : :
24547 : : static const char *
24548 : 945240378 : ix86_invalid_conversion (const_tree fromtype, const_tree totype)
24549 : : {
24550 : 945240378 : machine_mode from_mode = element_mode (fromtype);
24551 : 945240378 : machine_mode to_mode = element_mode (totype);
24552 : :
24553 : 945240378 : if (!TARGET_SSE2 && from_mode != to_mode)
24554 : : {
24555 : : /* Do no allow conversions to/from BFmode/HFmode scalar types
24556 : : when TARGET_SSE2 is not available. */
24557 : 453474 : if (from_mode == BFmode)
24558 : : return N_("invalid conversion from type %<__bf16%> "
24559 : : "without option %<-msse2%>");
24560 : 453473 : if (from_mode == HFmode)
24561 : : return N_("invalid conversion from type %<_Float16%> "
24562 : : "without option %<-msse2%>");
24563 : 453473 : if (to_mode == BFmode)
24564 : : return N_("invalid conversion to type %<__bf16%> "
24565 : : "without option %<-msse2%>");
24566 : 453473 : if (to_mode == HFmode)
24567 : : return N_("invalid conversion to type %<_Float16%> "
24568 : : "without option %<-msse2%>");
24569 : : }
24570 : :
24571 : : /* Warn for silent implicit conversion between __bf16 and short,
24572 : : since __bfloat16 is refined as real __bf16 instead of short
24573 : : since GCC13. */
24574 : 945240376 : if (element_mode (fromtype) != element_mode (totype)
24575 : 945240376 : && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
24576 : : {
24577 : : /* Warn for silent implicit conversion where user may expect
24578 : : a bitcast. */
24579 : 6733977 : if ((TYPE_MODE (fromtype) == BFmode
24580 : 13 : && TYPE_MODE (totype) == HImode)
24581 : 6733989 : || (TYPE_MODE (totype) == BFmode
24582 : 39 : && TYPE_MODE (fromtype) == HImode))
24583 : 1 : warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
24584 : : "to real %<__bf16%> since GCC 13.1, be careful of "
24585 : : "implicit conversion between %<__bf16%> and %<short%>; "
24586 : : "an explicit bitcast may be needed here");
24587 : : }
24588 : :
24589 : : /* Conversion allowed. */
24590 : : return NULL;
24591 : : }
24592 : :
24593 : : /* Return the diagnostic message string if the unary operation OP is
24594 : : not permitted on TYPE, NULL otherwise. */
24595 : :
24596 : : static const char *
24597 : 85244936 : ix86_invalid_unary_op (int op, const_tree type)
24598 : : {
24599 : 85244936 : machine_mode mmode = element_mode (type);
24600 : : /* Reject all single-operand operations on BFmode/HFmode except for &
24601 : : when TARGET_SSE2 is not available. */
24602 : 85244936 : if (!TARGET_SSE2 && op != ADDR_EXPR)
24603 : : {
24604 : 107752 : if (mmode == BFmode)
24605 : : return N_("operation not permitted on type %<__bf16%> "
24606 : : "without option %<-msse2%>");
24607 : 107752 : if (mmode == HFmode)
24608 : 0 : return N_("operation not permitted on type %<_Float16%> "
24609 : : "without option %<-msse2%>");
24610 : : }
24611 : :
24612 : : /* Operation allowed. */
24613 : : return NULL;
24614 : : }
24615 : :
24616 : : /* Return the diagnostic message string if the binary operation OP is
24617 : : not permitted on TYPE1 and TYPE2, NULL otherwise. */
24618 : :
24619 : : static const char *
24620 : 138616920 : ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
24621 : : const_tree type2)
24622 : : {
24623 : 138616920 : machine_mode type1_mode = element_mode (type1);
24624 : 138616920 : machine_mode type2_mode = element_mode (type2);
24625 : : /* Reject all 2-operand operations on BFmode or HFmode
24626 : : when TARGET_SSE2 is not available. */
24627 : 138616920 : if (!TARGET_SSE2)
24628 : : {
24629 : 979758 : if (type1_mode == BFmode || type2_mode == BFmode)
24630 : : return N_("operation not permitted on type %<__bf16%> "
24631 : : "without option %<-msse2%>");
24632 : :
24633 : 979758 : if (type1_mode == HFmode || type2_mode == HFmode)
24634 : 0 : return N_("operation not permitted on type %<_Float16%> "
24635 : : "without option %<-msse2%>");
24636 : : }
24637 : :
24638 : : /* Operation allowed. */
24639 : : return NULL;
24640 : : }
24641 : :
24642 : :
24643 : : /* Target hook for scalar_mode_supported_p. */
24644 : : static bool
24645 : 4293315 : ix86_scalar_mode_supported_p (scalar_mode mode)
24646 : : {
24647 : 4293315 : if (DECIMAL_FLOAT_MODE_P (mode))
24648 : 619962 : return default_decimal_float_supported_p ();
24649 : 3673353 : else if (mode == TFmode)
24650 : : return true;
24651 : 3355896 : else if (mode == HFmode || mode == BFmode)
24652 : : return true;
24653 : : else
24654 : 2722965 : return default_scalar_mode_supported_p (mode);
24655 : : }
24656 : :
24657 : : /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE
24658 : : if MODE is HFmode, and punt to the generic implementation otherwise. */
24659 : :
24660 : : static bool
24661 : 2180318 : ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode)
24662 : : {
24663 : : /* NB: Always return TRUE for HFmode so that the _Float16 type will
24664 : : be defined by the C front-end for AVX512FP16 intrinsics. We will
24665 : : issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't
24666 : : enabled. */
24667 : 1864328 : return ((mode == HFmode || mode == BFmode)
24668 : 3728656 : ? true
24669 : 1548338 : : default_libgcc_floating_mode_supported_p (mode));
24670 : : }
24671 : :
24672 : : /* Implements target hook vector_mode_supported_p. */
24673 : : static bool
24674 : 1291183867 : ix86_vector_mode_supported_p (machine_mode mode)
24675 : : {
24676 : : /* For ia32, scalar TImode isn't supported and so V1TImode shouldn't be
24677 : : either. */
24678 : 1426817651 : if (!TARGET_64BIT && GET_MODE_INNER (mode) == TImode)
24679 : : return false;
24680 : 1291183741 : if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
24681 : : return true;
24682 : 1087955308 : if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
24683 : : return true;
24684 : 469778701 : if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
24685 : : return true;
24686 : 335888508 : if (TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
24687 : : return true;
24688 : 209811356 : if ((TARGET_MMX || TARGET_MMX_WITH_SSE)
24689 : 209755182 : && VALID_MMX_REG_MODE (mode))
24690 : : return true;
24691 : 27141411 : if ((TARGET_3DNOW || TARGET_MMX_WITH_SSE)
24692 : 26532057 : && VALID_MMX_REG_MODE_3DNOW (mode))
24693 : : return true;
24694 : 18352520 : if (mode == V2QImode)
24695 : 22878 : return true;
24696 : : return false;
24697 : : }
24698 : :
24699 : : /* Target hook for c_mode_for_suffix. */
24700 : : static machine_mode
24701 : 82762 : ix86_c_mode_for_suffix (char suffix)
24702 : : {
24703 : 82762 : if (suffix == 'q')
24704 : : return TFmode;
24705 : 37 : if (suffix == 'w')
24706 : : return XFmode;
24707 : :
24708 : 0 : return VOIDmode;
24709 : : }
24710 : :
24711 : : /* Helper function to map common constraints to non-EGPR ones.
24712 : : All related constraints have h prefix, and h plus Upper letter
24713 : : means the constraint is strictly EGPR enabled, while h plus
24714 : : lower letter indicates the constraint is strictly gpr16 only.
24715 : :
24716 : : Specially for "g" constraint, split it to rmi as there is
24717 : : no corresponding general constraint define for backend.
24718 : :
24719 : : Here is the full list to map constraints that may involve
24720 : : gpr to h prefixed.
24721 : :
24722 : : "g" -> "jrjmi"
24723 : : "r" -> "jr"
24724 : : "m" -> "jm"
24725 : : "<" -> "j<"
24726 : : ">" -> "j>"
24727 : : "o" -> "jo"
24728 : : "V" -> "jV"
24729 : : "p" -> "jp"
24730 : : "Bm" -> "ja"
24731 : : */
24732 : :
24733 : 49 : static void map_egpr_constraints (vec<const char *> &constraints)
24734 : : {
24735 : 59 : for (size_t i = 0; i < constraints.length(); i++)
24736 : : {
24737 : 10 : const char *cur = constraints[i];
24738 : :
24739 : 10 : if (startswith (cur, "=@cc"))
24740 : 0 : continue;
24741 : :
24742 : 10 : int len = strlen (cur);
24743 : 10 : auto_vec<char> buf;
24744 : :
24745 : 24 : for (int j = 0; j < len; j++)
24746 : : {
24747 : 14 : switch (cur[j])
24748 : : {
24749 : 2 : case 'g':
24750 : 2 : buf.safe_push ('j');
24751 : 2 : buf.safe_push ('r');
24752 : 2 : buf.safe_push ('j');
24753 : 2 : buf.safe_push ('m');
24754 : 2 : buf.safe_push ('i');
24755 : 2 : break;
24756 : 8 : case 'r':
24757 : 8 : case 'm':
24758 : 8 : case '<':
24759 : 8 : case '>':
24760 : 8 : case 'o':
24761 : 8 : case 'V':
24762 : 8 : case 'p':
24763 : 8 : buf.safe_push ('j');
24764 : 8 : buf.safe_push (cur[j]);
24765 : 8 : break;
24766 : 0 : case 'B':
24767 : 0 : if (cur[j + 1] == 'm')
24768 : : {
24769 : 0 : buf.safe_push ('j');
24770 : 0 : buf.safe_push ('a');
24771 : 0 : j++;
24772 : : }
24773 : : else
24774 : : {
24775 : 0 : buf.safe_push (cur[j]);
24776 : 0 : buf.safe_push (cur[j + 1]);
24777 : 0 : j++;
24778 : : }
24779 : : break;
24780 : 0 : case 'T':
24781 : 0 : case 'Y':
24782 : 0 : case 'W':
24783 : 0 : case 'j':
24784 : 0 : buf.safe_push (cur[j]);
24785 : 0 : buf.safe_push (cur[j + 1]);
24786 : 0 : j++;
24787 : 0 : break;
24788 : 4 : default:
24789 : 4 : buf.safe_push (cur[j]);
24790 : 4 : break;
24791 : : }
24792 : : }
24793 : 10 : buf.safe_push ('\0');
24794 : 20 : constraints[i] = xstrdup (buf.address ());
24795 : 10 : }
24796 : 49 : }
24797 : :
24798 : : /* Worker function for TARGET_MD_ASM_ADJUST.
24799 : :
24800 : : We implement asm flag outputs, and maintain source compatibility
24801 : : with the old cc0-based compiler. */
24802 : :
24803 : : static rtx_insn *
24804 : 104710 : ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
24805 : : vec<machine_mode> & /*input_modes*/,
24806 : : vec<const char *> &constraints, vec<rtx> &/*uses*/,
24807 : : vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
24808 : : location_t loc)
24809 : : {
24810 : 104710 : bool saw_asm_flag = false;
24811 : :
24812 : 104710 : start_sequence ();
24813 : :
24814 : 104710 : if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
24815 : 49 : map_egpr_constraints (constraints);
24816 : :
24817 : 280140 : for (unsigned i = 0, n = outputs.length (); i < n; ++i)
24818 : : {
24819 : 71627 : const char *con = constraints[i];
24820 : 71627 : if (!startswith (con, "=@cc"))
24821 : 71540 : continue;
24822 : 87 : con += 4;
24823 : 87 : if (strchr (con, ',') != NULL)
24824 : : {
24825 : 1 : error_at (loc, "alternatives not allowed in %<asm%> flag output");
24826 : 1 : continue;
24827 : : }
24828 : :
24829 : 86 : bool invert = false;
24830 : 86 : if (con[0] == 'n')
24831 : 19 : invert = true, con++;
24832 : :
24833 : 86 : machine_mode mode = CCmode;
24834 : 86 : rtx_code code = UNKNOWN;
24835 : :
24836 : 86 : switch (con[0])
24837 : : {
24838 : 15 : case 'a':
24839 : 15 : if (con[1] == 0)
24840 : : mode = CCAmode, code = EQ;
24841 : 4 : else if (con[1] == 'e' && con[2] == 0)
24842 : : mode = CCCmode, code = NE;
24843 : : break;
24844 : 11 : case 'b':
24845 : 11 : if (con[1] == 0)
24846 : : mode = CCCmode, code = EQ;
24847 : 6 : else if (con[1] == 'e' && con[2] == 0)
24848 : : mode = CCAmode, code = NE;
24849 : : break;
24850 : 14 : case 'c':
24851 : 14 : if (con[1] == 0)
24852 : : mode = CCCmode, code = EQ;
24853 : : break;
24854 : 8 : case 'e':
24855 : 8 : if (con[1] == 0)
24856 : : mode = CCZmode, code = EQ;
24857 : : break;
24858 : 11 : case 'g':
24859 : 11 : if (con[1] == 0)
24860 : : mode = CCGCmode, code = GT;
24861 : 5 : else if (con[1] == 'e' && con[2] == 0)
24862 : : mode = CCGCmode, code = GE;
24863 : : break;
24864 : 10 : case 'l':
24865 : 10 : if (con[1] == 0)
24866 : : mode = CCGCmode, code = LT;
24867 : 5 : else if (con[1] == 'e' && con[2] == 0)
24868 : : mode = CCGCmode, code = LE;
24869 : : break;
24870 : 4 : case 'o':
24871 : 4 : if (con[1] == 0)
24872 : : mode = CCOmode, code = EQ;
24873 : : break;
24874 : 4 : case 'p':
24875 : 4 : if (con[1] == 0)
24876 : : mode = CCPmode, code = EQ;
24877 : : break;
24878 : 4 : case 's':
24879 : 4 : if (con[1] == 0)
24880 : : mode = CCSmode, code = EQ;
24881 : : break;
24882 : 5 : case 'z':
24883 : 5 : if (con[1] == 0)
24884 : : mode = CCZmode, code = EQ;
24885 : : break;
24886 : : }
24887 : 1 : if (code == UNKNOWN)
24888 : : {
24889 : 1 : error_at (loc, "unknown %<asm%> flag output %qs", constraints[i]);
24890 : 1 : continue;
24891 : : }
24892 : 85 : if (invert)
24893 : 19 : code = reverse_condition (code);
24894 : :
24895 : 85 : rtx dest = outputs[i];
24896 : 85 : if (!saw_asm_flag)
24897 : : {
24898 : : /* This is the first asm flag output. Here we put the flags
24899 : : register in as the real output and adjust the condition to
24900 : : allow it. */
24901 : 74 : constraints[i] = "=Bf";
24902 : 74 : outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG);
24903 : 74 : saw_asm_flag = true;
24904 : : }
24905 : : else
24906 : : {
24907 : : /* We don't need the flags register as output twice. */
24908 : 11 : constraints[i] = "=X";
24909 : 11 : outputs[i] = gen_rtx_SCRATCH (SImode);
24910 : : }
24911 : :
24912 : 85 : rtx x = gen_rtx_REG (mode, FLAGS_REG);
24913 : 85 : x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx);
24914 : :
24915 : 85 : machine_mode dest_mode = GET_MODE (dest);
24916 : 85 : if (!SCALAR_INT_MODE_P (dest_mode))
24917 : : {
24918 : 3 : error_at (loc, "invalid type for %<asm%> flag output");
24919 : 3 : continue;
24920 : : }
24921 : :
24922 : 82 : if (dest_mode == QImode)
24923 : 72 : emit_insn (gen_rtx_SET (dest, x));
24924 : : else
24925 : : {
24926 : 10 : rtx reg = gen_reg_rtx (QImode);
24927 : 10 : emit_insn (gen_rtx_SET (reg, x));
24928 : :
24929 : 10 : reg = convert_to_mode (dest_mode, reg, 1);
24930 : 10 : emit_move_insn (dest, reg);
24931 : : }
24932 : : }
24933 : :
24934 : 104710 : rtx_insn *seq = end_sequence ();
24935 : :
24936 : 104710 : if (saw_asm_flag)
24937 : : return seq;
24938 : : else
24939 : : {
24940 : : /* If we had no asm flag outputs, clobber the flags. */
24941 : 104636 : clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG));
24942 : 104636 : SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG);
24943 : 104636 : return NULL;
24944 : : }
24945 : : }
24946 : :
24947 : : /* Implements target vector targetm.asm.encode_section_info. */
24948 : :
24949 : : static void ATTRIBUTE_UNUSED
24950 : 9792346 : ix86_encode_section_info (tree decl, rtx rtl, int first)
24951 : : {
24952 : 9792346 : default_encode_section_info (decl, rtl, first);
24953 : :
24954 : 9792346 : if (ix86_in_large_data_p (decl))
24955 : 32 : SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
24956 : 9792346 : }
24957 : :
24958 : : /* Worker function for REVERSE_CONDITION. */
24959 : :
24960 : : enum rtx_code
24961 : 31032826 : ix86_reverse_condition (enum rtx_code code, machine_mode mode)
24962 : : {
24963 : 31032826 : return (mode == CCFPmode
24964 : 31032826 : ? reverse_condition_maybe_unordered (code)
24965 : 26775531 : : reverse_condition (code));
24966 : : }
24967 : :
24968 : : /* Output code to perform an x87 FP register move, from OPERANDS[1]
24969 : : to OPERANDS[0]. */
24970 : :
24971 : : const char *
24972 : 662777 : output_387_reg_move (rtx_insn *insn, rtx *operands)
24973 : : {
24974 : 662777 : if (REG_P (operands[0]))
24975 : : {
24976 : 553573 : if (REG_P (operands[1])
24977 : 553573 : && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
24978 : : {
24979 : 303306 : if (REGNO (operands[0]) == FIRST_STACK_REG)
24980 : 282656 : return output_387_ffreep (operands, 0);
24981 : : return "fstp\t%y0";
24982 : : }
24983 : 250267 : if (STACK_TOP_P (operands[0]))
24984 : 250267 : return "fld%Z1\t%y1";
24985 : : return "fst\t%y0";
24986 : : }
24987 : 109204 : else if (MEM_P (operands[0]))
24988 : : {
24989 : 109204 : gcc_assert (REG_P (operands[1]));
24990 : 109204 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
24991 : : return "fstp%Z0\t%y0";
24992 : : else
24993 : : {
24994 : : /* There is no non-popping store to memory for XFmode.
24995 : : So if we need one, follow the store with a load. */
24996 : 8006 : if (GET_MODE (operands[0]) == XFmode)
24997 : : return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
24998 : : else
24999 : 1845 : return "fst%Z0\t%y0";
25000 : : }
25001 : : }
25002 : : else
25003 : 0 : gcc_unreachable();
25004 : : }
25005 : : #ifdef TARGET_SOLARIS
25006 : : /* Solaris implementation of TARGET_ASM_NAMED_SECTION. */
25007 : :
25008 : : static void
25009 : : i386_solaris_elf_named_section (const char *name, unsigned int flags,
25010 : : tree decl)
25011 : : {
25012 : : /* With Binutils 2.15, the "@unwind" marker must be specified on
25013 : : every occurrence of the ".eh_frame" section, not just the first
25014 : : one. */
25015 : : if (TARGET_64BIT
25016 : : && strcmp (name, ".eh_frame") == 0)
25017 : : {
25018 : : fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
25019 : : flags & SECTION_WRITE ? "aw" : "a");
25020 : : return;
25021 : : }
25022 : :
25023 : : #ifndef USE_GAS
25024 : : if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
25025 : : {
25026 : : solaris_elf_asm_comdat_section (name, flags, decl);
25027 : : return;
25028 : : }
25029 : :
25030 : : /* Solaris/x86 as uses the same syntax for the SHF_EXCLUDE flags as the
25031 : : SPARC assembler. One cannot mix single-letter flags and #exclude, so
25032 : : only emit the latter here. */
25033 : : if (flags & SECTION_EXCLUDE)
25034 : : {
25035 : : fprintf (asm_out_file, "\t.section\t%s,#exclude\n", name);
25036 : : return;
25037 : : }
25038 : : #endif
25039 : :
25040 : : default_elf_asm_named_section (name, flags, decl);
25041 : : }
25042 : : #endif /* TARGET_SOLARIS */
25043 : :
25044 : : /* Return the mangling of TYPE if it is an extended fundamental type. */
25045 : :
25046 : : static const char *
25047 : 901341079 : ix86_mangle_type (const_tree type)
25048 : : {
25049 : 901341079 : type = TYPE_MAIN_VARIANT (type);
25050 : :
25051 : 901341079 : if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
25052 : : && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
25053 : : return NULL;
25054 : :
25055 : 492367760 : if (type == float128_type_node || type == float64x_type_node)
25056 : : return NULL;
25057 : :
25058 : 491532343 : switch (TYPE_MODE (type))
25059 : : {
25060 : : case E_BFmode:
25061 : : return "DF16b";
25062 : 518088 : case E_HFmode:
25063 : : /* _Float16 is "DF16_".
25064 : : Align with clang's decision in https://reviews.llvm.org/D33719. */
25065 : 518088 : return "DF16_";
25066 : 580750 : case E_TFmode:
25067 : : /* __float128 is "g". */
25068 : 580750 : return "g";
25069 : 7084095 : case E_XFmode:
25070 : : /* "long double" or __float80 is "e". */
25071 : 7084095 : return "e";
25072 : : default:
25073 : : return NULL;
25074 : : }
25075 : : }
25076 : :
25077 : : /* Create C++ tinfo symbols for only conditionally available fundamental
25078 : : types. */
25079 : :
25080 : : static void
25081 : 5 : ix86_emit_support_tinfos (emit_support_tinfos_callback callback)
25082 : : {
25083 : 5 : extern tree ix86_float16_type_node;
25084 : 5 : extern tree ix86_bf16_type_node;
25085 : :
25086 : 5 : if (!TARGET_SSE2)
25087 : : {
25088 : 0 : if (!float16_type_node)
25089 : 0 : float16_type_node = ix86_float16_type_node;
25090 : 0 : if (!bfloat16_type_node)
25091 : 0 : bfloat16_type_node = ix86_bf16_type_node;
25092 : 0 : callback (float16_type_node);
25093 : 0 : callback (bfloat16_type_node);
25094 : 0 : float16_type_node = NULL_TREE;
25095 : 0 : bfloat16_type_node = NULL_TREE;
25096 : : }
25097 : 5 : }
25098 : :
25099 : : static GTY(()) tree ix86_tls_stack_chk_guard_decl;
25100 : :
25101 : : static tree
25102 : 235 : ix86_stack_protect_guard (void)
25103 : : {
25104 : 235 : if (TARGET_SSP_TLS_GUARD)
25105 : : {
25106 : 232 : tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
25107 : 232 : int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg);
25108 : 232 : tree type = build_qualified_type (type_node, qual);
25109 : 232 : tree t;
25110 : :
25111 : 232 : if (OPTION_SET_P (ix86_stack_protector_guard_symbol_str))
25112 : : {
25113 : 1 : t = ix86_tls_stack_chk_guard_decl;
25114 : :
25115 : 1 : if (t == NULL)
25116 : : {
25117 : 1 : rtx x;
25118 : :
25119 : 1 : t = build_decl
25120 : 1 : (UNKNOWN_LOCATION, VAR_DECL,
25121 : : get_identifier (ix86_stack_protector_guard_symbol_str),
25122 : : type);
25123 : 1 : TREE_STATIC (t) = 1;
25124 : 1 : TREE_PUBLIC (t) = 1;
25125 : 1 : DECL_EXTERNAL (t) = 1;
25126 : 1 : TREE_USED (t) = 1;
25127 : 1 : TREE_THIS_VOLATILE (t) = 1;
25128 : 1 : DECL_ARTIFICIAL (t) = 1;
25129 : 1 : DECL_IGNORED_P (t) = 1;
25130 : :
25131 : : /* Do not share RTL as the declaration is visible outside of
25132 : : current function. */
25133 : 1 : x = DECL_RTL (t);
25134 : 1 : RTX_FLAG (x, used) = 1;
25135 : :
25136 : 1 : ix86_tls_stack_chk_guard_decl = t;
25137 : : }
25138 : : }
25139 : : else
25140 : : {
25141 : 231 : tree asptrtype = build_pointer_type (type);
25142 : :
25143 : 231 : t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset);
25144 : 231 : t = build2 (MEM_REF, asptrtype, t,
25145 : : build_int_cst (asptrtype, 0));
25146 : 231 : TREE_THIS_VOLATILE (t) = 1;
25147 : : }
25148 : :
25149 : 232 : return t;
25150 : : }
25151 : :
25152 : 3 : return default_stack_protect_guard ();
25153 : : }
25154 : :
25155 : : static bool
25156 : 734 : ix86_stack_protect_runtime_enabled_p (void)
25157 : : {
25158 : : /* Naked functions should not enable stack protector. */
25159 : 734 : return !ix86_function_naked (current_function_decl);
25160 : : }
25161 : :
25162 : : /* For 32-bit code we can save PIC register setup by using
25163 : : __stack_chk_fail_local hidden function instead of calling
25164 : : __stack_chk_fail directly. 64-bit code doesn't need to setup any PIC
25165 : : register, so it is better to call __stack_chk_fail directly. */
25166 : :
25167 : : static tree ATTRIBUTE_UNUSED
25168 : 261 : ix86_stack_protect_fail (void)
25169 : : {
25170 : 261 : return TARGET_64BIT
25171 : 261 : ? default_external_stack_protect_fail ()
25172 : 1 : : default_hidden_stack_protect_fail ();
25173 : : }
25174 : :
25175 : : /* Select a format to encode pointers in exception handling data. CODE
25176 : : is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
25177 : : true if the symbol may be affected by dynamic relocations.
25178 : :
25179 : : ??? All x86 object file formats are capable of representing this.
25180 : : After all, the relocation needed is the same as for the call insn.
25181 : : Whether or not a particular assembler allows us to enter such, I
25182 : : guess we'll have to see. */
25183 : :
25184 : : int
25185 : 783188 : asm_preferred_eh_data_format (int code, int global)
25186 : : {
25187 : : /* PE-COFF is effectively always -fPIC because of the .reloc section. */
25188 : 783188 : if (flag_pic || TARGET_PECOFF || !ix86_direct_extern_access)
25189 : : {
25190 : 37388 : int type = DW_EH_PE_sdata8;
25191 : 37388 : if (ptr_mode == SImode
25192 : 23634 : || ix86_cmodel == CM_SMALL_PIC
25193 : 37460 : || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
25194 : : type = DW_EH_PE_sdata4;
25195 : 52419 : return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
25196 : : }
25197 : :
25198 : 745800 : if (ix86_cmodel == CM_SMALL
25199 : 18733 : || (ix86_cmodel == CM_MEDIUM && code))
25200 : 727078 : return DW_EH_PE_udata4;
25201 : :
25202 : : return DW_EH_PE_absptr;
25203 : : }
25204 : :
25205 : : /* Implement targetm.vectorize.builtin_vectorization_cost. */
25206 : : static int
25207 : 14573496 : ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
25208 : : tree vectype, int)
25209 : : {
25210 : 14573496 : bool fp = false;
25211 : 14573496 : machine_mode mode = TImode;
25212 : 14573496 : int index;
25213 : 14573496 : if (vectype != NULL)
25214 : : {
25215 : 13774337 : fp = FLOAT_TYPE_P (vectype);
25216 : 13774337 : mode = TYPE_MODE (vectype);
25217 : : }
25218 : :
25219 : 14573496 : switch (type_of_cost)
25220 : : {
25221 : 2091780 : case scalar_stmt:
25222 : 2091780 : return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
25223 : :
25224 : 1601807 : case scalar_load:
25225 : : /* load/store costs are relative to register move which is 2. Recompute
25226 : : it to COSTS_N_INSNS so everything have same base. */
25227 : 3203614 : return COSTS_N_INSNS (fp ? ix86_cost->sse_load[0]
25228 : 1601807 : : ix86_cost->int_load [2]) / 2;
25229 : :
25230 : 3937962 : case scalar_store:
25231 : 7875924 : return COSTS_N_INSNS (fp ? ix86_cost->sse_store[0]
25232 : 3937962 : : ix86_cost->int_store [2]) / 2;
25233 : :
25234 : 913110 : case vector_stmt:
25235 : 1826220 : return ix86_vec_cost (mode,
25236 : 1826220 : fp ? ix86_cost->addss : ix86_cost->sse_op);
25237 : :
25238 : 1630987 : case vector_load:
25239 : 1630987 : index = sse_store_index (mode);
25240 : : /* See PR82713 - we may end up being called on non-vector type. */
25241 : 1630987 : if (index < 0)
25242 : 95004 : index = 2;
25243 : 1630987 : return COSTS_N_INSNS (ix86_cost->sse_load[index]) / 2;
25244 : :
25245 : 1025443 : case vector_store:
25246 : 1025443 : index = sse_store_index (mode);
25247 : : /* See PR82713 - we may end up being called on non-vector type. */
25248 : 1025443 : if (index < 0)
25249 : 90493 : index = 2;
25250 : 1025443 : return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
25251 : :
25252 : 994221 : case vec_to_scalar:
25253 : 994221 : case scalar_to_vec:
25254 : 994221 : return ix86_vec_cost (mode, ix86_cost->sse_op);
25255 : :
25256 : : /* We should have separate costs for unaligned loads and gather/scatter.
25257 : : Do that incrementally. */
25258 : 363137 : case unaligned_load:
25259 : 363137 : index = sse_store_index (mode);
25260 : : /* See PR82713 - we may end up being called on non-vector type. */
25261 : 363137 : if (index < 0)
25262 : 2627 : index = 2;
25263 : 363137 : return COSTS_N_INSNS (ix86_cost->sse_unaligned_load[index]) / 2;
25264 : :
25265 : 777377 : case unaligned_store:
25266 : 777377 : index = sse_store_index (mode);
25267 : : /* See PR82713 - we may end up being called on non-vector type. */
25268 : 777377 : if (index < 0)
25269 : 15296 : index = 2;
25270 : 777377 : return COSTS_N_INSNS (ix86_cost->sse_unaligned_store[index]) / 2;
25271 : :
25272 : 0 : case vector_gather_load:
25273 : 0 : return ix86_vec_cost (mode,
25274 : 0 : COSTS_N_INSNS
25275 : : (ix86_cost->gather_static
25276 : : + ix86_cost->gather_per_elt
25277 : 0 : * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
25278 : :
25279 : 0 : case vector_scatter_store:
25280 : 0 : return ix86_vec_cost (mode,
25281 : 0 : COSTS_N_INSNS
25282 : : (ix86_cost->scatter_static
25283 : : + ix86_cost->scatter_per_elt
25284 : 0 : * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
25285 : :
25286 : 210168 : case cond_branch_taken:
25287 : 210168 : return ix86_cost->cond_taken_branch_cost;
25288 : :
25289 : 5034 : case cond_branch_not_taken:
25290 : 5034 : return ix86_cost->cond_not_taken_branch_cost;
25291 : :
25292 : 240166 : case vec_perm:
25293 : 240166 : return ix86_vec_cost (mode, ix86_cost->sse_op);
25294 : :
25295 : 63219 : case vec_promote_demote:
25296 : 63219 : if (fp)
25297 : 7679 : return vec_fp_conversion_cost (ix86_tune_cost, mode);
25298 : 55540 : return ix86_vec_cost (mode, ix86_cost->sse_op);
25299 : :
25300 : 719085 : case vec_construct:
25301 : 719085 : {
25302 : 719085 : int n = TYPE_VECTOR_SUBPARTS (vectype);
25303 : : /* N - 1 element inserts into an SSE vector, the possible
25304 : : GPR -> XMM move is accounted for in add_stmt_cost. */
25305 : 1438170 : if (GET_MODE_BITSIZE (mode) <= 128)
25306 : 711923 : return (n - 1) * ix86_cost->sse_op;
25307 : : /* One vinserti128 for combining two SSE vectors for AVX256. */
25308 : 14324 : else if (GET_MODE_BITSIZE (mode) == 256)
25309 : 5586 : return ((n - 2) * ix86_cost->sse_op
25310 : 5586 : + ix86_vec_cost (mode, ix86_cost->sse_op));
25311 : : /* One vinserti64x4 and two vinserti128 for combining SSE
25312 : : and AVX256 vectors to AVX512. */
25313 : 3152 : else if (GET_MODE_BITSIZE (mode) == 512)
25314 : : {
25315 : 1576 : machine_mode half_mode
25316 : 1576 : = mode_for_vector (GET_MODE_INNER (mode),
25317 : 3152 : GET_MODE_NUNITS (mode) / 2).require ();
25318 : 1576 : return ((n - 4) * ix86_cost->sse_op
25319 : 1576 : + 2 * ix86_vec_cost (half_mode, ix86_cost->sse_op)
25320 : 1576 : + ix86_vec_cost (mode, ix86_cost->sse_op));
25321 : : }
25322 : 0 : gcc_unreachable ();
25323 : : }
25324 : :
25325 : 0 : default:
25326 : 0 : gcc_unreachable ();
25327 : : }
25328 : : }
25329 : :
25330 : :
25331 : : /* This function returns the calling abi specific va_list type node.
25332 : : It returns the FNDECL specific va_list type. */
25333 : :
25334 : : static tree
25335 : 47072 : ix86_fn_abi_va_list (tree fndecl)
25336 : : {
25337 : 47072 : if (!TARGET_64BIT)
25338 : 698 : return va_list_type_node;
25339 : 46374 : gcc_assert (fndecl != NULL_TREE);
25340 : :
25341 : 46374 : if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
25342 : 12868 : return ms_va_list_type_node;
25343 : : else
25344 : 33506 : return sysv_va_list_type_node;
25345 : : }
25346 : :
25347 : : /* Returns the canonical va_list type specified by TYPE. If there
25348 : : is no valid TYPE provided, it return NULL_TREE. */
25349 : :
25350 : : static tree
25351 : 245471 : ix86_canonical_va_list_type (tree type)
25352 : : {
25353 : 245471 : if (TARGET_64BIT)
25354 : : {
25355 : 244969 : if (lookup_attribute ("ms_abi va_list", TYPE_ATTRIBUTES (type)))
25356 : 5944 : return ms_va_list_type_node;
25357 : :
25358 : 239025 : if ((TREE_CODE (type) == ARRAY_TYPE
25359 : 49747 : && integer_zerop (array_type_nelts_minus_one (type)))
25360 : 239025 : || POINTER_TYPE_P (type))
25361 : : {
25362 : 187373 : tree elem_type = TREE_TYPE (type);
25363 : 187373 : if (TREE_CODE (elem_type) == RECORD_TYPE
25364 : 338234 : && lookup_attribute ("sysv_abi va_list",
25365 : 150861 : TYPE_ATTRIBUTES (elem_type)))
25366 : 150861 : return sysv_va_list_type_node;
25367 : : }
25368 : :
25369 : 88164 : return NULL_TREE;
25370 : : }
25371 : :
25372 : 502 : return std_canonical_va_list_type (type);
25373 : : }
25374 : :
25375 : : /* Iterate through the target-specific builtin types for va_list.
25376 : : IDX denotes the iterator, *PTREE is set to the result type of
25377 : : the va_list builtin, and *PNAME to its internal type.
25378 : : Returns zero if there is no element for this index, otherwise
25379 : : IDX should be increased upon the next call.
25380 : : Note, do not iterate a base builtin's name like __builtin_va_list.
25381 : : Used from c_common_nodes_and_builtins. */
25382 : :
25383 : : static int
25384 : 608157 : ix86_enum_va_list (int idx, const char **pname, tree *ptree)
25385 : : {
25386 : 608157 : if (TARGET_64BIT)
25387 : : {
25388 : 602850 : switch (idx)
25389 : : {
25390 : : default:
25391 : : break;
25392 : :
25393 : 200950 : case 0:
25394 : 200950 : *ptree = ms_va_list_type_node;
25395 : 200950 : *pname = "__builtin_ms_va_list";
25396 : 200950 : return 1;
25397 : :
25398 : 200950 : case 1:
25399 : 200950 : *ptree = sysv_va_list_type_node;
25400 : 200950 : *pname = "__builtin_sysv_va_list";
25401 : 200950 : return 1;
25402 : : }
25403 : : }
25404 : :
25405 : : return 0;
25406 : : }
25407 : :
25408 : : #undef TARGET_SCHED_DISPATCH
25409 : : #define TARGET_SCHED_DISPATCH ix86_bd_has_dispatch
25410 : : #undef TARGET_SCHED_DISPATCH_DO
25411 : : #define TARGET_SCHED_DISPATCH_DO ix86_bd_do_dispatch
25412 : : #undef TARGET_SCHED_REASSOCIATION_WIDTH
25413 : : #define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
25414 : : #undef TARGET_SCHED_REORDER
25415 : : #define TARGET_SCHED_REORDER ix86_atom_sched_reorder
25416 : : #undef TARGET_SCHED_ADJUST_PRIORITY
25417 : : #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
25418 : : #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
25419 : : #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
25420 : : ix86_dependencies_evaluation_hook
25421 : :
25422 : :
25423 : : /* Implementation of reassociation_width target hook used by
25424 : : reassoc phase to identify parallelism level in reassociated
25425 : : tree. Statements tree_code is passed in OPC. Arguments type
25426 : : is passed in MODE. */
25427 : :
25428 : : static int
25429 : 31994 : ix86_reassociation_width (unsigned int op, machine_mode mode)
25430 : : {
25431 : 31994 : int width = 1;
25432 : : /* Vector part. */
25433 : 31994 : if (VECTOR_MODE_P (mode))
25434 : : {
25435 : 7517 : int div = 1;
25436 : 7517 : if (INTEGRAL_MODE_P (mode))
25437 : 2320 : width = ix86_cost->reassoc_vec_int;
25438 : 5197 : else if (FLOAT_MODE_P (mode))
25439 : 5197 : width = ix86_cost->reassoc_vec_fp;
25440 : :
25441 : 7517 : if (width == 1)
25442 : : return 1;
25443 : :
25444 : : /* Znver1-4 Integer vector instructions execute in FP unit
25445 : : and can execute 3 additions and one multiplication per cycle. */
25446 : 7512 : if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2
25447 : 7512 : || ix86_tune == PROCESSOR_ZNVER3 || ix86_tune == PROCESSOR_ZNVER4)
25448 : 0 : && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS)
25449 : : return 1;
25450 : : /* Znver5 can do 2 integer multiplications per cycle with latency
25451 : : of 3. */
25452 : 7512 : if (ix86_tune == PROCESSOR_ZNVER5
25453 : 0 : && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS)
25454 : 7512 : width = 6;
25455 : :
25456 : : /* Account for targets that splits wide vectors into multiple parts. */
25457 : 7512 : if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 256)
25458 : 0 : div = GET_MODE_BITSIZE (mode) / 256;
25459 : 7512 : else if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 128)
25460 : 0 : div = GET_MODE_BITSIZE (mode) / 128;
25461 : 7512 : else if (TARGET_SSE_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 64)
25462 : 0 : div = GET_MODE_BITSIZE (mode) / 64;
25463 : 7512 : width = (width + div - 1) / div;
25464 : 7512 : }
25465 : : /* Scalar part. */
25466 : : else if (INTEGRAL_MODE_P (mode))
25467 : 14832 : width = ix86_cost->reassoc_int;
25468 : : else if (FLOAT_MODE_P (mode))
25469 : 9645 : width = ix86_cost->reassoc_fp;
25470 : :
25471 : : /* Avoid using too many registers in 32bit mode. */
25472 : 31989 : if (!TARGET_64BIT && width > 2)
25473 : 31994 : width = 2;
25474 : : return width;
25475 : : }
25476 : :
25477 : : /* ??? No autovectorization into MMX or 3DNOW until we can reliably
25478 : : place emms and femms instructions. */
25479 : :
25480 : : static machine_mode
25481 : 4965211 : ix86_preferred_simd_mode (scalar_mode mode)
25482 : : {
25483 : 4965211 : if (!TARGET_SSE)
25484 : 852 : return word_mode;
25485 : :
25486 : 4964359 : switch (mode)
25487 : : {
25488 : 389082 : case E_QImode:
25489 : 389082 : if (TARGET_AVX512BW && !TARGET_PREFER_AVX256)
25490 : : return V64QImode;
25491 : 381888 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25492 : : return V32QImode;
25493 : : else
25494 : 362318 : return V16QImode;
25495 : :
25496 : 180604 : case E_HImode:
25497 : 180604 : if (TARGET_AVX512BW && !TARGET_PREFER_AVX256)
25498 : : return V32HImode;
25499 : 171495 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25500 : : return V16HImode;
25501 : : else
25502 : 155282 : return V8HImode;
25503 : :
25504 : 1471086 : case E_SImode:
25505 : 1471086 : if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
25506 : : return V16SImode;
25507 : 1405672 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25508 : : return V8SImode;
25509 : : else
25510 : 1250142 : return V4SImode;
25511 : :
25512 : 1854447 : case E_DImode:
25513 : 1854447 : if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
25514 : : return V8DImode;
25515 : 1461268 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25516 : : return V4DImode;
25517 : : else
25518 : 1398584 : return V2DImode;
25519 : :
25520 : 138018 : case E_HFmode:
25521 : 138018 : if (TARGET_AVX512FP16)
25522 : : {
25523 : 137475 : if (TARGET_AVX512VL)
25524 : : {
25525 : 64695 : if (TARGET_PREFER_AVX128)
25526 : : return V8HFmode;
25527 : 64465 : else if (TARGET_PREFER_AVX256)
25528 : : return V16HFmode;
25529 : : }
25530 : 135089 : return V32HFmode;
25531 : : }
25532 : 543 : return word_mode;
25533 : :
25534 : 57044 : case E_BFmode:
25535 : 57044 : if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
25536 : : return V32BFmode;
25537 : 26552 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25538 : : return V16BFmode;
25539 : : else
25540 : 13489 : return V8BFmode;
25541 : :
25542 : 588484 : case E_SFmode:
25543 : 588484 : if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
25544 : : return V16SFmode;
25545 : 399282 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25546 : : return V8SFmode;
25547 : : else
25548 : 337061 : return V4SFmode;
25549 : :
25550 : 262376 : case E_DFmode:
25551 : 262376 : if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
25552 : : return V8DFmode;
25553 : 144496 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25554 : : return V4DFmode;
25555 : 94094 : else if (TARGET_SSE2)
25556 : : return V2DFmode;
25557 : : /* FALLTHRU */
25558 : :
25559 : 23274 : default:
25560 : 23274 : return word_mode;
25561 : : }
25562 : : }
25563 : :
25564 : : /* If AVX is enabled then try vectorizing with both 256bit and 128bit
25565 : : vectors. If AVX512F is enabled then try vectorizing with 512bit,
25566 : : 256bit and 128bit vectors. */
25567 : :
25568 : : static unsigned int
25569 : 2316210 : ix86_autovectorize_vector_modes (vector_modes *modes, bool all)
25570 : : {
25571 : 2316210 : if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
25572 : : {
25573 : 72241 : modes->safe_push (V64QImode);
25574 : 72241 : modes->safe_push (V32QImode);
25575 : 72241 : modes->safe_push (V16QImode);
25576 : : }
25577 : 2243969 : else if (TARGET_AVX512F && all)
25578 : : {
25579 : 555 : modes->safe_push (V32QImode);
25580 : 555 : modes->safe_push (V16QImode);
25581 : 555 : modes->safe_push (V64QImode);
25582 : : }
25583 : 2243414 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
25584 : : {
25585 : 28083 : modes->safe_push (V32QImode);
25586 : 28083 : modes->safe_push (V16QImode);
25587 : : }
25588 : 2215331 : else if (TARGET_AVX && all)
25589 : : {
25590 : 24 : modes->safe_push (V16QImode);
25591 : 24 : modes->safe_push (V32QImode);
25592 : : }
25593 : 2215307 : else if (TARGET_SSE2)
25594 : 2213056 : modes->safe_push (V16QImode);
25595 : :
25596 : 2316210 : if (TARGET_MMX_WITH_SSE)
25597 : 1849452 : modes->safe_push (V8QImode);
25598 : :
25599 : 2316210 : if (TARGET_SSE2)
25600 : 2313959 : modes->safe_push (V4QImode);
25601 : :
25602 : 2316210 : return 0;
25603 : : }
25604 : :
25605 : : /* Implemenation of targetm.vectorize.get_mask_mode. */
25606 : :
25607 : : static opt_machine_mode
25608 : 1934870 : ix86_get_mask_mode (machine_mode data_mode)
25609 : : {
25610 : 1934870 : unsigned vector_size = GET_MODE_SIZE (data_mode);
25611 : 1934870 : unsigned nunits = GET_MODE_NUNITS (data_mode);
25612 : 1934870 : unsigned elem_size = vector_size / nunits;
25613 : :
25614 : : /* Scalar mask case. */
25615 : 131131 : if ((TARGET_AVX512F && vector_size == 64)
25616 : 1910410 : || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
25617 : : /* AVX512FP16 only supports vector comparison
25618 : : to kmask for _Float16. */
25619 : 1865279 : || (TARGET_AVX512VL && TARGET_AVX512FP16
25620 : 367 : && GET_MODE_INNER (data_mode) == E_HFmode)
25621 : 3800139 : || (TARGET_AVX10_2 && GET_MODE_INNER (data_mode) == E_BFmode))
25622 : : {
25623 : 69690 : if (elem_size == 4
25624 : 69690 : || elem_size == 8
25625 : 24181 : || (TARGET_AVX512BW && (elem_size == 1 || elem_size == 2)))
25626 : 61471 : return smallest_int_mode_for_size (nunits).require ();
25627 : : }
25628 : :
25629 : 1873399 : scalar_int_mode elem_mode
25630 : 1873399 : = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT).require ();
25631 : :
25632 : 1873399 : gcc_assert (elem_size * nunits == vector_size);
25633 : :
25634 : 1873399 : return mode_for_vector (elem_mode, nunits);
25635 : : }
25636 : :
25637 : :
25638 : :
25639 : : /* Return class of registers which could be used for pseudo of MODE
25640 : : and of class RCLASS for spilling instead of memory. Return NO_REGS
25641 : : if it is not possible or non-profitable. */
25642 : :
25643 : : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657. */
25644 : :
25645 : : static reg_class_t
25646 : 6405267822 : ix86_spill_class (reg_class_t rclass, machine_mode mode)
25647 : : {
25648 : 6405267822 : if (0 && TARGET_GENERAL_REGS_SSE_SPILL
25649 : : && TARGET_SSE2
25650 : : && TARGET_INTER_UNIT_MOVES_TO_VEC
25651 : : && TARGET_INTER_UNIT_MOVES_FROM_VEC
25652 : : && (mode == SImode || (TARGET_64BIT && mode == DImode))
25653 : : && INTEGER_CLASS_P (rclass))
25654 : : return ALL_SSE_REGS;
25655 : 6405267822 : return NO_REGS;
25656 : : }
25657 : :
25658 : : /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST. Like the default implementation,
25659 : : but returns a lower bound. */
25660 : :
25661 : : static unsigned int
25662 : 1861844 : ix86_max_noce_ifcvt_seq_cost (edge e)
25663 : : {
25664 : 1861844 : bool predictable_p = predictable_edge_p (e);
25665 : 1861844 : if (predictable_p)
25666 : : {
25667 : 140381 : if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
25668 : 0 : return param_max_rtl_if_conversion_predictable_cost;
25669 : : }
25670 : : else
25671 : : {
25672 : 1721463 : if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
25673 : 83 : return param_max_rtl_if_conversion_unpredictable_cost;
25674 : : }
25675 : :
25676 : : /* For modern machines with deeper pipeline, the penalty for branch
25677 : : misprediction could be higher than before to reset the pipeline
25678 : : slots. Add parameter br_mispredict_scale as a factor to describe
25679 : : the impact of reseting the pipeline. */
25680 : :
25681 : 1861761 : return BRANCH_COST (true, predictable_p)
25682 : 1861761 : * ix86_tune_cost->br_mispredict_scale;
25683 : : }
25684 : :
25685 : : /* Return true if SEQ is a good candidate as a replacement for the
25686 : : if-convertible sequence described in IF_INFO. */
25687 : :
25688 : : static bool
25689 : 230134 : ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
25690 : : {
25691 : 230134 : if (TARGET_ONE_IF_CONV_INSN && if_info->speed_p)
25692 : : {
25693 : : int cmov_cnt = 0;
25694 : : /* Punt if SEQ contains more than one CMOV or FCMOV instruction.
25695 : : Maybe we should allow even more conditional moves as long as they
25696 : : are used far enough not to stall the CPU, or also consider
25697 : : IF_INFO->TEST_BB succ edge probabilities. */
25698 : 307 : for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
25699 : : {
25700 : 253 : rtx set = single_set (insn);
25701 : 253 : if (!set)
25702 : 0 : continue;
25703 : 253 : if (GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
25704 : 205 : continue;
25705 : 48 : rtx src = SET_SRC (set);
25706 : 48 : machine_mode mode = GET_MODE (src);
25707 : 48 : if (GET_MODE_CLASS (mode) != MODE_INT
25708 : 0 : && GET_MODE_CLASS (mode) != MODE_FLOAT)
25709 : 0 : continue;
25710 : 48 : if ((!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
25711 : 47 : || (!REG_P (XEXP (src, 2)) && !MEM_P (XEXP (src, 2))))
25712 : 1 : continue;
25713 : : /* insn is CMOV or FCMOV. */
25714 : 47 : if (++cmov_cnt > 1)
25715 : : return false;
25716 : : }
25717 : : }
25718 : :
25719 : : /* W/o TARGET_SSE4_1, it takes 3 instructions (pand, pandn and por)
25720 : : for movdfcc/movsfcc, and could possibly fail cost comparison.
25721 : : Increase branch cost will hurt performance for other modes, so
25722 : : specially add some preference for floating point ifcvt. */
25723 : 230126 : if (!TARGET_SSE4_1 && if_info->x
25724 : 175022 : && GET_MODE_CLASS (GET_MODE (if_info->x)) == MODE_FLOAT
25725 : 34271 : && if_info->speed_p)
25726 : : {
25727 : 27171 : unsigned cost = seq_cost (seq, true);
25728 : :
25729 : 27171 : if (cost <= if_info->original_cost)
25730 : : return true;
25731 : :
25732 : 26041 : return cost <= (if_info->max_seq_cost + COSTS_N_INSNS (2));
25733 : : }
25734 : :
25735 : 202955 : return default_noce_conversion_profitable_p (seq, if_info);
25736 : : }
25737 : :
25738 : : /* x86-specific vector costs. */
25739 : : class ix86_vector_costs : public vector_costs
25740 : : {
25741 : : public:
25742 : : ix86_vector_costs (vec_info *, bool);
25743 : :
25744 : : unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
25745 : : stmt_vec_info stmt_info, slp_tree node,
25746 : : tree vectype, int misalign,
25747 : : vect_cost_model_location where) override;
25748 : : void finish_cost (const vector_costs *) override;
25749 : :
25750 : : private:
25751 : :
25752 : : /* Estimate register pressure of the vectorized code. */
25753 : : void ix86_vect_estimate_reg_pressure ();
25754 : : /* Number of GENERAL_REGS/SSE_REGS used in the vectorizer, it's used for
25755 : : estimation of register pressure.
25756 : : ??? Currently it's only used by vec_construct/scalar_to_vec
25757 : : where we know it's not loaded from memory. */
25758 : : unsigned m_num_gpr_needed[3];
25759 : : unsigned m_num_sse_needed[3];
25760 : : /* Number of 256-bit vector permutation. */
25761 : : unsigned m_num_avx256_vec_perm[3];
25762 : : };
25763 : :
25764 : 1926924 : ix86_vector_costs::ix86_vector_costs (vec_info* vinfo, bool costing_for_scalar)
25765 : : : vector_costs (vinfo, costing_for_scalar),
25766 : 1926924 : m_num_gpr_needed (),
25767 : 1926924 : m_num_sse_needed (),
25768 : 1926924 : m_num_avx256_vec_perm ()
25769 : : {
25770 : 1926924 : }
25771 : :
25772 : : /* Implement targetm.vectorize.create_costs. */
25773 : :
25774 : : static vector_costs *
25775 : 1926924 : ix86_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
25776 : : {
25777 : 1926924 : return new ix86_vector_costs (vinfo, costing_for_scalar);
25778 : : }
25779 : :
25780 : : unsigned
25781 : 6525745 : ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
25782 : : stmt_vec_info stmt_info, slp_tree node,
25783 : : tree vectype, int misalign,
25784 : : vect_cost_model_location where)
25785 : : {
25786 : 6525745 : unsigned retval = 0;
25787 : 6525745 : bool scalar_p
25788 : : = (kind == scalar_stmt || kind == scalar_load || kind == scalar_store);
25789 : 6525745 : int stmt_cost = - 1;
25790 : :
25791 : 6525745 : bool fp = false;
25792 : 6525745 : machine_mode mode = scalar_p ? SImode : TImode;
25793 : :
25794 : 6525745 : if (vectype != NULL)
25795 : : {
25796 : 6231624 : fp = FLOAT_TYPE_P (vectype);
25797 : 6231624 : mode = TYPE_MODE (vectype);
25798 : 6231624 : if (scalar_p)
25799 : 3492162 : mode = TYPE_MODE (TREE_TYPE (vectype));
25800 : : }
25801 : : /* When we are costing a scalar stmt use the scalar stmt to get at the
25802 : : type of the operation. */
25803 : 294121 : else if (scalar_p && stmt_info)
25804 : 146245 : if (tree lhs = gimple_get_lhs (stmt_info->stmt))
25805 : : {
25806 : 71449 : fp = FLOAT_TYPE_P (TREE_TYPE (lhs));
25807 : 71449 : mode = TYPE_MODE (TREE_TYPE (lhs));
25808 : : }
25809 : :
25810 : 6525745 : if ((kind == vector_stmt || kind == scalar_stmt)
25811 : 1465928 : && stmt_info
25812 : 7985837 : && stmt_info->stmt && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
25813 : : {
25814 : 1200537 : tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
25815 : : /*machine_mode inner_mode = mode;
25816 : : if (VECTOR_MODE_P (mode))
25817 : : inner_mode = GET_MODE_INNER (mode);*/
25818 : :
25819 : 1200537 : switch (subcode)
25820 : : {
25821 : 508797 : case PLUS_EXPR:
25822 : 508797 : case POINTER_PLUS_EXPR:
25823 : 508797 : case MINUS_EXPR:
25824 : 508797 : if (kind == scalar_stmt)
25825 : : {
25826 : 349920 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
25827 : 66071 : stmt_cost = ix86_cost->addss;
25828 : 283849 : else if (X87_FLOAT_MODE_P (mode))
25829 : 80 : stmt_cost = ix86_cost->fadd;
25830 : : else
25831 : 283769 : stmt_cost = ix86_cost->add;
25832 : : }
25833 : : else
25834 : 158877 : stmt_cost = ix86_vec_cost (mode, fp ? ix86_cost->addss
25835 : : : ix86_cost->sse_op);
25836 : : break;
25837 : :
25838 : 153255 : case MULT_EXPR:
25839 : : /* For MULT_HIGHPART_EXPR, x86 only supports pmulhw,
25840 : : take it as MULT_EXPR. */
25841 : 153255 : case MULT_HIGHPART_EXPR:
25842 : 153255 : stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
25843 : 153255 : break;
25844 : : /* There's no direct instruction for WIDEN_MULT_EXPR,
25845 : : take emulation into account. */
25846 : 1726 : case WIDEN_MULT_EXPR:
25847 : 3452 : stmt_cost = ix86_widen_mult_cost (ix86_cost, mode,
25848 : 1726 : TYPE_UNSIGNED (vectype));
25849 : 1726 : break;
25850 : :
25851 : 5403 : case NEGATE_EXPR:
25852 : 5403 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
25853 : 1699 : stmt_cost = ix86_cost->sse_op;
25854 : 3704 : else if (X87_FLOAT_MODE_P (mode))
25855 : 0 : stmt_cost = ix86_cost->fchs;
25856 : 3704 : else if (VECTOR_MODE_P (mode))
25857 : 1722 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
25858 : : else
25859 : 1982 : stmt_cost = ix86_cost->add;
25860 : : break;
25861 : 7130 : case TRUNC_DIV_EXPR:
25862 : 7130 : case CEIL_DIV_EXPR:
25863 : 7130 : case FLOOR_DIV_EXPR:
25864 : 7130 : case ROUND_DIV_EXPR:
25865 : 7130 : case TRUNC_MOD_EXPR:
25866 : 7130 : case CEIL_MOD_EXPR:
25867 : 7130 : case FLOOR_MOD_EXPR:
25868 : 7130 : case RDIV_EXPR:
25869 : 7130 : case ROUND_MOD_EXPR:
25870 : 7130 : case EXACT_DIV_EXPR:
25871 : 7130 : stmt_cost = ix86_division_cost (ix86_cost, mode);
25872 : 7130 : break;
25873 : :
25874 : 36745 : case RSHIFT_EXPR:
25875 : 36745 : case LSHIFT_EXPR:
25876 : 36745 : case LROTATE_EXPR:
25877 : 36745 : case RROTATE_EXPR:
25878 : 36745 : {
25879 : 36745 : tree op1 = gimple_assign_rhs1 (stmt_info->stmt);
25880 : 36745 : tree op2 = gimple_assign_rhs2 (stmt_info->stmt);
25881 : 36745 : stmt_cost = ix86_shift_rotate_cost
25882 : 36745 : (ix86_cost,
25883 : : (subcode == RSHIFT_EXPR
25884 : 23689 : && !TYPE_UNSIGNED (TREE_TYPE (op1)))
25885 : : ? ASHIFTRT : LSHIFTRT, mode,
25886 : 36745 : TREE_CODE (op2) == INTEGER_CST,
25887 : 36745 : cst_and_fits_in_hwi (op2)
25888 : 24773 : ? int_cst_value (op2) : -1,
25889 : : false, false, NULL, NULL);
25890 : : }
25891 : 36745 : break;
25892 : 64719 : case NOP_EXPR:
25893 : : /* Only sign-conversions are free. */
25894 : 64719 : if (tree_nop_conversion_p
25895 : 64719 : (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt)),
25896 : 64719 : TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))))
25897 : : stmt_cost = 0;
25898 : 64719 : else if (fp)
25899 : 6649 : stmt_cost = vec_fp_conversion_cost
25900 : 6649 : (ix86_tune_cost, GET_MODE_BITSIZE (mode));
25901 : : break;
25902 : :
25903 : 14006 : case FLOAT_EXPR:
25904 : 14006 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
25905 : 10611 : stmt_cost = ix86_cost->cvtsi2ss;
25906 : 3395 : else if (X87_FLOAT_MODE_P (mode))
25907 : : /* TODO: We do not have cost tables for x87. */
25908 : 1 : stmt_cost = ix86_cost->fadd;
25909 : : else
25910 : 3394 : stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtpi2ps);
25911 : : break;
25912 : :
25913 : 1821 : case FIX_TRUNC_EXPR:
25914 : 1821 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
25915 : 0 : stmt_cost = ix86_cost->cvtss2si;
25916 : 1821 : else if (X87_FLOAT_MODE_P (mode))
25917 : : /* TODO: We do not have cost tables for x87. */
25918 : 0 : stmt_cost = ix86_cost->fadd;
25919 : : else
25920 : 1821 : stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtps2pi);
25921 : : break;
25922 : :
25923 : 30961 : case COND_EXPR:
25924 : 30961 : {
25925 : : /* SSE2 conditinal move sequence is:
25926 : : pcmpgtd %xmm5, %xmm0 (accounted separately)
25927 : : pand %xmm0, %xmm2
25928 : : pandn %xmm1, %xmm0
25929 : : por %xmm2, %xmm0
25930 : : while SSE4 uses cmp + blend
25931 : : and AVX512 masked moves.
25932 : :
25933 : : The condition is accounted separately since we usually have
25934 : : p = a < b
25935 : : c = p ? x : y
25936 : : and we will account first statement as setcc. Exception is when
25937 : : p is loaded from memory as bool and then we will not acocunt
25938 : : the compare, but there is no way to check for this. */
25939 : :
25940 : 30961 : int ninsns = TARGET_SSE4_1 ? 1 : 3;
25941 : :
25942 : : /* If one of parameters is 0 or -1 the sequence will be simplified:
25943 : : (if_true & mask) | (if_false & ~mask) -> if_true & mask */
25944 : 15928 : if (ninsns > 1
25945 : 15928 : && (zerop (gimple_assign_rhs2 (stmt_info->stmt))
25946 : 15669 : || zerop (gimple_assign_rhs3 (stmt_info->stmt))
25947 : 8145 : || integer_minus_onep
25948 : 8145 : (gimple_assign_rhs2 (stmt_info->stmt))
25949 : 7923 : || integer_minus_onep
25950 : 7923 : (gimple_assign_rhs3 (stmt_info->stmt))))
25951 : : ninsns = 1;
25952 : :
25953 : 30961 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
25954 : 3312 : stmt_cost = ninsns * ix86_cost->sse_op;
25955 : 27649 : else if (X87_FLOAT_MODE_P (mode))
25956 : : /* x87 requires conditional branch. We don't have cost for
25957 : : that. */
25958 : : ;
25959 : 27640 : else if (VECTOR_MODE_P (mode))
25960 : 11343 : stmt_cost = ix86_vec_cost (mode, ninsns * ix86_cost->sse_op);
25961 : : else
25962 : : /* compare (accounted separately) + cmov. */
25963 : 16297 : stmt_cost = ix86_cost->add;
25964 : : }
25965 : : break;
25966 : :
25967 : 15984 : case MIN_EXPR:
25968 : 15984 : case MAX_EXPR:
25969 : 15984 : if (fp)
25970 : : {
25971 : 993 : if (X87_FLOAT_MODE_P (mode)
25972 : 379 : && !SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
25973 : : /* x87 requires conditional branch. We don't have cost for
25974 : : that. */
25975 : : ;
25976 : : else
25977 : : /* minss */
25978 : 993 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
25979 : : }
25980 : : else
25981 : : {
25982 : 14991 : if (VECTOR_MODE_P (mode))
25983 : : {
25984 : 3980 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
25985 : : /* vpmin was introduced in SSE3.
25986 : : SSE2 needs pcmpgtd + pand + pandn + pxor.
25987 : : If one of parameters is 0 or -1 the sequence is simplified
25988 : : to pcmpgtd + pand. */
25989 : 3980 : if (!TARGET_SSSE3)
25990 : : {
25991 : 3011 : if (zerop (gimple_assign_rhs2 (stmt_info->stmt))
25992 : 4258 : || integer_minus_onep
25993 : 1247 : (gimple_assign_rhs2 (stmt_info->stmt)))
25994 : 1764 : stmt_cost *= 2;
25995 : : else
25996 : 1247 : stmt_cost *= 4;
25997 : : }
25998 : : }
25999 : : else
26000 : : /* cmp + cmov. */
26001 : 11011 : stmt_cost = ix86_cost->add * 2;
26002 : : }
26003 : : break;
26004 : :
26005 : 1849 : case ABS_EXPR:
26006 : 1849 : case ABSU_EXPR:
26007 : 1849 : if (fp)
26008 : : {
26009 : 1473 : if (X87_FLOAT_MODE_P (mode)
26010 : 1337 : && !SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
26011 : : /* fabs. */
26012 : 0 : stmt_cost = ix86_cost->fabs;
26013 : : else
26014 : : /* andss of sign bit. */
26015 : 1473 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
26016 : : }
26017 : : else
26018 : : {
26019 : 376 : if (VECTOR_MODE_P (mode))
26020 : : {
26021 : 94 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
26022 : : /* vabs was introduced in SSE3.
26023 : : SSE3 uses psrat + pxor + psub. */
26024 : 94 : if (!TARGET_SSSE3)
26025 : 85 : stmt_cost *= 3;
26026 : : }
26027 : : else
26028 : : /* neg + cmov. */
26029 : 282 : stmt_cost = ix86_cost->add * 2;
26030 : : }
26031 : : break;
26032 : :
26033 : 85167 : case BIT_IOR_EXPR:
26034 : 85167 : case BIT_XOR_EXPR:
26035 : 85167 : case BIT_AND_EXPR:
26036 : 85167 : case BIT_NOT_EXPR:
26037 : 85167 : gcc_assert (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode)
26038 : : && !X87_FLOAT_MODE_P (mode));
26039 : 85167 : if (VECTOR_MODE_P (mode))
26040 : 28757 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
26041 : : else
26042 : 56410 : stmt_cost = ix86_cost->add;
26043 : : break;
26044 : :
26045 : 272974 : default:
26046 : 272974 : if (truth_value_p (subcode))
26047 : : {
26048 : 53460 : if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
26049 : : /* CMPccS? insructions are cheap, so use sse_op. While they
26050 : : produce a mask which may need to be turned to 0/1 by and,
26051 : : expect that this will be optimized away in a common case. */
26052 : 0 : stmt_cost = ix86_cost->sse_op;
26053 : 53460 : else if (X87_FLOAT_MODE_P (mode))
26054 : : /* fcmp + setcc. */
26055 : 0 : stmt_cost = ix86_cost->fadd + ix86_cost->add;
26056 : 53460 : else if (VECTOR_MODE_P (mode))
26057 : 12958 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
26058 : : else
26059 : : /* setcc. */
26060 : 40502 : stmt_cost = ix86_cost->add;
26061 : : break;
26062 : : }
26063 : : break;
26064 : : }
26065 : : }
26066 : :
26067 : 6525745 : combined_fn cfn;
26068 : 6525745 : if ((kind == vector_stmt || kind == scalar_stmt)
26069 : 1465928 : && stmt_info
26070 : 1460092 : && stmt_info->stmt
26071 : 7985837 : && (cfn = gimple_call_combined_fn (stmt_info->stmt)) != CFN_LAST)
26072 : 15311 : switch (cfn)
26073 : : {
26074 : 48 : case CFN_FMA:
26075 : 48 : stmt_cost = ix86_vec_cost (mode,
26076 : 48 : mode == SFmode ? ix86_cost->fmass
26077 : : : ix86_cost->fmasd);
26078 : 48 : break;
26079 : 24 : case CFN_MULH:
26080 : 24 : stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
26081 : 24 : break;
26082 : : default:
26083 : : break;
26084 : : }
26085 : :
26086 : 6525745 : if (kind == vec_promote_demote)
26087 : : {
26088 : 34143 : int outer_size
26089 : : = tree_to_uhwi
26090 : 34143 : (TYPE_SIZE
26091 : 34143 : (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt))));
26092 : 34143 : int inner_size
26093 : : = tree_to_uhwi
26094 : 34143 : (TYPE_SIZE
26095 : 34143 : (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))));
26096 : 34143 : bool inner_fp = FLOAT_TYPE_P
26097 : : (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt)));
26098 : :
26099 : 3472 : if (fp && inner_fp)
26100 : 3106 : stmt_cost = vec_fp_conversion_cost
26101 : 3106 : (ix86_tune_cost, GET_MODE_BITSIZE (mode));
26102 : 31037 : else if (fp && !inner_fp)
26103 : 3733 : stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtpi2ps);
26104 : 27304 : else if (!fp && inner_fp)
26105 : 366 : stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtps2pi);
26106 : : else
26107 : 26938 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
26108 : : /* VEC_PACK_TRUNC_EXPR and similar demote operations: If outer size is
26109 : : greater than inner size we will end up doing two conversions and
26110 : : packing them. We always pack pairs; if the size difference is greater
26111 : : it is split into multiple demote operations. */
26112 : 34143 : if (inner_size > outer_size)
26113 : 16546 : stmt_cost = stmt_cost * 2
26114 : 16546 : + ix86_vec_cost (mode, ix86_cost->sse_op);
26115 : : }
26116 : :
26117 : : /* If we do elementwise loads into a vector then we are bound by
26118 : : latency and execution resources for the many scalar loads
26119 : : (AGU and load ports). Try to account for this by scaling the
26120 : : construction cost by the number of elements involved. */
26121 : 6525745 : if ((kind == vec_construct || kind == vec_to_scalar)
26122 : 482630 : && ((stmt_info
26123 : 196384 : && (STMT_VINFO_TYPE (stmt_info) == load_vec_info_type
26124 : 196384 : || STMT_VINFO_TYPE (stmt_info) == store_vec_info_type)
26125 : 75443 : && ((STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_ELEMENTWISE
26126 : 0 : && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)))
26127 : : != INTEGER_CST))
26128 : 75443 : || (STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info)
26129 : : == VMAT_GATHER_SCATTER)))
26130 : 478502 : || (node
26131 : 341161 : && (((SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_ELEMENTWISE
26132 : 335153 : || (SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_STRIDED_SLP
26133 : 36265 : && SLP_TREE_LANES (node) == 1))
26134 : 40396 : && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF
26135 : : (SLP_TREE_REPRESENTATIVE (node))))
26136 : : != INTEGER_CST))
26137 : 316195 : || (SLP_TREE_MEMORY_ACCESS_TYPE (node)
26138 : : == VMAT_GATHER_SCATTER)))))
26139 : : {
26140 : 32992 : stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
26141 : 32992 : stmt_cost *= (TYPE_VECTOR_SUBPARTS (vectype) + 1);
26142 : : }
26143 : 6492753 : else if ((kind == vec_construct || kind == scalar_to_vec)
26144 : 564012 : && node
26145 : 413301 : && SLP_TREE_DEF_TYPE (node) == vect_external_def)
26146 : : {
26147 : 373000 : stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
26148 : 373000 : unsigned i;
26149 : 373000 : tree op;
26150 : 1592948 : FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
26151 : 846948 : if (TREE_CODE (op) == SSA_NAME)
26152 : 581322 : TREE_VISITED (op) = 0;
26153 : 1219948 : FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
26154 : : {
26155 : 846948 : if (TREE_CODE (op) != SSA_NAME
26156 : 581322 : || TREE_VISITED (op))
26157 : 308467 : continue;
26158 : 538481 : TREE_VISITED (op) = 1;
26159 : 538481 : gimple *def = SSA_NAME_DEF_STMT (op);
26160 : 538481 : tree tem;
26161 : 538481 : if (is_gimple_assign (def)
26162 : 282757 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
26163 : 34366 : && ((tem = gimple_assign_rhs1 (def)), true)
26164 : 34366 : && TREE_CODE (tem) == SSA_NAME
26165 : : /* A sign-change expands to nothing. */
26166 : 572658 : && tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (def)),
26167 : 34177 : TREE_TYPE (tem)))
26168 : 9855 : def = SSA_NAME_DEF_STMT (tem);
26169 : : /* When the component is loaded from memory we can directly
26170 : : move it to a vector register, otherwise we have to go
26171 : : via a GPR or via vpinsr which involves similar cost.
26172 : : Likewise with a BIT_FIELD_REF extracting from a vector
26173 : : register we can hope to avoid using a GPR. */
26174 : 538481 : if (!is_gimple_assign (def)
26175 : 538481 : || ((!gimple_assign_load_p (def)
26176 : 143622 : || (!TARGET_SSE4_1
26177 : 279116 : && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op))) == 1))
26178 : 142271 : && (gimple_assign_rhs_code (def) != BIT_FIELD_REF
26179 : 3521 : || !VECTOR_TYPE_P (TREE_TYPE
26180 : : (TREE_OPERAND (gimple_assign_rhs1 (def), 0))))))
26181 : : {
26182 : 396272 : if (fp)
26183 : 15735 : m_num_sse_needed[where]++;
26184 : : else
26185 : : {
26186 : 380537 : m_num_gpr_needed[where]++;
26187 : :
26188 : 380537 : int cost = COSTS_N_INSNS (ix86_cost->integer_to_sse) / 2;
26189 : :
26190 : : /* For integer construction, the number of actual GPR -> XMM
26191 : : moves will be somewhere between 0 and n.
26192 : : We do not have very good idea about actual number, since
26193 : : the source may be a constant, memory or a chain of
26194 : : instructions that will be later converted by
26195 : : scalar-to-vector pass. */
26196 : 380537 : if (kind == vec_construct
26197 : 644360 : && GET_MODE_BITSIZE (mode) == 256)
26198 : 804 : cost *= 2;
26199 : 379733 : else if (kind == vec_construct
26200 : 642752 : && GET_MODE_BITSIZE (mode) == 512)
26201 : 48 : cost *= 3;
26202 : 380537 : stmt_cost += cost;
26203 : : }
26204 : : }
26205 : : }
26206 : 1219948 : FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
26207 : 846948 : if (TREE_CODE (op) == SSA_NAME)
26208 : 581322 : TREE_VISITED (op) = 0;
26209 : : }
26210 : 6525745 : if (stmt_cost == -1)
26211 : 5162594 : stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
26212 : :
26213 : 6525745 : if (kind == vec_perm && vectype
26214 : 6609180 : && GET_MODE_SIZE (TYPE_MODE (vectype)) == 32)
26215 : 2931 : m_num_avx256_vec_perm[where]++;
26216 : :
26217 : : /* Penalize DFmode vector operations for Bonnell. */
26218 : 6525745 : if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
26219 : 6525807 : && vectype && GET_MODE_INNER (TYPE_MODE (vectype)) == DFmode)
26220 : 12 : stmt_cost *= 5; /* FIXME: The value here is arbitrary. */
26221 : :
26222 : : /* Statements in an inner loop relative to the loop being
26223 : : vectorized are weighted more heavily. The value here is
26224 : : arbitrary and could potentially be improved with analysis. */
26225 : 6525745 : retval = adjust_cost_for_freq (stmt_info, where, count * stmt_cost);
26226 : :
26227 : : /* We need to multiply all vector stmt cost by 1.7 (estimated cost)
26228 : : for Silvermont as it has out of order integer pipeline and can execute
26229 : : 2 scalar instruction per tick, but has in order SIMD pipeline. */
26230 : 6525745 : if ((TARGET_CPU_P (SILVERMONT) || TARGET_CPU_P (GOLDMONT)
26231 : 6525745 : || TARGET_CPU_P (GOLDMONT_PLUS) || TARGET_CPU_P (INTEL))
26232 : 1779 : && stmt_info && stmt_info->stmt)
26233 : : {
26234 : 1559 : tree lhs_op = gimple_get_lhs (stmt_info->stmt);
26235 : 1559 : if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE)
26236 : 1171 : retval = (retval * 17) / 10;
26237 : : }
26238 : :
26239 : 6525745 : m_costs[where] += retval;
26240 : :
26241 : 6525745 : return retval;
26242 : : }
26243 : :
26244 : : void
26245 : 1729672 : ix86_vector_costs::ix86_vect_estimate_reg_pressure ()
26246 : : {
26247 : 1729672 : unsigned gpr_spill_cost = COSTS_N_INSNS (ix86_cost->int_store [2]) / 2;
26248 : 1729672 : unsigned sse_spill_cost = COSTS_N_INSNS (ix86_cost->sse_store[0]) / 2;
26249 : :
26250 : : /* Any better way to have target available fp registers, currently use SSE_REGS. */
26251 : 1729672 : unsigned target_avail_sse = TARGET_64BIT ? (TARGET_AVX512F ? 32 : 16) : 8;
26252 : 6918688 : for (unsigned i = 0; i != 3; i++)
26253 : : {
26254 : 5189016 : if (m_num_gpr_needed[i] > target_avail_regs)
26255 : 748 : m_costs[i] += gpr_spill_cost * (m_num_gpr_needed[i] - target_avail_regs);
26256 : : /* Only measure sse registers pressure. */
26257 : 5189016 : if (TARGET_SSE && (m_num_sse_needed[i] > target_avail_sse))
26258 : 138 : m_costs[i] += sse_spill_cost * (m_num_sse_needed[i] - target_avail_sse);
26259 : : }
26260 : 1729672 : }
26261 : :
26262 : : void
26263 : 1729672 : ix86_vector_costs::finish_cost (const vector_costs *scalar_costs)
26264 : : {
26265 : 1729672 : loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
26266 : 263300 : if (loop_vinfo && !m_costing_for_scalar)
26267 : : {
26268 : : /* We are currently not asking the vectorizer to compare costs
26269 : : between different vector mode sizes. When using predication
26270 : : that will end up always choosing the prefered mode size even
26271 : : if there's a smaller mode covering all lanes. Test for this
26272 : : situation and artificially reject the larger mode attempt.
26273 : : ??? We currently lack masked ops for sub-SSE sized modes,
26274 : : so we could restrict this rejection to AVX and AVX512 modes
26275 : : but error on the safe side for now. */
26276 : 78156 : if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
26277 : 20 : && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
26278 : 13 : && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
26279 : 78164 : && (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())
26280 : 16 : > ceil_log2 (LOOP_VINFO_INT_NITERS (loop_vinfo))))
26281 : 6 : m_costs[vect_body] = INT_MAX;
26282 : : }
26283 : :
26284 : 1729672 : ix86_vect_estimate_reg_pressure ();
26285 : :
26286 : 6918688 : for (int i = 0; i != 3; i++)
26287 : 5189016 : if (m_num_avx256_vec_perm[i]
26288 : 472 : && TARGET_AVX256_AVOID_VEC_PERM)
26289 : 2 : m_costs[i] = INT_MAX;
26290 : :
26291 : : /* When X86_TUNE_AVX512_TWO_EPILOGUES is enabled arrange for both
26292 : : a AVX2 and a SSE epilogue for AVX512 vectorized loops. */
26293 : 1729672 : if (loop_vinfo
26294 : 263300 : && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
26295 : 36634 : && GET_MODE_SIZE (loop_vinfo->vector_mode) == 32
26296 : 1730266 : && ix86_tune_features[X86_TUNE_AVX512_TWO_EPILOGUES])
26297 : 10 : m_suggested_epilogue_mode = V16QImode;
26298 : : /* When a 128bit SSE vectorized epilogue still has a VF of 16 or larger
26299 : : enable a 64bit SSE epilogue. */
26300 : 1729672 : if (loop_vinfo
26301 : 263300 : && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
26302 : 36634 : && GET_MODE_SIZE (loop_vinfo->vector_mode) == 16
26303 : 1731999 : && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () >= 16)
26304 : 80 : m_suggested_epilogue_mode = V8QImode;
26305 : :
26306 : : /* When X86_TUNE_AVX512_MASKED_EPILOGUES is enabled try to use
26307 : : a masked epilogue if that doesn't seem detrimental. */
26308 : 1729672 : if (loop_vinfo
26309 : 263300 : && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
26310 : 244983 : && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () > 2
26311 : 49232 : && ix86_tune_features[X86_TUNE_AVX512_MASKED_EPILOGUES]
26312 : 1729764 : && !OPTION_SET_P (param_vect_partial_vector_usage))
26313 : : {
26314 : 86 : bool avoid = false;
26315 : 86 : if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
26316 : 68 : && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) >= 0)
26317 : : {
26318 : 68 : unsigned int peel_niter
26319 : : = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo);
26320 : 68 : if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
26321 : 0 : peel_niter += 1;
26322 : : /* When we know the number of scalar iterations of the epilogue,
26323 : : avoid masking when a single vector epilog iteration handles
26324 : : it in full. */
26325 : 68 : if (pow2p_hwi ((LOOP_VINFO_INT_NITERS (loop_vinfo) - peel_niter)
26326 : 68 : % LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ()))
26327 : : avoid = true;
26328 : : }
26329 : 85 : if (!avoid && loop_outer (loop_outer (LOOP_VINFO_LOOP (loop_vinfo))))
26330 : 7 : for (auto ddr : LOOP_VINFO_DDRS (loop_vinfo))
26331 : : {
26332 : 2 : if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
26333 : : ;
26334 : 2 : else if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
26335 : : ;
26336 : : else
26337 : : {
26338 : 1 : int loop_depth
26339 : 2 : = index_in_loop_nest (LOOP_VINFO_LOOP (loop_vinfo)->num,
26340 : 1 : DDR_LOOP_NEST (ddr));
26341 : 2 : if (DDR_NUM_DIST_VECTS (ddr) == 1
26342 : 1 : && DDR_DIST_VECTS (ddr)[0][loop_depth] == 0)
26343 : : {
26344 : : /* Avoid the case when there's an outer loop that might
26345 : : traverse a multi-dimensional array with the inner
26346 : : loop just executing the masked epilogue with a
26347 : : read-write where the next outer iteration might
26348 : : read from the masked part of the previous write,
26349 : : 'n' filling half a vector.
26350 : : for (j = 0; j < m; ++j)
26351 : : for (i = 0; i < n; ++i)
26352 : : a[j][i] = c * a[j][i]; */
26353 : : avoid = true;
26354 : : break;
26355 : : }
26356 : : }
26357 : : }
26358 : 86 : if (!avoid)
26359 : : {
26360 : 84 : m_suggested_epilogue_mode = loop_vinfo->vector_mode;
26361 : 84 : m_masked_epilogue = 1;
26362 : : }
26363 : : }
26364 : :
26365 : 1729672 : vector_costs::finish_cost (scalar_costs);
26366 : 1729672 : }
26367 : :
26368 : : /* Validate target specific memory model bits in VAL. */
26369 : :
26370 : : static unsigned HOST_WIDE_INT
26371 : 517169 : ix86_memmodel_check (unsigned HOST_WIDE_INT val)
26372 : : {
26373 : 517169 : enum memmodel model = memmodel_from_int (val);
26374 : 517169 : bool strong;
26375 : :
26376 : 517169 : if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
26377 : : |MEMMODEL_MASK)
26378 : 517165 : || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
26379 : : {
26380 : 4 : warning (OPT_Winvalid_memory_model,
26381 : : "unknown architecture specific memory model");
26382 : 4 : return MEMMODEL_SEQ_CST;
26383 : : }
26384 : 517165 : strong = (is_mm_acq_rel (model) || is_mm_seq_cst (model));
26385 : 517165 : if (val & IX86_HLE_ACQUIRE && !(is_mm_acquire (model) || strong))
26386 : : {
26387 : 0 : warning (OPT_Winvalid_memory_model,
26388 : : "%<HLE_ACQUIRE%> not used with %<ACQUIRE%> or stronger "
26389 : : "memory model");
26390 : 0 : return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
26391 : : }
26392 : 517165 : if (val & IX86_HLE_RELEASE && !(is_mm_release (model) || strong))
26393 : : {
26394 : 0 : warning (OPT_Winvalid_memory_model,
26395 : : "%<HLE_RELEASE%> not used with %<RELEASE%> or stronger "
26396 : : "memory model");
26397 : 0 : return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
26398 : : }
26399 : : return val;
26400 : : }
26401 : :
26402 : : /* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
26403 : : CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
26404 : : CLONEI->simdlen. Return 0 if SIMD clones shouldn't be emitted,
26405 : : or number of vecsize_mangle variants that should be emitted. */
26406 : :
26407 : : static int
26408 : 7477 : ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
26409 : : struct cgraph_simd_clone *clonei,
26410 : : tree base_type, int num,
26411 : : bool explicit_p)
26412 : : {
26413 : 7477 : int ret = 1;
26414 : :
26415 : 7477 : if (clonei->simdlen
26416 : 7477 : && (clonei->simdlen < 2
26417 : 1289 : || clonei->simdlen > 1024
26418 : 1289 : || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
26419 : : {
26420 : 0 : if (explicit_p)
26421 : 0 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
26422 : : "unsupported simdlen %wd", clonei->simdlen.to_constant ());
26423 : 0 : return 0;
26424 : : }
26425 : :
26426 : 7477 : tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
26427 : 7477 : if (TREE_CODE (ret_type) != VOID_TYPE)
26428 : 6685 : switch (TYPE_MODE (ret_type))
26429 : : {
26430 : 6685 : case E_QImode:
26431 : 6685 : case E_HImode:
26432 : 6685 : case E_SImode:
26433 : 6685 : case E_DImode:
26434 : 6685 : case E_SFmode:
26435 : 6685 : case E_DFmode:
26436 : : /* case E_SCmode: */
26437 : : /* case E_DCmode: */
26438 : 6685 : if (!AGGREGATE_TYPE_P (ret_type))
26439 : : break;
26440 : : /* FALLTHRU */
26441 : 2 : default:
26442 : 2 : if (explicit_p)
26443 : 2 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
26444 : : "unsupported return type %qT for simd", ret_type);
26445 : 2 : return 0;
26446 : : }
26447 : :
26448 : 7475 : tree t;
26449 : 7475 : int i;
26450 : 7475 : tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
26451 : 7475 : bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
26452 : :
26453 : 7475 : for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
26454 : 20178 : t && t != void_list_node; t = TREE_CHAIN (t), i++)
26455 : : {
26456 : 16422 : tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
26457 : 12708 : switch (TYPE_MODE (arg_type))
26458 : : {
26459 : 12689 : case E_QImode:
26460 : 12689 : case E_HImode:
26461 : 12689 : case E_SImode:
26462 : 12689 : case E_DImode:
26463 : 12689 : case E_SFmode:
26464 : 12689 : case E_DFmode:
26465 : : /* case E_SCmode: */
26466 : : /* case E_DCmode: */
26467 : 12689 : if (!AGGREGATE_TYPE_P (arg_type))
26468 : : break;
26469 : : /* FALLTHRU */
26470 : 41 : default:
26471 : 41 : if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
26472 : : break;
26473 : 5 : if (explicit_p)
26474 : 5 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
26475 : : "unsupported argument type %qT for simd", arg_type);
26476 : : return 0;
26477 : : }
26478 : : }
26479 : :
26480 : 7470 : if (!TREE_PUBLIC (node->decl) || !explicit_p)
26481 : : {
26482 : : /* If the function isn't exported, we can pick up just one ISA
26483 : : for the clones. */
26484 : 114 : if (TARGET_AVX512F)
26485 : 0 : clonei->vecsize_mangle = 'e';
26486 : 114 : else if (TARGET_AVX2)
26487 : 1 : clonei->vecsize_mangle = 'd';
26488 : 113 : else if (TARGET_AVX)
26489 : 88 : clonei->vecsize_mangle = 'c';
26490 : : else
26491 : 25 : clonei->vecsize_mangle = 'b';
26492 : : ret = 1;
26493 : : }
26494 : : else
26495 : : {
26496 : 7356 : clonei->vecsize_mangle = "bcde"[num];
26497 : 7356 : ret = 4;
26498 : : }
26499 : 7470 : clonei->mask_mode = VOIDmode;
26500 : 7470 : switch (clonei->vecsize_mangle)
26501 : : {
26502 : 1864 : case 'b':
26503 : 1864 : clonei->vecsize_int = 128;
26504 : 1864 : clonei->vecsize_float = 128;
26505 : 1864 : break;
26506 : 1927 : case 'c':
26507 : 1927 : clonei->vecsize_int = 128;
26508 : 1927 : clonei->vecsize_float = 256;
26509 : 1927 : break;
26510 : 1840 : case 'd':
26511 : 1840 : clonei->vecsize_int = 256;
26512 : 1840 : clonei->vecsize_float = 256;
26513 : 1840 : break;
26514 : 1839 : case 'e':
26515 : 1839 : clonei->vecsize_int = 512;
26516 : 1839 : clonei->vecsize_float = 512;
26517 : 1839 : if (TYPE_MODE (base_type) == QImode)
26518 : 15 : clonei->mask_mode = DImode;
26519 : : else
26520 : 1824 : clonei->mask_mode = SImode;
26521 : : break;
26522 : : }
26523 : 7470 : if (clonei->simdlen == 0)
26524 : : {
26525 : 6181 : if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
26526 : 3265 : clonei->simdlen = clonei->vecsize_int;
26527 : : else
26528 : 2916 : clonei->simdlen = clonei->vecsize_float;
26529 : 6181 : clonei->simdlen = clonei->simdlen
26530 : 12362 : / GET_MODE_BITSIZE (TYPE_MODE (base_type));
26531 : : }
26532 : 1289 : else if (clonei->simdlen > 16)
26533 : : {
26534 : : /* For compatibility with ICC, use the same upper bounds
26535 : : for simdlen. In particular, for CTYPE below, use the return type,
26536 : : unless the function returns void, in that case use the characteristic
26537 : : type. If it is possible for given SIMDLEN to pass CTYPE value
26538 : : in registers (8 [XYZ]MM* regs for 32-bit code, 16 [XYZ]MM* regs
26539 : : for 64-bit code), accept that SIMDLEN, otherwise warn and don't
26540 : : emit corresponding clone. */
26541 : 4 : tree ctype = ret_type;
26542 : 4 : if (VOID_TYPE_P (ret_type))
26543 : 0 : ctype = base_type;
26544 : 8 : int cnt = GET_MODE_BITSIZE (TYPE_MODE (ctype)) * clonei->simdlen;
26545 : 4 : if (SCALAR_INT_MODE_P (TYPE_MODE (ctype)))
26546 : 0 : cnt /= clonei->vecsize_int;
26547 : : else
26548 : 4 : cnt /= clonei->vecsize_float;
26549 : 4 : if (cnt > (TARGET_64BIT ? 16 : 8))
26550 : : {
26551 : 0 : if (explicit_p)
26552 : 0 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
26553 : : "unsupported simdlen %wd",
26554 : : clonei->simdlen.to_constant ());
26555 : 0 : return 0;
26556 : : }
26557 : : }
26558 : : return ret;
26559 : : }
26560 : :
26561 : : /* If SIMD clone NODE can't be used in a vectorized loop
26562 : : in current function, return -1, otherwise return a badness of using it
26563 : : (0 if it is most desirable from vecsize_mangle point of view, 1
26564 : : slightly less desirable, etc.). */
26565 : :
26566 : : static int
26567 : 1650 : ix86_simd_clone_usable (struct cgraph_node *node, machine_mode)
26568 : : {
26569 : 1650 : switch (node->simdclone->vecsize_mangle)
26570 : : {
26571 : 577 : case 'b':
26572 : 577 : if (!TARGET_SSE2)
26573 : : return -1;
26574 : 577 : if (!TARGET_AVX)
26575 : : return 0;
26576 : 492 : return TARGET_AVX512F ? 3 : TARGET_AVX2 ? 2 : 1;
26577 : 587 : case 'c':
26578 : 587 : if (!TARGET_AVX)
26579 : : return -1;
26580 : 556 : return TARGET_AVX512F ? 2 : TARGET_AVX2 ? 1 : 0;
26581 : 312 : case 'd':
26582 : 312 : if (!TARGET_AVX2)
26583 : : return -1;
26584 : 119 : return TARGET_AVX512F ? 1 : 0;
26585 : 174 : case 'e':
26586 : 174 : if (!TARGET_AVX512F)
26587 : 136 : return -1;
26588 : : return 0;
26589 : 0 : default:
26590 : 0 : gcc_unreachable ();
26591 : : }
26592 : : }
26593 : :
26594 : : /* This function adjusts the unroll factor based on
26595 : : the hardware capabilities. For ex, bdver3 has
26596 : : a loop buffer which makes unrolling of smaller
26597 : : loops less important. This function decides the
26598 : : unroll factor using number of memory references
26599 : : (value 32 is used) as a heuristic. */
26600 : :
26601 : : static unsigned
26602 : 797846 : ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
26603 : : {
26604 : 797846 : basic_block *bbs;
26605 : 797846 : rtx_insn *insn;
26606 : 797846 : unsigned i;
26607 : 797846 : unsigned mem_count = 0;
26608 : :
26609 : : /* Unroll small size loop when unroll factor is not explicitly
26610 : : specified. */
26611 : 797846 : if (ix86_unroll_only_small_loops && !loop->unroll)
26612 : : {
26613 : 755644 : if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
26614 : 69584 : return MIN (nunroll, ix86_cost->small_unroll_factor);
26615 : : else
26616 : : return 1;
26617 : : }
26618 : :
26619 : 42202 : if (!TARGET_ADJUST_UNROLL)
26620 : : return nunroll;
26621 : :
26622 : : /* Count the number of memory references within the loop body.
26623 : : This value determines the unrolling factor for bdver3 and bdver4
26624 : : architectures. */
26625 : 7 : subrtx_iterator::array_type array;
26626 : 7 : bbs = get_loop_body (loop);
26627 : 21 : for (i = 0; i < loop->num_nodes; i++)
26628 : 102 : FOR_BB_INSNS (bbs[i], insn)
26629 : 88 : if (NONDEBUG_INSN_P (insn))
26630 : 464 : FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
26631 : 404 : if (const_rtx x = *iter)
26632 : 404 : if (MEM_P (x))
26633 : : {
26634 : 25 : machine_mode mode = GET_MODE (x);
26635 : 50 : unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
26636 : 25 : if (n_words > 4)
26637 : 0 : mem_count += 2;
26638 : : else
26639 : 25 : mem_count += 1;
26640 : : }
26641 : 7 : free (bbs);
26642 : :
26643 : 7 : if (mem_count && mem_count <=32)
26644 : 7 : return MIN (nunroll, 32 / mem_count);
26645 : :
26646 : : return nunroll;
26647 : 7 : }
26648 : :
26649 : :
26650 : : /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P. */
26651 : :
26652 : : static bool
26653 : 411462 : ix86_float_exceptions_rounding_supported_p (void)
26654 : : {
26655 : : /* For x87 floating point with standard excess precision handling,
26656 : : there is no adddf3 pattern (since x87 floating point only has
26657 : : XFmode operations) so the default hook implementation gets this
26658 : : wrong. */
26659 : 411462 : return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
26660 : : }
26661 : :
26662 : : /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
26663 : :
26664 : : static void
26665 : 7054 : ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
26666 : : {
26667 : 7054 : if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
26668 : : return;
26669 : 7054 : tree exceptions_var = create_tmp_var_raw (integer_type_node);
26670 : 7054 : if (TARGET_80387)
26671 : : {
26672 : 7054 : tree fenv_index_type = build_index_type (size_int (6));
26673 : 7054 : tree fenv_type = build_array_type (unsigned_type_node, fenv_index_type);
26674 : 7054 : tree fenv_var = create_tmp_var_raw (fenv_type);
26675 : 7054 : TREE_ADDRESSABLE (fenv_var) = 1;
26676 : 7054 : tree fenv_ptr = build_pointer_type (fenv_type);
26677 : 7054 : tree fenv_addr = build1 (ADDR_EXPR, fenv_ptr, fenv_var);
26678 : 7054 : fenv_addr = fold_convert (ptr_type_node, fenv_addr);
26679 : 7054 : tree fnstenv = get_ix86_builtin (IX86_BUILTIN_FNSTENV);
26680 : 7054 : tree fldenv = get_ix86_builtin (IX86_BUILTIN_FLDENV);
26681 : 7054 : tree fnstsw = get_ix86_builtin (IX86_BUILTIN_FNSTSW);
26682 : 7054 : tree fnclex = get_ix86_builtin (IX86_BUILTIN_FNCLEX);
26683 : 7054 : tree hold_fnstenv = build_call_expr (fnstenv, 1, fenv_addr);
26684 : 7054 : tree hold_fnclex = build_call_expr (fnclex, 0);
26685 : 7054 : fenv_var = build4 (TARGET_EXPR, fenv_type, fenv_var, hold_fnstenv,
26686 : : NULL_TREE, NULL_TREE);
26687 : 7054 : *hold = build2 (COMPOUND_EXPR, void_type_node, fenv_var,
26688 : : hold_fnclex);
26689 : 7054 : *clear = build_call_expr (fnclex, 0);
26690 : 7054 : tree sw_var = create_tmp_var_raw (short_unsigned_type_node);
26691 : 7054 : tree fnstsw_call = build_call_expr (fnstsw, 0);
26692 : 7054 : tree sw_mod = build4 (TARGET_EXPR, short_unsigned_type_node, sw_var,
26693 : : fnstsw_call, NULL_TREE, NULL_TREE);
26694 : 7054 : tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
26695 : 7054 : tree update_mod = build4 (TARGET_EXPR, integer_type_node,
26696 : : exceptions_var, exceptions_x87,
26697 : : NULL_TREE, NULL_TREE);
26698 : 7054 : *update = build2 (COMPOUND_EXPR, integer_type_node,
26699 : : sw_mod, update_mod);
26700 : 7054 : tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
26701 : 7054 : *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
26702 : : }
26703 : 7054 : if (TARGET_SSE && TARGET_SSE_MATH)
26704 : : {
26705 : 7054 : tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
26706 : 7054 : tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
26707 : 7054 : tree stmxcsr = get_ix86_builtin (IX86_BUILTIN_STMXCSR);
26708 : 7054 : tree ldmxcsr = get_ix86_builtin (IX86_BUILTIN_LDMXCSR);
26709 : 7054 : tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
26710 : 7054 : tree hold_assign_orig = build4 (TARGET_EXPR, unsigned_type_node,
26711 : : mxcsr_orig_var, stmxcsr_hold_call,
26712 : : NULL_TREE, NULL_TREE);
26713 : 7054 : tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
26714 : : mxcsr_orig_var,
26715 : : build_int_cst (unsigned_type_node, 0x1f80));
26716 : 7054 : hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
26717 : : build_int_cst (unsigned_type_node, 0xffffffc0));
26718 : 7054 : tree hold_assign_mod = build4 (TARGET_EXPR, unsigned_type_node,
26719 : : mxcsr_mod_var, hold_mod_val,
26720 : : NULL_TREE, NULL_TREE);
26721 : 7054 : tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
26722 : 7054 : tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
26723 : : hold_assign_orig, hold_assign_mod);
26724 : 7054 : hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
26725 : : ldmxcsr_hold_call);
26726 : 7054 : if (*hold)
26727 : 7054 : *hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
26728 : : else
26729 : 0 : *hold = hold_all;
26730 : 7054 : tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
26731 : 7054 : if (*clear)
26732 : 7054 : *clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
26733 : : ldmxcsr_clear_call);
26734 : : else
26735 : 0 : *clear = ldmxcsr_clear_call;
26736 : 7054 : tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
26737 : 7054 : tree exceptions_sse = fold_convert (integer_type_node,
26738 : : stxmcsr_update_call);
26739 : 7054 : if (*update)
26740 : : {
26741 : 7054 : tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
26742 : : exceptions_var, exceptions_sse);
26743 : 7054 : tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
26744 : : exceptions_var, exceptions_mod);
26745 : 7054 : *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
26746 : : exceptions_assign);
26747 : : }
26748 : : else
26749 : 0 : *update = build4 (TARGET_EXPR, integer_type_node, exceptions_var,
26750 : : exceptions_sse, NULL_TREE, NULL_TREE);
26751 : 7054 : tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
26752 : 7054 : *update = build2 (COMPOUND_EXPR, void_type_node, *update,
26753 : : ldmxcsr_update_call);
26754 : : }
26755 : 7054 : tree atomic_feraiseexcept
26756 : 7054 : = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
26757 : 7054 : tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
26758 : : 1, exceptions_var);
26759 : 7054 : *update = build2 (COMPOUND_EXPR, void_type_node, *update,
26760 : : atomic_feraiseexcept_call);
26761 : : }
26762 : :
26763 : : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
26764 : : /* For i386, common symbol is local only for non-PIE binaries. For
26765 : : x86-64, common symbol is local only for non-PIE binaries or linker
26766 : : supports copy reloc in PIE binaries. */
26767 : :
26768 : : static bool
26769 : 752617282 : ix86_binds_local_p (const_tree exp)
26770 : : {
26771 : 752617282 : bool direct_extern_access
26772 : 752617282 : = (ix86_direct_extern_access
26773 : 1501745494 : && !(VAR_OR_FUNCTION_DECL_P (exp)
26774 : 749128212 : && lookup_attribute ("nodirect_extern_access",
26775 : 749128212 : DECL_ATTRIBUTES (exp))));
26776 : 752617282 : if (!direct_extern_access)
26777 : 1039 : ix86_has_no_direct_extern_access = true;
26778 : 752617282 : return default_binds_local_p_3 (exp, flag_shlib != 0, true,
26779 : : direct_extern_access,
26780 : : (direct_extern_access
26781 : 752616243 : && (!flag_pic
26782 : 130419879 : || (TARGET_64BIT
26783 : 752617282 : && HAVE_LD_PIE_COPYRELOC != 0))));
26784 : : }
26785 : :
26786 : : /* If flag_pic or ix86_direct_extern_access is false, then neither
26787 : : local nor global relocs should be placed in readonly memory. */
26788 : :
26789 : : static int
26790 : 5139878 : ix86_reloc_rw_mask (void)
26791 : : {
26792 : 5139878 : return (flag_pic || !ix86_direct_extern_access) ? 3 : 0;
26793 : : }
26794 : : #endif
26795 : :
26796 : : /* Return true iff ADDR can be used as a symbolic base address. */
26797 : :
26798 : : static bool
26799 : 3702 : symbolic_base_address_p (rtx addr)
26800 : : {
26801 : 0 : if (GET_CODE (addr) == SYMBOL_REF)
26802 : : return true;
26803 : :
26804 : 3627 : if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
26805 : 0 : return true;
26806 : :
26807 : : return false;
26808 : : }
26809 : :
26810 : : /* Return true iff ADDR can be used as a base address. */
26811 : :
26812 : : static bool
26813 : 5676 : base_address_p (rtx addr)
26814 : : {
26815 : 0 : if (REG_P (addr))
26816 : : return true;
26817 : :
26818 : 3448 : if (symbolic_base_address_p (addr))
26819 : 0 : return true;
26820 : :
26821 : : return false;
26822 : : }
26823 : :
26824 : : /* If MEM is in the form of [(base+symbase)+offset], extract the three
26825 : : parts of address and set to BASE, SYMBASE and OFFSET, otherwise
26826 : : return false. */
26827 : :
26828 : : static bool
26829 : 3508 : extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
26830 : : {
26831 : 3508 : rtx addr;
26832 : :
26833 : 3508 : gcc_assert (MEM_P (mem));
26834 : :
26835 : 3508 : addr = XEXP (mem, 0);
26836 : :
26837 : 3508 : if (GET_CODE (addr) == CONST)
26838 : 56 : addr = XEXP (addr, 0);
26839 : :
26840 : 3508 : if (base_address_p (addr))
26841 : : {
26842 : 1340 : *base = addr;
26843 : 1340 : *symbase = const0_rtx;
26844 : 1340 : *offset = const0_rtx;
26845 : 1340 : return true;
26846 : : }
26847 : :
26848 : 2168 : if (GET_CODE (addr) == PLUS
26849 : 2168 : && base_address_p (XEXP (addr, 0)))
26850 : : {
26851 : 963 : rtx addend = XEXP (addr, 1);
26852 : :
26853 : 963 : if (GET_CODE (addend) == CONST)
26854 : 0 : addend = XEXP (addend, 0);
26855 : :
26856 : 963 : if (CONST_INT_P (addend))
26857 : : {
26858 : 709 : *base = XEXP (addr, 0);
26859 : 709 : *symbase = const0_rtx;
26860 : 709 : *offset = addend;
26861 : 709 : return true;
26862 : : }
26863 : :
26864 : : /* Also accept REG + symbolic ref, with or without a CONST_INT
26865 : : offset. */
26866 : 254 : if (REG_P (XEXP (addr, 0)))
26867 : : {
26868 : 254 : if (symbolic_base_address_p (addend))
26869 : : {
26870 : 0 : *base = XEXP (addr, 0);
26871 : 0 : *symbase = addend;
26872 : 0 : *offset = const0_rtx;
26873 : 0 : return true;
26874 : : }
26875 : :
26876 : 254 : if (GET_CODE (addend) == PLUS
26877 : 0 : && symbolic_base_address_p (XEXP (addend, 0))
26878 : 254 : && CONST_INT_P (XEXP (addend, 1)))
26879 : : {
26880 : 0 : *base = XEXP (addr, 0);
26881 : 0 : *symbase = XEXP (addend, 0);
26882 : 0 : *offset = XEXP (addend, 1);
26883 : 0 : return true;
26884 : : }
26885 : : }
26886 : : }
26887 : :
26888 : : return false;
26889 : : }
26890 : :
26891 : : /* Given OPERANDS of consecutive load/store, check if we can merge
26892 : : them into move multiple. LOAD is true if they are load instructions.
26893 : : MODE is the mode of memory operands. */
26894 : :
26895 : : bool
26896 : 1950 : ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
26897 : : machine_mode mode)
26898 : : {
26899 : 1950 : HOST_WIDE_INT offval_1, offval_2, msize;
26900 : 1950 : rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
26901 : : symbase_1, symbase_2, offset_1, offset_2;
26902 : :
26903 : 1950 : if (load)
26904 : : {
26905 : 1615 : mem_1 = operands[1];
26906 : 1615 : mem_2 = operands[3];
26907 : 1615 : reg_1 = operands[0];
26908 : 1615 : reg_2 = operands[2];
26909 : : }
26910 : : else
26911 : : {
26912 : 335 : mem_1 = operands[0];
26913 : 335 : mem_2 = operands[2];
26914 : 335 : reg_1 = operands[1];
26915 : 335 : reg_2 = operands[3];
26916 : : }
26917 : :
26918 : 1950 : gcc_assert (REG_P (reg_1) && REG_P (reg_2));
26919 : :
26920 : 1950 : if (REGNO (reg_1) != REGNO (reg_2))
26921 : : return false;
26922 : :
26923 : : /* Check if the addresses are in the form of [base+offset]. */
26924 : 1950 : if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
26925 : : return false;
26926 : 1558 : if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
26927 : : return false;
26928 : :
26929 : : /* Check if the bases are the same. */
26930 : 491 : if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))
26931 : 106 : return false;
26932 : :
26933 : 385 : offval_1 = INTVAL (offset_1);
26934 : 385 : offval_2 = INTVAL (offset_2);
26935 : 385 : msize = GET_MODE_SIZE (mode);
26936 : : /* Check if mem_1 is adjacent to mem_2 and mem_1 has lower address. */
26937 : 385 : if (offval_1 + msize != offval_2)
26938 : : return false;
26939 : :
26940 : : return true;
26941 : : }
26942 : :
26943 : : /* Implement the TARGET_OPTAB_SUPPORTED_P hook. */
26944 : :
26945 : : static bool
26946 : 325381 : ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
26947 : : optimization_type opt_type)
26948 : : {
26949 : 325381 : switch (op)
26950 : : {
26951 : 220 : case asin_optab:
26952 : 220 : case acos_optab:
26953 : 220 : case log1p_optab:
26954 : 220 : case exp_optab:
26955 : 220 : case exp10_optab:
26956 : 220 : case exp2_optab:
26957 : 220 : case expm1_optab:
26958 : 220 : case ldexp_optab:
26959 : 220 : case scalb_optab:
26960 : 220 : case round_optab:
26961 : 220 : case lround_optab:
26962 : 220 : return opt_type == OPTIMIZE_FOR_SPEED;
26963 : :
26964 : 267 : case rint_optab:
26965 : 267 : if (SSE_FLOAT_MODE_P (mode1)
26966 : 144 : && TARGET_SSE_MATH
26967 : 128 : && !flag_trapping_math
26968 : 21 : && !TARGET_SSE4_1
26969 : : && mode1 != HFmode)
26970 : 21 : return opt_type == OPTIMIZE_FOR_SPEED;
26971 : : return true;
26972 : :
26973 : 1816 : case floor_optab:
26974 : 1816 : case ceil_optab:
26975 : 1816 : case btrunc_optab:
26976 : 1816 : if (((SSE_FLOAT_MODE_P (mode1)
26977 : 1510 : && TARGET_SSE_MATH
26978 : 1431 : && TARGET_SSE4_1)
26979 : 1767 : || mode1 == HFmode)
26980 : 118 : && !flag_trapping_math)
26981 : : return true;
26982 : 1756 : return opt_type == OPTIMIZE_FOR_SPEED;
26983 : :
26984 : 84 : case rsqrt_optab:
26985 : 84 : return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1);
26986 : :
26987 : : default:
26988 : : return true;
26989 : : }
26990 : : }
26991 : :
26992 : : /* Address space support.
26993 : :
26994 : : This is not "far pointers" in the 16-bit sense, but an easy way
26995 : : to use %fs and %gs segment prefixes. Therefore:
26996 : :
26997 : : (a) All address spaces have the same modes,
26998 : : (b) All address spaces have the same addresss forms,
26999 : : (c) While %fs and %gs are technically subsets of the generic
27000 : : address space, they are probably not subsets of each other.
27001 : : (d) Since we have no access to the segment base register values
27002 : : without resorting to a system call, we cannot convert a
27003 : : non-default address space to a default address space.
27004 : : Therefore we do not claim %fs or %gs are subsets of generic.
27005 : :
27006 : : Therefore we can (mostly) use the default hooks. */
27007 : :
27008 : : /* All use of segmentation is assumed to make address 0 valid. */
27009 : :
27010 : : static bool
27011 : 67903372 : ix86_addr_space_zero_address_valid (addr_space_t as)
27012 : : {
27013 : 67903372 : return as != ADDR_SPACE_GENERIC;
27014 : : }
27015 : :
27016 : : static void
27017 : 782396 : ix86_init_libfuncs (void)
27018 : : {
27019 : 782396 : if (TARGET_64BIT)
27020 : : {
27021 : 767587 : set_optab_libfunc (sdivmod_optab, TImode, "__divmodti4");
27022 : 767587 : set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4");
27023 : : }
27024 : : else
27025 : : {
27026 : 14809 : set_optab_libfunc (sdivmod_optab, DImode, "__divmoddi4");
27027 : 14809 : set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
27028 : : }
27029 : :
27030 : : #if TARGET_MACHO
27031 : : darwin_rename_builtins ();
27032 : : #endif
27033 : 782396 : }
27034 : :
27035 : : /* Set the value of FLT_EVAL_METHOD in float.h. When using only the
27036 : : FPU, assume that the fpcw is set to extended precision; when using
27037 : : only SSE, rounding is correct; when using both SSE and the FPU,
27038 : : the rounding precision is indeterminate, since either may be chosen
27039 : : apparently at random. */
27040 : :
27041 : : static enum flt_eval_method
27042 : 91387167 : ix86_get_excess_precision (enum excess_precision_type type)
27043 : : {
27044 : 91387167 : switch (type)
27045 : : {
27046 : 87550977 : case EXCESS_PRECISION_TYPE_FAST:
27047 : : /* The fastest type to promote to will always be the native type,
27048 : : whether that occurs with implicit excess precision or
27049 : : otherwise. */
27050 : 87550977 : return TARGET_AVX512FP16
27051 : 87550977 : ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
27052 : 87550977 : : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
27053 : 3836109 : case EXCESS_PRECISION_TYPE_STANDARD:
27054 : 3836109 : case EXCESS_PRECISION_TYPE_IMPLICIT:
27055 : : /* Otherwise, the excess precision we want when we are
27056 : : in a standards compliant mode, and the implicit precision we
27057 : : provide would be identical were it not for the unpredictable
27058 : : cases. */
27059 : 3836109 : if (TARGET_AVX512FP16 && TARGET_SSE_MATH)
27060 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
27061 : 3830379 : else if (!TARGET_80387)
27062 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
27063 : 3824279 : else if (!TARGET_MIX_SSE_I387)
27064 : : {
27065 : 3824107 : if (!(TARGET_SSE && TARGET_SSE_MATH))
27066 : : return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
27067 : 2837449 : else if (TARGET_SSE2)
27068 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
27069 : : }
27070 : :
27071 : : /* If we are in standards compliant mode, but we know we will
27072 : : calculate in unpredictable precision, return
27073 : : FLT_EVAL_METHOD_FLOAT. There is no reason to introduce explicit
27074 : : excess precision if the target can't guarantee it will honor
27075 : : it. */
27076 : 318 : return (type == EXCESS_PRECISION_TYPE_STANDARD
27077 : 318 : ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
27078 : : : FLT_EVAL_METHOD_UNPREDICTABLE);
27079 : 81 : case EXCESS_PRECISION_TYPE_FLOAT16:
27080 : 81 : if (TARGET_80387
27081 : 75 : && !(TARGET_SSE_MATH && TARGET_SSE))
27082 : 4 : error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
27083 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
27084 : 0 : default:
27085 : 0 : gcc_unreachable ();
27086 : : }
27087 : :
27088 : : return FLT_EVAL_METHOD_UNPREDICTABLE;
27089 : : }
27090 : :
27091 : : /* Return true if _BitInt(N) is supported and fill its details into *INFO. */
27092 : : bool
27093 : 1712360 : ix86_bitint_type_info (int n, struct bitint_info *info)
27094 : : {
27095 : 1712360 : if (n <= 8)
27096 : 3871 : info->limb_mode = QImode;
27097 : 1708489 : else if (n <= 16)
27098 : 918 : info->limb_mode = HImode;
27099 : 1707571 : else if (n <= 32 || (!TARGET_64BIT && n > 64))
27100 : 18773 : info->limb_mode = SImode;
27101 : : else
27102 : 1688798 : info->limb_mode = DImode;
27103 : 1712360 : info->abi_limb_mode = info->limb_mode;
27104 : 1712360 : info->big_endian = false;
27105 : 1712360 : info->extended = false;
27106 : 1712360 : return true;
27107 : : }
27108 : :
27109 : : /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE. Return DFmode, TFmode
27110 : : or XFmode for TI_LONG_DOUBLE_TYPE which is for long double type,
27111 : : based on long double bits, go with the default one for the others. */
27112 : :
27113 : : static machine_mode
27114 : 3602814 : ix86_c_mode_for_floating_type (enum tree_index ti)
27115 : : {
27116 : 3602814 : if (ti == TI_LONG_DOUBLE_TYPE)
27117 : 601257 : return (TARGET_LONG_DOUBLE_64 ? DFmode
27118 : 601225 : : (TARGET_LONG_DOUBLE_128 ? TFmode : XFmode));
27119 : 3001557 : return default_mode_for_floating_type (ti);
27120 : : }
27121 : :
27122 : : /* Returns modified FUNCTION_TYPE for cdtor callabi. */
27123 : : tree
27124 : 13699 : ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype)
27125 : : {
27126 : 13699 : if (TARGET_64BIT
27127 : 65 : || TARGET_RTD
27128 : 13764 : || ix86_function_type_abi (fntype) != MS_ABI)
27129 : 13699 : return fntype;
27130 : : /* For 32-bit MS ABI add thiscall attribute. */
27131 : 0 : tree attribs = tree_cons (get_identifier ("thiscall"), NULL_TREE,
27132 : 0 : TYPE_ATTRIBUTES (fntype));
27133 : 0 : return build_type_attribute_variant (fntype, attribs);
27134 : : }
27135 : :
27136 : : /* Implement PUSH_ROUNDING. On 386, we have pushw instruction that
27137 : : decrements by exactly 2 no matter what the position was, there is no pushb.
27138 : :
27139 : : But as CIE data alignment factor on this arch is -4 for 32bit targets
27140 : : and -8 for 64bit targets, we need to make sure all stack pointer adjustments
27141 : : are in multiple of 4 for 32bit targets and 8 for 64bit targets. */
27142 : :
27143 : : poly_int64
27144 : 269686877 : ix86_push_rounding (poly_int64 bytes)
27145 : : {
27146 : 349261097 : return ROUND_UP (bytes, UNITS_PER_WORD);
27147 : : }
27148 : :
27149 : : /* Use 8 bits metadata start from bit48 for LAM_U48,
27150 : : 6 bits metadat start from bit57 for LAM_U57. */
27151 : : #define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48 \
27152 : : ? 48 \
27153 : : : (ix86_lam_type == lam_u57 ? 57 : 0))
27154 : : #define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48 \
27155 : : ? 8 \
27156 : : : (ix86_lam_type == lam_u57 ? 6 : 0))
27157 : :
27158 : : /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES. */
27159 : : bool
27160 : 6188434 : ix86_memtag_can_tag_addresses ()
27161 : : {
27162 : 6188434 : return ix86_lam_type != lam_none && TARGET_LP64;
27163 : : }
27164 : :
27165 : : /* Implement TARGET_MEMTAG_TAG_SIZE. */
27166 : : unsigned char
27167 : 440 : ix86_memtag_tag_size ()
27168 : : {
27169 : 440 : return IX86_HWASAN_TAG_SIZE;
27170 : : }
27171 : :
27172 : : /* Implement TARGET_MEMTAG_SET_TAG. */
27173 : : rtx
27174 : 104 : ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
27175 : : {
27176 : : /* default_memtag_insert_random_tag may
27177 : : generate tag with value more than 6 bits. */
27178 : 104 : if (ix86_lam_type == lam_u57)
27179 : : {
27180 : 104 : unsigned HOST_WIDE_INT and_imm
27181 : : = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
27182 : :
27183 : 104 : emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
27184 : : }
27185 : 104 : tag = expand_simple_binop (Pmode, ASHIFT, tag,
27186 : 104 : GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
27187 : : /* unsignedp = */1, OPTAB_WIDEN);
27188 : 104 : rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
27189 : : /* unsignedp = */1, OPTAB_DIRECT);
27190 : 104 : return ret;
27191 : : }
27192 : :
27193 : : /* Implement TARGET_MEMTAG_EXTRACT_TAG. */
27194 : : rtx
27195 : 176 : ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
27196 : : {
27197 : 176 : rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
27198 : 176 : GEN_INT (IX86_HWASAN_SHIFT), target,
27199 : : /* unsignedp = */0,
27200 : : OPTAB_DIRECT);
27201 : 176 : rtx ret = gen_reg_rtx (QImode);
27202 : : /* Mask off bit63 when LAM_U57. */
27203 : 176 : if (ix86_lam_type == lam_u57)
27204 : : {
27205 : 176 : unsigned HOST_WIDE_INT and_imm
27206 : : = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
27207 : 176 : emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
27208 : 176 : gen_int_mode (and_imm, QImode)));
27209 : : }
27210 : : else
27211 : 0 : emit_move_insn (ret, gen_lowpart (QImode, tag));
27212 : 176 : return ret;
27213 : : }
27214 : :
27215 : : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER. */
27216 : : rtx
27217 : 112 : ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
27218 : : {
27219 : : /* Leave bit63 alone. */
27220 : 112 : rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
27221 : 112 : + (HOST_WIDE_INT_1U << 63) - 1),
27222 : 112 : Pmode);
27223 : 112 : rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
27224 : : tag_mask, target, true,
27225 : : OPTAB_DIRECT);
27226 : 112 : gcc_assert (untagged_base);
27227 : 112 : return untagged_base;
27228 : : }
27229 : :
27230 : : /* Implement TARGET_MEMTAG_ADD_TAG. */
27231 : : rtx
27232 : 88 : ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
27233 : : {
27234 : 88 : rtx base_tag = gen_reg_rtx (QImode);
27235 : 88 : rtx base_addr = gen_reg_rtx (Pmode);
27236 : 88 : rtx tagged_addr = gen_reg_rtx (Pmode);
27237 : 88 : rtx new_tag = gen_reg_rtx (QImode);
27238 : 176 : unsigned HOST_WIDE_INT and_imm
27239 : 88 : = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
27240 : :
27241 : : /* When there's "overflow" in tag adding,
27242 : : need to mask the most significant bit off. */
27243 : 88 : emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
27244 : 88 : emit_move_insn (base_addr,
27245 : : ix86_memtag_untagged_pointer (base, NULL_RTX));
27246 : 88 : emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
27247 : 88 : emit_move_insn (new_tag, base_tag);
27248 : 88 : emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
27249 : 88 : emit_move_insn (tagged_addr,
27250 : : ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
27251 : 88 : return plus_constant (Pmode, tagged_addr, offset);
27252 : : }
27253 : :
27254 : : /* Implement TARGET_HAVE_CCMP. */
27255 : : static bool
27256 : 7873005 : ix86_have_ccmp ()
27257 : : {
27258 : 7873005 : return (bool) TARGET_APX_CCMP;
27259 : : }
27260 : :
27261 : : /* Implement TARGET_MODE_CAN_TRANSFER_BITS. */
27262 : : static bool
27263 : 4794925 : ix86_mode_can_transfer_bits (machine_mode mode)
27264 : : {
27265 : 4794925 : if (GET_MODE_CLASS (mode) == MODE_FLOAT
27266 : 4747197 : || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
27267 : 115466 : switch (GET_MODE_INNER (mode))
27268 : : {
27269 : 55630 : case E_SFmode:
27270 : 55630 : case E_DFmode:
27271 : : /* These suffer from normalization upon load when not using SSE. */
27272 : 55630 : return !(ix86_fpmath & FPMATH_387);
27273 : : default:
27274 : : return true;
27275 : : }
27276 : :
27277 : : return true;
27278 : : }
27279 : :
27280 : : /* Implement TARGET_REDZONE_CLOBBER. */
27281 : : static rtx
27282 : 2 : ix86_redzone_clobber ()
27283 : : {
27284 : 2 : cfun->machine->asm_redzone_clobber_seen = true;
27285 : 2 : if (ix86_using_red_zone ())
27286 : : {
27287 : 2 : rtx base = plus_constant (Pmode, stack_pointer_rtx, -RED_ZONE_SIZE);
27288 : 2 : rtx mem = gen_rtx_MEM (BLKmode, base);
27289 : 2 : set_mem_size (mem, RED_ZONE_SIZE);
27290 : 2 : return mem;
27291 : : }
27292 : : return NULL_RTX;
27293 : : }
27294 : :
27295 : : /* Target-specific selftests. */
27296 : :
27297 : : #if CHECKING_P
27298 : :
27299 : : namespace selftest {
27300 : :
27301 : : /* Verify that hard regs are dumped as expected (in compact mode). */
27302 : :
27303 : : static void
27304 : 4 : ix86_test_dumping_hard_regs ()
27305 : : {
27306 : 4 : ASSERT_RTL_DUMP_EQ ("(reg:SI ax)", gen_raw_REG (SImode, 0));
27307 : 4 : ASSERT_RTL_DUMP_EQ ("(reg:SI dx)", gen_raw_REG (SImode, 1));
27308 : 4 : }
27309 : :
27310 : : /* Test dumping an insn with repeated references to the same SCRATCH,
27311 : : to verify the rtx_reuse code. */
27312 : :
27313 : : static void
27314 : 4 : ix86_test_dumping_memory_blockage ()
27315 : : {
27316 : 4 : set_new_first_and_last_insn (NULL, NULL);
27317 : :
27318 : 4 : rtx pat = gen_memory_blockage ();
27319 : 4 : rtx_reuse_manager r;
27320 : 4 : r.preprocess (pat);
27321 : :
27322 : : /* Verify that the repeated references to the SCRATCH show use
27323 : : reuse IDS. The first should be prefixed with a reuse ID,
27324 : : and the second should be dumped as a "reuse_rtx" of that ID.
27325 : : The expected string assumes Pmode == DImode. */
27326 : 4 : if (Pmode == DImode)
27327 : 4 : ASSERT_RTL_DUMP_EQ_WITH_REUSE
27328 : : ("(cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0 A8])\n"
27329 : : " (unspec:BLK [\n"
27330 : : " (mem/v:BLK (reuse_rtx 0) [0 A8])\n"
27331 : : " ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r);
27332 : 4 : }
27333 : :
27334 : : /* Verify loading an RTL dump; specifically a dump of copying
27335 : : a param on x86_64 from a hard reg into the frame.
27336 : : This test is target-specific since the dump contains target-specific
27337 : : hard reg names. */
27338 : :
27339 : : static void
27340 : 4 : ix86_test_loading_dump_fragment_1 ()
27341 : : {
27342 : 4 : rtl_dump_test t (SELFTEST_LOCATION,
27343 : 4 : locate_file ("x86_64/copy-hard-reg-into-frame.rtl"));
27344 : :
27345 : 4 : rtx_insn *insn = get_insn_by_uid (1);
27346 : :
27347 : : /* The block structure and indentation here is purely for
27348 : : readability; it mirrors the structure of the rtx. */
27349 : 4 : tree mem_expr;
27350 : 4 : {
27351 : 4 : rtx pat = PATTERN (insn);
27352 : 4 : ASSERT_EQ (SET, GET_CODE (pat));
27353 : 4 : {
27354 : 4 : rtx dest = SET_DEST (pat);
27355 : 4 : ASSERT_EQ (MEM, GET_CODE (dest));
27356 : : /* Verify the "/c" was parsed. */
27357 : 4 : ASSERT_TRUE (RTX_FLAG (dest, call));
27358 : 4 : ASSERT_EQ (SImode, GET_MODE (dest));
27359 : 4 : {
27360 : 4 : rtx addr = XEXP (dest, 0);
27361 : 4 : ASSERT_EQ (PLUS, GET_CODE (addr));
27362 : 4 : ASSERT_EQ (DImode, GET_MODE (addr));
27363 : 4 : {
27364 : 4 : rtx lhs = XEXP (addr, 0);
27365 : : /* Verify that the "frame" REG was consolidated. */
27366 : 4 : ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs);
27367 : : }
27368 : 4 : {
27369 : 4 : rtx rhs = XEXP (addr, 1);
27370 : 4 : ASSERT_EQ (CONST_INT, GET_CODE (rhs));
27371 : 4 : ASSERT_EQ (-4, INTVAL (rhs));
27372 : : }
27373 : : }
27374 : : /* Verify the "[1 i+0 S4 A32]" was parsed. */
27375 : 4 : ASSERT_EQ (1, MEM_ALIAS_SET (dest));
27376 : : /* "i" should have been handled by synthesizing a global int
27377 : : variable named "i". */
27378 : 4 : mem_expr = MEM_EXPR (dest);
27379 : 4 : ASSERT_NE (mem_expr, NULL);
27380 : 4 : ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr));
27381 : 4 : ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr));
27382 : 4 : ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr)));
27383 : 4 : ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr)));
27384 : : /* "+0". */
27385 : 4 : ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest));
27386 : 4 : ASSERT_EQ (0, MEM_OFFSET (dest));
27387 : : /* "S4". */
27388 : 4 : ASSERT_EQ (4, MEM_SIZE (dest));
27389 : : /* "A32. */
27390 : 4 : ASSERT_EQ (32, MEM_ALIGN (dest));
27391 : : }
27392 : 4 : {
27393 : 4 : rtx src = SET_SRC (pat);
27394 : 4 : ASSERT_EQ (REG, GET_CODE (src));
27395 : 4 : ASSERT_EQ (SImode, GET_MODE (src));
27396 : 4 : ASSERT_EQ (5, REGNO (src));
27397 : 4 : tree reg_expr = REG_EXPR (src);
27398 : : /* "i" here should point to the same var as for the MEM_EXPR. */
27399 : 4 : ASSERT_EQ (reg_expr, mem_expr);
27400 : : }
27401 : : }
27402 : 4 : }
27403 : :
27404 : : /* Verify that the RTL loader copes with a call_insn dump.
27405 : : This test is target-specific since the dump contains a target-specific
27406 : : hard reg name. */
27407 : :
27408 : : static void
27409 : 4 : ix86_test_loading_call_insn ()
27410 : : {
27411 : : /* The test dump includes register "xmm0", where requires TARGET_SSE
27412 : : to exist. */
27413 : 4 : if (!TARGET_SSE)
27414 : 0 : return;
27415 : :
27416 : 4 : rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl"));
27417 : :
27418 : 4 : rtx_insn *insn = get_insns ();
27419 : 4 : ASSERT_EQ (CALL_INSN, GET_CODE (insn));
27420 : :
27421 : : /* "/j". */
27422 : 4 : ASSERT_TRUE (RTX_FLAG (insn, jump));
27423 : :
27424 : 4 : rtx pat = PATTERN (insn);
27425 : 4 : ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat)));
27426 : :
27427 : : /* Verify REG_NOTES. */
27428 : 4 : {
27429 : : /* "(expr_list:REG_CALL_DECL". */
27430 : 4 : ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn)));
27431 : 4 : rtx_expr_list *note0 = as_a <rtx_expr_list *> (REG_NOTES (insn));
27432 : 4 : ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0));
27433 : :
27434 : : /* "(expr_list:REG_EH_REGION (const_int 0 [0])". */
27435 : 4 : rtx_expr_list *note1 = note0->next ();
27436 : 4 : ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1));
27437 : :
27438 : 4 : ASSERT_EQ (NULL, note1->next ());
27439 : : }
27440 : :
27441 : : /* Verify CALL_INSN_FUNCTION_USAGE. */
27442 : 4 : {
27443 : : /* "(expr_list:DF (use (reg:DF 21 xmm0))". */
27444 : 4 : rtx_expr_list *usage
27445 : 4 : = as_a <rtx_expr_list *> (CALL_INSN_FUNCTION_USAGE (insn));
27446 : 4 : ASSERT_EQ (EXPR_LIST, GET_CODE (usage));
27447 : 4 : ASSERT_EQ (DFmode, GET_MODE (usage));
27448 : 4 : ASSERT_EQ (USE, GET_CODE (usage->element ()));
27449 : 4 : ASSERT_EQ (NULL, usage->next ());
27450 : : }
27451 : 4 : }
27452 : :
27453 : : /* Verify that the RTL loader copes a dump from print_rtx_function.
27454 : : This test is target-specific since the dump contains target-specific
27455 : : hard reg names. */
27456 : :
27457 : : static void
27458 : 4 : ix86_test_loading_full_dump ()
27459 : : {
27460 : 4 : rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl"));
27461 : :
27462 : 4 : ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
27463 : :
27464 : 4 : rtx_insn *insn_1 = get_insn_by_uid (1);
27465 : 4 : ASSERT_EQ (NOTE, GET_CODE (insn_1));
27466 : :
27467 : 4 : rtx_insn *insn_7 = get_insn_by_uid (7);
27468 : 4 : ASSERT_EQ (INSN, GET_CODE (insn_7));
27469 : 4 : ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7)));
27470 : :
27471 : 4 : rtx_insn *insn_15 = get_insn_by_uid (15);
27472 : 4 : ASSERT_EQ (INSN, GET_CODE (insn_15));
27473 : 4 : ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15)));
27474 : :
27475 : : /* Verify crtl->return_rtx. */
27476 : 4 : ASSERT_EQ (REG, GET_CODE (crtl->return_rtx));
27477 : 4 : ASSERT_EQ (0, REGNO (crtl->return_rtx));
27478 : 4 : ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
27479 : 4 : }
27480 : :
27481 : : /* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns.
27482 : : In particular, verify that it correctly loads the 2nd operand.
27483 : : This test is target-specific since these are machine-specific
27484 : : operands (and enums). */
27485 : :
27486 : : static void
27487 : 4 : ix86_test_loading_unspec ()
27488 : : {
27489 : 4 : rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl"));
27490 : :
27491 : 4 : ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
27492 : :
27493 : 4 : ASSERT_TRUE (cfun);
27494 : :
27495 : : /* Test of an UNSPEC. */
27496 : 4 : rtx_insn *insn = get_insns ();
27497 : 4 : ASSERT_EQ (INSN, GET_CODE (insn));
27498 : 4 : rtx set = single_set (insn);
27499 : 4 : ASSERT_NE (NULL, set);
27500 : 4 : rtx dst = SET_DEST (set);
27501 : 4 : ASSERT_EQ (MEM, GET_CODE (dst));
27502 : 4 : rtx src = SET_SRC (set);
27503 : 4 : ASSERT_EQ (UNSPEC, GET_CODE (src));
27504 : 4 : ASSERT_EQ (BLKmode, GET_MODE (src));
27505 : 4 : ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1));
27506 : :
27507 : 4 : rtx v0 = XVECEXP (src, 0, 0);
27508 : :
27509 : : /* Verify that the two uses of the first SCRATCH have pointer
27510 : : equality. */
27511 : 4 : rtx scratch_a = XEXP (dst, 0);
27512 : 4 : ASSERT_EQ (SCRATCH, GET_CODE (scratch_a));
27513 : :
27514 : 4 : rtx scratch_b = XEXP (v0, 0);
27515 : 4 : ASSERT_EQ (SCRATCH, GET_CODE (scratch_b));
27516 : :
27517 : 4 : ASSERT_EQ (scratch_a, scratch_b);
27518 : :
27519 : : /* Verify that the two mems are thus treated as equal. */
27520 : 4 : ASSERT_TRUE (rtx_equal_p (dst, v0));
27521 : :
27522 : : /* Verify that the insn is recognized. */
27523 : 4 : ASSERT_NE(-1, recog_memoized (insn));
27524 : :
27525 : : /* Test of an UNSPEC_VOLATILE, which has its own enum values. */
27526 : 4 : insn = NEXT_INSN (insn);
27527 : 4 : ASSERT_EQ (INSN, GET_CODE (insn));
27528 : :
27529 : 4 : set = single_set (insn);
27530 : 4 : ASSERT_NE (NULL, set);
27531 : :
27532 : 4 : src = SET_SRC (set);
27533 : 4 : ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src));
27534 : 4 : ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1));
27535 : 4 : }
27536 : :
27537 : : /* Run all target-specific selftests. */
27538 : :
27539 : : static void
27540 : 4 : ix86_run_selftests (void)
27541 : : {
27542 : 4 : ix86_test_dumping_hard_regs ();
27543 : 4 : ix86_test_dumping_memory_blockage ();
27544 : :
27545 : : /* Various tests of loading RTL dumps, here because they contain
27546 : : ix86-isms (e.g. names of hard regs). */
27547 : 4 : ix86_test_loading_dump_fragment_1 ();
27548 : 4 : ix86_test_loading_call_insn ();
27549 : 4 : ix86_test_loading_full_dump ();
27550 : 4 : ix86_test_loading_unspec ();
27551 : 4 : }
27552 : :
27553 : : } // namespace selftest
27554 : :
27555 : : #endif /* CHECKING_P */
27556 : :
27557 : : static const scoped_attribute_specs *const ix86_attribute_table[] =
27558 : : {
27559 : : &ix86_gnu_attribute_table
27560 : : };
27561 : :
27562 : : /* Initialize the GCC target structure. */
27563 : : #undef TARGET_RETURN_IN_MEMORY
27564 : : #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
27565 : :
27566 : : #undef TARGET_LEGITIMIZE_ADDRESS
27567 : : #define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
27568 : :
27569 : : #undef TARGET_ATTRIBUTE_TABLE
27570 : : #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
27571 : : #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
27572 : : #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
27573 : : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
27574 : : # undef TARGET_MERGE_DECL_ATTRIBUTES
27575 : : # define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
27576 : : #endif
27577 : :
27578 : : #undef TARGET_INVALID_CONVERSION
27579 : : #define TARGET_INVALID_CONVERSION ix86_invalid_conversion
27580 : :
27581 : : #undef TARGET_INVALID_UNARY_OP
27582 : : #define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op
27583 : :
27584 : : #undef TARGET_INVALID_BINARY_OP
27585 : : #define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op
27586 : :
27587 : : #undef TARGET_COMP_TYPE_ATTRIBUTES
27588 : : #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
27589 : :
27590 : : #undef TARGET_INIT_BUILTINS
27591 : : #define TARGET_INIT_BUILTINS ix86_init_builtins
27592 : : #undef TARGET_BUILTIN_DECL
27593 : : #define TARGET_BUILTIN_DECL ix86_builtin_decl
27594 : : #undef TARGET_EXPAND_BUILTIN
27595 : : #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
27596 : :
27597 : : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
27598 : : #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
27599 : : ix86_builtin_vectorized_function
27600 : :
27601 : : #undef TARGET_VECTORIZE_BUILTIN_GATHER
27602 : : #define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
27603 : :
27604 : : #undef TARGET_VECTORIZE_BUILTIN_SCATTER
27605 : : #define TARGET_VECTORIZE_BUILTIN_SCATTER ix86_vectorize_builtin_scatter
27606 : :
27607 : : #undef TARGET_BUILTIN_RECIPROCAL
27608 : : #define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
27609 : :
27610 : : #undef TARGET_ASM_FUNCTION_EPILOGUE
27611 : : #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
27612 : :
27613 : : #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
27614 : : #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
27615 : : ix86_print_patchable_function_entry
27616 : :
27617 : : #undef TARGET_ENCODE_SECTION_INFO
27618 : : #ifndef SUBTARGET_ENCODE_SECTION_INFO
27619 : : #define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
27620 : : #else
27621 : : #define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
27622 : : #endif
27623 : :
27624 : : #undef TARGET_ASM_OPEN_PAREN
27625 : : #define TARGET_ASM_OPEN_PAREN ""
27626 : : #undef TARGET_ASM_CLOSE_PAREN
27627 : : #define TARGET_ASM_CLOSE_PAREN ""
27628 : :
27629 : : #undef TARGET_ASM_BYTE_OP
27630 : : #define TARGET_ASM_BYTE_OP ASM_BYTE
27631 : :
27632 : : #undef TARGET_ASM_ALIGNED_HI_OP
27633 : : #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
27634 : : #undef TARGET_ASM_ALIGNED_SI_OP
27635 : : #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
27636 : : #ifdef ASM_QUAD
27637 : : #undef TARGET_ASM_ALIGNED_DI_OP
27638 : : #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
27639 : : #endif
27640 : :
27641 : : #undef TARGET_PROFILE_BEFORE_PROLOGUE
27642 : : #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
27643 : :
27644 : : #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
27645 : : #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
27646 : :
27647 : : #undef TARGET_ASM_UNALIGNED_HI_OP
27648 : : #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
27649 : : #undef TARGET_ASM_UNALIGNED_SI_OP
27650 : : #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
27651 : : #undef TARGET_ASM_UNALIGNED_DI_OP
27652 : : #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
27653 : :
27654 : : #undef TARGET_PRINT_OPERAND
27655 : : #define TARGET_PRINT_OPERAND ix86_print_operand
27656 : : #undef TARGET_PRINT_OPERAND_ADDRESS
27657 : : #define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
27658 : : #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
27659 : : #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
27660 : : #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
27661 : : #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
27662 : :
27663 : : #undef TARGET_SCHED_INIT_GLOBAL
27664 : : #define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
27665 : : #undef TARGET_SCHED_ADJUST_COST
27666 : : #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
27667 : : #undef TARGET_SCHED_ISSUE_RATE
27668 : : #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
27669 : : #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
27670 : : #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
27671 : : ia32_multipass_dfa_lookahead
27672 : : #undef TARGET_SCHED_MACRO_FUSION_P
27673 : : #define TARGET_SCHED_MACRO_FUSION_P ix86_macro_fusion_p
27674 : : #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
27675 : : #define TARGET_SCHED_MACRO_FUSION_PAIR_P ix86_macro_fusion_pair_p
27676 : :
27677 : : #undef TARGET_FUNCTION_OK_FOR_SIBCALL
27678 : : #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
27679 : :
27680 : : #undef TARGET_MEMMODEL_CHECK
27681 : : #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
27682 : :
27683 : : #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
27684 : : #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
27685 : :
27686 : : #ifdef HAVE_AS_TLS
27687 : : #undef TARGET_HAVE_TLS
27688 : : #define TARGET_HAVE_TLS true
27689 : : #endif
27690 : : #undef TARGET_CANNOT_FORCE_CONST_MEM
27691 : : #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
27692 : : #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
27693 : : #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
27694 : :
27695 : : #undef TARGET_DELEGITIMIZE_ADDRESS
27696 : : #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
27697 : :
27698 : : #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
27699 : : #define TARGET_CONST_NOT_OK_FOR_DEBUG_P ix86_const_not_ok_for_debug_p
27700 : :
27701 : : #undef TARGET_MS_BITFIELD_LAYOUT_P
27702 : : #define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
27703 : :
27704 : : #if TARGET_MACHO
27705 : : #undef TARGET_BINDS_LOCAL_P
27706 : : #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
27707 : : #else
27708 : : #undef TARGET_BINDS_LOCAL_P
27709 : : #define TARGET_BINDS_LOCAL_P ix86_binds_local_p
27710 : : #endif
27711 : : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
27712 : : #undef TARGET_BINDS_LOCAL_P
27713 : : #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
27714 : : #endif
27715 : :
27716 : : #undef TARGET_ASM_OUTPUT_MI_THUNK
27717 : : #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
27718 : : #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
27719 : : #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
27720 : :
27721 : : #undef TARGET_ASM_FILE_START
27722 : : #define TARGET_ASM_FILE_START x86_file_start
27723 : :
27724 : : #undef TARGET_OPTION_OVERRIDE
27725 : : #define TARGET_OPTION_OVERRIDE ix86_option_override
27726 : :
27727 : : #undef TARGET_REGISTER_MOVE_COST
27728 : : #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
27729 : : #undef TARGET_MEMORY_MOVE_COST
27730 : : #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
27731 : : #undef TARGET_RTX_COSTS
27732 : : #define TARGET_RTX_COSTS ix86_rtx_costs
27733 : : #undef TARGET_INSN_COST
27734 : : #define TARGET_INSN_COST ix86_insn_cost
27735 : : #undef TARGET_ADDRESS_COST
27736 : : #define TARGET_ADDRESS_COST ix86_address_cost
27737 : :
27738 : : #undef TARGET_OVERLAP_OP_BY_PIECES_P
27739 : : #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true
27740 : :
27741 : : #undef TARGET_FLAGS_REGNUM
27742 : : #define TARGET_FLAGS_REGNUM FLAGS_REG
27743 : : #undef TARGET_FIXED_CONDITION_CODE_REGS
27744 : : #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
27745 : : #undef TARGET_CC_MODES_COMPATIBLE
27746 : : #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
27747 : :
27748 : : #undef TARGET_MACHINE_DEPENDENT_REORG
27749 : : #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
27750 : :
27751 : : #undef TARGET_BUILD_BUILTIN_VA_LIST
27752 : : #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
27753 : :
27754 : : #undef TARGET_FOLD_BUILTIN
27755 : : #define TARGET_FOLD_BUILTIN ix86_fold_builtin
27756 : :
27757 : : #undef TARGET_GIMPLE_FOLD_BUILTIN
27758 : : #define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
27759 : :
27760 : : #undef TARGET_COMPARE_VERSION_PRIORITY
27761 : : #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
27762 : :
27763 : : #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
27764 : : #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
27765 : : ix86_generate_version_dispatcher_body
27766 : :
27767 : : #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
27768 : : #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
27769 : : ix86_get_function_versions_dispatcher
27770 : :
27771 : : #undef TARGET_ENUM_VA_LIST_P
27772 : : #define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
27773 : :
27774 : : #undef TARGET_FN_ABI_VA_LIST
27775 : : #define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
27776 : :
27777 : : #undef TARGET_CANONICAL_VA_LIST_TYPE
27778 : : #define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
27779 : :
27780 : : #undef TARGET_EXPAND_BUILTIN_VA_START
27781 : : #define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
27782 : :
27783 : : #undef TARGET_MD_ASM_ADJUST
27784 : : #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
27785 : :
27786 : : #undef TARGET_C_EXCESS_PRECISION
27787 : : #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
27788 : : #undef TARGET_C_BITINT_TYPE_INFO
27789 : : #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
27790 : : #undef TARGET_C_MODE_FOR_FLOATING_TYPE
27791 : : #define TARGET_C_MODE_FOR_FLOATING_TYPE ix86_c_mode_for_floating_type
27792 : : #undef TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE
27793 : : #define TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE ix86_cxx_adjust_cdtor_callabi_fntype
27794 : : #undef TARGET_PROMOTE_PROTOTYPES
27795 : : #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
27796 : : #undef TARGET_PUSH_ARGUMENT
27797 : : #define TARGET_PUSH_ARGUMENT ix86_push_argument
27798 : : #undef TARGET_SETUP_INCOMING_VARARGS
27799 : : #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
27800 : : #undef TARGET_MUST_PASS_IN_STACK
27801 : : #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
27802 : : #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
27803 : : #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args
27804 : : #undef TARGET_FUNCTION_ARG_ADVANCE
27805 : : #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
27806 : : #undef TARGET_FUNCTION_ARG
27807 : : #define TARGET_FUNCTION_ARG ix86_function_arg
27808 : : #undef TARGET_INIT_PIC_REG
27809 : : #define TARGET_INIT_PIC_REG ix86_init_pic_reg
27810 : : #undef TARGET_USE_PSEUDO_PIC_REG
27811 : : #define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
27812 : : #undef TARGET_FUNCTION_ARG_BOUNDARY
27813 : : #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
27814 : : #undef TARGET_PASS_BY_REFERENCE
27815 : : #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
27816 : : #undef TARGET_INTERNAL_ARG_POINTER
27817 : : #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
27818 : : #undef TARGET_UPDATE_STACK_BOUNDARY
27819 : : #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
27820 : : #undef TARGET_GET_DRAP_RTX
27821 : : #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
27822 : : #undef TARGET_STRICT_ARGUMENT_NAMING
27823 : : #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
27824 : : #undef TARGET_STATIC_CHAIN
27825 : : #define TARGET_STATIC_CHAIN ix86_static_chain
27826 : : #undef TARGET_TRAMPOLINE_INIT
27827 : : #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
27828 : : #undef TARGET_RETURN_POPS_ARGS
27829 : : #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
27830 : :
27831 : : #undef TARGET_WARN_FUNC_RETURN
27832 : : #define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
27833 : :
27834 : : #undef TARGET_LEGITIMATE_COMBINED_INSN
27835 : : #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
27836 : :
27837 : : #undef TARGET_ASAN_SHADOW_OFFSET
27838 : : #define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
27839 : :
27840 : : #undef TARGET_GIMPLIFY_VA_ARG_EXPR
27841 : : #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
27842 : :
27843 : : #undef TARGET_SCALAR_MODE_SUPPORTED_P
27844 : : #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
27845 : :
27846 : : #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
27847 : : #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
27848 : : ix86_libgcc_floating_mode_supported_p
27849 : :
27850 : : #undef TARGET_VECTOR_MODE_SUPPORTED_P
27851 : : #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
27852 : :
27853 : : #undef TARGET_C_MODE_FOR_SUFFIX
27854 : : #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
27855 : :
27856 : : #ifdef HAVE_AS_TLS
27857 : : #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
27858 : : #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
27859 : : #endif
27860 : :
27861 : : #ifdef SUBTARGET_INSERT_ATTRIBUTES
27862 : : #undef TARGET_INSERT_ATTRIBUTES
27863 : : #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
27864 : : #endif
27865 : :
27866 : : #undef TARGET_MANGLE_TYPE
27867 : : #define TARGET_MANGLE_TYPE ix86_mangle_type
27868 : :
27869 : : #undef TARGET_EMIT_SUPPORT_TINFOS
27870 : : #define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos
27871 : :
27872 : : #undef TARGET_STACK_PROTECT_GUARD
27873 : : #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard
27874 : :
27875 : : #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
27876 : : #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \
27877 : : ix86_stack_protect_runtime_enabled_p
27878 : :
27879 : : #if !TARGET_MACHO
27880 : : #undef TARGET_STACK_PROTECT_FAIL
27881 : : #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
27882 : : #endif
27883 : :
27884 : : #undef TARGET_FUNCTION_VALUE
27885 : : #define TARGET_FUNCTION_VALUE ix86_function_value
27886 : :
27887 : : #undef TARGET_FUNCTION_VALUE_REGNO_P
27888 : : #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
27889 : :
27890 : : #undef TARGET_ZERO_CALL_USED_REGS
27891 : : #define TARGET_ZERO_CALL_USED_REGS ix86_zero_call_used_regs
27892 : :
27893 : : #undef TARGET_PROMOTE_FUNCTION_MODE
27894 : : #define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
27895 : :
27896 : : #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
27897 : : #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
27898 : :
27899 : : #undef TARGET_MEMBER_TYPE_FORCES_BLK
27900 : : #define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
27901 : :
27902 : : #undef TARGET_INSTANTIATE_DECLS
27903 : : #define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
27904 : :
27905 : : #undef TARGET_SECONDARY_RELOAD
27906 : : #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
27907 : : #undef TARGET_SECONDARY_MEMORY_NEEDED
27908 : : #define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed
27909 : : #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
27910 : : #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
27911 : :
27912 : : #undef TARGET_CLASS_MAX_NREGS
27913 : : #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
27914 : :
27915 : : #undef TARGET_PREFERRED_RELOAD_CLASS
27916 : : #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
27917 : : #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
27918 : : #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
27919 : : /* When this hook returns true for MODE, the compiler allows
27920 : : registers explicitly used in the rtl to be used as spill registers
27921 : : but prevents the compiler from extending the lifetime of these
27922 : : registers. */
27923 : : #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
27924 : : #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
27925 : : #undef TARGET_CLASS_LIKELY_SPILLED_P
27926 : : #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
27927 : : #undef TARGET_CALLEE_SAVE_COST
27928 : : #define TARGET_CALLEE_SAVE_COST ix86_callee_save_cost
27929 : :
27930 : : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
27931 : : #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
27932 : : ix86_builtin_vectorization_cost
27933 : : #undef TARGET_VECTORIZE_VEC_PERM_CONST
27934 : : #define TARGET_VECTORIZE_VEC_PERM_CONST ix86_vectorize_vec_perm_const
27935 : : #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
27936 : : #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
27937 : : ix86_preferred_simd_mode
27938 : : #undef TARGET_VECTORIZE_SPLIT_REDUCTION
27939 : : #define TARGET_VECTORIZE_SPLIT_REDUCTION \
27940 : : ix86_split_reduction
27941 : : #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
27942 : : #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
27943 : : ix86_autovectorize_vector_modes
27944 : : #undef TARGET_VECTORIZE_GET_MASK_MODE
27945 : : #define TARGET_VECTORIZE_GET_MASK_MODE ix86_get_mask_mode
27946 : : #undef TARGET_VECTORIZE_CREATE_COSTS
27947 : : #define TARGET_VECTORIZE_CREATE_COSTS ix86_vectorize_create_costs
27948 : :
27949 : : #undef TARGET_SET_CURRENT_FUNCTION
27950 : : #define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
27951 : :
27952 : : #undef TARGET_OPTION_VALID_ATTRIBUTE_P
27953 : : #define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
27954 : :
27955 : : #undef TARGET_OPTION_SAVE
27956 : : #define TARGET_OPTION_SAVE ix86_function_specific_save
27957 : :
27958 : : #undef TARGET_OPTION_RESTORE
27959 : : #define TARGET_OPTION_RESTORE ix86_function_specific_restore
27960 : :
27961 : : #undef TARGET_OPTION_POST_STREAM_IN
27962 : : #define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
27963 : :
27964 : : #undef TARGET_OPTION_PRINT
27965 : : #define TARGET_OPTION_PRINT ix86_function_specific_print
27966 : :
27967 : : #undef TARGET_OPTION_FUNCTION_VERSIONS
27968 : : #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions
27969 : :
27970 : : #undef TARGET_CAN_INLINE_P
27971 : : #define TARGET_CAN_INLINE_P ix86_can_inline_p
27972 : :
27973 : : #undef TARGET_LEGITIMATE_ADDRESS_P
27974 : : #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
27975 : :
27976 : : #undef TARGET_REGISTER_PRIORITY
27977 : : #define TARGET_REGISTER_PRIORITY ix86_register_priority
27978 : :
27979 : : #undef TARGET_REGISTER_USAGE_LEVELING_P
27980 : : #define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
27981 : :
27982 : : #undef TARGET_LEGITIMATE_CONSTANT_P
27983 : : #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
27984 : :
27985 : : #undef TARGET_COMPUTE_FRAME_LAYOUT
27986 : : #define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
27987 : :
27988 : : #undef TARGET_FRAME_POINTER_REQUIRED
27989 : : #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
27990 : :
27991 : : #undef TARGET_CAN_ELIMINATE
27992 : : #define TARGET_CAN_ELIMINATE ix86_can_eliminate
27993 : :
27994 : : #undef TARGET_EXTRA_LIVE_ON_ENTRY
27995 : : #define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
27996 : :
27997 : : #undef TARGET_ASM_CODE_END
27998 : : #define TARGET_ASM_CODE_END ix86_code_end
27999 : :
28000 : : #undef TARGET_CONDITIONAL_REGISTER_USAGE
28001 : : #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
28002 : :
28003 : : #undef TARGET_CANONICALIZE_COMPARISON
28004 : : #define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison
28005 : :
28006 : : #undef TARGET_LOOP_UNROLL_ADJUST
28007 : : #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust
28008 : :
28009 : : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657. */
28010 : : #undef TARGET_SPILL_CLASS
28011 : : #define TARGET_SPILL_CLASS ix86_spill_class
28012 : :
28013 : : #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
28014 : : #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
28015 : : ix86_simd_clone_compute_vecsize_and_simdlen
28016 : :
28017 : : #undef TARGET_SIMD_CLONE_ADJUST
28018 : : #define TARGET_SIMD_CLONE_ADJUST ix86_simd_clone_adjust
28019 : :
28020 : : #undef TARGET_SIMD_CLONE_USABLE
28021 : : #define TARGET_SIMD_CLONE_USABLE ix86_simd_clone_usable
28022 : :
28023 : : #undef TARGET_OMP_DEVICE_KIND_ARCH_ISA
28024 : : #define TARGET_OMP_DEVICE_KIND_ARCH_ISA ix86_omp_device_kind_arch_isa
28025 : :
28026 : : #undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
28027 : : #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
28028 : : ix86_float_exceptions_rounding_supported_p
28029 : :
28030 : : #undef TARGET_MODE_EMIT
28031 : : #define TARGET_MODE_EMIT ix86_emit_mode_set
28032 : :
28033 : : #undef TARGET_MODE_NEEDED
28034 : : #define TARGET_MODE_NEEDED ix86_mode_needed
28035 : :
28036 : : #undef TARGET_MODE_AFTER
28037 : : #define TARGET_MODE_AFTER ix86_mode_after
28038 : :
28039 : : #undef TARGET_MODE_ENTRY
28040 : : #define TARGET_MODE_ENTRY ix86_mode_entry
28041 : :
28042 : : #undef TARGET_MODE_EXIT
28043 : : #define TARGET_MODE_EXIT ix86_mode_exit
28044 : :
28045 : : #undef TARGET_MODE_PRIORITY
28046 : : #define TARGET_MODE_PRIORITY ix86_mode_priority
28047 : :
28048 : : #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
28049 : : #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
28050 : :
28051 : : #undef TARGET_OFFLOAD_OPTIONS
28052 : : #define TARGET_OFFLOAD_OPTIONS \
28053 : : ix86_offload_options
28054 : :
28055 : : #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
28056 : : #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
28057 : :
28058 : : #undef TARGET_OPTAB_SUPPORTED_P
28059 : : #define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
28060 : :
28061 : : #undef TARGET_HARD_REGNO_SCRATCH_OK
28062 : : #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok
28063 : :
28064 : : #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
28065 : : #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST
28066 : :
28067 : : #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
28068 : : #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid
28069 : :
28070 : : #undef TARGET_INIT_LIBFUNCS
28071 : : #define TARGET_INIT_LIBFUNCS ix86_init_libfuncs
28072 : :
28073 : : #undef TARGET_EXPAND_DIVMOD_LIBFUNC
28074 : : #define TARGET_EXPAND_DIVMOD_LIBFUNC ix86_expand_divmod_libfunc
28075 : :
28076 : : #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
28077 : : #define TARGET_MAX_NOCE_IFCVT_SEQ_COST ix86_max_noce_ifcvt_seq_cost
28078 : :
28079 : : #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
28080 : : #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
28081 : :
28082 : : #undef TARGET_HARD_REGNO_NREGS
28083 : : #define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
28084 : : #undef TARGET_HARD_REGNO_MODE_OK
28085 : : #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
28086 : :
28087 : : #undef TARGET_MODES_TIEABLE_P
28088 : : #define TARGET_MODES_TIEABLE_P ix86_modes_tieable_p
28089 : :
28090 : : #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
28091 : : #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
28092 : : ix86_hard_regno_call_part_clobbered
28093 : :
28094 : : #undef TARGET_INSN_CALLEE_ABI
28095 : : #define TARGET_INSN_CALLEE_ABI ix86_insn_callee_abi
28096 : :
28097 : : #undef TARGET_CAN_CHANGE_MODE_CLASS
28098 : : #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
28099 : :
28100 : : #undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT
28101 : : #define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment
28102 : :
28103 : : #undef TARGET_STATIC_RTX_ALIGNMENT
28104 : : #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
28105 : : #undef TARGET_CONSTANT_ALIGNMENT
28106 : : #define TARGET_CONSTANT_ALIGNMENT ix86_constant_alignment
28107 : :
28108 : : #undef TARGET_EMPTY_RECORD_P
28109 : : #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
28110 : :
28111 : : #undef TARGET_WARN_PARAMETER_PASSING_ABI
28112 : : #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
28113 : :
28114 : : #undef TARGET_GET_MULTILIB_ABI_NAME
28115 : : #define TARGET_GET_MULTILIB_ABI_NAME \
28116 : : ix86_get_multilib_abi_name
28117 : :
28118 : : #undef TARGET_IFUNC_REF_LOCAL_OK
28119 : : #define TARGET_IFUNC_REF_LOCAL_OK ix86_ifunc_ref_local_ok
28120 : :
28121 : : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
28122 : : # undef TARGET_ASM_RELOC_RW_MASK
28123 : : # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
28124 : : #endif
28125 : :
28126 : : #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
28127 : : #define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
28128 : :
28129 : : #undef TARGET_MEMTAG_ADD_TAG
28130 : : #define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
28131 : :
28132 : : #undef TARGET_MEMTAG_SET_TAG
28133 : : #define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
28134 : :
28135 : : #undef TARGET_MEMTAG_EXTRACT_TAG
28136 : : #define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
28137 : :
28138 : : #undef TARGET_MEMTAG_UNTAGGED_POINTER
28139 : : #define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
28140 : :
28141 : : #undef TARGET_MEMTAG_TAG_SIZE
28142 : : #define TARGET_MEMTAG_TAG_SIZE ix86_memtag_tag_size
28143 : :
28144 : : #undef TARGET_GEN_CCMP_FIRST
28145 : : #define TARGET_GEN_CCMP_FIRST ix86_gen_ccmp_first
28146 : :
28147 : : #undef TARGET_GEN_CCMP_NEXT
28148 : : #define TARGET_GEN_CCMP_NEXT ix86_gen_ccmp_next
28149 : :
28150 : : #undef TARGET_HAVE_CCMP
28151 : : #define TARGET_HAVE_CCMP ix86_have_ccmp
28152 : :
28153 : : #undef TARGET_MODE_CAN_TRANSFER_BITS
28154 : : #define TARGET_MODE_CAN_TRANSFER_BITS ix86_mode_can_transfer_bits
28155 : :
28156 : : #undef TARGET_REDZONE_CLOBBER
28157 : : #define TARGET_REDZONE_CLOBBER ix86_redzone_clobber
28158 : :
28159 : : static bool
28160 : 80273 : ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
28161 : : {
28162 : : #ifdef OPTION_GLIBC
28163 : 80273 : if (OPTION_GLIBC)
28164 : 80273 : return (built_in_function)fcode == BUILT_IN_MEMPCPY;
28165 : : else
28166 : : return false;
28167 : : #else
28168 : : return false;
28169 : : #endif
28170 : : }
28171 : :
28172 : : #undef TARGET_LIBC_HAS_FAST_FUNCTION
28173 : : #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function
28174 : :
28175 : : static unsigned
28176 : 76967 : ix86_libm_function_max_error (unsigned cfn, machine_mode mode,
28177 : : bool boundary_p)
28178 : : {
28179 : : #ifdef OPTION_GLIBC
28180 : 76967 : bool glibc_p = OPTION_GLIBC;
28181 : : #else
28182 : : bool glibc_p = false;
28183 : : #endif
28184 : 76967 : if (glibc_p)
28185 : : {
28186 : : /* If __FAST_MATH__ is defined, glibc provides libmvec. */
28187 : 76967 : unsigned int libmvec_ret = 0;
28188 : 76967 : if (!flag_trapping_math
28189 : 8244 : && flag_unsafe_math_optimizations
28190 : 3362 : && flag_finite_math_only
28191 : 3336 : && !flag_signed_zeros
28192 : 3336 : && !flag_errno_math)
28193 : 3336 : switch (cfn)
28194 : : {
28195 : 1388 : CASE_CFN_COS:
28196 : 1388 : CASE_CFN_COS_FN:
28197 : 1388 : CASE_CFN_SIN:
28198 : 1388 : CASE_CFN_SIN_FN:
28199 : 1388 : if (!boundary_p)
28200 : : {
28201 : : /* With non-default rounding modes, libmvec provides
28202 : : complete garbage in results. E.g.
28203 : : _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD
28204 : : returns 0.00333309174f rather than 1.40129846e-45f. */
28205 : 583 : if (flag_rounding_math)
28206 : : return ~0U;
28207 : : /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
28208 : : claims libmvec maximum error is 4ulps.
28209 : : My own random testing indicates 2ulps for SFmode and
28210 : : 0.5ulps for DFmode, but let's go with the 4ulps. */
28211 : : libmvec_ret = 4;
28212 : : }
28213 : : break;
28214 : : default:
28215 : : break;
28216 : : }
28217 : 76967 : unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode,
28218 : : boundary_p);
28219 : 76967 : return MAX (ret, libmvec_ret);
28220 : : }
28221 : 0 : return default_libm_function_max_error (cfn, mode, boundary_p);
28222 : : }
28223 : :
28224 : : #undef TARGET_LIBM_FUNCTION_MAX_ERROR
28225 : : #define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error
28226 : :
28227 : : #if TARGET_MACHO
28228 : : static bool
28229 : : ix86_cannot_copy_insn_p (rtx_insn *insn)
28230 : : {
28231 : : if (TARGET_64BIT)
28232 : : return false;
28233 : :
28234 : : rtx set = single_set (insn);
28235 : : if (set)
28236 : : {
28237 : : rtx src = SET_SRC (set);
28238 : : if (GET_CODE (src) == UNSPEC
28239 : : && XINT (src, 1) == UNSPEC_SET_GOT)
28240 : : return true;
28241 : : }
28242 : : return false;
28243 : : }
28244 : :
28245 : : #undef TARGET_CANNOT_COPY_INSN_P
28246 : : #define TARGET_CANNOT_COPY_INSN_P ix86_cannot_copy_insn_p
28247 : :
28248 : : #endif
28249 : :
28250 : : #if CHECKING_P
28251 : : #undef TARGET_RUN_TARGET_SELFTESTS
28252 : : #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
28253 : : #endif /* #if CHECKING_P */
28254 : :
28255 : : #undef TARGET_DOCUMENTATION_NAME
28256 : : #define TARGET_DOCUMENTATION_NAME "x86"
28257 : :
28258 : : /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS. */
28259 : : sbitmap
28260 : 721058 : ix86_get_separate_components (void)
28261 : : {
28262 : 721058 : HOST_WIDE_INT offset, to_allocate;
28263 : 721058 : sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
28264 : 721058 : bitmap_clear (components);
28265 : 721058 : struct machine_function *m = cfun->machine;
28266 : :
28267 : 721058 : offset = m->frame.stack_pointer_offset;
28268 : 721058 : to_allocate = offset - m->frame.sse_reg_save_offset;
28269 : :
28270 : : /* Shrink wrap separate uses MOV, which means APX PPX cannot be used.
28271 : : Experiments show that APX PPX can speed up the prologue. If the function
28272 : : does not exit early during actual execution, then using APX PPX is faster.
28273 : : If the function always exits early during actual execution, then shrink
28274 : : wrap separate reduces the number of MOV (PUSH/POP) instructions actually
28275 : : executed, thus speeding up execution.
28276 : : foo:
28277 : : movl $1, %eax
28278 : : testq %rdi, %rdi
28279 : : jne.L60
28280 : : ret ---> early return.
28281 : : .L60:
28282 : : subq $88, %rsp ---> belong to prologue.
28283 : : xorl %eax, %eax
28284 : : movq %rbx, 40 (%rsp) ---> belong to prologue.
28285 : : movq 8 (%rdi), %rbx
28286 : : movq %rbp, 48 (%rsp) ---> belong to prologue.
28287 : : movq %rdi, %rbp
28288 : : testq %rbx, %rbx
28289 : : jne.L61
28290 : : movq 40 (%rsp), %rbx
28291 : : movq 48 (%rsp), %rbp
28292 : : addq $88, %rsp
28293 : : ret
28294 : : .L61:
28295 : : movq %r12, 56 (%rsp) ---> belong to prologue.
28296 : : movq %r13, 64 (%rsp) ---> belong to prologue.
28297 : : movq %r14, 72 (%rsp) ---> belong to prologue.
28298 : : ... ...
28299 : :
28300 : : Disable shrink wrap separate when PPX is enabled. */
28301 : 721058 : if ((TARGET_APX_PPX && !crtl->calls_eh_return)
28302 : 720603 : || cfun->machine->func_type != TYPE_NORMAL
28303 : : || TARGET_SEH
28304 : 720507 : || crtl->stack_realign_needed
28305 : 711243 : || m->call_ms2sysv)
28306 : : return components;
28307 : :
28308 : : /* Since shrink wrapping separate uses MOV instead of PUSH/POP.
28309 : : Disable shrink wrap separate when MOV is prohibited. */
28310 : 709321 : if (save_regs_using_push_pop (to_allocate))
28311 : : return components;
28312 : :
28313 : 32454675 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
28314 : 32105700 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
28315 : : {
28316 : : /* Skip registers with large offsets, where a pseudo may be needed. */
28317 : 614286 : if (IN_RANGE (offset, -0x8000, 0x7fff))
28318 : 613210 : bitmap_set_bit (components, regno);
28319 : 658553 : offset += UNITS_PER_WORD;
28320 : : }
28321 : :
28322 : : /* Don't mess with the following registers. */
28323 : 348975 : if (frame_pointer_needed)
28324 : 6306 : bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);
28325 : :
28326 : 348975 : if (crtl->drap_reg)
28327 : 128 : bitmap_clear_bit (components, REGNO (crtl->drap_reg));
28328 : :
28329 : 348975 : if (pic_offset_table_rtx)
28330 : 29016 : bitmap_clear_bit (components, REAL_PIC_OFFSET_TABLE_REGNUM);
28331 : :
28332 : : return components;
28333 : : }
28334 : :
28335 : : /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB. */
28336 : : sbitmap
28337 : 9353584 : ix86_components_for_bb (basic_block bb)
28338 : : {
28339 : 9353584 : bitmap in = DF_LIVE_IN (bb);
28340 : 9353584 : bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
28341 : 9353584 : bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;
28342 : :
28343 : 9353584 : sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
28344 : 9353584 : bitmap_clear (components);
28345 : :
28346 : 9353584 : function_abi_aggregator callee_abis;
28347 : 9353584 : rtx_insn *insn;
28348 : 107884190 : FOR_BB_INSNS (bb, insn)
28349 : 98530606 : if (CALL_P (insn))
28350 : 3064767 : callee_abis.note_callee_abi (insn_callee_abi (insn));
28351 : 9353584 : HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
28352 : :
28353 : : /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets. */
28354 : 869883312 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
28355 : 860529728 : if (!fixed_regs[regno]
28356 : 860529728 : && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
28357 : 437208146 : || bitmap_bit_p (in, regno)
28358 : 412062112 : || bitmap_bit_p (gen, regno)
28359 : 399317198 : || bitmap_bit_p (kill, regno)))
28360 : 38156125 : bitmap_set_bit (components, regno);
28361 : :
28362 : 9353584 : return components;
28363 : : }
28364 : :
28365 : : /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS. */
28366 : : void
28367 : 484725 : ix86_disqualify_components (sbitmap, edge, sbitmap, bool)
28368 : : {
28369 : : /* Nothing to do for x86. */
28370 : 484725 : }
28371 : :
28372 : : /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS. */
28373 : : void
28374 : 165669 : ix86_emit_prologue_components (sbitmap components)
28375 : : {
28376 : 165669 : HOST_WIDE_INT cfa_offset;
28377 : 165669 : struct machine_function *m = cfun->machine;
28378 : :
28379 : 165669 : cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
28380 : 165669 : - m->frame.stack_pointer_offset;
28381 : 15407217 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
28382 : 15241548 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
28383 : : {
28384 : 729169 : if (bitmap_bit_p (components, regno))
28385 : 198487 : ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
28386 : 777424 : cfa_offset -= UNITS_PER_WORD;
28387 : : }
28388 : 165669 : }
28389 : :
28390 : : /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS. */
28391 : : void
28392 : 152347 : ix86_emit_epilogue_components (sbitmap components)
28393 : : {
28394 : 152347 : HOST_WIDE_INT cfa_offset;
28395 : 152347 : struct machine_function *m = cfun->machine;
28396 : 152347 : cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
28397 : 152347 : - m->frame.stack_pointer_offset;
28398 : :
28399 : 14168271 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
28400 : 14015924 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
28401 : : {
28402 : 687235 : if (bitmap_bit_p (components, regno))
28403 : : {
28404 : 269374 : rtx reg = gen_rtx_REG (word_mode, regno);
28405 : 269374 : rtx mem;
28406 : 269374 : rtx_insn *insn;
28407 : :
28408 : 269374 : mem = choose_baseaddr (cfa_offset, NULL);
28409 : 269374 : mem = gen_frame_mem (word_mode, mem);
28410 : 269374 : insn = emit_move_insn (reg, mem);
28411 : :
28412 : 269374 : RTX_FRAME_RELATED_P (insn) = 1;
28413 : 269374 : add_reg_note (insn, REG_CFA_RESTORE, reg);
28414 : : }
28415 : 741769 : cfa_offset -= UNITS_PER_WORD;
28416 : : }
28417 : 152347 : }
28418 : :
28419 : : /* Implement TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS. */
28420 : : void
28421 : 46154 : ix86_set_handled_components (sbitmap components)
28422 : : {
28423 : 4292322 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
28424 : 4246168 : if (bitmap_bit_p (components, regno))
28425 : : {
28426 : 108624 : cfun->machine->reg_is_wrapped_separately[regno] = true;
28427 : 108624 : cfun->machine->use_fast_prologue_epilogue = true;
28428 : 108624 : cfun->machine->frame.save_regs_using_mov = true;
28429 : : }
28430 : 46154 : }
28431 : :
28432 : : #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
28433 : : #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS ix86_get_separate_components
28434 : : #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
28435 : : #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB ix86_components_for_bb
28436 : : #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
28437 : : #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS ix86_disqualify_components
28438 : : #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
28439 : : #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
28440 : : ix86_emit_prologue_components
28441 : : #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
28442 : : #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
28443 : : ix86_emit_epilogue_components
28444 : : #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
28445 : : #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS ix86_set_handled_components
28446 : :
28447 : : struct gcc_target targetm = TARGET_INITIALIZER;
28448 : :
28449 : : #include "gt-i386.h"
|