Branch data Line data Source code
1 : : /* Subroutines used for code generation on IA-32.
2 : : Copyright (C) 1988-2024 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 : :
104 : : /* This file should be included last. */
105 : : #include "target-def.h"
106 : :
107 : : static rtx legitimize_dllimport_symbol (rtx, bool);
108 : : static rtx legitimize_pe_coff_extern_decl (rtx, bool);
109 : : static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
110 : : static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
111 : :
112 : :
113 : : #ifndef CHECK_STACK_LIMIT
114 : : #define CHECK_STACK_LIMIT (-1)
115 : : #endif
116 : :
117 : : /* Return index of given mode in mult and division cost tables. */
118 : : #define MODE_INDEX(mode) \
119 : : ((mode) == QImode ? 0 \
120 : : : (mode) == HImode ? 1 \
121 : : : (mode) == SImode ? 2 \
122 : : : (mode) == DImode ? 3 \
123 : : : 4)
124 : :
125 : :
126 : : /* Set by -mtune. */
127 : : const struct processor_costs *ix86_tune_cost = NULL;
128 : :
129 : : /* Set by -mtune or -Os. */
130 : : const struct processor_costs *ix86_cost = NULL;
131 : :
132 : : /* In case the average insn count for single function invocation is
133 : : lower than this constant, emit fast (but longer) prologue and
134 : : epilogue code. */
135 : : #define FAST_PROLOGUE_INSN_COUNT 20
136 : :
137 : : /* Names for 8 (low), 8 (high), and 16-bit registers, respectively. */
138 : : static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
139 : : static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
140 : : static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
141 : :
142 : : /* Array of the smallest class containing reg number REGNO, indexed by
143 : : REGNO. Used by REGNO_REG_CLASS in i386.h. */
144 : :
145 : : enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
146 : : {
147 : : /* ax, dx, cx, bx */
148 : : AREG, DREG, CREG, BREG,
149 : : /* si, di, bp, sp */
150 : : SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
151 : : /* FP registers */
152 : : FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
153 : : FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
154 : : /* arg pointer, flags, fpsr, frame */
155 : : NON_Q_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
156 : : /* SSE registers */
157 : : SSE_FIRST_REG, SSE_REGS, SSE_REGS, SSE_REGS,
158 : : SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
159 : : /* MMX registers */
160 : : MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
161 : : MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
162 : : /* REX registers */
163 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
164 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
165 : : /* SSE REX registers */
166 : : SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
167 : : SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
168 : : /* AVX-512 SSE registers */
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 : : ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
173 : : /* Mask registers. */
174 : : ALL_MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
175 : : MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
176 : : /* REX2 registers */
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 : : GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
181 : : };
182 : :
183 : : /* The "default" register map used in 32bit mode. */
184 : :
185 : : int const debugger_register_map[FIRST_PSEUDO_REGISTER] =
186 : : {
187 : : /* general regs */
188 : : 0, 2, 1, 3, 6, 7, 4, 5,
189 : : /* fp regs */
190 : : 12, 13, 14, 15, 16, 17, 18, 19,
191 : : /* arg, flags, fpsr, frame */
192 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
193 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
194 : : /* SSE */
195 : : 21, 22, 23, 24, 25, 26, 27, 28,
196 : : /* MMX */
197 : : 29, 30, 31, 32, 33, 34, 35, 36,
198 : : /* extended integer registers */
199 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
200 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
201 : : /* extended sse registers */
202 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
203 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
204 : : /* AVX-512 registers 16-23 */
205 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
206 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
207 : : /* AVX-512 registers 24-31 */
208 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
209 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
210 : : /* Mask registers */
211 : : 93, 94, 95, 96, 97, 98, 99, 100
212 : : };
213 : :
214 : : /* The "default" register map used in 64bit mode. */
215 : :
216 : : int const debugger64_register_map[FIRST_PSEUDO_REGISTER] =
217 : : {
218 : : /* general regs */
219 : : 0, 1, 2, 3, 4, 5, 6, 7,
220 : : /* fp regs */
221 : : 33, 34, 35, 36, 37, 38, 39, 40,
222 : : /* arg, flags, fpsr, frame */
223 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
224 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
225 : : /* SSE */
226 : : 17, 18, 19, 20, 21, 22, 23, 24,
227 : : /* MMX */
228 : : 41, 42, 43, 44, 45, 46, 47, 48,
229 : : /* extended integer registers */
230 : : 8, 9, 10, 11, 12, 13, 14, 15,
231 : : /* extended SSE registers */
232 : : 25, 26, 27, 28, 29, 30, 31, 32,
233 : : /* AVX-512 registers 16-23 */
234 : : 67, 68, 69, 70, 71, 72, 73, 74,
235 : : /* AVX-512 registers 24-31 */
236 : : 75, 76, 77, 78, 79, 80, 81, 82,
237 : : /* Mask registers */
238 : : 118, 119, 120, 121, 122, 123, 124, 125,
239 : : /* rex2 extend interger registers */
240 : : 130, 131, 132, 133, 134, 135, 136, 137,
241 : : 138, 139, 140, 141, 142, 143, 144, 145
242 : : };
243 : :
244 : : /* Define the register numbers to be used in Dwarf debugging information.
245 : : The SVR4 reference port C compiler uses the following register numbers
246 : : in its Dwarf output code:
247 : : 0 for %eax (gcc regno = 0)
248 : : 1 for %ecx (gcc regno = 2)
249 : : 2 for %edx (gcc regno = 1)
250 : : 3 for %ebx (gcc regno = 3)
251 : : 4 for %esp (gcc regno = 7)
252 : : 5 for %ebp (gcc regno = 6)
253 : : 6 for %esi (gcc regno = 4)
254 : : 7 for %edi (gcc regno = 5)
255 : : The following three DWARF register numbers are never generated by
256 : : the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
257 : : believed these numbers have these meanings.
258 : : 8 for %eip (no gcc equivalent)
259 : : 9 for %eflags (gcc regno = 17)
260 : : 10 for %trapno (no gcc equivalent)
261 : : It is not at all clear how we should number the FP stack registers
262 : : for the x86 architecture. If the version of SDB on x86/svr4 were
263 : : a bit less brain dead with respect to floating-point then we would
264 : : have a precedent to follow with respect to DWARF register numbers
265 : : for x86 FP registers, but the SDB on x86/svr4 was so completely
266 : : broken with respect to FP registers that it is hardly worth thinking
267 : : of it as something to strive for compatibility with.
268 : : The version of x86/svr4 SDB I had does (partially)
269 : : seem to believe that DWARF register number 11 is associated with
270 : : the x86 register %st(0), but that's about all. Higher DWARF
271 : : register numbers don't seem to be associated with anything in
272 : : particular, and even for DWARF regno 11, SDB only seemed to under-
273 : : stand that it should say that a variable lives in %st(0) (when
274 : : asked via an `=' command) if we said it was in DWARF regno 11,
275 : : but SDB still printed garbage when asked for the value of the
276 : : variable in question (via a `/' command).
277 : : (Also note that the labels SDB printed for various FP stack regs
278 : : when doing an `x' command were all wrong.)
279 : : Note that these problems generally don't affect the native SVR4
280 : : C compiler because it doesn't allow the use of -O with -g and
281 : : because when it is *not* optimizing, it allocates a memory
282 : : location for each floating-point variable, and the memory
283 : : location is what gets described in the DWARF AT_location
284 : : attribute for the variable in question.
285 : : Regardless of the severe mental illness of the x86/svr4 SDB, we
286 : : do something sensible here and we use the following DWARF
287 : : register numbers. Note that these are all stack-top-relative
288 : : numbers.
289 : : 11 for %st(0) (gcc regno = 8)
290 : : 12 for %st(1) (gcc regno = 9)
291 : : 13 for %st(2) (gcc regno = 10)
292 : : 14 for %st(3) (gcc regno = 11)
293 : : 15 for %st(4) (gcc regno = 12)
294 : : 16 for %st(5) (gcc regno = 13)
295 : : 17 for %st(6) (gcc regno = 14)
296 : : 18 for %st(7) (gcc regno = 15)
297 : : */
298 : : int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER] =
299 : : {
300 : : /* general regs */
301 : : 0, 2, 1, 3, 6, 7, 5, 4,
302 : : /* fp regs */
303 : : 11, 12, 13, 14, 15, 16, 17, 18,
304 : : /* arg, flags, fpsr, frame */
305 : : IGNORED_DWARF_REGNUM, 9,
306 : : IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
307 : : /* SSE registers */
308 : : 21, 22, 23, 24, 25, 26, 27, 28,
309 : : /* MMX registers */
310 : : 29, 30, 31, 32, 33, 34, 35, 36,
311 : : /* extended integer registers */
312 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
313 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
314 : : /* extended sse registers */
315 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
316 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
317 : : /* AVX-512 registers 16-23 */
318 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
319 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
320 : : /* AVX-512 registers 24-31 */
321 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
322 : : INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
323 : : /* Mask registers */
324 : : 93, 94, 95, 96, 97, 98, 99, 100
325 : : };
326 : :
327 : : /* Define parameter passing and return registers. */
328 : :
329 : : static int const x86_64_int_parameter_registers[6] =
330 : : {
331 : : DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG
332 : : };
333 : :
334 : : static int const x86_64_ms_abi_int_parameter_registers[4] =
335 : : {
336 : : CX_REG, DX_REG, R8_REG, R9_REG
337 : : };
338 : :
339 : : static int const x86_64_int_return_registers[4] =
340 : : {
341 : : AX_REG, DX_REG, DI_REG, SI_REG
342 : : };
343 : :
344 : : /* Define the structure for the machine field in struct function. */
345 : :
346 : : struct GTY(()) stack_local_entry {
347 : : unsigned short mode;
348 : : unsigned short n;
349 : : rtx rtl;
350 : : struct stack_local_entry *next;
351 : : };
352 : :
353 : : /* Which cpu are we scheduling for. */
354 : : enum attr_cpu ix86_schedule;
355 : :
356 : : /* Which cpu are we optimizing for. */
357 : : enum processor_type ix86_tune;
358 : :
359 : : /* Which instruction set architecture to use. */
360 : : enum processor_type ix86_arch;
361 : :
362 : : /* True if processor has SSE prefetch instruction. */
363 : : unsigned char ix86_prefetch_sse;
364 : :
365 : : /* Preferred alignment for stack boundary in bits. */
366 : : unsigned int ix86_preferred_stack_boundary;
367 : :
368 : : /* Alignment for incoming stack boundary in bits specified at
369 : : command line. */
370 : : unsigned int ix86_user_incoming_stack_boundary;
371 : :
372 : : /* Default alignment for incoming stack boundary in bits. */
373 : : unsigned int ix86_default_incoming_stack_boundary;
374 : :
375 : : /* Alignment for incoming stack boundary in bits. */
376 : : unsigned int ix86_incoming_stack_boundary;
377 : :
378 : : /* True if there is no direct access to extern symbols. */
379 : : bool ix86_has_no_direct_extern_access;
380 : :
381 : : /* Calling abi specific va_list type nodes. */
382 : : tree sysv_va_list_type_node;
383 : : tree ms_va_list_type_node;
384 : :
385 : : /* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
386 : : char internal_label_prefix[16];
387 : : int internal_label_prefix_len;
388 : :
389 : : /* Fence to use after loop using movnt. */
390 : : tree x86_mfence;
391 : :
392 : : /* Register class used for passing given 64bit part of the argument.
393 : : These represent classes as documented by the PS ABI, with the exception
394 : : of SSESF, SSEDF classes, that are basically SSE class, just gcc will
395 : : use SF or DFmode move instead of DImode to avoid reformatting penalties.
396 : :
397 : : Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
398 : : whenever possible (upper half does contain padding). */
399 : : enum x86_64_reg_class
400 : : {
401 : : X86_64_NO_CLASS,
402 : : X86_64_INTEGER_CLASS,
403 : : X86_64_INTEGERSI_CLASS,
404 : : X86_64_SSE_CLASS,
405 : : X86_64_SSEHF_CLASS,
406 : : X86_64_SSESF_CLASS,
407 : : X86_64_SSEDF_CLASS,
408 : : X86_64_SSEUP_CLASS,
409 : : X86_64_X87_CLASS,
410 : : X86_64_X87UP_CLASS,
411 : : X86_64_COMPLEX_X87_CLASS,
412 : : X86_64_MEMORY_CLASS
413 : : };
414 : :
415 : : #define MAX_CLASSES 8
416 : :
417 : : /* Table of constants used by fldpi, fldln2, etc.... */
418 : : static REAL_VALUE_TYPE ext_80387_constants_table [5];
419 : : static bool ext_80387_constants_init;
420 : :
421 : :
422 : : static rtx ix86_function_value (const_tree, const_tree, bool);
423 : : static bool ix86_function_value_regno_p (const unsigned int);
424 : : static unsigned int ix86_function_arg_boundary (machine_mode,
425 : : const_tree);
426 : : static rtx ix86_static_chain (const_tree, bool);
427 : : static int ix86_function_regparm (const_tree, const_tree);
428 : : static void ix86_compute_frame_layout (void);
429 : : static tree ix86_canonical_va_list_type (tree);
430 : : static unsigned int split_stack_prologue_scratch_regno (void);
431 : : static bool i386_asm_output_addr_const_extra (FILE *, rtx);
432 : :
433 : : static bool ix86_can_inline_p (tree, tree);
434 : : static unsigned int ix86_minimum_incoming_stack_boundary (bool);
435 : :
436 : :
437 : : /* Whether -mtune= or -march= were specified */
438 : : int ix86_tune_defaulted;
439 : : int ix86_arch_specified;
440 : :
441 : : /* Return true if a red-zone is in use. We can't use red-zone when
442 : : there are local indirect jumps, like "indirect_jump" or "tablejump",
443 : : which jumps to another place in the function, since "call" in the
444 : : indirect thunk pushes the return address onto stack, destroying
445 : : red-zone.
446 : :
447 : : TODO: If we can reserve the first 2 WORDs, for PUSH and, another
448 : : for CALL, in red-zone, we can allow local indirect jumps with
449 : : indirect thunk. */
450 : :
451 : : bool
452 : 9071470 : ix86_using_red_zone (void)
453 : : {
454 : 9071470 : return (TARGET_RED_ZONE
455 : 8168031 : && !TARGET_64BIT_MS_ABI
456 : 16940462 : && (!cfun->machine->has_local_indirect_jump
457 : 106889 : || cfun->machine->indirect_branch_type == indirect_branch_keep));
458 : : }
459 : :
460 : : /* Return true, if profiling code should be emitted before
461 : : prologue. Otherwise it returns false.
462 : : Note: For x86 with "hotfix" it is sorried. */
463 : : static bool
464 : 4185326 : ix86_profile_before_prologue (void)
465 : : {
466 : 4185326 : return flag_fentry != 0;
467 : : }
468 : :
469 : : /* Update register usage after having seen the compiler flags. */
470 : :
471 : : static void
472 : 819042 : ix86_conditional_register_usage (void)
473 : : {
474 : 819042 : int i, c_mask;
475 : :
476 : : /* If there are no caller-saved registers, preserve all registers.
477 : : except fixed_regs and registers used for function return value
478 : : since aggregate_value_p checks call_used_regs[regno] on return
479 : : value. */
480 : 819042 : if (cfun
481 : 61113 : && (cfun->machine->call_saved_registers
482 : 61113 : == TYPE_NO_CALLER_SAVED_REGISTERS))
483 : 378510 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
484 : 374440 : if (!fixed_regs[i] && !ix86_function_value_regno_p (i))
485 : 337800 : call_used_regs[i] = 0;
486 : :
487 : : /* For 32-bit targets, disable the REX registers. */
488 : 819042 : if (! TARGET_64BIT)
489 : : {
490 : 133533 : for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
491 : 118696 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
492 : 133533 : for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
493 : 118696 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
494 : 252229 : for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
495 : 237392 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
496 : : }
497 : :
498 : : /* See the definition of CALL_USED_REGISTERS in i386.h. */
499 : 819042 : c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT_MS_ABI);
500 : :
501 : 819042 : CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
502 : :
503 : 76170906 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
504 : : {
505 : : /* Set/reset conditionally defined registers from
506 : : CALL_USED_REGISTERS initializer. */
507 : 75351864 : if (call_used_regs[i] > 1)
508 : 13047634 : call_used_regs[i] = !!(call_used_regs[i] & c_mask);
509 : :
510 : : /* Calculate registers of CLOBBERED_REGS register set
511 : : as call used registers from GENERAL_REGS register set. */
512 : 75351864 : if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
513 : 75351864 : && call_used_regs[i])
514 : 22839964 : SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
515 : : }
516 : :
517 : : /* If MMX is disabled, disable the registers. */
518 : 819042 : if (! TARGET_MMX)
519 : 384640 : accessible_reg_set &= ~reg_class_contents[MMX_REGS];
520 : :
521 : : /* If SSE is disabled, disable the registers. */
522 : 819042 : if (! TARGET_SSE)
523 : 379436 : accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS];
524 : :
525 : : /* If the FPU is disabled, disable the registers. */
526 : 819042 : if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
527 : 379890 : accessible_reg_set &= ~reg_class_contents[FLOAT_REGS];
528 : :
529 : : /* If AVX512F is disabled, disable the registers. */
530 : 819042 : if (! TARGET_AVX512F)
531 : : {
532 : 9533532 : for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
533 : 8972736 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
534 : :
535 : 1121592 : accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS];
536 : : }
537 : :
538 : : /* If APX is disabled, disable the registers. */
539 : 819042 : if (! (TARGET_APX_EGPR && TARGET_64BIT))
540 : : {
541 : 13919175 : for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)
542 : 13100400 : CLEAR_HARD_REG_BIT (accessible_reg_set, i);
543 : : }
544 : 819042 : }
545 : :
546 : : /* Canonicalize a comparison from one we don't have to one we do have. */
547 : :
548 : : static void
549 : 19151279 : ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
550 : : bool op0_preserve_value)
551 : : {
552 : : /* The order of operands in x87 ficom compare is forced by combine in
553 : : simplify_comparison () function. Float operator is treated as RTX_OBJ
554 : : with a precedence over other operators and is always put in the first
555 : : place. Swap condition and operands to match ficom instruction. */
556 : 19151279 : if (!op0_preserve_value
557 : 18452142 : && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1))
558 : : {
559 : 6 : enum rtx_code scode = swap_condition ((enum rtx_code) *code);
560 : :
561 : : /* We are called only for compares that are split to SAHF instruction.
562 : : Ensure that we have setcc/jcc insn for the swapped condition. */
563 : 6 : if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN)
564 : : {
565 : 6 : std::swap (*op0, *op1);
566 : 6 : *code = (int) scode;
567 : : }
568 : : }
569 : 19151279 : }
570 : :
571 : :
572 : : /* Hook to determine if one function can safely inline another. */
573 : :
574 : : static bool
575 : 7964609 : ix86_can_inline_p (tree caller, tree callee)
576 : : {
577 : 7964609 : tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
578 : 7964609 : tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
579 : :
580 : : /* Changes of those flags can be tolerated for always inlines. Lets hope
581 : : user knows what he is doing. */
582 : 7964609 : unsigned HOST_WIDE_INT always_inline_safe_mask
583 : : = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
584 : : | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
585 : : | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
586 : : | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
587 : : | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
588 : : | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
589 : : | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
590 : :
591 : :
592 : 7964609 : if (!callee_tree)
593 : 7334789 : callee_tree = target_option_default_node;
594 : 7964609 : if (!caller_tree)
595 : 7343475 : caller_tree = target_option_default_node;
596 : 7964609 : if (callee_tree == caller_tree)
597 : : return true;
598 : :
599 : 12807 : struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
600 : 12807 : struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
601 : 12807 : bool ret = false;
602 : 12807 : bool always_inline
603 : 12807 : = (DECL_DISREGARD_INLINE_LIMITS (callee)
604 : 24883 : && lookup_attribute ("always_inline",
605 : 12076 : DECL_ATTRIBUTES (callee)));
606 : :
607 : : /* If callee only uses GPRs, ignore MASK_80387. */
608 : 12807 : if (TARGET_GENERAL_REGS_ONLY_P (callee_opts->x_ix86_target_flags))
609 : 1016 : always_inline_safe_mask |= MASK_80387;
610 : :
611 : 12807 : cgraph_node *callee_node = cgraph_node::get (callee);
612 : : /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
613 : : function can inline a SSE2 function but a SSE2 function can't inline
614 : : a SSE4 function. */
615 : 12807 : if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
616 : : != callee_opts->x_ix86_isa_flags)
617 : 12573 : || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
618 : : != callee_opts->x_ix86_isa_flags2))
619 : : ret = false;
620 : :
621 : : /* See if we have the same non-isa options. */
622 : 12554 : else if ((!always_inline
623 : 493 : && caller_opts->x_target_flags != callee_opts->x_target_flags)
624 : 12510 : || (caller_opts->x_target_flags & ~always_inline_safe_mask)
625 : 12510 : != (callee_opts->x_target_flags & ~always_inline_safe_mask))
626 : : ret = false;
627 : :
628 : 12510 : else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
629 : : /* If the calle doesn't use FP expressions differences in
630 : : ix86_fpmath can be ignored. We are called from FEs
631 : : for multi-versioning call optimization, so beware of
632 : : ipa_fn_summaries not available. */
633 : 1233 : && (! ipa_fn_summaries
634 : 1233 : || ipa_fn_summaries->get (callee_node) == NULL
635 : 1233 : || ipa_fn_summaries->get (callee_node)->fp_expressions))
636 : : ret = false;
637 : :
638 : : /* At this point we cannot identify whether arch or tune setting
639 : : comes from target attribute or not. So the most conservative way
640 : : is to allow the callee that uses default arch and tune string to
641 : : be inlined. */
642 : 12236 : else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
643 : 9534 : && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
644 : : ret = true;
645 : :
646 : : /* See if arch, tune, etc. are the same. As previous ISA flags already
647 : : checks if callee's ISA is subset of caller's, do not block
648 : : always_inline attribute for callee even it has different arch. */
649 : 2710 : else if (!always_inline && caller_opts->arch != callee_opts->arch)
650 : : ret = false;
651 : :
652 : 4 : else if (!always_inline && caller_opts->tune != callee_opts->tune)
653 : : ret = false;
654 : :
655 : 2710 : else if (!always_inline
656 : 4 : && caller_opts->branch_cost != callee_opts->branch_cost)
657 : : ret = false;
658 : :
659 : : else
660 : 7964038 : ret = true;
661 : :
662 : : return ret;
663 : : }
664 : :
665 : : /* Return true if this goes in large data/bss. */
666 : :
667 : : static bool
668 : 64271708 : ix86_in_large_data_p (tree exp)
669 : : {
670 : 64271708 : if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC
671 : 64271457 : && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC)
672 : : return false;
673 : :
674 : 1137 : if (exp == NULL_TREE)
675 : : return false;
676 : :
677 : : /* Functions are never large data. */
678 : 1137 : if (TREE_CODE (exp) == FUNCTION_DECL)
679 : : return false;
680 : :
681 : : /* Automatic variables are never large data. */
682 : 309 : if (VAR_P (exp) && !is_global_var (exp))
683 : : return false;
684 : :
685 : 309 : if (VAR_P (exp) && DECL_SECTION_NAME (exp))
686 : : {
687 : 67 : const char *section = DECL_SECTION_NAME (exp);
688 : 67 : if (strcmp (section, ".ldata") == 0
689 : 67 : || strcmp (section, ".lbss") == 0)
690 : : return true;
691 : : return false;
692 : : }
693 : : else
694 : : {
695 : 242 : HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
696 : :
697 : : /* If this is an incomplete type with size 0, then we can't put it
698 : : in data because it might be too big when completed. Also,
699 : : int_size_in_bytes returns -1 if size can vary or is larger than
700 : : an integer in which case also it is safer to assume that it goes in
701 : : large data. */
702 : 242 : if (size <= 0 || size > ix86_section_threshold)
703 : : return true;
704 : : }
705 : :
706 : : return false;
707 : : }
708 : :
709 : : /* i386-specific section flag to mark large sections. */
710 : : #define SECTION_LARGE SECTION_MACH_DEP
711 : :
712 : : /* Switch to the appropriate section for output of DECL.
713 : : DECL is either a `VAR_DECL' node or a constant of some sort.
714 : : RELOC indicates whether forming the initial value of DECL requires
715 : : link-time relocations. */
716 : :
717 : : ATTRIBUTE_UNUSED static section *
718 : 1616433 : x86_64_elf_select_section (tree decl, int reloc,
719 : : unsigned HOST_WIDE_INT align)
720 : : {
721 : 1616433 : if (ix86_in_large_data_p (decl))
722 : : {
723 : 6 : const char *sname = NULL;
724 : 6 : unsigned int flags = SECTION_WRITE | SECTION_LARGE;
725 : 6 : switch (categorize_decl_for_section (decl, reloc))
726 : : {
727 : 1 : case SECCAT_DATA:
728 : 1 : sname = ".ldata";
729 : 1 : break;
730 : 0 : case SECCAT_DATA_REL:
731 : 0 : sname = ".ldata.rel";
732 : 0 : break;
733 : 0 : case SECCAT_DATA_REL_LOCAL:
734 : 0 : sname = ".ldata.rel.local";
735 : 0 : break;
736 : 0 : case SECCAT_DATA_REL_RO:
737 : 0 : sname = ".ldata.rel.ro";
738 : 0 : break;
739 : 0 : case SECCAT_DATA_REL_RO_LOCAL:
740 : 0 : sname = ".ldata.rel.ro.local";
741 : 0 : break;
742 : 0 : case SECCAT_BSS:
743 : 0 : sname = ".lbss";
744 : 0 : flags |= SECTION_BSS;
745 : 0 : break;
746 : : case SECCAT_RODATA:
747 : : case SECCAT_RODATA_MERGE_STR:
748 : : case SECCAT_RODATA_MERGE_STR_INIT:
749 : : case SECCAT_RODATA_MERGE_CONST:
750 : : sname = ".lrodata";
751 : : flags &= ~SECTION_WRITE;
752 : : break;
753 : 0 : case SECCAT_SRODATA:
754 : 0 : case SECCAT_SDATA:
755 : 0 : case SECCAT_SBSS:
756 : 0 : gcc_unreachable ();
757 : : case SECCAT_TEXT:
758 : : case SECCAT_TDATA:
759 : : case SECCAT_TBSS:
760 : : /* We don't split these for medium model. Place them into
761 : : default sections and hope for best. */
762 : : break;
763 : : }
764 : 1 : if (sname)
765 : : {
766 : : /* We might get called with string constants, but get_named_section
767 : : doesn't like them as they are not DECLs. Also, we need to set
768 : : flags in that case. */
769 : 6 : if (!DECL_P (decl))
770 : 3 : return get_section (sname, flags, NULL);
771 : 3 : return get_named_section (decl, sname, reloc);
772 : : }
773 : : }
774 : 1616427 : return default_elf_select_section (decl, reloc, align);
775 : : }
776 : :
777 : : /* Select a set of attributes for section NAME based on the properties
778 : : of DECL and whether or not RELOC indicates that DECL's initializer
779 : : might contain runtime relocations. */
780 : :
781 : : static unsigned int ATTRIBUTE_UNUSED
782 : 51259735 : x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
783 : : {
784 : 51259735 : unsigned int flags = default_section_type_flags (decl, name, reloc);
785 : :
786 : 51259735 : if (ix86_in_large_data_p (decl))
787 : 7 : flags |= SECTION_LARGE;
788 : :
789 : 51259735 : if (decl == NULL_TREE
790 : 368 : && (strcmp (name, ".ldata.rel.ro") == 0
791 : 368 : || strcmp (name, ".ldata.rel.ro.local") == 0))
792 : 0 : flags |= SECTION_RELRO;
793 : :
794 : 51259735 : if (strcmp (name, ".lbss") == 0
795 : 51259731 : || startswith (name, ".lbss.")
796 : 102519463 : || startswith (name, ".gnu.linkonce.lb."))
797 : 7 : flags |= SECTION_BSS;
798 : :
799 : 51259735 : return flags;
800 : : }
801 : :
802 : : /* Build up a unique section name, expressed as a
803 : : STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
804 : : RELOC indicates whether the initial value of EXP requires
805 : : link-time relocations. */
806 : :
807 : : static void ATTRIBUTE_UNUSED
808 : 1770238 : x86_64_elf_unique_section (tree decl, int reloc)
809 : : {
810 : 1770238 : if (ix86_in_large_data_p (decl))
811 : : {
812 : 3 : const char *prefix = NULL;
813 : : /* We only need to use .gnu.linkonce if we don't have COMDAT groups. */
814 : 3 : bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
815 : :
816 : 3 : switch (categorize_decl_for_section (decl, reloc))
817 : : {
818 : 0 : case SECCAT_DATA:
819 : 0 : case SECCAT_DATA_REL:
820 : 0 : case SECCAT_DATA_REL_LOCAL:
821 : 0 : case SECCAT_DATA_REL_RO:
822 : 0 : case SECCAT_DATA_REL_RO_LOCAL:
823 : 0 : prefix = one_only ? ".ld" : ".ldata";
824 : 0 : break;
825 : 3 : case SECCAT_BSS:
826 : 3 : prefix = one_only ? ".lb" : ".lbss";
827 : 3 : break;
828 : : case SECCAT_RODATA:
829 : : case SECCAT_RODATA_MERGE_STR:
830 : : case SECCAT_RODATA_MERGE_STR_INIT:
831 : : case SECCAT_RODATA_MERGE_CONST:
832 : : prefix = one_only ? ".lr" : ".lrodata";
833 : : break;
834 : 0 : case SECCAT_SRODATA:
835 : 0 : case SECCAT_SDATA:
836 : 0 : case SECCAT_SBSS:
837 : 0 : gcc_unreachable ();
838 : : case SECCAT_TEXT:
839 : : case SECCAT_TDATA:
840 : : case SECCAT_TBSS:
841 : : /* We don't split these for medium model. Place them into
842 : : default sections and hope for best. */
843 : : break;
844 : : }
845 : 3 : if (prefix)
846 : : {
847 : 3 : const char *name, *linkonce;
848 : 3 : char *string;
849 : :
850 : 3 : name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
851 : 3 : name = targetm.strip_name_encoding (name);
852 : :
853 : : /* If we're using one_only, then there needs to be a .gnu.linkonce
854 : : prefix to the section name. */
855 : 3 : linkonce = one_only ? ".gnu.linkonce" : "";
856 : :
857 : 3 : string = ACONCAT ((linkonce, prefix, ".", name, NULL));
858 : :
859 : 3 : set_decl_section_name (decl, string);
860 : 3 : return;
861 : : }
862 : : }
863 : 1770235 : default_unique_section (decl, reloc);
864 : : }
865 : :
866 : : #ifdef COMMON_ASM_OP
867 : :
868 : : #ifndef LARGECOMM_SECTION_ASM_OP
869 : : #define LARGECOMM_SECTION_ASM_OP "\t.largecomm\t"
870 : : #endif
871 : :
872 : : /* This says how to output assembler code to declare an
873 : : uninitialized external linkage data object.
874 : :
875 : : For medium model x86-64 we need to use LARGECOMM_SECTION_ASM_OP opcode for
876 : : large objects. */
877 : : void
878 : 164638 : x86_elf_aligned_decl_common (FILE *file, tree decl,
879 : : const char *name, unsigned HOST_WIDE_INT size,
880 : : unsigned align)
881 : : {
882 : 164638 : if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
883 : 164631 : || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
884 : 7 : && size > (unsigned int)ix86_section_threshold)
885 : : {
886 : 1 : switch_to_section (get_named_section (decl, ".lbss", 0));
887 : 1 : fputs (LARGECOMM_SECTION_ASM_OP, file);
888 : : }
889 : : else
890 : 164637 : fputs (COMMON_ASM_OP, file);
891 : 164638 : assemble_name (file, name);
892 : 164638 : fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
893 : : size, align / BITS_PER_UNIT);
894 : 164638 : }
895 : : #endif
896 : :
897 : : /* Utility function for targets to use in implementing
898 : : ASM_OUTPUT_ALIGNED_BSS. */
899 : :
900 : : void
901 : 761455 : x86_output_aligned_bss (FILE *file, tree decl, const char *name,
902 : : unsigned HOST_WIDE_INT size, unsigned align)
903 : : {
904 : 761455 : if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
905 : 761443 : || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
906 : 38 : && size > (unsigned int)ix86_section_threshold)
907 : 3 : switch_to_section (get_named_section (decl, ".lbss", 0));
908 : : else
909 : 761452 : switch_to_section (bss_section);
910 : 1522910 : ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
911 : : #ifdef ASM_DECLARE_OBJECT_NAME
912 : 761455 : last_assemble_variable_decl = decl;
913 : 761455 : ASM_DECLARE_OBJECT_NAME (file, name, decl);
914 : : #else
915 : : /* Standard thing is just output label for the object. */
916 : : ASM_OUTPUT_LABEL (file, name);
917 : : #endif /* ASM_DECLARE_OBJECT_NAME */
918 : 761455 : ASM_OUTPUT_SKIP (file, size ? size : 1);
919 : 761455 : }
920 : :
921 : : /* Decide whether we must probe the stack before any space allocation
922 : : on this target. It's essentially TARGET_STACK_PROBE except when
923 : : -fstack-check causes the stack to be already probed differently. */
924 : :
925 : : bool
926 : 808320 : ix86_target_stack_probe (void)
927 : : {
928 : : /* Do not probe the stack twice if static stack checking is enabled. */
929 : 808320 : if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
930 : : return false;
931 : :
932 : 808320 : return TARGET_STACK_PROBE;
933 : : }
934 : :
935 : : /* Decide whether we can make a sibling call to a function. DECL is the
936 : : declaration of the function being targeted by the call and EXP is the
937 : : CALL_EXPR representing the call. */
938 : :
939 : : static bool
940 : 122803 : ix86_function_ok_for_sibcall (tree decl, tree exp)
941 : : {
942 : 122803 : tree type, decl_or_type;
943 : 122803 : rtx a, b;
944 : 122803 : bool bind_global = decl && !targetm.binds_local_p (decl);
945 : :
946 : 122803 : if (ix86_function_naked (current_function_decl))
947 : : return false;
948 : :
949 : : /* Sibling call isn't OK if there are no caller-saved registers
950 : : since all registers must be preserved before return. */
951 : 122801 : if (cfun->machine->call_saved_registers
952 : 122801 : == TYPE_NO_CALLER_SAVED_REGISTERS)
953 : : return false;
954 : :
955 : : /* If we are generating position-independent code, we cannot sibcall
956 : : optimize direct calls to global functions, as the PLT requires
957 : : %ebx be live. (Darwin does not have a PLT.) */
958 : 122778 : if (!TARGET_MACHO
959 : 122778 : && !TARGET_64BIT
960 : 10668 : && flag_pic
961 : 7965 : && flag_plt
962 : 7965 : && bind_global)
963 : : return false;
964 : :
965 : : /* If we need to align the outgoing stack, then sibcalling would
966 : : unalign the stack, which may break the called function. */
967 : 118509 : if (ix86_minimum_incoming_stack_boundary (true)
968 : 118509 : < PREFERRED_STACK_BOUNDARY)
969 : : return false;
970 : :
971 : 117929 : if (decl)
972 : : {
973 : 108068 : decl_or_type = decl;
974 : 108068 : type = TREE_TYPE (decl);
975 : : }
976 : : else
977 : : {
978 : : /* We're looking at the CALL_EXPR, we need the type of the function. */
979 : 9861 : type = CALL_EXPR_FN (exp); /* pointer expression */
980 : 9861 : type = TREE_TYPE (type); /* pointer type */
981 : 9861 : type = TREE_TYPE (type); /* function type */
982 : 9861 : decl_or_type = type;
983 : : }
984 : :
985 : : /* Sibling call isn't OK if callee has no callee-saved registers
986 : : and the calling function has callee-saved registers. */
987 : 117929 : if (cfun->machine->call_saved_registers != TYPE_NO_CALLEE_SAVED_REGISTERS
988 : 117924 : && (cfun->machine->call_saved_registers
989 : : != TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP)
990 : 235853 : && lookup_attribute ("no_callee_saved_registers",
991 : 117924 : TYPE_ATTRIBUTES (type)))
992 : : return false;
993 : :
994 : : /* If outgoing reg parm stack space changes, we cannot do sibcall. */
995 : 117921 : if ((OUTGOING_REG_PARM_STACK_SPACE (type)
996 : 117921 : != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
997 : 235095 : || (REG_PARM_STACK_SPACE (decl_or_type)
998 : 117174 : != REG_PARM_STACK_SPACE (current_function_decl)))
999 : : {
1000 : 747 : maybe_complain_about_tail_call (exp,
1001 : : "inconsistent size of stack space"
1002 : : " allocated for arguments which are"
1003 : : " passed in registers");
1004 : 747 : return false;
1005 : : }
1006 : :
1007 : : /* Check that the return value locations are the same. Like
1008 : : if we are returning floats on the 80387 register stack, we cannot
1009 : : make a sibcall from a function that doesn't return a float to a
1010 : : function that does or, conversely, from a function that does return
1011 : : a float to a function that doesn't; the necessary stack adjustment
1012 : : would not be executed. This is also the place we notice
1013 : : differences in the return value ABI. Note that it is ok for one
1014 : : of the functions to have void return type as long as the return
1015 : : value of the other is passed in a register. */
1016 : 117174 : a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
1017 : 117174 : b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
1018 : 117174 : cfun->decl, false);
1019 : 117174 : if (STACK_REG_P (a) || STACK_REG_P (b))
1020 : : {
1021 : 686 : if (!rtx_equal_p (a, b))
1022 : : return false;
1023 : : }
1024 : 116488 : else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
1025 : : ;
1026 : 19629 : else if (!rtx_equal_p (a, b))
1027 : : return false;
1028 : :
1029 : 116755 : if (TARGET_64BIT)
1030 : : {
1031 : : /* The SYSV ABI has more call-clobbered registers;
1032 : : disallow sibcalls from MS to SYSV. */
1033 : 110356 : if (cfun->machine->call_abi == MS_ABI
1034 : 110356 : && ix86_function_type_abi (type) == SYSV_ABI)
1035 : : return false;
1036 : : }
1037 : : else
1038 : : {
1039 : : /* If this call is indirect, we'll need to be able to use a
1040 : : call-clobbered register for the address of the target function.
1041 : : Make sure that all such registers are not used for passing
1042 : : parameters. Note that DLLIMPORT functions and call to global
1043 : : function via GOT slot are indirect. */
1044 : 6399 : if (!decl
1045 : 4558 : || (bind_global && flag_pic && !flag_plt)
1046 : : || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl))
1047 : 4558 : || flag_force_indirect_call)
1048 : : {
1049 : : /* Check if regparm >= 3 since arg_reg_available is set to
1050 : : false if regparm == 0. If regparm is 1 or 2, there is
1051 : : always a call-clobbered register available.
1052 : :
1053 : : ??? The symbol indirect call doesn't need a call-clobbered
1054 : : register. But we don't know if this is a symbol indirect
1055 : : call or not here. */
1056 : 1841 : if (ix86_function_regparm (type, decl) >= 3
1057 : 1841 : && !cfun->machine->arg_reg_available)
1058 : : return false;
1059 : : }
1060 : : }
1061 : :
1062 : 116755 : if (decl && ix86_use_pseudo_pic_reg ())
1063 : : {
1064 : : /* When PIC register is used, it must be restored after ifunc
1065 : : function returns. */
1066 : 2050 : cgraph_node *node = cgraph_node::get (decl);
1067 : 2050 : if (node && node->ifunc_resolver)
1068 : : return false;
1069 : : }
1070 : :
1071 : : /* Disable sibcall if callee has indirect_return attribute and
1072 : : caller doesn't since callee will return to the caller's caller
1073 : : via an indirect jump. */
1074 : 116755 : if (((flag_cf_protection & (CF_RETURN | CF_BRANCH))
1075 : : == (CF_RETURN | CF_BRANCH))
1076 : 44705 : && lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (type))
1077 : 116759 : && !lookup_attribute ("indirect_return",
1078 : 4 : TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
1079 : : return false;
1080 : :
1081 : : /* Otherwise okay. That also includes certain types of indirect calls. */
1082 : : return true;
1083 : : }
1084 : :
1085 : : /* This function determines from TYPE the calling-convention. */
1086 : :
1087 : : unsigned int
1088 : 6034828 : ix86_get_callcvt (const_tree type)
1089 : : {
1090 : 6034828 : unsigned int ret = 0;
1091 : 6034828 : bool is_stdarg;
1092 : 6034828 : tree attrs;
1093 : :
1094 : 6034828 : if (TARGET_64BIT)
1095 : : return IX86_CALLCVT_CDECL;
1096 : :
1097 : 3214982 : attrs = TYPE_ATTRIBUTES (type);
1098 : 3214982 : if (attrs != NULL_TREE)
1099 : : {
1100 : 51617 : if (lookup_attribute ("cdecl", attrs))
1101 : : ret |= IX86_CALLCVT_CDECL;
1102 : 51617 : else if (lookup_attribute ("stdcall", attrs))
1103 : : ret |= IX86_CALLCVT_STDCALL;
1104 : 51617 : else if (lookup_attribute ("fastcall", attrs))
1105 : : ret |= IX86_CALLCVT_FASTCALL;
1106 : 51608 : else if (lookup_attribute ("thiscall", attrs))
1107 : 0 : ret |= IX86_CALLCVT_THISCALL;
1108 : :
1109 : : /* Regparam isn't allowed for thiscall and fastcall. */
1110 : 51617 : if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
1111 : : {
1112 : 51608 : if (lookup_attribute ("regparm", attrs))
1113 : 8304 : ret |= IX86_CALLCVT_REGPARM;
1114 : 51608 : if (lookup_attribute ("sseregparm", attrs))
1115 : 0 : ret |= IX86_CALLCVT_SSEREGPARM;
1116 : : }
1117 : :
1118 : 51617 : if (IX86_BASE_CALLCVT(ret) != 0)
1119 : : return ret;
1120 : : }
1121 : :
1122 : 3214973 : is_stdarg = stdarg_p (type);
1123 : 3214973 : if (TARGET_RTD && !is_stdarg)
1124 : 0 : return IX86_CALLCVT_STDCALL | ret;
1125 : :
1126 : 3214973 : if (ret != 0
1127 : 3214973 : || is_stdarg
1128 : 3198509 : || TREE_CODE (type) != METHOD_TYPE
1129 : 3339017 : || ix86_function_type_abi (type) != MS_ABI)
1130 : 3214973 : return IX86_CALLCVT_CDECL | ret;
1131 : :
1132 : : return IX86_CALLCVT_THISCALL;
1133 : : }
1134 : :
1135 : : /* Return 0 if the attributes for two types are incompatible, 1 if they
1136 : : are compatible, and 2 if they are nearly compatible (which causes a
1137 : : warning to be generated). */
1138 : :
1139 : : static int
1140 : 1419987 : ix86_comp_type_attributes (const_tree type1, const_tree type2)
1141 : : {
1142 : 1419987 : unsigned int ccvt1, ccvt2;
1143 : :
1144 : 1419987 : if (TREE_CODE (type1) != FUNCTION_TYPE
1145 : 1419987 : && TREE_CODE (type1) != METHOD_TYPE)
1146 : : return 1;
1147 : :
1148 : 1413492 : ccvt1 = ix86_get_callcvt (type1);
1149 : 1413492 : ccvt2 = ix86_get_callcvt (type2);
1150 : 1413492 : if (ccvt1 != ccvt2)
1151 : : return 0;
1152 : 2819886 : if (ix86_function_regparm (type1, NULL)
1153 : 1409943 : != ix86_function_regparm (type2, NULL))
1154 : : return 0;
1155 : :
1156 : 692604 : if (lookup_attribute ("no_callee_saved_registers",
1157 : 692604 : TYPE_ATTRIBUTES (type1))
1158 : 692604 : != lookup_attribute ("no_callee_saved_registers",
1159 : 692604 : TYPE_ATTRIBUTES (type2)))
1160 : : return 0;
1161 : :
1162 : : return 1;
1163 : : }
1164 : :
1165 : : /* Return the regparm value for a function with the indicated TYPE and DECL.
1166 : : DECL may be NULL when calling function indirectly
1167 : : or considering a libcall. */
1168 : :
1169 : : static int
1170 : 4075922 : ix86_function_regparm (const_tree type, const_tree decl)
1171 : : {
1172 : 4075922 : tree attr;
1173 : 4075922 : int regparm;
1174 : 4075922 : unsigned int ccvt;
1175 : :
1176 : 4075922 : if (TARGET_64BIT)
1177 : 2819846 : return (ix86_function_type_abi (type) == SYSV_ABI
1178 : 2819846 : ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
1179 : 1256076 : ccvt = ix86_get_callcvt (type);
1180 : 1256076 : regparm = ix86_regparm;
1181 : :
1182 : 1256076 : if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
1183 : : {
1184 : 2017 : attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
1185 : 2017 : if (attr)
1186 : : {
1187 : 2017 : regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
1188 : 2017 : return regparm;
1189 : : }
1190 : : }
1191 : 1254059 : else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
1192 : : return 2;
1193 : 1254059 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
1194 : : return 1;
1195 : :
1196 : : /* Use register calling convention for local functions when possible. */
1197 : 1254059 : if (decl
1198 : 1192803 : && TREE_CODE (decl) == FUNCTION_DECL)
1199 : : {
1200 : 1182680 : cgraph_node *target = cgraph_node::get (decl);
1201 : 1182680 : if (target)
1202 : 1175918 : target = target->function_symbol ();
1203 : :
1204 : : /* Caller and callee must agree on the calling convention, so
1205 : : checking here just optimize means that with
1206 : : __attribute__((optimize (...))) caller could use regparm convention
1207 : : and callee not, or vice versa. Instead look at whether the callee
1208 : : is optimized or not. */
1209 : 1175918 : if (target && opt_for_fn (target->decl, optimize)
1210 : 2350991 : && !(profile_flag && !flag_fentry))
1211 : : {
1212 : 1175073 : if (target->local && target->can_change_signature)
1213 : : {
1214 : 135504 : int local_regparm, globals = 0, regno;
1215 : :
1216 : : /* Make sure no regparm register is taken by a
1217 : : fixed register variable. */
1218 : 135504 : for (local_regparm = 0; local_regparm < REGPARM_MAX;
1219 : : local_regparm++)
1220 : 101628 : if (fixed_regs[local_regparm])
1221 : : break;
1222 : :
1223 : : /* We don't want to use regparm(3) for nested functions as
1224 : : these use a static chain pointer in the third argument. */
1225 : 33876 : if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
1226 : : local_regparm = 2;
1227 : :
1228 : : /* Save a register for the split stack. */
1229 : 33876 : if (flag_split_stack)
1230 : : {
1231 : 20947 : if (local_regparm == 3)
1232 : : local_regparm = 2;
1233 : 713 : else if (local_regparm == 2
1234 : 713 : && DECL_STATIC_CHAIN (target->decl))
1235 : : local_regparm = 1;
1236 : : }
1237 : :
1238 : : /* Each fixed register usage increases register pressure,
1239 : : so less registers should be used for argument passing.
1240 : : This functionality can be overriden by an explicit
1241 : : regparm value. */
1242 : 237132 : for (regno = AX_REG; regno <= DI_REG; regno++)
1243 : 203256 : if (fixed_regs[regno])
1244 : 0 : globals++;
1245 : :
1246 : 33876 : local_regparm
1247 : 33876 : = globals < local_regparm ? local_regparm - globals : 0;
1248 : :
1249 : 33876 : if (local_regparm > regparm)
1250 : 4075922 : regparm = local_regparm;
1251 : : }
1252 : : }
1253 : : }
1254 : :
1255 : : return regparm;
1256 : : }
1257 : :
1258 : : /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
1259 : : DFmode (2) arguments in SSE registers for a function with the
1260 : : indicated TYPE and DECL. DECL may be NULL when calling function
1261 : : indirectly or considering a libcall. Return -1 if any FP parameter
1262 : : should be rejected by error. This is used in siutation we imply SSE
1263 : : calling convetion but the function is called from another function with
1264 : : SSE disabled. Otherwise return 0. */
1265 : :
1266 : : static int
1267 : 1060290 : ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
1268 : : {
1269 : 1060290 : gcc_assert (!TARGET_64BIT);
1270 : :
1271 : : /* Use SSE registers to pass SFmode and DFmode arguments if requested
1272 : : by the sseregparm attribute. */
1273 : 1060290 : if (TARGET_SSEREGPARM
1274 : 1060290 : || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
1275 : : {
1276 : 0 : if (!TARGET_SSE)
1277 : : {
1278 : 0 : if (warn)
1279 : : {
1280 : 0 : if (decl)
1281 : 0 : error ("calling %qD with attribute sseregparm without "
1282 : : "SSE/SSE2 enabled", decl);
1283 : : else
1284 : 0 : error ("calling %qT with attribute sseregparm without "
1285 : : "SSE/SSE2 enabled", type);
1286 : : }
1287 : 0 : return 0;
1288 : : }
1289 : :
1290 : : return 2;
1291 : : }
1292 : :
1293 : 1060290 : if (!decl)
1294 : : return 0;
1295 : :
1296 : 966397 : cgraph_node *target = cgraph_node::get (decl);
1297 : 966397 : if (target)
1298 : 959642 : target = target->function_symbol ();
1299 : :
1300 : : /* For local functions, pass up to SSE_REGPARM_MAX SFmode
1301 : : (and DFmode for SSE2) arguments in SSE registers. */
1302 : 959642 : if (target
1303 : : /* TARGET_SSE_MATH */
1304 : 959642 : && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
1305 : 1296 : && opt_for_fn (target->decl, optimize)
1306 : 960938 : && !(profile_flag && !flag_fentry))
1307 : : {
1308 : 1296 : if (target->local && target->can_change_signature)
1309 : : {
1310 : : /* Refuse to produce wrong code when local function with SSE enabled
1311 : : is called from SSE disabled function.
1312 : : FIXME: We need a way to detect these cases cross-ltrans partition
1313 : : and avoid using SSE calling conventions on local functions called
1314 : : from function with SSE disabled. For now at least delay the
1315 : : warning until we know we are going to produce wrong code.
1316 : : See PR66047 */
1317 : 0 : if (!TARGET_SSE && warn)
1318 : : return -1;
1319 : 0 : return TARGET_SSE2_P (target_opts_for_fn (target->decl)
1320 : 0 : ->x_ix86_isa_flags) ? 2 : 1;
1321 : : }
1322 : : }
1323 : :
1324 : : return 0;
1325 : : }
1326 : :
1327 : : /* Return true if EAX is live at the start of the function. Used by
1328 : : ix86_expand_prologue to determine if we need special help before
1329 : : calling allocate_stack_worker. */
1330 : :
1331 : : static bool
1332 : 7089 : ix86_eax_live_at_start_p (void)
1333 : : {
1334 : : /* Cheat. Don't bother working forward from ix86_function_regparm
1335 : : to the function type to whether an actual argument is located in
1336 : : eax. Instead just look at cfg info, which is still close enough
1337 : : to correct at this point. This gives false positives for broken
1338 : : functions that might use uninitialized data that happens to be
1339 : : allocated in eax, but who cares? */
1340 : 7089 : return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 0);
1341 : : }
1342 : :
1343 : : static bool
1344 : 159071 : ix86_keep_aggregate_return_pointer (tree fntype)
1345 : : {
1346 : 159071 : tree attr;
1347 : :
1348 : 159071 : if (!TARGET_64BIT)
1349 : : {
1350 : 159071 : attr = lookup_attribute ("callee_pop_aggregate_return",
1351 : 159071 : TYPE_ATTRIBUTES (fntype));
1352 : 159071 : if (attr)
1353 : 0 : return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
1354 : :
1355 : : /* For 32-bit MS-ABI the default is to keep aggregate
1356 : : return pointer. */
1357 : 159071 : if (ix86_function_type_abi (fntype) == MS_ABI)
1358 : : return true;
1359 : : }
1360 : : return KEEP_AGGREGATE_RETURN_POINTER != 0;
1361 : : }
1362 : :
1363 : : /* Value is the number of bytes of arguments automatically
1364 : : popped when returning from a subroutine call.
1365 : : FUNDECL is the declaration node of the function (as a tree),
1366 : : FUNTYPE is the data type of the function (as a tree),
1367 : : or for a library call it is an identifier node for the subroutine name.
1368 : : SIZE is the number of bytes of arguments passed on the stack.
1369 : :
1370 : : On the 80386, the RTD insn may be used to pop them if the number
1371 : : of args is fixed, but if the number is variable then the caller
1372 : : must pop them all. RTD can't be used for library calls now
1373 : : because the library is compiled with the Unix compiler.
1374 : : Use of RTD is a selectable option, since it is incompatible with
1375 : : standard Unix calling sequences. If the option is not selected,
1376 : : the caller must always pop the args.
1377 : :
1378 : : The attribute stdcall is equivalent to RTD on a per module basis. */
1379 : :
1380 : : static poly_int64
1381 : 7095267 : ix86_return_pops_args (tree fundecl, tree funtype, poly_int64 size)
1382 : : {
1383 : 7095267 : unsigned int ccvt;
1384 : :
1385 : : /* None of the 64-bit ABIs pop arguments. */
1386 : 7095267 : if (TARGET_64BIT)
1387 : 6231342 : return 0;
1388 : :
1389 : 863925 : ccvt = ix86_get_callcvt (funtype);
1390 : :
1391 : 863925 : if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
1392 : : | IX86_CALLCVT_THISCALL)) != 0
1393 : 863925 : && ! stdarg_p (funtype))
1394 : 3 : return size;
1395 : :
1396 : : /* Lose any fake structure return argument if it is passed on the stack. */
1397 : 863922 : if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
1398 : 863922 : && !ix86_keep_aggregate_return_pointer (funtype))
1399 : : {
1400 : 159071 : int nregs = ix86_function_regparm (funtype, fundecl);
1401 : 159071 : if (nregs == 0)
1402 : 304170 : return GET_MODE_SIZE (Pmode);
1403 : : }
1404 : :
1405 : 711837 : return 0;
1406 : : }
1407 : :
1408 : : /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook. */
1409 : :
1410 : : static bool
1411 : 8682814 : ix86_legitimate_combined_insn (rtx_insn *insn)
1412 : : {
1413 : 8682814 : int i;
1414 : :
1415 : : /* Check operand constraints in case hard registers were propagated
1416 : : into insn pattern. This check prevents combine pass from
1417 : : generating insn patterns with invalid hard register operands.
1418 : : These invalid insns can eventually confuse reload to error out
1419 : : with a spill failure. See also PRs 46829 and 46843. */
1420 : :
1421 : 8682814 : gcc_assert (INSN_CODE (insn) >= 0);
1422 : :
1423 : 8682814 : extract_insn (insn);
1424 : 8682814 : preprocess_constraints (insn);
1425 : :
1426 : 8682814 : int n_operands = recog_data.n_operands;
1427 : 8682814 : int n_alternatives = recog_data.n_alternatives;
1428 : 29701168 : for (i = 0; i < n_operands; i++)
1429 : : {
1430 : 21022130 : rtx op = recog_data.operand[i];
1431 : 21022130 : machine_mode mode = GET_MODE (op);
1432 : 21022130 : const operand_alternative *op_alt;
1433 : 21022130 : int offset = 0;
1434 : 21022130 : bool win;
1435 : 21022130 : int j;
1436 : :
1437 : : /* A unary operator may be accepted by the predicate, but it
1438 : : is irrelevant for matching constraints. */
1439 : 21022130 : if (UNARY_P (op))
1440 : 41570 : op = XEXP (op, 0);
1441 : :
1442 : 21022130 : if (SUBREG_P (op))
1443 : : {
1444 : 843745 : if (REG_P (SUBREG_REG (op))
1445 : 843745 : && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
1446 : 189 : offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
1447 : 189 : GET_MODE (SUBREG_REG (op)),
1448 : 189 : SUBREG_BYTE (op),
1449 : 189 : GET_MODE (op));
1450 : 843745 : op = SUBREG_REG (op);
1451 : : }
1452 : :
1453 : 21022130 : if (!(REG_P (op) && HARD_REGISTER_P (op)))
1454 : 20746754 : continue;
1455 : :
1456 : 275376 : op_alt = recog_op_alt;
1457 : :
1458 : : /* Operand has no constraints, anything is OK. */
1459 : 275376 : win = !n_alternatives;
1460 : :
1461 : 275376 : alternative_mask preferred = get_preferred_alternatives (insn);
1462 : 752526 : for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
1463 : : {
1464 : 473177 : if (!TEST_BIT (preferred, j))
1465 : 134079 : continue;
1466 : 339098 : if (op_alt[i].anything_ok
1467 : 176307 : || (op_alt[i].matches != -1
1468 : 23927 : && operands_match_p
1469 : 23927 : (recog_data.operand[i],
1470 : 23927 : recog_data.operand[op_alt[i].matches]))
1471 : 511270 : || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
1472 : : {
1473 : : win = true;
1474 : : break;
1475 : : }
1476 : : }
1477 : :
1478 : 275376 : if (!win)
1479 : : return false;
1480 : : }
1481 : :
1482 : : return true;
1483 : : }
1484 : :
1485 : : /* Implement the TARGET_ASAN_SHADOW_OFFSET hook. */
1486 : :
1487 : : static unsigned HOST_WIDE_INT
1488 : 4493 : ix86_asan_shadow_offset (void)
1489 : : {
1490 : 4493 : return SUBTARGET_SHADOW_OFFSET;
1491 : : }
1492 : :
1493 : : /* Argument support functions. */
1494 : :
1495 : : /* Return true when register may be used to pass function parameters. */
1496 : : bool
1497 : 1326346105 : ix86_function_arg_regno_p (int regno)
1498 : : {
1499 : 1326346105 : int i;
1500 : 1326346105 : enum calling_abi call_abi;
1501 : 1326346105 : const int *parm_regs;
1502 : :
1503 : 1323115525 : if (TARGET_SSE && SSE_REGNO_P (regno)
1504 : 2189118567 : && regno < FIRST_SSE_REG + SSE_REGPARM_MAX)
1505 : : return true;
1506 : :
1507 : 1219906761 : if (!TARGET_64BIT)
1508 : 125272062 : return (regno < REGPARM_MAX
1509 : 125272062 : || (TARGET_MMX && MMX_REGNO_P (regno)
1510 : 11259056 : && regno < FIRST_MMX_REG + MMX_REGPARM_MAX));
1511 : :
1512 : : /* TODO: The function should depend on current function ABI but
1513 : : builtins.cc would need updating then. Therefore we use the
1514 : : default ABI. */
1515 : 1094634699 : call_abi = ix86_cfun_abi ();
1516 : :
1517 : : /* RAX is used as hidden argument to va_arg functions. */
1518 : 1094634699 : if (call_abi == SYSV_ABI && regno == AX_REG)
1519 : : return true;
1520 : :
1521 : 1082017756 : if (call_abi == MS_ABI)
1522 : : parm_regs = x86_64_ms_abi_int_parameter_registers;
1523 : : else
1524 : 1047413660 : parm_regs = x86_64_int_parameter_registers;
1525 : :
1526 : 14471607866 : for (i = 0; i < (call_abi == MS_ABI
1527 : 7235803933 : ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
1528 : 6231103816 : if (regno == parm_regs[i])
1529 : : return true;
1530 : : return false;
1531 : : }
1532 : :
1533 : : /* Return if we do not know how to pass ARG solely in registers. */
1534 : :
1535 : : static bool
1536 : 336084376 : ix86_must_pass_in_stack (const function_arg_info &arg)
1537 : : {
1538 : 336084376 : if (must_pass_in_stack_var_size_or_pad (arg))
1539 : : return true;
1540 : :
1541 : : /* For 32-bit, we want TImode aggregates to go on the stack. But watch out!
1542 : : The layout_type routine is crafty and tries to trick us into passing
1543 : : currently unsupported vector types on the stack by using TImode. */
1544 : 1744654 : return (!TARGET_64BIT && arg.mode == TImode
1545 : 336084370 : && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
1546 : : }
1547 : :
1548 : : /* It returns the size, in bytes, of the area reserved for arguments passed
1549 : : in registers for the function represented by fndecl dependent to the used
1550 : : abi format. */
1551 : : int
1552 : 9880782 : ix86_reg_parm_stack_space (const_tree fndecl)
1553 : : {
1554 : 9880782 : enum calling_abi call_abi = SYSV_ABI;
1555 : 9880782 : if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
1556 : 9573288 : call_abi = ix86_function_abi (fndecl);
1557 : : else
1558 : 307494 : call_abi = ix86_function_type_abi (fndecl);
1559 : 9880782 : if (TARGET_64BIT && call_abi == MS_ABI)
1560 : 119298 : return 32;
1561 : : return 0;
1562 : : }
1563 : :
1564 : : /* We add this as a workaround in order to use libc_has_function
1565 : : hook in i386.md. */
1566 : : bool
1567 : 0 : ix86_libc_has_function (enum function_class fn_class)
1568 : : {
1569 : 0 : return targetm.libc_has_function (fn_class, NULL_TREE);
1570 : : }
1571 : :
1572 : : /* Returns value SYSV_ABI, MS_ABI dependent on fntype,
1573 : : specifying the call abi used. */
1574 : : enum calling_abi
1575 : 368257252 : ix86_function_type_abi (const_tree fntype)
1576 : : {
1577 : 368257252 : enum calling_abi abi = ix86_abi;
1578 : :
1579 : 368257252 : if (fntype == NULL_TREE || TYPE_ATTRIBUTES (fntype) == NULL_TREE)
1580 : : return abi;
1581 : :
1582 : 16170088 : if (abi == SYSV_ABI
1583 : 16170088 : && lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
1584 : : {
1585 : 2564581 : static int warned;
1586 : 2564581 : if (TARGET_X32 && !warned)
1587 : : {
1588 : 1 : error ("X32 does not support %<ms_abi%> attribute");
1589 : 1 : warned = 1;
1590 : : }
1591 : :
1592 : : abi = MS_ABI;
1593 : : }
1594 : 13605507 : else if (abi == MS_ABI
1595 : 13605507 : && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
1596 : : abi = SYSV_ABI;
1597 : :
1598 : : return abi;
1599 : : }
1600 : :
1601 : : enum calling_abi
1602 : 180658153 : ix86_function_abi (const_tree fndecl)
1603 : : {
1604 : 180658153 : return fndecl ? ix86_function_type_abi (TREE_TYPE (fndecl)) : ix86_abi;
1605 : : }
1606 : :
1607 : : /* Returns value SYSV_ABI, MS_ABI dependent on cfun,
1608 : : specifying the call abi used. */
1609 : : enum calling_abi
1610 : 1865343162 : ix86_cfun_abi (void)
1611 : : {
1612 : 1865343162 : return cfun ? cfun->machine->call_abi : ix86_abi;
1613 : : }
1614 : :
1615 : : bool
1616 : 4737367 : ix86_function_ms_hook_prologue (const_tree fn)
1617 : : {
1618 : 4737367 : if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
1619 : : {
1620 : 15 : if (decl_function_context (fn) != NULL_TREE)
1621 : 0 : error_at (DECL_SOURCE_LOCATION (fn),
1622 : : "%<ms_hook_prologue%> attribute is not compatible "
1623 : : "with nested function");
1624 : : else
1625 : : return true;
1626 : : }
1627 : : return false;
1628 : : }
1629 : :
1630 : : bool
1631 : 101118379 : ix86_function_naked (const_tree fn)
1632 : : {
1633 : 101118379 : if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
1634 : : return true;
1635 : :
1636 : : return false;
1637 : : }
1638 : :
1639 : : /* Write the extra assembler code needed to declare a function properly. */
1640 : :
1641 : : void
1642 : 1457572 : ix86_asm_output_function_label (FILE *out_file, const char *fname,
1643 : : tree decl)
1644 : : {
1645 : 1457572 : bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
1646 : :
1647 : 1457572 : if (cfun)
1648 : 1453912 : cfun->machine->function_label_emitted = true;
1649 : :
1650 : 1457572 : if (is_ms_hook)
1651 : : {
1652 : 2 : int i, filler_count = (TARGET_64BIT ? 32 : 16);
1653 : 2 : unsigned int filler_cc = 0xcccccccc;
1654 : :
1655 : 18 : for (i = 0; i < filler_count; i += 4)
1656 : 16 : fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
1657 : : }
1658 : :
1659 : : #ifdef SUBTARGET_ASM_UNWIND_INIT
1660 : : SUBTARGET_ASM_UNWIND_INIT (out_file);
1661 : : #endif
1662 : :
1663 : 1457572 : assemble_function_label_raw (out_file, fname);
1664 : :
1665 : : /* Output magic byte marker, if hot-patch attribute is set. */
1666 : 1457572 : if (is_ms_hook)
1667 : : {
1668 : 2 : if (TARGET_64BIT)
1669 : : {
1670 : : /* leaq [%rsp + 0], %rsp */
1671 : 2 : fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
1672 : : out_file);
1673 : : }
1674 : : else
1675 : : {
1676 : : /* movl.s %edi, %edi
1677 : : push %ebp
1678 : : movl.s %esp, %ebp */
1679 : 0 : fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
1680 : : }
1681 : : }
1682 : 1457572 : }
1683 : :
1684 : : /* Implementation of call abi switching target hook. Specific to FNDECL
1685 : : the specific call register sets are set. See also
1686 : : ix86_conditional_register_usage for more details. */
1687 : : void
1688 : 161732677 : ix86_call_abi_override (const_tree fndecl)
1689 : : {
1690 : 161732677 : cfun->machine->call_abi = ix86_function_abi (fndecl);
1691 : 161732677 : }
1692 : :
1693 : : /* Return 1 if pseudo register should be created and used to hold
1694 : : GOT address for PIC code. */
1695 : : bool
1696 : 156269335 : ix86_use_pseudo_pic_reg (void)
1697 : : {
1698 : 156269335 : if ((TARGET_64BIT
1699 : 145571866 : && (ix86_cmodel == CM_SMALL_PIC
1700 : : || TARGET_PECOFF))
1701 : 151204333 : || !flag_pic)
1702 : 151735495 : return false;
1703 : : return true;
1704 : : }
1705 : :
1706 : : /* Initialize large model PIC register. */
1707 : :
1708 : : static void
1709 : 55 : ix86_init_large_pic_reg (unsigned int tmp_regno)
1710 : : {
1711 : 55 : rtx_code_label *label;
1712 : 55 : rtx tmp_reg;
1713 : :
1714 : 55 : gcc_assert (Pmode == DImode);
1715 : 55 : label = gen_label_rtx ();
1716 : 55 : emit_label (label);
1717 : 55 : LABEL_PRESERVE_P (label) = 1;
1718 : 55 : tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
1719 : 55 : gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
1720 : 55 : emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
1721 : : label));
1722 : 55 : emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
1723 : 55 : emit_insn (gen_add2_insn (pic_offset_table_rtx, tmp_reg));
1724 : 55 : const char *name = LABEL_NAME (label);
1725 : 55 : PUT_CODE (label, NOTE);
1726 : 55 : NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
1727 : 55 : NOTE_DELETED_LABEL_NAME (label) = name;
1728 : 55 : }
1729 : :
1730 : : /* Create and initialize PIC register if required. */
1731 : : static void
1732 : 1392359 : ix86_init_pic_reg (void)
1733 : : {
1734 : 1392359 : edge entry_edge;
1735 : 1392359 : rtx_insn *seq;
1736 : :
1737 : 1392359 : if (!ix86_use_pseudo_pic_reg ())
1738 : : return;
1739 : :
1740 : 39336 : start_sequence ();
1741 : :
1742 : 39336 : if (TARGET_64BIT)
1743 : : {
1744 : 68 : if (ix86_cmodel == CM_LARGE_PIC)
1745 : 51 : ix86_init_large_pic_reg (R11_REG);
1746 : : else
1747 : 17 : emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
1748 : : }
1749 : : else
1750 : : {
1751 : : /* If there is future mcount call in the function it is more profitable
1752 : : to emit SET_GOT into ABI defined REAL_PIC_OFFSET_TABLE_REGNUM. */
1753 : 39268 : rtx reg = crtl->profile
1754 : 39268 : ? gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM)
1755 : 39268 : : pic_offset_table_rtx;
1756 : 39268 : rtx_insn *insn = emit_insn (gen_set_got (reg));
1757 : 39268 : RTX_FRAME_RELATED_P (insn) = 1;
1758 : 39268 : if (crtl->profile)
1759 : 0 : emit_move_insn (pic_offset_table_rtx, reg);
1760 : 39268 : add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
1761 : : }
1762 : :
1763 : 39336 : seq = get_insns ();
1764 : 39336 : end_sequence ();
1765 : :
1766 : 39336 : entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
1767 : 39336 : insert_insn_on_edge (seq, entry_edge);
1768 : 39336 : commit_one_edge_insertion (entry_edge);
1769 : : }
1770 : :
1771 : : /* Initialize a variable CUM of type CUMULATIVE_ARGS
1772 : : for a call to a function whose data type is FNTYPE.
1773 : : For a library call, FNTYPE is 0. */
1774 : :
1775 : : void
1776 : 9628609 : init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
1777 : : tree fntype, /* tree ptr for function decl */
1778 : : rtx libname, /* SYMBOL_REF of library name or 0 */
1779 : : tree fndecl,
1780 : : int caller)
1781 : : {
1782 : 9628609 : struct cgraph_node *local_info_node = NULL;
1783 : 9628609 : struct cgraph_node *target = NULL;
1784 : :
1785 : : /* Set silent_p to false to raise an error for invalid calls when
1786 : : expanding function body. */
1787 : 9628609 : cfun->machine->silent_p = false;
1788 : :
1789 : 9628609 : memset (cum, 0, sizeof (*cum));
1790 : :
1791 : 9628609 : if (fndecl)
1792 : : {
1793 : 9306464 : target = cgraph_node::get (fndecl);
1794 : 9306464 : if (target)
1795 : : {
1796 : 9199165 : target = target->function_symbol ();
1797 : 9199165 : local_info_node = cgraph_node::local_info_node (target->decl);
1798 : 9199165 : cum->call_abi = ix86_function_abi (target->decl);
1799 : : }
1800 : : else
1801 : 107299 : cum->call_abi = ix86_function_abi (fndecl);
1802 : : }
1803 : : else
1804 : 322145 : cum->call_abi = ix86_function_type_abi (fntype);
1805 : :
1806 : 9628609 : cum->caller = caller;
1807 : :
1808 : : /* Set up the number of registers to use for passing arguments. */
1809 : 9628609 : cum->nregs = ix86_regparm;
1810 : 9628609 : if (TARGET_64BIT)
1811 : : {
1812 : 8608254 : cum->nregs = (cum->call_abi == SYSV_ABI
1813 : 8608254 : ? X86_64_REGPARM_MAX
1814 : : : X86_64_MS_REGPARM_MAX);
1815 : : }
1816 : 9628609 : if (TARGET_SSE)
1817 : : {
1818 : 9619566 : cum->sse_nregs = SSE_REGPARM_MAX;
1819 : 9619566 : if (TARGET_64BIT)
1820 : : {
1821 : 8599322 : cum->sse_nregs = (cum->call_abi == SYSV_ABI
1822 : 8599322 : ? X86_64_SSE_REGPARM_MAX
1823 : : : X86_64_MS_SSE_REGPARM_MAX);
1824 : : }
1825 : : }
1826 : 9628609 : if (TARGET_MMX)
1827 : 10441968 : cum->mmx_nregs = MMX_REGPARM_MAX;
1828 : 9628609 : cum->warn_avx512f = true;
1829 : 9628609 : cum->warn_avx = true;
1830 : 9628609 : cum->warn_sse = true;
1831 : 9628609 : cum->warn_mmx = true;
1832 : :
1833 : : /* Because type might mismatch in between caller and callee, we need to
1834 : : use actual type of function for local calls.
1835 : : FIXME: cgraph_analyze can be told to actually record if function uses
1836 : : va_start so for local functions maybe_vaarg can be made aggressive
1837 : : helping K&R code.
1838 : : FIXME: once typesytem is fixed, we won't need this code anymore. */
1839 : 9628609 : if (local_info_node && local_info_node->local
1840 : 9199165 : && local_info_node->can_change_signature)
1841 : 346454 : fntype = TREE_TYPE (target->decl);
1842 : 9628609 : cum->stdarg = stdarg_p (fntype);
1843 : 19257218 : cum->maybe_vaarg = (fntype
1844 : 10165461 : ? (!prototype_p (fntype) || stdarg_p (fntype))
1845 : 120224 : : !libname);
1846 : :
1847 : 9628609 : cum->decl = fndecl;
1848 : :
1849 : 9628609 : cum->warn_empty = !warn_abi || cum->stdarg;
1850 : 9628609 : if (!cum->warn_empty && fntype)
1851 : : {
1852 : 106506 : function_args_iterator iter;
1853 : 106506 : tree argtype;
1854 : 106506 : bool seen_empty_type = false;
1855 : 305707 : FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
1856 : : {
1857 : 305707 : if (argtype == error_mark_node || VOID_TYPE_P (argtype))
1858 : : break;
1859 : 199655 : if (TYPE_EMPTY_P (argtype))
1860 : : seen_empty_type = true;
1861 : 198751 : else if (seen_empty_type)
1862 : : {
1863 : 454 : cum->warn_empty = true;
1864 : 454 : break;
1865 : : }
1866 : : }
1867 : : }
1868 : :
1869 : 9628609 : if (!TARGET_64BIT)
1870 : : {
1871 : : /* If there are variable arguments, then we won't pass anything
1872 : : in registers in 32-bit mode. */
1873 : 1020355 : if (stdarg_p (fntype))
1874 : : {
1875 : 8209 : cum->nregs = 0;
1876 : : /* Since in 32-bit, variable arguments are always passed on
1877 : : stack, there is scratch register available for indirect
1878 : : sibcall. */
1879 : 8209 : cfun->machine->arg_reg_available = true;
1880 : 8209 : cum->sse_nregs = 0;
1881 : 8209 : cum->mmx_nregs = 0;
1882 : 8209 : cum->warn_avx512f = false;
1883 : 8209 : cum->warn_avx = false;
1884 : 8209 : cum->warn_sse = false;
1885 : 8209 : cum->warn_mmx = false;
1886 : 8209 : return;
1887 : : }
1888 : :
1889 : : /* Use ecx and edx registers if function has fastcall attribute,
1890 : : else look for regparm information. */
1891 : 1012146 : if (fntype)
1892 : : {
1893 : 998900 : unsigned int ccvt = ix86_get_callcvt (fntype);
1894 : 998900 : if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
1895 : : {
1896 : 0 : cum->nregs = 1;
1897 : 0 : cum->fastcall = 1; /* Same first register as in fastcall. */
1898 : : }
1899 : 998900 : else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
1900 : : {
1901 : 4 : cum->nregs = 2;
1902 : 4 : cum->fastcall = 1;
1903 : : }
1904 : : else
1905 : 998896 : cum->nregs = ix86_function_regparm (fntype, fndecl);
1906 : : }
1907 : :
1908 : : /* Set up the number of SSE registers used for passing SFmode
1909 : : and DFmode arguments. Warn for mismatching ABI. */
1910 : 1012146 : cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
1911 : : }
1912 : :
1913 : 9620400 : cfun->machine->arg_reg_available = (cum->nregs > 0);
1914 : : }
1915 : :
1916 : : /* Return the "natural" mode for TYPE. In most cases, this is just TYPE_MODE.
1917 : : But in the case of vector types, it is some vector mode.
1918 : :
1919 : : When we have only some of our vector isa extensions enabled, then there
1920 : : are some modes for which vector_mode_supported_p is false. For these
1921 : : modes, the generic vector support in gcc will choose some non-vector mode
1922 : : in order to implement the type. By computing the natural mode, we'll
1923 : : select the proper ABI location for the operand and not depend on whatever
1924 : : the middle-end decides to do with these vector types.
1925 : :
1926 : : The midde-end can't deal with the vector types > 16 bytes. In this
1927 : : case, we return the original mode and warn ABI change if CUM isn't
1928 : : NULL.
1929 : :
1930 : : If INT_RETURN is true, warn ABI change if the vector mode isn't
1931 : : available for function return value. */
1932 : :
1933 : : static machine_mode
1934 : 193898152 : type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
1935 : : bool in_return)
1936 : : {
1937 : 193898152 : machine_mode mode = TYPE_MODE (type);
1938 : :
1939 : 193898152 : if (VECTOR_TYPE_P (type) && !VECTOR_MODE_P (mode))
1940 : : {
1941 : 417923 : HOST_WIDE_INT size = int_size_in_bytes (type);
1942 : 417923 : if ((size == 8 || size == 16 || size == 32 || size == 64)
1943 : : /* ??? Generic code allows us to create width 1 vectors. Ignore. */
1944 : 417923 : && TYPE_VECTOR_SUBPARTS (type) > 1)
1945 : : {
1946 : 383394 : machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
1947 : :
1948 : : /* There are no XFmode vector modes ... */
1949 : 383394 : if (innermode == XFmode)
1950 : : return mode;
1951 : :
1952 : : /* ... and no decimal float vector modes. */
1953 : 382843 : if (DECIMAL_FLOAT_MODE_P (innermode))
1954 : : return mode;
1955 : :
1956 : 382600 : if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (type)))
1957 : : mode = MIN_MODE_VECTOR_FLOAT;
1958 : : else
1959 : 317105 : mode = MIN_MODE_VECTOR_INT;
1960 : :
1961 : : /* Get the mode which has this inner mode and number of units. */
1962 : 7999883 : FOR_EACH_MODE_FROM (mode, mode)
1963 : 16596146 : if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
1964 : 8978863 : && GET_MODE_INNER (mode) == innermode)
1965 : : {
1966 : 382600 : if (size == 64 && (!TARGET_AVX512F || !TARGET_EVEX512)
1967 : 259296 : && !TARGET_IAMCU)
1968 : : {
1969 : 259296 : static bool warnedavx512f;
1970 : 259296 : static bool warnedavx512f_ret;
1971 : :
1972 : 259296 : if (cum && cum->warn_avx512f && !warnedavx512f)
1973 : : {
1974 : 1135 : if (warning (OPT_Wpsabi, "AVX512F vector argument "
1975 : : "without AVX512F enabled changes the ABI"))
1976 : 2 : warnedavx512f = true;
1977 : : }
1978 : 258161 : else if (in_return && !warnedavx512f_ret)
1979 : : {
1980 : 255547 : if (warning (OPT_Wpsabi, "AVX512F vector return "
1981 : : "without AVX512F enabled changes the ABI"))
1982 : 2 : warnedavx512f_ret = true;
1983 : : }
1984 : :
1985 : 259296 : return TYPE_MODE (type);
1986 : : }
1987 : 123304 : else if (size == 32 && !TARGET_AVX && !TARGET_IAMCU)
1988 : : {
1989 : 122760 : static bool warnedavx;
1990 : 122760 : static bool warnedavx_ret;
1991 : :
1992 : 122760 : if (cum && cum->warn_avx && !warnedavx)
1993 : : {
1994 : 612 : if (warning (OPT_Wpsabi, "AVX vector argument "
1995 : : "without AVX enabled changes the ABI"))
1996 : 5 : warnedavx = true;
1997 : : }
1998 : 122148 : else if (in_return && !warnedavx_ret)
1999 : : {
2000 : 120165 : if (warning (OPT_Wpsabi, "AVX vector return "
2001 : : "without AVX enabled changes the ABI"))
2002 : 7 : warnedavx_ret = true;
2003 : : }
2004 : :
2005 : 122760 : return TYPE_MODE (type);
2006 : : }
2007 : 544 : else if (((size == 8 && TARGET_64BIT) || size == 16)
2008 : 541 : && !TARGET_SSE
2009 : 124 : && !TARGET_IAMCU)
2010 : : {
2011 : 124 : static bool warnedsse;
2012 : 124 : static bool warnedsse_ret;
2013 : :
2014 : 124 : if (cum && cum->warn_sse && !warnedsse)
2015 : : {
2016 : 19 : if (warning (OPT_Wpsabi, "SSE vector argument "
2017 : : "without SSE enabled changes the ABI"))
2018 : 6 : warnedsse = true;
2019 : : }
2020 : 105 : else if (!TARGET_64BIT && in_return && !warnedsse_ret)
2021 : : {
2022 : 0 : if (warning (OPT_Wpsabi, "SSE vector return "
2023 : : "without SSE enabled changes the ABI"))
2024 : 0 : warnedsse_ret = true;
2025 : : }
2026 : : }
2027 : 420 : else if ((size == 8 && !TARGET_64BIT)
2028 : 0 : && (!cfun
2029 : 0 : || cfun->machine->func_type == TYPE_NORMAL)
2030 : 0 : && !TARGET_MMX
2031 : 0 : && !TARGET_IAMCU)
2032 : : {
2033 : 0 : static bool warnedmmx;
2034 : 0 : static bool warnedmmx_ret;
2035 : :
2036 : 0 : if (cum && cum->warn_mmx && !warnedmmx)
2037 : : {
2038 : 0 : if (warning (OPT_Wpsabi, "MMX vector argument "
2039 : : "without MMX enabled changes the ABI"))
2040 : 0 : warnedmmx = true;
2041 : : }
2042 : 0 : else if (in_return && !warnedmmx_ret)
2043 : : {
2044 : 0 : if (warning (OPT_Wpsabi, "MMX vector return "
2045 : : "without MMX enabled changes the ABI"))
2046 : 0 : warnedmmx_ret = true;
2047 : : }
2048 : : }
2049 : 544 : return mode;
2050 : : }
2051 : :
2052 : 0 : gcc_unreachable ();
2053 : : }
2054 : : }
2055 : :
2056 : : return mode;
2057 : : }
2058 : :
2059 : : /* We want to pass a value in REGNO whose "natural" mode is MODE. However,
2060 : : this may not agree with the mode that the type system has chosen for the
2061 : : register, which is ORIG_MODE. If ORIG_MODE is not BLKmode, then we can
2062 : : go ahead and use it. Otherwise we have to build a PARALLEL instead. */
2063 : :
2064 : : static rtx
2065 : 31704403 : gen_reg_or_parallel (machine_mode mode, machine_mode orig_mode,
2066 : : unsigned int regno)
2067 : : {
2068 : 31704403 : rtx tmp;
2069 : :
2070 : 31704403 : if (orig_mode != BLKmode)
2071 : 31704375 : tmp = gen_rtx_REG (orig_mode, regno);
2072 : : else
2073 : : {
2074 : 28 : tmp = gen_rtx_REG (mode, regno);
2075 : 28 : tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
2076 : 28 : tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
2077 : : }
2078 : :
2079 : 31704403 : return tmp;
2080 : : }
2081 : :
2082 : : /* x86-64 register passing implementation. See x86-64 ABI for details. Goal
2083 : : of this code is to classify each 8bytes of incoming argument by the register
2084 : : class and assign registers accordingly. */
2085 : :
2086 : : /* Return the union class of CLASS1 and CLASS2.
2087 : : See the x86-64 PS ABI for details. */
2088 : :
2089 : : static enum x86_64_reg_class
2090 : 37719195 : merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
2091 : : {
2092 : : /* Rule #1: If both classes are equal, this is the resulting class. */
2093 : 37719195 : if (class1 == class2)
2094 : : return class1;
2095 : :
2096 : : /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
2097 : : the other class. */
2098 : 32795677 : if (class1 == X86_64_NO_CLASS)
2099 : : return class2;
2100 : 32713979 : if (class2 == X86_64_NO_CLASS)
2101 : : return class1;
2102 : :
2103 : : /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
2104 : 1377224 : if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
2105 : : return X86_64_MEMORY_CLASS;
2106 : :
2107 : : /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
2108 : 1376630 : if ((class1 == X86_64_INTEGERSI_CLASS
2109 : 190146 : && (class2 == X86_64_SSESF_CLASS || class2 == X86_64_SSEHF_CLASS))
2110 : 1375347 : || (class2 == X86_64_INTEGERSI_CLASS
2111 : 624375 : && (class1 == X86_64_SSESF_CLASS || class1 == X86_64_SSEHF_CLASS)))
2112 : : return X86_64_INTEGERSI_CLASS;
2113 : 1371483 : if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
2114 : 471254 : || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
2115 : : return X86_64_INTEGER_CLASS;
2116 : :
2117 : : /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
2118 : : MEMORY is used. */
2119 : 60317 : if (class1 == X86_64_X87_CLASS
2120 : : || class1 == X86_64_X87UP_CLASS
2121 : 60317 : || class1 == X86_64_COMPLEX_X87_CLASS
2122 : : || class2 == X86_64_X87_CLASS
2123 : 59412 : || class2 == X86_64_X87UP_CLASS
2124 : 59102 : || class2 == X86_64_COMPLEX_X87_CLASS)
2125 : 1215 : return X86_64_MEMORY_CLASS;
2126 : :
2127 : : /* Rule #6: Otherwise class SSE is used. */
2128 : : return X86_64_SSE_CLASS;
2129 : : }
2130 : :
2131 : : /* Classify the argument of type TYPE and mode MODE.
2132 : : CLASSES will be filled by the register class used to pass each word
2133 : : of the operand. The number of words is returned. In case the parameter
2134 : : should be passed in memory, 0 is returned. As a special case for zero
2135 : : sized containers, classes[0] will be NO_CLASS and 1 is returned.
2136 : :
2137 : : BIT_OFFSET is used internally for handling records and specifies offset
2138 : : of the offset in bits modulo 512 to avoid overflow cases.
2139 : :
2140 : : See the x86-64 PS ABI for details.
2141 : : */
2142 : :
2143 : : static int
2144 : 322539139 : classify_argument (machine_mode mode, const_tree type,
2145 : : enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset,
2146 : : int &zero_width_bitfields)
2147 : : {
2148 : 322539139 : HOST_WIDE_INT bytes
2149 : 640246385 : = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
2150 : 322539139 : int words = CEIL (bytes + (bit_offset % 64) / 8, UNITS_PER_WORD);
2151 : :
2152 : : /* Variable sized entities are always passed/returned in memory. */
2153 : 322539139 : if (bytes < 0)
2154 : : return 0;
2155 : :
2156 : 322538055 : if (mode != VOIDmode)
2157 : : {
2158 : : /* The value of "named" doesn't matter. */
2159 : 321823149 : function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
2160 : 321823149 : if (targetm.calls.must_pass_in_stack (arg))
2161 : 6 : return 0;
2162 : : }
2163 : :
2164 : 322538049 : if (type && (AGGREGATE_TYPE_P (type)
2165 : 300153657 : || (TREE_CODE (type) == BITINT_TYPE && words > 1)))
2166 : : {
2167 : 23521373 : int i;
2168 : 23521373 : tree field;
2169 : 23521373 : enum x86_64_reg_class subclasses[MAX_CLASSES];
2170 : :
2171 : : /* On x86-64 we pass structures larger than 64 bytes on the stack. */
2172 : 23521373 : if (bytes > 64)
2173 : : return 0;
2174 : :
2175 : 61492638 : for (i = 0; i < words; i++)
2176 : 38757743 : classes[i] = X86_64_NO_CLASS;
2177 : :
2178 : : /* Zero sized arrays or structures are NO_CLASS. We return 0 to
2179 : : signalize memory class, so handle it as special case. */
2180 : 22734895 : if (!words)
2181 : : {
2182 : 64994 : classes[0] = X86_64_NO_CLASS;
2183 : 64994 : return 1;
2184 : : }
2185 : :
2186 : : /* Classify each field of record and merge classes. */
2187 : 22669901 : switch (TREE_CODE (type))
2188 : : {
2189 : 20747466 : case RECORD_TYPE:
2190 : : /* And now merge the fields of structure. */
2191 : 499263311 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2192 : : {
2193 : 478694968 : if (TREE_CODE (field) == FIELD_DECL)
2194 : : {
2195 : 32343311 : int num;
2196 : :
2197 : 32343311 : if (TREE_TYPE (field) == error_mark_node)
2198 : 5 : continue;
2199 : :
2200 : : /* Bitfields are always classified as integer. Handle them
2201 : : early, since later code would consider them to be
2202 : : misaligned integers. */
2203 : 32343306 : if (DECL_BIT_FIELD (field))
2204 : : {
2205 : 415136 : if (integer_zerop (DECL_SIZE (field)))
2206 : : {
2207 : 12911 : if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
2208 : 8057 : continue;
2209 : 4854 : if (zero_width_bitfields != 2)
2210 : : {
2211 : 4320 : zero_width_bitfields = 1;
2212 : 4320 : continue;
2213 : : }
2214 : : }
2215 : 402759 : for (i = (int_bit_position (field)
2216 : 402759 : + (bit_offset % 64)) / 8 / 8;
2217 : 808625 : i < ((int_bit_position (field) + (bit_offset % 64))
2218 : 808625 : + tree_to_shwi (DECL_SIZE (field))
2219 : 808625 : + 63) / 8 / 8; i++)
2220 : 405866 : classes[i]
2221 : 405866 : = merge_classes (X86_64_INTEGER_CLASS, classes[i]);
2222 : : }
2223 : : else
2224 : : {
2225 : 31928170 : int pos;
2226 : :
2227 : 31928170 : type = TREE_TYPE (field);
2228 : :
2229 : : /* Flexible array member is ignored. */
2230 : 31928170 : if (TYPE_MODE (type) == BLKmode
2231 : 408499 : && TREE_CODE (type) == ARRAY_TYPE
2232 : 174705 : && TYPE_SIZE (type) == NULL_TREE
2233 : 2016 : && TYPE_DOMAIN (type) != NULL_TREE
2234 : 31929415 : && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
2235 : : == NULL_TREE))
2236 : : {
2237 : 1245 : static bool warned;
2238 : :
2239 : 1245 : if (!warned && warn_psabi)
2240 : : {
2241 : 2 : warned = true;
2242 : 2 : inform (input_location,
2243 : : "the ABI of passing struct with"
2244 : : " a flexible array member has"
2245 : : " changed in GCC 4.4");
2246 : : }
2247 : 1245 : continue;
2248 : 1245 : }
2249 : 31926925 : num = classify_argument (TYPE_MODE (type), type,
2250 : : subclasses,
2251 : 31926925 : (int_bit_position (field)
2252 : 31926925 : + bit_offset) % 512,
2253 : : zero_width_bitfields);
2254 : 31926925 : if (!num)
2255 : : return 0;
2256 : 31747802 : pos = (int_bit_position (field)
2257 : 31747802 : + (bit_offset % 64)) / 8 / 8;
2258 : 66310315 : for (i = 0; i < num && (i + pos) < words; i++)
2259 : 34562513 : classes[i + pos]
2260 : 34562513 : = merge_classes (subclasses[i], classes[i + pos]);
2261 : : }
2262 : : }
2263 : : }
2264 : : break;
2265 : :
2266 : 375515 : case ARRAY_TYPE:
2267 : : /* Arrays are handled as small records. */
2268 : 375515 : {
2269 : 375515 : int num;
2270 : 375515 : num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
2271 : 375515 : TREE_TYPE (type), subclasses, bit_offset,
2272 : : zero_width_bitfields);
2273 : 375515 : if (!num)
2274 : : return 0;
2275 : :
2276 : : /* The partial classes are now full classes. */
2277 : 372596 : if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
2278 : 13634 : subclasses[0] = X86_64_SSE_CLASS;
2279 : 372596 : if (subclasses[0] == X86_64_SSEHF_CLASS && bytes != 2)
2280 : 4704 : subclasses[0] = X86_64_SSE_CLASS;
2281 : 372596 : if (subclasses[0] == X86_64_INTEGERSI_CLASS
2282 : 170711 : && !((bit_offset % 64) == 0 && bytes == 4))
2283 : 117469 : subclasses[0] = X86_64_INTEGER_CLASS;
2284 : :
2285 : 1202256 : for (i = 0; i < words; i++)
2286 : 829660 : classes[i] = subclasses[i % num];
2287 : :
2288 : : break;
2289 : : }
2290 : 292238 : case UNION_TYPE:
2291 : 292238 : case QUAL_UNION_TYPE:
2292 : : /* Unions are similar to RECORD_TYPE but offset is always 0.
2293 : : */
2294 : 3585215 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2295 : : {
2296 : 3326507 : if (TREE_CODE (field) == FIELD_DECL)
2297 : : {
2298 : 1781881 : int num;
2299 : :
2300 : 1781881 : if (TREE_TYPE (field) == error_mark_node)
2301 : 1 : continue;
2302 : :
2303 : 1781880 : num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
2304 : 1781880 : TREE_TYPE (field), subclasses,
2305 : : bit_offset, zero_width_bitfields);
2306 : 1781880 : if (!num)
2307 : : return 0;
2308 : 4499166 : for (i = 0; i < num && i < words; i++)
2309 : 2750816 : classes[i] = merge_classes (subclasses[i], classes[i]);
2310 : : }
2311 : : }
2312 : : break;
2313 : :
2314 : 1254682 : case BITINT_TYPE:
2315 : : /* _BitInt(N) for N > 64 is passed as structure containing
2316 : : (N + 63) / 64 64-bit elements. */
2317 : 1254682 : if (words > 2)
2318 : : return 0;
2319 : 74519 : classes[0] = classes[1] = X86_64_INTEGER_CLASS;
2320 : 74519 : return 2;
2321 : :
2322 : 0 : default:
2323 : 0 : gcc_unreachable ();
2324 : : }
2325 : :
2326 : 21199647 : if (words > 2)
2327 : : {
2328 : : /* When size > 16 bytes, if the first one isn't
2329 : : X86_64_SSE_CLASS or any other ones aren't
2330 : : X86_64_SSEUP_CLASS, everything should be passed in
2331 : : memory. */
2332 : 1058155 : if (classes[0] != X86_64_SSE_CLASS)
2333 : : return 0;
2334 : :
2335 : 188168 : for (i = 1; i < words; i++)
2336 : 170811 : if (classes[i] != X86_64_SSEUP_CLASS)
2337 : : return 0;
2338 : : }
2339 : :
2340 : : /* Final merger cleanup. */
2341 : 50004466 : for (i = 0; i < words; i++)
2342 : : {
2343 : : /* If one class is MEMORY, everything should be passed in
2344 : : memory. */
2345 : 29848491 : if (classes[i] == X86_64_MEMORY_CLASS)
2346 : : return 0;
2347 : :
2348 : : /* The X86_64_SSEUP_CLASS should be always preceded by
2349 : : X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
2350 : 29847989 : if (classes[i] == X86_64_SSEUP_CLASS
2351 : 141445 : && classes[i - 1] != X86_64_SSE_CLASS
2352 : 73474 : && classes[i - 1] != X86_64_SSEUP_CLASS)
2353 : : {
2354 : : /* The first one should never be X86_64_SSEUP_CLASS. */
2355 : 1916 : gcc_assert (i != 0);
2356 : 1916 : classes[i] = X86_64_SSE_CLASS;
2357 : : }
2358 : :
2359 : : /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
2360 : : everything should be passed in memory. */
2361 : 29847989 : if (classes[i] == X86_64_X87UP_CLASS
2362 : 186992 : && (classes[i - 1] != X86_64_X87_CLASS))
2363 : : {
2364 : 2372 : static bool warned;
2365 : :
2366 : : /* The first one should never be X86_64_X87UP_CLASS. */
2367 : 2372 : gcc_assert (i != 0);
2368 : 2372 : if (!warned && warn_psabi)
2369 : : {
2370 : 1 : warned = true;
2371 : 1 : inform (input_location,
2372 : : "the ABI of passing union with %<long double%>"
2373 : : " has changed in GCC 4.4");
2374 : : }
2375 : 2372 : return 0;
2376 : : }
2377 : : }
2378 : : return words;
2379 : : }
2380 : :
2381 : : /* Compute alignment needed. We align all types to natural boundaries with
2382 : : exception of XFmode that is aligned to 64bits. */
2383 : 299016676 : if (mode != VOIDmode && mode != BLKmode)
2384 : : {
2385 : 297886977 : int mode_alignment = GET_MODE_BITSIZE (mode);
2386 : :
2387 : 297886977 : if (mode == XFmode)
2388 : : mode_alignment = 128;
2389 : 291019636 : else if (mode == XCmode)
2390 : 539289 : mode_alignment = 256;
2391 : 297886977 : if (COMPLEX_MODE_P (mode))
2392 : 2348069 : mode_alignment /= 2;
2393 : : /* Misaligned fields are always returned in memory. */
2394 : 297886977 : if (bit_offset % mode_alignment)
2395 : : return 0;
2396 : : }
2397 : :
2398 : : /* for V1xx modes, just use the base mode */
2399 : 299009043 : if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
2400 : 378606249 : && GET_MODE_UNIT_SIZE (mode) == bytes)
2401 : 2927 : mode = GET_MODE_INNER (mode);
2402 : :
2403 : : /* Classification of atomic types. */
2404 : 299009043 : switch (mode)
2405 : : {
2406 : 221632 : case E_SDmode:
2407 : 221632 : case E_DDmode:
2408 : 221632 : classes[0] = X86_64_SSE_CLASS;
2409 : 221632 : return 1;
2410 : 106532 : case E_TDmode:
2411 : 106532 : classes[0] = X86_64_SSE_CLASS;
2412 : 106532 : classes[1] = X86_64_SSEUP_CLASS;
2413 : 106532 : return 2;
2414 : 191456578 : case E_DImode:
2415 : 191456578 : case E_SImode:
2416 : 191456578 : case E_HImode:
2417 : 191456578 : case E_QImode:
2418 : 191456578 : case E_CSImode:
2419 : 191456578 : case E_CHImode:
2420 : 191456578 : case E_CQImode:
2421 : 191456578 : {
2422 : 191456578 : int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
2423 : :
2424 : : /* Analyze last 128 bits only. */
2425 : 191456578 : size = (size - 1) & 0x7f;
2426 : :
2427 : 191456578 : if (size < 32)
2428 : : {
2429 : 84259847 : classes[0] = X86_64_INTEGERSI_CLASS;
2430 : 84259847 : return 1;
2431 : : }
2432 : 107196731 : else if (size < 64)
2433 : : {
2434 : 98311972 : classes[0] = X86_64_INTEGER_CLASS;
2435 : 98311972 : return 1;
2436 : : }
2437 : 8884759 : else if (size < 64+32)
2438 : : {
2439 : 3777553 : classes[0] = X86_64_INTEGER_CLASS;
2440 : 3777553 : classes[1] = X86_64_INTEGERSI_CLASS;
2441 : 3777553 : return 2;
2442 : : }
2443 : 5107206 : else if (size < 64+64)
2444 : : {
2445 : 5107206 : classes[0] = classes[1] = X86_64_INTEGER_CLASS;
2446 : 5107206 : return 2;
2447 : : }
2448 : : else
2449 : : gcc_unreachable ();
2450 : : }
2451 : 1704611 : case E_CDImode:
2452 : 1704611 : case E_TImode:
2453 : 1704611 : classes[0] = classes[1] = X86_64_INTEGER_CLASS;
2454 : 1704611 : return 2;
2455 : 0 : case E_COImode:
2456 : 0 : case E_OImode:
2457 : : /* OImode shouldn't be used directly. */
2458 : 0 : gcc_unreachable ();
2459 : : case E_CTImode:
2460 : : return 0;
2461 : 840026 : case E_HFmode:
2462 : 840026 : case E_BFmode:
2463 : 840026 : if (!(bit_offset % 64))
2464 : 837766 : classes[0] = X86_64_SSEHF_CLASS;
2465 : : else
2466 : 2260 : classes[0] = X86_64_SSE_CLASS;
2467 : : return 1;
2468 : 9589460 : case E_SFmode:
2469 : 9589460 : if (!(bit_offset % 64))
2470 : 9536476 : classes[0] = X86_64_SSESF_CLASS;
2471 : : else
2472 : 52984 : classes[0] = X86_64_SSE_CLASS;
2473 : : return 1;
2474 : 4118041 : case E_DFmode:
2475 : 4118041 : classes[0] = X86_64_SSEDF_CLASS;
2476 : 4118041 : return 1;
2477 : 6866625 : case E_XFmode:
2478 : 6866625 : classes[0] = X86_64_X87_CLASS;
2479 : 6866625 : classes[1] = X86_64_X87UP_CLASS;
2480 : 6866625 : return 2;
2481 : 1221278 : case E_TFmode:
2482 : 1221278 : classes[0] = X86_64_SSE_CLASS;
2483 : 1221278 : classes[1] = X86_64_SSEUP_CLASS;
2484 : 1221278 : return 2;
2485 : 112414 : case E_HCmode:
2486 : 112414 : case E_BCmode:
2487 : 112414 : classes[0] = X86_64_SSE_CLASS;
2488 : 112414 : if (!(bit_offset % 64))
2489 : : return 1;
2490 : : else
2491 : : {
2492 : 98 : classes[1] = X86_64_SSEHF_CLASS;
2493 : 98 : return 2;
2494 : : }
2495 : 692501 : case E_SCmode:
2496 : 692501 : classes[0] = X86_64_SSE_CLASS;
2497 : 692501 : if (!(bit_offset % 64))
2498 : : return 1;
2499 : : else
2500 : : {
2501 : 1047 : static bool warned;
2502 : :
2503 : 1047 : if (!warned && warn_psabi)
2504 : : {
2505 : 1 : warned = true;
2506 : 1 : inform (input_location,
2507 : : "the ABI of passing structure with %<complex float%>"
2508 : : " member has changed in GCC 4.4");
2509 : : }
2510 : 1047 : classes[1] = X86_64_SSESF_CLASS;
2511 : 1047 : return 2;
2512 : : }
2513 : 706315 : case E_DCmode:
2514 : 706315 : classes[0] = X86_64_SSEDF_CLASS;
2515 : 706315 : classes[1] = X86_64_SSEDF_CLASS;
2516 : 706315 : return 2;
2517 : 539289 : case E_XCmode:
2518 : 539289 : classes[0] = X86_64_COMPLEX_X87_CLASS;
2519 : 539289 : return 1;
2520 : : case E_TCmode:
2521 : : /* This modes is larger than 16 bytes. */
2522 : : return 0;
2523 : 21053338 : case E_V8SFmode:
2524 : 21053338 : case E_V8SImode:
2525 : 21053338 : case E_V32QImode:
2526 : 21053338 : case E_V16HFmode:
2527 : 21053338 : case E_V16BFmode:
2528 : 21053338 : case E_V16HImode:
2529 : 21053338 : case E_V4DFmode:
2530 : 21053338 : case E_V4DImode:
2531 : 21053338 : classes[0] = X86_64_SSE_CLASS;
2532 : 21053338 : classes[1] = X86_64_SSEUP_CLASS;
2533 : 21053338 : classes[2] = X86_64_SSEUP_CLASS;
2534 : 21053338 : classes[3] = X86_64_SSEUP_CLASS;
2535 : 21053338 : return 4;
2536 : 23120785 : case E_V8DFmode:
2537 : 23120785 : case E_V16SFmode:
2538 : 23120785 : case E_V32HFmode:
2539 : 23120785 : case E_V32BFmode:
2540 : 23120785 : case E_V8DImode:
2541 : 23120785 : case E_V16SImode:
2542 : 23120785 : case E_V32HImode:
2543 : 23120785 : case E_V64QImode:
2544 : 23120785 : classes[0] = X86_64_SSE_CLASS;
2545 : 23120785 : classes[1] = X86_64_SSEUP_CLASS;
2546 : 23120785 : classes[2] = X86_64_SSEUP_CLASS;
2547 : 23120785 : classes[3] = X86_64_SSEUP_CLASS;
2548 : 23120785 : classes[4] = X86_64_SSEUP_CLASS;
2549 : 23120785 : classes[5] = X86_64_SSEUP_CLASS;
2550 : 23120785 : classes[6] = X86_64_SSEUP_CLASS;
2551 : 23120785 : classes[7] = X86_64_SSEUP_CLASS;
2552 : 23120785 : return 8;
2553 : 32241734 : case E_V4SFmode:
2554 : 32241734 : case E_V4SImode:
2555 : 32241734 : case E_V16QImode:
2556 : 32241734 : case E_V8HImode:
2557 : 32241734 : case E_V8HFmode:
2558 : 32241734 : case E_V8BFmode:
2559 : 32241734 : case E_V2DFmode:
2560 : 32241734 : case E_V2DImode:
2561 : 32241734 : classes[0] = X86_64_SSE_CLASS;
2562 : 32241734 : classes[1] = X86_64_SSEUP_CLASS;
2563 : 32241734 : return 2;
2564 : 3165433 : case E_V1TImode:
2565 : 3165433 : case E_V1DImode:
2566 : 3165433 : case E_V2SFmode:
2567 : 3165433 : case E_V2SImode:
2568 : 3165433 : case E_V4HImode:
2569 : 3165433 : case E_V4HFmode:
2570 : 3165433 : case E_V4BFmode:
2571 : 3165433 : case E_V2HFmode:
2572 : 3165433 : case E_V2BFmode:
2573 : 3165433 : case E_V8QImode:
2574 : 3165433 : classes[0] = X86_64_SSE_CLASS;
2575 : 3165433 : return 1;
2576 : : case E_BLKmode:
2577 : : case E_VOIDmode:
2578 : : return 0;
2579 : 32293 : default:
2580 : 32293 : gcc_assert (VECTOR_MODE_P (mode));
2581 : :
2582 : 32293 : if (bytes > 16)
2583 : : return 0;
2584 : :
2585 : 38684 : gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
2586 : :
2587 : 38684 : if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
2588 : 18902 : classes[0] = X86_64_INTEGERSI_CLASS;
2589 : : else
2590 : 440 : classes[0] = X86_64_INTEGER_CLASS;
2591 : 19342 : classes[1] = X86_64_INTEGER_CLASS;
2592 : 19342 : return 1 + (bytes > 8);
2593 : : }
2594 : : }
2595 : :
2596 : : /* Wrapper around classify_argument with the extra zero_width_bitfields
2597 : : argument, to diagnose GCC 12.1 ABI differences for C. */
2598 : :
2599 : : static int
2600 : 288454285 : classify_argument (machine_mode mode, const_tree type,
2601 : : enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
2602 : : {
2603 : 288454285 : int zero_width_bitfields = 0;
2604 : 288454285 : static bool warned = false;
2605 : 288454285 : int n = classify_argument (mode, type, classes, bit_offset,
2606 : : zero_width_bitfields);
2607 : 288454285 : if (!zero_width_bitfields || warned || !warn_psabi)
2608 : : return n;
2609 : 534 : enum x86_64_reg_class alt_classes[MAX_CLASSES];
2610 : 534 : zero_width_bitfields = 2;
2611 : 534 : if (classify_argument (mode, type, alt_classes, bit_offset,
2612 : : zero_width_bitfields) != n)
2613 : 0 : zero_width_bitfields = 3;
2614 : : else
2615 : 1286 : for (int i = 0; i < n; i++)
2616 : 760 : if (classes[i] != alt_classes[i])
2617 : : {
2618 : 8 : zero_width_bitfields = 3;
2619 : 8 : break;
2620 : : }
2621 : 534 : if (zero_width_bitfields == 3)
2622 : : {
2623 : 8 : warned = true;
2624 : 8 : const char *url
2625 : : = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields";
2626 : :
2627 : 8 : inform (input_location,
2628 : : "the ABI of passing C structures with zero-width bit-fields"
2629 : : " has changed in GCC %{12.1%}", url);
2630 : : }
2631 : : return n;
2632 : : }
2633 : :
2634 : : /* Examine the argument and return set number of register required in each
2635 : : class. Return true iff parameter should be passed in memory. */
2636 : :
2637 : : static bool
2638 : 193966998 : examine_argument (machine_mode mode, const_tree type, int in_return,
2639 : : int *int_nregs, int *sse_nregs)
2640 : : {
2641 : 193966998 : enum x86_64_reg_class regclass[MAX_CLASSES];
2642 : 193966998 : int n = classify_argument (mode, type, regclass, 0);
2643 : :
2644 : 193966998 : *int_nregs = 0;
2645 : 193966998 : *sse_nregs = 0;
2646 : :
2647 : 193966998 : if (!n)
2648 : : return true;
2649 : 563195722 : for (n--; n >= 0; n--)
2650 : 373138058 : switch (regclass[n])
2651 : : {
2652 : 126774360 : case X86_64_INTEGER_CLASS:
2653 : 126774360 : case X86_64_INTEGERSI_CLASS:
2654 : 126774360 : (*int_nregs)++;
2655 : 126774360 : break;
2656 : 64919068 : case X86_64_SSE_CLASS:
2657 : 64919068 : case X86_64_SSEHF_CLASS:
2658 : 64919068 : case X86_64_SSESF_CLASS:
2659 : 64919068 : case X86_64_SSEDF_CLASS:
2660 : 64919068 : (*sse_nregs)++;
2661 : 64919068 : break;
2662 : : case X86_64_NO_CLASS:
2663 : : case X86_64_SSEUP_CLASS:
2664 : : break;
2665 : 9255802 : case X86_64_X87_CLASS:
2666 : 9255802 : case X86_64_X87UP_CLASS:
2667 : 9255802 : case X86_64_COMPLEX_X87_CLASS:
2668 : 9255802 : if (!in_return)
2669 : : return true;
2670 : : break;
2671 : 0 : case X86_64_MEMORY_CLASS:
2672 : 0 : gcc_unreachable ();
2673 : : }
2674 : :
2675 : : return false;
2676 : : }
2677 : :
2678 : : /* Construct container for the argument used by GCC interface. See
2679 : : FUNCTION_ARG for the detailed description. */
2680 : :
2681 : : static rtx
2682 : 94487287 : construct_container (machine_mode mode, machine_mode orig_mode,
2683 : : const_tree type, int in_return, int nintregs, int nsseregs,
2684 : : const int *intreg, int sse_regno)
2685 : : {
2686 : : /* The following variables hold the static issued_error state. */
2687 : 94487287 : static bool issued_sse_arg_error;
2688 : 94487287 : static bool issued_sse_ret_error;
2689 : 94487287 : static bool issued_x87_ret_error;
2690 : :
2691 : 94487287 : machine_mode tmpmode;
2692 : 94487287 : int bytes
2693 : 188400612 : = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
2694 : 94487287 : enum x86_64_reg_class regclass[MAX_CLASSES];
2695 : 94487287 : int n;
2696 : 94487287 : int i;
2697 : 94487287 : int nexps = 0;
2698 : 94487287 : int needed_sseregs, needed_intregs;
2699 : 94487287 : rtx exp[MAX_CLASSES];
2700 : 94487287 : rtx ret;
2701 : :
2702 : 94487287 : n = classify_argument (mode, type, regclass, 0);
2703 : 94487287 : if (!n)
2704 : : return NULL;
2705 : 94048344 : if (examine_argument (mode, type, in_return, &needed_intregs,
2706 : : &needed_sseregs))
2707 : : return NULL;
2708 : 94000611 : if (needed_intregs > nintregs || needed_sseregs > nsseregs)
2709 : : return NULL;
2710 : :
2711 : : /* We allowed the user to turn off SSE for kernel mode. Don't crash if
2712 : : some less clueful developer tries to use floating-point anyway. */
2713 : 92929806 : if (needed_sseregs
2714 : 32029975 : && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2)))
2715 : : {
2716 : : /* Return early if we shouldn't raise an error for invalid
2717 : : calls. */
2718 : 68 : if (cfun != NULL && cfun->machine->silent_p)
2719 : : return NULL;
2720 : 43 : if (in_return)
2721 : : {
2722 : 37 : if (!issued_sse_ret_error)
2723 : : {
2724 : 18 : if (VALID_SSE2_TYPE_MODE (mode))
2725 : 6 : error ("SSE register return with SSE2 disabled");
2726 : : else
2727 : 12 : error ("SSE register return with SSE disabled");
2728 : 18 : issued_sse_ret_error = true;
2729 : : }
2730 : : }
2731 : 6 : else if (!issued_sse_arg_error)
2732 : : {
2733 : 6 : if (VALID_SSE2_TYPE_MODE (mode))
2734 : 0 : error ("SSE register argument with SSE2 disabled");
2735 : : else
2736 : 6 : error ("SSE register argument with SSE disabled");
2737 : 6 : issued_sse_arg_error = true;
2738 : : }
2739 : 43 : return NULL;
2740 : : }
2741 : :
2742 : : /* Likewise, error if the ABI requires us to return values in the
2743 : : x87 registers and the user specified -mno-80387. */
2744 : 92929738 : if (!TARGET_FLOAT_RETURNS_IN_80387 && in_return)
2745 : 1364687 : for (i = 0; i < n; i++)
2746 : 716873 : if (regclass[i] == X86_64_X87_CLASS
2747 : : || regclass[i] == X86_64_X87UP_CLASS
2748 : 716873 : || regclass[i] == X86_64_COMPLEX_X87_CLASS)
2749 : : {
2750 : : /* Return early if we shouldn't raise an error for invalid
2751 : : calls. */
2752 : 15 : if (cfun != NULL && cfun->machine->silent_p)
2753 : : return NULL;
2754 : 12 : if (!issued_x87_ret_error)
2755 : : {
2756 : 7 : error ("x87 register return with x87 disabled");
2757 : 7 : issued_x87_ret_error = true;
2758 : : }
2759 : 12 : return NULL;
2760 : : }
2761 : :
2762 : : /* First construct simple cases. Avoid SCmode, since we want to use
2763 : : single register to pass this type. */
2764 : 92929723 : if (n == 1 && mode != SCmode && mode != HCmode)
2765 : 61369472 : switch (regclass[0])
2766 : : {
2767 : 55471765 : case X86_64_INTEGER_CLASS:
2768 : 55471765 : case X86_64_INTEGERSI_CLASS:
2769 : 55471765 : return gen_rtx_REG (mode, intreg[0]);
2770 : 5706777 : case X86_64_SSE_CLASS:
2771 : 5706777 : case X86_64_SSEHF_CLASS:
2772 : 5706777 : case X86_64_SSESF_CLASS:
2773 : 5706777 : case X86_64_SSEDF_CLASS:
2774 : 5706777 : if (mode != BLKmode)
2775 : 11412746 : return gen_reg_or_parallel (mode, orig_mode,
2776 : 11412746 : GET_SSE_REGNO (sse_regno));
2777 : : break;
2778 : 166671 : case X86_64_X87_CLASS:
2779 : 166671 : case X86_64_COMPLEX_X87_CLASS:
2780 : 166671 : return gen_rtx_REG (mode, FIRST_STACK_REG);
2781 : : case X86_64_NO_CLASS:
2782 : : /* Zero sized array, struct or class. */
2783 : : return NULL;
2784 : 0 : default:
2785 : 0 : gcc_unreachable ();
2786 : : }
2787 : 31560655 : if (n == 2
2788 : 16636220 : && regclass[0] == X86_64_SSE_CLASS
2789 : 11149465 : && regclass[1] == X86_64_SSEUP_CLASS
2790 : 11144699 : && mode != BLKmode)
2791 : 22289398 : return gen_reg_or_parallel (mode, orig_mode,
2792 : 22289398 : GET_SSE_REGNO (sse_regno));
2793 : 20415956 : if (n == 4
2794 : 7002794 : && regclass[0] == X86_64_SSE_CLASS
2795 : 7002794 : && regclass[1] == X86_64_SSEUP_CLASS
2796 : 7002794 : && regclass[2] == X86_64_SSEUP_CLASS
2797 : 7002794 : && regclass[3] == X86_64_SSEUP_CLASS
2798 : 7002794 : && mode != BLKmode)
2799 : 14002210 : return gen_reg_or_parallel (mode, orig_mode,
2800 : 14002210 : GET_SSE_REGNO (sse_regno));
2801 : 13414851 : if (n == 8
2802 : 7677854 : && regclass[0] == X86_64_SSE_CLASS
2803 : 7677854 : && regclass[1] == X86_64_SSEUP_CLASS
2804 : 7677854 : && regclass[2] == X86_64_SSEUP_CLASS
2805 : 7677854 : && regclass[3] == X86_64_SSEUP_CLASS
2806 : 7677854 : && regclass[4] == X86_64_SSEUP_CLASS
2807 : 7677854 : && regclass[5] == X86_64_SSEUP_CLASS
2808 : 7677854 : && regclass[6] == X86_64_SSEUP_CLASS
2809 : 7677854 : && regclass[7] == X86_64_SSEUP_CLASS
2810 : 7677854 : && mode != BLKmode)
2811 : 15351452 : return gen_reg_or_parallel (mode, orig_mode,
2812 : 15351452 : GET_SSE_REGNO (sse_regno));
2813 : 5739125 : if (n == 2
2814 : 5491521 : && regclass[0] == X86_64_X87_CLASS
2815 : 2211261 : && regclass[1] == X86_64_X87UP_CLASS)
2816 : 2211261 : return gen_rtx_REG (XFmode, FIRST_STACK_REG);
2817 : :
2818 : 3527864 : if (n == 2
2819 : 3280260 : && regclass[0] == X86_64_INTEGER_CLASS
2820 : 2915033 : && regclass[1] == X86_64_INTEGER_CLASS
2821 : 2906944 : && (mode == CDImode || mode == TImode || mode == BLKmode)
2822 : 2906944 : && intreg[0] + 1 == intreg[1])
2823 : : {
2824 : 2621316 : if (mode == BLKmode)
2825 : : {
2826 : : /* Use TImode for BLKmode values in 2 integer registers. */
2827 : 494080 : exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
2828 : 247040 : gen_rtx_REG (TImode, intreg[0]),
2829 : : GEN_INT (0));
2830 : 247040 : ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
2831 : 247040 : XVECEXP (ret, 0, 0) = exp[0];
2832 : 247040 : return ret;
2833 : : }
2834 : : else
2835 : 2374276 : return gen_rtx_REG (mode, intreg[0]);
2836 : : }
2837 : :
2838 : : /* Otherwise figure out the entries of the PARALLEL. */
2839 : 2472040 : for (i = 0; i < n; i++)
2840 : : {
2841 : 1565492 : int pos;
2842 : :
2843 : 1565492 : switch (regclass[i])
2844 : : {
2845 : : case X86_64_NO_CLASS:
2846 : : break;
2847 : 812251 : case X86_64_INTEGER_CLASS:
2848 : 812251 : case X86_64_INTEGERSI_CLASS:
2849 : : /* Merge TImodes on aligned occasions here too. */
2850 : 812251 : if (i * 8 + 8 > bytes)
2851 : : {
2852 : 3153 : unsigned int tmpbits = (bytes - i * 8) * BITS_PER_UNIT;
2853 : 5947 : if (!int_mode_for_size (tmpbits, 0).exists (&tmpmode))
2854 : : /* We've requested 24 bytes we
2855 : : don't have mode for. Use DImode. */
2856 : 694091 : tmpmode = DImode;
2857 : : }
2858 : 809098 : else if (regclass[i] == X86_64_INTEGERSI_CLASS)
2859 : : tmpmode = SImode;
2860 : : else
2861 : 694091 : tmpmode = DImode;
2862 : 1624502 : exp [nexps++]
2863 : 812251 : = gen_rtx_EXPR_LIST (VOIDmode,
2864 : 812251 : gen_rtx_REG (tmpmode, *intreg),
2865 : 812251 : GEN_INT (i*8));
2866 : 812251 : intreg++;
2867 : 812251 : break;
2868 : 584 : case X86_64_SSEHF_CLASS:
2869 : 584 : tmpmode = (mode == BFmode ? BFmode : HFmode);
2870 : 1168 : exp [nexps++]
2871 : 1168 : = gen_rtx_EXPR_LIST (VOIDmode,
2872 : : gen_rtx_REG (tmpmode,
2873 : 584 : GET_SSE_REGNO (sse_regno)),
2874 : 584 : GEN_INT (i*8));
2875 : 584 : sse_regno++;
2876 : 584 : break;
2877 : 2828 : case X86_64_SSESF_CLASS:
2878 : 5656 : exp [nexps++]
2879 : 5656 : = gen_rtx_EXPR_LIST (VOIDmode,
2880 : : gen_rtx_REG (SFmode,
2881 : 2828 : GET_SSE_REGNO (sse_regno)),
2882 : 2828 : GEN_INT (i*8));
2883 : 2828 : sse_regno++;
2884 : 2828 : break;
2885 : 485020 : case X86_64_SSEDF_CLASS:
2886 : 970040 : exp [nexps++]
2887 : 970040 : = gen_rtx_EXPR_LIST (VOIDmode,
2888 : : gen_rtx_REG (DFmode,
2889 : 485020 : GET_SSE_REGNO (sse_regno)),
2890 : 485020 : GEN_INT (i*8));
2891 : 485020 : sse_regno++;
2892 : 485020 : break;
2893 : 256746 : case X86_64_SSE_CLASS:
2894 : 256746 : pos = i;
2895 : 256746 : switch (n)
2896 : : {
2897 : : case 1:
2898 : : tmpmode = DImode;
2899 : : break;
2900 : 9356 : case 2:
2901 : 9356 : if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
2902 : : {
2903 : 0 : tmpmode = TImode;
2904 : 0 : i++;
2905 : : }
2906 : : else
2907 : : tmpmode = DImode;
2908 : : break;
2909 : 1689 : case 4:
2910 : 1689 : gcc_assert (i == 0
2911 : : && regclass[1] == X86_64_SSEUP_CLASS
2912 : : && regclass[2] == X86_64_SSEUP_CLASS
2913 : : && regclass[3] == X86_64_SSEUP_CLASS);
2914 : : tmpmode = OImode;
2915 : : i += 3;
2916 : : break;
2917 : 2128 : case 8:
2918 : 2128 : gcc_assert (i == 0
2919 : : && regclass[1] == X86_64_SSEUP_CLASS
2920 : : && regclass[2] == X86_64_SSEUP_CLASS
2921 : : && regclass[3] == X86_64_SSEUP_CLASS
2922 : : && regclass[4] == X86_64_SSEUP_CLASS
2923 : : && regclass[5] == X86_64_SSEUP_CLASS
2924 : : && regclass[6] == X86_64_SSEUP_CLASS
2925 : : && regclass[7] == X86_64_SSEUP_CLASS);
2926 : : tmpmode = XImode;
2927 : : i += 7;
2928 : : break;
2929 : 0 : default:
2930 : 0 : gcc_unreachable ();
2931 : : }
2932 : 513492 : exp [nexps++]
2933 : 513492 : = gen_rtx_EXPR_LIST (VOIDmode,
2934 : : gen_rtx_REG (tmpmode,
2935 : 256746 : GET_SSE_REGNO (sse_regno)),
2936 : 256746 : GEN_INT (pos*8));
2937 : 256746 : sse_regno++;
2938 : 256746 : break;
2939 : 0 : default:
2940 : 0 : gcc_unreachable ();
2941 : : }
2942 : : }
2943 : :
2944 : : /* Empty aligned struct, union or class. */
2945 : 906548 : if (nexps == 0)
2946 : : return NULL;
2947 : :
2948 : 906286 : ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
2949 : 2463715 : for (i = 0; i < nexps; i++)
2950 : 1557429 : XVECEXP (ret, 0, i) = exp [i];
2951 : : return ret;
2952 : : }
2953 : :
2954 : : /* Update the data in CUM to advance over an argument of mode MODE
2955 : : and data type TYPE. (TYPE is null for libcalls where that information
2956 : : may not be available.)
2957 : :
2958 : : Return a number of integer regsiters advanced over. */
2959 : :
2960 : : static int
2961 : 2091413 : function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
2962 : : const_tree type, HOST_WIDE_INT bytes,
2963 : : HOST_WIDE_INT words)
2964 : : {
2965 : 2091413 : int res = 0;
2966 : 2091413 : bool error_p = false;
2967 : :
2968 : 2091413 : if (TARGET_IAMCU)
2969 : : {
2970 : : /* Intel MCU psABI passes scalars and aggregates no larger than 8
2971 : : bytes in registers. */
2972 : 0 : if (!VECTOR_MODE_P (mode) && bytes <= 8)
2973 : 0 : goto pass_in_reg;
2974 : : return res;
2975 : : }
2976 : :
2977 : 2091413 : switch (mode)
2978 : : {
2979 : : default:
2980 : : break;
2981 : :
2982 : 93580 : case E_BLKmode:
2983 : 93580 : if (bytes < 0)
2984 : : break;
2985 : : /* FALLTHRU */
2986 : :
2987 : 2054738 : case E_DImode:
2988 : 2054738 : case E_SImode:
2989 : 2054738 : case E_HImode:
2990 : 2054738 : case E_QImode:
2991 : 93580 : pass_in_reg:
2992 : 2054738 : cum->words += words;
2993 : 2054738 : cum->nregs -= words;
2994 : 2054738 : cum->regno += words;
2995 : 2054738 : if (cum->nregs >= 0)
2996 : 45603 : res = words;
2997 : 2054738 : if (cum->nregs <= 0)
2998 : : {
2999 : 2022063 : cum->nregs = 0;
3000 : 2022063 : cfun->machine->arg_reg_available = false;
3001 : 2022063 : cum->regno = 0;
3002 : : }
3003 : : break;
3004 : :
3005 : 0 : case E_OImode:
3006 : : /* OImode shouldn't be used directly. */
3007 : 0 : gcc_unreachable ();
3008 : :
3009 : 4687 : case E_DFmode:
3010 : 4687 : if (cum->float_in_sse == -1)
3011 : 0 : error_p = true;
3012 : 4687 : if (cum->float_in_sse < 2)
3013 : : break;
3014 : : /* FALLTHRU */
3015 : 1351 : case E_SFmode:
3016 : 1351 : if (cum->float_in_sse == -1)
3017 : 0 : error_p = true;
3018 : 1351 : if (cum->float_in_sse < 1)
3019 : : break;
3020 : : /* FALLTHRU */
3021 : :
3022 : 52 : case E_V16HFmode:
3023 : 52 : case E_V16BFmode:
3024 : 52 : case E_V8SFmode:
3025 : 52 : case E_V8SImode:
3026 : 52 : case E_V64QImode:
3027 : 52 : case E_V32HImode:
3028 : 52 : case E_V16SImode:
3029 : 52 : case E_V8DImode:
3030 : 52 : case E_V32HFmode:
3031 : 52 : case E_V32BFmode:
3032 : 52 : case E_V16SFmode:
3033 : 52 : case E_V8DFmode:
3034 : 52 : case E_V32QImode:
3035 : 52 : case E_V16HImode:
3036 : 52 : case E_V4DFmode:
3037 : 52 : case E_V4DImode:
3038 : 52 : case E_TImode:
3039 : 52 : case E_V16QImode:
3040 : 52 : case E_V8HImode:
3041 : 52 : case E_V4SImode:
3042 : 52 : case E_V2DImode:
3043 : 52 : case E_V8HFmode:
3044 : 52 : case E_V8BFmode:
3045 : 52 : case E_V4SFmode:
3046 : 52 : case E_V2DFmode:
3047 : 52 : if (!type || !AGGREGATE_TYPE_P (type))
3048 : : {
3049 : 52 : cum->sse_words += words;
3050 : 52 : cum->sse_nregs -= 1;
3051 : 52 : cum->sse_regno += 1;
3052 : 52 : if (cum->sse_nregs <= 0)
3053 : : {
3054 : 4 : cum->sse_nregs = 0;
3055 : 4 : cum->sse_regno = 0;
3056 : : }
3057 : : }
3058 : : break;
3059 : :
3060 : 12 : case E_V8QImode:
3061 : 12 : case E_V4HImode:
3062 : 12 : case E_V4HFmode:
3063 : 12 : case E_V4BFmode:
3064 : 12 : case E_V2SImode:
3065 : 12 : case E_V2SFmode:
3066 : 12 : case E_V1TImode:
3067 : 12 : case E_V1DImode:
3068 : 12 : if (!type || !AGGREGATE_TYPE_P (type))
3069 : : {
3070 : 12 : cum->mmx_words += words;
3071 : 12 : cum->mmx_nregs -= 1;
3072 : 12 : cum->mmx_regno += 1;
3073 : 12 : if (cum->mmx_nregs <= 0)
3074 : : {
3075 : 0 : cum->mmx_nregs = 0;
3076 : 0 : cum->mmx_regno = 0;
3077 : : }
3078 : : }
3079 : : break;
3080 : : }
3081 : 2028153 : if (error_p)
3082 : : {
3083 : 0 : cum->float_in_sse = 0;
3084 : 0 : error ("calling %qD with SSE calling convention without "
3085 : : "SSE/SSE2 enabled", cum->decl);
3086 : 0 : sorry ("this is a GCC bug that can be worked around by adding "
3087 : : "attribute used to function called");
3088 : : }
3089 : :
3090 : : return res;
3091 : : }
3092 : :
3093 : : static int
3094 : 17481097 : function_arg_advance_64 (CUMULATIVE_ARGS *cum, machine_mode mode,
3095 : : const_tree type, HOST_WIDE_INT words, bool named)
3096 : : {
3097 : 17481097 : int int_nregs, sse_nregs;
3098 : :
3099 : : /* Unnamed 512 and 256bit vector mode parameters are passed on stack. */
3100 : 17481097 : if (!named && (VALID_AVX512F_REG_MODE (mode)
3101 : : || VALID_AVX256_REG_MODE (mode)))
3102 : : return 0;
3103 : :
3104 : 17480733 : if (!examine_argument (mode, type, 0, &int_nregs, &sse_nregs)
3105 : 17480733 : && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
3106 : : {
3107 : 15256817 : cum->nregs -= int_nregs;
3108 : 15256817 : cum->sse_nregs -= sse_nregs;
3109 : 15256817 : cum->regno += int_nregs;
3110 : 15256817 : cum->sse_regno += sse_nregs;
3111 : 15256817 : return int_nregs;
3112 : : }
3113 : : else
3114 : : {
3115 : 2223916 : int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
3116 : 2223916 : cum->words = ROUND_UP (cum->words, align);
3117 : 2223916 : cum->words += words;
3118 : 2223916 : return 0;
3119 : : }
3120 : : }
3121 : :
3122 : : static int
3123 : 447221 : function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
3124 : : HOST_WIDE_INT words)
3125 : : {
3126 : : /* Otherwise, this should be passed indirect. */
3127 : 447221 : gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
3128 : :
3129 : 447221 : cum->words += words;
3130 : 447221 : if (cum->nregs > 0)
3131 : : {
3132 : 289536 : cum->nregs -= 1;
3133 : 289536 : cum->regno += 1;
3134 : 289536 : return 1;
3135 : : }
3136 : : return 0;
3137 : : }
3138 : :
3139 : : /* Update the data in CUM to advance over argument ARG. */
3140 : :
3141 : : static void
3142 : 20020085 : ix86_function_arg_advance (cumulative_args_t cum_v,
3143 : : const function_arg_info &arg)
3144 : : {
3145 : 20020085 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3146 : 20020085 : machine_mode mode = arg.mode;
3147 : 20020085 : HOST_WIDE_INT bytes, words;
3148 : 20020085 : int nregs;
3149 : :
3150 : : /* The argument of interrupt handler is a special case and is
3151 : : handled in ix86_function_arg. */
3152 : 20020085 : if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
3153 : : return;
3154 : :
3155 : 20019731 : bytes = arg.promoted_size_in_bytes ();
3156 : 20019731 : words = CEIL (bytes, UNITS_PER_WORD);
3157 : :
3158 : 20019731 : if (arg.type)
3159 : 19742164 : mode = type_natural_mode (arg.type, NULL, false);
3160 : :
3161 : 20019731 : if (TARGET_64BIT)
3162 : : {
3163 : 17928318 : enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
3164 : :
3165 : 17928318 : if (call_abi == MS_ABI)
3166 : 447221 : nregs = function_arg_advance_ms_64 (cum, bytes, words);
3167 : : else
3168 : 17481097 : nregs = function_arg_advance_64 (cum, mode, arg.type, words,
3169 : 17481097 : arg.named);
3170 : : }
3171 : : else
3172 : 2091413 : nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
3173 : :
3174 : 20019731 : if (!nregs)
3175 : : {
3176 : : /* Track if there are outgoing arguments on stack. */
3177 : 5549423 : if (cum->caller)
3178 : 2668929 : cfun->machine->outgoing_args_on_stack = true;
3179 : : }
3180 : : }
3181 : :
3182 : : /* Define where to put the arguments to a function.
3183 : : Value is zero to push the argument on the stack,
3184 : : or a hard register in which to store the argument.
3185 : :
3186 : : MODE is the argument's machine mode.
3187 : : TYPE is the data type of the argument (as a tree).
3188 : : This is null for libcalls where that information may
3189 : : not be available.
3190 : : CUM is a variable of type CUMULATIVE_ARGS which gives info about
3191 : : the preceding args and about the function being called.
3192 : : NAMED is nonzero if this argument is a named parameter
3193 : : (otherwise it is an extra parameter matching an ellipsis). */
3194 : :
3195 : : static rtx
3196 : 2518952 : function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
3197 : : machine_mode orig_mode, const_tree type,
3198 : : HOST_WIDE_INT bytes, HOST_WIDE_INT words)
3199 : : {
3200 : 2518952 : bool error_p = false;
3201 : :
3202 : : /* Avoid the AL settings for the Unix64 ABI. */
3203 : 2518952 : if (mode == VOIDmode)
3204 : 734400 : return constm1_rtx;
3205 : :
3206 : 1784552 : if (TARGET_IAMCU)
3207 : : {
3208 : : /* Intel MCU psABI passes scalars and aggregates no larger than 8
3209 : : bytes in registers. */
3210 : 0 : if (!VECTOR_MODE_P (mode) && bytes <= 8)
3211 : 0 : goto pass_in_reg;
3212 : : return NULL_RTX;
3213 : : }
3214 : :
3215 : 1784552 : switch (mode)
3216 : : {
3217 : : default:
3218 : : break;
3219 : :
3220 : 77611 : case E_BLKmode:
3221 : 77611 : if (bytes < 0)
3222 : : break;
3223 : : /* FALLTHRU */
3224 : 1751126 : case E_DImode:
3225 : 1751126 : case E_SImode:
3226 : 1751126 : case E_HImode:
3227 : 1751126 : case E_QImode:
3228 : 77611 : pass_in_reg:
3229 : 1751126 : if (words <= cum->nregs)
3230 : : {
3231 : 43771 : int regno = cum->regno;
3232 : :
3233 : : /* Fastcall allocates the first two DWORD (SImode) or
3234 : : smaller arguments to ECX and EDX if it isn't an
3235 : : aggregate type . */
3236 : 43771 : if (cum->fastcall)
3237 : : {
3238 : 6 : if (mode == BLKmode
3239 : 6 : || mode == DImode
3240 : 6 : || (type && AGGREGATE_TYPE_P (type)))
3241 : : break;
3242 : :
3243 : : /* ECX not EAX is the first allocated register. */
3244 : 6 : if (regno == AX_REG)
3245 : 43771 : regno = CX_REG;
3246 : : }
3247 : 43771 : return gen_rtx_REG (mode, regno);
3248 : : }
3249 : : break;
3250 : :
3251 : 3305 : case E_DFmode:
3252 : 3305 : if (cum->float_in_sse == -1)
3253 : 0 : error_p = true;
3254 : 3305 : if (cum->float_in_sse < 2)
3255 : : break;
3256 : : /* FALLTHRU */
3257 : 963 : case E_SFmode:
3258 : 963 : if (cum->float_in_sse == -1)
3259 : 0 : error_p = true;
3260 : 963 : if (cum->float_in_sse < 1)
3261 : : break;
3262 : : /* FALLTHRU */
3263 : 12 : case E_TImode:
3264 : : /* In 32bit, we pass TImode in xmm registers. */
3265 : 12 : case E_V16QImode:
3266 : 12 : case E_V8HImode:
3267 : 12 : case E_V4SImode:
3268 : 12 : case E_V2DImode:
3269 : 12 : case E_V8HFmode:
3270 : 12 : case E_V8BFmode:
3271 : 12 : case E_V4SFmode:
3272 : 12 : case E_V2DFmode:
3273 : 12 : if (!type || !AGGREGATE_TYPE_P (type))
3274 : : {
3275 : 12 : if (cum->sse_nregs)
3276 : 12 : return gen_reg_or_parallel (mode, orig_mode,
3277 : 12 : cum->sse_regno + FIRST_SSE_REG);
3278 : : }
3279 : : break;
3280 : :
3281 : 0 : case E_OImode:
3282 : 0 : case E_XImode:
3283 : : /* OImode and XImode shouldn't be used directly. */
3284 : 0 : gcc_unreachable ();
3285 : :
3286 : 9 : case E_V64QImode:
3287 : 9 : case E_V32HImode:
3288 : 9 : case E_V16SImode:
3289 : 9 : case E_V8DImode:
3290 : 9 : case E_V32HFmode:
3291 : 9 : case E_V32BFmode:
3292 : 9 : case E_V16SFmode:
3293 : 9 : case E_V8DFmode:
3294 : 9 : case E_V16HFmode:
3295 : 9 : case E_V16BFmode:
3296 : 9 : case E_V8SFmode:
3297 : 9 : case E_V8SImode:
3298 : 9 : case E_V32QImode:
3299 : 9 : case E_V16HImode:
3300 : 9 : case E_V4DFmode:
3301 : 9 : case E_V4DImode:
3302 : 9 : if (!type || !AGGREGATE_TYPE_P (type))
3303 : : {
3304 : 9 : if (cum->sse_nregs)
3305 : 9 : return gen_reg_or_parallel (mode, orig_mode,
3306 : 9 : cum->sse_regno + FIRST_SSE_REG);
3307 : : }
3308 : : break;
3309 : :
3310 : 6 : case E_V8QImode:
3311 : 6 : case E_V4HImode:
3312 : 6 : case E_V4HFmode:
3313 : 6 : case E_V4BFmode:
3314 : 6 : case E_V2SImode:
3315 : 6 : case E_V2SFmode:
3316 : 6 : case E_V1TImode:
3317 : 6 : case E_V1DImode:
3318 : 6 : if (!type || !AGGREGATE_TYPE_P (type))
3319 : : {
3320 : 6 : if (cum->mmx_nregs)
3321 : 6 : return gen_reg_or_parallel (mode, orig_mode,
3322 : 6 : cum->mmx_regno + FIRST_MMX_REG);
3323 : : }
3324 : : break;
3325 : : }
3326 : 4268 : if (error_p)
3327 : : {
3328 : 0 : cum->float_in_sse = 0;
3329 : 0 : error ("calling %qD with SSE calling convention without "
3330 : : "SSE/SSE2 enabled", cum->decl);
3331 : 0 : sorry ("this is a GCC bug that can be worked around by adding "
3332 : : "attribute used to function called");
3333 : : }
3334 : :
3335 : : return NULL_RTX;
3336 : : }
3337 : :
3338 : : static rtx
3339 : 17390904 : function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
3340 : : machine_mode orig_mode, const_tree type, bool named)
3341 : : {
3342 : : /* Handle a hidden AL argument containing number of registers
3343 : : for varargs x86-64 functions. */
3344 : 17390904 : if (mode == VOIDmode)
3345 : 4818116 : return GEN_INT (cum->maybe_vaarg
3346 : : ? (cum->sse_nregs < 0
3347 : : ? X86_64_SSE_REGPARM_MAX
3348 : : : cum->sse_regno)
3349 : : : -1);
3350 : :
3351 : 12572788 : switch (mode)
3352 : : {
3353 : : default:
3354 : : break;
3355 : :
3356 : 77499 : case E_V16HFmode:
3357 : 77499 : case E_V16BFmode:
3358 : 77499 : case E_V8SFmode:
3359 : 77499 : case E_V8SImode:
3360 : 77499 : case E_V32QImode:
3361 : 77499 : case E_V16HImode:
3362 : 77499 : case E_V4DFmode:
3363 : 77499 : case E_V4DImode:
3364 : 77499 : case E_V32HFmode:
3365 : 77499 : case E_V32BFmode:
3366 : 77499 : case E_V16SFmode:
3367 : 77499 : case E_V16SImode:
3368 : 77499 : case E_V64QImode:
3369 : 77499 : case E_V32HImode:
3370 : 77499 : case E_V8DFmode:
3371 : 77499 : case E_V8DImode:
3372 : : /* Unnamed 256 and 512bit vector mode parameters are passed on stack. */
3373 : 77499 : if (!named)
3374 : : return NULL;
3375 : : break;
3376 : : }
3377 : :
3378 : 12572424 : return construct_container (mode, orig_mode, type, 0, cum->nregs,
3379 : 12572424 : cum->sse_nregs,
3380 : 12572424 : &x86_64_int_parameter_registers [cum->regno],
3381 : 12572424 : cum->sse_regno);
3382 : : }
3383 : :
3384 : : static rtx
3385 : 296636 : function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
3386 : : machine_mode orig_mode, bool named, const_tree type,
3387 : : HOST_WIDE_INT bytes)
3388 : : {
3389 : 296636 : unsigned int regno;
3390 : :
3391 : : /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
3392 : : We use value of -2 to specify that current function call is MSABI. */
3393 : 296636 : if (mode == VOIDmode)
3394 : 36357 : return GEN_INT (-2);
3395 : :
3396 : : /* If we've run out of registers, it goes on the stack. */
3397 : 260279 : if (cum->nregs == 0)
3398 : : return NULL_RTX;
3399 : :
3400 : 176473 : regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
3401 : :
3402 : : /* Only floating point modes are passed in anything but integer regs. */
3403 : 176473 : if (TARGET_SSE && (mode == SFmode || mode == DFmode))
3404 : : {
3405 : 38334 : if (named)
3406 : : {
3407 : 38334 : if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
3408 : 37337 : regno = cum->regno + FIRST_SSE_REG;
3409 : : }
3410 : : else
3411 : : {
3412 : 0 : rtx t1, t2;
3413 : :
3414 : : /* Unnamed floating parameters are passed in both the
3415 : : SSE and integer registers. */
3416 : 0 : t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
3417 : 0 : t2 = gen_rtx_REG (mode, regno);
3418 : 0 : t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
3419 : 0 : t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
3420 : 0 : return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
3421 : : }
3422 : : }
3423 : : /* Handle aggregated types passed in register. */
3424 : 176473 : if (orig_mode == BLKmode)
3425 : : {
3426 : 0 : if (bytes > 0 && bytes <= 8)
3427 : 0 : mode = (bytes > 4 ? DImode : SImode);
3428 : 0 : if (mode == BLKmode)
3429 : 0 : mode = DImode;
3430 : : }
3431 : :
3432 : 176473 : return gen_reg_or_parallel (mode, orig_mode, regno);
3433 : : }
3434 : :
3435 : : /* Return where to put the arguments to a function.
3436 : : Return zero to push the argument on the stack, or a hard register in which to store the argument.
3437 : :
3438 : : ARG describes the argument while CUM gives information about the
3439 : : preceding args and about the function being called. */
3440 : :
3441 : : static rtx
3442 : 20206673 : ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
3443 : : {
3444 : 20206673 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3445 : 20206673 : machine_mode mode = arg.mode;
3446 : 20206673 : HOST_WIDE_INT bytes, words;
3447 : 20206673 : rtx reg;
3448 : :
3449 : 20206673 : if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
3450 : : {
3451 : 181 : gcc_assert (arg.type != NULL_TREE);
3452 : 181 : if (POINTER_TYPE_P (arg.type))
3453 : : {
3454 : : /* This is the pointer argument. */
3455 : 118 : gcc_assert (TYPE_MODE (arg.type) == ptr_mode);
3456 : : /* It is at -WORD(AP) in the current frame in interrupt and
3457 : : exception handlers. */
3458 : 118 : reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
3459 : : }
3460 : : else
3461 : : {
3462 : 63 : gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
3463 : : && TREE_CODE (arg.type) == INTEGER_TYPE
3464 : : && TYPE_MODE (arg.type) == word_mode);
3465 : : /* The error code is the word-mode integer argument at
3466 : : -2 * WORD(AP) in the current frame of the exception
3467 : : handler. */
3468 : 63 : reg = gen_rtx_MEM (word_mode,
3469 : 63 : plus_constant (Pmode,
3470 : : arg_pointer_rtx,
3471 : 63 : -2 * UNITS_PER_WORD));
3472 : : }
3473 : 181 : return reg;
3474 : : }
3475 : :
3476 : 20206492 : bytes = arg.promoted_size_in_bytes ();
3477 : 20206492 : words = CEIL (bytes, UNITS_PER_WORD);
3478 : :
3479 : : /* To simplify the code below, represent vector types with a vector mode
3480 : : even if MMX/SSE are not active. */
3481 : 20206492 : if (arg.type && VECTOR_TYPE_P (arg.type))
3482 : 150470 : mode = type_natural_mode (arg.type, cum, false);
3483 : :
3484 : 20206492 : if (TARGET_64BIT)
3485 : : {
3486 : 17687540 : enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
3487 : :
3488 : 17687540 : if (call_abi == MS_ABI)
3489 : 296636 : reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
3490 : 296636 : arg.type, bytes);
3491 : : else
3492 : 17390904 : reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
3493 : : }
3494 : : else
3495 : 2518952 : reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
3496 : :
3497 : : /* Track if there are outgoing arguments on stack. */
3498 : 20206492 : if (reg == NULL_RTX && cum->caller)
3499 : 2145587 : cfun->machine->outgoing_args_on_stack = true;
3500 : :
3501 : : return reg;
3502 : : }
3503 : :
3504 : : /* A C expression that indicates when an argument must be passed by
3505 : : reference. If nonzero for an argument, a copy of that argument is
3506 : : made in memory and a pointer to the argument is passed instead of
3507 : : the argument itself. The pointer is passed in whatever way is
3508 : : appropriate for passing a pointer to that type. */
3509 : :
3510 : : static bool
3511 : 19980382 : ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
3512 : : {
3513 : 19980382 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
3514 : :
3515 : 19980382 : if (TARGET_64BIT)
3516 : : {
3517 : 17899250 : enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
3518 : :
3519 : : /* See Windows x64 Software Convention. */
3520 : 17899250 : if (call_abi == MS_ABI)
3521 : : {
3522 : 441622 : HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
3523 : :
3524 : 441622 : if (tree type = arg.type)
3525 : : {
3526 : : /* Arrays are passed by reference. */
3527 : 441622 : if (TREE_CODE (type) == ARRAY_TYPE)
3528 : : return true;
3529 : :
3530 : 441622 : if (RECORD_OR_UNION_TYPE_P (type))
3531 : : {
3532 : : /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
3533 : : are passed by reference. */
3534 : 15036 : msize = int_size_in_bytes (type);
3535 : : }
3536 : : }
3537 : :
3538 : : /* __m128 is passed by reference. */
3539 : 873293 : return msize != 1 && msize != 2 && msize != 4 && msize != 8;
3540 : : }
3541 : 17457628 : else if (arg.type && int_size_in_bytes (arg.type) == -1)
3542 : : return true;
3543 : : }
3544 : :
3545 : : return false;
3546 : : }
3547 : :
3548 : : /* Return true when TYPE should be 128bit aligned for 32bit argument
3549 : : passing ABI. XXX: This function is obsolete and is only used for
3550 : : checking psABI compatibility with previous versions of GCC. */
3551 : :
3552 : : static bool
3553 : 1931842 : ix86_compat_aligned_value_p (const_tree type)
3554 : : {
3555 : 1931842 : machine_mode mode = TYPE_MODE (type);
3556 : 1931842 : if (((TARGET_SSE && SSE_REG_MODE_P (mode))
3557 : 1931800 : || mode == TDmode
3558 : 1931800 : || mode == TFmode
3559 : : || mode == TCmode)
3560 : 1932054 : && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
3561 : : return true;
3562 : 1931630 : if (TYPE_ALIGN (type) < 128)
3563 : : return false;
3564 : :
3565 : 0 : if (AGGREGATE_TYPE_P (type))
3566 : : {
3567 : : /* Walk the aggregates recursively. */
3568 : 0 : switch (TREE_CODE (type))
3569 : : {
3570 : 0 : case RECORD_TYPE:
3571 : 0 : case UNION_TYPE:
3572 : 0 : case QUAL_UNION_TYPE:
3573 : 0 : {
3574 : 0 : tree field;
3575 : :
3576 : : /* Walk all the structure fields. */
3577 : 0 : for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
3578 : : {
3579 : 0 : if (TREE_CODE (field) == FIELD_DECL
3580 : 0 : && ix86_compat_aligned_value_p (TREE_TYPE (field)))
3581 : : return true;
3582 : : }
3583 : : break;
3584 : : }
3585 : :
3586 : 0 : case ARRAY_TYPE:
3587 : : /* Just for use if some languages passes arrays by value. */
3588 : 0 : if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
3589 : : return true;
3590 : : break;
3591 : :
3592 : : default:
3593 : : gcc_unreachable ();
3594 : : }
3595 : : }
3596 : : return false;
3597 : : }
3598 : :
3599 : : /* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
3600 : : XXX: This function is obsolete and is only used for checking psABI
3601 : : compatibility with previous versions of GCC. */
3602 : :
3603 : : static unsigned int
3604 : 5239190 : ix86_compat_function_arg_boundary (machine_mode mode,
3605 : : const_tree type, unsigned int align)
3606 : : {
3607 : : /* In 32bit, only _Decimal128 and __float128 are aligned to their
3608 : : natural boundaries. */
3609 : 5239190 : if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
3610 : : {
3611 : : /* i386 ABI defines all arguments to be 4 byte aligned. We have to
3612 : : make an exception for SSE modes since these require 128bit
3613 : : alignment.
3614 : :
3615 : : The handling here differs from field_alignment. ICC aligns MMX
3616 : : arguments to 4 byte boundaries, while structure fields are aligned
3617 : : to 8 byte boundaries. */
3618 : 1943795 : if (!type)
3619 : : {
3620 : 11953 : if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
3621 : 1943583 : align = PARM_BOUNDARY;
3622 : : }
3623 : : else
3624 : : {
3625 : 1931842 : if (!ix86_compat_aligned_value_p (type))
3626 : 1931630 : align = PARM_BOUNDARY;
3627 : : }
3628 : : }
3629 : 10124370 : if (align > BIGGEST_ALIGNMENT)
3630 : 76 : align = BIGGEST_ALIGNMENT;
3631 : 5239190 : return align;
3632 : : }
3633 : :
3634 : : /* Return true when TYPE should be 128bit aligned for 32bit argument
3635 : : passing ABI. */
3636 : :
3637 : : static bool
3638 : 1934494 : ix86_contains_aligned_value_p (const_tree type)
3639 : : {
3640 : 1934494 : machine_mode mode = TYPE_MODE (type);
3641 : :
3642 : 1934494 : if (mode == XFmode || mode == XCmode)
3643 : : return false;
3644 : :
3645 : 1932402 : if (TYPE_ALIGN (type) < 128)
3646 : : return false;
3647 : :
3648 : 2864 : if (AGGREGATE_TYPE_P (type))
3649 : : {
3650 : : /* Walk the aggregates recursively. */
3651 : 0 : switch (TREE_CODE (type))
3652 : : {
3653 : 0 : case RECORD_TYPE:
3654 : 0 : case UNION_TYPE:
3655 : 0 : case QUAL_UNION_TYPE:
3656 : 0 : {
3657 : 0 : tree field;
3658 : :
3659 : : /* Walk all the structure fields. */
3660 : 0 : for (field = TYPE_FIELDS (type);
3661 : 0 : field;
3662 : 0 : field = DECL_CHAIN (field))
3663 : : {
3664 : 0 : if (TREE_CODE (field) == FIELD_DECL
3665 : 0 : && ix86_contains_aligned_value_p (TREE_TYPE (field)))
3666 : : return true;
3667 : : }
3668 : : break;
3669 : : }
3670 : :
3671 : 0 : case ARRAY_TYPE:
3672 : : /* Just for use if some languages passes arrays by value. */
3673 : 0 : if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
3674 : : return true;
3675 : : break;
3676 : :
3677 : : default:
3678 : : gcc_unreachable ();
3679 : : }
3680 : : }
3681 : : else
3682 : 2864 : return TYPE_ALIGN (type) >= 128;
3683 : :
3684 : : return false;
3685 : : }
3686 : :
3687 : : /* Gives the alignment boundary, in bits, of an argument with the
3688 : : specified mode and type. */
3689 : :
3690 : : static unsigned int
3691 : 10528190 : ix86_function_arg_boundary (machine_mode mode, const_tree type)
3692 : : {
3693 : 10528190 : unsigned int align;
3694 : 10528190 : if (type)
3695 : : {
3696 : : /* Since the main variant type is used for call, we convert it to
3697 : : the main variant type. */
3698 : 10488376 : type = TYPE_MAIN_VARIANT (type);
3699 : 10488376 : align = TYPE_ALIGN (type);
3700 : 10488376 : if (TYPE_EMPTY_P (type))
3701 : 21199 : return PARM_BOUNDARY;
3702 : : }
3703 : : else
3704 : 39814 : align = GET_MODE_ALIGNMENT (mode);
3705 : 12501728 : if (align < PARM_BOUNDARY)
3706 : 10528190 : align = PARM_BOUNDARY;
3707 : : else
3708 : : {
3709 : 6494774 : static bool warned;
3710 : 6494774 : unsigned int saved_align = align;
3711 : :
3712 : 6494774 : if (!TARGET_64BIT)
3713 : : {
3714 : : /* i386 ABI defines XFmode arguments to be 4 byte aligned. */
3715 : 1970305 : if (!type)
3716 : : {
3717 : 35811 : if (mode == XFmode || mode == XCmode)
3718 : : align = PARM_BOUNDARY;
3719 : : }
3720 : 1934494 : else if (!ix86_contains_aligned_value_p (type))
3721 : : align = PARM_BOUNDARY;
3722 : :
3723 : 38669 : if (align < 128)
3724 : 1943583 : align = PARM_BOUNDARY;
3725 : : }
3726 : :
3727 : 6494774 : if (warn_psabi
3728 : 5241838 : && !warned
3729 : 11733964 : && align != ix86_compat_function_arg_boundary (mode, type,
3730 : : saved_align))
3731 : : {
3732 : 76 : warned = true;
3733 : 76 : inform (input_location,
3734 : : "the ABI for passing parameters with %d-byte"
3735 : : " alignment has changed in GCC 4.6",
3736 : : align / BITS_PER_UNIT);
3737 : : }
3738 : : }
3739 : :
3740 : : return align;
3741 : : }
3742 : :
3743 : : /* Return true if N is a possible register number of function value. */
3744 : :
3745 : : static bool
3746 : 4376002 : ix86_function_value_regno_p (const unsigned int regno)
3747 : : {
3748 : 4376002 : switch (regno)
3749 : : {
3750 : : case AX_REG:
3751 : : return true;
3752 : 94858 : case DX_REG:
3753 : 94858 : return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI);
3754 : 89651 : case DI_REG:
3755 : 89651 : case SI_REG:
3756 : 89651 : return TARGET_64BIT && ix86_cfun_abi () != MS_ABI;
3757 : :
3758 : : /* Complex values are returned in %st(0)/%st(1) pair. */
3759 : 21446 : case ST0_REG:
3760 : 21446 : case ST1_REG:
3761 : : /* TODO: The function should depend on current function ABI but
3762 : : builtins.cc would need updating then. Therefore we use the
3763 : : default ABI. */
3764 : 21446 : if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI)
3765 : : return false;
3766 : 21446 : return TARGET_FLOAT_RETURNS_IN_80387;
3767 : :
3768 : : /* Complex values are returned in %xmm0/%xmm1 pair. */
3769 : 1259704 : case XMM0_REG:
3770 : 1259704 : case XMM1_REG:
3771 : 1259704 : return TARGET_SSE;
3772 : :
3773 : 9652 : case MM0_REG:
3774 : 9652 : if (TARGET_MACHO || TARGET_64BIT)
3775 : : return false;
3776 : 4399 : return TARGET_MMX;
3777 : : }
3778 : :
3779 : : return false;
3780 : : }
3781 : :
3782 : : /* Check whether the register REGNO should be zeroed on X86.
3783 : : When ALL_SSE_ZEROED is true, all SSE registers have been zeroed
3784 : : together, no need to zero it again.
3785 : : When NEED_ZERO_MMX is true, MMX registers should be cleared. */
3786 : :
3787 : : static bool
3788 : 1514 : zero_call_used_regno_p (const unsigned int regno,
3789 : : bool all_sse_zeroed,
3790 : : bool need_zero_mmx)
3791 : : {
3792 : 883 : return GENERAL_REGNO_P (regno)
3793 : 883 : || (!all_sse_zeroed && SSE_REGNO_P (regno))
3794 : 431 : || MASK_REGNO_P (regno)
3795 : 1937 : || (need_zero_mmx && MMX_REGNO_P (regno));
3796 : : }
3797 : :
3798 : : /* Return the machine_mode that is used to zero register REGNO. */
3799 : :
3800 : : static machine_mode
3801 : 1091 : zero_call_used_regno_mode (const unsigned int regno)
3802 : : {
3803 : : /* NB: We only need to zero the lower 32 bits for integer registers
3804 : : and the lower 128 bits for vector registers since destination are
3805 : : zero-extended to the full register width. */
3806 : 1091 : if (GENERAL_REGNO_P (regno))
3807 : : return SImode;
3808 : : else if (SSE_REGNO_P (regno))
3809 : 452 : return V4SFmode;
3810 : : else if (MASK_REGNO_P (regno))
3811 : : return HImode;
3812 : : else if (MMX_REGNO_P (regno))
3813 : 0 : return V2SImode;
3814 : : else
3815 : 0 : gcc_unreachable ();
3816 : : }
3817 : :
3818 : : /* Generate a rtx to zero all vector registers together if possible,
3819 : : otherwise, return NULL. */
3820 : :
3821 : : static rtx
3822 : 156 : zero_all_vector_registers (HARD_REG_SET need_zeroed_hardregs)
3823 : : {
3824 : 156 : if (!TARGET_AVX)
3825 : : return NULL;
3826 : :
3827 : 279 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
3828 : 276 : if ((LEGACY_SSE_REGNO_P (regno)
3829 : 252 : || (TARGET_64BIT
3830 : 252 : && (REX_SSE_REGNO_P (regno)
3831 : 228 : || (TARGET_AVX512F && EXT_REX_SSE_REGNO_P (regno)))))
3832 : 316 : && !TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
3833 : : return NULL;
3834 : :
3835 : 3 : return gen_avx_vzeroall ();
3836 : : }
3837 : :
3838 : : /* Generate insns to zero all st registers together.
3839 : : Return true when zeroing instructions are generated.
3840 : : Assume the number of st registers that are zeroed is num_of_st,
3841 : : we will emit the following sequence to zero them together:
3842 : : fldz; \
3843 : : fldz; \
3844 : : ...
3845 : : fldz; \
3846 : : fstp %%st(0); \
3847 : : fstp %%st(0); \
3848 : : ...
3849 : : fstp %%st(0);
3850 : : i.e., num_of_st fldz followed by num_of_st fstp to clear the stack
3851 : : mark stack slots empty.
3852 : :
3853 : : How to compute the num_of_st:
3854 : : There is no direct mapping from stack registers to hard register
3855 : : numbers. If one stack register needs to be cleared, we don't know
3856 : : where in the stack the value remains. So, if any stack register
3857 : : needs to be cleared, the whole stack should be cleared. However,
3858 : : x87 stack registers that hold the return value should be excluded.
3859 : : x87 returns in the top (two for complex values) register, so
3860 : : num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
3861 : : return the value of num_of_st. */
3862 : :
3863 : :
3864 : : static int
3865 : 156 : zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
3866 : : {
3867 : :
3868 : : /* If the FPU is disabled, no need to zero all st registers. */
3869 : 156 : if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
3870 : : return 0;
3871 : :
3872 : 12486 : unsigned int num_of_st = 0;
3873 : 12486 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
3874 : 12354 : if ((STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
3875 : 12354 : && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
3876 : : {
3877 : : num_of_st++;
3878 : : break;
3879 : : }
3880 : :
3881 : 155 : if (num_of_st == 0)
3882 : : return 0;
3883 : :
3884 : 23 : bool return_with_x87 = false;
3885 : 46 : return_with_x87 = (crtl->return_rtx
3886 : 23 : && (STACK_REG_P (crtl->return_rtx)));
3887 : :
3888 : 23 : bool complex_return = false;
3889 : 46 : complex_return = (crtl->return_rtx
3890 : 23 : && COMPLEX_MODE_P (GET_MODE (crtl->return_rtx)));
3891 : :
3892 : 23 : if (return_with_x87)
3893 : 2 : if (complex_return)
3894 : : num_of_st = 6;
3895 : : else
3896 : 1 : num_of_st = 7;
3897 : : else
3898 : : num_of_st = 8;
3899 : :
3900 : 23 : rtx st_reg = gen_rtx_REG (XFmode, FIRST_STACK_REG);
3901 : 204 : for (unsigned int i = 0; i < num_of_st; i++)
3902 : 181 : emit_insn (gen_rtx_SET (st_reg, CONST0_RTX (XFmode)));
3903 : :
3904 : 204 : for (unsigned int i = 0; i < num_of_st; i++)
3905 : : {
3906 : 181 : rtx insn;
3907 : 181 : insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
3908 : 181 : add_reg_note (insn, REG_DEAD, st_reg);
3909 : : }
3910 : 23 : return num_of_st;
3911 : : }
3912 : :
3913 : :
3914 : : /* When the routine exit in MMX mode, if any ST register needs
3915 : : to be zeroed, we should clear all MMX registers except the
3916 : : RET_MMX_REGNO that holds the return value. */
3917 : : static bool
3918 : 0 : zero_all_mm_registers (HARD_REG_SET need_zeroed_hardregs,
3919 : : unsigned int ret_mmx_regno)
3920 : : {
3921 : 0 : bool need_zero_all_mm = false;
3922 : 0 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
3923 : 0 : if (STACK_REGNO_P (regno)
3924 : 0 : && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
3925 : : {
3926 : : need_zero_all_mm = true;
3927 : : break;
3928 : : }
3929 : :
3930 : 0 : if (!need_zero_all_mm)
3931 : : return false;
3932 : :
3933 : : machine_mode mode = V2SImode;
3934 : 0 : for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
3935 : 0 : if (regno != ret_mmx_regno)
3936 : : {
3937 : 0 : rtx reg = gen_rtx_REG (mode, regno);
3938 : 0 : emit_insn (gen_rtx_SET (reg, CONST0_RTX (mode)));
3939 : : }
3940 : : return true;
3941 : : }
3942 : :
3943 : : /* TARGET_ZERO_CALL_USED_REGS. */
3944 : : /* Generate a sequence of instructions that zero registers specified by
3945 : : NEED_ZEROED_HARDREGS. Return the ZEROED_HARDREGS that are actually
3946 : : zeroed. */
3947 : : static HARD_REG_SET
3948 : 156 : ix86_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
3949 : : {
3950 : 156 : HARD_REG_SET zeroed_hardregs;
3951 : 156 : bool all_sse_zeroed = false;
3952 : 156 : int all_st_zeroed_num = 0;
3953 : 156 : bool all_mm_zeroed = false;
3954 : :
3955 : 156 : CLEAR_HARD_REG_SET (zeroed_hardregs);
3956 : :
3957 : : /* first, let's see whether we can zero all vector registers together. */
3958 : 156 : rtx zero_all_vec_insn = zero_all_vector_registers (need_zeroed_hardregs);
3959 : 156 : if (zero_all_vec_insn)
3960 : : {
3961 : 3 : emit_insn (zero_all_vec_insn);
3962 : 3 : all_sse_zeroed = true;
3963 : : }
3964 : :
3965 : : /* mm/st registers are shared registers set, we should follow the following
3966 : : rules to clear them:
3967 : : MMX exit mode x87 exit mode
3968 : : -------------|----------------------|---------------
3969 : : uses x87 reg | clear all MMX | clear all x87
3970 : : uses MMX reg | clear individual MMX | clear all x87
3971 : : x87 + MMX | clear all MMX | clear all x87
3972 : :
3973 : : first, we should decide which mode (MMX mode or x87 mode) the function
3974 : : exit with. */
3975 : :
3976 : 156 : bool exit_with_mmx_mode = (crtl->return_rtx
3977 : 156 : && (MMX_REG_P (crtl->return_rtx)));
3978 : :
3979 : 156 : if (!exit_with_mmx_mode)
3980 : : /* x87 exit mode, we should zero all st registers together. */
3981 : : {
3982 : 156 : all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
3983 : :
3984 : 156 : if (all_st_zeroed_num > 0)
3985 : 207 : for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
3986 : : /* x87 stack registers that hold the return value should be excluded.
3987 : : x87 returns in the top (two for complex values) register. */
3988 : 184 : if (all_st_zeroed_num == 8
3989 : 184 : || !((all_st_zeroed_num >= 6 && regno == REGNO (crtl->return_rtx))
3990 : : || (all_st_zeroed_num == 6
3991 : 7 : && (regno == (REGNO (crtl->return_rtx) + 1)))))
3992 : 181 : SET_HARD_REG_BIT (zeroed_hardregs, regno);
3993 : : }
3994 : : else
3995 : : /* MMX exit mode, check whether we can zero all mm registers. */
3996 : : {
3997 : 0 : unsigned int exit_mmx_regno = REGNO (crtl->return_rtx);
3998 : 0 : all_mm_zeroed = zero_all_mm_registers (need_zeroed_hardregs,
3999 : : exit_mmx_regno);
4000 : 0 : if (all_mm_zeroed)
4001 : 0 : for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
4002 : 0 : if (regno != exit_mmx_regno)
4003 : 0 : SET_HARD_REG_BIT (zeroed_hardregs, regno);
4004 : : }
4005 : :
4006 : : /* Now, generate instructions to zero all the other registers. */
4007 : :
4008 : 14508 : for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
4009 : : {
4010 : 14352 : if (!TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
4011 : 12838 : continue;
4012 : 1937 : if (!zero_call_used_regno_p (regno, all_sse_zeroed,
4013 : 1514 : exit_with_mmx_mode && !all_mm_zeroed))
4014 : 423 : continue;
4015 : :
4016 : 1091 : SET_HARD_REG_BIT (zeroed_hardregs, regno);
4017 : :
4018 : 1091 : machine_mode mode = zero_call_used_regno_mode (regno);
4019 : :
4020 : 1091 : rtx reg = gen_rtx_REG (mode, regno);
4021 : 1091 : rtx tmp = gen_rtx_SET (reg, CONST0_RTX (mode));
4022 : :
4023 : 1091 : switch (mode)
4024 : : {
4025 : 631 : case E_SImode:
4026 : 631 : if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
4027 : : {
4028 : 631 : rtx clob = gen_rtx_CLOBBER (VOIDmode,
4029 : : gen_rtx_REG (CCmode,
4030 : : FLAGS_REG));
4031 : 631 : tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4032 : : tmp,
4033 : : clob));
4034 : : }
4035 : : /* FALLTHRU. */
4036 : :
4037 : 1091 : case E_V4SFmode:
4038 : 1091 : case E_HImode:
4039 : 1091 : case E_V2SImode:
4040 : 1091 : emit_insn (tmp);
4041 : 1091 : break;
4042 : :
4043 : 0 : default:
4044 : 0 : gcc_unreachable ();
4045 : : }
4046 : : }
4047 : 156 : return zeroed_hardregs;
4048 : : }
4049 : :
4050 : : /* Define how to find the value returned by a function.
4051 : : VALTYPE is the data type of the value (as a tree).
4052 : : If the precise function being called is known, FUNC is its FUNCTION_DECL;
4053 : : otherwise, FUNC is 0. */
4054 : :
4055 : : static rtx
4056 : 3823142 : function_value_32 (machine_mode orig_mode, machine_mode mode,
4057 : : const_tree fntype, const_tree fn)
4058 : : {
4059 : 3823142 : unsigned int regno;
4060 : :
4061 : : /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
4062 : : we normally prevent this case when mmx is not available. However
4063 : : some ABIs may require the result to be returned like DImode. */
4064 : 4061603 : if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
4065 : : regno = FIRST_MMX_REG;
4066 : :
4067 : : /* 16-byte vector modes in %xmm0. See ix86_return_in_memory for where
4068 : : we prevent this case when sse is not available. However some ABIs
4069 : : may require the result to be returned like integer TImode. */
4070 : 3813902 : else if (mode == TImode
4071 : 4043123 : || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
4072 : : regno = FIRST_SSE_REG;
4073 : :
4074 : : /* 32-byte vector modes in %ymm0. */
4075 : 3846297 : else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
4076 : : regno = FIRST_SSE_REG;
4077 : :
4078 : : /* 64-byte vector modes in %zmm0. */
4079 : 3721019 : else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 64)
4080 : : regno = FIRST_SSE_REG;
4081 : :
4082 : : /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387). */
4083 : 3584681 : else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
4084 : : regno = FIRST_FLOAT_REG;
4085 : : else
4086 : : /* Most things go in %eax. */
4087 : 3522786 : regno = AX_REG;
4088 : :
4089 : : /* Return __bf16/ _Float16/_Complex _Foat16 by sse register. */
4090 : 3823142 : if (mode == HFmode || mode == BFmode)
4091 : : {
4092 : 1619 : if (!TARGET_SSE2)
4093 : : {
4094 : 0 : error ("SSE register return with SSE2 disabled");
4095 : 0 : regno = AX_REG;
4096 : : }
4097 : : else
4098 : : regno = FIRST_SSE_REG;
4099 : : }
4100 : :
4101 : 3823142 : if (mode == HCmode)
4102 : : {
4103 : 80 : if (!TARGET_SSE2)
4104 : 0 : error ("SSE register return with SSE2 disabled");
4105 : :
4106 : 80 : rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1));
4107 : 160 : XVECEXP (ret, 0, 0)
4108 : 160 : = gen_rtx_EXPR_LIST (VOIDmode,
4109 : : gen_rtx_REG (SImode,
4110 : 80 : TARGET_SSE2 ? FIRST_SSE_REG : AX_REG),
4111 : : GEN_INT (0));
4112 : 80 : return ret;
4113 : : }
4114 : :
4115 : : /* Override FP return register with %xmm0 for local functions when
4116 : : SSE math is enabled or for functions with sseregparm attribute. */
4117 : 3823062 : if ((fn || fntype) && (mode == SFmode || mode == DFmode))
4118 : : {
4119 : 48144 : int sse_level = ix86_function_sseregparm (fntype, fn, false);
4120 : 48144 : if (sse_level == -1)
4121 : : {
4122 : 0 : error ("calling %qD with SSE calling convention without "
4123 : : "SSE/SSE2 enabled", fn);
4124 : 0 : sorry ("this is a GCC bug that can be worked around by adding "
4125 : : "attribute used to function called");
4126 : : }
4127 : 48144 : else if ((sse_level >= 1 && mode == SFmode)
4128 : 48144 : || (sse_level == 2 && mode == DFmode))
4129 : : regno = FIRST_SSE_REG;
4130 : : }
4131 : :
4132 : : /* OImode shouldn't be used directly. */
4133 : 3823062 : gcc_assert (mode != OImode);
4134 : :
4135 : 3823062 : return gen_rtx_REG (orig_mode, regno);
4136 : : }
4137 : :
4138 : : static rtx
4139 : 81968710 : function_value_64 (machine_mode orig_mode, machine_mode mode,
4140 : : const_tree valtype)
4141 : : {
4142 : 81968710 : rtx ret;
4143 : :
4144 : : /* Handle libcalls, which don't provide a type node. */
4145 : 81968710 : if (valtype == NULL)
4146 : : {
4147 : 105352 : unsigned int regno;
4148 : :
4149 : 105352 : switch (mode)
4150 : : {
4151 : : case E_BFmode:
4152 : : case E_HFmode:
4153 : : case E_HCmode:
4154 : : case E_SFmode:
4155 : : case E_SCmode:
4156 : : case E_DFmode:
4157 : : case E_DCmode:
4158 : : case E_TFmode:
4159 : : case E_SDmode:
4160 : : case E_DDmode:
4161 : : case E_TDmode:
4162 : : regno = FIRST_SSE_REG;
4163 : : break;
4164 : 1096 : case E_XFmode:
4165 : 1096 : case E_XCmode:
4166 : 1096 : regno = FIRST_FLOAT_REG;
4167 : 1096 : break;
4168 : : case E_TCmode:
4169 : : return NULL;
4170 : 57277 : default:
4171 : 57277 : regno = AX_REG;
4172 : : }
4173 : :
4174 : 105352 : return gen_rtx_REG (mode, regno);
4175 : : }
4176 : 81863358 : else if (POINTER_TYPE_P (valtype))
4177 : : {
4178 : : /* Pointers are always returned in word_mode. */
4179 : 12895730 : mode = word_mode;
4180 : : }
4181 : :
4182 : 81863358 : ret = construct_container (mode, orig_mode, valtype, 1,
4183 : : X86_64_REGPARM_MAX, X86_64_SSE_REGPARM_MAX,
4184 : : x86_64_int_return_registers, 0);
4185 : :
4186 : : /* For zero sized structures, construct_container returns NULL, but we
4187 : : need to keep rest of compiler happy by returning meaningful value. */
4188 : 81863358 : if (!ret)
4189 : 183288 : ret = gen_rtx_REG (orig_mode, AX_REG);
4190 : :
4191 : : return ret;
4192 : : }
4193 : :
4194 : : static rtx
4195 : 0 : function_value_ms_32 (machine_mode orig_mode, machine_mode mode,
4196 : : const_tree fntype, const_tree fn, const_tree valtype)
4197 : : {
4198 : 0 : unsigned int regno;
4199 : :
4200 : : /* Floating point return values in %st(0)
4201 : : (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes). */
4202 : 0 : if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387
4203 : 0 : && (GET_MODE_SIZE (mode) > 8
4204 : 0 : || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype)))
4205 : : {
4206 : 0 : regno = FIRST_FLOAT_REG;
4207 : 0 : return gen_rtx_REG (orig_mode, regno);
4208 : : }
4209 : : else
4210 : 0 : return function_value_32(orig_mode, mode, fntype,fn);
4211 : : }
4212 : :
4213 : : static rtx
4214 : 760940 : function_value_ms_64 (machine_mode orig_mode, machine_mode mode,
4215 : : const_tree valtype)
4216 : : {
4217 : 760940 : unsigned int regno = AX_REG;
4218 : :
4219 : 760940 : if (TARGET_SSE)
4220 : : {
4221 : 1520426 : switch (GET_MODE_SIZE (mode))
4222 : : {
4223 : 12531 : case 16:
4224 : 12531 : if (valtype != NULL_TREE
4225 : 12531 : && !VECTOR_INTEGER_TYPE_P (valtype)
4226 : 6654 : && !VECTOR_INTEGER_TYPE_P (valtype)
4227 : 6654 : && !INTEGRAL_TYPE_P (valtype)
4228 : 19185 : && !VECTOR_FLOAT_TYPE_P (valtype))
4229 : : break;
4230 : 12531 : if ((SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
4231 : : && !COMPLEX_MODE_P (mode))
4232 : 760940 : regno = FIRST_SSE_REG;
4233 : : break;
4234 : 728054 : case 8:
4235 : 728054 : case 4:
4236 : 728054 : if (valtype != NULL_TREE && AGGREGATE_TYPE_P (valtype))
4237 : : break;
4238 : 713280 : if (mode == SFmode || mode == DFmode)
4239 : 760940 : regno = FIRST_SSE_REG;
4240 : : break;
4241 : : default:
4242 : : break;
4243 : : }
4244 : : }
4245 : 760940 : return gen_rtx_REG (orig_mode, regno);
4246 : : }
4247 : :
4248 : : static rtx
4249 : 86552792 : ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
4250 : : machine_mode orig_mode, machine_mode mode)
4251 : : {
4252 : 86552792 : const_tree fn, fntype;
4253 : :
4254 : 86552792 : fn = NULL_TREE;
4255 : 86552792 : if (fntype_or_decl && DECL_P (fntype_or_decl))
4256 : 3303480 : fn = fntype_or_decl;
4257 : 3303480 : fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
4258 : :
4259 : 86552792 : if (ix86_function_type_abi (fntype) == MS_ABI)
4260 : : {
4261 : 760940 : if (TARGET_64BIT)
4262 : 760940 : return function_value_ms_64 (orig_mode, mode, valtype);
4263 : : else
4264 : 0 : return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype);
4265 : : }
4266 : 85791852 : else if (TARGET_64BIT)
4267 : 81968710 : return function_value_64 (orig_mode, mode, valtype);
4268 : : else
4269 : 3823142 : return function_value_32 (orig_mode, mode, fntype, fn);
4270 : : }
4271 : :
4272 : : static rtx
4273 : 86444282 : ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
4274 : : {
4275 : 86444282 : machine_mode mode, orig_mode;
4276 : :
4277 : 86444282 : orig_mode = TYPE_MODE (valtype);
4278 : 86444282 : mode = type_natural_mode (valtype, NULL, true);
4279 : 86444282 : return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
4280 : : }
4281 : :
4282 : : /* Pointer function arguments and return values are promoted to
4283 : : word_mode for normal functions. */
4284 : :
4285 : : static machine_mode
4286 : 29973743 : ix86_promote_function_mode (const_tree type, machine_mode mode,
4287 : : int *punsignedp, const_tree fntype,
4288 : : int for_return)
4289 : : {
4290 : 29973743 : if (cfun->machine->func_type == TYPE_NORMAL
4291 : 29972751 : && type != NULL_TREE
4292 : 29940083 : && POINTER_TYPE_P (type))
4293 : : {
4294 : 14720409 : *punsignedp = POINTERS_EXTEND_UNSIGNED;
4295 : 14720409 : return word_mode;
4296 : : }
4297 : 15253334 : return default_promote_function_mode (type, mode, punsignedp, fntype,
4298 : 15253334 : for_return);
4299 : : }
4300 : :
4301 : : /* Return true if a structure, union or array with MODE containing FIELD
4302 : : should be accessed using BLKmode. */
4303 : :
4304 : : static bool
4305 : 109398991 : ix86_member_type_forces_blk (const_tree field, machine_mode mode)
4306 : : {
4307 : : /* Union with XFmode must be in BLKmode. */
4308 : 109398991 : return (mode == XFmode
4309 : 109526926 : && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
4310 : 116754 : || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
4311 : : }
4312 : :
4313 : : rtx
4314 : 108510 : ix86_libcall_value (machine_mode mode)
4315 : : {
4316 : 108510 : return ix86_function_value_1 (NULL, NULL, mode, mode);
4317 : : }
4318 : :
4319 : : /* Return true iff type is returned in memory. */
4320 : :
4321 : : static bool
4322 : 87509703 : ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
4323 : : {
4324 : 87509703 : const machine_mode mode = type_natural_mode (type, NULL, true);
4325 : 87509703 : HOST_WIDE_INT size;
4326 : :
4327 : 87509703 : if (TARGET_64BIT)
4328 : : {
4329 : 83107360 : if (ix86_function_type_abi (fntype) == MS_ABI)
4330 : : {
4331 : 697878 : size = int_size_in_bytes (type);
4332 : :
4333 : : /* __m128 is returned in xmm0. */
4334 : 697878 : if ((!type || VECTOR_INTEGER_TYPE_P (type)
4335 : 681119 : || INTEGRAL_TYPE_P (type)
4336 : 215574 : || VECTOR_FLOAT_TYPE_P (type))
4337 : 496728 : && (SCALAR_INT_MODE_P (mode) || VECTOR_MODE_P (mode))
4338 : : && !COMPLEX_MODE_P (mode)
4339 : 1194606 : && (GET_MODE_SIZE (mode) == 16 || size == 16))
4340 : : return false;
4341 : :
4342 : : /* Otherwise, the size must be exactly in [1248]. */
4343 : 1337087 : return size != 1 && size != 2 && size != 4 && size != 8;
4344 : : }
4345 : : else
4346 : : {
4347 : 82409482 : int needed_intregs, needed_sseregs;
4348 : :
4349 : 82409482 : return examine_argument (mode, type, 1,
4350 : : &needed_intregs, &needed_sseregs);
4351 : : }
4352 : : }
4353 : : else
4354 : : {
4355 : 4402343 : size = int_size_in_bytes (type);
4356 : :
4357 : : /* Intel MCU psABI returns scalars and aggregates no larger than 8
4358 : : bytes in registers. */
4359 : 4402343 : if (TARGET_IAMCU)
4360 : 0 : return VECTOR_MODE_P (mode) || size < 0 || size > 8;
4361 : :
4362 : 4402343 : if (mode == BLKmode)
4363 : : return true;
4364 : :
4365 : 4402343 : if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
4366 : : return false;
4367 : :
4368 : 4402343 : if (VECTOR_MODE_P (mode) || mode == TImode)
4369 : : {
4370 : : /* User-created vectors small enough to fit in EAX. */
4371 : 238433 : if (size < 8)
4372 : : return false;
4373 : :
4374 : : /* Unless ABI prescibes otherwise,
4375 : : MMX/3dNow values are returned in MM0 if available. */
4376 : :
4377 : 238433 : if (size == 8)
4378 : 9232 : return TARGET_VECT8_RETURNS || !TARGET_MMX;
4379 : :
4380 : : /* SSE values are returned in XMM0 if available. */
4381 : 229201 : if (size == 16)
4382 : 98403 : return !TARGET_SSE;
4383 : :
4384 : : /* AVX values are returned in YMM0 if available. */
4385 : 130798 : if (size == 32)
4386 : 62630 : return !TARGET_AVX;
4387 : :
4388 : : /* AVX512F values are returned in ZMM0 if available. */
4389 : 68168 : if (size == 64)
4390 : 68168 : return !TARGET_AVX512F || !TARGET_EVEX512;
4391 : : }
4392 : :
4393 : 4163910 : if (mode == XFmode)
4394 : : return false;
4395 : :
4396 : 4152689 : if (size > 12)
4397 : : return true;
4398 : :
4399 : : /* OImode shouldn't be used directly. */
4400 : 3205006 : gcc_assert (mode != OImode);
4401 : :
4402 : : return false;
4403 : : }
4404 : : }
4405 : :
4406 : : /* Implement TARGET_PUSH_ARGUMENT. */
4407 : :
4408 : : static bool
4409 : 8823406 : ix86_push_argument (unsigned int npush)
4410 : : {
4411 : : /* If SSE2 is available, use vector move to put large argument onto
4412 : : stack. NB: In 32-bit mode, use 8-byte vector move. */
4413 : 11221205 : return ((!TARGET_SSE2 || npush < (TARGET_64BIT ? 16 : 8))
4414 : 8561020 : && TARGET_PUSH_ARGS
4415 : 17384338 : && !ACCUMULATE_OUTGOING_ARGS);
4416 : : }
4417 : :
4418 : :
4419 : : /* Create the va_list data type. */
4420 : :
4421 : : static tree
4422 : 273310 : ix86_build_builtin_va_list_64 (void)
4423 : : {
4424 : 273310 : tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4425 : :
4426 : 273310 : record = lang_hooks.types.make_type (RECORD_TYPE);
4427 : 273310 : type_decl = build_decl (BUILTINS_LOCATION,
4428 : : TYPE_DECL, get_identifier ("__va_list_tag"), record);
4429 : :
4430 : 273310 : f_gpr = build_decl (BUILTINS_LOCATION,
4431 : : FIELD_DECL, get_identifier ("gp_offset"),
4432 : : unsigned_type_node);
4433 : 273310 : f_fpr = build_decl (BUILTINS_LOCATION,
4434 : : FIELD_DECL, get_identifier ("fp_offset"),
4435 : : unsigned_type_node);
4436 : 273310 : f_ovf = build_decl (BUILTINS_LOCATION,
4437 : : FIELD_DECL, get_identifier ("overflow_arg_area"),
4438 : : ptr_type_node);
4439 : 273310 : f_sav = build_decl (BUILTINS_LOCATION,
4440 : : FIELD_DECL, get_identifier ("reg_save_area"),
4441 : : ptr_type_node);
4442 : :
4443 : 273310 : va_list_gpr_counter_field = f_gpr;
4444 : 273310 : va_list_fpr_counter_field = f_fpr;
4445 : :
4446 : 273310 : DECL_FIELD_CONTEXT (f_gpr) = record;
4447 : 273310 : DECL_FIELD_CONTEXT (f_fpr) = record;
4448 : 273310 : DECL_FIELD_CONTEXT (f_ovf) = record;
4449 : 273310 : DECL_FIELD_CONTEXT (f_sav) = record;
4450 : :
4451 : 273310 : TYPE_STUB_DECL (record) = type_decl;
4452 : 273310 : TYPE_NAME (record) = type_decl;
4453 : 273310 : TYPE_FIELDS (record) = f_gpr;
4454 : 273310 : DECL_CHAIN (f_gpr) = f_fpr;
4455 : 273310 : DECL_CHAIN (f_fpr) = f_ovf;
4456 : 273310 : DECL_CHAIN (f_ovf) = f_sav;
4457 : :
4458 : 273310 : layout_type (record);
4459 : :
4460 : 273310 : TYPE_ATTRIBUTES (record) = tree_cons (get_identifier ("sysv_abi va_list"),
4461 : 273310 : NULL_TREE, TYPE_ATTRIBUTES (record));
4462 : :
4463 : : /* The correct type is an array type of one element. */
4464 : 273310 : return build_array_type (record, build_index_type (size_zero_node));
4465 : : }
4466 : :
4467 : : /* Setup the builtin va_list data type and for 64-bit the additional
4468 : : calling convention specific va_list data types. */
4469 : :
4470 : : static tree
4471 : 280166 : ix86_build_builtin_va_list (void)
4472 : : {
4473 : 280166 : if (TARGET_64BIT)
4474 : : {
4475 : : /* Initialize ABI specific va_list builtin types.
4476 : :
4477 : : In lto1, we can encounter two va_list types:
4478 : : - one as a result of the type-merge across TUs, and
4479 : : - the one constructed here.
4480 : : These two types will not have the same TYPE_MAIN_VARIANT, and therefore
4481 : : a type identity check in canonical_va_list_type based on
4482 : : TYPE_MAIN_VARIANT (which we used to have) will not work.
4483 : : Instead, we tag each va_list_type_node with its unique attribute, and
4484 : : look for the attribute in the type identity check in
4485 : : canonical_va_list_type.
4486 : :
4487 : : Tagging sysv_va_list_type_node directly with the attribute is
4488 : : problematic since it's a array of one record, which will degrade into a
4489 : : pointer to record when used as parameter (see build_va_arg comments for
4490 : : an example), dropping the attribute in the process. So we tag the
4491 : : record instead. */
4492 : :
4493 : : /* For SYSV_ABI we use an array of one record. */
4494 : 273310 : sysv_va_list_type_node = ix86_build_builtin_va_list_64 ();
4495 : :
4496 : : /* For MS_ABI we use plain pointer to argument area. */
4497 : 273310 : tree char_ptr_type = build_pointer_type (char_type_node);
4498 : 273310 : tree attr = tree_cons (get_identifier ("ms_abi va_list"), NULL_TREE,
4499 : 273310 : TYPE_ATTRIBUTES (char_ptr_type));
4500 : 273310 : ms_va_list_type_node = build_type_attribute_variant (char_ptr_type, attr);
4501 : :
4502 : 273310 : return ((ix86_abi == MS_ABI)
4503 : 273310 : ? ms_va_list_type_node
4504 : 273310 : : sysv_va_list_type_node);
4505 : : }
4506 : : else
4507 : : {
4508 : : /* For i386 we use plain pointer to argument area. */
4509 : 6856 : return build_pointer_type (char_type_node);
4510 : : }
4511 : : }
4512 : :
4513 : : /* Worker function for TARGET_SETUP_INCOMING_VARARGS. */
4514 : :
4515 : : static void
4516 : 15346 : setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
4517 : : {
4518 : 15346 : rtx save_area, mem;
4519 : 15346 : alias_set_type set;
4520 : 15346 : int i, max;
4521 : :
4522 : : /* GPR size of varargs save area. */
4523 : 15346 : if (cfun->va_list_gpr_size)
4524 : 14925 : ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
4525 : : else
4526 : 421 : ix86_varargs_gpr_size = 0;
4527 : :
4528 : : /* FPR size of varargs save area. We don't need it if we don't pass
4529 : : anything in SSE registers. */
4530 : 15346 : if (TARGET_SSE && cfun->va_list_fpr_size)
4531 : 14388 : ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
4532 : : else
4533 : 958 : ix86_varargs_fpr_size = 0;
4534 : :
4535 : 15346 : if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
4536 : : return;
4537 : :
4538 : 15092 : save_area = frame_pointer_rtx;
4539 : 15092 : set = get_varargs_alias_set ();
4540 : :
4541 : 15092 : max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
4542 : 15092 : if (max > X86_64_REGPARM_MAX)
4543 : : max = X86_64_REGPARM_MAX;
4544 : :
4545 : 84071 : for (i = cum->regno; i < max; i++)
4546 : : {
4547 : 68979 : mem = gen_rtx_MEM (word_mode,
4548 : 68979 : plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
4549 : 68979 : MEM_NOTRAP_P (mem) = 1;
4550 : 68979 : set_mem_alias_set (mem, set);
4551 : 68979 : emit_move_insn (mem,
4552 : : gen_rtx_REG (word_mode,
4553 : 68979 : x86_64_int_parameter_registers[i]));
4554 : : }
4555 : :
4556 : 15092 : if (ix86_varargs_fpr_size)
4557 : : {
4558 : 14388 : machine_mode smode;
4559 : 14388 : rtx_code_label *label;
4560 : 14388 : rtx test;
4561 : :
4562 : : /* Now emit code to save SSE registers. The AX parameter contains number
4563 : : of SSE parameter registers used to call this function, though all we
4564 : : actually check here is the zero/non-zero status. */
4565 : :
4566 : 14388 : label = gen_label_rtx ();
4567 : 14388 : test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
4568 : 14388 : emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
4569 : : label));
4570 : :
4571 : : /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
4572 : : we used movdqa (i.e. TImode) instead? Perhaps even better would
4573 : : be if we could determine the real mode of the data, via a hook
4574 : : into pass_stdarg. Ignore all that for now. */
4575 : 14388 : smode = V4SFmode;
4576 : 14388 : if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
4577 : 3898 : crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
4578 : :
4579 : 14388 : max = cum->sse_regno + cfun->va_list_fpr_size / 16;
4580 : 14388 : if (max > X86_64_SSE_REGPARM_MAX)
4581 : : max = X86_64_SSE_REGPARM_MAX;
4582 : :
4583 : 127956 : for (i = cum->sse_regno; i < max; ++i)
4584 : : {
4585 : 113568 : mem = plus_constant (Pmode, save_area,
4586 : 113568 : i * 16 + ix86_varargs_gpr_size);
4587 : 113568 : mem = gen_rtx_MEM (smode, mem);
4588 : 113568 : MEM_NOTRAP_P (mem) = 1;
4589 : 113568 : set_mem_alias_set (mem, set);
4590 : 113568 : set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
4591 : :
4592 : 113568 : emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
4593 : : }
4594 : :
4595 : 14388 : emit_label (label);
4596 : : }
4597 : : }
4598 : :
4599 : : static void
4600 : 5652 : setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
4601 : : {
4602 : 5652 : alias_set_type set = get_varargs_alias_set ();
4603 : 5652 : int i;
4604 : :
4605 : : /* Reset to zero, as there might be a sysv vaarg used
4606 : : before. */
4607 : 5652 : ix86_varargs_gpr_size = 0;
4608 : 5652 : ix86_varargs_fpr_size = 0;
4609 : :
4610 : 14154 : for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
4611 : : {
4612 : 8502 : rtx reg, mem;
4613 : :
4614 : 8502 : mem = gen_rtx_MEM (Pmode,
4615 : 8502 : plus_constant (Pmode, virtual_incoming_args_rtx,
4616 : 8502 : i * UNITS_PER_WORD));
4617 : 8502 : MEM_NOTRAP_P (mem) = 1;
4618 : 8502 : set_mem_alias_set (mem, set);
4619 : :
4620 : 8502 : reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
4621 : 8502 : emit_move_insn (mem, reg);
4622 : : }
4623 : 5652 : }
4624 : :
4625 : : static void
4626 : 21144 : ix86_setup_incoming_varargs (cumulative_args_t cum_v,
4627 : : const function_arg_info &arg,
4628 : : int *, int no_rtl)
4629 : : {
4630 : 21144 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4631 : 21144 : CUMULATIVE_ARGS next_cum;
4632 : 21144 : tree fntype;
4633 : :
4634 : : /* This argument doesn't appear to be used anymore. Which is good,
4635 : : because the old code here didn't suppress rtl generation. */
4636 : 21144 : gcc_assert (!no_rtl);
4637 : :
4638 : 21144 : if (!TARGET_64BIT)
4639 : 146 : return;
4640 : :
4641 : 20998 : fntype = TREE_TYPE (current_function_decl);
4642 : :
4643 : : /* For varargs, we do not want to skip the dummy va_dcl argument.
4644 : : For stdargs, we do want to skip the last named argument. */
4645 : 20998 : next_cum = *cum;
4646 : 20998 : if ((!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
4647 : 63 : || arg.type != NULL_TREE)
4648 : 21010 : && stdarg_p (fntype))
4649 : 20947 : ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
4650 : :
4651 : 20998 : if (cum->call_abi == MS_ABI)
4652 : 5652 : setup_incoming_varargs_ms_64 (&next_cum);
4653 : : else
4654 : 15346 : setup_incoming_varargs_64 (&next_cum);
4655 : : }
4656 : :
4657 : : /* Checks if TYPE is of kind va_list char *. */
4658 : :
4659 : : static bool
4660 : 72481 : is_va_list_char_pointer (tree type)
4661 : : {
4662 : 72481 : tree canonic;
4663 : :
4664 : : /* For 32-bit it is always true. */
4665 : 72481 : if (!TARGET_64BIT)
4666 : : return true;
4667 : 72319 : canonic = ix86_canonical_va_list_type (type);
4668 : 72319 : return (canonic == ms_va_list_type_node
4669 : 72319 : || (ix86_abi == MS_ABI && canonic == va_list_type_node));
4670 : : }
4671 : :
4672 : : /* Implement va_start. */
4673 : :
4674 : : static void
4675 : 20688 : ix86_va_start (tree valist, rtx nextarg)
4676 : : {
4677 : 20688 : HOST_WIDE_INT words, n_gpr, n_fpr;
4678 : 20688 : tree f_gpr, f_fpr, f_ovf, f_sav;
4679 : 20688 : tree gpr, fpr, ovf, sav, t;
4680 : 20688 : tree type;
4681 : 20688 : rtx ovf_rtx;
4682 : :
4683 : 20688 : if (flag_split_stack
4684 : 12 : && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
4685 : : {
4686 : 12 : unsigned int scratch_regno;
4687 : :
4688 : : /* When we are splitting the stack, we can't refer to the stack
4689 : : arguments using internal_arg_pointer, because they may be on
4690 : : the old stack. The split stack prologue will arrange to
4691 : : leave a pointer to the old stack arguments in a scratch
4692 : : register, which we here copy to a pseudo-register. The split
4693 : : stack prologue can't set the pseudo-register directly because
4694 : : it (the prologue) runs before any registers have been saved. */
4695 : :
4696 : 12 : scratch_regno = split_stack_prologue_scratch_regno ();
4697 : 12 : if (scratch_regno != INVALID_REGNUM)
4698 : : {
4699 : 12 : rtx reg;
4700 : 12 : rtx_insn *seq;
4701 : :
4702 : 12 : reg = gen_reg_rtx (Pmode);
4703 : 12 : cfun->machine->split_stack_varargs_pointer = reg;
4704 : :
4705 : 12 : start_sequence ();
4706 : 12 : emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
4707 : 12 : seq = get_insns ();
4708 : 12 : end_sequence ();
4709 : :
4710 : 12 : push_topmost_sequence ();
4711 : 12 : emit_insn_after (seq, entry_of_function ());
4712 : 12 : pop_topmost_sequence ();
4713 : : }
4714 : : }
4715 : :
4716 : : /* Only 64bit target needs something special. */
4717 : 20688 : if (is_va_list_char_pointer (TREE_TYPE (valist)))
4718 : : {
4719 : 5656 : if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
4720 : 5652 : std_expand_builtin_va_start (valist, nextarg);
4721 : : else
4722 : : {
4723 : 4 : rtx va_r, next;
4724 : :
4725 : 4 : va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4726 : 8 : next = expand_binop (ptr_mode, add_optab,
4727 : 4 : cfun->machine->split_stack_varargs_pointer,
4728 : : crtl->args.arg_offset_rtx,
4729 : : NULL_RTX, 0, OPTAB_LIB_WIDEN);
4730 : 4 : convert_move (va_r, next, 0);
4731 : : }
4732 : 5656 : return;
4733 : : }
4734 : :
4735 : 15032 : f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
4736 : 15032 : f_fpr = DECL_CHAIN (f_gpr);
4737 : 15032 : f_ovf = DECL_CHAIN (f_fpr);
4738 : 15032 : f_sav = DECL_CHAIN (f_ovf);
4739 : :
4740 : 15032 : valist = build_simple_mem_ref (valist);
4741 : 15032 : TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
4742 : : /* The following should be folded into the MEM_REF offset. */
4743 : 15032 : gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
4744 : : f_gpr, NULL_TREE);
4745 : 15032 : fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
4746 : : f_fpr, NULL_TREE);
4747 : 15032 : ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
4748 : : f_ovf, NULL_TREE);
4749 : 15032 : sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
4750 : : f_sav, NULL_TREE);
4751 : :
4752 : : /* Count number of gp and fp argument registers used. */
4753 : 15032 : words = crtl->args.info.words;
4754 : 15032 : n_gpr = crtl->args.info.regno;
4755 : 15032 : n_fpr = crtl->args.info.sse_regno;
4756 : :
4757 : 15032 : if (cfun->va_list_gpr_size)
4758 : : {
4759 : 14819 : type = TREE_TYPE (gpr);
4760 : 14819 : t = build2 (MODIFY_EXPR, type,
4761 : 14819 : gpr, build_int_cst (type, n_gpr * 8));
4762 : 14819 : TREE_SIDE_EFFECTS (t) = 1;
4763 : 14819 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4764 : : }
4765 : :
4766 : 15032 : if (TARGET_SSE && cfun->va_list_fpr_size)
4767 : : {
4768 : 14273 : type = TREE_TYPE (fpr);
4769 : 14273 : t = build2 (MODIFY_EXPR, type, fpr,
4770 : 14273 : build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
4771 : 14273 : TREE_SIDE_EFFECTS (t) = 1;
4772 : 14273 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4773 : : }
4774 : :
4775 : : /* Find the overflow area. */
4776 : 15032 : type = TREE_TYPE (ovf);
4777 : 15032 : if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
4778 : 15024 : ovf_rtx = crtl->args.internal_arg_pointer;
4779 : : else
4780 : : ovf_rtx = cfun->machine->split_stack_varargs_pointer;
4781 : 15032 : t = make_tree (type, ovf_rtx);
4782 : 15032 : if (words != 0)
4783 : 435 : t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
4784 : :
4785 : 15032 : t = build2 (MODIFY_EXPR, type, ovf, t);
4786 : 15032 : TREE_SIDE_EFFECTS (t) = 1;
4787 : 15032 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4788 : :
4789 : 15032 : if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
4790 : : {
4791 : : /* Find the register save area.
4792 : : Prologue of the function save it right above stack frame. */
4793 : 14986 : type = TREE_TYPE (sav);
4794 : 14986 : t = make_tree (type, frame_pointer_rtx);
4795 : 14986 : if (!ix86_varargs_gpr_size)
4796 : 167 : t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
4797 : :
4798 : 14986 : t = build2 (MODIFY_EXPR, type, sav, t);
4799 : 14986 : TREE_SIDE_EFFECTS (t) = 1;
4800 : 14986 : expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4801 : : }
4802 : : }
4803 : :
4804 : : /* Implement va_arg. */
4805 : :
4806 : : static tree
4807 : 51793 : ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
4808 : : gimple_seq *post_p)
4809 : : {
4810 : 51793 : static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
4811 : 51793 : tree f_gpr, f_fpr, f_ovf, f_sav;
4812 : 51793 : tree gpr, fpr, ovf, sav, t;
4813 : 51793 : int size, rsize;
4814 : 51793 : tree lab_false, lab_over = NULL_TREE;
4815 : 51793 : tree addr, t2;
4816 : 51793 : rtx container;
4817 : 51793 : int indirect_p = 0;
4818 : 51793 : tree ptrtype;
4819 : 51793 : machine_mode nat_mode;
4820 : 51793 : unsigned int arg_boundary;
4821 : 51793 : unsigned int type_align;
4822 : :
4823 : : /* Only 64bit target needs something special. */
4824 : 51793 : if (is_va_list_char_pointer (TREE_TYPE (valist)))
4825 : 260 : return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
4826 : :
4827 : 51533 : f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
4828 : 51533 : f_fpr = DECL_CHAIN (f_gpr);
4829 : 51533 : f_ovf = DECL_CHAIN (f_fpr);
4830 : 51533 : f_sav = DECL_CHAIN (f_ovf);
4831 : :
4832 : 51533 : gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
4833 : : valist, f_gpr, NULL_TREE);
4834 : :
4835 : 51533 : fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
4836 : 51533 : ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
4837 : 51533 : sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
4838 : :
4839 : 51533 : indirect_p = pass_va_arg_by_reference (type);
4840 : 51533 : if (indirect_p)
4841 : 99 : type = build_pointer_type (type);
4842 : 51533 : size = arg_int_size_in_bytes (type);
4843 : 51533 : rsize = CEIL (size, UNITS_PER_WORD);
4844 : :
4845 : 51533 : nat_mode = type_natural_mode (type, NULL, false);
4846 : 51533 : switch (nat_mode)
4847 : : {
4848 : 28 : case E_V16HFmode:
4849 : 28 : case E_V16BFmode:
4850 : 28 : case E_V8SFmode:
4851 : 28 : case E_V8SImode:
4852 : 28 : case E_V32QImode:
4853 : 28 : case E_V16HImode:
4854 : 28 : case E_V4DFmode:
4855 : 28 : case E_V4DImode:
4856 : 28 : case E_V32HFmode:
4857 : 28 : case E_V32BFmode:
4858 : 28 : case E_V16SFmode:
4859 : 28 : case E_V16SImode:
4860 : 28 : case E_V64QImode:
4861 : 28 : case E_V32HImode:
4862 : 28 : case E_V8DFmode:
4863 : 28 : case E_V8DImode:
4864 : : /* Unnamed 256 and 512bit vector mode parameters are passed on stack. */
4865 : 28 : if (!TARGET_64BIT_MS_ABI)
4866 : : {
4867 : : container = NULL;
4868 : : break;
4869 : : }
4870 : : /* FALLTHRU */
4871 : :
4872 : 51505 : default:
4873 : 51505 : container = construct_container (nat_mode, TYPE_MODE (type),
4874 : : type, 0, X86_64_REGPARM_MAX,
4875 : : X86_64_SSE_REGPARM_MAX, intreg,
4876 : : 0);
4877 : 51505 : break;
4878 : : }
4879 : :
4880 : : /* Pull the value out of the saved registers. */
4881 : :
4882 : 51533 : addr = create_tmp_var (ptr_type_node, "addr");
4883 : 51533 : type_align = TYPE_ALIGN (type);
4884 : :
4885 : 51533 : if (container)
4886 : : {
4887 : 28439 : int needed_intregs, needed_sseregs;
4888 : 28439 : bool need_temp;
4889 : 28439 : tree int_addr, sse_addr;
4890 : :
4891 : 28439 : lab_false = create_artificial_label (UNKNOWN_LOCATION);
4892 : 28439 : lab_over = create_artificial_label (UNKNOWN_LOCATION);
4893 : :
4894 : 28439 : examine_argument (nat_mode, type, 0, &needed_intregs, &needed_sseregs);
4895 : :
4896 : 56360 : need_temp = (!REG_P (container)
4897 : 28439 : && ((needed_intregs && TYPE_ALIGN (type) > 64)
4898 : 1113 : || TYPE_ALIGN (type) > 128));
4899 : :
4900 : : /* In case we are passing structure, verify that it is consecutive block
4901 : : on the register save area. If not we need to do moves. */
4902 : 27921 : if (!need_temp && !REG_P (container))
4903 : : {
4904 : : /* Verify that all registers are strictly consecutive */
4905 : 1394 : if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
4906 : : {
4907 : : int i;
4908 : :
4909 : 795 : for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
4910 : : {
4911 : 514 : rtx slot = XVECEXP (container, 0, i);
4912 : 514 : if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
4913 : 514 : || INTVAL (XEXP (slot, 1)) != i * 16)
4914 : : need_temp = true;
4915 : : }
4916 : : }
4917 : : else
4918 : : {
4919 : : int i;
4920 : :
4921 : 1996 : for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
4922 : : {
4923 : 1164 : rtx slot = XVECEXP (container, 0, i);
4924 : 1164 : if (REGNO (XEXP (slot, 0)) != (unsigned int) i
4925 : 1164 : || INTVAL (XEXP (slot, 1)) != i * 8)
4926 : : need_temp = true;
4927 : : }
4928 : : }
4929 : : }
4930 : 27921 : if (!need_temp)
4931 : : {
4932 : : int_addr = addr;
4933 : : sse_addr = addr;
4934 : : }
4935 : : else
4936 : : {
4937 : 915 : int_addr = create_tmp_var (ptr_type_node, "int_addr");
4938 : 915 : sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
4939 : : }
4940 : :
4941 : : /* First ensure that we fit completely in registers. */
4942 : 28439 : if (needed_intregs)
4943 : : {
4944 : 17760 : t = build_int_cst (TREE_TYPE (gpr),
4945 : 17760 : (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
4946 : 17760 : t = build2 (GE_EXPR, boolean_type_node, gpr, t);
4947 : 17760 : t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
4948 : 17760 : t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
4949 : 17760 : gimplify_and_add (t, pre_p);
4950 : : }
4951 : 28439 : if (needed_sseregs)
4952 : : {
4953 : 11059 : t = build_int_cst (TREE_TYPE (fpr),
4954 : : (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
4955 : 11059 : + X86_64_REGPARM_MAX * 8);
4956 : 11059 : t = build2 (GE_EXPR, boolean_type_node, fpr, t);
4957 : 11059 : t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
4958 : 11059 : t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
4959 : 11059 : gimplify_and_add (t, pre_p);
4960 : : }
4961 : :
4962 : : /* Compute index to start of area used for integer regs. */
4963 : 28439 : if (needed_intregs)
4964 : : {
4965 : : /* int_addr = gpr + sav; */
4966 : 17760 : t = fold_build_pointer_plus (sav, gpr);
4967 : 17760 : gimplify_assign (int_addr, t, pre_p);
4968 : : }
4969 : 28439 : if (needed_sseregs)
4970 : : {
4971 : : /* sse_addr = fpr + sav; */
4972 : 11059 : t = fold_build_pointer_plus (sav, fpr);
4973 : 11059 : gimplify_assign (sse_addr, t, pre_p);
4974 : : }
4975 : 28439 : if (need_temp)
4976 : : {
4977 : 915 : int i, prev_size = 0;
4978 : 915 : tree temp = create_tmp_var (type, "va_arg_tmp");
4979 : 915 : TREE_ADDRESSABLE (temp) = 1;
4980 : :
4981 : : /* addr = &temp; */
4982 : 915 : t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
4983 : 915 : gimplify_assign (addr, t, pre_p);
4984 : :
4985 : 2307 : for (i = 0; i < XVECLEN (container, 0); i++)
4986 : : {
4987 : 1392 : rtx slot = XVECEXP (container, 0, i);
4988 : 1392 : rtx reg = XEXP (slot, 0);
4989 : 1392 : machine_mode mode = GET_MODE (reg);
4990 : 1392 : tree piece_type;
4991 : 1392 : tree addr_type;
4992 : 1392 : tree daddr_type;
4993 : 1392 : tree src_addr, src;
4994 : 1392 : int src_offset;
4995 : 1392 : tree dest_addr, dest;
4996 : 1392 : int cur_size = GET_MODE_SIZE (mode);
4997 : :
4998 : 1392 : gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
4999 : 1392 : prev_size = INTVAL (XEXP (slot, 1));
5000 : 1392 : if (prev_size + cur_size > size)
5001 : : {
5002 : 30 : cur_size = size - prev_size;
5003 : 30 : unsigned int nbits = cur_size * BITS_PER_UNIT;
5004 : 30 : if (!int_mode_for_size (nbits, 1).exists (&mode))
5005 : 10 : mode = QImode;
5006 : : }
5007 : 1392 : piece_type = lang_hooks.types.type_for_mode (mode, 1);
5008 : 1392 : if (mode == GET_MODE (reg))
5009 : 1362 : addr_type = build_pointer_type (piece_type);
5010 : : else
5011 : 30 : addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
5012 : : true);
5013 : 1392 : daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
5014 : : true);
5015 : :
5016 : 1392 : if (SSE_REGNO_P (REGNO (reg)))
5017 : : {
5018 : 526 : src_addr = sse_addr;
5019 : 526 : src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
5020 : : }
5021 : : else
5022 : : {
5023 : 866 : src_addr = int_addr;
5024 : 866 : src_offset = REGNO (reg) * 8;
5025 : : }
5026 : 1392 : src_addr = fold_convert (addr_type, src_addr);
5027 : 1392 : src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
5028 : :
5029 : 1392 : dest_addr = fold_convert (daddr_type, addr);
5030 : 1392 : dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
5031 : 2784 : if (cur_size == GET_MODE_SIZE (mode))
5032 : : {
5033 : 1382 : src = build_va_arg_indirect_ref (src_addr);
5034 : 1382 : dest = build_va_arg_indirect_ref (dest_addr);
5035 : :
5036 : 1382 : gimplify_assign (dest, src, pre_p);
5037 : : }
5038 : : else
5039 : : {
5040 : 10 : tree copy
5041 : 10 : = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
5042 : : 3, dest_addr, src_addr,
5043 : : size_int (cur_size));
5044 : 10 : gimplify_and_add (copy, pre_p);
5045 : : }
5046 : 1392 : prev_size += cur_size;
5047 : : }
5048 : : }
5049 : :
5050 : 28439 : if (needed_intregs)
5051 : : {
5052 : 17760 : t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
5053 : 17760 : build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
5054 : 17760 : gimplify_assign (gpr, t, pre_p);
5055 : : /* The GPR save area guarantees only 8-byte alignment. */
5056 : 17760 : if (!need_temp)
5057 : 16920 : type_align = MIN (type_align, 64);
5058 : : }
5059 : :
5060 : 28439 : if (needed_sseregs)
5061 : : {
5062 : 11059 : t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
5063 : 11059 : build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
5064 : 11059 : gimplify_assign (unshare_expr (fpr), t, pre_p);
5065 : : }
5066 : :
5067 : 28439 : gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
5068 : :
5069 : 28439 : gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
5070 : : }
5071 : :
5072 : : /* ... otherwise out of the overflow area. */
5073 : :
5074 : : /* When we align parameter on stack for caller, if the parameter
5075 : : alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
5076 : : aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
5077 : : here with caller. */
5078 : 51533 : arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
5079 : 51533 : if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
5080 : : arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
5081 : :
5082 : : /* Care for on-stack alignment if needed. */
5083 : 51533 : if (arg_boundary <= 64 || size == 0)
5084 : 34476 : t = ovf;
5085 : : else
5086 : : {
5087 : 17057 : HOST_WIDE_INT align = arg_boundary / 8;
5088 : 17057 : t = fold_build_pointer_plus_hwi (ovf, align - 1);
5089 : 17057 : t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
5090 : 34114 : build_int_cst (TREE_TYPE (t), -align));
5091 : : }
5092 : :
5093 : 51533 : gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
5094 : 51533 : gimplify_assign (addr, t, pre_p);
5095 : :
5096 : 51533 : t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
5097 : 51533 : gimplify_assign (unshare_expr (ovf), t, pre_p);
5098 : :
5099 : 51533 : if (container)
5100 : 28439 : gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
5101 : :
5102 : 51533 : type = build_aligned_type (type, type_align);
5103 : 51533 : ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
5104 : 51533 : addr = fold_convert (ptrtype, addr);
5105 : :
5106 : 51533 : if (indirect_p)
5107 : 99 : addr = build_va_arg_indirect_ref (addr);
5108 : 51533 : return build_va_arg_indirect_ref (addr);
5109 : : }
5110 : :
5111 : : /* Return true if OPNUM's MEM should be matched
5112 : : in movabs* patterns. */
5113 : :
5114 : : bool
5115 : 10270 : ix86_check_movabs (rtx insn, int opnum)
5116 : : {
5117 : 10270 : rtx set, mem;
5118 : :
5119 : 10270 : set = PATTERN (insn);
5120 : 10270 : if (GET_CODE (set) == PARALLEL)
5121 : 0 : set = XVECEXP (set, 0, 0);
5122 : 10270 : gcc_assert (GET_CODE (set) == SET);
5123 : 10270 : mem = XEXP (set, opnum);
5124 : 10270 : while (SUBREG_P (mem))
5125 : 0 : mem = SUBREG_REG (mem);
5126 : 10270 : gcc_assert (MEM_P (mem));
5127 : 10270 : return volatile_ok || !MEM_VOLATILE_P (mem);
5128 : : }
5129 : :
5130 : : /* Return false if INSN contains a MEM with a non-default address space. */
5131 : : bool
5132 : 137633 : ix86_check_no_addr_space (rtx insn)
5133 : : {
5134 : 137633 : subrtx_var_iterator::array_type array;
5135 : 3103100 : FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), ALL)
5136 : : {
5137 : 2965467 : rtx x = *iter;
5138 : 3182506 : if (MEM_P (x) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)))
5139 : 0 : return false;
5140 : : }
5141 : 137633 : return true;
5142 : 137633 : }
5143 : :
5144 : : /* Initialize the table of extra 80387 mathematical constants. */
5145 : :
5146 : : static void
5147 : 2350 : init_ext_80387_constants (void)
5148 : : {
5149 : 2350 : static const char * cst[5] =
5150 : : {
5151 : : "0.3010299956639811952256464283594894482", /* 0: fldlg2 */
5152 : : "0.6931471805599453094286904741849753009", /* 1: fldln2 */
5153 : : "1.4426950408889634073876517827983434472", /* 2: fldl2e */
5154 : : "3.3219280948873623478083405569094566090", /* 3: fldl2t */
5155 : : "3.1415926535897932385128089594061862044", /* 4: fldpi */
5156 : : };
5157 : 2350 : int i;
5158 : :
5159 : 14100 : for (i = 0; i < 5; i++)
5160 : : {
5161 : 11750 : real_from_string (&ext_80387_constants_table[i], cst[i]);
5162 : : /* Ensure each constant is rounded to XFmode precision. */
5163 : 11750 : real_convert (&ext_80387_constants_table[i],
5164 : 23500 : XFmode, &ext_80387_constants_table[i]);
5165 : : }
5166 : :
5167 : 2350 : ext_80387_constants_init = 1;
5168 : 2350 : }
5169 : :
5170 : : /* Return non-zero if the constant is something that
5171 : : can be loaded with a special instruction. */
5172 : :
5173 : : int
5174 : 4896996 : standard_80387_constant_p (rtx x)
5175 : : {
5176 : 4896996 : machine_mode mode = GET_MODE (x);
5177 : :
5178 : 4896996 : const REAL_VALUE_TYPE *r;
5179 : :
5180 : 4896996 : if (!(CONST_DOUBLE_P (x) && X87_FLOAT_MODE_P (mode)))
5181 : : return -1;
5182 : :
5183 : 4477509 : if (x == CONST0_RTX (mode))
5184 : : return 1;
5185 : 2027275 : if (x == CONST1_RTX (mode))
5186 : : return 2;
5187 : :
5188 : 1199074 : r = CONST_DOUBLE_REAL_VALUE (x);
5189 : :
5190 : : /* For XFmode constants, try to find a special 80387 instruction when
5191 : : optimizing for size or on those CPUs that benefit from them. */
5192 : 1199074 : if (mode == XFmode
5193 : 783816 : && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
5194 : 1982890 : && !flag_rounding_math)
5195 : : {
5196 : 776168 : int i;
5197 : :
5198 : 776168 : if (! ext_80387_constants_init)
5199 : 2343 : init_ext_80387_constants ();
5200 : :
5201 : 4646514 : for (i = 0; i < 5; i++)
5202 : 3879159 : if (real_identical (r, &ext_80387_constants_table[i]))
5203 : 8813 : return i + 3;
5204 : : }
5205 : :
5206 : : /* Load of the constant -0.0 or -1.0 will be split as
5207 : : fldz;fchs or fld1;fchs sequence. */
5208 : 1190261 : if (real_isnegzero (r))
5209 : : return 8;
5210 : 1174413 : if (real_identical (r, &dconstm1))
5211 : 294746 : return 9;
5212 : :
5213 : : return 0;
5214 : : }
5215 : :
5216 : : /* Return the opcode of the special instruction to be used to load
5217 : : the constant X. */
5218 : :
5219 : : const char *
5220 : 55257 : standard_80387_constant_opcode (rtx x)
5221 : : {
5222 : 55257 : switch (standard_80387_constant_p (x))
5223 : : {
5224 : : case 1:
5225 : : return "fldz";
5226 : 34083 : case 2:
5227 : 34083 : return "fld1";
5228 : 1 : case 3:
5229 : 1 : return "fldlg2";
5230 : 10 : case 4:
5231 : 10 : return "fldln2";
5232 : 12 : case 5:
5233 : 12 : return "fldl2e";
5234 : 2 : case 6:
5235 : 2 : return "fldl2t";
5236 : 192 : case 7:
5237 : 192 : return "fldpi";
5238 : 0 : case 8:
5239 : 0 : case 9:
5240 : 0 : return "#";
5241 : 0 : default:
5242 : 0 : gcc_unreachable ();
5243 : : }
5244 : : }
5245 : :
5246 : : /* Return the CONST_DOUBLE representing the 80387 constant that is
5247 : : loaded by the specified special instruction. The argument IDX
5248 : : matches the return value from standard_80387_constant_p. */
5249 : :
5250 : : rtx
5251 : 24 : standard_80387_constant_rtx (int idx)
5252 : : {
5253 : 24 : int i;
5254 : :
5255 : 24 : if (! ext_80387_constants_init)
5256 : 7 : init_ext_80387_constants ();
5257 : :
5258 : 24 : switch (idx)
5259 : : {
5260 : 24 : case 3:
5261 : 24 : case 4:
5262 : 24 : case 5:
5263 : 24 : case 6:
5264 : 24 : case 7:
5265 : 24 : i = idx - 3;
5266 : 24 : break;
5267 : :
5268 : 0 : default:
5269 : 0 : gcc_unreachable ();
5270 : : }
5271 : :
5272 : 24 : return const_double_from_real_value (ext_80387_constants_table[i],
5273 : 24 : XFmode);
5274 : : }
5275 : :
5276 : : /* Return 1 if X is all bits 0, 2 if X is all bits 1
5277 : : and 3 if X is all bits 1 with zero extend
5278 : : in supported SSE/AVX vector mode. */
5279 : :
5280 : : int
5281 : 35465390 : standard_sse_constant_p (rtx x, machine_mode pred_mode)
5282 : : {
5283 : 35465390 : machine_mode mode;
5284 : :
5285 : 35465390 : if (!TARGET_SSE)
5286 : : return 0;
5287 : :
5288 : 35302166 : mode = GET_MODE (x);
5289 : :
5290 : 35302166 : if (x == const0_rtx || const0_operand (x, mode))
5291 : 7720176 : return 1;
5292 : :
5293 : 27581990 : if (x == constm1_rtx
5294 : 27456559 : || vector_all_ones_operand (x, mode)
5295 : 54950660 : || ((GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
5296 : 23559842 : || GET_MODE_CLASS (pred_mode) == MODE_VECTOR_FLOAT)
5297 : 3808828 : && float_vector_all_ones_operand (x, mode)))
5298 : : {
5299 : : /* VOIDmode integer constant, get mode from the predicate. */
5300 : 214735 : if (mode == VOIDmode)
5301 : 125431 : mode = pred_mode;
5302 : :
5303 : 429470 : switch (GET_MODE_SIZE (mode))
5304 : : {
5305 : 7473 : case 64:
5306 : 7473 : if (TARGET_AVX512F && TARGET_EVEX512)
5307 : : return 2;
5308 : : break;
5309 : 6326 : case 32:
5310 : 6326 : if (TARGET_AVX2)
5311 : : return 2;
5312 : : break;
5313 : 190575 : case 16:
5314 : 190575 : if (TARGET_SSE2)
5315 : : return 2;
5316 : : break;
5317 : 0 : case 0:
5318 : : /* VOIDmode */
5319 : 0 : gcc_unreachable ();
5320 : : default:
5321 : : break;
5322 : : }
5323 : : }
5324 : :
5325 : 27378097 : if (vector_all_ones_zero_extend_half_operand (x, mode)
5326 : 27378097 : || vector_all_ones_zero_extend_quarter_operand (x, mode))
5327 : 407 : return 3;
5328 : :
5329 : : return 0;
5330 : : }
5331 : :
5332 : : /* Return the opcode of the special instruction to be used to load
5333 : : the constant operands[1] into operands[0]. */
5334 : :
5335 : : const char *
5336 : 423462 : standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
5337 : : {
5338 : 423462 : machine_mode mode;
5339 : 423462 : rtx x = operands[1];
5340 : :
5341 : 423462 : gcc_assert (TARGET_SSE);
5342 : :
5343 : 423462 : mode = GET_MODE (x);
5344 : :
5345 : 423462 : if (x == const0_rtx || const0_operand (x, mode))
5346 : : {
5347 : 420672 : switch (get_attr_mode (insn))
5348 : : {
5349 : 405269 : case MODE_TI:
5350 : 405269 : if (!EXT_REX_SSE_REG_P (operands[0]))
5351 : : return "%vpxor\t%0, %d0";
5352 : : /* FALLTHRU */
5353 : 4277 : case MODE_XI:
5354 : 4277 : case MODE_OI:
5355 : 4277 : if (EXT_REX_SSE_REG_P (operands[0]))
5356 : : {
5357 : 25 : if (TARGET_AVX512VL)
5358 : : return "vpxord\t%x0, %x0, %x0";
5359 : 22 : else if (TARGET_EVEX512)
5360 : : return "vpxord\t%g0, %g0, %g0";
5361 : : else
5362 : 0 : gcc_unreachable ();
5363 : : }
5364 : : return "vpxor\t%x0, %x0, %x0";
5365 : :
5366 : 1991 : case MODE_V2DF:
5367 : 1991 : if (!EXT_REX_SSE_REG_P (operands[0]))
5368 : : return "%vxorpd\t%0, %d0";
5369 : : /* FALLTHRU */
5370 : 871 : case MODE_V8DF:
5371 : 871 : case MODE_V4DF:
5372 : 871 : if (EXT_REX_SSE_REG_P (operands[0]))
5373 : : {
5374 : 5 : if (TARGET_AVX512DQ)
5375 : : {
5376 : 0 : if (TARGET_AVX512VL)
5377 : : return "vxorpd\t%x0, %x0, %x0";
5378 : 0 : else if (TARGET_EVEX512)
5379 : : return "vxorpd\t%g0, %g0, %g0";
5380 : : else
5381 : 0 : gcc_unreachable ();
5382 : : }
5383 : : else
5384 : : {
5385 : 5 : if (TARGET_AVX512VL)
5386 : : return "vpxorq\t%x0, %x0, %x0";
5387 : 5 : else if (TARGET_EVEX512)
5388 : : return "vpxorq\t%g0, %g0, %g0";
5389 : : else
5390 : 0 : gcc_unreachable ();
5391 : : }
5392 : : }
5393 : : return "vxorpd\t%x0, %x0, %x0";
5394 : :
5395 : 6368 : case MODE_V4SF:
5396 : 6368 : if (!EXT_REX_SSE_REG_P (operands[0]))
5397 : : return "%vxorps\t%0, %d0";
5398 : : /* FALLTHRU */
5399 : 1921 : case MODE_V16SF:
5400 : 1921 : case MODE_V8SF:
5401 : 1921 : if (EXT_REX_SSE_REG_P (operands[0]))
5402 : : {
5403 : 24 : if (TARGET_AVX512DQ)
5404 : : {
5405 : 21 : if (TARGET_AVX512VL)
5406 : : return "vxorps\t%x0, %x0, %x0";
5407 : 0 : else if (TARGET_EVEX512)
5408 : : return "vxorps\t%g0, %g0, %g0";
5409 : : else
5410 : 0 : gcc_unreachable ();
5411 : : }
5412 : : else
5413 : : {
5414 : 3 : if (TARGET_AVX512VL)
5415 : : return "vpxord\t%x0, %x0, %x0";
5416 : 0 : else if (TARGET_EVEX512)
5417 : : return "vpxord\t%g0, %g0, %g0";
5418 : : else
5419 : 0 : gcc_unreachable ();
5420 : : }
5421 : : }
5422 : : return "vxorps\t%x0, %x0, %x0";
5423 : :
5424 : 0 : default:
5425 : 0 : gcc_unreachable ();
5426 : : }
5427 : : }
5428 : 2790 : else if (x == constm1_rtx
5429 : 2781 : || vector_all_ones_operand (x, mode)
5430 : 2836 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
5431 : 26 : && float_vector_all_ones_operand (x, mode)))
5432 : : {
5433 : 2770 : enum attr_mode insn_mode = get_attr_mode (insn);
5434 : :
5435 : 2770 : switch (insn_mode)
5436 : : {
5437 : 0 : case MODE_XI:
5438 : 0 : case MODE_V8DF:
5439 : 0 : case MODE_V16SF:
5440 : 0 : gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
5441 : : return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
5442 : :
5443 : 162 : case MODE_OI:
5444 : 162 : case MODE_V4DF:
5445 : 162 : case MODE_V8SF:
5446 : 162 : gcc_assert (TARGET_AVX2);
5447 : : /* FALLTHRU */
5448 : 2770 : case MODE_TI:
5449 : 2770 : case MODE_V2DF:
5450 : 2770 : case MODE_V4SF:
5451 : 2770 : gcc_assert (TARGET_SSE2);
5452 : 2770 : if (EXT_REX_SSE_REG_P (operands[0]))
5453 : : {
5454 : 2 : if (TARGET_AVX512VL)
5455 : : return "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}";
5456 : 0 : else if (TARGET_EVEX512)
5457 : : return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
5458 : : else
5459 : 0 : gcc_unreachable ();
5460 : : }
5461 : 2768 : return (TARGET_AVX
5462 : 2768 : ? "vpcmpeqd\t%0, %0, %0"
5463 : 2768 : : "pcmpeqd\t%0, %0");
5464 : :
5465 : 0 : default:
5466 : 0 : gcc_unreachable ();
5467 : : }
5468 : : }
5469 : 20 : else if (vector_all_ones_zero_extend_half_operand (x, mode))
5470 : : {
5471 : 38 : if (GET_MODE_SIZE (mode) == 64)
5472 : : {
5473 : 5 : gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
5474 : : return "vpcmpeqd\t%t0, %t0, %t0";
5475 : : }
5476 : 28 : else if (GET_MODE_SIZE (mode) == 32)
5477 : : {
5478 : 14 : gcc_assert (TARGET_AVX);
5479 : : return "vpcmpeqd\t%x0, %x0, %x0";
5480 : : }
5481 : 0 : gcc_unreachable ();
5482 : : }
5483 : 1 : else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
5484 : : {
5485 : 1 : gcc_assert (TARGET_AVX512F && TARGET_EVEX512);
5486 : : return "vpcmpeqd\t%x0, %x0, %x0";
5487 : : }
5488 : :
5489 : 0 : gcc_unreachable ();
5490 : : }
5491 : :
5492 : : /* Returns true if INSN can be transformed from a memory load
5493 : : to a supported FP constant load. */
5494 : :
5495 : : bool
5496 : 2151814 : ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
5497 : : {
5498 : 2151814 : rtx src = find_constant_src (insn);
5499 : :
5500 : 2151814 : gcc_assert (REG_P (dst));
5501 : :
5502 : 2151814 : if (src == NULL
5503 : 604477 : || (SSE_REGNO_P (REGNO (dst))
5504 : 471012 : && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
5505 : 166561 : || (!TARGET_AVX512VL
5506 : 166499 : && EXT_REX_SSE_REGNO_P (REGNO (dst))
5507 : 14 : && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
5508 : 2318361 : || (STACK_REGNO_P (REGNO (dst))
5509 : 133465 : && standard_80387_constant_p (src) < 1))
5510 : 2075194 : return false;
5511 : :
5512 : : return true;
5513 : : }
5514 : :
5515 : : /* Predicate for pre-reload splitters with associated instructions,
5516 : : which can match any time before the split1 pass (usually combine),
5517 : : then are unconditionally split in that pass and should not be
5518 : : matched again afterwards. */
5519 : :
5520 : : bool
5521 : 5828383 : ix86_pre_reload_split (void)
5522 : : {
5523 : 5828383 : return (can_create_pseudo_p ()
5524 : 8719106 : && !(cfun->curr_properties & PROP_rtl_split_insns));
5525 : : }
5526 : :
5527 : : /* Return the opcode of the TYPE_SSEMOV instruction. To move from
5528 : : or to xmm16-xmm31/ymm16-ymm31 registers, we either require
5529 : : TARGET_AVX512VL or it is a register to register move which can
5530 : : be done with zmm register move. */
5531 : :
5532 : : static const char *
5533 : 3621484 : ix86_get_ssemov (rtx *operands, unsigned size,
5534 : : enum attr_mode insn_mode, machine_mode mode)
5535 : : {
5536 : 3621484 : char buf[128];
5537 : 3621484 : bool misaligned_p = (misaligned_operand (operands[0], mode)
5538 : 3621484 : || misaligned_operand (operands[1], mode));
5539 : 3621484 : bool evex_reg_p = (size == 64
5540 : 3546174 : || EXT_REX_SSE_REG_P (operands[0])
5541 : 7167048 : || EXT_REX_SSE_REG_P (operands[1]));
5542 : :
5543 : 3621484 : bool egpr_p = (TARGET_APX_EGPR
5544 : 3621484 : && (x86_extended_rex2reg_mentioned_p (operands[0])
5545 : 101 : || x86_extended_rex2reg_mentioned_p (operands[1])));
5546 : 193 : bool egpr_vl = egpr_p && TARGET_AVX512VL;
5547 : :
5548 : 3621484 : machine_mode scalar_mode;
5549 : :
5550 : 3621484 : const char *opcode = NULL;
5551 : 3621484 : enum
5552 : : {
5553 : : opcode_int,
5554 : : opcode_float,
5555 : : opcode_double
5556 : 3621484 : } type = opcode_int;
5557 : :
5558 : 3621484 : switch (insn_mode)
5559 : : {
5560 : : case MODE_V16SF:
5561 : : case MODE_V8SF:
5562 : : case MODE_V4SF:
5563 : : scalar_mode = E_SFmode;
5564 : : type = opcode_float;
5565 : : break;
5566 : 196718 : case MODE_V8DF:
5567 : 196718 : case MODE_V4DF:
5568 : 196718 : case MODE_V2DF:
5569 : 196718 : scalar_mode = E_DFmode;
5570 : 196718 : type = opcode_double;
5571 : 196718 : break;
5572 : 1275395 : case MODE_XI:
5573 : 1275395 : case MODE_OI:
5574 : 1275395 : case MODE_TI:
5575 : 1275395 : scalar_mode = GET_MODE_INNER (mode);
5576 : : break;
5577 : 0 : default:
5578 : 0 : gcc_unreachable ();
5579 : : }
5580 : :
5581 : : /* NB: To move xmm16-xmm31/ymm16-ymm31 registers without AVX512VL,
5582 : : we can only use zmm register move without memory operand. */
5583 : 3621484 : if (evex_reg_p
5584 : 76484 : && !TARGET_AVX512VL
5585 : 3661684 : && GET_MODE_SIZE (mode) < 64)
5586 : : {
5587 : : /* NB: Even though ix86_hard_regno_mode_ok doesn't allow
5588 : : xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when
5589 : : AVX512VL is disabled, LRA can still generate reg to
5590 : : reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit
5591 : : modes. */
5592 : 0 : if (memory_operand (operands[0], mode)
5593 : 0 : || memory_operand (operands[1], mode))
5594 : 0 : gcc_unreachable ();
5595 : 0 : size = 64;
5596 : : /* We need TARGET_EVEX512 to move into zmm register. */
5597 : 0 : gcc_assert (TARGET_EVEX512);
5598 : 0 : switch (type)
5599 : : {
5600 : 0 : case opcode_int:
5601 : 0 : if (scalar_mode == E_HFmode || scalar_mode == E_BFmode)
5602 : 0 : opcode = (misaligned_p
5603 : 0 : ? (TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64")
5604 : : : "vmovdqa64");
5605 : : else
5606 : 0 : opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
5607 : : break;
5608 : 0 : case opcode_float:
5609 : 0 : opcode = misaligned_p ? "vmovups" : "vmovaps";
5610 : : break;
5611 : 0 : case opcode_double:
5612 : 0 : opcode = misaligned_p ? "vmovupd" : "vmovapd";
5613 : : break;
5614 : : }
5615 : : }
5616 : 3621484 : else if (SCALAR_FLOAT_MODE_P (scalar_mode))
5617 : : {
5618 : 2515362 : switch (scalar_mode)
5619 : : {
5620 : 29441 : case E_HFmode:
5621 : 29441 : case E_BFmode:
5622 : 29441 : if (evex_reg_p || egpr_vl)
5623 : 8817 : opcode = (misaligned_p
5624 : 159 : ? (TARGET_AVX512BW
5625 : : ? "vmovdqu16"
5626 : : : "vmovdqu64")
5627 : : : "vmovdqa64");
5628 : 20624 : else if (egpr_p)
5629 : 0 : opcode = (misaligned_p
5630 : 0 : ? (TARGET_AVX512BW
5631 : 0 : ? "vmovdqu16"
5632 : : : "%vmovups")
5633 : : : "%vmovaps");
5634 : : else
5635 : 20624 : opcode = (misaligned_p
5636 : 20624 : ? (TARGET_AVX512BW
5637 : 463 : ? "vmovdqu16"
5638 : : : "%vmovdqu")
5639 : : : "%vmovdqa");
5640 : : break;
5641 : 2149371 : case E_SFmode:
5642 : 2149371 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5643 : : break;
5644 : 196718 : case E_DFmode:
5645 : 196718 : opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
5646 : : break;
5647 : 139832 : case E_TFmode:
5648 : 139832 : if (evex_reg_p || egpr_vl)
5649 : 14 : opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
5650 : 139818 : else if (egpr_p)
5651 : 0 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5652 : : else
5653 : 139818 : opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
5654 : : break;
5655 : 0 : default:
5656 : 0 : gcc_unreachable ();
5657 : : }
5658 : : }
5659 : 1106122 : else if (SCALAR_INT_MODE_P (scalar_mode))
5660 : : {
5661 : 1106122 : switch (scalar_mode)
5662 : : {
5663 : 38499 : case E_QImode:
5664 : 38499 : if (evex_reg_p || egpr_vl)
5665 : 5596 : opcode = (misaligned_p
5666 : 5596 : ? (TARGET_AVX512BW
5667 : 2351 : ? "vmovdqu8"
5668 : : : "vmovdqu64")
5669 : : : "vmovdqa64");
5670 : 32903 : else if (egpr_p)
5671 : 30 : opcode = (misaligned_p
5672 : 0 : ? (TARGET_AVX512BW
5673 : : ? "vmovdqu8"
5674 : : : "%vmovups")
5675 : : : "%vmovaps");
5676 : : else
5677 : 32873 : opcode = (misaligned_p
5678 : 4454 : ? (TARGET_AVX512BW
5679 : : ? "vmovdqu8"
5680 : : : "%vmovdqu")
5681 : : : "%vmovdqa");
5682 : : break;
5683 : 36204 : case E_HImode:
5684 : 36204 : if (evex_reg_p || egpr_vl)
5685 : 3124 : opcode = (misaligned_p
5686 : 111 : ? (TARGET_AVX512BW
5687 : : ? "vmovdqu16"
5688 : : : "vmovdqu64")
5689 : : : "vmovdqa64");
5690 : 33080 : else if (egpr_p)
5691 : 27 : opcode = (misaligned_p
5692 : 27 : ? (TARGET_AVX512BW
5693 : 0 : ? "vmovdqu16"
5694 : : : "%vmovups")
5695 : : : "%vmovaps");
5696 : : else
5697 : 33053 : opcode = (misaligned_p
5698 : 33053 : ? (TARGET_AVX512BW
5699 : 2903 : ? "vmovdqu16"
5700 : : : "%vmovdqu")
5701 : : : "%vmovdqa");
5702 : : break;
5703 : 138615 : case E_SImode:
5704 : 138615 : if (evex_reg_p || egpr_vl)
5705 : 7047 : opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
5706 : 131568 : else if (egpr_p)
5707 : 14 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5708 : : else
5709 : 131554 : opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
5710 : : break;
5711 : 881759 : case E_DImode:
5712 : 881759 : case E_TImode:
5713 : 881759 : case E_OImode:
5714 : 881759 : if (evex_reg_p || egpr_vl)
5715 : 16999 : opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
5716 : 864760 : else if (egpr_p)
5717 : 26 : opcode = misaligned_p ? "%vmovups" : "%vmovaps";
5718 : : else
5719 : 864734 : opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
5720 : : break;
5721 : 11045 : case E_XImode:
5722 : 11045 : opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
5723 : : break;
5724 : 0 : default:
5725 : 0 : gcc_unreachable ();
5726 : : }
5727 : : }
5728 : : else
5729 : 0 : gcc_unreachable ();
5730 : :
5731 : 3621484 : switch (size)
5732 : : {
5733 : 75310 : case 64:
5734 : 75310 : snprintf (buf, sizeof (buf), "%s\t{%%g1, %%g0|%%g0, %%g1}",
5735 : : opcode);
5736 : 75310 : break;
5737 : 80140 : case 32:
5738 : 80140 : snprintf (buf, sizeof (buf), "%s\t{%%t1, %%t0|%%t0, %%t1}",
5739 : : opcode);
5740 : 80140 : break;
5741 : 3466034 : case 16:
5742 : 3466034 : snprintf (buf, sizeof (buf), "%s\t{%%x1, %%x0|%%x0, %%x1}",
5743 : : opcode);
5744 : 3466034 : break;
5745 : 0 : default:
5746 : 0 : gcc_unreachable ();
5747 : : }
5748 : 3621484 : output_asm_insn (buf, operands);
5749 : 3621484 : return "";
5750 : : }
5751 : :
5752 : : /* Return the template of the TYPE_SSEMOV instruction to move
5753 : : operands[1] into operands[0]. */
5754 : :
5755 : : const char *
5756 : 6085310 : ix86_output_ssemov (rtx_insn *insn, rtx *operands)
5757 : : {
5758 : 6085310 : machine_mode mode = GET_MODE (operands[0]);
5759 : 6085310 : if (get_attr_type (insn) != TYPE_SSEMOV
5760 : 6085310 : || mode != GET_MODE (operands[1]))
5761 : 0 : gcc_unreachable ();
5762 : :
5763 : 6085310 : enum attr_mode insn_mode = get_attr_mode (insn);
5764 : :
5765 : 6085310 : switch (insn_mode)
5766 : : {
5767 : 75310 : case MODE_XI:
5768 : 75310 : case MODE_V8DF:
5769 : 75310 : case MODE_V16SF:
5770 : 75310 : return ix86_get_ssemov (operands, 64, insn_mode, mode);
5771 : :
5772 : 80140 : case MODE_OI:
5773 : 80140 : case MODE_V4DF:
5774 : 80140 : case MODE_V8SF:
5775 : 80140 : return ix86_get_ssemov (operands, 32, insn_mode, mode);
5776 : :
5777 : 3466034 : case MODE_TI:
5778 : 3466034 : case MODE_V2DF:
5779 : 3466034 : case MODE_V4SF:
5780 : 3466034 : return ix86_get_ssemov (operands, 16, insn_mode, mode);
5781 : :
5782 : 727107 : case MODE_DI:
5783 : : /* Handle broken assemblers that require movd instead of movq. */
5784 : 727107 : if (GENERAL_REG_P (operands[0]))
5785 : : {
5786 : : if (HAVE_AS_IX86_INTERUNIT_MOVQ)
5787 : : return "%vmovq\t{%1, %q0|%q0, %1}";
5788 : : else
5789 : : return "%vmovd\t{%1, %q0|%q0, %1}";
5790 : : }
5791 : 653143 : else if (GENERAL_REG_P (operands[1]))
5792 : : {
5793 : : if (HAVE_AS_IX86_INTERUNIT_MOVQ)
5794 : : return "%vmovq\t{%q1, %0|%0, %q1}";
5795 : : else
5796 : : return "%vmovd\t{%q1, %0|%0, %q1}";
5797 : : }
5798 : : else
5799 : 460950 : return "%vmovq\t{%1, %0|%0, %1}";
5800 : :
5801 : 246817 : case MODE_SI:
5802 : 246817 : if (GENERAL_REG_P (operands[0]))
5803 : : return "%vmovd\t{%1, %k0|%k0, %1}";
5804 : 194069 : else if (GENERAL_REG_P (operands[1]))
5805 : : return "%vmovd\t{%k1, %0|%0, %k1}";
5806 : : else
5807 : 82254 : return "%vmovd\t{%1, %0|%0, %1}";
5808 : :
5809 : 49114 : case MODE_HI:
5810 : 49114 : if (GENERAL_REG_P (operands[0]))
5811 : : return "vmovw\t{%1, %k0|%k0, %1}";
5812 : 49088 : else if (GENERAL_REG_P (operands[1]))
5813 : : return "vmovw\t{%k1, %0|%0, %k1}";
5814 : : else
5815 : 48985 : return "vmovw\t{%1, %0|%0, %1}";
5816 : :
5817 : 774844 : case MODE_DF:
5818 : 774844 : if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
5819 : : return "vmovsd\t{%d1, %0|%0, %d1}";
5820 : : else
5821 : 773849 : return "%vmovsd\t{%1, %0|%0, %1}";
5822 : :
5823 : 662838 : case MODE_SF:
5824 : 662838 : if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
5825 : : return "vmovss\t{%d1, %0|%0, %d1}";
5826 : : else
5827 : 662197 : return "%vmovss\t{%1, %0|%0, %1}";
5828 : :
5829 : 52 : case MODE_HF:
5830 : 52 : case MODE_BF:
5831 : 52 : if (REG_P (operands[0]) && REG_P (operands[1]))
5832 : : return "vmovsh\t{%d1, %0|%0, %d1}";
5833 : : else
5834 : 0 : return "vmovsh\t{%1, %0|%0, %1}";
5835 : :
5836 : 33 : case MODE_V1DF:
5837 : 33 : gcc_assert (!TARGET_AVX);
5838 : : return "movlpd\t{%1, %0|%0, %1}";
5839 : :
5840 : 3021 : case MODE_V2SF:
5841 : 3021 : if (TARGET_AVX && REG_P (operands[0]))
5842 : : return "vmovlps\t{%1, %d0|%d0, %1}";
5843 : : else
5844 : 2935 : return "%vmovlps\t{%1, %0|%0, %1}";
5845 : :
5846 : 0 : default:
5847 : 0 : gcc_unreachable ();
5848 : : }
5849 : : }
5850 : :
5851 : : /* Returns true if OP contains a symbol reference */
5852 : :
5853 : : bool
5854 : 496587938 : symbolic_reference_mentioned_p (rtx op)
5855 : : {
5856 : 496587938 : const char *fmt;
5857 : 496587938 : int i;
5858 : :
5859 : 496587938 : if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5860 : : return true;
5861 : :
5862 : 375640127 : fmt = GET_RTX_FORMAT (GET_CODE (op));
5863 : 638412656 : for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5864 : : {
5865 : 509026372 : if (fmt[i] == 'E')
5866 : : {
5867 : 1797015 : int j;
5868 : :
5869 : 3630367 : for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5870 : 2993934 : if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5871 : : return true;
5872 : : }
5873 : :
5874 : 507229357 : else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5875 : : return true;
5876 : : }
5877 : :
5878 : : return false;
5879 : : }
5880 : :
5881 : : /* Return true if it is appropriate to emit `ret' instructions in the
5882 : : body of a function. Do this only if the epilogue is simple, needing a
5883 : : couple of insns. Prior to reloading, we can't tell how many registers
5884 : : must be saved, so return false then. Return false if there is no frame
5885 : : marker to de-allocate. */
5886 : :
5887 : : bool
5888 : 0 : ix86_can_use_return_insn_p (void)
5889 : : {
5890 : 0 : if (ix86_function_ms_hook_prologue (current_function_decl))
5891 : : return false;
5892 : :
5893 : 0 : if (ix86_function_naked (current_function_decl))
5894 : : return false;
5895 : :
5896 : : /* Don't use `ret' instruction in interrupt handler. */
5897 : 0 : if (! reload_completed
5898 : 0 : || frame_pointer_needed
5899 : 0 : || cfun->machine->func_type != TYPE_NORMAL)
5900 : : return 0;
5901 : :
5902 : : /* Don't allow more than 32k pop, since that's all we can do
5903 : : with one instruction. */
5904 : 0 : if (crtl->args.pops_args && crtl->args.size >= 32768)
5905 : : return 0;
5906 : :
5907 : 0 : struct ix86_frame &frame = cfun->machine->frame;
5908 : 0 : return (frame.stack_pointer_offset == UNITS_PER_WORD
5909 : 0 : && (frame.nregs + frame.nsseregs) == 0);
5910 : : }
5911 : :
5912 : : /* Return stack frame size. get_frame_size () returns used stack slots
5913 : : during compilation, which may be optimized out later. If stack frame
5914 : : is needed, stack_frame_required should be true. */
5915 : :
5916 : : static HOST_WIDE_INT
5917 : 7599095 : ix86_get_frame_size (void)
5918 : : {
5919 : 7599095 : if (cfun->machine->stack_frame_required)
5920 : 7541689 : return get_frame_size ();
5921 : : else
5922 : : return 0;
5923 : : }
5924 : :
5925 : : /* Value should be nonzero if functions must have frame pointers.
5926 : : Zero means the frame pointer need not be set up (and parms may
5927 : : be accessed via the stack pointer) in functions that seem suitable. */
5928 : :
5929 : : static bool
5930 : 1098092 : ix86_frame_pointer_required (void)
5931 : : {
5932 : : /* If we accessed previous frames, then the generated code expects
5933 : : to be able to access the saved ebp value in our frame. */
5934 : 1098092 : if (cfun->machine->accesses_prev_frame)
5935 : : return true;
5936 : :
5937 : : /* Several x86 os'es need a frame pointer for other reasons,
5938 : : usually pertaining to setjmp. */
5939 : 1098059 : if (SUBTARGET_FRAME_POINTER_REQUIRED)
5940 : : return true;
5941 : :
5942 : : /* For older 32-bit runtimes setjmp requires valid frame-pointer. */
5943 : 1098059 : if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
5944 : : return true;
5945 : :
5946 : : /* Win64 SEH, very large frames need a frame-pointer as maximum stack
5947 : : allocation is 4GB. */
5948 : 1098059 : if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
5949 : : return true;
5950 : :
5951 : : /* SSE saves require frame-pointer when stack is misaligned. */
5952 : 1098059 : if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
5953 : : return true;
5954 : :
5955 : : /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
5956 : : turns off the frame pointer by default. Turn it back on now if
5957 : : we've not got a leaf function. */
5958 : 1098058 : if (TARGET_OMIT_LEAF_FRAME_POINTER
5959 : 1098058 : && (!crtl->is_leaf
5960 : 0 : || ix86_current_function_calls_tls_descriptor))
5961 : 0 : return true;
5962 : :
5963 : : /* Several versions of mcount for the x86 assumes that there is a
5964 : : frame, so we cannot allow profiling without a frame pointer. */
5965 : 1098058 : if (crtl->profile && !flag_fentry)
5966 : : return true;
5967 : :
5968 : : return false;
5969 : : }
5970 : :
5971 : : /* Record that the current function accesses previous call frames. */
5972 : :
5973 : : void
5974 : 1016 : ix86_setup_frame_addresses (void)
5975 : : {
5976 : 1016 : cfun->machine->accesses_prev_frame = 1;
5977 : 1016 : }
5978 : :
5979 : : #ifndef USE_HIDDEN_LINKONCE
5980 : : # if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
5981 : : # define USE_HIDDEN_LINKONCE 1
5982 : : # else
5983 : : # define USE_HIDDEN_LINKONCE 0
5984 : : # endif
5985 : : #endif
5986 : :
5987 : : /* Label count for call and return thunks. It is used to make unique
5988 : : labels in call and return thunks. */
5989 : : static int indirectlabelno;
5990 : :
5991 : : /* True if call thunk function is needed. */
5992 : : static bool indirect_thunk_needed = false;
5993 : :
5994 : : /* Bit masks of integer registers, which contain branch target, used
5995 : : by call thunk functions. */
5996 : : static HARD_REG_SET indirect_thunks_used;
5997 : :
5998 : : /* True if return thunk function is needed. */
5999 : : static bool indirect_return_needed = false;
6000 : :
6001 : : /* True if return thunk function via CX is needed. */
6002 : : static bool indirect_return_via_cx;
6003 : :
6004 : : #ifndef INDIRECT_LABEL
6005 : : # define INDIRECT_LABEL "LIND"
6006 : : #endif
6007 : :
6008 : : /* Indicate what prefix is needed for an indirect branch. */
6009 : : enum indirect_thunk_prefix
6010 : : {
6011 : : indirect_thunk_prefix_none,
6012 : : indirect_thunk_prefix_nt
6013 : : };
6014 : :
6015 : : /* Return the prefix needed for an indirect branch INSN. */
6016 : :
6017 : : enum indirect_thunk_prefix
6018 : 67 : indirect_thunk_need_prefix (rtx_insn *insn)
6019 : : {
6020 : 67 : enum indirect_thunk_prefix need_prefix;
6021 : 67 : if ((cfun->machine->indirect_branch_type
6022 : 67 : == indirect_branch_thunk_extern)
6023 : 67 : && ix86_notrack_prefixed_insn_p (insn))
6024 : : {
6025 : : /* NOTRACK prefix is only used with external thunk so that it
6026 : : can be properly updated to support CET at run-time. */
6027 : : need_prefix = indirect_thunk_prefix_nt;
6028 : : }
6029 : : else
6030 : : need_prefix = indirect_thunk_prefix_none;
6031 : 67 : return need_prefix;
6032 : : }
6033 : :
6034 : : /* Fills in the label name that should be used for the indirect thunk. */
6035 : :
6036 : : static void
6037 : 73 : indirect_thunk_name (char name[32], unsigned int regno,
6038 : : enum indirect_thunk_prefix need_prefix,
6039 : : bool ret_p)
6040 : : {
6041 : 73 : if (regno != INVALID_REGNUM && regno != CX_REG && ret_p)
6042 : 0 : gcc_unreachable ();
6043 : :
6044 : 73 : if (USE_HIDDEN_LINKONCE)
6045 : : {
6046 : 73 : const char *prefix;
6047 : :
6048 : 73 : if (need_prefix == indirect_thunk_prefix_nt
6049 : 73 : && regno != INVALID_REGNUM)
6050 : : {
6051 : : /* NOTRACK prefix is only used with external thunk via
6052 : : register so that NOTRACK prefix can be added to indirect
6053 : : branch via register to support CET at run-time. */
6054 : : prefix = "_nt";
6055 : : }
6056 : : else
6057 : 71 : prefix = "";
6058 : :
6059 : 73 : const char *ret = ret_p ? "return" : "indirect";
6060 : :
6061 : 73 : if (regno != INVALID_REGNUM)
6062 : : {
6063 : 55 : const char *reg_prefix;
6064 : 55 : if (LEGACY_INT_REGNO_P (regno))
6065 : 53 : reg_prefix = TARGET_64BIT ? "r" : "e";
6066 : : else
6067 : : reg_prefix = "";
6068 : 55 : sprintf (name, "__x86_%s_thunk%s_%s%s",
6069 : : ret, prefix, reg_prefix, reg_names[regno]);
6070 : : }
6071 : : else
6072 : 18 : sprintf (name, "__x86_%s_thunk%s", ret, prefix);
6073 : : }
6074 : : else
6075 : : {
6076 : : if (regno != INVALID_REGNUM)
6077 : : ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
6078 : : else
6079 : : {
6080 : : if (ret_p)
6081 : : ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
6082 : : else
6083 : 73 : ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
6084 : : }
6085 : : }
6086 : 73 : }
6087 : :
6088 : : /* Output a call and return thunk for indirect branch. If REGNO != -1,
6089 : : the function address is in REGNO and the call and return thunk looks like:
6090 : :
6091 : : call L2
6092 : : L1:
6093 : : pause
6094 : : lfence
6095 : : jmp L1
6096 : : L2:
6097 : : mov %REG, (%sp)
6098 : : ret
6099 : :
6100 : : Otherwise, the function address is on the top of stack and the
6101 : : call and return thunk looks like:
6102 : :
6103 : : call L2
6104 : : L1:
6105 : : pause
6106 : : lfence
6107 : : jmp L1
6108 : : L2:
6109 : : lea WORD_SIZE(%sp), %sp
6110 : : ret
6111 : : */
6112 : :
6113 : : static void
6114 : 38 : output_indirect_thunk (unsigned int regno)
6115 : : {
6116 : 38 : char indirectlabel1[32];
6117 : 38 : char indirectlabel2[32];
6118 : :
6119 : 38 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
6120 : : indirectlabelno++);
6121 : 38 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
6122 : : indirectlabelno++);
6123 : :
6124 : : /* Call */
6125 : 38 : fputs ("\tcall\t", asm_out_file);
6126 : 38 : assemble_name_raw (asm_out_file, indirectlabel2);
6127 : 38 : fputc ('\n', asm_out_file);
6128 : :
6129 : 38 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
6130 : :
6131 : : /* AMD and Intel CPUs prefer each a different instruction as loop filler.
6132 : : Usage of both pause + lfence is compromise solution. */
6133 : 38 : fprintf (asm_out_file, "\tpause\n\tlfence\n");
6134 : :
6135 : : /* Jump. */
6136 : 38 : fputs ("\tjmp\t", asm_out_file);
6137 : 38 : assemble_name_raw (asm_out_file, indirectlabel1);
6138 : 38 : fputc ('\n', asm_out_file);
6139 : :
6140 : 38 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
6141 : :
6142 : : /* The above call insn pushed a word to stack. Adjust CFI info. */
6143 : 38 : if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
6144 : : {
6145 : 38 : if (! dwarf2out_do_cfi_asm ())
6146 : : {
6147 : 0 : dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
6148 : 0 : xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
6149 : 0 : xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
6150 : 0 : vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
6151 : : }
6152 : 38 : dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
6153 : 38 : xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
6154 : 38 : xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
6155 : 38 : vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
6156 : 38 : dwarf2out_emit_cfi (xcfi);
6157 : : }
6158 : :
6159 : 38 : if (regno != INVALID_REGNUM)
6160 : : {
6161 : : /* MOV. */
6162 : 27 : rtx xops[2];
6163 : 27 : xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
6164 : 27 : xops[1] = gen_rtx_REG (word_mode, regno);
6165 : 27 : output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
6166 : : }
6167 : : else
6168 : : {
6169 : : /* LEA. */
6170 : 11 : rtx xops[2];
6171 : 11 : xops[0] = stack_pointer_rtx;
6172 : 11 : xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
6173 : 11 : output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
6174 : : }
6175 : :
6176 : 38 : fputs ("\tret\n", asm_out_file);
6177 : 38 : if ((ix86_harden_sls & harden_sls_return))
6178 : 1 : fputs ("\tint3\n", asm_out_file);
6179 : 38 : }
6180 : :
6181 : : /* Output a funtion with a call and return thunk for indirect branch.
6182 : : If REGNO != INVALID_REGNUM, the function address is in REGNO.
6183 : : Otherwise, the function address is on the top of stack. Thunk is
6184 : : used for function return if RET_P is true. */
6185 : :
6186 : : static void
6187 : 22 : output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
6188 : : unsigned int regno, bool ret_p)
6189 : : {
6190 : 22 : char name[32];
6191 : 22 : tree decl;
6192 : :
6193 : : /* Create __x86_indirect_thunk. */
6194 : 22 : indirect_thunk_name (name, regno, need_prefix, ret_p);
6195 : 22 : decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
6196 : : get_identifier (name),
6197 : : build_function_type_list (void_type_node, NULL_TREE));
6198 : 22 : DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
6199 : : NULL_TREE, void_type_node);
6200 : 22 : TREE_PUBLIC (decl) = 1;
6201 : 22 : TREE_STATIC (decl) = 1;
6202 : 22 : DECL_IGNORED_P (decl) = 1;
6203 : :
6204 : : #if TARGET_MACHO
6205 : : if (TARGET_MACHO)
6206 : : {
6207 : : switch_to_section (darwin_sections[picbase_thunk_section]);
6208 : : fputs ("\t.weak_definition\t", asm_out_file);
6209 : : assemble_name (asm_out_file, name);
6210 : : fputs ("\n\t.private_extern\t", asm_out_file);
6211 : : assemble_name (asm_out_file, name);
6212 : : putc ('\n', asm_out_file);
6213 : : ASM_OUTPUT_LABEL (asm_out_file, name);
6214 : : DECL_WEAK (decl) = 1;
6215 : : }
6216 : : else
6217 : : #endif
6218 : 22 : if (USE_HIDDEN_LINKONCE)
6219 : : {
6220 : 22 : cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
6221 : :
6222 : 22 : targetm.asm_out.unique_section (decl, 0);
6223 : 22 : switch_to_section (get_named_section (decl, NULL, 0));
6224 : :
6225 : 22 : targetm.asm_out.globalize_label (asm_out_file, name);
6226 : 22 : fputs ("\t.hidden\t", asm_out_file);
6227 : 22 : assemble_name (asm_out_file, name);
6228 : 22 : putc ('\n', asm_out_file);
6229 : 22 : ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
6230 : : }
6231 : : else
6232 : : {
6233 : : switch_to_section (text_section);
6234 : 22 : ASM_OUTPUT_LABEL (asm_out_file, name);
6235 : : }
6236 : :
6237 : 22 : DECL_INITIAL (decl) = make_node (BLOCK);
6238 : 22 : current_function_decl = decl;
6239 : 22 : allocate_struct_function (decl, false);
6240 : 22 : init_function_start (decl);
6241 : : /* We're about to hide the function body from callees of final_* by
6242 : : emitting it directly; tell them we're a thunk, if they care. */
6243 : 22 : cfun->is_thunk = true;
6244 : 22 : first_function_block_is_cold = false;
6245 : : /* Make sure unwind info is emitted for the thunk if needed. */
6246 : 22 : final_start_function (emit_barrier (), asm_out_file, 1);
6247 : :
6248 : 22 : output_indirect_thunk (regno);
6249 : :
6250 : 22 : final_end_function ();
6251 : 22 : init_insn_lengths ();
6252 : 22 : free_after_compilation (cfun);
6253 : 22 : set_cfun (NULL);
6254 : 22 : current_function_decl = NULL;
6255 : 22 : }
6256 : :
6257 : : static int pic_labels_used;
6258 : :
6259 : : /* Fills in the label name that should be used for a pc thunk for
6260 : : the given register. */
6261 : :
6262 : : static void
6263 : 35633 : get_pc_thunk_name (char name[32], unsigned int regno)
6264 : : {
6265 : 35633 : gcc_assert (!TARGET_64BIT);
6266 : :
6267 : 35633 : if (USE_HIDDEN_LINKONCE)
6268 : 35633 : sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
6269 : : else
6270 : 35633 : ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
6271 : 35633 : }
6272 : :
6273 : :
6274 : : /* This function generates code for -fpic that loads %ebx with
6275 : : the return address of the caller and then returns. */
6276 : :
6277 : : static void
6278 : 224703 : ix86_code_end (void)
6279 : : {
6280 : 224703 : rtx xops[2];
6281 : 224703 : unsigned int regno;
6282 : :
6283 : 224703 : if (indirect_return_needed)
6284 : 6 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6285 : : INVALID_REGNUM, true);
6286 : 224703 : if (indirect_return_via_cx)
6287 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6288 : : CX_REG, true);
6289 : 224703 : if (indirect_thunk_needed)
6290 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6291 : : INVALID_REGNUM, false);
6292 : :
6293 : 2022327 : for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
6294 : : {
6295 : 1797624 : if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
6296 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6297 : : regno, false);
6298 : : }
6299 : :
6300 : 3819951 : for (regno = FIRST_REX2_INT_REG; regno <= LAST_REX2_INT_REG; regno++)
6301 : : {
6302 : 3595248 : if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
6303 : 0 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6304 : : regno, false);
6305 : : }
6306 : :
6307 : 2022327 : for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
6308 : : {
6309 : 1797624 : char name[32];
6310 : 1797624 : tree decl;
6311 : :
6312 : 1797624 : if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
6313 : 16 : output_indirect_thunk_function (indirect_thunk_prefix_none,
6314 : : regno, false);
6315 : :
6316 : 1797624 : if (!(pic_labels_used & (1 << regno)))
6317 : 1793986 : continue;
6318 : :
6319 : 3638 : get_pc_thunk_name (name, regno);
6320 : :
6321 : 3638 : decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
6322 : : get_identifier (name),
6323 : : build_function_type_list (void_type_node, NULL_TREE));
6324 : 3638 : DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
6325 : : NULL_TREE, void_type_node);
6326 : 3638 : TREE_PUBLIC (decl) = 1;
6327 : 3638 : TREE_STATIC (decl) = 1;
6328 : 3638 : DECL_IGNORED_P (decl) = 1;
6329 : :
6330 : : #if TARGET_MACHO
6331 : : if (TARGET_MACHO)
6332 : : {
6333 : : switch_to_section (darwin_sections[picbase_thunk_section]);
6334 : : fputs ("\t.weak_definition\t", asm_out_file);
6335 : : assemble_name (asm_out_file, name);
6336 : : fputs ("\n\t.private_extern\t", asm_out_file);
6337 : : assemble_name (asm_out_file, name);
6338 : : putc ('\n', asm_out_file);
6339 : : ASM_OUTPUT_LABEL (asm_out_file, name);
6340 : : DECL_WEAK (decl) = 1;
6341 : : }
6342 : : else
6343 : : #endif
6344 : 3638 : if (USE_HIDDEN_LINKONCE)
6345 : : {
6346 : 3638 : cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
6347 : :
6348 : 3638 : targetm.asm_out.unique_section (decl, 0);
6349 : 3638 : switch_to_section (get_named_section (decl, NULL, 0));
6350 : :
6351 : 3638 : targetm.asm_out.globalize_label (asm_out_file, name);
6352 : 3638 : fputs ("\t.hidden\t", asm_out_file);
6353 : 3638 : assemble_name (asm_out_file, name);
6354 : 3638 : putc ('\n', asm_out_file);
6355 : 3638 : ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
6356 : : }
6357 : : else
6358 : : {
6359 : : switch_to_section (text_section);
6360 : 3638 : ASM_OUTPUT_LABEL (asm_out_file, name);
6361 : : }
6362 : :
6363 : 3638 : DECL_INITIAL (decl) = make_node (BLOCK);
6364 : 3638 : current_function_decl = decl;
6365 : 3638 : allocate_struct_function (decl, false);
6366 : 3638 : init_function_start (decl);
6367 : : /* We're about to hide the function body from callees of final_* by
6368 : : emitting it directly; tell them we're a thunk, if they care. */
6369 : 3638 : cfun->is_thunk = true;
6370 : 3638 : first_function_block_is_cold = false;
6371 : : /* Make sure unwind info is emitted for the thunk if needed. */
6372 : 3638 : final_start_function (emit_barrier (), asm_out_file, 1);
6373 : :
6374 : : /* Pad stack IP move with 4 instructions (two NOPs count
6375 : : as one instruction). */
6376 : 3638 : if (TARGET_PAD_SHORT_FUNCTION)
6377 : : {
6378 : : int i = 8;
6379 : :
6380 : 0 : while (i--)
6381 : 0 : fputs ("\tnop\n", asm_out_file);
6382 : : }
6383 : :
6384 : 3638 : xops[0] = gen_rtx_REG (Pmode, regno);
6385 : 3638 : xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
6386 : 3638 : output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
6387 : 3638 : fputs ("\tret\n", asm_out_file);
6388 : 3638 : final_end_function ();
6389 : 3638 : init_insn_lengths ();
6390 : 3638 : free_after_compilation (cfun);
6391 : 3638 : set_cfun (NULL);
6392 : 3638 : current_function_decl = NULL;
6393 : : }
6394 : :
6395 : 224703 : if (flag_split_stack)
6396 : 4706 : file_end_indicate_split_stack ();
6397 : 224703 : }
6398 : :
6399 : : /* Emit code for the SET_GOT patterns. */
6400 : :
6401 : : const char *
6402 : 31995 : output_set_got (rtx dest, rtx label)
6403 : : {
6404 : 31995 : rtx xops[3];
6405 : :
6406 : 31995 : xops[0] = dest;
6407 : :
6408 : 31995 : if (TARGET_VXWORKS_RTP && flag_pic)
6409 : : {
6410 : : /* Load (*VXWORKS_GOTT_BASE) into the PIC register. */
6411 : : xops[2] = gen_rtx_MEM (Pmode,
6412 : : gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
6413 : : output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
6414 : :
6415 : : /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
6416 : : Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
6417 : : an unadorned address. */
6418 : : xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
6419 : : SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
6420 : : output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
6421 : : return "";
6422 : : }
6423 : :
6424 : 31995 : xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
6425 : :
6426 : 31995 : if (flag_pic)
6427 : : {
6428 : 31995 : char name[32];
6429 : 31995 : get_pc_thunk_name (name, REGNO (dest));
6430 : 31995 : pic_labels_used |= 1 << REGNO (dest);
6431 : :
6432 : 31995 : xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
6433 : 31995 : xops[2] = gen_rtx_MEM (QImode, xops[2]);
6434 : 31995 : output_asm_insn ("%!call\t%X2", xops);
6435 : :
6436 : : #if TARGET_MACHO
6437 : : /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
6438 : : This is what will be referenced by the Mach-O PIC subsystem. */
6439 : : if (machopic_should_output_picbase_label () || !label)
6440 : : ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
6441 : :
6442 : : /* When we are restoring the pic base at the site of a nonlocal label,
6443 : : and we decided to emit the pic base above, we will still output a
6444 : : local label used for calculating the correction offset (even though
6445 : : the offset will be 0 in that case). */
6446 : : if (label)
6447 : : targetm.asm_out.internal_label (asm_out_file, "L",
6448 : : CODE_LABEL_NUMBER (label));
6449 : : #endif
6450 : : }
6451 : : else
6452 : : {
6453 : 0 : if (TARGET_MACHO)
6454 : : /* We don't need a pic base, we're not producing pic. */
6455 : : gcc_unreachable ();
6456 : :
6457 : 0 : xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
6458 : 0 : output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
6459 : 0 : targetm.asm_out.internal_label (asm_out_file, "L",
6460 : 0 : CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
6461 : : }
6462 : :
6463 : 31995 : if (!TARGET_MACHO)
6464 : 31995 : output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
6465 : :
6466 : 31995 : return "";
6467 : : }
6468 : :
6469 : : /* Generate an "push" pattern for input ARG. */
6470 : :
6471 : : rtx
6472 : 1921989 : gen_push (rtx arg, bool ppx_p)
6473 : : {
6474 : 1921989 : struct machine_function *m = cfun->machine;
6475 : :
6476 : 1921989 : if (m->fs.cfa_reg == stack_pointer_rtx)
6477 : 1675378 : m->fs.cfa_offset += UNITS_PER_WORD;
6478 : 1921989 : m->fs.sp_offset += UNITS_PER_WORD;
6479 : :
6480 : 1921989 : if (REG_P (arg) && GET_MODE (arg) != word_mode)
6481 : 25 : arg = gen_rtx_REG (word_mode, REGNO (arg));
6482 : :
6483 : 1921989 : rtx stack = gen_rtx_MEM (word_mode,
6484 : 1921989 : gen_rtx_PRE_DEC (Pmode,
6485 : : stack_pointer_rtx));
6486 : 3843969 : return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
6487 : : }
6488 : :
6489 : : rtx
6490 : 23 : gen_pushfl (void)
6491 : : {
6492 : 23 : struct machine_function *m = cfun->machine;
6493 : 23 : rtx flags, mem;
6494 : :
6495 : 23 : if (m->fs.cfa_reg == stack_pointer_rtx)
6496 : 0 : m->fs.cfa_offset += UNITS_PER_WORD;
6497 : 23 : m->fs.sp_offset += UNITS_PER_WORD;
6498 : :
6499 : 23 : flags = gen_rtx_REG (CCmode, FLAGS_REG);
6500 : :
6501 : 23 : mem = gen_rtx_MEM (word_mode,
6502 : 23 : gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6503 : :
6504 : 23 : return gen_pushfl2 (word_mode, mem, flags);
6505 : : }
6506 : :
6507 : : /* Generate an "pop" pattern for input ARG. */
6508 : :
6509 : : rtx
6510 : 1564820 : gen_pop (rtx arg, bool ppx_p)
6511 : : {
6512 : 1564820 : if (REG_P (arg) && GET_MODE (arg) != word_mode)
6513 : 20 : arg = gen_rtx_REG (word_mode, REGNO (arg));
6514 : :
6515 : 1564820 : rtx stack = gen_rtx_MEM (word_mode,
6516 : 1564820 : gen_rtx_POST_INC (Pmode,
6517 : : stack_pointer_rtx));
6518 : :
6519 : 3129631 : return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
6520 : : }
6521 : :
6522 : : rtx
6523 : 21 : gen_popfl (void)
6524 : : {
6525 : 21 : rtx flags, mem;
6526 : :
6527 : 21 : flags = gen_rtx_REG (CCmode, FLAGS_REG);
6528 : :
6529 : 21 : mem = gen_rtx_MEM (word_mode,
6530 : 21 : gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6531 : :
6532 : 21 : return gen_popfl1 (word_mode, flags, mem);
6533 : : }
6534 : :
6535 : : /* Generate a "push2" pattern for input ARG. */
6536 : : rtx
6537 : 15 : gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
6538 : : {
6539 : 15 : struct machine_function *m = cfun->machine;
6540 : 15 : const int offset = UNITS_PER_WORD * 2;
6541 : :
6542 : 15 : if (m->fs.cfa_reg == stack_pointer_rtx)
6543 : 10 : m->fs.cfa_offset += offset;
6544 : 15 : m->fs.sp_offset += offset;
6545 : :
6546 : 15 : if (REG_P (reg1) && GET_MODE (reg1) != word_mode)
6547 : 0 : reg1 = gen_rtx_REG (word_mode, REGNO (reg1));
6548 : :
6549 : 15 : if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
6550 : 0 : reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
6551 : :
6552 : 15 : return ppx_p ? gen_push2p_di (mem, reg1, reg2):
6553 : 4 : gen_push2_di (mem, reg1, reg2);
6554 : : }
6555 : :
6556 : : /* Return >= 0 if there is an unused call-clobbered register available
6557 : : for the entire function. */
6558 : :
6559 : : static unsigned int
6560 : 0 : ix86_select_alt_pic_regnum (void)
6561 : : {
6562 : 0 : if (ix86_use_pseudo_pic_reg ())
6563 : : return INVALID_REGNUM;
6564 : :
6565 : 0 : if (crtl->is_leaf
6566 : 0 : && !crtl->profile
6567 : 0 : && !ix86_current_function_calls_tls_descriptor)
6568 : : {
6569 : 0 : int i, drap;
6570 : : /* Can't use the same register for both PIC and DRAP. */
6571 : 0 : if (crtl->drap_reg)
6572 : 0 : drap = REGNO (crtl->drap_reg);
6573 : : else
6574 : : drap = -1;
6575 : 0 : for (i = 2; i >= 0; --i)
6576 : 0 : if (i != drap && !df_regs_ever_live_p (i))
6577 : 0 : return i;
6578 : : }
6579 : :
6580 : : return INVALID_REGNUM;
6581 : : }
6582 : :
6583 : : /* Return true if REGNO is used by the epilogue. */
6584 : :
6585 : : bool
6586 : 1414707039 : ix86_epilogue_uses (int regno)
6587 : : {
6588 : : /* If there are no caller-saved registers, we preserve all registers,
6589 : : except for MMX and x87 registers which aren't supported when saving
6590 : : and restoring registers. Don't explicitly save SP register since
6591 : : it is always preserved. */
6592 : 1414707039 : return (epilogue_completed
6593 : 247375365 : && (cfun->machine->call_saved_registers
6594 : 247375365 : == TYPE_NO_CALLER_SAVED_REGISTERS)
6595 : 24840 : && !fixed_regs[regno]
6596 : 4114 : && !STACK_REGNO_P (regno)
6597 : 1414711153 : && !MMX_REGNO_P (regno));
6598 : : }
6599 : :
6600 : : /* Return nonzero if register REGNO can be used as a scratch register
6601 : : in peephole2. */
6602 : :
6603 : : static bool
6604 : 1099042 : ix86_hard_regno_scratch_ok (unsigned int regno)
6605 : : {
6606 : : /* If there are no caller-saved registers, we can't use any register
6607 : : as a scratch register after epilogue and use REGNO as scratch
6608 : : register only if it has been used before to avoid saving and
6609 : : restoring it. */
6610 : 1099042 : return ((cfun->machine->call_saved_registers
6611 : 1099042 : != TYPE_NO_CALLER_SAVED_REGISTERS)
6612 : 1099042 : || (!epilogue_completed
6613 : 0 : && df_regs_ever_live_p (regno)));
6614 : : }
6615 : :
6616 : : /* Return TRUE if we need to save REGNO. */
6617 : :
6618 : : bool
6619 : 306145118 : ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
6620 : : {
6621 : 306145118 : rtx reg;
6622 : :
6623 : 306145118 : switch (cfun->machine->call_saved_registers)
6624 : : {
6625 : : case TYPE_DEFAULT_CALL_SAVED_REGISTERS:
6626 : : break;
6627 : :
6628 : 30432 : case TYPE_NO_CALLER_SAVED_REGISTERS:
6629 : : /* If there are no caller-saved registers, we preserve all
6630 : : registers, except for MMX and x87 registers which aren't
6631 : : supported when saving and restoring registers. Don't
6632 : : explicitly save SP register since it is always preserved.
6633 : :
6634 : : Don't preserve registers used for function return value. */
6635 : 30432 : reg = crtl->return_rtx;
6636 : 30432 : if (reg)
6637 : : {
6638 : 448 : unsigned int i = REGNO (reg);
6639 : 448 : unsigned int nregs = REG_NREGS (reg);
6640 : 882 : while (nregs-- > 0)
6641 : 448 : if ((i + nregs) == regno)
6642 : : return false;
6643 : : }
6644 : :
6645 : 30418 : return (df_regs_ever_live_p (regno)
6646 : 4875 : && !fixed_regs[regno]
6647 : 3993 : && !STACK_REGNO_P (regno)
6648 : 3993 : && !MMX_REGNO_P (regno)
6649 : 34411 : && (regno != HARD_FRAME_POINTER_REGNUM
6650 : 236 : || !frame_pointer_needed));
6651 : :
6652 : : case TYPE_NO_CALLEE_SAVED_REGISTERS:
6653 : : return false;
6654 : :
6655 : 1664 : case TYPE_NO_CALLEE_SAVED_REGISTERS_EXCEPT_BP:
6656 : 1664 : if (regno != HARD_FRAME_POINTER_REGNUM)
6657 : : return false;
6658 : : break;
6659 : : }
6660 : :
6661 : 337421842 : if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
6662 : 9276990 : && pic_offset_table_rtx)
6663 : : {
6664 : 325590 : if (ix86_use_pseudo_pic_reg ())
6665 : : {
6666 : : /* REAL_PIC_OFFSET_TABLE_REGNUM used by call to
6667 : : _mcount in prologue. */
6668 : 325590 : if (!TARGET_64BIT && flag_pic && crtl->profile)
6669 : : return true;
6670 : : }
6671 : 0 : else if (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
6672 : 0 : || crtl->profile
6673 : 0 : || crtl->calls_eh_return
6674 : 0 : || crtl->uses_const_pool
6675 : 0 : || cfun->has_nonlocal_label)
6676 : 0 : return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
6677 : : }
6678 : :
6679 : 306107506 : if (crtl->calls_eh_return && maybe_eh_return)
6680 : : {
6681 : : unsigned i;
6682 : 13908 : for (i = 0; ; i++)
6683 : : {
6684 : 21204 : unsigned test = EH_RETURN_DATA_REGNO (i);
6685 : 14364 : if (test == INVALID_REGNUM)
6686 : : break;
6687 : 14364 : if (test == regno)
6688 : : return true;
6689 : 13908 : }
6690 : : }
6691 : :
6692 : 306107050 : if (ignore_outlined && cfun->machine->call_ms2sysv)
6693 : : {
6694 : 2637504 : unsigned count = cfun->machine->call_ms2sysv_extra_regs
6695 : : + xlogue_layout::MIN_REGS;
6696 : 2637504 : if (xlogue_layout::is_stub_managed_reg (regno, count))
6697 : : return false;
6698 : : }
6699 : :
6700 : 305594337 : if (crtl->drap_reg
6701 : 2111232 : && regno == REGNO (crtl->drap_reg)
6702 : 305647442 : && !cfun->machine->no_drap_save_restore)
6703 : : return true;
6704 : :
6705 : 305541232 : return (df_regs_ever_live_p (regno)
6706 : 322585361 : && !call_used_or_fixed_reg_p (regno)
6707 : 321981475 : && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
6708 : : }
6709 : :
6710 : : /* Return number of saved general prupose registers. */
6711 : :
6712 : : static int
6713 : 7532232 : ix86_nsaved_regs (void)
6714 : : {
6715 : 7532232 : int nregs = 0;
6716 : 7532232 : int regno;
6717 : :
6718 : 700497576 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
6719 : 692965344 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
6720 : 8367594 : nregs ++;
6721 : 7532232 : return nregs;
6722 : : }
6723 : :
6724 : : /* Return number of saved SSE registers. */
6725 : :
6726 : : static int
6727 : 7561147 : ix86_nsaved_sseregs (void)
6728 : : {
6729 : 7561147 : int nregs = 0;
6730 : 7561147 : int regno;
6731 : :
6732 : 7561147 : if (!TARGET_64BIT_MS_ABI)
6733 : 7338797 : return 0;
6734 : 20678550 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
6735 : 20456200 : if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
6736 : 1865439 : nregs ++;
6737 : : return nregs;
6738 : : }
6739 : :
6740 : : /* Given FROM and TO register numbers, say whether this elimination is
6741 : : allowed. If stack alignment is needed, we can only replace argument
6742 : : pointer with hard frame pointer, or replace frame pointer with stack
6743 : : pointer. Otherwise, frame pointer elimination is automatically
6744 : : handled and all other eliminations are valid. */
6745 : :
6746 : : static bool
6747 : 44864538 : ix86_can_eliminate (const int from, const int to)
6748 : : {
6749 : 44864538 : if (stack_realign_fp)
6750 : 1484176 : return ((from == ARG_POINTER_REGNUM
6751 : 1484176 : && to == HARD_FRAME_POINTER_REGNUM)
6752 : 1484176 : || (from == FRAME_POINTER_REGNUM
6753 : 1484176 : && to == STACK_POINTER_REGNUM));
6754 : : else
6755 : 80506052 : return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
6756 : : }
6757 : :
6758 : : /* Return the offset between two registers, one to be eliminated, and the other
6759 : : its replacement, at the start of a routine. */
6760 : :
6761 : : HOST_WIDE_INT
6762 : 139376585 : ix86_initial_elimination_offset (int from, int to)
6763 : : {
6764 : 139376585 : struct ix86_frame &frame = cfun->machine->frame;
6765 : :
6766 : 139376585 : if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
6767 : 9682638 : return frame.hard_frame_pointer_offset;
6768 : 129693947 : else if (from == FRAME_POINTER_REGNUM
6769 : 129693947 : && to == HARD_FRAME_POINTER_REGNUM)
6770 : 7503054 : return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
6771 : : else
6772 : : {
6773 : 122190893 : gcc_assert (to == STACK_POINTER_REGNUM);
6774 : :
6775 : 122190893 : if (from == ARG_POINTER_REGNUM)
6776 : 114687839 : return frame.stack_pointer_offset;
6777 : :
6778 : 7503054 : gcc_assert (from == FRAME_POINTER_REGNUM);
6779 : 7503054 : return frame.stack_pointer_offset - frame.frame_pointer_offset;
6780 : : }
6781 : : }
6782 : :
6783 : : /* Emits a warning for unsupported msabi to sysv pro/epilogues. */
6784 : : void
6785 : 0 : warn_once_call_ms2sysv_xlogues (const char *feature)
6786 : : {
6787 : 0 : static bool warned_once = false;
6788 : 0 : if (!warned_once)
6789 : : {
6790 : 0 : warning (0, "%<-mcall-ms2sysv-xlogues%> is not compatible with %s",
6791 : : feature);
6792 : 0 : warned_once = true;
6793 : : }
6794 : 0 : }
6795 : :
6796 : : /* Return the probing interval for -fstack-clash-protection. */
6797 : :
6798 : : static HOST_WIDE_INT
6799 : 350 : get_probe_interval (void)
6800 : : {
6801 : 218 : if (flag_stack_clash_protection)
6802 : 265 : return (HOST_WIDE_INT_1U
6803 : 265 : << param_stack_clash_protection_probe_interval);
6804 : : else
6805 : : return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP);
6806 : : }
6807 : :
6808 : : /* When using -fsplit-stack, the allocation routines set a field in
6809 : : the TCB to the bottom of the stack plus this much space, measured
6810 : : in bytes. */
6811 : :
6812 : : #define SPLIT_STACK_AVAILABLE 256
6813 : :
6814 : : /* Return true if push2/pop2 can be generated. */
6815 : :
6816 : : static bool
6817 : 7532642 : ix86_can_use_push2pop2 (void)
6818 : : {
6819 : : /* Use push2/pop2 only if the incoming stack is 16-byte aligned. */
6820 : 7532642 : unsigned int incoming_stack_boundary
6821 : 7532642 : = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
6822 : 7532642 : ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
6823 : 7532642 : return incoming_stack_boundary % 128 == 0;
6824 : : }
6825 : :
6826 : : /* Helper function to determine whether push2/pop2 can be used in prologue or
6827 : : epilogue for register save/restore. */
6828 : : static bool
6829 : 7532232 : ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
6830 : : {
6831 : 7532232 : if (!ix86_can_use_push2pop2 ())
6832 : : return false;
6833 : 7496433 : int aligned = cfun->machine->fs.sp_offset % 16 == 0;
6834 : 7496433 : return TARGET_APX_PUSH2POP2
6835 : 2015 : && !cfun->machine->frame.save_regs_using_mov
6836 : 2015 : && cfun->machine->func_type == TYPE_NORMAL
6837 : 7498440 : && (nregs + aligned) >= 3;
6838 : : }
6839 : :
6840 : : /* Fill structure ix86_frame about frame of currently computed function. */
6841 : :
6842 : : static void
6843 : 7532232 : ix86_compute_frame_layout (void)
6844 : : {
6845 : 7532232 : struct ix86_frame *frame = &cfun->machine->frame;
6846 : 7532232 : struct machine_function *m = cfun->machine;
6847 : 7532232 : unsigned HOST_WIDE_INT stack_alignment_needed;
6848 : 7532232 : HOST_WIDE_INT offset;
6849 : 7532232 : unsigned HOST_WIDE_INT preferred_alignment;
6850 : 7532232 : HOST_WIDE_INT size = ix86_get_frame_size ();
6851 : 7532232 : HOST_WIDE_INT to_allocate;
6852 : :
6853 : : /* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
6854 : : * ms_abi functions that call a sysv function. We now need to prune away
6855 : : * cases where it should be disabled. */
6856 : 7532232 : if (TARGET_64BIT && m->call_ms2sysv)
6857 : : {
6858 : 35231 : gcc_assert (TARGET_64BIT_MS_ABI);
6859 : 35231 : gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
6860 : 35231 : gcc_assert (!TARGET_SEH);
6861 : 35231 : gcc_assert (TARGET_SSE);
6862 : 35231 : gcc_assert (!ix86_using_red_zone ());
6863 : :
6864 : 35231 : if (crtl->calls_eh_return)
6865 : : {
6866 : 0 : gcc_assert (!reload_completed);
6867 : 0 : m->call_ms2sysv = false;
6868 : 0 : warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
6869 : : }
6870 : :
6871 : 35231 : else if (ix86_static_chain_on_stack)
6872 : : {
6873 : 0 : gcc_assert (!reload_completed);
6874 : 0 : m->call_ms2sysv = false;
6875 : 0 : warn_once_call_ms2sysv_xlogues ("static call chains");
6876 : : }
6877 : :
6878 : : /* Finally, compute which registers the stub will manage. */
6879 : : else
6880 : : {
6881 : 35231 : unsigned count = xlogue_layout::count_stub_managed_regs ();
6882 : 35231 : m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
6883 : 35231 : m->call_ms2sysv_pad_in = 0;
6884 : : }
6885 : : }
6886 : :
6887 : 7532232 : frame->nregs = ix86_nsaved_regs ();
6888 : 7532232 : frame->nsseregs = ix86_nsaved_sseregs ();
6889 : :
6890 : : /* 64-bit MS ABI seem to require stack alignment to be always 16,
6891 : : except for function prologues, leaf functions and when the defult
6892 : : incoming stack boundary is overriden at command line or via
6893 : : force_align_arg_pointer attribute.
6894 : :
6895 : : Darwin's ABI specifies 128b alignment for both 32 and 64 bit variants
6896 : : at call sites, including profile function calls.
6897 : :
6898 : : For APX push2/pop2, the stack also requires 128b alignment. */
6899 : 7532232 : if ((ix86_pro_and_epilogue_can_use_push2pop2 (frame->nregs)
6900 : 55 : && crtl->preferred_stack_boundary < 128)
6901 : 7532286 : || (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
6902 : 222349 : && crtl->preferred_stack_boundary < 128)
6903 : 0 : && (!crtl->is_leaf || cfun->calls_alloca != 0
6904 : 0 : || ix86_current_function_calls_tls_descriptor
6905 : 0 : || (TARGET_MACHO && crtl->profile)
6906 : 0 : || ix86_incoming_stack_boundary < 128)))
6907 : : {
6908 : 1 : crtl->preferred_stack_boundary = 128;
6909 : 1 : if (crtl->stack_alignment_needed < 128)
6910 : 0 : crtl->stack_alignment_needed = 128;
6911 : : }
6912 : :
6913 : 7532232 : stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
6914 : 7532232 : preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
6915 : :
6916 : 7532232 : gcc_assert (!size || stack_alignment_needed);
6917 : 8305965 : gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
6918 : 7532232 : gcc_assert (preferred_alignment <= stack_alignment_needed);
6919 : :
6920 : : /* The only ABI saving SSE regs should be 64-bit ms_abi. */
6921 : 7532232 : gcc_assert (TARGET_64BIT || !frame->nsseregs);
6922 : 7532232 : if (TARGET_64BIT && m->call_ms2sysv)
6923 : : {
6924 : 35231 : gcc_assert (stack_alignment_needed >= 16);
6925 : 35231 : gcc_assert (!frame->nsseregs);
6926 : : }
6927 : :
6928 : : /* For SEH we have to limit the amount of code movement into the prologue.
6929 : : At present we do this via a BLOCKAGE, at which point there's very little
6930 : : scheduling that can be done, which means that there's very little point
6931 : : in doing anything except PUSHs. */
6932 : 7532232 : if (TARGET_SEH)
6933 : : m->use_fast_prologue_epilogue = false;
6934 : 7532232 : else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
6935 : : {
6936 : 7222633 : int count = frame->nregs;
6937 : 7222633 : struct cgraph_node *node = cgraph_node::get (current_function_decl);
6938 : :
6939 : : /* The fast prologue uses move instead of push to save registers. This
6940 : : is significantly longer, but also executes faster as modern hardware
6941 : : can execute the moves in parallel, but can't do that for push/pop.
6942 : :
6943 : : Be careful about choosing what prologue to emit: When function takes
6944 : : many instructions to execute we may use slow version as well as in
6945 : : case function is known to be outside hot spot (this is known with
6946 : : feedback only). Weight the size of function by number of registers
6947 : : to save as it is cheap to use one or two push instructions but very
6948 : : slow to use many of them.
6949 : :
6950 : : Calling this hook multiple times with the same frame requirements
6951 : : must produce the same layout, since the RA might otherwise be
6952 : : unable to reach a fixed point or might fail its final sanity checks.
6953 : : This means that once we've assumed that a function does or doesn't
6954 : : have a particular size, we have to stick to that assumption
6955 : : regardless of how the function has changed since. */
6956 : 7222633 : if (count)
6957 : 2539818 : count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
6958 : 7222633 : if (node->frequency < NODE_FREQUENCY_NORMAL
6959 : 6591973 : || (flag_branch_probabilities
6960 : 997 : && node->frequency < NODE_FREQUENCY_HOT))
6961 : 630995 : m->use_fast_prologue_epilogue = false;
6962 : : else
6963 : : {
6964 : 6591638 : if (count != frame->expensive_count)
6965 : : {
6966 : 276873 : frame->expensive_count = count;
6967 : 276873 : frame->expensive_p = expensive_function_p (count);
6968 : : }
6969 : 6591638 : m->use_fast_prologue_epilogue = !frame->expensive_p;
6970 : : }
6971 : : }
6972 : :
6973 : 7532232 : frame->save_regs_using_mov
6974 : 7532232 : = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
6975 : :
6976 : : /* Skip return address and error code in exception handler. */
6977 : 7532232 : offset = INCOMING_FRAME_SP_OFFSET;
6978 : :
6979 : : /* Skip pushed static chain. */
6980 : 7532232 : if (ix86_static_chain_on_stack)
6981 : 0 : offset += UNITS_PER_WORD;
6982 : :
6983 : : /* Skip saved base pointer. */
6984 : 7532232 : if (frame_pointer_needed)
6985 : 2633792 : offset += UNITS_PER_WORD;
6986 : 7532232 : frame->hfp_save_offset = offset;
6987 : :
6988 : : /* The traditional frame pointer location is at the top of the frame. */
6989 : 7532232 : frame->hard_frame_pointer_offset = offset;
6990 : :
6991 : : /* Register save area */
6992 : 7532232 : offset += frame->nregs * UNITS_PER_WORD;
6993 : 7532232 : frame->reg_save_offset = offset;
6994 : :
6995 : : /* Calculate the size of the va-arg area (not including padding, if any). */
6996 : 7532232 : frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
6997 : :
6998 : : /* Also adjust stack_realign_offset for the largest alignment of
6999 : : stack slot actually used. */
7000 : 7532232 : if (stack_realign_fp
7001 : 7264807 : || (cfun->machine->max_used_stack_alignment != 0
7002 : 126 : && (offset % cfun->machine->max_used_stack_alignment) != 0))
7003 : : {
7004 : : /* We may need a 16-byte aligned stack for the remainder of the
7005 : : register save area, but the stack frame for the local function
7006 : : may require a greater alignment if using AVX/2/512. In order
7007 : : to avoid wasting space, we first calculate the space needed for
7008 : : the rest of the register saves, add that to the stack pointer,
7009 : : and then realign the stack to the boundary of the start of the
7010 : : frame for the local function. */
7011 : 267483 : HOST_WIDE_INT space_needed = 0;
7012 : 267483 : HOST_WIDE_INT sse_reg_space_needed = 0;
7013 : :
7014 : 267483 : if (TARGET_64BIT)
7015 : : {
7016 : 265688 : if (m->call_ms2sysv)
7017 : : {
7018 : 6421 : m->call_ms2sysv_pad_in = 0;
7019 : 6421 : space_needed = xlogue_layout::get_instance ().get_stack_space_used ();
7020 : : }
7021 : :
7022 : 259267 : else if (frame->nsseregs)
7023 : : /* The only ABI that has saved SSE registers (Win64) also has a
7024 : : 16-byte aligned default stack. However, many programs violate
7025 : : the ABI, and Wine64 forces stack realignment to compensate. */
7026 : 6457 : space_needed = frame->nsseregs * 16;
7027 : :
7028 : 265688 : sse_reg_space_needed = space_needed = ROUND_UP (space_needed, 16);
7029 : :
7030 : : /* 64-bit frame->va_arg_size should always be a multiple of 16, but
7031 : : rounding to be pedantic. */
7032 : 265688 : space_needed = ROUND_UP (space_needed + frame->va_arg_size, 16);
7033 : : }
7034 : : else
7035 : 1795 : space_needed = frame->va_arg_size;
7036 : :
7037 : : /* Record the allocation size required prior to the realignment AND. */
7038 : 267483 : frame->stack_realign_allocate = space_needed;
7039 : :
7040 : : /* The re-aligned stack starts at frame->stack_realign_offset. Values
7041 : : before this point are not directly comparable with values below
7042 : : this point. Use sp_valid_at to determine if the stack pointer is
7043 : : valid for a given offset, fp_valid_at for the frame pointer, or
7044 : : choose_baseaddr to have a base register chosen for you.
7045 : :
7046 : : Note that the result of (frame->stack_realign_offset
7047 : : & (stack_alignment_needed - 1)) may not equal zero. */
7048 : 267483 : offset = ROUND_UP (offset + space_needed, stack_alignment_needed);
7049 : 267483 : frame->stack_realign_offset = offset - space_needed;
7050 : 267483 : frame->sse_reg_save_offset = frame->stack_realign_offset
7051 : 267483 : + sse_reg_space_needed;
7052 : 267483 : }
7053 : : else
7054 : : {
7055 : 7264749 : frame->stack_realign_offset = offset;
7056 : :
7057 : 7264749 : if (TARGET_64BIT && m->call_ms2sysv)
7058 : : {
7059 : 28810 : m->call_ms2sysv_pad_in = !!(offset & UNITS_PER_WORD);
7060 : 28810 : offset += xlogue_layout::get_instance ().get_stack_space_used ();
7061 : : }
7062 : :
7063 : : /* Align and set SSE register save area. */
7064 : 7235939 : else if (frame->nsseregs)
7065 : : {
7066 : : /* If the incoming stack boundary is at least 16 bytes, or DRAP is
7067 : : required and the DRAP re-alignment boundary is at least 16 bytes,
7068 : : then we want the SSE register save area properly aligned. */
7069 : 180095 : if (ix86_incoming_stack_boundary >= 128
7070 : 6400 : || (stack_realign_drap && stack_alignment_needed >= 16))
7071 : 180095 : offset = ROUND_UP (offset, 16);
7072 : 180095 : offset += frame->nsseregs * 16;
7073 : : }
7074 : 7264749 : frame->sse_reg_save_offset = offset;
7075 : 7264749 : offset += frame->va_arg_size;
7076 : : }
7077 : :
7078 : : /* Align start of frame for local function. When a function call
7079 : : is removed, it may become a leaf function. But if argument may
7080 : : be passed on stack, we need to align the stack when there is no
7081 : : tail call. */
7082 : 7532232 : if (m->call_ms2sysv
7083 : 7497001 : || frame->va_arg_size != 0
7084 : 7420033 : || size != 0
7085 : 4071765 : || !crtl->is_leaf
7086 : 1858815 : || (!crtl->tail_call_emit
7087 : 1567265 : && cfun->machine->outgoing_args_on_stack)
7088 : 1858785 : || cfun->calls_alloca
7089 : 9389475 : || ix86_current_function_calls_tls_descriptor)
7090 : 5675390 : offset = ROUND_UP (offset, stack_alignment_needed);
7091 : :
7092 : : /* Frame pointer points here. */
7093 : 7532232 : frame->frame_pointer_offset = offset;
7094 : :
7095 : 7532232 : offset += size;
7096 : :
7097 : : /* Add outgoing arguments area. Can be skipped if we eliminated
7098 : : all the function calls as dead code.
7099 : : Skipping is however impossible when function calls alloca. Alloca
7100 : : expander assumes that last crtl->outgoing_args_size
7101 : : of stack frame are unused. */
7102 : 7532232 : if (ACCUMULATE_OUTGOING_ARGS
7103 : 8109054 : && (!crtl->is_leaf || cfun->calls_alloca
7104 : 353646 : || ix86_current_function_calls_tls_descriptor))
7105 : : {
7106 : 223176 : offset += crtl->outgoing_args_size;
7107 : 223176 : frame->outgoing_arguments_size = crtl->outgoing_args_size;
7108 : : }
7109 : : else
7110 : 7309056 : frame->outgoing_arguments_size = 0;
7111 : :
7112 : : /* Align stack boundary. Only needed if we're calling another function
7113 : : or using alloca. */
7114 : 2547448 : if (!crtl->is_leaf || cfun->calls_alloca
7115 : 10076210 : || ix86_current_function_calls_tls_descriptor)
7116 : 4990039 : offset = ROUND_UP (offset, preferred_alignment);
7117 : :
7118 : : /* We've reached end of stack frame. */
7119 : 7532232 : frame->stack_pointer_offset = offset;
7120 : :
7121 : : /* Size prologue needs to allocate. */
7122 : 7532232 : to_allocate = offset - frame->sse_reg_save_offset;
7123 : :
7124 : 2633999 : if ((!to_allocate && frame->nregs <= 1)
7125 : 5134680 : || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
7126 : : /* If static stack checking is enabled and done with probes,
7127 : : the registers need to be saved before allocating the frame. */
7128 : 5134112 : || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
7129 : : /* If stack clash probing needs a loop, then it needs a
7130 : : scratch register. But the returned register is only guaranteed
7131 : : to be safe to use after register saves are complete. So if
7132 : : stack clash protections are enabled and the allocated frame is
7133 : : larger than the probe interval, then use pushes to save
7134 : : callee saved registers. */
7135 : 12666274 : || (flag_stack_clash_protection
7136 : 218 : && !ix86_target_stack_probe ()
7137 : 218 : && to_allocate > get_probe_interval ()))
7138 : 2398279 : frame->save_regs_using_mov = false;
7139 : :
7140 : 7532232 : if (ix86_using_red_zone ()
7141 : 6535984 : && crtl->sp_is_unchanging
7142 : 5930227 : && crtl->is_leaf
7143 : 2448073 : && !ix86_pc_thunk_call_expanded
7144 : 9980305 : && !ix86_current_function_calls_tls_descriptor)
7145 : : {
7146 : 2448073 : frame->red_zone_size = to_allocate;
7147 : 2448073 : if (frame->save_regs_using_mov)
7148 : 125209 : frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
7149 : 2448073 : if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
7150 : 98621 : frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
7151 : : }
7152 : : else
7153 : 5084159 : frame->red_zone_size = 0;
7154 : 7532232 : frame->stack_pointer_offset -= frame->red_zone_size;
7155 : :
7156 : : /* The SEH frame pointer location is near the bottom of the frame.
7157 : : This is enforced by the fact that the difference between the
7158 : : stack pointer and the frame pointer is limited to 240 bytes in
7159 : : the unwind data structure. */
7160 : 7532232 : if (TARGET_SEH)
7161 : : {
7162 : : /* Force the frame pointer to point at or below the lowest register save
7163 : : area, see the SEH code in config/i386/winnt.cc for the rationale. */
7164 : : frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
7165 : :
7166 : : /* If we can leave the frame pointer where it is, do so; however return
7167 : : the establisher frame for __builtin_frame_address (0) or else if the
7168 : : frame overflows the SEH maximum frame size.
7169 : :
7170 : : Note that the value returned by __builtin_frame_address (0) is quite
7171 : : constrained, because setjmp is piggybacked on the SEH machinery with
7172 : : recent versions of MinGW:
7173 : :
7174 : : # elif defined(__SEH__)
7175 : : # if defined(__aarch64__) || defined(_ARM64_)
7176 : : # define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
7177 : : # elif (__MINGW_GCC_VERSION < 40702)
7178 : : # define setjmp(BUF) _setjmp((BUF), mingw_getsp())
7179 : : # else
7180 : : # define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
7181 : : # endif
7182 : :
7183 : : and the second argument passed to _setjmp, if not null, is forwarded
7184 : : to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
7185 : : built an ExceptionRecord on the fly describing the setjmp buffer). */
7186 : : const HOST_WIDE_INT diff
7187 : : = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
7188 : : if (diff <= 255 && !crtl->accesses_prior_frames)
7189 : : {
7190 : : /* The resulting diff will be a multiple of 16 lower than 255,
7191 : : i.e. at most 240 as required by the unwind data structure. */
7192 : : frame->hard_frame_pointer_offset += (diff & 15);
7193 : : }
7194 : : else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
7195 : : {
7196 : : /* Ideally we'd determine what portion of the local stack frame
7197 : : (within the constraint of the lowest 240) is most heavily used.
7198 : : But without that complication, simply bias the frame pointer
7199 : : by 128 bytes so as to maximize the amount of the local stack
7200 : : frame that is addressable with 8-bit offsets. */
7201 : : frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
7202 : : }
7203 : : else
7204 : : frame->hard_frame_pointer_offset = frame->hfp_save_offset;
7205 : : }
7206 : 7532232 : }
7207 : :
7208 : : /* This is semi-inlined memory_address_length, but simplified
7209 : : since we know that we're always dealing with reg+offset, and
7210 : : to avoid having to create and discard all that rtl. */
7211 : :
7212 : : static inline int
7213 : 702210 : choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
7214 : : {
7215 : 702210 : int len = 4;
7216 : :
7217 : 0 : if (offset == 0)
7218 : : {
7219 : : /* EBP and R13 cannot be encoded without an offset. */
7220 : 0 : len = (regno == BP_REG || regno == R13_REG);
7221 : : }
7222 : 698192 : else if (IN_RANGE (offset, -128, 127))
7223 : 433060 : len = 1;
7224 : :
7225 : : /* ESP and R12 must be encoded with a SIB byte. */
7226 : 0 : if (regno == SP_REG || regno == R12_REG)
7227 : 0 : len++;
7228 : :
7229 : 702210 : return len;
7230 : : }
7231 : :
7232 : : /* Determine if the stack pointer is valid for accessing the CFA_OFFSET in
7233 : : the frame save area. The register is saved at CFA - CFA_OFFSET. */
7234 : :
7235 : : static bool
7236 : 2688899 : sp_valid_at (HOST_WIDE_INT cfa_offset)
7237 : : {
7238 : 2688899 : const struct machine_frame_state &fs = cfun->machine->fs;
7239 : 2688899 : if (fs.sp_realigned && cfa_offset <= fs.sp_realigned_offset)
7240 : : {
7241 : : /* Validate that the cfa_offset isn't in a "no-man's land". */
7242 : 42665 : gcc_assert (cfa_offset <= fs.sp_realigned_fp_last);
7243 : : return false;
7244 : : }
7245 : 2646234 : return fs.sp_valid;
7246 : : }
7247 : :
7248 : : /* Determine if the frame pointer is valid for accessing the CFA_OFFSET in
7249 : : the frame save area. The register is saved at CFA - CFA_OFFSET. */
7250 : :
7251 : : static inline bool
7252 : 725553 : fp_valid_at (HOST_WIDE_INT cfa_offset)
7253 : : {
7254 : 725553 : const struct machine_frame_state &fs = cfun->machine->fs;
7255 : 725553 : if (fs.sp_realigned && cfa_offset > fs.sp_realigned_fp_last)
7256 : : {
7257 : : /* Validate that the cfa_offset isn't in a "no-man's land". */
7258 : 28328 : gcc_assert (cfa_offset >= fs.sp_realigned_offset);
7259 : : return false;
7260 : : }
7261 : 697225 : return fs.fp_valid;
7262 : : }
7263 : :
7264 : : /* Choose a base register based upon alignment requested, speed and/or
7265 : : size. */
7266 : :
7267 : : static void
7268 : 725553 : choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
7269 : : HOST_WIDE_INT &base_offset,
7270 : : unsigned int align_reqested, unsigned int *align)
7271 : : {
7272 : 725553 : const struct machine_function *m = cfun->machine;
7273 : 725553 : unsigned int hfp_align;
7274 : 725553 : unsigned int drap_align;
7275 : 725553 : unsigned int sp_align;
7276 : 725553 : bool hfp_ok = fp_valid_at (cfa_offset);
7277 : 725553 : bool drap_ok = m->fs.drap_valid;
7278 : 725553 : bool sp_ok = sp_valid_at (cfa_offset);
7279 : :
7280 : 725553 : hfp_align = drap_align = sp_align = INCOMING_STACK_BOUNDARY;
7281 : :
7282 : : /* Filter out any registers that don't meet the requested alignment
7283 : : criteria. */
7284 : 725553 : if (align_reqested)
7285 : : {
7286 : 683556 : if (m->fs.realigned)
7287 : 28160 : hfp_align = drap_align = sp_align = crtl->stack_alignment_needed;
7288 : : /* SEH unwind code does do not currently support REG_CFA_EXPRESSION
7289 : : notes (which we would need to use a realigned stack pointer),
7290 : : so disable on SEH targets. */
7291 : 655396 : else if (m->fs.sp_realigned)
7292 : 28332 : sp_align = crtl->stack_alignment_needed;
7293 : :
7294 : 683556 : hfp_ok = hfp_ok && hfp_align >= align_reqested;
7295 : 683556 : drap_ok = drap_ok && drap_align >= align_reqested;
7296 : 683556 : sp_ok = sp_ok && sp_align >= align_reqested;
7297 : : }
7298 : :
7299 : 725553 : if (m->use_fast_prologue_epilogue)
7300 : : {
7301 : : /* Choose the base register most likely to allow the most scheduling
7302 : : opportunities. Generally FP is valid throughout the function,
7303 : : while DRAP must be reloaded within the epilogue. But choose either
7304 : : over the SP due to increased encoding size. */
7305 : :
7306 : 312157 : if (hfp_ok)
7307 : : {
7308 : 97843 : base_reg = hard_frame_pointer_rtx;
7309 : 97843 : base_offset = m->fs.fp_offset - cfa_offset;
7310 : : }
7311 : 214314 : else if (drap_ok)
7312 : : {
7313 : 0 : base_reg = crtl->drap_reg;
7314 : 0 : base_offset = 0 - cfa_offset;
7315 : : }
7316 : 214314 : else if (sp_ok)
7317 : : {
7318 : 214314 : base_reg = stack_pointer_rtx;
7319 : 214314 : base_offset = m->fs.sp_offset - cfa_offset;
7320 : : }
7321 : : }
7322 : : else
7323 : : {
7324 : 413396 : HOST_WIDE_INT toffset;
7325 : 413396 : int len = 16, tlen;
7326 : :
7327 : : /* Choose the base register with the smallest address encoding.
7328 : : With a tie, choose FP > DRAP > SP. */
7329 : 413396 : if (sp_ok)
7330 : : {
7331 : 396354 : base_reg = stack_pointer_rtx;
7332 : 396354 : base_offset = m->fs.sp_offset - cfa_offset;
7333 : 788690 : len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
7334 : : }
7335 : 413396 : if (drap_ok)
7336 : : {
7337 : 0 : toffset = 0 - cfa_offset;
7338 : 0 : tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
7339 : 0 : if (tlen <= len)
7340 : : {
7341 : 0 : base_reg = crtl->drap_reg;
7342 : 0 : base_offset = toffset;
7343 : 0 : len = tlen;
7344 : : }
7345 : : }
7346 : 413396 : if (hfp_ok)
7347 : : {
7348 : 305856 : toffset = m->fs.fp_offset - cfa_offset;
7349 : 305856 : tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
7350 : 305856 : if (tlen <= len)
7351 : : {
7352 : 215206 : base_reg = hard_frame_pointer_rtx;
7353 : 215206 : base_offset = toffset;
7354 : : }
7355 : : }
7356 : : }
7357 : :
7358 : : /* Set the align return value. */
7359 : 725553 : if (align)
7360 : : {
7361 : 683556 : if (base_reg == stack_pointer_rtx)
7362 : 412464 : *align = sp_align;
7363 : 271092 : else if (base_reg == crtl->drap_reg)
7364 : 0 : *align = drap_align;
7365 : 271092 : else if (base_reg == hard_frame_pointer_rtx)
7366 : 271092 : *align = hfp_align;
7367 : : }
7368 : 725553 : }
7369 : :
7370 : : /* Return an RTX that points to CFA_OFFSET within the stack frame and
7371 : : the alignment of address. If ALIGN is non-null, it should point to
7372 : : an alignment value (in bits) that is preferred or zero and will
7373 : : recieve the alignment of the base register that was selected,
7374 : : irrespective of rather or not CFA_OFFSET is a multiple of that
7375 : : alignment value. If it is possible for the base register offset to be
7376 : : non-immediate then SCRATCH_REGNO should specify a scratch register to
7377 : : use.
7378 : :
7379 : : The valid base registers are taken from CFUN->MACHINE->FS. */
7380 : :
7381 : : static rtx
7382 : 725553 : choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align,
7383 : : unsigned int scratch_regno = INVALID_REGNUM)
7384 : : {
7385 : 725553 : rtx base_reg = NULL;
7386 : 725553 : HOST_WIDE_INT base_offset = 0;
7387 : :
7388 : : /* If a specific alignment is requested, try to get a base register
7389 : : with that alignment first. */
7390 : 725553 : if (align && *align)
7391 : 683556 : choose_basereg (cfa_offset, base_reg, base_offset, *align, align);
7392 : :
7393 : 725553 : if (!base_reg)
7394 : 41997 : choose_basereg (cfa_offset, base_reg, base_offset, 0, align);
7395 : :
7396 : 725553 : gcc_assert (base_reg != NULL);
7397 : :
7398 : 725553 : rtx base_offset_rtx = GEN_INT (base_offset);
7399 : :
7400 : 725553 : if (!x86_64_immediate_operand (base_offset_rtx, Pmode))
7401 : : {
7402 : 1 : gcc_assert (scratch_regno != INVALID_REGNUM);
7403 : :
7404 : 1 : rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
7405 : 1 : emit_move_insn (scratch_reg, base_offset_rtx);
7406 : :
7407 : 1 : return gen_rtx_PLUS (Pmode, base_reg, scratch_reg);
7408 : : }
7409 : :
7410 : 725552 : return plus_constant (Pmode, base_reg, base_offset);
7411 : : }
7412 : :
7413 : : /* Emit code to save registers in the prologue. */
7414 : :
7415 : : static void
7416 : 431411 : ix86_emit_save_regs (void)
7417 : : {
7418 : 431411 : int regno;
7419 : 431411 : rtx_insn *insn;
7420 : :
7421 : 431411 : if (!TARGET_APX_PUSH2POP2
7422 : 10 : || !ix86_can_use_push2pop2 ()
7423 : 431419 : || cfun->machine->func_type != TYPE_NORMAL)
7424 : : {
7425 : 40120572 : for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
7426 : 39689168 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7427 : : {
7428 : 1259655 : insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
7429 : 1259655 : TARGET_APX_PPX));
7430 : 1259655 : RTX_FRAME_RELATED_P (insn) = 1;
7431 : : }
7432 : : }
7433 : : else
7434 : : {
7435 : 7 : int regno_list[2];
7436 : 7 : regno_list[0] = regno_list[1] = -1;
7437 : 7 : int loaded_regnum = 0;
7438 : 7 : bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
7439 : :
7440 : 651 : for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
7441 : 644 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7442 : : {
7443 : 41 : if (aligned)
7444 : : {
7445 : 36 : regno_list[loaded_regnum++] = regno;
7446 : 36 : if (loaded_regnum == 2)
7447 : : {
7448 : 15 : gcc_assert (regno_list[0] != -1
7449 : : && regno_list[1] != -1
7450 : : && regno_list[0] != regno_list[1]);
7451 : 15 : const int offset = UNITS_PER_WORD * 2;
7452 : 15 : rtx mem = gen_rtx_MEM (TImode,
7453 : 15 : gen_rtx_PRE_DEC (Pmode,
7454 : : stack_pointer_rtx));
7455 : 15 : insn = emit_insn (gen_push2 (mem,
7456 : : gen_rtx_REG (word_mode,
7457 : : regno_list[0]),
7458 : : gen_rtx_REG (word_mode,
7459 : : regno_list[1]),
7460 : 15 : TARGET_APX_PPX));
7461 : 15 : RTX_FRAME_RELATED_P (insn) = 1;
7462 : 15 : rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
7463 : :
7464 : 45 : for (int i = 0; i < 2; i++)
7465 : : {
7466 : 60 : rtx dwarf_reg = gen_rtx_REG (word_mode,
7467 : 30 : regno_list[i]);
7468 : 30 : rtx sp_offset = plus_constant (Pmode,
7469 : : stack_pointer_rtx,
7470 : 30 : + UNITS_PER_WORD
7471 : 30 : * (1 - i));
7472 : 30 : rtx tmp = gen_rtx_SET (gen_frame_mem (DImode,
7473 : : sp_offset),
7474 : : dwarf_reg);
7475 : 30 : RTX_FRAME_RELATED_P (tmp) = 1;
7476 : 30 : XVECEXP (dwarf, 0, i + 1) = tmp;
7477 : : }
7478 : 15 : rtx sp_tmp = gen_rtx_SET (stack_pointer_rtx,
7479 : : plus_constant (Pmode,
7480 : : stack_pointer_rtx,
7481 : : -offset));
7482 : 15 : RTX_FRAME_RELATED_P (sp_tmp) = 1;
7483 : 15 : XVECEXP (dwarf, 0, 0) = sp_tmp;
7484 : 15 : add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
7485 : :
7486 : 15 : loaded_regnum = 0;
7487 : 15 : regno_list[0] = regno_list[1] = -1;
7488 : : }
7489 : : }
7490 : : else
7491 : : {
7492 : 5 : insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
7493 : 5 : TARGET_APX_PPX));
7494 : 5 : RTX_FRAME_RELATED_P (insn) = 1;
7495 : 5 : aligned = true;
7496 : : }
7497 : : }
7498 : 7 : if (loaded_regnum == 1)
7499 : : {
7500 : 6 : insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
7501 : 6 : regno_list[0]),
7502 : 6 : TARGET_APX_PPX));
7503 : 6 : RTX_FRAME_RELATED_P (insn) = 1;
7504 : : }
7505 : : }
7506 : 431411 : }
7507 : :
7508 : : /* Emit a single register save at CFA - CFA_OFFSET. */
7509 : :
7510 : : static void
7511 : 331609 : ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
7512 : : HOST_WIDE_INT cfa_offset)
7513 : : {
7514 : 331609 : struct machine_function *m = cfun->machine;
7515 : 331609 : rtx reg = gen_rtx_REG (mode, regno);
7516 : 331609 : rtx mem, addr, base, insn;
7517 : 331609 : unsigned int align = GET_MODE_ALIGNMENT (mode);
7518 : :
7519 : 331609 : addr = choose_baseaddr (cfa_offset, &align);
7520 : 331609 : mem = gen_frame_mem (mode, addr);
7521 : :
7522 : : /* The location aligment depends upon the base register. */
7523 : 331609 : align = MIN (GET_MODE_ALIGNMENT (mode), align);
7524 : 331609 : gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
7525 : 331609 : set_mem_align (mem, align);
7526 : :
7527 : 331609 : insn = emit_insn (gen_rtx_SET (mem, reg));
7528 : 331609 : RTX_FRAME_RELATED_P (insn) = 1;
7529 : :
7530 : 331609 : base = addr;
7531 : 331609 : if (GET_CODE (base) == PLUS)
7532 : 324930 : base = XEXP (base, 0);
7533 : 331609 : gcc_checking_assert (REG_P (base));
7534 : :
7535 : : /* When saving registers into a re-aligned local stack frame, avoid
7536 : : any tricky guessing by dwarf2out. */
7537 : 331609 : if (m->fs.realigned)
7538 : : {
7539 : 12800 : gcc_checking_assert (stack_realign_drap);
7540 : :
7541 : 12800 : if (regno == REGNO (crtl->drap_reg))
7542 : : {
7543 : : /* A bit of a hack. We force the DRAP register to be saved in
7544 : : the re-aligned stack frame, which provides us with a copy
7545 : : of the CFA that will last past the prologue. Install it. */
7546 : 0 : gcc_checking_assert (cfun->machine->fs.fp_valid);
7547 : 0 : addr = plus_constant (Pmode, hard_frame_pointer_rtx,
7548 : 0 : cfun->machine->fs.fp_offset - cfa_offset);
7549 : 0 : mem = gen_rtx_MEM (mode, addr);
7550 : 0 : add_reg_note (insn, REG_CFA_DEF_CFA, mem);
7551 : : }
7552 : : else
7553 : : {
7554 : : /* The frame pointer is a stable reference within the
7555 : : aligned frame. Use it. */
7556 : 12800 : gcc_checking_assert (cfun->machine->fs.fp_valid);
7557 : 12800 : addr = plus_constant (Pmode, hard_frame_pointer_rtx,
7558 : 12800 : cfun->machine->fs.fp_offset - cfa_offset);
7559 : 12800 : mem = gen_rtx_MEM (mode, addr);
7560 : 12800 : add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
7561 : : }
7562 : : }
7563 : :
7564 : 318809 : else if (base == stack_pointer_rtx && m->fs.sp_realigned
7565 : 12881 : && cfa_offset >= m->fs.sp_realigned_offset)
7566 : : {
7567 : 12881 : gcc_checking_assert (stack_realign_fp);
7568 : 12881 : add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
7569 : : }
7570 : :
7571 : : /* The memory may not be relative to the current CFA register,
7572 : : which means that we may need to generate a new pattern for
7573 : : use by the unwind info. */
7574 : 305928 : else if (base != m->fs.cfa_reg)
7575 : : {
7576 : 45090 : addr = plus_constant (Pmode, m->fs.cfa_reg,
7577 : 45090 : m->fs.cfa_offset - cfa_offset);
7578 : 45090 : mem = gen_rtx_MEM (mode, addr);
7579 : 45090 : add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
7580 : : }
7581 : 331609 : }
7582 : :
7583 : : /* Emit code to save registers using MOV insns.
7584 : : First register is stored at CFA - CFA_OFFSET. */
7585 : : static void
7586 : 63 : ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
7587 : : {
7588 : 63 : unsigned int regno;
7589 : :
7590 : 5859 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
7591 : 5796 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7592 : : {
7593 : 88 : ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
7594 : 88 : cfa_offset -= UNITS_PER_WORD;
7595 : : }
7596 : 63 : }
7597 : :
7598 : : /* Emit code to save SSE registers using MOV insns.
7599 : : First register is stored at CFA - CFA_OFFSET. */
7600 : : static void
7601 : 33153 : ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
7602 : : {
7603 : 33153 : unsigned int regno;
7604 : :
7605 : 3083229 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
7606 : 3050076 : if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
7607 : : {
7608 : 331521 : ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
7609 : 331521 : cfa_offset -= GET_MODE_SIZE (V4SFmode);
7610 : : }
7611 : 33153 : }
7612 : :
7613 : : static GTY(()) rtx queued_cfa_restores;
7614 : :
7615 : : /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
7616 : : manipulation insn. The value is on the stack at CFA - CFA_OFFSET.
7617 : : Don't add the note if the previously saved value will be left untouched
7618 : : within stack red-zone till return, as unwinders can find the same value
7619 : : in the register and on the stack. */
7620 : :
7621 : : static void
7622 : 2277879 : ix86_add_cfa_restore_note (rtx_insn *insn, rtx reg, HOST_WIDE_INT cfa_offset)
7623 : : {
7624 : 2277879 : if (!crtl->shrink_wrapped
7625 : 2267005 : && cfa_offset <= cfun->machine->fs.red_zone_offset)
7626 : : return;
7627 : :
7628 : 783715 : if (insn)
7629 : : {
7630 : 389157 : add_reg_note (insn, REG_CFA_RESTORE, reg);
7631 : 389157 : RTX_FRAME_RELATED_P (insn) = 1;
7632 : : }
7633 : : else
7634 : 394558 : queued_cfa_restores
7635 : 394558 : = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
7636 : : }
7637 : :
7638 : : /* Add queued REG_CFA_RESTORE notes if any to INSN. */
7639 : :
7640 : : static void
7641 : 2340771 : ix86_add_queued_cfa_restore_notes (rtx insn)
7642 : : {
7643 : 2340771 : rtx last;
7644 : 2340771 : if (!queued_cfa_restores)
7645 : : return;
7646 : 394558 : for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
7647 : : ;
7648 : 44603 : XEXP (last, 1) = REG_NOTES (insn);
7649 : 44603 : REG_NOTES (insn) = queued_cfa_restores;
7650 : 44603 : queued_cfa_restores = NULL_RTX;
7651 : 44603 : RTX_FRAME_RELATED_P (insn) = 1;
7652 : : }
7653 : :
7654 : : /* Expand prologue or epilogue stack adjustment.
7655 : : The pattern exist to put a dependency on all ebp-based memory accesses.
7656 : : STYLE should be negative if instructions should be marked as frame related,
7657 : : zero if %r11 register is live and cannot be freely used and positive
7658 : : otherwise. */
7659 : :
7660 : : static rtx
7661 : 1380774 : pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
7662 : : int style, bool set_cfa)
7663 : : {
7664 : 1380774 : struct machine_function *m = cfun->machine;
7665 : 1380774 : rtx addend = offset;
7666 : 1380774 : rtx insn;
7667 : 1380774 : bool add_frame_related_expr = false;
7668 : :
7669 : 1380774 : if (!x86_64_immediate_operand (offset, Pmode))
7670 : : {
7671 : : /* r11 is used by indirect sibcall return as well, set before the
7672 : : epilogue and used after the epilogue. */
7673 : 209 : if (style)
7674 : 174 : addend = gen_rtx_REG (Pmode, R11_REG);
7675 : : else
7676 : : {
7677 : 35 : gcc_assert (src != hard_frame_pointer_rtx
7678 : : && dest != hard_frame_pointer_rtx);
7679 : : addend = hard_frame_pointer_rtx;
7680 : : }
7681 : 209 : emit_insn (gen_rtx_SET (addend, offset));
7682 : 209 : if (style < 0)
7683 : 86 : add_frame_related_expr = true;
7684 : : }
7685 : :
7686 : 1380774 : insn = emit_insn (gen_pro_epilogue_adjust_stack_add
7687 : 1380774 : (Pmode, dest, src, addend));
7688 : 1380774 : if (style >= 0)
7689 : 595502 : ix86_add_queued_cfa_restore_notes (insn);
7690 : :
7691 : 1380774 : if (set_cfa)
7692 : : {
7693 : 1032181 : rtx r;
7694 : :
7695 : 1032181 : gcc_assert (m->fs.cfa_reg == src);
7696 : 1032181 : m->fs.cfa_offset += INTVAL (offset);
7697 : 1032181 : m->fs.cfa_reg = dest;
7698 : :
7699 : 1032181 : r = gen_rtx_PLUS (Pmode, src, offset);
7700 : 1032181 : r = gen_rtx_SET (dest, r);
7701 : 1032181 : add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
7702 : 1032181 : RTX_FRAME_RELATED_P (insn) = 1;
7703 : : }
7704 : 348593 : else if (style < 0)
7705 : : {
7706 : 283914 : RTX_FRAME_RELATED_P (insn) = 1;
7707 : 283914 : if (add_frame_related_expr)
7708 : : {
7709 : 20 : rtx r = gen_rtx_PLUS (Pmode, src, offset);
7710 : 20 : r = gen_rtx_SET (dest, r);
7711 : 20 : add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
7712 : : }
7713 : : }
7714 : :
7715 : 1380774 : if (dest == stack_pointer_rtx)
7716 : : {
7717 : 1380774 : HOST_WIDE_INT ooffset = m->fs.sp_offset;
7718 : 1380774 : bool valid = m->fs.sp_valid;
7719 : 1380774 : bool realigned = m->fs.sp_realigned;
7720 : :
7721 : 1380774 : if (src == hard_frame_pointer_rtx)
7722 : : {
7723 : 28949 : valid = m->fs.fp_valid;
7724 : 28949 : realigned = false;
7725 : 28949 : ooffset = m->fs.fp_offset;
7726 : : }
7727 : 1351825 : else if (src == crtl->drap_reg)
7728 : : {
7729 : 0 : valid = m->fs.drap_valid;
7730 : 0 : realigned = false;
7731 : 0 : ooffset = 0;
7732 : : }
7733 : : else
7734 : : {
7735 : : /* Else there are two possibilities: SP itself, which we set
7736 : : up as the default above. Or EH_RETURN_STACKADJ_RTX, which is
7737 : : taken care of this by hand along the eh_return path. */
7738 : 1351825 : gcc_checking_assert (src == stack_pointer_rtx
7739 : : || offset == const0_rtx);
7740 : : }
7741 : :
7742 : 1380774 : m->fs.sp_offset = ooffset - INTVAL (offset);
7743 : 1380774 : m->fs.sp_valid = valid;
7744 : 1380774 : m->fs.sp_realigned = realigned;
7745 : : }
7746 : 1380774 : return insn;
7747 : : }
7748 : :
7749 : : /* Find an available register to be used as dynamic realign argument
7750 : : pointer regsiter. Such a register will be written in prologue and
7751 : : used in begin of body, so it must not be
7752 : : 1. parameter passing register.
7753 : : 2. GOT pointer.
7754 : : We reuse static-chain register if it is available. Otherwise, we
7755 : : use DI for i386 and R13 for x86-64. We chose R13 since it has
7756 : : shorter encoding.
7757 : :
7758 : : Return: the regno of chosen register. */
7759 : :
7760 : : static unsigned int
7761 : 7040 : find_drap_reg (void)
7762 : : {
7763 : 7040 : tree decl = cfun->decl;
7764 : :
7765 : : /* Always use callee-saved register if there are no caller-saved
7766 : : registers. */
7767 : 7040 : if (TARGET_64BIT)
7768 : : {
7769 : : /* Use R13 for nested function or function need static chain.
7770 : : Since function with tail call may use any caller-saved
7771 : : registers in epilogue, DRAP must not use caller-saved
7772 : : register in such case. */
7773 : 6755 : if (DECL_STATIC_CHAIN (decl)
7774 : 6713 : || (cfun->machine->call_saved_registers
7775 : 6713 : == TYPE_NO_CALLER_SAVED_REGISTERS)
7776 : 13468 : || crtl->tail_call_emit)
7777 : 197 : return R13_REG;
7778 : :
7779 : : return R10_REG;
7780 : : }
7781 : : else
7782 : : {
7783 : : /* Use DI for nested function or function need static chain.
7784 : : Since function with tail call may use any caller-saved
7785 : : registers in epilogue, DRAP must not use caller-saved
7786 : : register in such case. */
7787 : 285 : if (DECL_STATIC_CHAIN (decl)
7788 : 285 : || (cfun->machine->call_saved_registers
7789 : 285 : == TYPE_NO_CALLER_SAVED_REGISTERS)
7790 : 285 : || crtl->tail_call_emit
7791 : 548 : || crtl->calls_eh_return)
7792 : : return DI_REG;
7793 : :
7794 : : /* Reuse static chain register if it isn't used for parameter
7795 : : passing. */
7796 : 263 : if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
7797 : : {
7798 : 263 : unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
7799 : 263 : if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
7800 : : return CX_REG;
7801 : : }
7802 : 0 : return DI_REG;
7803 : : }
7804 : : }
7805 : :
7806 : : /* Return minimum incoming stack alignment. */
7807 : :
7808 : : static unsigned int
7809 : 1511477 : ix86_minimum_incoming_stack_boundary (bool sibcall)
7810 : : {
7811 : 1511477 : unsigned int incoming_stack_boundary;
7812 : :
7813 : : /* Stack of interrupt handler is aligned to 128 bits in 64bit mode. */
7814 : 1511477 : if (cfun->machine->func_type != TYPE_NORMAL)
7815 : 118 : incoming_stack_boundary = TARGET_64BIT ? 128 : MIN_STACK_BOUNDARY;
7816 : : /* Prefer the one specified at command line. */
7817 : 1511359 : else if (ix86_user_incoming_stack_boundary)
7818 : : incoming_stack_boundary = ix86_user_incoming_stack_boundary;
7819 : : /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
7820 : : if -mstackrealign is used, it isn't used for sibcall check and
7821 : : estimated stack alignment is 128bit. */
7822 : 1511337 : else if (!sibcall
7823 : 1392833 : && ix86_force_align_arg_pointer
7824 : 4578 : && crtl->stack_alignment_estimated == 128)
7825 : 599 : incoming_stack_boundary = MIN_STACK_BOUNDARY;
7826 : : else
7827 : 1510738 : incoming_stack_boundary = ix86_default_incoming_stack_boundary;
7828 : :
7829 : : /* Incoming stack alignment can be changed on individual functions
7830 : : via force_align_arg_pointer attribute. We use the smallest
7831 : : incoming stack boundary. */
7832 : 1511477 : if (incoming_stack_boundary > MIN_STACK_BOUNDARY
7833 : 3022345 : && lookup_attribute ("force_align_arg_pointer",
7834 : 1510868 : TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
7835 : 5707 : incoming_stack_boundary = MIN_STACK_BOUNDARY;
7836 : :
7837 : : /* The incoming stack frame has to be aligned at least at
7838 : : parm_stack_boundary. */
7839 : 1511477 : if (incoming_stack_boundary < crtl->parm_stack_boundary)
7840 : : incoming_stack_boundary = crtl->parm_stack_boundary;
7841 : :
7842 : : /* Stack at entrance of main is aligned by runtime. We use the
7843 : : smallest incoming stack boundary. */
7844 : 1511477 : if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
7845 : 138474 : && DECL_NAME (current_function_decl)
7846 : 138474 : && MAIN_NAME_P (DECL_NAME (current_function_decl))
7847 : 1513933 : && DECL_FILE_SCOPE_P (current_function_decl))
7848 : 1511477 : incoming_stack_boundary = MAIN_STACK_BOUNDARY;
7849 : :
7850 : 1511477 : return incoming_stack_boundary;
7851 : : }
7852 : :
7853 : : /* Update incoming stack boundary and estimated stack alignment. */
7854 : :
7855 : : static void
7856 : 1392968 : ix86_update_stack_boundary (void)
7857 : : {
7858 : 1392968 : ix86_incoming_stack_boundary
7859 : 1392968 : = ix86_minimum_incoming_stack_boundary (false);
7860 : :
7861 : : /* x86_64 vararg needs 16byte stack alignment for register save area. */
7862 : 1392968 : if (TARGET_64BIT
7863 : 1268152 : && cfun->stdarg
7864 : 20999 : && crtl->stack_alignment_estimated < 128)
7865 : 9983 : crtl->stack_alignment_estimated = 128;
7866 : :
7867 : : /* __tls_get_addr needs to be called with 16-byte aligned stack. */
7868 : 1392968 : if (ix86_tls_descriptor_calls_expanded_in_cfun
7869 : 1324 : && crtl->preferred_stack_boundary < 128)
7870 : 978 : crtl->preferred_stack_boundary = 128;
7871 : 1392968 : }
7872 : :
7873 : : /* Handle the TARGET_GET_DRAP_RTX hook. Return NULL if no DRAP is
7874 : : needed or an rtx for DRAP otherwise. */
7875 : :
7876 : : static rtx
7877 : 1508834 : ix86_get_drap_rtx (void)
7878 : : {
7879 : : /* We must use DRAP if there are outgoing arguments on stack or
7880 : : the stack pointer register is clobbered by asm statment and
7881 : : ACCUMULATE_OUTGOING_ARGS is false. */
7882 : 1508834 : if (ix86_force_drap
7883 : 1508834 : || ((cfun->machine->outgoing_args_on_stack
7884 : 1179602 : || crtl->sp_is_clobbered_by_asm)
7885 : 327286 : && !ACCUMULATE_OUTGOING_ARGS))
7886 : 307086 : crtl->need_drap = true;
7887 : :
7888 : 1508834 : if (stack_realign_drap)
7889 : : {
7890 : : /* Assign DRAP to vDRAP and returns vDRAP */
7891 : 7040 : unsigned int regno = find_drap_reg ();
7892 : 7040 : rtx drap_vreg;
7893 : 7040 : rtx arg_ptr;
7894 : 7040 : rtx_insn *seq, *insn;
7895 : :
7896 : 7040 : arg_ptr = gen_rtx_REG (Pmode, regno);
7897 : 7040 : crtl->drap_reg = arg_ptr;
7898 : :
7899 : 7040 : start_sequence ();
7900 : 7040 : drap_vreg = copy_to_reg (arg_ptr);
7901 : 7040 : seq = get_insns ();
7902 : 7040 : end_sequence ();
7903 : :
7904 : 7040 : insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
7905 : 7040 : if (!optimize)
7906 : : {
7907 : 1870 : add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
7908 : 1870 : RTX_FRAME_RELATED_P (insn) = 1;
7909 : : }
7910 : 7040 : return drap_vreg;
7911 : : }
7912 : : else
7913 : : return NULL;
7914 : : }
7915 : :
7916 : : /* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
7917 : :
7918 : : static rtx
7919 : 1392968 : ix86_internal_arg_pointer (void)
7920 : : {
7921 : 1392968 : return virtual_incoming_args_rtx;
7922 : : }
7923 : :
7924 : : struct scratch_reg {
7925 : : rtx reg;
7926 : : bool saved;
7927 : : };
7928 : :
7929 : : /* Return a short-lived scratch register for use on function entry.
7930 : : In 32-bit mode, it is valid only after the registers are saved
7931 : : in the prologue. This register must be released by means of
7932 : : release_scratch_register_on_entry once it is dead. */
7933 : :
7934 : : static void
7935 : 18 : get_scratch_register_on_entry (struct scratch_reg *sr)
7936 : : {
7937 : 18 : int regno;
7938 : :
7939 : 18 : sr->saved = false;
7940 : :
7941 : 18 : if (TARGET_64BIT)
7942 : : {
7943 : : /* We always use R11 in 64-bit mode. */
7944 : : regno = R11_REG;
7945 : : }
7946 : : else
7947 : : {
7948 : 0 : tree decl = current_function_decl, fntype = TREE_TYPE (decl);
7949 : 0 : bool fastcall_p
7950 : 0 : = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
7951 : 0 : bool thiscall_p
7952 : 0 : = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
7953 : 0 : bool static_chain_p = DECL_STATIC_CHAIN (decl);
7954 : 0 : int regparm = ix86_function_regparm (fntype, decl);
7955 : 0 : int drap_regno
7956 : 0 : = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
7957 : :
7958 : : /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
7959 : : for the static chain register. */
7960 : 0 : if ((regparm < 1 || (fastcall_p && !static_chain_p))
7961 : 0 : && drap_regno != AX_REG)
7962 : : regno = AX_REG;
7963 : : /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
7964 : : for the static chain register. */
7965 : 0 : else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
7966 : : regno = AX_REG;
7967 : 0 : else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
7968 : : regno = DX_REG;
7969 : : /* ecx is the static chain register. */
7970 : 0 : else if (regparm < 3 && !fastcall_p && !thiscall_p
7971 : 0 : && !static_chain_p
7972 : 0 : && drap_regno != CX_REG)
7973 : : regno = CX_REG;
7974 : 0 : else if (ix86_save_reg (BX_REG, true, false))
7975 : : regno = BX_REG;
7976 : : /* esi is the static chain register. */
7977 : 0 : else if (!(regparm == 3 && static_chain_p)
7978 : 0 : && ix86_save_reg (SI_REG, true, false))
7979 : : regno = SI_REG;
7980 : 0 : else if (ix86_save_reg (DI_REG, true, false))
7981 : : regno = DI_REG;
7982 : : else
7983 : : {
7984 : 0 : regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
7985 : 0 : sr->saved = true;
7986 : : }
7987 : : }
7988 : :
7989 : 18 : sr->reg = gen_rtx_REG (Pmode, regno);
7990 : 18 : if (sr->saved)
7991 : : {
7992 : 0 : rtx_insn *insn = emit_insn (gen_push (sr->reg));
7993 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
7994 : : }
7995 : 18 : }
7996 : :
7997 : : /* Release a scratch register obtained from the preceding function.
7998 : :
7999 : : If RELEASE_VIA_POP is true, we just pop the register off the stack
8000 : : to release it. This is what non-Linux systems use with -fstack-check.
8001 : :
8002 : : Otherwise we use OFFSET to locate the saved register and the
8003 : : allocated stack space becomes part of the local frame and is
8004 : : deallocated by the epilogue. */
8005 : :
8006 : : static void
8007 : 18 : release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
8008 : : bool release_via_pop)
8009 : : {
8010 : 18 : if (sr->saved)
8011 : : {
8012 : 0 : if (release_via_pop)
8013 : : {
8014 : 0 : struct machine_function *m = cfun->machine;
8015 : 0 : rtx x, insn = emit_insn (gen_pop (sr->reg));
8016 : :
8017 : : /* The RX FRAME_RELATED_P mechanism doesn't know about pop. */
8018 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
8019 : 0 : x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
8020 : 0 : x = gen_rtx_SET (stack_pointer_rtx, x);
8021 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
8022 : 0 : m->fs.sp_offset -= UNITS_PER_WORD;
8023 : : }
8024 : : else
8025 : : {
8026 : 0 : rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
8027 : 0 : x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
8028 : 0 : emit_insn (x);
8029 : : }
8030 : : }
8031 : 18 : }
8032 : :
8033 : : /* Emit code to adjust the stack pointer by SIZE bytes while probing it.
8034 : :
8035 : : If INT_REGISTERS_SAVED is true, then integer registers have already been
8036 : : pushed on the stack.
8037 : :
8038 : : If PROTECTION AREA is true, then probe PROBE_INTERVAL plus a small dope
8039 : : beyond SIZE bytes.
8040 : :
8041 : : This assumes no knowledge of the current probing state, i.e. it is never
8042 : : allowed to allocate more than PROBE_INTERVAL bytes of stack space without
8043 : : a suitable probe. */
8044 : :
8045 : : static void
8046 : 114 : ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
8047 : : const bool int_registers_saved,
8048 : : const bool protection_area)
8049 : : {
8050 : 114 : struct machine_function *m = cfun->machine;
8051 : :
8052 : : /* If this function does not statically allocate stack space, then
8053 : : no probes are needed. */
8054 : 114 : if (!size)
8055 : : {
8056 : : /* However, the allocation of space via pushes for register
8057 : : saves could be viewed as allocating space, but without the
8058 : : need to probe. */
8059 : 47 : if (m->frame.nregs || m->frame.nsseregs || frame_pointer_needed)
8060 : 24 : dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
8061 : : else
8062 : 23 : dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
8063 : 47 : return;
8064 : : }
8065 : :
8066 : : /* If we are a noreturn function, then we have to consider the
8067 : : possibility that we're called via a jump rather than a call.
8068 : :
8069 : : Thus we don't have the implicit probe generated by saving the
8070 : : return address into the stack at the call. Thus, the stack
8071 : : pointer could be anywhere in the guard page. The safe thing
8072 : : to do is emit a probe now.
8073 : :
8074 : : The probe can be avoided if we have already emitted any callee
8075 : : register saves into the stack or have a frame pointer (which will
8076 : : have been saved as well). Those saves will function as implicit
8077 : : probes.
8078 : :
8079 : : ?!? This should be revamped to work like aarch64 and s390 where
8080 : : we track the offset from the most recent probe. Normally that
8081 : : offset would be zero. For a noreturn function we would reset
8082 : : it to PROBE_INTERVAL - (STACK_BOUNDARY / BITS_PER_UNIT). Then
8083 : : we just probe when we cross PROBE_INTERVAL. */
8084 : 67 : if (TREE_THIS_VOLATILE (cfun->decl)
8085 : 8 : && !(m->frame.nregs || m->frame.nsseregs || frame_pointer_needed))
8086 : : {
8087 : : /* We can safely use any register here since we're just going to push
8088 : : its value and immediately pop it back. But we do try and avoid
8089 : : argument passing registers so as not to introduce dependencies in
8090 : : the pipeline. For 32 bit we use %esi and for 64 bit we use %rax. */
8091 : 7 : rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
8092 : 7 : rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
8093 : 7 : rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
8094 : 7 : m->fs.sp_offset -= UNITS_PER_WORD;
8095 : 7 : if (m->fs.cfa_reg == stack_pointer_rtx)
8096 : : {
8097 : 7 : m->fs.cfa_offset -= UNITS_PER_WORD;
8098 : 7 : rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
8099 : 7 : x = gen_rtx_SET (stack_pointer_rtx, x);
8100 : 7 : add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
8101 : 7 : RTX_FRAME_RELATED_P (insn_push) = 1;
8102 : 7 : x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
8103 : 7 : x = gen_rtx_SET (stack_pointer_rtx, x);
8104 : 7 : add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
8105 : 7 : RTX_FRAME_RELATED_P (insn_pop) = 1;
8106 : : }
8107 : 7 : emit_insn (gen_blockage ());
8108 : : }
8109 : :
8110 : 67 : const HOST_WIDE_INT probe_interval = get_probe_interval ();
8111 : 67 : const int dope = 4 * UNITS_PER_WORD;
8112 : :
8113 : : /* If there is protection area, take it into account in the size. */
8114 : 67 : if (protection_area)
8115 : 25 : size += probe_interval + dope;
8116 : :
8117 : : /* If we allocate less than the size of the guard statically,
8118 : : then no probing is necessary, but we do need to allocate
8119 : : the stack. */
8120 : 42 : else if (size < (1 << param_stack_clash_protection_guard_size))
8121 : : {
8122 : 28 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8123 : : GEN_INT (-size), -1,
8124 : 28 : m->fs.cfa_reg == stack_pointer_rtx);
8125 : 28 : dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
8126 : 28 : return;
8127 : : }
8128 : :
8129 : : /* We're allocating a large enough stack frame that we need to
8130 : : emit probes. Either emit them inline or in a loop depending
8131 : : on the size. */
8132 : 39 : if (size <= 4 * probe_interval)
8133 : : {
8134 : : HOST_WIDE_INT i;
8135 : 49 : for (i = probe_interval; i <= size; i += probe_interval)
8136 : : {
8137 : : /* Allocate PROBE_INTERVAL bytes. */
8138 : 28 : rtx insn
8139 : 28 : = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8140 : : GEN_INT (-probe_interval), -1,
8141 : 28 : m->fs.cfa_reg == stack_pointer_rtx);
8142 : 28 : add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
8143 : :
8144 : : /* And probe at *sp. */
8145 : 28 : emit_stack_probe (stack_pointer_rtx);
8146 : 28 : emit_insn (gen_blockage ());
8147 : : }
8148 : :
8149 : : /* We need to allocate space for the residual, but we do not need
8150 : : to probe the residual... */
8151 : 21 : HOST_WIDE_INT residual = (i - probe_interval - size);
8152 : 21 : if (residual)
8153 : : {
8154 : 21 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8155 : : GEN_INT (residual), -1,
8156 : 21 : m->fs.cfa_reg == stack_pointer_rtx);
8157 : :
8158 : : /* ...except if there is a protection area to maintain. */
8159 : 21 : if (protection_area)
8160 : 12 : emit_stack_probe (stack_pointer_rtx);
8161 : : }
8162 : :
8163 : 21 : dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
8164 : : }
8165 : : else
8166 : : {
8167 : : /* We expect the GP registers to be saved when probes are used
8168 : : as the probing sequences might need a scratch register and
8169 : : the routine to allocate one assumes the integer registers
8170 : : have already been saved. */
8171 : 18 : gcc_assert (int_registers_saved);
8172 : :
8173 : 18 : struct scratch_reg sr;
8174 : 18 : get_scratch_register_on_entry (&sr);
8175 : :
8176 : : /* If we needed to save a register, then account for any space
8177 : : that was pushed (we are not going to pop the register when
8178 : : we do the restore). */
8179 : 18 : if (sr.saved)
8180 : 0 : size -= UNITS_PER_WORD;
8181 : :
8182 : : /* Step 1: round SIZE down to a multiple of the interval. */
8183 : 18 : HOST_WIDE_INT rounded_size = size & -probe_interval;
8184 : :
8185 : : /* Step 2: compute final value of the loop counter. Use lea if
8186 : : possible. */
8187 : 18 : rtx addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
8188 : 18 : rtx insn;
8189 : 18 : if (address_no_seg_operand (addr, Pmode))
8190 : 6 : insn = emit_insn (gen_rtx_SET (sr.reg, addr));
8191 : : else
8192 : : {
8193 : 12 : emit_move_insn (sr.reg, GEN_INT (-rounded_size));
8194 : 12 : insn = emit_insn (gen_rtx_SET (sr.reg,
8195 : : gen_rtx_PLUS (Pmode, sr.reg,
8196 : : stack_pointer_rtx)));
8197 : : }
8198 : 18 : if (m->fs.cfa_reg == stack_pointer_rtx)
8199 : : {
8200 : 16 : add_reg_note (insn, REG_CFA_DEF_CFA,
8201 : 16 : plus_constant (Pmode, sr.reg,
8202 : 16 : m->fs.cfa_offset + rounded_size));
8203 : 16 : RTX_FRAME_RELATED_P (insn) = 1;
8204 : : }
8205 : :
8206 : : /* Step 3: the loop. */
8207 : 18 : rtx size_rtx = GEN_INT (rounded_size);
8208 : 18 : insn = emit_insn (gen_adjust_stack_and_probe (Pmode, sr.reg, sr.reg,
8209 : : size_rtx));
8210 : 18 : if (m->fs.cfa_reg == stack_pointer_rtx)
8211 : : {
8212 : 16 : m->fs.cfa_offset += rounded_size;
8213 : 16 : add_reg_note (insn, REG_CFA_DEF_CFA,
8214 : 16 : plus_constant (Pmode, stack_pointer_rtx,
8215 : 16 : m->fs.cfa_offset));
8216 : 16 : RTX_FRAME_RELATED_P (insn) = 1;
8217 : : }
8218 : 18 : m->fs.sp_offset += rounded_size;
8219 : 18 : emit_insn (gen_blockage ());
8220 : :
8221 : : /* Step 4: adjust SP if we cannot assert at compile-time that SIZE
8222 : : is equal to ROUNDED_SIZE. */
8223 : :
8224 : 18 : if (size != rounded_size)
8225 : : {
8226 : 18 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8227 : : GEN_INT (rounded_size - size), -1,
8228 : 18 : m->fs.cfa_reg == stack_pointer_rtx);
8229 : :
8230 : 18 : if (protection_area)
8231 : 13 : emit_stack_probe (stack_pointer_rtx);
8232 : : }
8233 : :
8234 : 18 : dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
8235 : :
8236 : : /* This does not deallocate the space reserved for the scratch
8237 : : register. That will be deallocated in the epilogue. */
8238 : 18 : release_scratch_register_on_entry (&sr, size, false);
8239 : : }
8240 : :
8241 : : /* Adjust back to account for the protection area. */
8242 : 39 : if (protection_area)
8243 : 25 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
8244 : 25 : GEN_INT (probe_interval + dope), -1,
8245 : 25 : m->fs.cfa_reg == stack_pointer_rtx);
8246 : :
8247 : : /* Make sure nothing is scheduled before we are done. */
8248 : 39 : emit_insn (gen_blockage ());
8249 : : }
8250 : :
8251 : : /* Adjust the stack pointer up to REG while probing it. */
8252 : :
8253 : : const char *
8254 : 18 : output_adjust_stack_and_probe (rtx reg)
8255 : : {
8256 : 18 : static int labelno = 0;
8257 : 18 : char loop_lab[32];
8258 : 18 : rtx xops[2];
8259 : :
8260 : 18 : ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
8261 : :
8262 : : /* Loop. */
8263 : 18 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
8264 : :
8265 : : /* SP = SP + PROBE_INTERVAL. */
8266 : 18 : xops[0] = stack_pointer_rtx;
8267 : 23 : xops[1] = GEN_INT (get_probe_interval ());
8268 : 18 : output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
8269 : :
8270 : : /* Probe at SP. */
8271 : 18 : xops[1] = const0_rtx;
8272 : 18 : output_asm_insn ("or%z0\t{%1, (%0)|DWORD PTR [%0], %1}", xops);
8273 : :
8274 : : /* Test if SP == LAST_ADDR. */
8275 : 18 : xops[0] = stack_pointer_rtx;
8276 : 18 : xops[1] = reg;
8277 : 18 : output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
8278 : :
8279 : : /* Branch. */
8280 : 18 : fputs ("\tjne\t", asm_out_file);
8281 : 18 : assemble_name_raw (asm_out_file, loop_lab);
8282 : 18 : fputc ('\n', asm_out_file);
8283 : :
8284 : 18 : return "";
8285 : : }
8286 : :
8287 : : /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
8288 : : inclusive. These are offsets from the current stack pointer.
8289 : :
8290 : : INT_REGISTERS_SAVED is true if integer registers have already been
8291 : : pushed on the stack. */
8292 : :
8293 : : static void
8294 : 0 : ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
8295 : : const bool int_registers_saved)
8296 : : {
8297 : 0 : const HOST_WIDE_INT probe_interval = get_probe_interval ();
8298 : :
8299 : : /* See if we have a constant small number of probes to generate. If so,
8300 : : that's the easy case. The run-time loop is made up of 6 insns in the
8301 : : generic case while the compile-time loop is made up of n insns for n #
8302 : : of intervals. */
8303 : 0 : if (size <= 6 * probe_interval)
8304 : : {
8305 : : HOST_WIDE_INT i;
8306 : :
8307 : : /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
8308 : : it exceeds SIZE. If only one probe is needed, this will not
8309 : : generate any code. Then probe at FIRST + SIZE. */
8310 : 0 : for (i = probe_interval; i < size; i += probe_interval)
8311 : 0 : emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
8312 : 0 : -(first + i)));
8313 : :
8314 : 0 : emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
8315 : 0 : -(first + size)));
8316 : : }
8317 : :
8318 : : /* Otherwise, do the same as above, but in a loop. Note that we must be
8319 : : extra careful with variables wrapping around because we might be at
8320 : : the very top (or the very bottom) of the address space and we have
8321 : : to be able to handle this case properly; in particular, we use an
8322 : : equality test for the loop condition. */
8323 : : else
8324 : : {
8325 : : /* We expect the GP registers to be saved when probes are used
8326 : : as the probing sequences might need a scratch register and
8327 : : the routine to allocate one assumes the integer registers
8328 : : have already been saved. */
8329 : 0 : gcc_assert (int_registers_saved);
8330 : :
8331 : 0 : HOST_WIDE_INT rounded_size, last;
8332 : 0 : struct scratch_reg sr;
8333 : :
8334 : 0 : get_scratch_register_on_entry (&sr);
8335 : :
8336 : :
8337 : : /* Step 1: round SIZE to the previous multiple of the interval. */
8338 : :
8339 : 0 : rounded_size = ROUND_DOWN (size, probe_interval);
8340 : :
8341 : :
8342 : : /* Step 2: compute initial and final value of the loop counter. */
8343 : :
8344 : : /* TEST_OFFSET = FIRST. */
8345 : 0 : emit_move_insn (sr.reg, GEN_INT (-first));
8346 : :
8347 : : /* LAST_OFFSET = FIRST + ROUNDED_SIZE. */
8348 : 0 : last = first + rounded_size;
8349 : :
8350 : :
8351 : : /* Step 3: the loop
8352 : :
8353 : : do
8354 : : {
8355 : : TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
8356 : : probe at TEST_ADDR
8357 : : }
8358 : : while (TEST_ADDR != LAST_ADDR)
8359 : :
8360 : : probes at FIRST + N * PROBE_INTERVAL for values of N from 1
8361 : : until it is equal to ROUNDED_SIZE. */
8362 : :
8363 : 0 : emit_insn
8364 : 0 : (gen_probe_stack_range (Pmode, sr.reg, sr.reg, GEN_INT (-last)));
8365 : :
8366 : :
8367 : : /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
8368 : : that SIZE is equal to ROUNDED_SIZE. */
8369 : :
8370 : 0 : if (size != rounded_size)
8371 : 0 : emit_stack_probe (plus_constant (Pmode,
8372 : 0 : gen_rtx_PLUS (Pmode,
8373 : : stack_pointer_rtx,
8374 : : sr.reg),
8375 : 0 : rounded_size - size));
8376 : :
8377 : 0 : release_scratch_register_on_entry (&sr, size, true);
8378 : : }
8379 : :
8380 : : /* Make sure nothing is scheduled before we are done. */
8381 : 0 : emit_insn (gen_blockage ());
8382 : 0 : }
8383 : :
8384 : : /* Probe a range of stack addresses from REG to END, inclusive. These are
8385 : : offsets from the current stack pointer. */
8386 : :
8387 : : const char *
8388 : 0 : output_probe_stack_range (rtx reg, rtx end)
8389 : : {
8390 : 0 : static int labelno = 0;
8391 : 0 : char loop_lab[32];
8392 : 0 : rtx xops[3];
8393 : :
8394 : 0 : ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
8395 : :
8396 : : /* Loop. */
8397 : 0 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
8398 : :
8399 : : /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
8400 : 0 : xops[0] = reg;
8401 : 0 : xops[1] = GEN_INT (get_probe_interval ());
8402 : 0 : output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
8403 : :
8404 : : /* Probe at TEST_ADDR. */
8405 : 0 : xops[0] = stack_pointer_rtx;
8406 : 0 : xops[1] = reg;
8407 : 0 : xops[2] = const0_rtx;
8408 : 0 : output_asm_insn ("or%z0\t{%2, (%0,%1)|DWORD PTR [%0+%1], %2}", xops);
8409 : :
8410 : : /* Test if TEST_ADDR == LAST_ADDR. */
8411 : 0 : xops[0] = reg;
8412 : 0 : xops[1] = end;
8413 : 0 : output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
8414 : :
8415 : : /* Branch. */
8416 : 0 : fputs ("\tjne\t", asm_out_file);
8417 : 0 : assemble_name_raw (asm_out_file, loop_lab);
8418 : 0 : fputc ('\n', asm_out_file);
8419 : :
8420 : 0 : return "";
8421 : : }
8422 : :
8423 : : /* Set stack_frame_required to false if stack frame isn't required.
8424 : : Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
8425 : : slot used if stack frame is required and CHECK_STACK_SLOT is true. */
8426 : :
8427 : : static void
8428 : 1392283 : ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
8429 : : bool check_stack_slot)
8430 : : {
8431 : 1392283 : HARD_REG_SET set_up_by_prologue, prologue_used;
8432 : 1392283 : basic_block bb;
8433 : :
8434 : 5569132 : CLEAR_HARD_REG_SET (prologue_used);
8435 : 1392283 : CLEAR_HARD_REG_SET (set_up_by_prologue);
8436 : 1392283 : add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
8437 : 1392283 : add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
8438 : 1392283 : add_to_hard_reg_set (&set_up_by_prologue, Pmode,
8439 : : HARD_FRAME_POINTER_REGNUM);
8440 : :
8441 : : /* The preferred stack alignment is the minimum stack alignment. */
8442 : 1392283 : if (stack_alignment > crtl->preferred_stack_boundary)
8443 : 135521 : stack_alignment = crtl->preferred_stack_boundary;
8444 : :
8445 : 1392283 : bool require_stack_frame = false;
8446 : :
8447 : 14274479 : FOR_EACH_BB_FN (bb, cfun)
8448 : : {
8449 : 12882196 : rtx_insn *insn;
8450 : 149530571 : FOR_BB_INSNS (bb, insn)
8451 : 136648375 : if (NONDEBUG_INSN_P (insn)
8452 : 136648375 : && requires_stack_frame_p (insn, prologue_used,
8453 : : set_up_by_prologue))
8454 : : {
8455 : 30544640 : require_stack_frame = true;
8456 : :
8457 : 30544640 : if (check_stack_slot)
8458 : : {
8459 : : /* Find the maximum stack alignment. */
8460 : 27025330 : subrtx_iterator::array_type array;
8461 : 186491755 : FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
8462 : 159466425 : if (MEM_P (*iter)
8463 : 159466425 : && (reg_mentioned_p (stack_pointer_rtx,
8464 : : *iter)
8465 : 12057628 : || reg_mentioned_p (frame_pointer_rtx,
8466 : : *iter)))
8467 : : {
8468 : 9590133 : unsigned int alignment = MEM_ALIGN (*iter);
8469 : 9590133 : if (alignment > stack_alignment)
8470 : 25726 : stack_alignment = alignment;
8471 : : }
8472 : 27025330 : }
8473 : : }
8474 : : }
8475 : :
8476 : 1392283 : cfun->machine->stack_frame_required = require_stack_frame;
8477 : 1392283 : }
8478 : :
8479 : : /* Finalize stack_realign_needed and frame_pointer_needed flags, which
8480 : : will guide prologue/epilogue to be generated in correct form. */
8481 : :
8482 : : static void
8483 : 3156003 : ix86_finalize_stack_frame_flags (void)
8484 : : {
8485 : : /* Check if stack realign is really needed after reload, and
8486 : : stores result in cfun */
8487 : 3156003 : unsigned int incoming_stack_boundary
8488 : 3156003 : = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
8489 : 3156003 : ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
8490 : 3156003 : unsigned int stack_alignment
8491 : 1085426 : = (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
8492 : 4241429 : ? crtl->max_used_stack_slot_alignment
8493 : 3156003 : : crtl->stack_alignment_needed);
8494 : 3156003 : unsigned int stack_realign
8495 : 3156003 : = (incoming_stack_boundary < stack_alignment);
8496 : 3156003 : bool recompute_frame_layout_p = false;
8497 : :
8498 : 3156003 : if (crtl->stack_realign_finalized)
8499 : : {
8500 : : /* After stack_realign_needed is finalized, we can't no longer
8501 : : change it. */
8502 : 1763720 : gcc_assert (crtl->stack_realign_needed == stack_realign);
8503 : 1763720 : return;
8504 : : }
8505 : :
8506 : : /* It is always safe to compute max_used_stack_alignment. We
8507 : : compute it only if 128-bit aligned load/store may be generated
8508 : : on misaligned stack slot which will lead to segfault. */
8509 : 2784566 : bool check_stack_slot
8510 : 1392283 : = (stack_realign || crtl->max_used_stack_slot_alignment >= 128);
8511 : 1392283 : ix86_find_max_used_stack_alignment (stack_alignment,
8512 : : check_stack_slot);
8513 : :
8514 : : /* If the only reason for frame_pointer_needed is that we conservatively
8515 : : assumed stack realignment might be needed or -fno-omit-frame-pointer
8516 : : is used, but in the end nothing that needed the stack alignment had
8517 : : been spilled nor stack access, clear frame_pointer_needed and say we
8518 : : don't need stack realignment.
8519 : :
8520 : : When vector register is used for piecewise move and store, we don't
8521 : : increase stack_alignment_needed as there is no register spill for
8522 : : piecewise move and store. Since stack_realign_needed is set to true
8523 : : by checking stack_alignment_estimated which is updated by pseudo
8524 : : vector register usage, we also need to check stack_realign_needed to
8525 : : eliminate frame pointer. */
8526 : 1392283 : if ((stack_realign
8527 : 1334177 : || (!flag_omit_frame_pointer && optimize)
8528 : 1323950 : || crtl->stack_realign_needed)
8529 : 68895 : && frame_pointer_needed
8530 : 68895 : && crtl->is_leaf
8531 : 44955 : && crtl->sp_is_unchanging
8532 : 44903 : && !ix86_current_function_calls_tls_descriptor
8533 : 44903 : && !crtl->accesses_prior_frames
8534 : 44903 : && !cfun->calls_alloca
8535 : 44903 : && !crtl->calls_eh_return
8536 : : /* See ira_setup_eliminable_regset for the rationale. */
8537 : 44903 : && !(STACK_CHECK_MOVING_SP
8538 : 44903 : && flag_stack_check
8539 : 0 : && flag_exceptions
8540 : 0 : && cfun->can_throw_non_call_exceptions)
8541 : 44903 : && !ix86_frame_pointer_required ()
8542 : 44902 : && ix86_get_frame_size () == 0
8543 : 28915 : && ix86_nsaved_sseregs () == 0
8544 : 1421198 : && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
8545 : : {
8546 : 28915 : if (cfun->machine->stack_frame_required)
8547 : : {
8548 : : /* Stack frame is required. If stack alignment needed is less
8549 : : than incoming stack boundary, don't realign stack. */
8550 : 213 : stack_realign = incoming_stack_boundary < stack_alignment;
8551 : 213 : if (!stack_realign)
8552 : : {
8553 : 213 : crtl->max_used_stack_slot_alignment
8554 : 213 : = incoming_stack_boundary;
8555 : 213 : crtl->stack_alignment_needed
8556 : 213 : = incoming_stack_boundary;
8557 : : /* Also update preferred_stack_boundary for leaf
8558 : : functions. */
8559 : 213 : crtl->preferred_stack_boundary
8560 : 213 : = incoming_stack_boundary;
8561 : : }
8562 : : }
8563 : : else
8564 : : {
8565 : : /* If drap has been set, but it actually isn't live at the
8566 : : start of the function, there is no reason to set it up. */
8567 : 28702 : if (crtl->drap_reg)
8568 : : {
8569 : 37 : basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
8570 : 74 : if (! REGNO_REG_SET_P (DF_LR_IN (bb),
8571 : : REGNO (crtl->drap_reg)))
8572 : : {
8573 : 37 : crtl->drap_reg = NULL_RTX;
8574 : 37 : crtl->need_drap = false;
8575 : : }
8576 : : }
8577 : : else
8578 : 28665 : cfun->machine->no_drap_save_restore = true;
8579 : :
8580 : 28702 : frame_pointer_needed = false;
8581 : 28702 : stack_realign = false;
8582 : 28702 : crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
8583 : 28702 : crtl->stack_alignment_needed = incoming_stack_boundary;
8584 : 28702 : crtl->stack_alignment_estimated = incoming_stack_boundary;
8585 : 28702 : if (crtl->preferred_stack_boundary > incoming_stack_boundary)
8586 : 0 : crtl->preferred_stack_boundary = incoming_stack_boundary;
8587 : 28702 : df_finish_pass (true);
8588 : 28702 : df_scan_alloc (NULL);
8589 : 28702 : df_scan_blocks ();
8590 : 28702 : df_compute_regs_ever_live (true);
8591 : 28702 : df_analyze ();
8592 : :
8593 : 28702 : if (flag_var_tracking)
8594 : : {
8595 : : /* Since frame pointer is no longer available, replace it with
8596 : : stack pointer - UNITS_PER_WORD in debug insns. */
8597 : 127 : df_ref ref, next;
8598 : 127 : for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM);
8599 : 127 : ref; ref = next)
8600 : : {
8601 : 0 : next = DF_REF_NEXT_REG (ref);
8602 : 0 : if (!DF_REF_INSN_INFO (ref))
8603 : 0 : continue;
8604 : :
8605 : : /* Make sure the next ref is for a different instruction,
8606 : : so that we're not affected by the rescan. */
8607 : 0 : rtx_insn *insn = DF_REF_INSN (ref);
8608 : 0 : while (next && DF_REF_INSN (next) == insn)
8609 : 0 : next = DF_REF_NEXT_REG (next);
8610 : :
8611 : 0 : if (DEBUG_INSN_P (insn))
8612 : : {
8613 : : bool changed = false;
8614 : 0 : for (; ref != next; ref = DF_REF_NEXT_REG (ref))
8615 : : {
8616 : 0 : rtx *loc = DF_REF_LOC (ref);
8617 : 0 : if (*loc == hard_frame_pointer_rtx)
8618 : : {
8619 : 0 : *loc = plus_constant (Pmode,
8620 : : stack_pointer_rtx,
8621 : 0 : -UNITS_PER_WORD);
8622 : 0 : changed = true;
8623 : : }
8624 : : }
8625 : 0 : if (changed)
8626 : 0 : df_insn_rescan (insn);
8627 : : }
8628 : : }
8629 : : }
8630 : :
8631 : : recompute_frame_layout_p = true;
8632 : : }
8633 : : }
8634 : 1363368 : else if (crtl->max_used_stack_slot_alignment >= 128
8635 : 612355 : && cfun->machine->stack_frame_required)
8636 : : {
8637 : : /* We don't need to realign stack. max_used_stack_alignment is
8638 : : used to decide how stack frame should be aligned. This is
8639 : : independent of any psABIs nor 32-bit vs 64-bit. */
8640 : 571677 : cfun->machine->max_used_stack_alignment
8641 : 571677 : = stack_alignment / BITS_PER_UNIT;
8642 : : }
8643 : :
8644 : 1392283 : if (crtl->stack_realign_needed != stack_realign)
8645 : 29101 : recompute_frame_layout_p = true;
8646 : 1392283 : crtl->stack_realign_needed = stack_realign;
8647 : 1392283 : crtl->stack_realign_finalized = true;
8648 : 1392283 : if (recompute_frame_layout_p)
8649 : 29178 : ix86_compute_frame_layout ();
8650 : : }
8651 : :
8652 : : /* Delete SET_GOT right after entry block if it is allocated to reg. */
8653 : :
8654 : : static void
8655 : 0 : ix86_elim_entry_set_got (rtx reg)
8656 : : {
8657 : 0 : basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
8658 : 0 : rtx_insn *c_insn = BB_HEAD (bb);
8659 : 0 : if (!NONDEBUG_INSN_P (c_insn))
8660 : 0 : c_insn = next_nonnote_nondebug_insn (c_insn);
8661 : 0 : if (c_insn && NONJUMP_INSN_P (c_insn))
8662 : : {
8663 : 0 : rtx pat = PATTERN (c_insn);
8664 : 0 : if (GET_CODE (pat) == PARALLEL)
8665 : : {
8666 : 0 : rtx set = XVECEXP (pat, 0, 0);
8667 : 0 : if (GET_CODE (set) == SET
8668 : 0 : && GET_CODE (SET_SRC (set)) == UNSPEC
8669 : 0 : && XINT (SET_SRC (set), 1) == UNSPEC_SET_GOT
8670 : 0 : && REGNO (SET_DEST (set)) == REGNO (reg))
8671 : 0 : delete_insn (c_insn);
8672 : : }
8673 : : }
8674 : 0 : }
8675 : :
8676 : : static rtx
8677 : 197890 : gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store)
8678 : : {
8679 : 197890 : rtx addr, mem;
8680 : :
8681 : 197890 : if (offset)
8682 : 189156 : addr = plus_constant (Pmode, frame_reg, offset);
8683 : 197890 : mem = gen_frame_mem (GET_MODE (reg), offset ? addr : frame_reg);
8684 : 197890 : return gen_rtx_SET (store ? mem : reg, store ? reg : mem);
8685 : : }
8686 : :
8687 : : static inline rtx
8688 : 102965 : gen_frame_load (rtx reg, rtx frame_reg, int offset)
8689 : : {
8690 : 102965 : return gen_frame_set (reg, frame_reg, offset, false);
8691 : : }
8692 : :
8693 : : static inline rtx
8694 : 94925 : gen_frame_store (rtx reg, rtx frame_reg, int offset)
8695 : : {
8696 : 94925 : return gen_frame_set (reg, frame_reg, offset, true);
8697 : : }
8698 : :
8699 : : static void
8700 : 7045 : ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
8701 : : {
8702 : 7045 : struct machine_function *m = cfun->machine;
8703 : 7045 : const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
8704 : 7045 : + m->call_ms2sysv_extra_regs;
8705 : 7045 : rtvec v = rtvec_alloc (ncregs + 1);
8706 : 7045 : unsigned int align, i, vi = 0;
8707 : 7045 : rtx_insn *insn;
8708 : 7045 : rtx sym, addr;
8709 : 7045 : rtx rax = gen_rtx_REG (word_mode, AX_REG);
8710 : 7045 : const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
8711 : :
8712 : : /* AL should only be live with sysv_abi. */
8713 : 7045 : gcc_assert (!ix86_eax_live_at_start_p ());
8714 : 7045 : gcc_assert (m->fs.sp_offset >= frame.sse_reg_save_offset);
8715 : :
8716 : : /* Setup RAX as the stub's base pointer. We use stack_realign_offset rather
8717 : : we've actually realigned the stack or not. */
8718 : 7045 : align = GET_MODE_ALIGNMENT (V4SFmode);
8719 : 7045 : addr = choose_baseaddr (frame.stack_realign_offset
8720 : 7045 : + xlogue.get_stub_ptr_offset (), &align, AX_REG);
8721 : 7045 : gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
8722 : :
8723 : 7045 : emit_insn (gen_rtx_SET (rax, addr));
8724 : :
8725 : : /* Get the stub symbol. */
8726 : 8327 : sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP
8727 : : : XLOGUE_STUB_SAVE);
8728 : 7045 : RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
8729 : :
8730 : 101970 : for (i = 0; i < ncregs; ++i)
8731 : : {
8732 : 94925 : const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
8733 : 94925 : rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode),
8734 : 94925 : r.regno);
8735 : 94925 : RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);
8736 : : }
8737 : :
8738 : 7045 : gcc_assert (vi == (unsigned)GET_NUM_ELEM (v));
8739 : :
8740 : 7045 : insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
8741 : 7045 : RTX_FRAME_RELATED_P (insn) = true;
8742 : 7045 : }
8743 : :
8744 : : /* Generate and return an insn body to AND X with Y. */
8745 : :
8746 : : static rtx_insn *
8747 : 29567 : gen_and2_insn (rtx x, rtx y)
8748 : : {
8749 : 29567 : enum insn_code icode = optab_handler (and_optab, GET_MODE (x));
8750 : :
8751 : 29567 : gcc_assert (insn_operand_matches (icode, 0, x));
8752 : 29567 : gcc_assert (insn_operand_matches (icode, 1, x));
8753 : 29567 : gcc_assert (insn_operand_matches (icode, 2, y));
8754 : :
8755 : 29567 : return GEN_FCN (icode) (x, x, y);
8756 : : }
8757 : :
8758 : : /* Expand the prologue into a bunch of separate insns. */
8759 : :
8760 : : void
8761 : 1392360 : ix86_expand_prologue (void)
8762 : : {
8763 : 1392360 : struct machine_function *m = cfun->machine;
8764 : 1392360 : rtx insn, t;
8765 : 1392360 : HOST_WIDE_INT allocate;
8766 : 1392360 : bool int_registers_saved;
8767 : 1392360 : bool sse_registers_saved;
8768 : 1392360 : bool save_stub_call_needed;
8769 : 1392360 : rtx static_chain = NULL_RTX;
8770 : :
8771 : 1392360 : ix86_last_zero_store_uid = 0;
8772 : 1392360 : if (ix86_function_naked (current_function_decl))
8773 : : {
8774 : 77 : if (flag_stack_usage_info)
8775 : 0 : current_function_static_stack_size = 0;
8776 : 77 : return;
8777 : : }
8778 : :
8779 : 1392283 : ix86_finalize_stack_frame_flags ();
8780 : :
8781 : : /* DRAP should not coexist with stack_realign_fp */
8782 : 1392283 : gcc_assert (!(crtl->drap_reg && stack_realign_fp));
8783 : :
8784 : 1392283 : memset (&m->fs, 0, sizeof (m->fs));
8785 : :
8786 : : /* Initialize CFA state for before the prologue. */
8787 : 1392283 : m->fs.cfa_reg = stack_pointer_rtx;
8788 : 1392283 : m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
8789 : :
8790 : : /* Track SP offset to the CFA. We continue tracking this after we've
8791 : : swapped the CFA register away from SP. In the case of re-alignment
8792 : : this is fudged; we're interested to offsets within the local frame. */
8793 : 1392283 : m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
8794 : 1392283 : m->fs.sp_valid = true;
8795 : 1392283 : m->fs.sp_realigned = false;
8796 : :
8797 : 1392283 : const struct ix86_frame &frame = cfun->machine->frame;
8798 : :
8799 : 1392283 : if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
8800 : : {
8801 : : /* We should have already generated an error for any use of
8802 : : ms_hook on a nested function. */
8803 : 0 : gcc_checking_assert (!ix86_static_chain_on_stack);
8804 : :
8805 : : /* Check if profiling is active and we shall use profiling before
8806 : : prologue variant. If so sorry. */
8807 : 0 : if (crtl->profile && flag_fentry != 0)
8808 : 0 : sorry ("%<ms_hook_prologue%> attribute is not compatible "
8809 : : "with %<-mfentry%> for 32-bit");
8810 : :
8811 : : /* In ix86_asm_output_function_label we emitted:
8812 : : 8b ff movl.s %edi,%edi
8813 : : 55 push %ebp
8814 : : 8b ec movl.s %esp,%ebp
8815 : :
8816 : : This matches the hookable function prologue in Win32 API
8817 : : functions in Microsoft Windows XP Service Pack 2 and newer.
8818 : : Wine uses this to enable Windows apps to hook the Win32 API
8819 : : functions provided by Wine.
8820 : :
8821 : : What that means is that we've already set up the frame pointer. */
8822 : :
8823 : 0 : if (frame_pointer_needed
8824 : 0 : && !(crtl->drap_reg && crtl->stack_realign_needed))
8825 : : {
8826 : 0 : rtx push, mov;
8827 : :
8828 : : /* We've decided to use the frame pointer already set up.
8829 : : Describe this to the unwinder by pretending that both
8830 : : push and mov insns happen right here.
8831 : :
8832 : : Putting the unwind info here at the end of the ms_hook
8833 : : is done so that we can make absolutely certain we get
8834 : : the required byte sequence at the start of the function,
8835 : : rather than relying on an assembler that can produce
8836 : : the exact encoding required.
8837 : :
8838 : : However it does mean (in the unpatched case) that we have
8839 : : a 1 insn window where the asynchronous unwind info is
8840 : : incorrect. However, if we placed the unwind info at
8841 : : its correct location we would have incorrect unwind info
8842 : : in the patched case. Which is probably all moot since
8843 : : I don't expect Wine generates dwarf2 unwind info for the
8844 : : system libraries that use this feature. */
8845 : :
8846 : 0 : insn = emit_insn (gen_blockage ());
8847 : :
8848 : 0 : push = gen_push (hard_frame_pointer_rtx);
8849 : 0 : mov = gen_rtx_SET (hard_frame_pointer_rtx,
8850 : : stack_pointer_rtx);
8851 : 0 : RTX_FRAME_RELATED_P (push) = 1;
8852 : 0 : RTX_FRAME_RELATED_P (mov) = 1;
8853 : :
8854 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
8855 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
8856 : : gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
8857 : :
8858 : : /* Note that gen_push incremented m->fs.cfa_offset, even
8859 : : though we didn't emit the push insn here. */
8860 : 0 : m->fs.cfa_reg = hard_frame_pointer_rtx;
8861 : 0 : m->fs.fp_offset = m->fs.cfa_offset;
8862 : 0 : m->fs.fp_valid = true;
8863 : 0 : }
8864 : : else
8865 : : {
8866 : : /* The frame pointer is not needed so pop %ebp again.
8867 : : This leaves us with a pristine state. */
8868 : 0 : emit_insn (gen_pop (hard_frame_pointer_rtx));
8869 : : }
8870 : : }
8871 : :
8872 : : /* The first insn of a function that accepts its static chain on the
8873 : : stack is to push the register that would be filled in by a direct
8874 : : call. This insn will be skipped by the trampoline. */
8875 : 1392283 : else if (ix86_static_chain_on_stack)
8876 : : {
8877 : 0 : static_chain = ix86_static_chain (cfun->decl, false);
8878 : 0 : insn = emit_insn (gen_push (static_chain));
8879 : 0 : emit_insn (gen_blockage ());
8880 : :
8881 : : /* We don't want to interpret this push insn as a register save,
8882 : : only as a stack adjustment. The real copy of the register as
8883 : : a save will be done later, if needed. */
8884 : 0 : t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
8885 : 0 : t = gen_rtx_SET (stack_pointer_rtx, t);
8886 : 0 : add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
8887 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
8888 : : }
8889 : :
8890 : : /* Emit prologue code to adjust stack alignment and setup DRAP, in case
8891 : : of DRAP is needed and stack realignment is really needed after reload */
8892 : 1392283 : if (stack_realign_drap)
8893 : : {
8894 : 6840 : int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
8895 : :
8896 : : /* Can't use DRAP in interrupt function. */
8897 : 6840 : if (cfun->machine->func_type != TYPE_NORMAL)
8898 : 0 : sorry ("Dynamic Realign Argument Pointer (DRAP) not supported "
8899 : : "in interrupt service routine. This may be worked "
8900 : : "around by avoiding functions with aggregate return.");
8901 : :
8902 : : /* Only need to push parameter pointer reg if it is caller saved. */
8903 : 6840 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
8904 : : {
8905 : : /* Push arg pointer reg */
8906 : 142 : insn = emit_insn (gen_push (crtl->drap_reg));
8907 : 142 : RTX_FRAME_RELATED_P (insn) = 1;
8908 : : }
8909 : :
8910 : : /* Grab the argument pointer. */
8911 : 6840 : t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
8912 : 6840 : insn = emit_insn (gen_rtx_SET (crtl->drap_reg, t));
8913 : 6840 : RTX_FRAME_RELATED_P (insn) = 1;
8914 : 6840 : m->fs.cfa_reg = crtl->drap_reg;
8915 : 6840 : m->fs.cfa_offset = 0;
8916 : :
8917 : : /* Align the stack. */
8918 : 6840 : insn = emit_insn (gen_and2_insn (stack_pointer_rtx,
8919 : 6840 : GEN_INT (-align_bytes)));
8920 : 6840 : RTX_FRAME_RELATED_P (insn) = 1;
8921 : :
8922 : : /* Replicate the return address on the stack so that return
8923 : : address can be reached via (argp - 1) slot. This is needed
8924 : : to implement macro RETURN_ADDR_RTX and intrinsic function
8925 : : expand_builtin_return_addr etc. */
8926 : 7125 : t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
8927 : 6840 : t = gen_frame_mem (word_mode, t);
8928 : 6840 : insn = emit_insn (gen_push (t));
8929 : 6840 : RTX_FRAME_RELATED_P (insn) = 1;
8930 : :
8931 : : /* For the purposes of frame and register save area addressing,
8932 : : we've started over with a new frame. */
8933 : 6840 : m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
8934 : 6840 : m->fs.realigned = true;
8935 : :
8936 : 6840 : if (static_chain)
8937 : : {
8938 : : /* Replicate static chain on the stack so that static chain
8939 : : can be reached via (argp - 2) slot. This is needed for
8940 : : nested function with stack realignment. */
8941 : 0 : insn = emit_insn (gen_push (static_chain));
8942 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
8943 : : }
8944 : : }
8945 : :
8946 : 1392283 : int_registers_saved = (frame.nregs == 0);
8947 : 1392283 : sse_registers_saved = (frame.nsseregs == 0);
8948 : 1392283 : save_stub_call_needed = (m->call_ms2sysv);
8949 : 1392283 : gcc_assert (sse_registers_saved || !save_stub_call_needed);
8950 : :
8951 : 1392283 : if (frame_pointer_needed && !m->fs.fp_valid)
8952 : : {
8953 : : /* Note: AT&T enter does NOT have reversed args. Enter is probably
8954 : : slower on all targets. Also sdb didn't like it. */
8955 : 459493 : insn = emit_insn (gen_push (hard_frame_pointer_rtx));
8956 : 459493 : RTX_FRAME_RELATED_P (insn) = 1;
8957 : :
8958 : 459493 : if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
8959 : : {
8960 : 459493 : insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
8961 : 459493 : RTX_FRAME_RELATED_P (insn) = 1;
8962 : :
8963 : 459493 : if (m->fs.cfa_reg == stack_pointer_rtx)
8964 : 452653 : m->fs.cfa_reg = hard_frame_pointer_rtx;
8965 : 459493 : m->fs.fp_offset = m->fs.sp_offset;
8966 : 459493 : m->fs.fp_valid = true;
8967 : : }
8968 : : }
8969 : :
8970 : 1392283 : if (!int_registers_saved)
8971 : : {
8972 : : /* If saving registers via PUSH, do so now. */
8973 : 431474 : if (!frame.save_regs_using_mov)
8974 : : {
8975 : 431411 : ix86_emit_save_regs ();
8976 : 431411 : int_registers_saved = true;
8977 : 431411 : gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
8978 : : }
8979 : :
8980 : : /* When using red zone we may start register saving before allocating
8981 : : the stack frame saving one cycle of the prologue. However, avoid
8982 : : doing this if we have to probe the stack; at least on x86_64 the
8983 : : stack probe can turn into a call that clobbers a red zone location. */
8984 : 63 : else if (ix86_using_red_zone ()
8985 : 63 : && (! TARGET_STACK_PROBE
8986 : 0 : || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
8987 : : {
8988 : 59 : ix86_emit_save_regs_using_mov (frame.reg_save_offset);
8989 : 59 : cfun->machine->red_zone_used = true;
8990 : 59 : int_registers_saved = true;
8991 : : }
8992 : : }
8993 : :
8994 : 1392283 : if (frame.red_zone_size != 0)
8995 : 133924 : cfun->machine->red_zone_used = true;
8996 : :
8997 : 1392283 : if (stack_realign_fp)
8998 : : {
8999 : 22727 : int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
9000 : 23078 : gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
9001 : :
9002 : : /* Record last valid frame pointer offset. */
9003 : 22727 : m->fs.sp_realigned_fp_last = frame.reg_save_offset;
9004 : :
9005 : : /* The computation of the size of the re-aligned stack frame means
9006 : : that we must allocate the size of the register save area before
9007 : : performing the actual alignment. Otherwise we cannot guarantee
9008 : : that there's enough storage above the realignment point. */
9009 : 22727 : allocate = frame.reg_save_offset - m->fs.sp_offset
9010 : 22727 : + frame.stack_realign_allocate;
9011 : 22727 : if (allocate)
9012 : 2699 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9013 : : GEN_INT (-allocate), -1, false);
9014 : :
9015 : : /* Align the stack. */
9016 : 22727 : emit_insn (gen_and2_insn (stack_pointer_rtx, GEN_INT (-align_bytes)));
9017 : 22727 : m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes);
9018 : 22727 : m->fs.sp_realigned_offset = m->fs.sp_offset
9019 : 22727 : - frame.stack_realign_allocate;
9020 : : /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset.
9021 : : Beyond this point, stack access should be done via choose_baseaddr or
9022 : : by using sp_valid_at and fp_valid_at to determine the correct base
9023 : : register. Henceforth, any CFA offset should be thought of as logical
9024 : : and not physical. */
9025 : 22727 : gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last);
9026 : 22727 : gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset);
9027 : 22727 : m->fs.sp_realigned = true;
9028 : :
9029 : : /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which
9030 : : is needed to describe where a register is saved using a realigned
9031 : : stack pointer, so we need to invalidate the stack pointer for that
9032 : : target. */
9033 : 22727 : if (TARGET_SEH)
9034 : : m->fs.sp_valid = false;
9035 : :
9036 : : /* If SP offset is non-immediate after allocation of the stack frame,
9037 : : then emit SSE saves or stub call prior to allocating the rest of the
9038 : : stack frame. This is less efficient for the out-of-line stub because
9039 : : we can't combine allocations across the call barrier, but it's better
9040 : : than using a scratch register. */
9041 : 22727 : else if (!x86_64_immediate_operand (GEN_INT (frame.stack_pointer_offset
9042 : : - m->fs.sp_realigned_offset),
9043 : 22727 : Pmode))
9044 : : {
9045 : 3 : if (!sse_registers_saved)
9046 : : {
9047 : 1 : ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
9048 : 1 : sse_registers_saved = true;
9049 : : }
9050 : 2 : else if (save_stub_call_needed)
9051 : : {
9052 : 1 : ix86_emit_outlined_ms2sysv_save (frame);
9053 : 1 : save_stub_call_needed = false;
9054 : : }
9055 : : }
9056 : : }
9057 : :
9058 : 1392283 : allocate = frame.stack_pointer_offset - m->fs.sp_offset;
9059 : :
9060 : 1392283 : if (flag_stack_usage_info)
9061 : : {
9062 : : /* We start to count from ARG_POINTER. */
9063 : 357 : HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
9064 : :
9065 : : /* If it was realigned, take into account the fake frame. */
9066 : 357 : if (stack_realign_drap)
9067 : : {
9068 : 1 : if (ix86_static_chain_on_stack)
9069 : 0 : stack_size += UNITS_PER_WORD;
9070 : :
9071 : 1 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
9072 : 0 : stack_size += UNITS_PER_WORD;
9073 : :
9074 : : /* This over-estimates by 1 minimal-stack-alignment-unit but
9075 : : mitigates that by counting in the new return address slot. */
9076 : 1 : current_function_dynamic_stack_size
9077 : 1 : += crtl->stack_alignment_needed / BITS_PER_UNIT;
9078 : : }
9079 : :
9080 : 357 : current_function_static_stack_size = stack_size;
9081 : : }
9082 : :
9083 : : /* On SEH target with very large frame size, allocate an area to save
9084 : : SSE registers (as the very large allocation won't be described). */
9085 : 1392283 : if (TARGET_SEH
9086 : : && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
9087 : : && !sse_registers_saved)
9088 : : {
9089 : : HOST_WIDE_INT sse_size
9090 : : = frame.sse_reg_save_offset - frame.reg_save_offset;
9091 : :
9092 : : gcc_assert (int_registers_saved);
9093 : :
9094 : : /* No need to do stack checking as the area will be immediately
9095 : : written. */
9096 : : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9097 : : GEN_INT (-sse_size), -1,
9098 : : m->fs.cfa_reg == stack_pointer_rtx);
9099 : : allocate -= sse_size;
9100 : : ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
9101 : : sse_registers_saved = true;
9102 : : }
9103 : :
9104 : : /* If stack clash protection is requested, then probe the stack, unless it
9105 : : is already probed on the target. */
9106 : 1392283 : if (allocate >= 0
9107 : 1392279 : && flag_stack_clash_protection
9108 : 1392367 : && !ix86_target_stack_probe ())
9109 : : {
9110 : 84 : ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
9111 : 84 : allocate = 0;
9112 : : }
9113 : :
9114 : : /* The stack has already been decremented by the instruction calling us
9115 : : so probe if the size is non-negative to preserve the protection area. */
9116 : 1392199 : else if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
9117 : : {
9118 : 47 : const HOST_WIDE_INT probe_interval = get_probe_interval ();
9119 : :
9120 : 47 : if (STACK_CHECK_MOVING_SP)
9121 : : {
9122 : 47 : if (crtl->is_leaf
9123 : 18 : && !cfun->calls_alloca
9124 : 18 : && allocate <= probe_interval)
9125 : : ;
9126 : :
9127 : : else
9128 : : {
9129 : 30 : ix86_adjust_stack_and_probe (allocate, int_registers_saved, true);
9130 : 30 : allocate = 0;
9131 : : }
9132 : : }
9133 : :
9134 : : else
9135 : : {
9136 : : HOST_WIDE_INT size = allocate;
9137 : :
9138 : : if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
9139 : : size = 0x80000000 - get_stack_check_protect () - 1;
9140 : :
9141 : : if (TARGET_STACK_PROBE)
9142 : : {
9143 : : if (crtl->is_leaf && !cfun->calls_alloca)
9144 : : {
9145 : : if (size > probe_interval)
9146 : : ix86_emit_probe_stack_range (0, size, int_registers_saved);
9147 : : }
9148 : : else
9149 : : ix86_emit_probe_stack_range (0,
9150 : : size + get_stack_check_protect (),
9151 : : int_registers_saved);
9152 : : }
9153 : : else
9154 : : {
9155 : : if (crtl->is_leaf && !cfun->calls_alloca)
9156 : : {
9157 : : if (size > probe_interval
9158 : : && size > get_stack_check_protect ())
9159 : : ix86_emit_probe_stack_range (get_stack_check_protect (),
9160 : : (size
9161 : : - get_stack_check_protect ()),
9162 : : int_registers_saved);
9163 : : }
9164 : : else
9165 : : ix86_emit_probe_stack_range (get_stack_check_protect (), size,
9166 : : int_registers_saved);
9167 : : }
9168 : : }
9169 : : }
9170 : :
9171 : 1392279 : if (allocate == 0)
9172 : : ;
9173 : 782497 : else if (!ix86_target_stack_probe ()
9174 : 782497 : || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
9175 : : {
9176 : 782453 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9177 : : GEN_INT (-allocate), -1,
9178 : 782453 : m->fs.cfa_reg == stack_pointer_rtx);
9179 : : }
9180 : : else
9181 : : {
9182 : 44 : rtx eax = gen_rtx_REG (Pmode, AX_REG);
9183 : 44 : rtx r10 = NULL;
9184 : 44 : const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
9185 : 44 : bool eax_live = ix86_eax_live_at_start_p ();
9186 : 44 : bool r10_live = false;
9187 : :
9188 : 44 : if (TARGET_64BIT)
9189 : 44 : r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
9190 : :
9191 : 44 : if (eax_live)
9192 : : {
9193 : 0 : insn = emit_insn (gen_push (eax));
9194 : 0 : allocate -= UNITS_PER_WORD;
9195 : : /* Note that SEH directives need to continue tracking the stack
9196 : : pointer even after the frame pointer has been set up. */
9197 : 0 : if (sp_is_cfa_reg || TARGET_SEH)
9198 : : {
9199 : 0 : if (sp_is_cfa_reg)
9200 : 0 : m->fs.cfa_offset += UNITS_PER_WORD;
9201 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9202 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9203 : 0 : gen_rtx_SET (stack_pointer_rtx,
9204 : : plus_constant (Pmode,
9205 : : stack_pointer_rtx,
9206 : : -UNITS_PER_WORD)));
9207 : : }
9208 : : }
9209 : :
9210 : 44 : if (r10_live)
9211 : : {
9212 : 0 : r10 = gen_rtx_REG (Pmode, R10_REG);
9213 : 0 : insn = emit_insn (gen_push (r10));
9214 : 0 : allocate -= UNITS_PER_WORD;
9215 : 0 : if (sp_is_cfa_reg || TARGET_SEH)
9216 : : {
9217 : 0 : if (sp_is_cfa_reg)
9218 : 0 : m->fs.cfa_offset += UNITS_PER_WORD;
9219 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9220 : 0 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9221 : 0 : gen_rtx_SET (stack_pointer_rtx,
9222 : : plus_constant (Pmode,
9223 : : stack_pointer_rtx,
9224 : : -UNITS_PER_WORD)));
9225 : : }
9226 : : }
9227 : :
9228 : 44 : emit_move_insn (eax, GEN_INT (allocate));
9229 : 44 : emit_insn (gen_allocate_stack_worker_probe (Pmode, eax, eax));
9230 : :
9231 : : /* Use the fact that AX still contains ALLOCATE. */
9232 : 44 : insn = emit_insn (gen_pro_epilogue_adjust_stack_sub
9233 : 44 : (Pmode, stack_pointer_rtx, stack_pointer_rtx, eax));
9234 : :
9235 : 44 : if (sp_is_cfa_reg || TARGET_SEH)
9236 : : {
9237 : 36 : if (sp_is_cfa_reg)
9238 : 36 : m->fs.cfa_offset += allocate;
9239 : 36 : RTX_FRAME_RELATED_P (insn) = 1;
9240 : 36 : add_reg_note (insn, REG_FRAME_RELATED_EXPR,
9241 : 36 : gen_rtx_SET (stack_pointer_rtx,
9242 : : plus_constant (Pmode, stack_pointer_rtx,
9243 : : -allocate)));
9244 : : }
9245 : 44 : m->fs.sp_offset += allocate;
9246 : :
9247 : : /* Use stack_pointer_rtx for relative addressing so that code works for
9248 : : realigned stack. But this means that we need a blockage to prevent
9249 : : stores based on the frame pointer from being scheduled before. */
9250 : 44 : if (r10_live && eax_live)
9251 : : {
9252 : 0 : t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
9253 : 0 : emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
9254 : : gen_frame_mem (word_mode, t));
9255 : 0 : t = plus_constant (Pmode, t, UNITS_PER_WORD);
9256 : 0 : emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
9257 : : gen_frame_mem (word_mode, t));
9258 : 0 : emit_insn (gen_memory_blockage ());
9259 : : }
9260 : 44 : else if (eax_live || r10_live)
9261 : : {
9262 : 0 : t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
9263 : 0 : emit_move_insn (gen_rtx_REG (word_mode,
9264 : : (eax_live ? AX_REG : R10_REG)),
9265 : : gen_frame_mem (word_mode, t));
9266 : 0 : emit_insn (gen_memory_blockage ());
9267 : : }
9268 : : }
9269 : 1392283 : gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
9270 : :
9271 : : /* If we havn't already set up the frame pointer, do so now. */
9272 : 1392283 : if (frame_pointer_needed && !m->fs.fp_valid)
9273 : : {
9274 : 0 : insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
9275 : 0 : GEN_INT (frame.stack_pointer_offset
9276 : : - frame.hard_frame_pointer_offset));
9277 : 0 : insn = emit_insn (insn);
9278 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9279 : 0 : add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
9280 : :
9281 : 0 : if (m->fs.cfa_reg == stack_pointer_rtx)
9282 : 0 : m->fs.cfa_reg = hard_frame_pointer_rtx;
9283 : 0 : m->fs.fp_offset = frame.hard_frame_pointer_offset;
9284 : 0 : m->fs.fp_valid = true;
9285 : : }
9286 : :
9287 : 1392283 : if (!int_registers_saved)
9288 : 4 : ix86_emit_save_regs_using_mov (frame.reg_save_offset);
9289 : 1392283 : if (!sse_registers_saved)
9290 : 33152 : ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
9291 : 1359131 : else if (save_stub_call_needed)
9292 : 7044 : ix86_emit_outlined_ms2sysv_save (frame);
9293 : :
9294 : : /* For the mcount profiling on 32 bit PIC mode we need to emit SET_GOT
9295 : : in PROLOGUE. */
9296 : 1392283 : if (!TARGET_64BIT && pic_offset_table_rtx && crtl->profile && !flag_fentry)
9297 : : {
9298 : 0 : rtx pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
9299 : 0 : insn = emit_insn (gen_set_got (pic));
9300 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9301 : 0 : add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
9302 : 0 : emit_insn (gen_prologue_use (pic));
9303 : : /* Deleting already emmitted SET_GOT if exist and allocated to
9304 : : REAL_PIC_OFFSET_TABLE_REGNUM. */
9305 : 0 : ix86_elim_entry_set_got (pic);
9306 : : }
9307 : :
9308 : 1392283 : if (crtl->drap_reg && !crtl->stack_realign_needed)
9309 : : {
9310 : : /* vDRAP is setup but after reload it turns out stack realign
9311 : : isn't necessary, here we will emit prologue to setup DRAP
9312 : : without stack realign adjustment */
9313 : 157 : t = choose_baseaddr (0, NULL);
9314 : 157 : emit_insn (gen_rtx_SET (crtl->drap_reg, t));
9315 : : }
9316 : :
9317 : : /* Prevent instructions from being scheduled into register save push
9318 : : sequence when access to the redzone area is done through frame pointer.
9319 : : The offset between the frame pointer and the stack pointer is calculated
9320 : : relative to the value of the stack pointer at the end of the function
9321 : : prologue, and moving instructions that access redzone area via frame
9322 : : pointer inside push sequence violates this assumption. */
9323 : 1392283 : if (frame_pointer_needed && frame.red_zone_size)
9324 : 121875 : emit_insn (gen_memory_blockage ());
9325 : :
9326 : : /* SEH requires that the prologue end within 256 bytes of the start of
9327 : : the function. Prevent instruction schedules that would extend that.
9328 : : Further, prevent alloca modifications to the stack pointer from being
9329 : : combined with prologue modifications. */
9330 : : if (TARGET_SEH)
9331 : : emit_insn (gen_prologue_use (stack_pointer_rtx));
9332 : : }
9333 : :
9334 : : /* Emit code to restore REG using a POP or POPP insn. */
9335 : :
9336 : : static void
9337 : 1564773 : ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
9338 : : {
9339 : 1564773 : struct machine_function *m = cfun->machine;
9340 : 1564773 : rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
9341 : :
9342 : 1564773 : ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
9343 : 1564773 : m->fs.sp_offset -= UNITS_PER_WORD;
9344 : :
9345 : 1564773 : if (m->fs.cfa_reg == crtl->drap_reg
9346 : 1564773 : && REGNO (reg) == REGNO (crtl->drap_reg))
9347 : : {
9348 : : /* Previously we'd represented the CFA as an expression
9349 : : like *(%ebp - 8). We've just popped that value from
9350 : : the stack, which means we need to reset the CFA to
9351 : : the drap register. This will remain until we restore
9352 : : the stack pointer. */
9353 : 4185 : add_reg_note (insn, REG_CFA_DEF_CFA, reg);
9354 : 4185 : RTX_FRAME_RELATED_P (insn) = 1;
9355 : :
9356 : : /* This means that the DRAP register is valid for addressing too. */
9357 : 4185 : m->fs.drap_valid = true;
9358 : 4185 : return;
9359 : : }
9360 : :
9361 : 1560588 : if (m->fs.cfa_reg == stack_pointer_rtx)
9362 : : {
9363 : 1336501 : rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
9364 : 1128239 : x = gen_rtx_SET (stack_pointer_rtx, x);
9365 : 1128239 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
9366 : 1128239 : RTX_FRAME_RELATED_P (insn) = 1;
9367 : :
9368 : 1336501 : m->fs.cfa_offset -= UNITS_PER_WORD;
9369 : : }
9370 : :
9371 : : /* When the frame pointer is the CFA, and we pop it, we are
9372 : : swapping back to the stack pointer as the CFA. This happens
9373 : : for stack frames that don't allocate other data, so we assume
9374 : : the stack pointer is now pointing at the return address, i.e.
9375 : : the function entry state, which makes the offset be 1 word. */
9376 : 1560588 : if (reg == hard_frame_pointer_rtx)
9377 : : {
9378 : 226792 : m->fs.fp_valid = false;
9379 : 226792 : if (m->fs.cfa_reg == hard_frame_pointer_rtx)
9380 : : {
9381 : 222592 : m->fs.cfa_reg = stack_pointer_rtx;
9382 : 222592 : m->fs.cfa_offset -= UNITS_PER_WORD;
9383 : :
9384 : 222592 : add_reg_note (insn, REG_CFA_DEF_CFA,
9385 : 222592 : plus_constant (Pmode, stack_pointer_rtx,
9386 : 222592 : m->fs.cfa_offset));
9387 : 222592 : RTX_FRAME_RELATED_P (insn) = 1;
9388 : : }
9389 : : }
9390 : : }
9391 : :
9392 : : /* Emit code to restore REG using a POP2 insn. */
9393 : : static void
9394 : 15 : ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
9395 : : {
9396 : 15 : struct machine_function *m = cfun->machine;
9397 : 15 : const int offset = UNITS_PER_WORD * 2;
9398 : 15 : rtx_insn *insn;
9399 : :
9400 : 15 : rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
9401 : : stack_pointer_rtx));
9402 : :
9403 : 15 : if (ppx_p)
9404 : 11 : insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
9405 : : else
9406 : 4 : insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
9407 : :
9408 : 15 : RTX_FRAME_RELATED_P (insn) = 1;
9409 : :
9410 : 15 : rtx dwarf = NULL_RTX;
9411 : 15 : dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf);
9412 : 15 : dwarf = alloc_reg_note (REG_CFA_RESTORE, reg2, dwarf);
9413 : 15 : REG_NOTES (insn) = dwarf;
9414 : 15 : m->fs.sp_offset -= offset;
9415 : :
9416 : 15 : if (m->fs.cfa_reg == crtl->drap_reg
9417 : 15 : && (REGNO (reg1) == REGNO (crtl->drap_reg)
9418 : 3 : || REGNO (reg2) == REGNO (crtl->drap_reg)))
9419 : : {
9420 : : /* Previously we'd represented the CFA as an expression
9421 : : like *(%ebp - 8). We've just popped that value from
9422 : : the stack, which means we need to reset the CFA to
9423 : : the drap register. This will remain until we restore
9424 : : the stack pointer. */
9425 : 1 : add_reg_note (insn, REG_CFA_DEF_CFA,
9426 : 1 : REGNO (reg1) == REGNO (crtl->drap_reg) ? reg1 : reg2);
9427 : 1 : RTX_FRAME_RELATED_P (insn) = 1;
9428 : :
9429 : : /* This means that the DRAP register is valid for addressing too. */
9430 : 1 : m->fs.drap_valid = true;
9431 : 1 : return;
9432 : : }
9433 : :
9434 : 14 : if (m->fs.cfa_reg == stack_pointer_rtx)
9435 : : {
9436 : 10 : rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
9437 : 10 : x = gen_rtx_SET (stack_pointer_rtx, x);
9438 : 10 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
9439 : 10 : RTX_FRAME_RELATED_P (insn) = 1;
9440 : :
9441 : 10 : m->fs.cfa_offset -= offset;
9442 : : }
9443 : :
9444 : : /* When the frame pointer is the CFA, and we pop it, we are
9445 : : swapping back to the stack pointer as the CFA. This happens
9446 : : for stack frames that don't allocate other data, so we assume
9447 : : the stack pointer is now pointing at the return address, i.e.
9448 : : the function entry state, which makes the offset be 1 word. */
9449 : 14 : if (reg1 == hard_frame_pointer_rtx || reg2 == hard_frame_pointer_rtx)
9450 : : {
9451 : 0 : m->fs.fp_valid = false;
9452 : 0 : if (m->fs.cfa_reg == hard_frame_pointer_rtx)
9453 : : {
9454 : 0 : m->fs.cfa_reg = stack_pointer_rtx;
9455 : 0 : m->fs.cfa_offset -= offset;
9456 : :
9457 : 0 : add_reg_note (insn, REG_CFA_DEF_CFA,
9458 : 0 : plus_constant (Pmode, stack_pointer_rtx,
9459 : 0 : m->fs.cfa_offset));
9460 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
9461 : : }
9462 : : }
9463 : : }
9464 : :
9465 : : /* Emit code to restore saved registers using POP insns. */
9466 : :
9467 : : static void
9468 : 1269402 : ix86_emit_restore_regs_using_pop (bool ppx_p)
9469 : : {
9470 : 1269402 : unsigned int regno;
9471 : :
9472 : 118054386 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9473 : 116784984 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
9474 : 1337728 : ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
9475 : 1269402 : }
9476 : :
9477 : : /* Emit code to restore saved registers using POP2 insns. */
9478 : :
9479 : : static void
9480 : 397 : ix86_emit_restore_regs_using_pop2 (void)
9481 : : {
9482 : 397 : int regno;
9483 : 397 : int regno_list[2];
9484 : 397 : regno_list[0] = regno_list[1] = -1;
9485 : 397 : int loaded_regnum = 0;
9486 : 397 : bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
9487 : :
9488 : 36921 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9489 : 36524 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
9490 : : {
9491 : 41 : if (aligned)
9492 : : {
9493 : 35 : regno_list[loaded_regnum++] = regno;
9494 : 35 : if (loaded_regnum == 2)
9495 : : {
9496 : 15 : gcc_assert (regno_list[0] != -1
9497 : : && regno_list[1] != -1
9498 : : && regno_list[0] != regno_list[1]);
9499 : :
9500 : 15 : ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
9501 : : regno_list[0]),
9502 : : gen_rtx_REG (word_mode,
9503 : : regno_list[1]),
9504 : 15 : TARGET_APX_PPX);
9505 : 15 : loaded_regnum = 0;
9506 : 15 : regno_list[0] = regno_list[1] = -1;
9507 : : }
9508 : : }
9509 : : else
9510 : : {
9511 : 12 : ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
9512 : 6 : TARGET_APX_PPX);
9513 : 6 : aligned = true;
9514 : : }
9515 : : }
9516 : :
9517 : 397 : if (loaded_regnum == 1)
9518 : 5 : ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
9519 : 5 : TARGET_APX_PPX);
9520 : 397 : }
9521 : :
9522 : : /* Emit code and notes for the LEAVE instruction. If insn is non-null,
9523 : : omits the emit and only attaches the notes. */
9524 : :
9525 : : static void
9526 : 233774 : ix86_emit_leave (rtx_insn *insn)
9527 : : {
9528 : 233774 : struct machine_function *m = cfun->machine;
9529 : :
9530 : 233774 : if (!insn)
9531 : 232643 : insn = emit_insn (gen_leave (word_mode));
9532 : :
9533 : 233774 : ix86_add_queued_cfa_restore_notes (insn);
9534 : :
9535 : 233774 : gcc_assert (m->fs.fp_valid);
9536 : 233774 : m->fs.sp_valid = true;
9537 : 233774 : m->fs.sp_realigned = false;
9538 : 233774 : m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
9539 : 233774 : m->fs.fp_valid = false;
9540 : :
9541 : 233774 : if (m->fs.cfa_reg == hard_frame_pointer_rtx)
9542 : : {
9543 : 231020 : m->fs.cfa_reg = stack_pointer_rtx;
9544 : 231020 : m->fs.cfa_offset = m->fs.sp_offset;
9545 : :
9546 : 231020 : add_reg_note (insn, REG_CFA_DEF_CFA,
9547 : 231020 : plus_constant (Pmode, stack_pointer_rtx,
9548 : 231020 : m->fs.sp_offset));
9549 : 231020 : RTX_FRAME_RELATED_P (insn) = 1;
9550 : : }
9551 : 233774 : ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
9552 : : m->fs.fp_offset);
9553 : 233774 : }
9554 : :
9555 : : /* Emit code to restore saved registers using MOV insns.
9556 : : First register is restored from CFA - CFA_OFFSET. */
9557 : : static void
9558 : 41621 : ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
9559 : : bool maybe_eh_return)
9560 : : {
9561 : 41621 : struct machine_function *m = cfun->machine;
9562 : 41621 : unsigned int regno;
9563 : :
9564 : 3870753 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9565 : 3829132 : if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
9566 : : {
9567 : 41840 : rtx reg = gen_rtx_REG (word_mode, regno);
9568 : 41840 : rtx mem;
9569 : 41840 : rtx_insn *insn;
9570 : :
9571 : 41840 : mem = choose_baseaddr (cfa_offset, NULL);
9572 : 41840 : mem = gen_frame_mem (word_mode, mem);
9573 : 41840 : insn = emit_move_insn (reg, mem);
9574 : :
9575 : 41840 : if (m->fs.cfa_reg == crtl->drap_reg && regno == REGNO (crtl->drap_reg))
9576 : : {
9577 : : /* Previously we'd represented the CFA as an expression
9578 : : like *(%ebp - 8). We've just popped that value from
9579 : : the stack, which means we need to reset the CFA to
9580 : : the drap register. This will remain until we restore
9581 : : the stack pointer. */
9582 : 2754 : add_reg_note (insn, REG_CFA_DEF_CFA, reg);
9583 : 2754 : RTX_FRAME_RELATED_P (insn) = 1;
9584 : :
9585 : : /* This means that the DRAP register is valid for addressing. */
9586 : 2754 : m->fs.drap_valid = true;
9587 : : }
9588 : : else
9589 : 39086 : ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
9590 : :
9591 : 43669 : cfa_offset -= UNITS_PER_WORD;
9592 : : }
9593 : 41621 : }
9594 : :
9595 : : /* Emit code to restore saved registers using MOV insns.
9596 : : First register is restored from CFA - CFA_OFFSET. */
9597 : : static void
9598 : 33729 : ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
9599 : : bool maybe_eh_return)
9600 : : {
9601 : 33729 : unsigned int regno;
9602 : :
9603 : 3136797 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
9604 : 3103068 : if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
9605 : : {
9606 : 337281 : rtx reg = gen_rtx_REG (V4SFmode, regno);
9607 : 337281 : rtx mem;
9608 : 337281 : unsigned int align = GET_MODE_ALIGNMENT (V4SFmode);
9609 : :
9610 : 337281 : mem = choose_baseaddr (cfa_offset, &align);
9611 : 337281 : mem = gen_rtx_MEM (V4SFmode, mem);
9612 : :
9613 : : /* The location aligment depends upon the base register. */
9614 : 337281 : align = MIN (GET_MODE_ALIGNMENT (V4SFmode), align);
9615 : 337281 : gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
9616 : 337281 : set_mem_align (mem, align);
9617 : 337281 : emit_insn (gen_rtx_SET (reg, mem));
9618 : :
9619 : 337281 : ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
9620 : :
9621 : 337281 : cfa_offset -= GET_MODE_SIZE (V4SFmode);
9622 : : }
9623 : 33729 : }
9624 : :
9625 : : static void
9626 : 7621 : ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
9627 : : bool use_call, int style)
9628 : : {
9629 : 7621 : struct machine_function *m = cfun->machine;
9630 : 7621 : const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
9631 : 7621 : + m->call_ms2sysv_extra_regs;
9632 : 7621 : rtvec v;
9633 : 7621 : unsigned int elems_needed, align, i, vi = 0;
9634 : 7621 : rtx_insn *insn;
9635 : 7621 : rtx sym, tmp;
9636 : 7621 : rtx rsi = gen_rtx_REG (word_mode, SI_REG);
9637 : 7621 : rtx r10 = NULL_RTX;
9638 : 7621 : const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
9639 : 7621 : HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
9640 : 7621 : HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
9641 : 7621 : rtx rsi_frame_load = NULL_RTX;
9642 : 7621 : HOST_WIDE_INT rsi_restore_offset = (HOST_WIDE_INT)-1;
9643 : 7621 : enum xlogue_stub stub;
9644 : :
9645 : 7621 : gcc_assert (!m->fs.fp_valid || frame_pointer_needed);
9646 : :
9647 : : /* If using a realigned stack, we should never start with padding. */
9648 : 7621 : gcc_assert (!stack_realign_fp || !xlogue.get_stack_align_off_in ());
9649 : :
9650 : : /* Setup RSI as the stub's base pointer. */
9651 : 7621 : align = GET_MODE_ALIGNMENT (V4SFmode);
9652 : 7621 : tmp = choose_baseaddr (rsi_offset, &align, SI_REG);
9653 : 7621 : gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
9654 : :
9655 : 7621 : emit_insn (gen_rtx_SET (rsi, tmp));
9656 : :
9657 : : /* Get a symbol for the stub. */
9658 : 7621 : if (frame_pointer_needed)
9659 : 5955 : stub = use_call ? XLOGUE_STUB_RESTORE_HFP
9660 : : : XLOGUE_STUB_RESTORE_HFP_TAIL;
9661 : : else
9662 : 1666 : stub = use_call ? XLOGUE_STUB_RESTORE
9663 : : : XLOGUE_STUB_RESTORE_TAIL;
9664 : 7621 : sym = xlogue.get_stub_rtx (stub);
9665 : :
9666 : 7621 : elems_needed = ncregs;
9667 : 7621 : if (use_call)
9668 : 6298 : elems_needed += 1;
9669 : : else
9670 : 1515 : elems_needed += frame_pointer_needed ? 5 : 3;
9671 : 7621 : v = rtvec_alloc (elems_needed);
9672 : :
9673 : : /* We call the epilogue stub when we need to pop incoming args or we are
9674 : : doing a sibling call as the tail. Otherwise, we will emit a jmp to the
9675 : : epilogue stub and it is the tail-call. */
9676 : 7621 : if (use_call)
9677 : 6298 : RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
9678 : : else
9679 : : {
9680 : 1323 : RTVEC_ELT (v, vi++) = ret_rtx;
9681 : 1323 : RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
9682 : 1323 : if (frame_pointer_needed)
9683 : : {
9684 : 1131 : rtx rbp = gen_rtx_REG (DImode, BP_REG);
9685 : 1131 : gcc_assert (m->fs.fp_valid);
9686 : 1131 : gcc_assert (m->fs.cfa_reg == hard_frame_pointer_rtx);
9687 : :
9688 : 1131 : tmp = plus_constant (DImode, rbp, 8);
9689 : 1131 : RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, tmp);
9690 : 1131 : RTVEC_ELT (v, vi++) = gen_rtx_SET (rbp, gen_rtx_MEM (DImode, rbp));
9691 : 1131 : tmp = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
9692 : 1131 : RTVEC_ELT (v, vi++) = gen_rtx_CLOBBER (VOIDmode, tmp);
9693 : : }
9694 : : else
9695 : : {
9696 : : /* If no hard frame pointer, we set R10 to the SP restore value. */
9697 : 192 : gcc_assert (!m->fs.fp_valid);
9698 : 192 : gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
9699 : 192 : gcc_assert (m->fs.sp_valid);
9700 : :
9701 : 192 : r10 = gen_rtx_REG (DImode, R10_REG);
9702 : 192 : tmp = plus_constant (Pmode, rsi, stub_ptr_offset);
9703 : 192 : emit_insn (gen_rtx_SET (r10, tmp));
9704 : :
9705 : 192 : RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, r10);
9706 : : }
9707 : : }
9708 : :
9709 : : /* Generate frame load insns and restore notes. */
9710 : 110586 : for (i = 0; i < ncregs; ++i)
9711 : : {
9712 : 102965 : const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
9713 : 102965 : machine_mode mode = SSE_REGNO_P (r.regno) ? V4SFmode : word_mode;
9714 : 102965 : rtx reg, frame_load;
9715 : :
9716 : 102965 : reg = gen_rtx_REG (mode, r.regno);
9717 : 102965 : frame_load = gen_frame_load (reg, rsi, r.offset);
9718 : :
9719 : : /* Save RSI frame load insn & note to add last. */
9720 : 102965 : if (r.regno == SI_REG)
9721 : : {
9722 : 7621 : gcc_assert (!rsi_frame_load);
9723 : 7621 : rsi_frame_load = frame_load;
9724 : 7621 : rsi_restore_offset = r.offset;
9725 : : }
9726 : : else
9727 : : {
9728 : 95344 : RTVEC_ELT (v, vi++) = frame_load;
9729 : 95344 : ix86_add_cfa_restore_note (NULL, reg, r.offset);
9730 : : }
9731 : : }
9732 : :
9733 : : /* Add RSI frame load & restore note at the end. */
9734 : 7621 : gcc_assert (rsi_frame_load);
9735 : 7621 : gcc_assert (rsi_restore_offset != (HOST_WIDE_INT)-1);
9736 : 7621 : RTVEC_ELT (v, vi++) = rsi_frame_load;
9737 : 7621 : ix86_add_cfa_restore_note (NULL, gen_rtx_REG (DImode, SI_REG),
9738 : : rsi_restore_offset);
9739 : :
9740 : : /* Finally, for tail-call w/o a hard frame pointer, set SP to R10. */
9741 : 7621 : if (!use_call && !frame_pointer_needed)
9742 : : {
9743 : 192 : gcc_assert (m->fs.sp_valid);
9744 : 192 : gcc_assert (!m->fs.sp_realigned);
9745 : :
9746 : : /* At this point, R10 should point to frame.stack_realign_offset. */
9747 : 192 : if (m->fs.cfa_reg == stack_pointer_rtx)
9748 : 192 : m->fs.cfa_offset += m->fs.sp_offset - frame.stack_realign_offset;
9749 : 192 : m->fs.sp_offset = frame.stack_realign_offset;
9750 : : }
9751 : :
9752 : 7621 : gcc_assert (vi == (unsigned int)GET_NUM_ELEM (v));
9753 : 7621 : tmp = gen_rtx_PARALLEL (VOIDmode, v);
9754 : 7621 : if (use_call)
9755 : 6298 : insn = emit_insn (tmp);
9756 : : else
9757 : : {
9758 : 1323 : insn = emit_jump_insn (tmp);
9759 : 1323 : JUMP_LABEL (insn) = ret_rtx;
9760 : :
9761 : 1323 : if (frame_pointer_needed)
9762 : 1131 : ix86_emit_leave (insn);
9763 : : else
9764 : : {
9765 : : /* Need CFA adjust note. */
9766 : 192 : tmp = gen_rtx_SET (stack_pointer_rtx, r10);
9767 : 192 : add_reg_note (insn, REG_CFA_ADJUST_CFA, tmp);
9768 : : }
9769 : : }
9770 : :
9771 : 7621 : RTX_FRAME_RELATED_P (insn) = true;
9772 : 7621 : ix86_add_queued_cfa_restore_notes (insn);
9773 : :
9774 : : /* If we're not doing a tail-call, we need to adjust the stack. */
9775 : 7621 : if (use_call && m->fs.sp_valid)
9776 : : {
9777 : 3586 : HOST_WIDE_INT dealloc = m->fs.sp_offset - frame.stack_realign_offset;
9778 : 3586 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9779 : : GEN_INT (dealloc), style,
9780 : 3586 : m->fs.cfa_reg == stack_pointer_rtx);
9781 : : }
9782 : 7621 : }
9783 : :
9784 : : /* Restore function stack, frame, and registers. */
9785 : :
9786 : : void
9787 : 1504021 : ix86_expand_epilogue (int style)
9788 : : {
9789 : 1504021 : struct machine_function *m = cfun->machine;
9790 : 1504021 : struct machine_frame_state frame_state_save = m->fs;
9791 : 1504021 : bool restore_regs_via_mov;
9792 : 1504021 : bool using_drap;
9793 : 1504021 : bool restore_stub_is_tail = false;
9794 : :
9795 : 1504021 : if (ix86_function_naked (current_function_decl))
9796 : : {
9797 : : /* The program should not reach this point. */
9798 : 77 : emit_insn (gen_ud2 ());
9799 : 111787 : return;
9800 : : }
9801 : :
9802 : 1503944 : ix86_finalize_stack_frame_flags ();
9803 : 1503944 : const struct ix86_frame &frame = cfun->machine->frame;
9804 : :
9805 : 1503944 : m->fs.sp_realigned = stack_realign_fp;
9806 : 29709 : m->fs.sp_valid = stack_realign_fp
9807 : 1481175 : || !frame_pointer_needed
9808 : 1941768 : || crtl->sp_is_unchanging;
9809 : 1503944 : gcc_assert (!m->fs.sp_valid
9810 : : || m->fs.sp_offset == frame.stack_pointer_offset);
9811 : :
9812 : : /* The FP must be valid if the frame pointer is present. */
9813 : 1503944 : gcc_assert (frame_pointer_needed == m->fs.fp_valid);
9814 : 1503944 : gcc_assert (!m->fs.fp_valid
9815 : : || m->fs.fp_offset == frame.hard_frame_pointer_offset);
9816 : :
9817 : : /* We must have *some* valid pointer to the stack frame. */
9818 : 1503944 : gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
9819 : :
9820 : : /* The DRAP is never valid at this point. */
9821 : 1503944 : gcc_assert (!m->fs.drap_valid);
9822 : :
9823 : : /* See the comment about red zone and frame
9824 : : pointer usage in ix86_expand_prologue. */
9825 : 1503944 : if (frame_pointer_needed && frame.red_zone_size)
9826 : 121882 : emit_insn (gen_memory_blockage ());
9827 : :
9828 : 1503944 : using_drap = crtl->drap_reg && crtl->stack_realign_needed;
9829 : 6940 : gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
9830 : :
9831 : : /* Determine the CFA offset of the end of the red-zone. */
9832 : 1503944 : m->fs.red_zone_offset = 0;
9833 : 1503944 : if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
9834 : : {
9835 : : /* The red-zone begins below return address and error code in
9836 : : exception handler. */
9837 : 1332901 : m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
9838 : :
9839 : : /* When the register save area is in the aligned portion of
9840 : : the stack, determine the maximum runtime displacement that
9841 : : matches up with the aligned frame. */
9842 : 1332901 : if (stack_realign_drap)
9843 : 8146 : m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
9844 : 4073 : + UNITS_PER_WORD);
9845 : : }
9846 : :
9847 : 1503944 : HOST_WIDE_INT reg_save_offset = frame.reg_save_offset;
9848 : :
9849 : : /* Special care must be taken for the normal return case of a function
9850 : : using eh_return: the eax and edx registers are marked as saved, but
9851 : : not restored along this path. Adjust the save location to match. */
9852 : 1503944 : if (crtl->calls_eh_return && style != 2)
9853 : 36 : reg_save_offset -= 2 * UNITS_PER_WORD;
9854 : :
9855 : : /* EH_RETURN requires the use of moves to function properly. */
9856 : 1503944 : if (crtl->calls_eh_return)
9857 : : restore_regs_via_mov = true;
9858 : : /* SEH requires the use of pops to identify the epilogue. */
9859 : 1503888 : else if (TARGET_SEH)
9860 : : restore_regs_via_mov = false;
9861 : : /* If we're only restoring one register and sp cannot be used then
9862 : : using a move instruction to restore the register since it's
9863 : : less work than reloading sp and popping the register. */
9864 : 1503888 : else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
9865 : : restore_regs_via_mov = true;
9866 : 1446152 : else if (TARGET_EPILOGUE_USING_MOVE
9867 : 51418 : && cfun->machine->use_fast_prologue_epilogue
9868 : 51238 : && (frame.nregs > 1
9869 : 51231 : || m->fs.sp_offset != reg_save_offset))
9870 : : restore_regs_via_mov = true;
9871 : 1445950 : else if (frame_pointer_needed
9872 : 402635 : && !frame.nregs
9873 : 310806 : && m->fs.sp_offset != reg_save_offset)
9874 : : restore_regs_via_mov = true;
9875 : 1298167 : else if (frame_pointer_needed
9876 : 254852 : && TARGET_USE_LEAVE
9877 : 254818 : && cfun->machine->use_fast_prologue_epilogue
9878 : 199940 : && frame.nregs == 1)
9879 : : restore_regs_via_mov = true;
9880 : : else
9881 : 1269991 : restore_regs_via_mov = false;
9882 : :
9883 : 1269991 : if (restore_regs_via_mov || frame.nsseregs)
9884 : : {
9885 : : /* Ensure that the entire register save area is addressable via
9886 : : the stack pointer, if we will restore SSE regs via sp. */
9887 : 267679 : if (TARGET_64BIT
9888 : 260448 : && m->fs.sp_offset > 0x7fffffff
9889 : 23 : && sp_valid_at (frame.stack_realign_offset + 1)
9890 : 267701 : && (frame.nsseregs + frame.nregs) != 0)
9891 : : {
9892 : 6 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
9893 : 6 : GEN_INT (m->fs.sp_offset
9894 : : - frame.sse_reg_save_offset),
9895 : : style,
9896 : 6 : m->fs.cfa_reg == stack_pointer_rtx);
9897 : : }
9898 : : }
9899 : :
9900 : : /* If there are any SSE registers to restore, then we have to do it
9901 : : via moves, since there's obviously no pop for SSE regs. */
9902 : 1503944 : if (frame.nsseregs)
9903 : 33729 : ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
9904 : : style == 2);
9905 : :
9906 : 1503944 : if (m->call_ms2sysv)
9907 : : {
9908 : 7621 : int pop_incoming_args = crtl->args.pops_args && crtl->args.size;
9909 : :
9910 : : /* We cannot use a tail-call for the stub if:
9911 : : 1. We have to pop incoming args,
9912 : : 2. We have additional int regs to restore, or
9913 : : 3. A sibling call will be the tail-call, or
9914 : : 4. We are emitting an eh_return_internal epilogue.
9915 : :
9916 : : TODO: Item 4 has not yet tested!
9917 : :
9918 : : If any of the above are true, we will call the stub rather than
9919 : : jump to it. */
9920 : 7621 : restore_stub_is_tail = !(pop_incoming_args || frame.nregs || style != 1);
9921 : 7621 : ix86_emit_outlined_ms2sysv_restore (frame, !restore_stub_is_tail, style);
9922 : : }
9923 : :
9924 : : /* If using out-of-line stub that is a tail-call, then...*/
9925 : 1503944 : if (m->call_ms2sysv && restore_stub_is_tail)
9926 : : {
9927 : : /* TODO: parinoid tests. (remove eventually) */
9928 : 1323 : gcc_assert (m->fs.sp_valid);
9929 : 1323 : gcc_assert (!m->fs.sp_realigned);
9930 : 1323 : gcc_assert (!m->fs.fp_valid);
9931 : 1323 : gcc_assert (!m->fs.realigned);
9932 : 1323 : gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
9933 : 1323 : gcc_assert (!crtl->drap_reg);
9934 : 1323 : gcc_assert (!frame.nregs);
9935 : : }
9936 : 1502621 : else if (restore_regs_via_mov)
9937 : : {
9938 : 232822 : rtx t;
9939 : :
9940 : 232822 : if (frame.nregs)
9941 : 41621 : ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2);
9942 : :
9943 : : /* eh_return epilogues need %ecx added to the stack pointer. */
9944 : 232822 : if (style == 2)
9945 : : {
9946 : 28 : rtx sa = EH_RETURN_STACKADJ_RTX;
9947 : 28 : rtx_insn *insn;
9948 : :
9949 : : /* Stack realignment doesn't work with eh_return. */
9950 : 28 : if (crtl->stack_realign_needed)
9951 : 0 : sorry ("Stack realignment not supported with "
9952 : : "%<__builtin_eh_return%>");
9953 : :
9954 : : /* regparm nested functions don't work with eh_return. */
9955 : 28 : if (ix86_static_chain_on_stack)
9956 : 0 : sorry ("regparm nested function not supported with "
9957 : : "%<__builtin_eh_return%>");
9958 : :
9959 : 28 : if (frame_pointer_needed)
9960 : : {
9961 : 27 : t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
9962 : 35 : t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
9963 : 27 : emit_insn (gen_rtx_SET (sa, t));
9964 : :
9965 : : /* NB: eh_return epilogues must restore the frame pointer
9966 : : in word_mode since the upper 32 bits of RBP register
9967 : : can have any values. */
9968 : 27 : t = gen_frame_mem (word_mode, hard_frame_pointer_rtx);
9969 : 27 : rtx frame_reg = gen_rtx_REG (word_mode,
9970 : : HARD_FRAME_POINTER_REGNUM);
9971 : 27 : insn = emit_move_insn (frame_reg, t);
9972 : :
9973 : : /* Note that we use SA as a temporary CFA, as the return
9974 : : address is at the proper place relative to it. We
9975 : : pretend this happens at the FP restore insn because
9976 : : prior to this insn the FP would be stored at the wrong
9977 : : offset relative to SA, and after this insn we have no
9978 : : other reasonable register to use for the CFA. We don't
9979 : : bother resetting the CFA to the SP for the duration of
9980 : : the return insn, unless the control flow instrumentation
9981 : : is done. In this case the SP is used later and we have
9982 : : to reset CFA to SP. */
9983 : 35 : add_reg_note (insn, REG_CFA_DEF_CFA,
9984 : 35 : plus_constant (Pmode, sa, UNITS_PER_WORD));
9985 : 27 : ix86_add_queued_cfa_restore_notes (insn);
9986 : 27 : add_reg_note (insn, REG_CFA_RESTORE, frame_reg);
9987 : 27 : RTX_FRAME_RELATED_P (insn) = 1;
9988 : :
9989 : 27 : m->fs.cfa_reg = sa;
9990 : 27 : m->fs.cfa_offset = UNITS_PER_WORD;
9991 : 27 : m->fs.fp_valid = false;
9992 : :
9993 : 27 : pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
9994 : : const0_rtx, style,
9995 : 27 : flag_cf_protection);
9996 : : }
9997 : : else
9998 : : {
9999 : 1 : t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
10000 : 1 : t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
10001 : 1 : insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, t));
10002 : 1 : ix86_add_queued_cfa_restore_notes (insn);
10003 : :
10004 : 1 : gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
10005 : 1 : if (m->fs.cfa_offset != UNITS_PER_WORD)
10006 : : {
10007 : 1 : m->fs.cfa_offset = UNITS_PER_WORD;
10008 : 1 : add_reg_note (insn, REG_CFA_DEF_CFA,
10009 : 1 : plus_constant (Pmode, stack_pointer_rtx,
10010 : 1 : UNITS_PER_WORD));
10011 : 1 : RTX_FRAME_RELATED_P (insn) = 1;
10012 : : }
10013 : : }
10014 : 28 : m->fs.sp_offset = UNITS_PER_WORD;
10015 : 28 : m->fs.sp_valid = true;
10016 : 28 : m->fs.sp_realigned = false;
10017 : : }
10018 : : }
10019 : : else
10020 : : {
10021 : : /* SEH requires that the function end with (1) a stack adjustment
10022 : : if necessary, (2) a sequence of pops, and (3) a return or
10023 : : jump instruction. Prevent insns from the function body from
10024 : : being scheduled into this sequence. */
10025 : 1269799 : if (TARGET_SEH)
10026 : : {
10027 : : /* Prevent a catch region from being adjacent to the standard
10028 : : epilogue sequence. Unfortunately neither crtl->uses_eh_lsda
10029 : : nor several other flags that would be interesting to test are
10030 : : set up yet. */
10031 : : if (flag_non_call_exceptions)
10032 : : emit_insn (gen_nops (const1_rtx));
10033 : : else
10034 : : emit_insn (gen_blockage ());
10035 : : }
10036 : :
10037 : : /* First step is to deallocate the stack frame so that we can
10038 : : pop the registers. If the stack pointer was realigned, it needs
10039 : : to be restored now. Also do it on SEH target for very large
10040 : : frame as the emitted instructions aren't allowed by the ABI
10041 : : in epilogues. */
10042 : 1269799 : if (!m->fs.sp_valid || m->fs.sp_realigned
10043 : : || (TARGET_SEH
10044 : : && (m->fs.sp_offset - reg_save_offset
10045 : : >= SEH_MAX_FRAME_SIZE)))
10046 : : {
10047 : 28935 : pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
10048 : 28935 : GEN_INT (m->fs.fp_offset
10049 : : - reg_save_offset),
10050 : : style, false);
10051 : : }
10052 : 1240864 : else if (m->fs.sp_offset != reg_save_offset)
10053 : : {
10054 : 562836 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10055 : : GEN_INT (m->fs.sp_offset
10056 : : - reg_save_offset),
10057 : : style,
10058 : 562836 : m->fs.cfa_reg == stack_pointer_rtx);
10059 : : }
10060 : :
10061 : 1269799 : if (TARGET_APX_PUSH2POP2
10062 : 400 : && ix86_can_use_push2pop2 ()
10063 : 1270197 : && m->func_type == TYPE_NORMAL)
10064 : 397 : ix86_emit_restore_regs_using_pop2 ();
10065 : : else
10066 : 1269402 : ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
10067 : : }
10068 : :
10069 : : /* If we used a stack pointer and haven't already got rid of it,
10070 : : then do so now. */
10071 : 1503944 : if (m->fs.fp_valid)
10072 : : {
10073 : : /* If the stack pointer is valid and pointing at the frame
10074 : : pointer store address, then we only need a pop. */
10075 : 459435 : if (sp_valid_at (frame.hfp_save_offset)
10076 : 459435 : && m->fs.sp_offset == frame.hfp_save_offset)
10077 : 226778 : ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
10078 : : /* Leave results in shorter dependency chains on CPUs that are
10079 : : able to grok it fast. */
10080 : 232657 : else if (TARGET_USE_LEAVE
10081 : 14 : || optimize_bb_for_size_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
10082 : 232671 : || !cfun->machine->use_fast_prologue_epilogue)
10083 : 232643 : ix86_emit_leave (NULL);
10084 : : else
10085 : : {
10086 : 14 : pro_epilogue_adjust_stack (stack_pointer_rtx,
10087 : : hard_frame_pointer_rtx,
10088 : 14 : const0_rtx, style, !using_drap);
10089 : 14 : ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
10090 : : }
10091 : : }
10092 : :
10093 : 1503944 : if (using_drap)
10094 : : {
10095 : 6940 : int param_ptr_offset = UNITS_PER_WORD;
10096 : 6940 : rtx_insn *insn;
10097 : :
10098 : 6940 : gcc_assert (stack_realign_drap);
10099 : :
10100 : 6940 : if (ix86_static_chain_on_stack)
10101 : 0 : param_ptr_offset += UNITS_PER_WORD;
10102 : 6940 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
10103 : 242 : param_ptr_offset += UNITS_PER_WORD;
10104 : :
10105 : 6940 : insn = emit_insn (gen_rtx_SET
10106 : : (stack_pointer_rtx,
10107 : : plus_constant (Pmode, crtl->drap_reg,
10108 : : -param_ptr_offset)));
10109 : 6940 : m->fs.cfa_reg = stack_pointer_rtx;
10110 : 6940 : m->fs.cfa_offset = param_ptr_offset;
10111 : 6940 : m->fs.sp_offset = param_ptr_offset;
10112 : 6940 : m->fs.realigned = false;
10113 : :
10114 : 7247 : add_reg_note (insn, REG_CFA_DEF_CFA,
10115 : 6940 : plus_constant (Pmode, stack_pointer_rtx,
10116 : : param_ptr_offset));
10117 : 6940 : RTX_FRAME_RELATED_P (insn) = 1;
10118 : :
10119 : 6940 : if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
10120 : 242 : ix86_emit_restore_reg_using_pop (crtl->drap_reg);
10121 : : }
10122 : :
10123 : : /* At this point the stack pointer must be valid, and we must have
10124 : : restored all of the registers. We may not have deallocated the
10125 : : entire stack frame. We've delayed this until now because it may
10126 : : be possible to merge the local stack deallocation with the
10127 : : deallocation forced by ix86_static_chain_on_stack. */
10128 : 1503944 : gcc_assert (m->fs.sp_valid);
10129 : 1503944 : gcc_assert (!m->fs.sp_realigned);
10130 : 1503944 : gcc_assert (!m->fs.fp_valid);
10131 : 1503944 : gcc_assert (!m->fs.realigned);
10132 : 1633470 : if (m->fs.sp_offset != UNITS_PER_WORD)
10133 : : {
10134 : 98 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10135 : : GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
10136 : : style, true);
10137 : : }
10138 : : else
10139 : 1503846 : ix86_add_queued_cfa_restore_notes (get_last_insn ());
10140 : :
10141 : : /* Sibcall epilogues don't want a return instruction. */
10142 : 1503944 : if (style == 0)
10143 : : {
10144 : 111633 : m->fs = frame_state_save;
10145 : 111633 : return;
10146 : : }
10147 : :
10148 : 1392311 : if (cfun->machine->func_type != TYPE_NORMAL)
10149 : 118 : emit_jump_insn (gen_interrupt_return ());
10150 : 1392193 : else if (crtl->args.pops_args && crtl->args.size)
10151 : : {
10152 : 25612 : rtx popc = GEN_INT (crtl->args.pops_args);
10153 : :
10154 : : /* i386 can only pop 64K bytes. If asked to pop more, pop return
10155 : : address, do explicit add, and jump indirectly to the caller. */
10156 : :
10157 : 25612 : if (crtl->args.pops_args >= 65536)
10158 : : {
10159 : 0 : rtx ecx = gen_rtx_REG (SImode, CX_REG);
10160 : 0 : rtx_insn *insn;
10161 : :
10162 : : /* There is no "pascal" calling convention in any 64bit ABI. */
10163 : 0 : gcc_assert (!TARGET_64BIT);
10164 : :
10165 : 0 : insn = emit_insn (gen_pop (ecx));
10166 : 0 : m->fs.cfa_offset -= UNITS_PER_WORD;
10167 : 0 : m->fs.sp_offset -= UNITS_PER_WORD;
10168 : :
10169 : 0 : rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
10170 : 0 : x = gen_rtx_SET (stack_pointer_rtx, x);
10171 : 0 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
10172 : 0 : add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
10173 : 0 : RTX_FRAME_RELATED_P (insn) = 1;
10174 : :
10175 : 0 : pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
10176 : : popc, -1, true);
10177 : 0 : emit_jump_insn (gen_simple_return_indirect_internal (ecx));
10178 : : }
10179 : : else
10180 : 25612 : emit_jump_insn (gen_simple_return_pop_internal (popc));
10181 : : }
10182 : 1366581 : else if (!m->call_ms2sysv || !restore_stub_is_tail)
10183 : : {
10184 : : /* In case of return from EH a simple return cannot be used
10185 : : as a return address will be compared with a shadow stack
10186 : : return address. Use indirect jump instead. */
10187 : 1365258 : if (style == 2 && flag_cf_protection)
10188 : : {
10189 : : /* Register used in indirect jump must be in word_mode. But
10190 : : Pmode may not be the same as word_mode for x32. */
10191 : 17 : rtx ecx = gen_rtx_REG (word_mode, CX_REG);
10192 : 17 : rtx_insn *insn;
10193 : :
10194 : 17 : insn = emit_insn (gen_pop (ecx));
10195 : 17 : m->fs.cfa_offset -= UNITS_PER_WORD;
10196 : 17 : m->fs.sp_offset -= UNITS_PER_WORD;
10197 : :
10198 : 25 : rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
10199 : 17 : x = gen_rtx_SET (stack_pointer_rtx, x);
10200 : 17 : add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
10201 : 17 : add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
10202 : 17 : RTX_FRAME_RELATED_P (insn) = 1;
10203 : :
10204 : 17 : emit_jump_insn (gen_simple_return_indirect_internal (ecx));
10205 : 17 : }
10206 : : else
10207 : 1365241 : emit_jump_insn (gen_simple_return_internal ());
10208 : : }
10209 : :
10210 : : /* Restore the state back to the state from the prologue,
10211 : : so that it's correct for the next epilogue. */
10212 : 1392311 : m->fs = frame_state_save;
10213 : : }
10214 : :
10215 : : /* Reset from the function's potential modifications. */
10216 : :
10217 : : static void
10218 : 1398289 : ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
10219 : : {
10220 : 1398289 : if (pic_offset_table_rtx
10221 : 1398289 : && !ix86_use_pseudo_pic_reg ())
10222 : 0 : SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
10223 : :
10224 : 1398289 : if (TARGET_MACHO)
10225 : : {
10226 : : rtx_insn *insn = get_last_insn ();
10227 : : rtx_insn *deleted_debug_label = NULL;
10228 : :
10229 : : /* Mach-O doesn't support labels at the end of objects, so if
10230 : : it looks like we might want one, take special action.
10231 : : First, collect any sequence of deleted debug labels. */
10232 : : while (insn
10233 : : && NOTE_P (insn)
10234 : : && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
10235 : : {
10236 : : /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
10237 : : notes only, instead set their CODE_LABEL_NUMBER to -1,
10238 : : otherwise there would be code generation differences
10239 : : in between -g and -g0. */
10240 : : if (NOTE_P (insn) && NOTE_KIND (insn)
10241 : : == NOTE_INSN_DELETED_DEBUG_LABEL)
10242 : : deleted_debug_label = insn;
10243 : : insn = PREV_INSN (insn);
10244 : : }
10245 : :
10246 : : /* If we have:
10247 : : label:
10248 : : barrier
10249 : : then this needs to be detected, so skip past the barrier. */
10250 : :
10251 : : if (insn && BARRIER_P (insn))
10252 : : insn = PREV_INSN (insn);
10253 : :
10254 : : /* Up to now we've only seen notes or barriers. */
10255 : : if (insn)
10256 : : {
10257 : : if (LABEL_P (insn)
10258 : : || (NOTE_P (insn)
10259 : : && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
10260 : : /* Trailing label. */
10261 : : fputs ("\tnop\n", file);
10262 : : else if (cfun && ! cfun->is_thunk)
10263 : : {
10264 : : /* See if we have a completely empty function body, skipping
10265 : : the special case of the picbase thunk emitted as asm. */
10266 : : while (insn && ! INSN_P (insn))
10267 : : insn = PREV_INSN (insn);
10268 : : /* If we don't find any insns, we've got an empty function body;
10269 : : I.e. completely empty - without a return or branch. This is
10270 : : taken as the case where a function body has been removed
10271 : : because it contains an inline __builtin_unreachable(). GCC
10272 : : declares that reaching __builtin_unreachable() means UB so
10273 : : we're not obliged to do anything special; however, we want
10274 : : non-zero-sized function bodies. To meet this, and help the
10275 : : user out, let's trap the case. */
10276 : : if (insn == NULL)
10277 : : fputs ("\tud2\n", file);
10278 : : }
10279 : : }
10280 : : else if (deleted_debug_label)
10281 : : for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
10282 : : if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
10283 : : CODE_LABEL_NUMBER (insn) = -1;
10284 : : }
10285 : 1398289 : }
10286 : :
10287 : : /* Implement TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY. */
10288 : :
10289 : : void
10290 : 70 : ix86_print_patchable_function_entry (FILE *file,
10291 : : unsigned HOST_WIDE_INT patch_area_size,
10292 : : bool record_p)
10293 : : {
10294 : 70 : if (cfun->machine->function_label_emitted)
10295 : : {
10296 : : /* NB: When ix86_print_patchable_function_entry is called after
10297 : : function table has been emitted, we have inserted or queued
10298 : : a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
10299 : : place. There is nothing to do here. */
10300 : : return;
10301 : : }
10302 : :
10303 : 9 : default_print_patchable_function_entry (file, patch_area_size,
10304 : : record_p);
10305 : : }
10306 : :
10307 : : /* Output patchable area. NB: default_print_patchable_function_entry
10308 : : isn't available in i386.md. */
10309 : :
10310 : : void
10311 : 61 : ix86_output_patchable_area (unsigned int patch_area_size,
10312 : : bool record_p)
10313 : : {
10314 : 61 : default_print_patchable_function_entry (asm_out_file,
10315 : : patch_area_size,
10316 : : record_p);
10317 : 61 : }
10318 : :
10319 : : /* Return a scratch register to use in the split stack prologue. The
10320 : : split stack prologue is used for -fsplit-stack. It is the first
10321 : : instructions in the function, even before the regular prologue.
10322 : : The scratch register can be any caller-saved register which is not
10323 : : used for parameters or for the static chain. */
10324 : :
10325 : : static unsigned int
10326 : 24254 : split_stack_prologue_scratch_regno (void)
10327 : : {
10328 : 24254 : if (TARGET_64BIT)
10329 : : return R11_REG;
10330 : : else
10331 : : {
10332 : 7209 : bool is_fastcall, is_thiscall;
10333 : 7209 : int regparm;
10334 : :
10335 : 7209 : is_fastcall = (lookup_attribute ("fastcall",
10336 : 7209 : TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
10337 : : != NULL);
10338 : 7209 : is_thiscall = (lookup_attribute ("thiscall",
10339 : 7209 : TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
10340 : : != NULL);
10341 : 7209 : regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
10342 : :
10343 : 7209 : if (is_fastcall)
10344 : : {
10345 : 0 : if (DECL_STATIC_CHAIN (cfun->decl))
10346 : : {
10347 : 0 : sorry ("%<-fsplit-stack%> does not support fastcall with "
10348 : : "nested function");
10349 : 0 : return INVALID_REGNUM;
10350 : : }
10351 : : return AX_REG;
10352 : : }
10353 : 7209 : else if (is_thiscall)
10354 : : {
10355 : 0 : if (!DECL_STATIC_CHAIN (cfun->decl))
10356 : : return DX_REG;
10357 : 0 : return AX_REG;
10358 : : }
10359 : 7209 : else if (regparm < 3)
10360 : : {
10361 : 7209 : if (!DECL_STATIC_CHAIN (cfun->decl))
10362 : : return CX_REG;
10363 : : else
10364 : : {
10365 : 475 : if (regparm >= 2)
10366 : : {
10367 : 0 : sorry ("%<-fsplit-stack%> does not support 2 register "
10368 : : "parameters for a nested function");
10369 : 0 : return INVALID_REGNUM;
10370 : : }
10371 : : return DX_REG;
10372 : : }
10373 : : }
10374 : : else
10375 : : {
10376 : : /* FIXME: We could make this work by pushing a register
10377 : : around the addition and comparison. */
10378 : 0 : sorry ("%<-fsplit-stack%> does not support 3 register parameters");
10379 : 0 : return INVALID_REGNUM;
10380 : : }
10381 : : }
10382 : : }
10383 : :
10384 : : /* A SYMBOL_REF for the function which allocates new stackspace for
10385 : : -fsplit-stack. */
10386 : :
10387 : : static GTY(()) rtx split_stack_fn;
10388 : :
10389 : : /* A SYMBOL_REF for the more stack function when using the large
10390 : : model. */
10391 : :
10392 : : static GTY(()) rtx split_stack_fn_large;
10393 : :
10394 : : /* Return location of the stack guard value in the TLS block. */
10395 : :
10396 : : rtx
10397 : 259785 : ix86_split_stack_guard (void)
10398 : : {
10399 : 259785 : int offset;
10400 : 259785 : addr_space_t as = DEFAULT_TLS_SEG_REG;
10401 : 259785 : rtx r;
10402 : :
10403 : 259785 : gcc_assert (flag_split_stack);
10404 : :
10405 : : #ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
10406 : 259785 : offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
10407 : : #else
10408 : : gcc_unreachable ();
10409 : : #endif
10410 : :
10411 : 259785 : r = GEN_INT (offset);
10412 : 259785 : r = gen_const_mem (Pmode, r);
10413 : 259785 : set_mem_addr_space (r, as);
10414 : :
10415 : 259785 : return r;
10416 : : }
10417 : :
10418 : : /* Handle -fsplit-stack. These are the first instructions in the
10419 : : function, even before the regular prologue. */
10420 : :
10421 : : void
10422 : 259776 : ix86_expand_split_stack_prologue (void)
10423 : : {
10424 : 259776 : HOST_WIDE_INT allocate;
10425 : 259776 : unsigned HOST_WIDE_INT args_size;
10426 : 259776 : rtx_code_label *label;
10427 : 259776 : rtx limit, current, allocate_rtx, call_fusage;
10428 : 259776 : rtx_insn *call_insn;
10429 : 259776 : unsigned int scratch_regno = INVALID_REGNUM;
10430 : 259776 : rtx scratch_reg = NULL_RTX;
10431 : 259776 : rtx_code_label *varargs_label = NULL;
10432 : 259776 : rtx fn;
10433 : :
10434 : 259776 : gcc_assert (flag_split_stack && reload_completed);
10435 : :
10436 : 259776 : ix86_finalize_stack_frame_flags ();
10437 : 259776 : struct ix86_frame &frame = cfun->machine->frame;
10438 : 259776 : allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
10439 : :
10440 : : /* This is the label we will branch to if we have enough stack
10441 : : space. We expect the basic block reordering pass to reverse this
10442 : : branch if optimizing, so that we branch in the unlikely case. */
10443 : 259776 : label = gen_label_rtx ();
10444 : :
10445 : : /* We need to compare the stack pointer minus the frame size with
10446 : : the stack boundary in the TCB. The stack boundary always gives
10447 : : us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
10448 : : can compare directly. Otherwise we need to do an addition. */
10449 : :
10450 : 259776 : limit = ix86_split_stack_guard ();
10451 : :
10452 : 259776 : if (allocate >= SPLIT_STACK_AVAILABLE
10453 : 235687 : || flag_force_indirect_call)
10454 : : {
10455 : 24106 : scratch_regno = split_stack_prologue_scratch_regno ();
10456 : 24106 : if (scratch_regno == INVALID_REGNUM)
10457 : 0 : return;
10458 : : }
10459 : :
10460 : 259776 : if (allocate >= SPLIT_STACK_AVAILABLE)
10461 : : {
10462 : 24089 : rtx offset;
10463 : :
10464 : : /* We need a scratch register to hold the stack pointer minus
10465 : : the required frame size. Since this is the very start of the
10466 : : function, the scratch register can be any caller-saved
10467 : : register which is not used for parameters. */
10468 : 24089 : offset = GEN_INT (- allocate);
10469 : :
10470 : 24089 : scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
10471 : 24089 : if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
10472 : : {
10473 : : /* We don't use gen_add in this case because it will
10474 : : want to split to lea, but when not optimizing the insn
10475 : : will not be split after this point. */
10476 : 24089 : emit_insn (gen_rtx_SET (scratch_reg,
10477 : : gen_rtx_PLUS (Pmode, stack_pointer_rtx,
10478 : : offset)));
10479 : : }
10480 : : else
10481 : : {
10482 : 0 : emit_move_insn (scratch_reg, offset);
10483 : 0 : emit_insn (gen_add2_insn (scratch_reg, stack_pointer_rtx));
10484 : : }
10485 : : current = scratch_reg;
10486 : : }
10487 : : else
10488 : 235687 : current = stack_pointer_rtx;
10489 : :
10490 : 259776 : ix86_expand_branch (GEU, current, limit, label);
10491 : 259776 : rtx_insn *jump_insn = get_last_insn ();
10492 : 259776 : JUMP_LABEL (jump_insn) = label;
10493 : :
10494 : : /* Mark the jump as very likely to be taken. */
10495 : 259776 : add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
10496 : :
10497 : 259776 : if (split_stack_fn == NULL_RTX)
10498 : : {
10499 : 4343 : split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
10500 : 4343 : SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
10501 : : }
10502 : 259776 : fn = split_stack_fn;
10503 : :
10504 : : /* Get more stack space. We pass in the desired stack space and the
10505 : : size of the arguments to copy to the new stack. In 32-bit mode
10506 : : we push the parameters; __morestack will return on a new stack
10507 : : anyhow. In 64-bit mode we pass the parameters in r10 and
10508 : : r11. */
10509 : 259776 : allocate_rtx = GEN_INT (allocate);
10510 : 259776 : args_size = crtl->args.size >= 0 ? (HOST_WIDE_INT) crtl->args.size : 0;
10511 : 259776 : call_fusage = NULL_RTX;
10512 : 259776 : rtx pop = NULL_RTX;
10513 : 259776 : if (TARGET_64BIT)
10514 : : {
10515 : 161866 : rtx reg10, reg11;
10516 : :
10517 : 161866 : reg10 = gen_rtx_REG (DImode, R10_REG);
10518 : 161866 : reg11 = gen_rtx_REG (DImode, R11_REG);
10519 : :
10520 : : /* If this function uses a static chain, it will be in %r10.
10521 : : Preserve it across the call to __morestack. */
10522 : 161866 : if (DECL_STATIC_CHAIN (cfun->decl))
10523 : : {
10524 : 7505 : rtx rax;
10525 : :
10526 : 7505 : rax = gen_rtx_REG (word_mode, AX_REG);
10527 : 7505 : emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
10528 : 7505 : use_reg (&call_fusage, rax);
10529 : : }
10530 : :
10531 : 161866 : if (flag_force_indirect_call
10532 : 161849 : || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
10533 : : {
10534 : 18 : HOST_WIDE_INT argval;
10535 : :
10536 : 18 : if (split_stack_fn_large == NULL_RTX)
10537 : : {
10538 : 8 : split_stack_fn_large
10539 : 8 : = gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
10540 : 8 : SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
10541 : : }
10542 : :
10543 : 18 : fn = split_stack_fn_large;
10544 : :
10545 : 18 : if (ix86_cmodel == CM_LARGE_PIC)
10546 : : {
10547 : 3 : rtx_code_label *label;
10548 : 3 : rtx x;
10549 : :
10550 : 3 : gcc_assert (Pmode == DImode);
10551 : :
10552 : 3 : label = gen_label_rtx ();
10553 : 3 : emit_label (label);
10554 : 3 : LABEL_PRESERVE_P (label) = 1;
10555 : 3 : emit_insn (gen_set_rip_rex64 (reg10, label));
10556 : 3 : emit_insn (gen_set_got_offset_rex64 (reg11, label));
10557 : 3 : emit_insn (gen_add2_insn (reg10, reg11));
10558 : 3 : x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
10559 : 3 : x = gen_rtx_CONST (Pmode, x);
10560 : 3 : emit_move_insn (reg11, x);
10561 : 3 : x = gen_rtx_PLUS (Pmode, reg10, reg11);
10562 : 3 : x = gen_const_mem (Pmode, x);
10563 : 3 : fn = copy_to_suggested_reg (x, reg11, Pmode);
10564 : : }
10565 : 15 : else if (ix86_cmodel == CM_LARGE)
10566 : 1 : fn = copy_to_suggested_reg (fn, reg11, Pmode);
10567 : :
10568 : : /* When using the large model we need to load the address
10569 : : into a register, and we've run out of registers. So we
10570 : : switch to a different calling convention, and we call a
10571 : : different function: __morestack_large. We pass the
10572 : : argument size in the upper 32 bits of r10 and pass the
10573 : : frame size in the lower 32 bits. */
10574 : 18 : gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
10575 : 18 : gcc_assert ((args_size & 0xffffffff) == args_size);
10576 : :
10577 : 18 : argval = ((args_size << 16) << 16) + allocate;
10578 : 18 : emit_move_insn (reg10, GEN_INT (argval));
10579 : 18 : }
10580 : : else
10581 : : {
10582 : 161848 : emit_move_insn (reg10, allocate_rtx);
10583 : 161848 : emit_move_insn (reg11, GEN_INT (args_size));
10584 : 161848 : use_reg (&call_fusage, reg11);
10585 : : }
10586 : :
10587 : 161866 : use_reg (&call_fusage, reg10);
10588 : : }
10589 : : else
10590 : : {
10591 : 97910 : if (flag_force_indirect_call && flag_pic)
10592 : : {
10593 : 0 : rtx x;
10594 : :
10595 : 0 : gcc_assert (Pmode == SImode);
10596 : :
10597 : 0 : scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
10598 : :
10599 : 0 : emit_insn (gen_set_got (scratch_reg));
10600 : 0 : x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
10601 : : UNSPEC_GOT);
10602 : 0 : x = gen_rtx_CONST (Pmode, x);
10603 : 0 : x = gen_rtx_PLUS (Pmode, scratch_reg, x);
10604 : 0 : x = gen_const_mem (Pmode, x);
10605 : 0 : fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
10606 : : }
10607 : :
10608 : 97910 : rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
10609 : 195820 : add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
10610 : 97910 : insn = emit_insn (gen_push (allocate_rtx));
10611 : 195820 : add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
10612 : 195820 : pop = GEN_INT (2 * UNITS_PER_WORD);
10613 : : }
10614 : :
10615 : 259776 : if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
10616 : : {
10617 : 14 : scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
10618 : :
10619 : 14 : if (GET_MODE (fn) != word_mode)
10620 : 0 : fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
10621 : :
10622 : 14 : fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
10623 : : }
10624 : :
10625 : 259776 : call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
10626 : 259776 : GEN_INT (UNITS_PER_WORD), constm1_rtx,
10627 : : pop, false);
10628 : 259776 : add_function_usage_to (call_insn, call_fusage);
10629 : 259776 : if (!TARGET_64BIT)
10630 : 97910 : add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (0));
10631 : : /* Indicate that this function can't jump to non-local gotos. */
10632 : 259776 : make_reg_eh_region_note_nothrow_nononlocal (call_insn);
10633 : :
10634 : : /* In order to make call/return prediction work right, we now need
10635 : : to execute a return instruction. See
10636 : : libgcc/config/i386/morestack.S for the details on how this works.
10637 : :
10638 : : For flow purposes gcc must not see this as a return
10639 : : instruction--we need control flow to continue at the subsequent
10640 : : label. Therefore, we use an unspec. */
10641 : 259776 : gcc_assert (crtl->args.pops_args < 65536);
10642 : 259776 : rtx_insn *ret_insn
10643 : 259776 : = emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
10644 : :
10645 : 259776 : if ((flag_cf_protection & CF_BRANCH))
10646 : : {
10647 : : /* Insert ENDBR since __morestack will jump back here via indirect
10648 : : call. */
10649 : 21 : rtx cet_eb = gen_nop_endbr ();
10650 : 21 : emit_insn_after (cet_eb, ret_insn);
10651 : : }
10652 : :
10653 : : /* If we are in 64-bit mode and this function uses a static chain,
10654 : : we saved %r10 in %rax before calling _morestack. */
10655 : 259776 : if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
10656 : 7505 : emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
10657 : : gen_rtx_REG (word_mode, AX_REG));
10658 : :
10659 : : /* If this function calls va_start, we need to store a pointer to
10660 : : the arguments on the old stack, because they may not have been
10661 : : all copied to the new stack. At this point the old stack can be
10662 : : found at the frame pointer value used by __morestack, because
10663 : : __morestack has set that up before calling back to us. Here we
10664 : : store that pointer in a scratch register, and in
10665 : : ix86_expand_prologue we store the scratch register in a stack
10666 : : slot. */
10667 : 259776 : if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
10668 : : {
10669 : 12 : rtx frame_reg;
10670 : 12 : int words;
10671 : :
10672 : 12 : scratch_regno = split_stack_prologue_scratch_regno ();
10673 : 12 : scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
10674 : 12 : frame_reg = gen_rtx_REG (Pmode, BP_REG);
10675 : :
10676 : : /* 64-bit:
10677 : : fp -> old fp value
10678 : : return address within this function
10679 : : return address of caller of this function
10680 : : stack arguments
10681 : : So we add three words to get to the stack arguments.
10682 : :
10683 : : 32-bit:
10684 : : fp -> old fp value
10685 : : return address within this function
10686 : : first argument to __morestack
10687 : : second argument to __morestack
10688 : : return address of caller of this function
10689 : : stack arguments
10690 : : So we add five words to get to the stack arguments.
10691 : : */
10692 : 12 : words = TARGET_64BIT ? 3 : 5;
10693 : 16 : emit_insn (gen_rtx_SET (scratch_reg,
10694 : : plus_constant (Pmode, frame_reg,
10695 : : words * UNITS_PER_WORD)));
10696 : :
10697 : 12 : varargs_label = gen_label_rtx ();
10698 : 12 : emit_jump_insn (gen_jump (varargs_label));
10699 : 12 : JUMP_LABEL (get_last_insn ()) = varargs_label;
10700 : :
10701 : 12 : emit_barrier ();
10702 : : }
10703 : :
10704 : 259776 : emit_label (label);
10705 : 259776 : LABEL_NUSES (label) = 1;
10706 : :
10707 : : /* If this function calls va_start, we now have to set the scratch
10708 : : register for the case where we do not call __morestack. In this
10709 : : case we need to set it based on the stack pointer. */
10710 : 259776 : if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
10711 : : {
10712 : 16 : emit_insn (gen_rtx_SET (scratch_reg,
10713 : : plus_constant (Pmode, stack_pointer_rtx,
10714 : : UNITS_PER_WORD)));
10715 : :
10716 : 12 : emit_label (varargs_label);
10717 : 12 : LABEL_NUSES (varargs_label) = 1;
10718 : : }
10719 : : }
10720 : :
10721 : : /* We may have to tell the dataflow pass that the split stack prologue
10722 : : is initializing a scratch register. */
10723 : :
10724 : : static void
10725 : 14190176 : ix86_live_on_entry (bitmap regs)
10726 : : {
10727 : 14190176 : if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
10728 : : {
10729 : 124 : gcc_assert (flag_split_stack);
10730 : 124 : bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
10731 : : }
10732 : 14190176 : }
10733 : :
10734 : : /* Extract the parts of an RTL expression that is a valid memory address
10735 : : for an instruction. Return false if the structure of the address is
10736 : : grossly off. */
10737 : :
10738 : : bool
10739 : 3823651681 : ix86_decompose_address (rtx addr, struct ix86_address *out)
10740 : : {
10741 : 3823651681 : rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
10742 : 3823651681 : rtx base_reg, index_reg;
10743 : 3823651681 : HOST_WIDE_INT scale = 1;
10744 : 3823651681 : rtx scale_rtx = NULL_RTX;
10745 : 3823651681 : rtx tmp;
10746 : 3823651681 : addr_space_t seg = ADDR_SPACE_GENERIC;
10747 : :
10748 : : /* Allow zero-extended SImode addresses,
10749 : : they will be emitted with addr32 prefix. */
10750 : 3823651681 : if (TARGET_64BIT && GET_MODE (addr) == DImode)
10751 : : {
10752 : 1813505212 : if (GET_CODE (addr) == ZERO_EXTEND
10753 : 1482415 : && GET_MODE (XEXP (addr, 0)) == SImode)
10754 : : {
10755 : 1390098 : addr = XEXP (addr, 0);
10756 : 1390098 : if (CONST_INT_P (addr))
10757 : : return false;
10758 : : }
10759 : 1812115114 : else if (GET_CODE (addr) == AND
10760 : 1812115114 : && const_32bit_mask (XEXP (addr, 1), DImode))
10761 : : {
10762 : 22905 : addr = lowpart_subreg (SImode, XEXP (addr, 0), DImode);
10763 : 22905 : if (addr == NULL_RTX)
10764 : : return false;
10765 : :
10766 : 22905 : if (CONST_INT_P (addr))
10767 : : return false;
10768 : : }
10769 : 1812092209 : else if (GET_CODE (addr) == AND)
10770 : : {
10771 : : /* For ASHIFT inside AND, combine will not generate
10772 : : canonical zero-extend. Merge mask for AND and shift_count
10773 : : to check if it is canonical zero-extend. */
10774 : 2410822 : tmp = XEXP (addr, 0);
10775 : 2410822 : rtx mask = XEXP (addr, 1);
10776 : 2410822 : if (tmp && GET_CODE(tmp) == ASHIFT)
10777 : : {
10778 : 135042 : rtx shift_val = XEXP (tmp, 1);
10779 : 135042 : if (CONST_INT_P (mask) && CONST_INT_P (shift_val)
10780 : 119478 : && (((unsigned HOST_WIDE_INT) INTVAL(mask)
10781 : 119478 : | ((HOST_WIDE_INT_1U << INTVAL(shift_val)) - 1))
10782 : : == 0xffffffff))
10783 : : {
10784 : 35596 : addr = lowpart_subreg (SImode, XEXP (addr, 0),
10785 : : DImode);
10786 : : }
10787 : : }
10788 : :
10789 : : }
10790 : : }
10791 : :
10792 : : /* Allow SImode subregs of DImode addresses,
10793 : : they will be emitted with addr32 prefix. */
10794 : 3823651681 : if (TARGET_64BIT && GET_MODE (addr) == SImode)
10795 : : {
10796 : 13815423 : if (SUBREG_P (addr)
10797 : 188612 : && GET_MODE (SUBREG_REG (addr)) == DImode)
10798 : : {
10799 : 168335 : addr = SUBREG_REG (addr);
10800 : 168335 : if (CONST_INT_P (addr))
10801 : : return false;
10802 : : }
10803 : : }
10804 : :
10805 : 3823651681 : if (REG_P (addr))
10806 : : base = addr;
10807 : : else if (SUBREG_P (addr))
10808 : : {
10809 : 390375 : if (REG_P (SUBREG_REG (addr)))
10810 : : base = addr;
10811 : : else
10812 : : return false;
10813 : : }
10814 : : else if (GET_CODE (addr) == PLUS)
10815 : : {
10816 : : rtx addends[4], op;
10817 : : int n = 0, i;
10818 : :
10819 : : op = addr;
10820 : 2818179611 : do
10821 : : {
10822 : 2818179611 : if (n >= 4)
10823 : 644903330 : return false;
10824 : 2818175969 : addends[n++] = XEXP (op, 1);
10825 : 2818175969 : op = XEXP (op, 0);
10826 : : }
10827 : 2818175969 : while (GET_CODE (op) == PLUS);
10828 : 2777833761 : if (n >= 4)
10829 : : return false;
10830 : 2777827672 : addends[n] = op;
10831 : :
10832 : 7086498936 : for (i = n; i >= 0; --i)
10833 : : {
10834 : 4953564863 : op = addends[i];
10835 : 4953564863 : switch (GET_CODE (op))
10836 : : {
10837 : 46564244 : case MULT:
10838 : 46564244 : if (index)
10839 : : return false;
10840 : 46527648 : index = XEXP (op, 0);
10841 : 46527648 : scale_rtx = XEXP (op, 1);
10842 : 46527648 : break;
10843 : :
10844 : 9886204 : case ASHIFT:
10845 : 9886204 : if (index)
10846 : : return false;
10847 : 9825890 : index = XEXP (op, 0);
10848 : 9825890 : tmp = XEXP (op, 1);
10849 : 9825890 : if (!CONST_INT_P (tmp))
10850 : : return false;
10851 : 9812819 : scale = INTVAL (tmp);
10852 : 9812819 : if ((unsigned HOST_WIDE_INT) scale > 3)
10853 : : return false;
10854 : 9511850 : scale = 1 << scale;
10855 : 9511850 : break;
10856 : :
10857 : 554989 : case ZERO_EXTEND:
10858 : 554989 : op = XEXP (op, 0);
10859 : 554989 : if (GET_CODE (op) != UNSPEC)
10860 : : return false;
10861 : : /* FALLTHRU */
10862 : :
10863 : 462192 : case UNSPEC:
10864 : 462192 : if (XINT (op, 1) == UNSPEC_TP
10865 : 460260 : && TARGET_TLS_DIRECT_SEG_REFS
10866 : 460260 : && seg == ADDR_SPACE_GENERIC)
10867 : 460260 : seg = DEFAULT_TLS_SEG_REG;
10868 : : else
10869 : : return false;
10870 : : break;
10871 : :
10872 : 440271 : case SUBREG:
10873 : 440271 : if (!REG_P (SUBREG_REG (op)))
10874 : : return false;
10875 : : /* FALLTHRU */
10876 : :
10877 : 2180075840 : case REG:
10878 : 2180075840 : if (!base)
10879 : : base = op;
10880 : 57314489 : else if (!index)
10881 : : index = op;
10882 : : else
10883 : : return false;
10884 : : break;
10885 : :
10886 : 2072741336 : case CONST:
10887 : 2072741336 : case CONST_INT:
10888 : 2072741336 : case SYMBOL_REF:
10889 : 2072741336 : case LABEL_REF:
10890 : 2072741336 : if (disp)
10891 : : return false;
10892 : : disp = op;
10893 : : break;
10894 : :
10895 : : default:
10896 : : return false;
10897 : : }
10898 : : }
10899 : : }
10900 : : else if (GET_CODE (addr) == MULT)
10901 : : {
10902 : 2795359 : index = XEXP (addr, 0); /* index*scale */
10903 : 2795359 : scale_rtx = XEXP (addr, 1);
10904 : : }
10905 : : else if (GET_CODE (addr) == ASHIFT)
10906 : : {
10907 : : /* We're called for lea too, which implements ashift on occasion. */
10908 : 2536552 : index = XEXP (addr, 0);
10909 : 2536552 : tmp = XEXP (addr, 1);
10910 : 2536552 : if (!CONST_INT_P (tmp))
10911 : : return false;
10912 : 2248681 : scale = INTVAL (tmp);
10913 : 2248681 : if ((unsigned HOST_WIDE_INT) scale > 3)
10914 : : return false;
10915 : 1662464 : scale = 1 << scale;
10916 : : }
10917 : : else
10918 : : disp = addr; /* displacement */
10919 : :
10920 : 3177837757 : if (index)
10921 : : {
10922 : 110061729 : if (REG_P (index))
10923 : : ;
10924 : 2689606 : else if (SUBREG_P (index)
10925 : 262600 : && REG_P (SUBREG_REG (index)))
10926 : : ;
10927 : : else
10928 : : return false;
10929 : : }
10930 : :
10931 : : /* Extract the integral value of scale. */
10932 : 3175375668 : if (scale_rtx)
10933 : : {
10934 : 42972772 : if (!CONST_INT_P (scale_rtx))
10935 : : return false;
10936 : 42536343 : scale = INTVAL (scale_rtx);
10937 : : }
10938 : :
10939 : 3174939239 : base_reg = base && SUBREG_P (base) ? SUBREG_REG (base) : base;
10940 : 3174939239 : index_reg = index && SUBREG_P (index) ? SUBREG_REG (index) : index;
10941 : :
10942 : : /* Avoid useless 0 displacement. */
10943 : 3174939239 : if (disp == const0_rtx && (base || index))
10944 : 3174939239 : disp = NULL_RTX;
10945 : :
10946 : : /* Allow arg pointer and stack pointer as index if there is not scaling. */
10947 : 2314218617 : if (base_reg && index_reg && scale == 1
10948 : 3231065509 : && (REGNO (index_reg) == ARG_POINTER_REGNUM
10949 : : || REGNO (index_reg) == FRAME_POINTER_REGNUM
10950 : : || REGNO (index_reg) == SP_REG))
10951 : : {
10952 : : std::swap (base, index);
10953 : : std::swap (base_reg, index_reg);
10954 : : }
10955 : :
10956 : : /* Special case: %ebp cannot be encoded as a base without a displacement.
10957 : : Similarly %r13. */
10958 : 256653854 : if (!disp && base_reg
10959 : 3428258473 : && (REGNO (base_reg) == ARG_POINTER_REGNUM
10960 : : || REGNO (base_reg) == FRAME_POINTER_REGNUM
10961 : : || REGNO (base_reg) == BP_REG
10962 : : || REGNO (base_reg) == R13_REG))
10963 : : disp = const0_rtx;
10964 : :
10965 : : /* Special case: on K6, [%esi] makes the instruction vector decoded.
10966 : : Avoid this by transforming to [%esi+0].
10967 : : Reload calls address legitimization without cfun defined, so we need
10968 : : to test cfun for being non-NULL. */
10969 : 0 : if (TARGET_CPU_P (K6) && cfun && optimize_function_for_speed_p (cfun)
10970 : 0 : && base_reg && !index_reg && !disp
10971 : 3174939239 : && REGNO (base_reg) == SI_REG)
10972 : 0 : disp = const0_rtx;
10973 : :
10974 : : /* Special case: encode reg+reg instead of reg*2. */
10975 : 3174939239 : if (!base && index && scale == 2)
10976 : 860720622 : base = index, base_reg = index_reg, scale = 1;
10977 : :
10978 : : /* Special case: scaling cannot be encoded without base or displacement. */
10979 : 860720622 : if (!base && !disp && index && scale != 1)
10980 : 2679776 : disp = const0_rtx;
10981 : :
10982 : 3174939239 : out->base = base;
10983 : 3174939239 : out->index = index;
10984 : 3174939239 : out->disp = disp;
10985 : 3174939239 : out->scale = scale;
10986 : 3174939239 : out->seg = seg;
10987 : :
10988 : 3174939239 : return true;
10989 : : }
10990 : :
10991 : : /* Return cost of the memory address x.
10992 : : For i386, it is better to use a complex address than let gcc copy
10993 : : the address into a reg and make a new pseudo. But not if the address
10994 : : requires to two regs - that would mean more pseudos with longer
10995 : : lifetimes. */
10996 : : static int
10997 : 9183348 : ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
10998 : : {
10999 : 9183348 : struct ix86_address parts;
11000 : 9183348 : int cost = 1;
11001 : 9183348 : int ok = ix86_decompose_address (x, &parts);
11002 : :
11003 : 9183348 : gcc_assert (ok);
11004 : :
11005 : 9183348 : if (parts.base && SUBREG_P (parts.base))
11006 : 287 : parts.base = SUBREG_REG (parts.base);
11007 : 9183348 : if (parts.index && SUBREG_P (parts.index))
11008 : 14 : parts.index = SUBREG_REG (parts.index);
11009 : :
11010 : : /* Attempt to minimize number of registers in the address by increasing
11011 : : address cost for each used register. We don't increase address cost
11012 : : for "pic_offset_table_rtx". When a memopt with "pic_offset_table_rtx"
11013 : : is not invariant itself it most likely means that base or index is not
11014 : : invariant. Therefore only "pic_offset_table_rtx" could be hoisted out,
11015 : : which is not profitable for x86. */
11016 : 9183348 : if (parts.base
11017 : 7955050 : && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
11018 : 16845240 : && (current_pass->type == GIMPLE_PASS
11019 : 2135970 : || !pic_offset_table_rtx
11020 : 110174 : || !REG_P (parts.base)
11021 : 110174 : || REGNO (pic_offset_table_rtx) != REGNO (parts.base)))
11022 : : cost++;
11023 : :
11024 : 9183348 : if (parts.index
11025 : 4534183 : && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
11026 : 13700055 : && (current_pass->type == GIMPLE_PASS
11027 : 494797 : || !pic_offset_table_rtx
11028 : 42564 : || !REG_P (parts.index)
11029 : 42564 : || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
11030 : 4515912 : cost++;
11031 : :
11032 : : /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
11033 : : since it's predecode logic can't detect the length of instructions
11034 : : and it degenerates to vector decoded. Increase cost of such
11035 : : addresses here. The penalty is minimally 2 cycles. It may be worthwhile
11036 : : to split such addresses or even refuse such addresses at all.
11037 : :
11038 : : Following addressing modes are affected:
11039 : : [base+scale*index]
11040 : : [scale*index+disp]
11041 : : [base+index]
11042 : :
11043 : : The first and last case may be avoidable by explicitly coding the zero in
11044 : : memory address, but I don't have AMD-K6 machine handy to check this
11045 : : theory. */
11046 : :
11047 : 9183348 : if (TARGET_CPU_P (K6)
11048 : 0 : && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
11049 : 0 : || (parts.disp && !parts.base && parts.index && parts.scale != 1)
11050 : 0 : || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
11051 : 0 : cost += 10;
11052 : :
11053 : 9183348 : return cost;
11054 : : }
11055 : :
11056 : : /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
11057 : : this is used for to form addresses to local data when -fPIC is in
11058 : : use. */
11059 : :
11060 : : static bool
11061 : 0 : darwin_local_data_pic (rtx disp)
11062 : : {
11063 : 0 : return (GET_CODE (disp) == UNSPEC
11064 : 0 : && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
11065 : : }
11066 : :
11067 : : /* True if the function symbol operand X should be loaded from GOT.
11068 : : If CALL_P is true, X is a call operand.
11069 : :
11070 : : NB: -mno-direct-extern-access doesn't force load from GOT for
11071 : : call.
11072 : :
11073 : : NB: In 32-bit mode, only non-PIC is allowed in inline assembly
11074 : : statements, since a PIC register could not be available at the
11075 : : call site. */
11076 : :
11077 : : bool
11078 : 1566121497 : ix86_force_load_from_GOT_p (rtx x, bool call_p)
11079 : : {
11080 : 83956004 : return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X))
11081 : : && !TARGET_PECOFF && !TARGET_MACHO
11082 : 1563835302 : && (!flag_pic || this_is_asm_operands)
11083 : 1547246175 : && ix86_cmodel != CM_LARGE
11084 : 1547240892 : && ix86_cmodel != CM_LARGE_PIC
11085 : 1547240891 : && GET_CODE (x) == SYMBOL_REF
11086 : 1547240889 : && ((!call_p
11087 : 1542160231 : && (!ix86_direct_extern_access
11088 : 1542158994 : || (SYMBOL_REF_DECL (x)
11089 : 1381505417 : && lookup_attribute ("nodirect_extern_access",
11090 : 1381505417 : DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))
11091 : 1547239245 : || (SYMBOL_REF_FUNCTION_P (x)
11092 : 587194193 : && (!flag_plt
11093 : 587192421 : || (SYMBOL_REF_DECL (x)
11094 : 587192421 : && lookup_attribute ("noplt",
11095 : 587192421 : DECL_ATTRIBUTES (SYMBOL_REF_DECL (x)))))))
11096 : 1566125270 : && !SYMBOL_REF_LOCAL_P (x));
11097 : : }
11098 : :
11099 : : /* Determine if a given RTX is a valid constant. We already know this
11100 : : satisfies CONSTANT_P. */
11101 : :
11102 : : static bool
11103 : 1212967513 : ix86_legitimate_constant_p (machine_mode mode, rtx x)
11104 : : {
11105 : 1212967513 : switch (GET_CODE (x))
11106 : : {
11107 : 116181347 : case CONST:
11108 : 116181347 : x = XEXP (x, 0);
11109 : :
11110 : 116181347 : if (GET_CODE (x) == PLUS)
11111 : : {
11112 : 116105107 : if (!CONST_INT_P (XEXP (x, 1)))
11113 : : return false;
11114 : 116105107 : x = XEXP (x, 0);
11115 : : }
11116 : :
11117 : 116181347 : if (TARGET_MACHO && darwin_local_data_pic (x))
11118 : : return true;
11119 : :
11120 : : /* Only some unspecs are valid as "constants". */
11121 : 116181347 : if (GET_CODE (x) == UNSPEC)
11122 : 390645 : switch (XINT (x, 1))
11123 : : {
11124 : 20561 : case UNSPEC_GOT:
11125 : 20561 : case UNSPEC_GOTOFF:
11126 : 20561 : case UNSPEC_PLTOFF:
11127 : 20561 : return TARGET_64BIT;
11128 : 369494 : case UNSPEC_TPOFF:
11129 : 369494 : case UNSPEC_NTPOFF:
11130 : 369494 : x = XVECEXP (x, 0, 0);
11131 : 369494 : return (GET_CODE (x) == SYMBOL_REF
11132 : 369494 : && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
11133 : 502 : case UNSPEC_DTPOFF:
11134 : 502 : x = XVECEXP (x, 0, 0);
11135 : 502 : return (GET_CODE (x) == SYMBOL_REF
11136 : 502 : && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
11137 : : default:
11138 : : return false;
11139 : : }
11140 : :
11141 : : /* We must have drilled down to a symbol. */
11142 : 115790702 : if (GET_CODE (x) == LABEL_REF)
11143 : : return true;
11144 : 115787294 : if (GET_CODE (x) != SYMBOL_REF)
11145 : : return false;
11146 : : /* FALLTHRU */
11147 : :
11148 : 779660910 : case SYMBOL_REF:
11149 : : /* TLS symbols are never valid. */
11150 : 779660910 : if (SYMBOL_REF_TLS_MODEL (x))
11151 : : return false;
11152 : :
11153 : : /* DLLIMPORT symbols are never valid. */
11154 : 779566960 : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
11155 : : && SYMBOL_REF_DLLIMPORT_P (x))
11156 : : return false;
11157 : :
11158 : : #if TARGET_MACHO
11159 : : /* mdynamic-no-pic */
11160 : : if (MACHO_DYNAMIC_NO_PIC_P)
11161 : : return machopic_symbol_defined_p (x);
11162 : : #endif
11163 : :
11164 : : /* External function address should be loaded
11165 : : via the GOT slot to avoid PLT. */
11166 : 779566960 : if (ix86_force_load_from_GOT_p (x))
11167 : : return false;
11168 : :
11169 : : break;
11170 : :
11171 : 416237673 : CASE_CONST_SCALAR_INT:
11172 : 416237673 : if (ix86_endbr_immediate_operand (x, VOIDmode))
11173 : : return false;
11174 : :
11175 : 416237500 : switch (mode)
11176 : : {
11177 : 921468 : case E_TImode:
11178 : 921468 : if (TARGET_64BIT)
11179 : : return true;
11180 : : /* FALLTHRU */
11181 : 20550 : case E_OImode:
11182 : 20550 : case E_XImode:
11183 : 20550 : if (!standard_sse_constant_p (x, mode)
11184 : 34814 : && GET_MODE_SIZE (TARGET_AVX512F && TARGET_EVEX512
11185 : : ? XImode
11186 : : : (TARGET_AVX
11187 : : ? OImode
11188 : : : (TARGET_SSE2
11189 : 14264 : ? TImode : DImode))) < GET_MODE_SIZE (mode))
11190 : : return false;
11191 : : default:
11192 : : break;
11193 : : }
11194 : : break;
11195 : :
11196 : 5978465 : case CONST_VECTOR:
11197 : 5978465 : if (!standard_sse_constant_p (x, mode))
11198 : : return false;
11199 : : break;
11200 : :
11201 : 6599427 : case CONST_DOUBLE:
11202 : 6599427 : if (mode == E_BFmode)
11203 : : return false;
11204 : :
11205 : : default:
11206 : : break;
11207 : : }
11208 : :
11209 : : /* Otherwise we handle everything else in the move patterns. */
11210 : : return true;
11211 : : }
11212 : :
11213 : : /* Determine if it's legal to put X into the constant pool. This
11214 : : is not possible for the address of thread-local symbols, which
11215 : : is checked above. */
11216 : :
11217 : : static bool
11218 : 45361217 : ix86_cannot_force_const_mem (machine_mode mode, rtx x)
11219 : : {
11220 : : /* We can put any immediate constant in memory. */
11221 : 45361217 : switch (GET_CODE (x))
11222 : : {
11223 : : CASE_CONST_ANY:
11224 : : return false;
11225 : :
11226 : 1644594 : default:
11227 : 1644594 : break;
11228 : : }
11229 : :
11230 : 1644594 : return !ix86_legitimate_constant_p (mode, x);
11231 : : }
11232 : :
11233 : : /* Nonzero if the symbol is marked as dllimport, or as stub-variable,
11234 : : otherwise zero. */
11235 : :
11236 : : static bool
11237 : 0 : is_imported_p (rtx x)
11238 : : {
11239 : 0 : if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
11240 : : || GET_CODE (x) != SYMBOL_REF)
11241 : 0 : return false;
11242 : :
11243 : : return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
11244 : : }
11245 : :
11246 : :
11247 : : /* Nonzero if the constant value X is a legitimate general operand
11248 : : when generating PIC code. It is given that flag_pic is on and
11249 : : that X satisfies CONSTANT_P. */
11250 : :
11251 : : bool
11252 : 97249551 : legitimate_pic_operand_p (rtx x)
11253 : : {
11254 : 97249551 : rtx inner;
11255 : :
11256 : 97249551 : switch (GET_CODE (x))
11257 : : {
11258 : 1611791 : case CONST:
11259 : 1611791 : inner = XEXP (x, 0);
11260 : 1611791 : if (GET_CODE (inner) == PLUS
11261 : 296656 : && CONST_INT_P (XEXP (inner, 1)))
11262 : 296656 : inner = XEXP (inner, 0);
11263 : :
11264 : : /* Only some unspecs are valid as "constants". */
11265 : 1611791 : if (GET_CODE (inner) == UNSPEC)
11266 : 1381018 : switch (XINT (inner, 1))
11267 : : {
11268 : 1342208 : case UNSPEC_GOT:
11269 : 1342208 : case UNSPEC_GOTOFF:
11270 : 1342208 : case UNSPEC_PLTOFF:
11271 : 1342208 : return TARGET_64BIT;
11272 : 0 : case UNSPEC_TPOFF:
11273 : 0 : x = XVECEXP (inner, 0, 0);
11274 : 0 : return (GET_CODE (x) == SYMBOL_REF
11275 : 0 : && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
11276 : 0 : case UNSPEC_MACHOPIC_OFFSET:
11277 : 0 : return legitimate_pic_address_disp_p (x);
11278 : : default:
11279 : : return false;
11280 : : }
11281 : : /* FALLTHRU */
11282 : :
11283 : 6151713 : case SYMBOL_REF:
11284 : 6151713 : case LABEL_REF:
11285 : 6151713 : return legitimate_pic_address_disp_p (x);
11286 : :
11287 : : default:
11288 : : return true;
11289 : : }
11290 : : }
11291 : :
11292 : : /* Determine if a given CONST RTX is a valid memory displacement
11293 : : in PIC mode. */
11294 : :
11295 : : bool
11296 : 56548757 : legitimate_pic_address_disp_p (rtx disp)
11297 : : {
11298 : 56548757 : bool saw_plus;
11299 : :
11300 : : /* In 64bit mode we can allow direct addresses of symbols and labels
11301 : : when they are not dynamic symbols. */
11302 : 56548757 : if (TARGET_64BIT)
11303 : : {
11304 : 34475684 : rtx op0 = disp, op1;
11305 : :
11306 : 34475684 : switch (GET_CODE (disp))
11307 : : {
11308 : : case LABEL_REF:
11309 : : return true;
11310 : :
11311 : 9269408 : case CONST:
11312 : 9269408 : if (GET_CODE (XEXP (disp, 0)) != PLUS)
11313 : : break;
11314 : 998881 : op0 = XEXP (XEXP (disp, 0), 0);
11315 : 998881 : op1 = XEXP (XEXP (disp, 0), 1);
11316 : 998881 : if (!CONST_INT_P (op1))
11317 : : break;
11318 : 998881 : if (GET_CODE (op0) == UNSPEC
11319 : 291 : && (XINT (op0, 1) == UNSPEC_DTPOFF
11320 : 291 : || XINT (op0, 1) == UNSPEC_NTPOFF)
11321 : 999172 : && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
11322 : : return true;
11323 : 998590 : if (INTVAL (op1) >= 16*1024*1024
11324 : 998590 : || INTVAL (op1) < -16*1024*1024)
11325 : : break;
11326 : 998418 : if (GET_CODE (op0) == LABEL_REF)
11327 : : return true;
11328 : 998418 : if (GET_CODE (op0) == CONST
11329 : 0 : && GET_CODE (XEXP (op0, 0)) == UNSPEC
11330 : 0 : && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
11331 : : return true;
11332 : 998418 : if (GET_CODE (op0) == UNSPEC
11333 : 0 : && XINT (op0, 1) == UNSPEC_PCREL)
11334 : : return true;
11335 : 998418 : if (GET_CODE (op0) != SYMBOL_REF)
11336 : : break;
11337 : : /* FALLTHRU */
11338 : :
11339 : 25998556 : case SYMBOL_REF:
11340 : : /* TLS references should always be enclosed in UNSPEC.
11341 : : The dllimported symbol needs always to be resolved. */
11342 : 25998556 : if (SYMBOL_REF_TLS_MODEL (op0)
11343 : : || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
11344 : : return false;
11345 : :
11346 : 25845606 : if (TARGET_PECOFF)
11347 : : {
11348 : : if (is_imported_p (op0))
11349 : : return true;
11350 : :
11351 : : if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
11352 : : break;
11353 : :
11354 : : /* Non-external-weak function symbols need to be resolved only
11355 : : for the large model. Non-external symbols don't need to be
11356 : : resolved for large and medium models. For the small model,
11357 : : we don't need to resolve anything here. */
11358 : : if ((ix86_cmodel != CM_LARGE_PIC
11359 : : && SYMBOL_REF_FUNCTION_P (op0)
11360 : : && !(SYMBOL_REF_EXTERNAL_P (op0) && SYMBOL_REF_WEAK (op0)))
11361 : : || !SYMBOL_REF_EXTERNAL_P (op0)
11362 : : || ix86_cmodel == CM_SMALL_PIC)
11363 : : return true;
11364 : : }
11365 : 25845606 : else if (!SYMBOL_REF_FAR_ADDR_P (op0)
11366 : 25845602 : && (SYMBOL_REF_LOCAL_P (op0)
11367 : 15963086 : || ((ix86_direct_extern_access
11368 : 31720558 : && !(SYMBOL_REF_DECL (op0)
11369 : 15757621 : && lookup_attribute ("nodirect_extern_access",
11370 : 15757621 : DECL_ATTRIBUTES (SYMBOL_REF_DECL (op0)))))
11371 : : && HAVE_LD_PIE_COPYRELOC
11372 : 15962788 : && flag_pie
11373 : 38866 : && !SYMBOL_REF_WEAK (op0)
11374 : 38380 : && !SYMBOL_REF_FUNCTION_P (op0)))
11375 : 35735617 : && ix86_cmodel != CM_LARGE_PIC)
11376 : : return true;
11377 : : break;
11378 : :
11379 : : default:
11380 : : break;
11381 : : }
11382 : : }
11383 : 46303144 : if (GET_CODE (disp) != CONST)
11384 : : return false;
11385 : 12229301 : disp = XEXP (disp, 0);
11386 : :
11387 : 12229301 : if (TARGET_64BIT)
11388 : : {
11389 : : /* We are unsafe to allow PLUS expressions. This limit allowed distance
11390 : : of GOT tables. We should not need these anyway. */
11391 : 8334191 : if (GET_CODE (disp) != UNSPEC
11392 : 8270527 : || (XINT (disp, 1) != UNSPEC_GOTPCREL
11393 : 8270527 : && XINT (disp, 1) != UNSPEC_GOTOFF
11394 : : && XINT (disp, 1) != UNSPEC_PCREL
11395 : : && XINT (disp, 1) != UNSPEC_PLTOFF))
11396 : : return false;
11397 : :
11398 : 8270527 : if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
11399 : 8270527 : && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF)
11400 : : return false;
11401 : : return true;
11402 : : }
11403 : :
11404 : 3895110 : saw_plus = false;
11405 : 3895110 : if (GET_CODE (disp) == PLUS)
11406 : : {
11407 : 521090 : if (!CONST_INT_P (XEXP (disp, 1)))
11408 : : return false;
11409 : 521090 : disp = XEXP (disp, 0);
11410 : 521090 : saw_plus = true;
11411 : : }
11412 : :
11413 : 3895110 : if (TARGET_MACHO && darwin_local_data_pic (disp))
11414 : : return true;
11415 : :
11416 : 3895110 : if (GET_CODE (disp) != UNSPEC)
11417 : : return false;
11418 : :
11419 : 3714077 : switch (XINT (disp, 1))
11420 : : {
11421 : 1695978 : case UNSPEC_GOT:
11422 : 1695978 : if (saw_plus)
11423 : : return false;
11424 : : /* We need to check for both symbols and labels because VxWorks loads
11425 : : text labels with @GOT rather than @GOTOFF. See gotoff_operand for
11426 : : details. */
11427 : 1695978 : return (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
11428 : 1695978 : || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF);
11429 : 2018099 : case UNSPEC_GOTOFF:
11430 : : /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
11431 : : While ABI specify also 32bit relocation but we don't produce it in
11432 : : small PIC model at all. */
11433 : 2018099 : if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
11434 : 2018099 : || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
11435 : : && !TARGET_64BIT)
11436 : 2018099 : return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
11437 : : return false;
11438 : 0 : case UNSPEC_GOTTPOFF:
11439 : 0 : case UNSPEC_GOTNTPOFF:
11440 : 0 : case UNSPEC_INDNTPOFF:
11441 : 0 : if (saw_plus)
11442 : : return false;
11443 : 0 : disp = XVECEXP (disp, 0, 0);
11444 : 0 : return (GET_CODE (disp) == SYMBOL_REF
11445 : 0 : && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
11446 : 0 : case UNSPEC_NTPOFF:
11447 : 0 : disp = XVECEXP (disp, 0, 0);
11448 : 0 : return (GET_CODE (disp) == SYMBOL_REF
11449 : 0 : && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
11450 : 0 : case UNSPEC_DTPOFF:
11451 : 0 : disp = XVECEXP (disp, 0, 0);
11452 : 0 : return (GET_CODE (disp) == SYMBOL_REF
11453 : 0 : && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
11454 : : }
11455 : :
11456 : : return false;
11457 : : }
11458 : :
11459 : : /* Determine if op is suitable RTX for an address register.
11460 : : Return naked register if a register or a register subreg is
11461 : : found, otherwise return NULL_RTX. */
11462 : :
11463 : : static rtx
11464 : 1057520461 : ix86_validate_address_register (rtx op)
11465 : : {
11466 : 1057520461 : machine_mode mode = GET_MODE (op);
11467 : :
11468 : : /* Only SImode or DImode registers can form the address. */
11469 : 1057520461 : if (mode != SImode && mode != DImode)
11470 : : return NULL_RTX;
11471 : :
11472 : 1057511346 : if (REG_P (op))
11473 : : return op;
11474 : 578773 : else if (SUBREG_P (op))
11475 : : {
11476 : 578773 : rtx reg = SUBREG_REG (op);
11477 : :
11478 : 578773 : if (!REG_P (reg))
11479 : : return NULL_RTX;
11480 : :
11481 : 578773 : mode = GET_MODE (reg);
11482 : :
11483 : : /* Don't allow SUBREGs that span more than a word. It can
11484 : : lead to spill failures when the register is one word out
11485 : : of a two word structure. */
11486 : 1197443 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
11487 : : return NULL_RTX;
11488 : :
11489 : : /* Allow only SUBREGs of non-eliminable hard registers. */
11490 : 176508 : if (register_no_elim_operand (reg, mode))
11491 : : return reg;
11492 : : }
11493 : :
11494 : : /* Op is not a register. */
11495 : : return NULL_RTX;
11496 : : }
11497 : :
11498 : : /* Determine which memory address register set insn can use. */
11499 : :
11500 : : static enum attr_addr
11501 : 228324483 : ix86_memory_address_reg_class (rtx_insn* insn)
11502 : : {
11503 : : /* LRA can do some initialization with NULL insn,
11504 : : return maximum register class in this case. */
11505 : 228324483 : enum attr_addr addr_rclass = ADDR_GPR32;
11506 : :
11507 : 228324483 : if (!insn)
11508 : : return addr_rclass;
11509 : :
11510 : 63741466 : if (asm_noperands (PATTERN (insn)) >= 0
11511 : 63741466 : || GET_CODE (PATTERN (insn)) == ASM_INPUT)
11512 : 69726 : return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
11513 : :
11514 : : /* Return maximum register class for unrecognized instructions. */
11515 : 63706603 : if (INSN_CODE (insn) < 0)
11516 : : return addr_rclass;
11517 : :
11518 : : /* Try to recognize the insn before calling get_attr_addr.
11519 : : Save current recog_data and current alternative. */
11520 : 63706603 : struct recog_data_d saved_recog_data = recog_data;
11521 : 63706603 : int saved_alternative = which_alternative;
11522 : :
11523 : : /* Update recog_data for processing of alternatives. */
11524 : 63706603 : extract_insn_cached (insn);
11525 : :
11526 : : /* If current alternative is not set, loop throught enabled
11527 : : alternatives and get the most limited register class. */
11528 : 63706603 : if (saved_alternative == -1)
11529 : : {
11530 : 63706603 : alternative_mask enabled = get_enabled_alternatives (insn);
11531 : :
11532 : 1105319756 : for (int i = 0; i < recog_data.n_alternatives; i++)
11533 : : {
11534 : 1041613153 : if (!TEST_BIT (enabled, i))
11535 : 153273241 : continue;
11536 : :
11537 : 888339912 : which_alternative = i;
11538 : 888339912 : addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
11539 : : }
11540 : : }
11541 : : else
11542 : : {
11543 : 0 : which_alternative = saved_alternative;
11544 : 0 : addr_rclass = get_attr_addr (insn);
11545 : : }
11546 : :
11547 : 63706603 : recog_data = saved_recog_data;
11548 : 63706603 : which_alternative = saved_alternative;
11549 : :
11550 : 63706603 : return addr_rclass;
11551 : : }
11552 : :
11553 : : /* Return memory address register class insn can use. */
11554 : :
11555 : : enum reg_class
11556 : 192593161 : ix86_insn_base_reg_class (rtx_insn* insn)
11557 : : {
11558 : 192593161 : switch (ix86_memory_address_reg_class (insn))
11559 : : {
11560 : : case ADDR_GPR8:
11561 : : return LEGACY_GENERAL_REGS;
11562 : : case ADDR_GPR16:
11563 : : return GENERAL_GPR16;
11564 : : case ADDR_GPR32:
11565 : : break;
11566 : 0 : default:
11567 : 0 : gcc_unreachable ();
11568 : : }
11569 : :
11570 : : return BASE_REG_CLASS;
11571 : : }
11572 : :
11573 : : bool
11574 : 916894 : ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
11575 : : {
11576 : 916894 : switch (ix86_memory_address_reg_class (insn))
11577 : : {
11578 : 0 : case ADDR_GPR8:
11579 : 0 : return LEGACY_INT_REGNO_P (regno);
11580 : 0 : case ADDR_GPR16:
11581 : 0 : return GENERAL_GPR16_REGNO_P (regno);
11582 : 916894 : case ADDR_GPR32:
11583 : 916894 : break;
11584 : 0 : default:
11585 : 0 : gcc_unreachable ();
11586 : : }
11587 : :
11588 : 916894 : return GENERAL_REGNO_P (regno);
11589 : : }
11590 : :
11591 : : enum reg_class
11592 : 34814428 : ix86_insn_index_reg_class (rtx_insn* insn)
11593 : : {
11594 : 34814428 : switch (ix86_memory_address_reg_class (insn))
11595 : : {
11596 : : case ADDR_GPR8:
11597 : : return LEGACY_INDEX_REGS;
11598 : : case ADDR_GPR16:
11599 : : return INDEX_GPR16;
11600 : : case ADDR_GPR32:
11601 : : break;
11602 : 0 : default:
11603 : 0 : gcc_unreachable ();
11604 : : }
11605 : :
11606 : : return INDEX_REG_CLASS;
11607 : : }
11608 : :
11609 : : /* Recognizes RTL expressions that are valid memory addresses for an
11610 : : instruction. The MODE argument is the machine mode for the MEM
11611 : : expression that wants to use this address.
11612 : :
11613 : : It only recognizes address in canonical form. LEGITIMIZE_ADDRESS should
11614 : : convert common non-canonical forms to canonical form so that they will
11615 : : be recognized. */
11616 : :
11617 : : static bool
11618 : 1820203794 : ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
11619 : : code_helper = ERROR_MARK)
11620 : : {
11621 : 1820203794 : struct ix86_address parts;
11622 : 1820203794 : rtx base, index, disp;
11623 : 1820203794 : HOST_WIDE_INT scale;
11624 : 1820203794 : addr_space_t seg;
11625 : :
11626 : 1820203794 : if (ix86_decompose_address (addr, &parts) == 0)
11627 : : /* Decomposition failed. */
11628 : : return false;
11629 : :
11630 : 1812123471 : base = parts.base;
11631 : 1812123471 : index = parts.index;
11632 : 1812123471 : disp = parts.disp;
11633 : 1812123471 : scale = parts.scale;
11634 : 1812123471 : seg = parts.seg;
11635 : :
11636 : : /* Validate base register. */
11637 : 1812123471 : if (base)
11638 : : {
11639 : 994924468 : rtx reg = ix86_validate_address_register (base);
11640 : :
11641 : 994924468 : if (reg == NULL_RTX)
11642 : : return false;
11643 : :
11644 : 994559369 : unsigned int regno = REGNO (reg);
11645 : 994559369 : if ((strict && !REGNO_OK_FOR_BASE_P (regno))
11646 : 990287358 : || (!strict && !REGNO_OK_FOR_BASE_NONSTRICT_P (regno)))
11647 : : /* Base is not valid. */
11648 : : return false;
11649 : : }
11650 : :
11651 : : /* Validate index register. */
11652 : 1810428989 : if (index)
11653 : : {
11654 : 62595993 : rtx reg = ix86_validate_address_register (index);
11655 : :
11656 : 62595993 : if (reg == NULL_RTX)
11657 : : return false;
11658 : :
11659 : 62549570 : unsigned int regno = REGNO (reg);
11660 : 62549570 : if ((strict && !REGNO_OK_FOR_INDEX_P (regno))
11661 : 62543230 : || (!strict && !REGNO_OK_FOR_INDEX_NONSTRICT_P (regno)))
11662 : : /* Index is not valid. */
11663 : : return false;
11664 : : }
11665 : :
11666 : : /* Index and base should have the same mode. */
11667 : 1810382327 : if (base && index
11668 : 54399466 : && GET_MODE (base) != GET_MODE (index))
11669 : : return false;
11670 : :
11671 : : /* Address override works only on the (%reg) part of %fs:(%reg). */
11672 : 1810287971 : if (seg != ADDR_SPACE_GENERIC
11673 : 1810287971 : && ((base && GET_MODE (base) != word_mode)
11674 : 174115 : || (index && GET_MODE (index) != word_mode)))
11675 : : return false;
11676 : :
11677 : : /* Validate scale factor. */
11678 : 1810287966 : if (scale != 1)
11679 : : {
11680 : 29656315 : if (!index)
11681 : : /* Scale without index. */
11682 : : return false;
11683 : :
11684 : 29656315 : if (scale != 2 && scale != 4 && scale != 8)
11685 : : /* Scale is not a valid multiplier. */
11686 : : return false;
11687 : : }
11688 : :
11689 : : /* Validate displacement. */
11690 : 1807647492 : if (disp)
11691 : : {
11692 : 1633200268 : if (ix86_endbr_immediate_operand (disp, VOIDmode))
11693 : : return false;
11694 : :
11695 : 1633200203 : if (GET_CODE (disp) == CONST
11696 : 125303377 : && GET_CODE (XEXP (disp, 0)) == UNSPEC
11697 : 12439005 : && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
11698 : 12439005 : switch (XINT (XEXP (disp, 0), 1))
11699 : : {
11700 : : /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
11701 : : when used. While ABI specify also 32bit relocations, we
11702 : : don't produce them at all and use IP relative instead.
11703 : : Allow GOT in 32bit mode for both PIC and non-PIC if symbol
11704 : : should be loaded via GOT. */
11705 : 1696013 : case UNSPEC_GOT:
11706 : 1696013 : if (!TARGET_64BIT
11707 : 1696013 : && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
11708 : 0 : goto is_legitimate_pic;
11709 : : /* FALLTHRU */
11710 : 3374095 : case UNSPEC_GOTOFF:
11711 : 3374095 : gcc_assert (flag_pic);
11712 : 3374095 : if (!TARGET_64BIT)
11713 : 3374020 : goto is_legitimate_pic;
11714 : :
11715 : : /* 64bit address unspec. */
11716 : : return false;
11717 : :
11718 : 8270493 : case UNSPEC_GOTPCREL:
11719 : 8270493 : if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
11720 : 1351 : goto is_legitimate_pic;
11721 : : /* FALLTHRU */
11722 : 8269142 : case UNSPEC_PCREL:
11723 : 8269142 : gcc_assert (flag_pic);
11724 : 8269142 : goto is_legitimate_pic;
11725 : :
11726 : : case UNSPEC_GOTTPOFF:
11727 : : case UNSPEC_GOTNTPOFF:
11728 : : case UNSPEC_INDNTPOFF:
11729 : : case UNSPEC_NTPOFF:
11730 : : case UNSPEC_DTPOFF:
11731 : : break;
11732 : :
11733 : : default:
11734 : : /* Invalid address unspec. */
11735 : : return false;
11736 : : }
11737 : :
11738 : 993231421 : else if (SYMBOLIC_CONST (disp)
11739 : 1733625570 : && (flag_pic
11740 : : #if TARGET_MACHO
11741 : : || (MACHOPIC_INDIRECT
11742 : : && !machopic_operand_p (disp))
11743 : : #endif
11744 : : ))
11745 : : {
11746 : :
11747 : 50233842 : is_legitimate_pic:
11748 : 50233842 : if (TARGET_64BIT && (index || base))
11749 : : {
11750 : : /* foo@dtpoff(%rX) is ok. */
11751 : 30309 : if (GET_CODE (disp) != CONST
11752 : 6619 : || GET_CODE (XEXP (disp, 0)) != PLUS
11753 : 6619 : || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
11754 : 4366 : || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
11755 : 4366 : || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
11756 : 4366 : && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF))
11757 : : /* Non-constant pic memory reference. */
11758 : : return false;
11759 : : }
11760 : 50203533 : else if ((!TARGET_MACHO || flag_pic)
11761 : 50203533 : && ! legitimate_pic_address_disp_p (disp))
11762 : : /* Displacement is an invalid pic construct. */
11763 : : return false;
11764 : : #if TARGET_MACHO
11765 : : else if (MACHO_DYNAMIC_NO_PIC_P
11766 : : && !ix86_legitimate_constant_p (Pmode, disp))
11767 : : /* displacment must be referenced via non_lazy_pointer */
11768 : : return false;
11769 : : #endif
11770 : :
11771 : : /* This code used to verify that a symbolic pic displacement
11772 : : includes the pic_offset_table_rtx register.
11773 : :
11774 : : While this is good idea, unfortunately these constructs may
11775 : : be created by "adds using lea" optimization for incorrect
11776 : : code like:
11777 : :
11778 : : int a;
11779 : : int foo(int i)
11780 : : {
11781 : : return *(&a+i);
11782 : : }
11783 : :
11784 : : This code is nonsensical, but results in addressing
11785 : : GOT table with pic_offset_table_rtx base. We can't
11786 : : just refuse it easily, since it gets matched by
11787 : : "addsi3" pattern, that later gets split to lea in the
11788 : : case output register differs from input. While this
11789 : : can be handled by separate addsi pattern for this case
11790 : : that never results in lea, this seems to be easier and
11791 : : correct fix for crash to disable this test. */
11792 : : }
11793 : 1582171869 : else if (GET_CODE (disp) != LABEL_REF
11794 : 1581935596 : && !CONST_INT_P (disp)
11795 : 747156073 : && (GET_CODE (disp) != CONST
11796 : 111576239 : || !ix86_legitimate_constant_p (Pmode, disp))
11797 : 2217761726 : && (GET_CODE (disp) != SYMBOL_REF
11798 : 589992308 : || !ix86_legitimate_constant_p (Pmode, disp)))
11799 : : /* Displacement is not constant. */
11800 : 45654466 : return false;
11801 : 1536517403 : else if (TARGET_64BIT
11802 : 1536517403 : && !x86_64_immediate_operand (disp, VOIDmode))
11803 : : /* Displacement is out of range. */
11804 : : return false;
11805 : : /* In x32 mode, constant addresses are sign extended to 64bit, so
11806 : : we have to prevent addresses from 0x80000000 to 0xffffffff. */
11807 : 23034 : else if (TARGET_X32 && !(index || base)
11808 : 12420 : && CONST_INT_P (disp)
11809 : 1536077996 : && val_signbit_known_set_p (SImode, INTVAL (disp)))
11810 : : return false;
11811 : : }
11812 : :
11813 : : /* Everything looks valid. */
11814 : : return true;
11815 : : }
11816 : :
11817 : : /* Determine if a given RTX is a valid constant address. */
11818 : :
11819 : : bool
11820 : 2329722283 : constant_address_p (rtx x)
11821 : : {
11822 : 2329722283 : return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
11823 : : }
11824 : :
11825 : : /* Return a unique alias set for the GOT. */
11826 : :
11827 : : alias_set_type
11828 : 183674 : ix86_GOT_alias_set (void)
11829 : : {
11830 : 183674 : static alias_set_type set = -1;
11831 : 183674 : if (set == -1)
11832 : 2892 : set = new_alias_set ();
11833 : 183674 : return set;
11834 : : }
11835 : :
11836 : : /* Return a legitimate reference for ORIG (an address) using the
11837 : : register REG. If REG is 0, a new pseudo is generated.
11838 : :
11839 : : There are two types of references that must be handled:
11840 : :
11841 : : 1. Global data references must load the address from the GOT, via
11842 : : the PIC reg. An insn is emitted to do this load, and the reg is
11843 : : returned.
11844 : :
11845 : : 2. Static data references, constant pool addresses, and code labels
11846 : : compute the address as an offset from the GOT, whose base is in
11847 : : the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
11848 : : differentiate them from global data objects. The returned
11849 : : address is the PIC reg + an unspec constant.
11850 : :
11851 : : TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
11852 : : reg also appears in the address. */
11853 : :
11854 : : rtx
11855 : 392511 : legitimize_pic_address (rtx orig, rtx reg)
11856 : : {
11857 : 392511 : rtx addr = orig;
11858 : 392511 : rtx new_rtx = orig;
11859 : :
11860 : : #if TARGET_MACHO
11861 : : if (TARGET_MACHO && !TARGET_64BIT)
11862 : : {
11863 : : if (reg == 0)
11864 : : reg = gen_reg_rtx (Pmode);
11865 : : /* Use the generic Mach-O PIC machinery. */
11866 : : return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
11867 : : }
11868 : : #endif
11869 : :
11870 : 392511 : if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
11871 : : {
11872 : : rtx tmp = legitimize_pe_coff_symbol (addr, true);
11873 : : if (tmp)
11874 : : return tmp;
11875 : : }
11876 : :
11877 : 392511 : if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
11878 : : new_rtx = addr;
11879 : 298565 : else if ((!TARGET_64BIT
11880 : 99565 : || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
11881 : : && !TARGET_PECOFF
11882 : 298662 : && gotoff_operand (addr, Pmode))
11883 : : {
11884 : : /* This symbol may be referenced via a displacement
11885 : : from the PIC base address (@GOTOFF). */
11886 : 97257 : if (GET_CODE (addr) == CONST)
11887 : 2874 : addr = XEXP (addr, 0);
11888 : :
11889 : 97257 : if (GET_CODE (addr) == PLUS)
11890 : : {
11891 : 2874 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
11892 : : UNSPEC_GOTOFF);
11893 : 2874 : new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
11894 : : }
11895 : : else
11896 : 94383 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
11897 : :
11898 : 97257 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
11899 : :
11900 : 97257 : if (TARGET_64BIT)
11901 : 13 : new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
11902 : :
11903 : 97257 : if (reg != 0)
11904 : : {
11905 : 4 : gcc_assert (REG_P (reg));
11906 : 4 : new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
11907 : : new_rtx, reg, 1, OPTAB_DIRECT);
11908 : : }
11909 : : else
11910 : 97253 : new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
11911 : : }
11912 : 375457 : else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
11913 : : /* We can't always use @GOTOFF for text labels
11914 : : on VxWorks, see gotoff_operand. */
11915 : 201308 : || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
11916 : : {
11917 : 174146 : rtx tmp = legitimize_pe_coff_symbol (addr, true);
11918 : 174146 : if (tmp)
11919 : : return tmp;
11920 : :
11921 : : /* For x64 PE-COFF there is no GOT table,
11922 : : so we use address directly. */
11923 : 174146 : if (TARGET_64BIT && TARGET_PECOFF)
11924 : : {
11925 : : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
11926 : : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
11927 : : }
11928 : 174146 : else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
11929 : : {
11930 : 92280 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
11931 : : UNSPEC_GOTPCREL);
11932 : 92280 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
11933 : 92280 : new_rtx = gen_const_mem (Pmode, new_rtx);
11934 : 92280 : set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
11935 : : }
11936 : : else
11937 : : {
11938 : : /* This symbol must be referenced via a load
11939 : : from the Global Offset Table (@GOT). */
11940 : 81866 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
11941 : 81866 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
11942 : :
11943 : 81866 : if (TARGET_64BIT)
11944 : 26 : new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
11945 : :
11946 : 81866 : if (reg != 0)
11947 : : {
11948 : 0 : gcc_assert (REG_P (reg));
11949 : 0 : new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
11950 : : new_rtx, reg, 1, OPTAB_DIRECT);
11951 : : }
11952 : : else
11953 : 81866 : new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
11954 : :
11955 : 81866 : new_rtx = gen_const_mem (Pmode, new_rtx);
11956 : 81866 : set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
11957 : : }
11958 : :
11959 : 174146 : new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
11960 : : }
11961 : : else
11962 : : {
11963 : 27162 : if (CONST_INT_P (addr)
11964 : 27162 : && !x86_64_immediate_operand (addr, VOIDmode))
11965 : 8 : new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
11966 : 27154 : else if (GET_CODE (addr) == CONST)
11967 : : {
11968 : 16731 : addr = XEXP (addr, 0);
11969 : :
11970 : : /* We must match stuff we generate before. Assume the only
11971 : : unspecs that can get here are ours. Not that we could do
11972 : : anything with them anyway.... */
11973 : 16731 : if (GET_CODE (addr) == UNSPEC
11974 : 8926 : || (GET_CODE (addr) == PLUS
11975 : 8926 : && GET_CODE (XEXP (addr, 0)) == UNSPEC))
11976 : : return orig;
11977 : 6847 : gcc_assert (GET_CODE (addr) == PLUS);
11978 : : }
11979 : :
11980 : 17278 : if (GET_CODE (addr) == PLUS)
11981 : : {
11982 : 8640 : rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
11983 : :
11984 : : /* Check first to see if this is a constant
11985 : : offset from a @GOTOFF symbol reference. */
11986 : 8640 : if (!TARGET_PECOFF
11987 : 8640 : && gotoff_operand (op0, Pmode)
11988 : 8640 : && CONST_INT_P (op1))
11989 : : {
11990 : 5 : if (!TARGET_64BIT)
11991 : : {
11992 : 0 : new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
11993 : : UNSPEC_GOTOFF);
11994 : 0 : new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
11995 : 0 : new_rtx = gen_rtx_CONST (Pmode, new_rtx);
11996 : :
11997 : 0 : if (reg != 0)
11998 : : {
11999 : 0 : gcc_assert (REG_P (reg));
12000 : 0 : new_rtx = expand_simple_binop (Pmode, PLUS,
12001 : : pic_offset_table_rtx,
12002 : : new_rtx, reg, 1,
12003 : : OPTAB_DIRECT);
12004 : : }
12005 : : else
12006 : 0 : new_rtx
12007 : 0 : = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
12008 : : }
12009 : : else
12010 : : {
12011 : 5 : if (INTVAL (op1) < -16*1024*1024
12012 : 5 : || INTVAL (op1) >= 16*1024*1024)
12013 : : {
12014 : 5 : if (!x86_64_immediate_operand (op1, Pmode))
12015 : 5 : op1 = force_reg (Pmode, op1);
12016 : :
12017 : 5 : new_rtx
12018 : 5 : = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
12019 : : }
12020 : : }
12021 : : }
12022 : : else
12023 : : {
12024 : 8635 : rtx base = legitimize_pic_address (op0, reg);
12025 : 8635 : machine_mode mode = GET_MODE (base);
12026 : 8635 : new_rtx
12027 : 8635 : = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
12028 : :
12029 : 8635 : if (CONST_INT_P (new_rtx))
12030 : : {
12031 : 6834 : if (INTVAL (new_rtx) < -16*1024*1024
12032 : 6834 : || INTVAL (new_rtx) >= 16*1024*1024)
12033 : : {
12034 : 0 : if (!x86_64_immediate_operand (new_rtx, mode))
12035 : 0 : new_rtx = force_reg (mode, new_rtx);
12036 : :
12037 : 0 : new_rtx
12038 : 0 : = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
12039 : : }
12040 : : else
12041 : 6834 : new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
12042 : : }
12043 : : else
12044 : : {
12045 : : /* For %rip addressing, we have to use
12046 : : just disp32, not base nor index. */
12047 : 1801 : if (TARGET_64BIT
12048 : 99 : && (GET_CODE (base) == SYMBOL_REF
12049 : 99 : || GET_CODE (base) == LABEL_REF))
12050 : 7 : base = force_reg (mode, base);
12051 : 1801 : if (GET_CODE (new_rtx) == PLUS
12052 : 1678 : && CONSTANT_P (XEXP (new_rtx, 1)))
12053 : : {
12054 : 1674 : base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
12055 : 1674 : new_rtx = XEXP (new_rtx, 1);
12056 : : }
12057 : 1801 : new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
12058 : : }
12059 : : }
12060 : : }
12061 : : }
12062 : : return new_rtx;
12063 : : }
12064 : :
12065 : : /* Load the thread pointer. If TO_REG is true, force it into a register. */
12066 : :
12067 : : static rtx
12068 : 21624 : get_thread_pointer (machine_mode tp_mode, bool to_reg)
12069 : : {
12070 : 21624 : rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
12071 : :
12072 : 21624 : if (GET_MODE (tp) != tp_mode)
12073 : : {
12074 : 7 : gcc_assert (GET_MODE (tp) == SImode);
12075 : 7 : gcc_assert (tp_mode == DImode);
12076 : :
12077 : 7 : tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
12078 : : }
12079 : :
12080 : 21624 : if (to_reg)
12081 : 7542 : tp = copy_to_mode_reg (tp_mode, tp);
12082 : :
12083 : 21624 : return tp;
12084 : : }
12085 : :
12086 : : /* Construct the SYMBOL_REF for the tls_get_addr function. */
12087 : :
12088 : : static GTY(()) rtx ix86_tls_symbol;
12089 : :
12090 : : static rtx
12091 : 6955 : ix86_tls_get_addr (void)
12092 : : {
12093 : 6955 : if (!ix86_tls_symbol)
12094 : : {
12095 : 830 : const char *sym
12096 : 415 : = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
12097 : 415 : ? "___tls_get_addr" : "__tls_get_addr");
12098 : :
12099 : 415 : ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
12100 : : }
12101 : :
12102 : 6955 : if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
12103 : : {
12104 : 0 : rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
12105 : : UNSPEC_PLTOFF);
12106 : 0 : return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
12107 : : gen_rtx_CONST (Pmode, unspec));
12108 : : }
12109 : :
12110 : 6955 : return ix86_tls_symbol;
12111 : : }
12112 : :
12113 : : /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
12114 : :
12115 : : static GTY(()) rtx ix86_tls_module_base_symbol;
12116 : :
12117 : : rtx
12118 : 8 : ix86_tls_module_base (void)
12119 : : {
12120 : 8 : if (!ix86_tls_module_base_symbol)
12121 : : {
12122 : 2 : ix86_tls_module_base_symbol
12123 : 2 : = gen_rtx_SYMBOL_REF (ptr_mode, "_TLS_MODULE_BASE_");
12124 : :
12125 : 2 : SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
12126 : 2 : |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
12127 : : }
12128 : :
12129 : 8 : return ix86_tls_module_base_symbol;
12130 : : }
12131 : :
12132 : : /* A subroutine of ix86_legitimize_address and ix86_expand_move. FOR_MOV is
12133 : : false if we expect this to be used for a memory address and true if
12134 : : we expect to load the address into a register. */
12135 : :
12136 : : rtx
12137 : 28579 : legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
12138 : : {
12139 : 28579 : rtx dest, base, off;
12140 : 28579 : rtx pic = NULL_RTX, tp = NULL_RTX;
12141 : 28579 : machine_mode tp_mode = Pmode;
12142 : 28579 : int type;
12143 : :
12144 : : /* Fall back to global dynamic model if tool chain cannot support local
12145 : : dynamic. */
12146 : 28579 : if (TARGET_SUN_TLS && !TARGET_64BIT
12147 : : && !HAVE_AS_IX86_TLSLDMPLT && !HAVE_AS_IX86_TLSLDM
12148 : : && model == TLS_MODEL_LOCAL_DYNAMIC)
12149 : : model = TLS_MODEL_GLOBAL_DYNAMIC;
12150 : :
12151 : 28579 : switch (model)
12152 : : {
12153 : 6537 : case TLS_MODEL_GLOBAL_DYNAMIC:
12154 : 6537 : if (!TARGET_64BIT)
12155 : : {
12156 : 2076 : if (flag_pic && !TARGET_PECOFF)
12157 : 2076 : pic = pic_offset_table_rtx;
12158 : : else
12159 : : {
12160 : 0 : pic = gen_reg_rtx (Pmode);
12161 : 0 : emit_insn (gen_set_got (pic));
12162 : : }
12163 : : }
12164 : :
12165 : 6537 : if (TARGET_GNU2_TLS)
12166 : : {
12167 : 12 : dest = gen_reg_rtx (ptr_mode);
12168 : 12 : if (TARGET_64BIT)
12169 : 12 : emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, dest, x));
12170 : : else
12171 : 0 : emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
12172 : :
12173 : 12 : tp = get_thread_pointer (ptr_mode, true);
12174 : 12 : dest = gen_rtx_PLUS (ptr_mode, tp, dest);
12175 : 12 : if (GET_MODE (dest) != Pmode)
12176 : 6 : dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
12177 : 12 : dest = force_reg (Pmode, dest);
12178 : :
12179 : 12 : if (GET_MODE (x) != Pmode)
12180 : 3 : x = gen_rtx_ZERO_EXTEND (Pmode, x);
12181 : :
12182 : 12 : set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
12183 : : }
12184 : : else
12185 : : {
12186 : 6525 : rtx caddr = ix86_tls_get_addr ();
12187 : :
12188 : 6525 : dest = gen_reg_rtx (Pmode);
12189 : 6525 : if (TARGET_64BIT)
12190 : : {
12191 : 4449 : rtx rax = gen_rtx_REG (Pmode, AX_REG);
12192 : 4449 : rtx_insn *insns;
12193 : :
12194 : 4449 : start_sequence ();
12195 : 4449 : emit_call_insn
12196 : 4449 : (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr));
12197 : 4449 : insns = get_insns ();
12198 : 4449 : end_sequence ();
12199 : :
12200 : 4449 : if (GET_MODE (x) != Pmode)
12201 : 1 : x = gen_rtx_ZERO_EXTEND (Pmode, x);
12202 : :
12203 : 4449 : RTL_CONST_CALL_P (insns) = 1;
12204 : 4449 : emit_libcall_block (insns, dest, rax, x);
12205 : : }
12206 : : else
12207 : 2076 : emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
12208 : : }
12209 : : break;
12210 : :
12211 : 434 : case TLS_MODEL_LOCAL_DYNAMIC:
12212 : 434 : if (!TARGET_64BIT)
12213 : : {
12214 : 110 : if (flag_pic)
12215 : 110 : pic = pic_offset_table_rtx;
12216 : : else
12217 : : {
12218 : 0 : pic = gen_reg_rtx (Pmode);
12219 : 0 : emit_insn (gen_set_got (pic));
12220 : : }
12221 : : }
12222 : :
12223 : 434 : if (TARGET_GNU2_TLS)
12224 : : {
12225 : 4 : rtx tmp = ix86_tls_module_base ();
12226 : :
12227 : 4 : base = gen_reg_rtx (ptr_mode);
12228 : 4 : if (TARGET_64BIT)
12229 : 4 : emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
12230 : : else
12231 : 0 : emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
12232 : :
12233 : 4 : tp = get_thread_pointer (ptr_mode, true);
12234 : 4 : if (GET_MODE (base) != Pmode)
12235 : 2 : base = gen_rtx_ZERO_EXTEND (Pmode, base);
12236 : 4 : base = force_reg (Pmode, base);
12237 : : }
12238 : : else
12239 : : {
12240 : 430 : rtx caddr = ix86_tls_get_addr ();
12241 : :
12242 : 430 : base = gen_reg_rtx (Pmode);
12243 : 430 : if (TARGET_64BIT)
12244 : : {
12245 : 320 : rtx rax = gen_rtx_REG (Pmode, AX_REG);
12246 : 320 : rtx_insn *insns;
12247 : 320 : rtx eqv;
12248 : :
12249 : 320 : start_sequence ();
12250 : 320 : emit_call_insn
12251 : 320 : (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr));
12252 : 320 : insns = get_insns ();
12253 : 320 : end_sequence ();
12254 : :
12255 : : /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
12256 : : share the LD_BASE result with other LD model accesses. */
12257 : 320 : eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12258 : : UNSPEC_TLS_LD_BASE);
12259 : :
12260 : 320 : RTL_CONST_CALL_P (insns) = 1;
12261 : 320 : emit_libcall_block (insns, base, rax, eqv);
12262 : : }
12263 : : else
12264 : 110 : emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
12265 : : }
12266 : :
12267 : 434 : off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
12268 : 434 : off = gen_rtx_CONST (Pmode, off);
12269 : :
12270 : 434 : dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
12271 : :
12272 : 434 : if (TARGET_GNU2_TLS)
12273 : : {
12274 : 4 : if (GET_MODE (tp) != Pmode)
12275 : : {
12276 : 2 : dest = lowpart_subreg (ptr_mode, dest, Pmode);
12277 : 2 : dest = gen_rtx_PLUS (ptr_mode, tp, dest);
12278 : 2 : dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
12279 : : }
12280 : : else
12281 : 2 : dest = gen_rtx_PLUS (Pmode, tp, dest);
12282 : 4 : dest = force_reg (Pmode, dest);
12283 : :
12284 : 4 : if (GET_MODE (x) != Pmode)
12285 : 1 : x = gen_rtx_ZERO_EXTEND (Pmode, x);
12286 : :
12287 : 4 : set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
12288 : : }
12289 : : break;
12290 : :
12291 : 9516 : case TLS_MODEL_INITIAL_EXEC:
12292 : 9516 : if (TARGET_64BIT)
12293 : : {
12294 : : if (TARGET_SUN_TLS && !TARGET_X32)
12295 : : {
12296 : : /* The Sun linker took the AMD64 TLS spec literally
12297 : : and can only handle %rax as destination of the
12298 : : initial executable code sequence. */
12299 : :
12300 : : dest = gen_reg_rtx (DImode);
12301 : : emit_insn (gen_tls_initial_exec_64_sun (dest, x));
12302 : : return dest;
12303 : : }
12304 : :
12305 : : /* Generate DImode references to avoid %fs:(%reg32)
12306 : : problems and linker IE->LE relaxation bug. */
12307 : : tp_mode = DImode;
12308 : : pic = NULL;
12309 : : type = UNSPEC_GOTNTPOFF;
12310 : : }
12311 : 741 : else if (flag_pic)
12312 : : {
12313 : 740 : pic = pic_offset_table_rtx;
12314 : 740 : type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
12315 : : }
12316 : 1 : else if (!TARGET_ANY_GNU_TLS)
12317 : : {
12318 : 0 : pic = gen_reg_rtx (Pmode);
12319 : 0 : emit_insn (gen_set_got (pic));
12320 : 0 : type = UNSPEC_GOTTPOFF;
12321 : : }
12322 : : else
12323 : : {
12324 : : pic = NULL;
12325 : : type = UNSPEC_INDNTPOFF;
12326 : : }
12327 : :
12328 : 9516 : off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
12329 : 9516 : off = gen_rtx_CONST (tp_mode, off);
12330 : 9516 : if (pic)
12331 : 740 : off = gen_rtx_PLUS (tp_mode, pic, off);
12332 : 9516 : off = gen_const_mem (tp_mode, off);
12333 : 9516 : set_mem_alias_set (off, ix86_GOT_alias_set ());
12334 : :
12335 : 9516 : if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
12336 : : {
12337 : 9516 : base = get_thread_pointer (tp_mode,
12338 : 9516 : for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
12339 : 9516 : off = force_reg (tp_mode, off);
12340 : 9516 : dest = gen_rtx_PLUS (tp_mode, base, off);
12341 : 9516 : if (tp_mode != Pmode)
12342 : 4 : dest = convert_to_mode (Pmode, dest, 1);
12343 : : }
12344 : : else
12345 : : {
12346 : 0 : base = get_thread_pointer (Pmode, true);
12347 : 0 : dest = gen_reg_rtx (Pmode);
12348 : 0 : emit_insn (gen_sub3_insn (dest, base, off));
12349 : : }
12350 : : break;
12351 : :
12352 : 12092 : case TLS_MODEL_LOCAL_EXEC:
12353 : 24184 : off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
12354 : : (TARGET_64BIT || TARGET_ANY_GNU_TLS)
12355 : : ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
12356 : 12092 : off = gen_rtx_CONST (Pmode, off);
12357 : :
12358 : 12092 : if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
12359 : : {
12360 : 12092 : base = get_thread_pointer (Pmode,
12361 : 12092 : for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
12362 : 12092 : return gen_rtx_PLUS (Pmode, base, off);
12363 : : }
12364 : : else
12365 : : {
12366 : 0 : base = get_thread_pointer (Pmode, true);
12367 : 0 : dest = gen_reg_rtx (Pmode);
12368 : 0 : emit_insn (gen_sub3_insn (dest, base, off));
12369 : : }
12370 : 0 : break;
12371 : :
12372 : 0 : default:
12373 : 0 : gcc_unreachable ();
12374 : : }
12375 : :
12376 : : return dest;
12377 : : }
12378 : :
12379 : : /* Return true if the TLS address requires insn using integer registers.
12380 : : It's used to prevent KMOV/VMOV in TLS code sequences which require integer
12381 : : MOV instructions, refer to PR103275. */
12382 : : bool
12383 : 4217396 : ix86_gpr_tls_address_pattern_p (rtx mem)
12384 : : {
12385 : 4217396 : gcc_assert (MEM_P (mem));
12386 : :
12387 : 4217396 : rtx addr = XEXP (mem, 0);
12388 : 4217396 : subrtx_var_iterator::array_type array;
12389 : 13738085 : FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
12390 : : {
12391 : 9520689 : rtx op = *iter;
12392 : 9520689 : if (GET_CODE (op) == UNSPEC)
12393 : 28848 : switch (XINT (op, 1))
12394 : : {
12395 : : case UNSPEC_GOTNTPOFF:
12396 : 0 : return true;
12397 : 0 : case UNSPEC_TPOFF:
12398 : 0 : if (!TARGET_64BIT)
12399 : : return true;
12400 : : break;
12401 : : default:
12402 : : break;
12403 : : }
12404 : : }
12405 : :
12406 : 4217396 : return false;
12407 : 4217396 : }
12408 : :
12409 : : /* Return true if OP refers to a TLS address. */
12410 : : bool
12411 : 214763177 : ix86_tls_address_pattern_p (rtx op)
12412 : : {
12413 : 214763177 : subrtx_var_iterator::array_type array;
12414 : 1264785375 : FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
12415 : : {
12416 : 1050037623 : rtx op = *iter;
12417 : 1050037623 : if (MEM_P (op))
12418 : : {
12419 : 96086568 : rtx *x = &XEXP (op, 0);
12420 : 150125242 : while (GET_CODE (*x) == PLUS)
12421 : : {
12422 : : int i;
12423 : 162131470 : for (i = 0; i < 2; i++)
12424 : : {
12425 : 108092796 : rtx u = XEXP (*x, i);
12426 : 108092796 : if (GET_CODE (u) == ZERO_EXTEND)
12427 : 98837 : u = XEXP (u, 0);
12428 : 108092796 : if (GET_CODE (u) == UNSPEC
12429 : 15447 : && XINT (u, 1) == UNSPEC_TP)
12430 : 15425 : return true;
12431 : : }
12432 : 54038674 : x = &XEXP (*x, 0);
12433 : : }
12434 : :
12435 : 96071143 : iter.skip_subrtxes ();
12436 : : }
12437 : : }
12438 : :
12439 : 214747752 : return false;
12440 : 214763177 : }
12441 : :
12442 : : /* Rewrite *LOC so that it refers to a default TLS address space. */
12443 : : void
12444 : 15425 : ix86_rewrite_tls_address_1 (rtx *loc)
12445 : : {
12446 : 15425 : subrtx_ptr_iterator::array_type array;
12447 : 44976 : FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
12448 : : {
12449 : 44976 : rtx *loc = *iter;
12450 : 44976 : if (MEM_P (*loc))
12451 : : {
12452 : 15582 : rtx addr = XEXP (*loc, 0);
12453 : 15582 : rtx *x = &addr;
12454 : 20368 : while (GET_CODE (*x) == PLUS)
12455 : : {
12456 : : int i;
12457 : 29806 : for (i = 0; i < 2; i++)
12458 : : {
12459 : 25020 : rtx u = XEXP (*x, i);
12460 : 25020 : if (GET_CODE (u) == ZERO_EXTEND)
12461 : 3 : u = XEXP (u, 0);
12462 : 25020 : if (GET_CODE (u) == UNSPEC
12463 : 15425 : && XINT (u, 1) == UNSPEC_TP)
12464 : : {
12465 : 15425 : addr_space_t as = DEFAULT_TLS_SEG_REG;
12466 : :
12467 : 15425 : *x = XEXP (*x, 1 - i);
12468 : :
12469 : 15425 : *loc = replace_equiv_address_nv (*loc, addr, true);
12470 : 15425 : set_mem_addr_space (*loc, as);
12471 : 15425 : return;
12472 : : }
12473 : : }
12474 : 4786 : x = &XEXP (*x, 0);
12475 : : }
12476 : :
12477 : 157 : iter.skip_subrtxes ();
12478 : : }
12479 : : }
12480 : 15425 : }
12481 : :
12482 : : /* Rewrite instruction pattern involvning TLS address
12483 : : so that it refers to a default TLS address space. */
12484 : : rtx
12485 : 15425 : ix86_rewrite_tls_address (rtx pattern)
12486 : : {
12487 : 15425 : pattern = copy_insn (pattern);
12488 : 15425 : ix86_rewrite_tls_address_1 (&pattern);
12489 : 15425 : return pattern;
12490 : : }
12491 : :
12492 : : /* Create or return the unique __imp_DECL dllimport symbol corresponding
12493 : : to symbol DECL if BEIMPORT is true. Otherwise create or return the
12494 : : unique refptr-DECL symbol corresponding to symbol DECL. */
12495 : :
12496 : : struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
12497 : : {
12498 : 0 : static inline hashval_t hash (tree_map *m) { return m->hash; }
12499 : : static inline bool
12500 : 0 : equal (tree_map *a, tree_map *b)
12501 : : {
12502 : 0 : return a->base.from == b->base.from;
12503 : : }
12504 : :
12505 : : static int
12506 : 0 : keep_cache_entry (tree_map *&m)
12507 : : {
12508 : 0 : return ggc_marked_p (m->base.from);
12509 : : }
12510 : : };
12511 : :
12512 : : static GTY((cache)) hash_table<dllimport_hasher> *dllimport_map;
12513 : :
12514 : : static tree
12515 : 0 : get_dllimport_decl (tree decl, bool beimport)
12516 : : {
12517 : 0 : struct tree_map *h, in;
12518 : 0 : const char *name;
12519 : 0 : const char *prefix;
12520 : 0 : size_t namelen, prefixlen;
12521 : 0 : char *imp_name;
12522 : 0 : tree to;
12523 : 0 : rtx rtl;
12524 : :
12525 : 0 : if (!dllimport_map)
12526 : 0 : dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
12527 : :
12528 : 0 : in.hash = htab_hash_pointer (decl);
12529 : 0 : in.base.from = decl;
12530 : 0 : tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
12531 : 0 : h = *loc;
12532 : 0 : if (h)
12533 : 0 : return h->to;
12534 : :
12535 : 0 : *loc = h = ggc_alloc<tree_map> ();
12536 : 0 : h->hash = in.hash;
12537 : 0 : h->base.from = decl;
12538 : 0 : h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
12539 : : VAR_DECL, NULL, ptr_type_node);
12540 : 0 : DECL_ARTIFICIAL (to) = 1;
12541 : 0 : DECL_IGNORED_P (to) = 1;
12542 : 0 : DECL_EXTERNAL (to) = 1;
12543 : 0 : TREE_READONLY (to) = 1;
12544 : :
12545 : 0 : name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
12546 : 0 : name = targetm.strip_name_encoding (name);
12547 : 0 : if (beimport)
12548 : 0 : prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
12549 : 0 : ? "*__imp_" : "*__imp__";
12550 : : else
12551 : 0 : prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
12552 : 0 : namelen = strlen (name);
12553 : 0 : prefixlen = strlen (prefix);
12554 : 0 : imp_name = (char *) alloca (namelen + prefixlen + 1);
12555 : 0 : memcpy (imp_name, prefix, prefixlen);
12556 : 0 : memcpy (imp_name + prefixlen, name, namelen + 1);
12557 : :
12558 : 0 : name = ggc_alloc_string (imp_name, namelen + prefixlen);
12559 : 0 : rtl = gen_rtx_SYMBOL_REF (Pmode, name);
12560 : 0 : SET_SYMBOL_REF_DECL (rtl, to);
12561 : 0 : SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
12562 : 0 : if (!beimport)
12563 : : {
12564 : 0 : SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
12565 : : #ifdef SUB_TARGET_RECORD_STUB
12566 : : SUB_TARGET_RECORD_STUB (name);
12567 : : #endif
12568 : : }
12569 : :
12570 : 0 : rtl = gen_const_mem (Pmode, rtl);
12571 : 0 : set_mem_alias_set (rtl, ix86_GOT_alias_set ());
12572 : :
12573 : 0 : SET_DECL_RTL (to, rtl);
12574 : 0 : SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
12575 : :
12576 : 0 : return to;
12577 : : }
12578 : :
12579 : : /* Expand SYMBOL into its corresponding far-address symbol.
12580 : : WANT_REG is true if we require the result be a register. */
12581 : :
12582 : : static rtx
12583 : 0 : legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
12584 : : {
12585 : 0 : tree imp_decl;
12586 : 0 : rtx x;
12587 : :
12588 : 0 : gcc_assert (SYMBOL_REF_DECL (symbol));
12589 : 0 : imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
12590 : :
12591 : 0 : x = DECL_RTL (imp_decl);
12592 : 0 : if (want_reg)
12593 : 0 : x = force_reg (Pmode, x);
12594 : 0 : return x;
12595 : : }
12596 : :
12597 : : /* Expand SYMBOL into its corresponding dllimport symbol. WANT_REG is
12598 : : true if we require the result be a register. */
12599 : :
12600 : : static rtx
12601 : 0 : legitimize_dllimport_symbol (rtx symbol, bool want_reg)
12602 : : {
12603 : 0 : tree imp_decl;
12604 : 0 : rtx x;
12605 : :
12606 : 0 : gcc_assert (SYMBOL_REF_DECL (symbol));
12607 : 0 : imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
12608 : :
12609 : 0 : x = DECL_RTL (imp_decl);
12610 : 0 : if (want_reg)
12611 : 0 : x = force_reg (Pmode, x);
12612 : 0 : return x;
12613 : : }
12614 : :
12615 : : /* Expand SYMBOL into its corresponding dllimport or refptr symbol. WANT_REG
12616 : : is true if we require the result be a register. */
12617 : :
12618 : : rtx
12619 : 4828360 : legitimize_pe_coff_symbol (rtx addr, bool inreg)
12620 : : {
12621 : 4828360 : if (!TARGET_PECOFF)
12622 : 4828360 : return NULL_RTX;
12623 : :
12624 : : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
12625 : : {
12626 : : if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
12627 : : return legitimize_dllimport_symbol (addr, inreg);
12628 : : if (GET_CODE (addr) == CONST
12629 : : && GET_CODE (XEXP (addr, 0)) == PLUS
12630 : : && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
12631 : : && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
12632 : : {
12633 : : rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
12634 : : return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
12635 : : }
12636 : : }
12637 : :
12638 : : if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
12639 : : return NULL_RTX;
12640 : : if (GET_CODE (addr) == SYMBOL_REF
12641 : : && !is_imported_p (addr)
12642 : : && SYMBOL_REF_EXTERNAL_P (addr)
12643 : : && SYMBOL_REF_DECL (addr))
12644 : : return legitimize_pe_coff_extern_decl (addr, inreg);
12645 : :
12646 : : if (GET_CODE (addr) == CONST
12647 : : && GET_CODE (XEXP (addr, 0)) == PLUS
12648 : : && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
12649 : : && !is_imported_p (XEXP (XEXP (addr, 0), 0))
12650 : : && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
12651 : : && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
12652 : : {
12653 : : rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
12654 : : return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
12655 : : }
12656 : : return NULL_RTX;
12657 : : }
12658 : :
12659 : : /* Try machine-dependent ways of modifying an illegitimate address
12660 : : to be legitimate. If we find one, return the new, valid address.
12661 : : This macro is used in only one place: `memory_address' in explow.cc.
12662 : :
12663 : : OLDX is the address as it was before break_out_memory_refs was called.
12664 : : In some cases it is useful to look at this to decide what needs to be done.
12665 : :
12666 : : It is always safe for this macro to do nothing. It exists to recognize
12667 : : opportunities to optimize the output.
12668 : :
12669 : : For the 80386, we handle X+REG by loading X into a register R and
12670 : : using R+REG. R will go in a general reg and indexing will be used.
12671 : : However, if REG is a broken-out memory address or multiplication,
12672 : : nothing needs to be done because REG can certainly go in a general reg.
12673 : :
12674 : : When -fpic is used, special handling is needed for symbolic references.
12675 : : See comments by legitimize_pic_address in i386.cc for details. */
12676 : :
12677 : : static rtx
12678 : 587358 : ix86_legitimize_address (rtx x, rtx, machine_mode mode)
12679 : : {
12680 : 587358 : bool changed = false;
12681 : 587358 : unsigned log;
12682 : :
12683 : 587358 : log = GET_CODE (x) == SYMBOL_REF ? SYMBOL_REF_TLS_MODEL (x) : 0;
12684 : 149592 : if (log)
12685 : 18975 : return legitimize_tls_address (x, (enum tls_model) log, false);
12686 : 568383 : if (GET_CODE (x) == CONST
12687 : 431 : && GET_CODE (XEXP (x, 0)) == PLUS
12688 : 431 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
12689 : 568814 : && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
12690 : : {
12691 : 4 : rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
12692 : : (enum tls_model) log, false);
12693 : 4 : return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
12694 : : }
12695 : :
12696 : 568379 : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
12697 : : {
12698 : : rtx tmp = legitimize_pe_coff_symbol (x, true);
12699 : : if (tmp)
12700 : : return tmp;
12701 : : }
12702 : :
12703 : 568379 : if (flag_pic && SYMBOLIC_CONST (x))
12704 : 130925 : return legitimize_pic_address (x, 0);
12705 : :
12706 : : #if TARGET_MACHO
12707 : : if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
12708 : : return machopic_indirect_data_reference (x, 0);
12709 : : #endif
12710 : :
12711 : : /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
12712 : 437454 : if (GET_CODE (x) == ASHIFT
12713 : 0 : && CONST_INT_P (XEXP (x, 1))
12714 : 0 : && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
12715 : : {
12716 : 0 : changed = true;
12717 : 0 : log = INTVAL (XEXP (x, 1));
12718 : 0 : x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
12719 : : GEN_INT (1 << log));
12720 : : }
12721 : :
12722 : 437454 : if (GET_CODE (x) == PLUS)
12723 : : {
12724 : : /* Canonicalize shifts by 0, 1, 2, 3 into multiply. */
12725 : :
12726 : 117877 : if (GET_CODE (XEXP (x, 0)) == ASHIFT
12727 : 567 : && CONST_INT_P (XEXP (XEXP (x, 0), 1))
12728 : 567 : && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
12729 : : {
12730 : 567 : changed = true;
12731 : 567 : log = INTVAL (XEXP (XEXP (x, 0), 1));
12732 : 567 : XEXP (x, 0) = gen_rtx_MULT (Pmode,
12733 : : force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
12734 : : GEN_INT (1 << log));
12735 : : }
12736 : :
12737 : 117877 : if (GET_CODE (XEXP (x, 1)) == ASHIFT
12738 : 0 : && CONST_INT_P (XEXP (XEXP (x, 1), 1))
12739 : 0 : && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
12740 : : {
12741 : 0 : changed = true;
12742 : 0 : log = INTVAL (XEXP (XEXP (x, 1), 1));
12743 : 0 : XEXP (x, 1) = gen_rtx_MULT (Pmode,
12744 : : force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
12745 : : GEN_INT (1 << log));
12746 : : }
12747 : :
12748 : : /* Put multiply first if it isn't already. */
12749 : 117877 : if (GET_CODE (XEXP (x, 1)) == MULT)
12750 : : {
12751 : 0 : std::swap (XEXP (x, 0), XEXP (x, 1));
12752 : 0 : changed = true;
12753 : : }
12754 : :
12755 : : /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
12756 : : into (plus (plus (mult (reg) (const)) (reg)) (const)). This can be
12757 : : created by virtual register instantiation, register elimination, and
12758 : : similar optimizations. */
12759 : 117877 : if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
12760 : : {
12761 : 9306 : changed = true;
12762 : 9306 : x = gen_rtx_PLUS (Pmode,
12763 : : gen_rtx_PLUS (Pmode, XEXP (x, 0),
12764 : : XEXP (XEXP (x, 1), 0)),
12765 : : XEXP (XEXP (x, 1), 1));
12766 : : }
12767 : :
12768 : : /* Canonicalize
12769 : : (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
12770 : : into (plus (plus (mult (reg) (const)) (reg)) (const)). */
12771 : 108571 : else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
12772 : 71752 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
12773 : 45893 : && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
12774 : 0 : && CONSTANT_P (XEXP (x, 1)))
12775 : : {
12776 : 0 : rtx constant;
12777 : 0 : rtx other = NULL_RTX;
12778 : :
12779 : 0 : if (CONST_INT_P (XEXP (x, 1)))
12780 : : {
12781 : 0 : constant = XEXP (x, 1);
12782 : 0 : other = XEXP (XEXP (XEXP (x, 0), 1), 1);
12783 : : }
12784 : 0 : else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
12785 : : {
12786 : : constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
12787 : : other = XEXP (x, 1);
12788 : : }
12789 : : else
12790 : : constant = 0;
12791 : :
12792 : 0 : if (constant)
12793 : : {
12794 : 0 : changed = true;
12795 : 0 : x = gen_rtx_PLUS (Pmode,
12796 : : gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
12797 : : XEXP (XEXP (XEXP (x, 0), 1), 0)),
12798 : : plus_constant (Pmode, other,
12799 : : INTVAL (constant)));
12800 : : }
12801 : : }
12802 : :
12803 : 117877 : if (changed && ix86_legitimate_address_p (mode, x, false))
12804 : 9350 : return x;
12805 : :
12806 : 108527 : if (GET_CODE (XEXP (x, 0)) == MULT)
12807 : : {
12808 : 18382 : changed = true;
12809 : 18382 : XEXP (x, 0) = copy_addr_to_reg (XEXP (x, 0));
12810 : : }
12811 : :
12812 : 108527 : if (GET_CODE (XEXP (x, 1)) == MULT)
12813 : : {
12814 : 0 : changed = true;
12815 : 0 : XEXP (x, 1) = copy_addr_to_reg (XEXP (x, 1));
12816 : : }
12817 : :
12818 : 108527 : if (changed
12819 : 18391 : && REG_P (XEXP (x, 1))
12820 : 14929 : && REG_P (XEXP (x, 0)))
12821 : : return x;
12822 : :
12823 : 93598 : if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
12824 : : {
12825 : 1793 : changed = true;
12826 : 1793 : x = legitimize_pic_address (x, 0);
12827 : : }
12828 : :
12829 : 93598 : if (changed && ix86_legitimate_address_p (mode, x, false))
12830 : 3719 : return x;
12831 : :
12832 : 89879 : if (REG_P (XEXP (x, 0)))
12833 : : {
12834 : 17654 : rtx temp = gen_reg_rtx (Pmode);
12835 : 17654 : rtx val = force_operand (XEXP (x, 1), temp);
12836 : 17654 : if (val != temp)
12837 : : {
12838 : 9432 : val = convert_to_mode (Pmode, val, 1);
12839 : 9432 : emit_move_insn (temp, val);
12840 : : }
12841 : :
12842 : 17654 : XEXP (x, 1) = temp;
12843 : 17654 : return x;
12844 : : }
12845 : :
12846 : 72225 : else if (REG_P (XEXP (x, 1)))
12847 : : {
12848 : 2554 : rtx temp = gen_reg_rtx (Pmode);
12849 : 2554 : rtx val = force_operand (XEXP (x, 0), temp);
12850 : 2554 : if (val != temp)
12851 : : {
12852 : 0 : val = convert_to_mode (Pmode, val, 1);
12853 : 0 : emit_move_insn (temp, val);
12854 : : }
12855 : :
12856 : 2554 : XEXP (x, 0) = temp;
12857 : 2554 : return x;
12858 : : }
12859 : : }
12860 : :
12861 : : return x;
12862 : : }
12863 : :
12864 : : /* Print an integer constant expression in assembler syntax. Addition
12865 : : and subtraction are the only arithmetic that may appear in these
12866 : : expressions. FILE is the stdio stream to write to, X is the rtx, and
12867 : : CODE is the operand print code from the output string. */
12868 : :
12869 : : static void
12870 : 3340280 : output_pic_addr_const (FILE *file, rtx x, int code)
12871 : : {
12872 : 3562487 : char buf[256];
12873 : :
12874 : 3562487 : switch (GET_CODE (x))
12875 : : {
12876 : 0 : case PC:
12877 : 0 : gcc_assert (flag_pic);
12878 : 0 : putc ('.', file);
12879 : 0 : break;
12880 : :
12881 : 836441 : case SYMBOL_REF:
12882 : 836441 : if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
12883 : 836441 : output_addr_const (file, x);
12884 : : else
12885 : : {
12886 : : const char *name = XSTR (x, 0);
12887 : :
12888 : : /* Mark the decl as referenced so that cgraph will
12889 : : output the function. */
12890 : : if (SYMBOL_REF_DECL (x))
12891 : : mark_decl_referenced (SYMBOL_REF_DECL (x));
12892 : :
12893 : : #if TARGET_MACHO
12894 : : if (MACHOPIC_INDIRECT
12895 : : && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
12896 : : name = machopic_indirection_name (x, /*stub_p=*/true);
12897 : : #endif
12898 : : assemble_name (file, name);
12899 : : }
12900 : 836441 : if (!TARGET_MACHO && !(TARGET_64BIT && TARGET_PECOFF)
12901 : 836441 : && code == 'P' && ix86_call_use_plt_p (x))
12902 : 385825 : fputs ("@PLT", file);
12903 : : break;
12904 : :
12905 : 2588 : case LABEL_REF:
12906 : 2588 : x = XEXP (x, 0);
12907 : : /* FALLTHRU */
12908 : 2588 : case CODE_LABEL:
12909 : 2588 : ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
12910 : 2588 : assemble_name (asm_out_file, buf);
12911 : 2588 : break;
12912 : :
12913 : 2305184 : CASE_CONST_SCALAR_INT:
12914 : 2305184 : output_addr_const (file, x);
12915 : 2305184 : break;
12916 : :
12917 : 204641 : case CONST:
12918 : : /* This used to output parentheses around the expression,
12919 : : but that does not work on the 386 (either ATT or BSD assembler). */
12920 : 204641 : output_pic_addr_const (file, XEXP (x, 0), code);
12921 : 204641 : break;
12922 : :
12923 : 0 : case CONST_DOUBLE:
12924 : : /* We can't handle floating point constants;
12925 : : TARGET_PRINT_OPERAND must handle them. */
12926 : 0 : output_operand_lossage ("floating constant misused");
12927 : 0 : break;
12928 : :
12929 : 17566 : case PLUS:
12930 : : /* Some assemblers need integer constants to appear first. */
12931 : 17566 : if (CONST_INT_P (XEXP (x, 0)))
12932 : : {
12933 : 0 : output_pic_addr_const (file, XEXP (x, 0), code);
12934 : 0 : putc ('+', file);
12935 : 0 : output_pic_addr_const (file, XEXP (x, 1), code);
12936 : : }
12937 : : else
12938 : : {
12939 : 17566 : gcc_assert (CONST_INT_P (XEXP (x, 1)));
12940 : 17566 : output_pic_addr_const (file, XEXP (x, 1), code);
12941 : 17566 : putc ('+', file);
12942 : 17566 : output_pic_addr_const (file, XEXP (x, 0), code);
12943 : : }
12944 : : break;
12945 : :
12946 : 0 : case MINUS:
12947 : 0 : if (!TARGET_MACHO)
12948 : 0 : putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
12949 : 0 : output_pic_addr_const (file, XEXP (x, 0), code);
12950 : 0 : putc ('-', file);
12951 : 0 : output_pic_addr_const (file, XEXP (x, 1), code);
12952 : 0 : if (!TARGET_MACHO)
12953 : 0 : putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
12954 : 0 : break;
12955 : :
12956 : 196067 : case UNSPEC:
12957 : 196067 : gcc_assert (XVECLEN (x, 0) == 1);
12958 : 196067 : output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
12959 : 196067 : switch (XINT (x, 1))
12960 : : {
12961 : 42461 : case UNSPEC_GOT:
12962 : 42461 : fputs ("@GOT", file);
12963 : 42461 : break;
12964 : 78356 : case UNSPEC_GOTOFF:
12965 : 78356 : fputs ("@GOTOFF", file);
12966 : 78356 : break;
12967 : 34 : case UNSPEC_PLTOFF:
12968 : 34 : fputs ("@PLTOFF", file);
12969 : 34 : break;
12970 : 0 : case UNSPEC_PCREL:
12971 : 0 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
12972 : : "(%rip)" : "[rip]", file);
12973 : 0 : break;
12974 : 71253 : case UNSPEC_GOTPCREL:
12975 : 71253 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
12976 : : "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
12977 : 71253 : break;
12978 : 0 : case UNSPEC_GOTTPOFF:
12979 : : /* FIXME: This might be @TPOFF in Sun ld too. */
12980 : 0 : fputs ("@gottpoff", file);
12981 : 0 : break;
12982 : 0 : case UNSPEC_TPOFF:
12983 : 0 : fputs ("@tpoff", file);
12984 : 0 : break;
12985 : 1353 : case UNSPEC_NTPOFF:
12986 : 1353 : if (TARGET_64BIT)
12987 : 1353 : fputs ("@tpoff", file);
12988 : : else
12989 : 0 : fputs ("@ntpoff", file);
12990 : : break;
12991 : 304 : case UNSPEC_DTPOFF:
12992 : 304 : fputs ("@dtpoff", file);
12993 : 304 : break;
12994 : 2306 : case UNSPEC_GOTNTPOFF:
12995 : 2306 : if (TARGET_64BIT)
12996 : 2055 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
12997 : : "@gottpoff(%rip)": "@gottpoff[rip]", file);
12998 : : else
12999 : 251 : fputs ("@gotntpoff", file);
13000 : : break;
13001 : 0 : case UNSPEC_INDNTPOFF:
13002 : 0 : fputs ("@indntpoff", file);
13003 : 0 : break;
13004 : : #if TARGET_MACHO
13005 : : case UNSPEC_MACHOPIC_OFFSET:
13006 : : putc ('-', file);
13007 : : machopic_output_function_base_name (file);
13008 : : break;
13009 : : #endif
13010 : 0 : default:
13011 : 0 : output_operand_lossage ("invalid UNSPEC as operand");
13012 : 0 : break;
13013 : : }
13014 : : break;
13015 : :
13016 : 0 : default:
13017 : 0 : output_operand_lossage ("invalid expression as operand");
13018 : : }
13019 : 3340280 : }
13020 : :
13021 : : /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
13022 : : We need to emit DTP-relative relocations. */
13023 : :
13024 : : static void ATTRIBUTE_UNUSED
13025 : 708 : i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
13026 : : {
13027 : 708 : fputs (ASM_LONG, file);
13028 : 708 : output_addr_const (file, x);
13029 : 708 : fputs ("@dtpoff", file);
13030 : 708 : switch (size)
13031 : : {
13032 : : case 4:
13033 : : break;
13034 : 536 : case 8:
13035 : 536 : fputs (", 0", file);
13036 : 536 : break;
13037 : 0 : default:
13038 : 0 : gcc_unreachable ();
13039 : : }
13040 : 708 : }
13041 : :
13042 : : /* Return true if X is a representation of the PIC register. This copes
13043 : : with calls from ix86_find_base_term, where the register might have
13044 : : been replaced by a cselib value. */
13045 : :
13046 : : static bool
13047 : 25477545 : ix86_pic_register_p (rtx x)
13048 : : {
13049 : 25477545 : if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
13050 : 799703 : return (pic_offset_table_rtx
13051 : 799703 : && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
13052 : 24677842 : else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SET_GOT)
13053 : : return true;
13054 : 24677456 : else if (!REG_P (x))
13055 : : return false;
13056 : 24110055 : else if (pic_offset_table_rtx)
13057 : : {
13058 : 24102542 : if (REGNO (x) == REGNO (pic_offset_table_rtx))
13059 : : return true;
13060 : 287709 : if (HARD_REGISTER_P (x)
13061 : 266397 : && !HARD_REGISTER_P (pic_offset_table_rtx)
13062 : 554106 : && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
13063 : : return true;
13064 : : return false;
13065 : : }
13066 : : else
13067 : 7513 : return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
13068 : : }
13069 : :
13070 : : /* Helper function for ix86_delegitimize_address.
13071 : : Attempt to delegitimize TLS local-exec accesses. */
13072 : :
13073 : : static rtx
13074 : 3511091911 : ix86_delegitimize_tls_address (rtx orig_x)
13075 : : {
13076 : 3511091911 : rtx x = orig_x, unspec;
13077 : 3511091911 : struct ix86_address addr;
13078 : :
13079 : 3511091911 : if (!TARGET_TLS_DIRECT_SEG_REFS)
13080 : : return orig_x;
13081 : 3511091911 : if (MEM_P (x))
13082 : 40091367 : x = XEXP (x, 0);
13083 : 3511091911 : if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
13084 : : return orig_x;
13085 : 1681043284 : if (ix86_decompose_address (x, &addr) == 0
13086 : 1965486642 : || addr.seg != DEFAULT_TLS_SEG_REG
13087 : 227302 : || addr.disp == NULL_RTX
13088 : 1681224519 : || GET_CODE (addr.disp) != CONST)
13089 : : return orig_x;
13090 : 89026 : unspec = XEXP (addr.disp, 0);
13091 : 89026 : if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
13092 : 58880 : unspec = XEXP (unspec, 0);
13093 : 89026 : if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
13094 : : return orig_x;
13095 : 89026 : x = XVECEXP (unspec, 0, 0);
13096 : 89026 : gcc_assert (GET_CODE (x) == SYMBOL_REF);
13097 : 89026 : if (unspec != XEXP (addr.disp, 0))
13098 : 58880 : x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
13099 : 89026 : if (addr.index)
13100 : : {
13101 : 182 : rtx idx = addr.index;
13102 : 182 : if (addr.scale != 1)
13103 : 182 : idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
13104 : 182 : x = gen_rtx_PLUS (Pmode, idx, x);
13105 : : }
13106 : 89026 : if (addr.base)
13107 : 2 : x = gen_rtx_PLUS (Pmode, addr.base, x);
13108 : 89026 : if (MEM_P (orig_x))
13109 : 132 : x = replace_equiv_address_nv (orig_x, x);
13110 : : return x;
13111 : : }
13112 : :
13113 : : /* In the name of slightly smaller debug output, and to cater to
13114 : : general assembler lossage, recognize PIC+GOTOFF and turn it back
13115 : : into a direct symbol reference.
13116 : :
13117 : : On Darwin, this is necessary to avoid a crash, because Darwin
13118 : : has a different PIC label for each routine but the DWARF debugging
13119 : : information is not associated with any particular routine, so it's
13120 : : necessary to remove references to the PIC label from RTL stored by
13121 : : the DWARF output code.
13122 : :
13123 : : This helper is used in the normal ix86_delegitimize_address
13124 : : entrypoint (e.g. used in the target delegitimization hook) and
13125 : : in ix86_find_base_term. As compile time memory optimization, we
13126 : : avoid allocating rtxes that will not change anything on the outcome
13127 : : of the callers (find_base_value and find_base_term). */
13128 : :
13129 : : static inline rtx
13130 : 3534570980 : ix86_delegitimize_address_1 (rtx x, bool base_term_p)
13131 : : {
13132 : 3534570980 : rtx orig_x = delegitimize_mem_from_attrs (x);
13133 : : /* addend is NULL or some rtx if x is something+GOTOFF where
13134 : : something doesn't include the PIC register. */
13135 : 3534570980 : rtx addend = NULL_RTX;
13136 : : /* reg_addend is NULL or a multiple of some register. */
13137 : 3534570980 : rtx reg_addend = NULL_RTX;
13138 : : /* const_addend is NULL or a const_int. */
13139 : 3534570980 : rtx const_addend = NULL_RTX;
13140 : : /* This is the result, or NULL. */
13141 : 3534570980 : rtx result = NULL_RTX;
13142 : :
13143 : 3534570980 : x = orig_x;
13144 : :
13145 : 3534570980 : if (MEM_P (x))
13146 : 57996580 : x = XEXP (x, 0);
13147 : :
13148 : 3534570980 : if (TARGET_64BIT)
13149 : : {
13150 : 194673177 : if (GET_CODE (x) == CONST
13151 : 6361162 : && GET_CODE (XEXP (x, 0)) == PLUS
13152 : 4753258 : && GET_MODE (XEXP (x, 0)) == Pmode
13153 : 4753258 : && CONST_INT_P (XEXP (XEXP (x, 0), 1))
13154 : 4753258 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
13155 : 194673870 : && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
13156 : : {
13157 : : /* find_base_{value,term} only care about MEMs with arg_pointer_rtx
13158 : : base. A CONST can't be arg_pointer_rtx based. */
13159 : 0 : if (base_term_p && MEM_P (orig_x))
13160 : : return orig_x;
13161 : 0 : rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
13162 : 0 : x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
13163 : 0 : if (MEM_P (orig_x))
13164 : 0 : x = replace_equiv_address_nv (orig_x, x);
13165 : 0 : return x;
13166 : : }
13167 : :
13168 : 194673177 : if (GET_CODE (x) == CONST
13169 : 6361162 : && GET_CODE (XEXP (x, 0)) == UNSPEC
13170 : 1607904 : && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
13171 : 535531 : || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
13172 : 1072373 : && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
13173 : : {
13174 : 235844 : x = XVECEXP (XEXP (x, 0), 0, 0);
13175 : 235844 : if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
13176 : : {
13177 : 9 : x = lowpart_subreg (GET_MODE (orig_x), x, GET_MODE (x));
13178 : 9 : if (x == NULL_RTX)
13179 : : return orig_x;
13180 : : }
13181 : 235844 : return x;
13182 : : }
13183 : :
13184 : 194437333 : if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
13185 : 194436296 : return ix86_delegitimize_tls_address (orig_x);
13186 : :
13187 : : /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
13188 : : and -mcmodel=medium -fpic. */
13189 : : }
13190 : :
13191 : 3339898840 : if (GET_CODE (x) != PLUS
13192 : 1585935416 : || GET_CODE (XEXP (x, 1)) != CONST)
13193 : 3314975753 : return ix86_delegitimize_tls_address (orig_x);
13194 : :
13195 : 24923087 : if (ix86_pic_register_p (XEXP (x, 0)))
13196 : : /* %ebx + GOT/GOTOFF */
13197 : : ;
13198 : 1286372 : else if (GET_CODE (XEXP (x, 0)) == PLUS)
13199 : : {
13200 : : /* %ebx + %reg * scale + GOT/GOTOFF */
13201 : 486389 : reg_addend = XEXP (x, 0);
13202 : 486389 : if (ix86_pic_register_p (XEXP (reg_addend, 0)))
13203 : 418320 : reg_addend = XEXP (reg_addend, 1);
13204 : 68069 : else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
13205 : 37757 : reg_addend = XEXP (reg_addend, 0);
13206 : : else
13207 : : {
13208 : 30312 : reg_addend = NULL_RTX;
13209 : 30312 : addend = XEXP (x, 0);
13210 : : }
13211 : : }
13212 : : else
13213 : : addend = XEXP (x, 0);
13214 : :
13215 : 24923087 : x = XEXP (XEXP (x, 1), 0);
13216 : 24923087 : if (GET_CODE (x) == PLUS
13217 : 1429964 : && CONST_INT_P (XEXP (x, 1)))
13218 : : {
13219 : 1429964 : const_addend = XEXP (x, 1);
13220 : 1429964 : x = XEXP (x, 0);
13221 : : }
13222 : :
13223 : 24923087 : if (GET_CODE (x) == UNSPEC
13224 : 24248990 : && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
13225 : 6579621 : || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
13226 : 1005765 : || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
13227 : 0 : && !MEM_P (orig_x) && !addend)))
13228 : 23243225 : result = XVECEXP (x, 0, 0);
13229 : :
13230 : 23243225 : if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
13231 : : && !MEM_P (orig_x))
13232 : : result = XVECEXP (x, 0, 0);
13233 : :
13234 : 23243225 : if (! result)
13235 : 1679862 : return ix86_delegitimize_tls_address (orig_x);
13236 : :
13237 : : /* For (PLUS something CONST_INT) both find_base_{value,term} just
13238 : : recurse on the first operand. */
13239 : 23243225 : if (const_addend && !base_term_p)
13240 : 87506 : result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
13241 : 23243225 : if (reg_addend)
13242 : 444565 : result = gen_rtx_PLUS (Pmode, reg_addend, result);
13243 : 23243225 : if (addend)
13244 : : {
13245 : : /* If the rest of original X doesn't involve the PIC register, add
13246 : : addend and subtract pic_offset_table_rtx. This can happen e.g.
13247 : : for code like:
13248 : : leal (%ebx, %ecx, 4), %ecx
13249 : : ...
13250 : : movl foo@GOTOFF(%ecx), %edx
13251 : : in which case we return (%ecx - %ebx) + foo
13252 : : or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
13253 : : and reload has completed. Don't do the latter for debug,
13254 : : as _GLOBAL_OFFSET_TABLE_ can't be expressed in the assembly. */
13255 : 131772 : if (pic_offset_table_rtx
13256 : 131772 : && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
13257 : 729 : result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
13258 : : pic_offset_table_rtx),
13259 : : result);
13260 : 131043 : else if (base_term_p
13261 : 126982 : && pic_offset_table_rtx
13262 : : && !TARGET_MACHO
13263 : : && !TARGET_VXWORKS_RTP)
13264 : : {
13265 : 126982 : rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
13266 : 126982 : tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
13267 : 126982 : result = gen_rtx_PLUS (Pmode, tmp, result);
13268 : 126982 : }
13269 : : else
13270 : : return orig_x;
13271 : : }
13272 : 23239164 : if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
13273 : : {
13274 : 0 : result = lowpart_subreg (GET_MODE (orig_x), result, Pmode);
13275 : 0 : if (result == NULL_RTX)
13276 : : return orig_x;
13277 : : }
13278 : : return result;
13279 : : }
13280 : :
13281 : : /* The normal instantiation of the above template. */
13282 : :
13283 : : static rtx
13284 : 257447420 : ix86_delegitimize_address (rtx x)
13285 : : {
13286 : 257447420 : return ix86_delegitimize_address_1 (x, false);
13287 : : }
13288 : :
13289 : : /* If X is a machine specific address (i.e. a symbol or label being
13290 : : referenced as a displacement from the GOT implemented using an
13291 : : UNSPEC), then return the base term. Otherwise return X. */
13292 : :
13293 : : rtx
13294 : 6364370519 : ix86_find_base_term (rtx x)
13295 : : {
13296 : 6364370519 : rtx term;
13297 : :
13298 : 6364370519 : if (TARGET_64BIT)
13299 : : {
13300 : 3087246959 : if (GET_CODE (x) != CONST)
13301 : : return x;
13302 : 28984186 : term = XEXP (x, 0);
13303 : 28984186 : if (GET_CODE (term) == PLUS
13304 : 28970357 : && CONST_INT_P (XEXP (term, 1)))
13305 : 28970357 : term = XEXP (term, 0);
13306 : 28984186 : if (GET_CODE (term) != UNSPEC
13307 : 37021 : || (XINT (term, 1) != UNSPEC_GOTPCREL
13308 : 37021 : && XINT (term, 1) != UNSPEC_PCREL))
13309 : : return x;
13310 : :
13311 : 0 : return XVECEXP (term, 0, 0);
13312 : : }
13313 : :
13314 : 3277123560 : return ix86_delegitimize_address_1 (x, true);
13315 : : }
13316 : :
13317 : : /* Return true if X shouldn't be emitted into the debug info.
13318 : : Disallow UNSPECs other than @gotoff - we can't emit _GLOBAL_OFFSET_TABLE_
13319 : : symbol easily into the .debug_info section, so we need not to
13320 : : delegitimize, but instead assemble as @gotoff.
13321 : : Disallow _GLOBAL_OFFSET_TABLE_ SYMBOL_REF - the assembler magically
13322 : : assembles that as _GLOBAL_OFFSET_TABLE_-. expression. */
13323 : :
13324 : : static bool
13325 : 1502877 : ix86_const_not_ok_for_debug_p (rtx x)
13326 : : {
13327 : 1502877 : if (GET_CODE (x) == UNSPEC && XINT (x, 1) != UNSPEC_GOTOFF)
13328 : : return true;
13329 : :
13330 : 1502857 : if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
13331 : 0 : return true;
13332 : :
13333 : : return false;
13334 : : }
13335 : :
13336 : : static void
13337 : 6240837 : put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
13338 : : bool fp, FILE *file)
13339 : : {
13340 : 6240837 : const char *suffix;
13341 : :
13342 : 6240837 : if (mode == CCFPmode)
13343 : : {
13344 : 541543 : code = ix86_fp_compare_code_to_integer (code);
13345 : 541543 : mode = CCmode;
13346 : : }
13347 : 6240837 : if (reverse)
13348 : 154246 : code = reverse_condition (code);
13349 : :
13350 : 6240837 : switch (code)
13351 : : {
13352 : 2447774 : case EQ:
13353 : 2447774 : gcc_assert (mode != CCGZmode);
13354 : 2447774 : switch (mode)
13355 : : {
13356 : : case E_CCAmode:
13357 : : suffix = "a";
13358 : : break;
13359 : : case E_CCCmode:
13360 : 27793 : suffix = "c";
13361 : : break;
13362 : : case E_CCOmode:
13363 : 6240837 : suffix = "o";
13364 : : break;
13365 : : case E_CCPmode:
13366 : 229839 : suffix = "p";
13367 : : break;
13368 : : case E_CCSmode:
13369 : 109213 : suffix = "s";
13370 : : break;
13371 : 2424931 : default:
13372 : 2424931 : suffix = "e";
13373 : 2424931 : break;
13374 : : }
13375 : : break;
13376 : 2051994 : case NE:
13377 : 2051994 : gcc_assert (mode != CCGZmode);
13378 : 2051994 : switch (mode)
13379 : : {
13380 : : case E_CCAmode:
13381 : : suffix = "na";
13382 : : break;
13383 : : case E_CCCmode:
13384 : 10993 : suffix = "nc";
13385 : : break;
13386 : 11661 : case E_CCOmode:
13387 : 11661 : suffix = "no";
13388 : 11661 : break;
13389 : : case E_CCPmode:
13390 : 4210 : suffix = "np";
13391 : : break;
13392 : : case E_CCSmode:
13393 : 51576 : suffix = "ns";
13394 : : break;
13395 : 2036389 : default:
13396 : 2036389 : suffix = "ne";
13397 : 2036389 : break;
13398 : : }
13399 : : break;
13400 : 168060 : case GT:
13401 : 168060 : gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
13402 : : suffix = "g";
13403 : : break;
13404 : 164480 : case GTU:
13405 : : /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
13406 : : Those same assemblers have the same but opposite lossage on cmov. */
13407 : 164480 : if (mode == CCmode)
13408 : 164480 : suffix = fp ? "nbe" : "a";
13409 : : else
13410 : 0 : gcc_unreachable ();
13411 : : break;
13412 : 204531 : case LT:
13413 : 204531 : switch (mode)
13414 : : {
13415 : : case E_CCNOmode:
13416 : : case E_CCGOCmode:
13417 : : suffix = "s";
13418 : : break;
13419 : :
13420 : : case E_CCmode:
13421 : : case E_CCGCmode:
13422 : : case E_CCGZmode:
13423 : 6240837 : suffix = "l";
13424 : : break;
13425 : :
13426 : 0 : default:
13427 : 0 : gcc_unreachable ();
13428 : : }
13429 : : break;
13430 : 381041 : case LTU:
13431 : 381041 : if (mode == CCmode || mode == CCGZmode)
13432 : : suffix = "b";
13433 : 23458 : else if (mode == CCCmode)
13434 : 23458 : suffix = fp ? "b" : "c";
13435 : : else
13436 : 0 : gcc_unreachable ();
13437 : : break;
13438 : 116742 : case GE:
13439 : 116742 : switch (mode)
13440 : : {
13441 : : case E_CCNOmode:
13442 : : case E_CCGOCmode:
13443 : : suffix = "ns";
13444 : : break;
13445 : :
13446 : : case E_CCmode:
13447 : : case E_CCGCmode:
13448 : : case E_CCGZmode:
13449 : 6240837 : suffix = "ge";
13450 : : break;
13451 : :
13452 : 0 : default:
13453 : 0 : gcc_unreachable ();
13454 : : }
13455 : : break;
13456 : 154943 : case GEU:
13457 : 154943 : if (mode == CCmode || mode == CCGZmode)
13458 : : suffix = "nb";
13459 : 7069 : else if (mode == CCCmode)
13460 : 7069 : suffix = fp ? "nb" : "nc";
13461 : : else
13462 : 0 : gcc_unreachable ();
13463 : : break;
13464 : 216789 : case LE:
13465 : 216789 : gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
13466 : : suffix = "le";
13467 : : break;
13468 : 100434 : case LEU:
13469 : 100434 : if (mode == CCmode)
13470 : : suffix = "be";
13471 : : else
13472 : 0 : gcc_unreachable ();
13473 : : break;
13474 : 229832 : case UNORDERED:
13475 : 229832 : suffix = fp ? "u" : "p";
13476 : : break;
13477 : 4217 : case ORDERED:
13478 : 4217 : suffix = fp ? "nu" : "np";
13479 : : break;
13480 : 0 : default:
13481 : 0 : gcc_unreachable ();
13482 : : }
13483 : 6240837 : fputs (suffix, file);
13484 : 6240837 : }
13485 : :
13486 : : /* Print the name of register X to FILE based on its machine mode and number.
13487 : : If CODE is 'w', pretend the mode is HImode.
13488 : : If CODE is 'b', pretend the mode is QImode.
13489 : : If CODE is 'k', pretend the mode is SImode.
13490 : : If CODE is 'q', pretend the mode is DImode.
13491 : : If CODE is 'x', pretend the mode is V4SFmode.
13492 : : If CODE is 't', pretend the mode is V8SFmode.
13493 : : If CODE is 'g', pretend the mode is V16SFmode.
13494 : : If CODE is 'h', pretend the reg is the 'high' byte register.
13495 : : If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
13496 : : If CODE is 'd', duplicate the operand for AVX instruction.
13497 : : If CODE is 'V', print naked full integer register name without %.
13498 : : */
13499 : :
13500 : : void
13501 : 113265859 : print_reg (rtx x, int code, FILE *file)
13502 : : {
13503 : 113265859 : const char *reg;
13504 : 113265859 : int msize;
13505 : 113265859 : unsigned int regno;
13506 : 113265859 : bool duplicated;
13507 : :
13508 : 113265859 : if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
13509 : 113264054 : putc ('%', file);
13510 : :
13511 : 113265859 : if (x == pc_rtx)
13512 : : {
13513 : 5467394 : gcc_assert (TARGET_64BIT);
13514 : 5467394 : fputs ("rip", file);
13515 : 5467394 : return;
13516 : : }
13517 : :
13518 : 107798465 : if (code == 'y' && STACK_TOP_P (x))
13519 : : {
13520 : 298066 : fputs ("st(0)", file);
13521 : 298066 : return;
13522 : : }
13523 : :
13524 : 107500399 : if (code == 'w')
13525 : : msize = 2;
13526 : : else if (code == 'b')
13527 : : msize = 1;
13528 : : else if (code == 'k')
13529 : : msize = 4;
13530 : : else if (code == 'q')
13531 : : msize = 8;
13532 : : else if (code == 'h')
13533 : : msize = 0;
13534 : : else if (code == 'x')
13535 : : msize = 16;
13536 : : else if (code == 't')
13537 : : msize = 32;
13538 : : else if (code == 'g')
13539 : : msize = 64;
13540 : : else
13541 : 184456832 : msize = GET_MODE_SIZE (GET_MODE (x));
13542 : :
13543 : 107500399 : regno = REGNO (x);
13544 : :
13545 : 107500399 : if (regno == ARG_POINTER_REGNUM
13546 : 107500399 : || regno == FRAME_POINTER_REGNUM
13547 : 107500399 : || regno == FPSR_REG)
13548 : : {
13549 : 0 : output_operand_lossage
13550 : 0 : ("invalid use of register '%s'", reg_names[regno]);
13551 : 0 : return;
13552 : : }
13553 : 107500399 : else if (regno == FLAGS_REG)
13554 : : {
13555 : 1 : output_operand_lossage ("invalid use of asm flag output");
13556 : 1 : return;
13557 : : }
13558 : :
13559 : 107500398 : if (code == 'V')
13560 : : {
13561 : 1 : if (GENERAL_REGNO_P (regno))
13562 : 2 : msize = GET_MODE_SIZE (word_mode);
13563 : : else
13564 : 0 : error ("%<V%> modifier on non-integer register");
13565 : : }
13566 : :
13567 : 107500398 : duplicated = code == 'd' && TARGET_AVX;
13568 : :
13569 : 107500398 : switch (msize)
13570 : : {
13571 : 69917162 : case 16:
13572 : 69917162 : case 12:
13573 : 69917162 : case 8:
13574 : 130566595 : if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
13575 : 5 : warning (0, "unsupported size for integer register");
13576 : : /* FALLTHRU */
13577 : 104324855 : case 4:
13578 : 104324855 : if (LEGACY_INT_REGNO_P (regno))
13579 : 114038328 : putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
13580 : : /* FALLTHRU */
13581 : 105122397 : case 2:
13582 : 20401474 : normal:
13583 : 105122397 : reg = hi_reg_name[regno];
13584 : 105122397 : break;
13585 : 2110270 : case 1:
13586 : 2110270 : if (regno >= ARRAY_SIZE (qi_reg_name))
13587 : 226046 : goto normal;
13588 : 1884224 : if (!ANY_QI_REGNO_P (regno))
13589 : 0 : error ("unsupported size for integer register");
13590 : 1884224 : reg = qi_reg_name[regno];
13591 : 1884224 : break;
13592 : 26472 : case 0:
13593 : 26472 : if (regno >= ARRAY_SIZE (qi_high_reg_name))
13594 : 0 : goto normal;
13595 : 26472 : reg = qi_high_reg_name[regno];
13596 : 26472 : break;
13597 : 467305 : case 32:
13598 : 467305 : case 64:
13599 : 467305 : if (SSE_REGNO_P (regno))
13600 : : {
13601 : 467305 : gcc_assert (!duplicated);
13602 : 641428 : putc (msize == 32 ? 'y' : 'z', file);
13603 : 467305 : reg = hi_reg_name[regno] + 1;
13604 : 467305 : break;
13605 : : }
13606 : 0 : goto normal;
13607 : 0 : default:
13608 : 0 : gcc_unreachable ();
13609 : : }
13610 : :
13611 : 107500398 : fputs (reg, file);
13612 : :
13613 : : /* Irritatingly, AMD extended registers use
13614 : : different naming convention: "r%d[bwd]" */
13615 : 107500398 : if (REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
13616 : : {
13617 : 9347703 : gcc_assert (TARGET_64BIT);
13618 : 9347703 : switch (msize)
13619 : : {
13620 : 0 : case 0:
13621 : 0 : error ("extended registers have no high halves");
13622 : 0 : break;
13623 : 155085 : case 1:
13624 : 155085 : putc ('b', file);
13625 : 155085 : break;
13626 : 26337 : case 2:
13627 : 26337 : putc ('w', file);
13628 : 26337 : break;
13629 : 2325282 : case 4:
13630 : 2325282 : putc ('d', file);
13631 : 2325282 : break;
13632 : : case 8:
13633 : : /* no suffix */
13634 : : break;
13635 : 0 : default:
13636 : 0 : error ("unsupported operand size for extended register");
13637 : 0 : break;
13638 : : }
13639 : 9347703 : return;
13640 : : }
13641 : :
13642 : 98152695 : if (duplicated)
13643 : : {
13644 : 16398 : if (ASSEMBLER_DIALECT == ASM_ATT)
13645 : 16379 : fprintf (file, ", %%%s", reg);
13646 : : else
13647 : 19 : fprintf (file, ", %s", reg);
13648 : : }
13649 : : }
13650 : :
13651 : : /* Meaning of CODE:
13652 : : L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
13653 : : C -- print opcode suffix for set/cmov insn.
13654 : : c -- like C, but print reversed condition
13655 : : F,f -- likewise, but for floating-point.
13656 : : O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
13657 : : otherwise nothing
13658 : : R -- print embedded rounding and sae.
13659 : : r -- print only sae.
13660 : : z -- print the opcode suffix for the size of the current operand.
13661 : : Z -- likewise, with special suffixes for x87 instructions.
13662 : : * -- print a star (in certain assembler syntax)
13663 : : A -- print an absolute memory reference.
13664 : : E -- print address with DImode register names if TARGET_64BIT.
13665 : : w -- print the operand as if it's a "word" (HImode) even if it isn't.
13666 : : s -- print a shift double count, followed by the assemblers argument
13667 : : delimiter.
13668 : : b -- print the QImode name of the register for the indicated operand.
13669 : : %b0 would print %al if operands[0] is reg 0.
13670 : : w -- likewise, print the HImode name of the register.
13671 : : k -- likewise, print the SImode name of the register.
13672 : : q -- likewise, print the DImode name of the register.
13673 : : x -- likewise, print the V4SFmode name of the register.
13674 : : t -- likewise, print the V8SFmode name of the register.
13675 : : g -- likewise, print the V16SFmode name of the register.
13676 : : h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
13677 : : y -- print "st(0)" instead of "st" as a register.
13678 : : d -- print duplicated register operand for AVX instruction.
13679 : : D -- print condition for SSE cmp instruction.
13680 : : P -- if PIC, print an @PLT suffix. For -fno-plt, load function
13681 : : address from GOT.
13682 : : p -- print raw symbol name.
13683 : : X -- don't print any sort of PIC '@' suffix for a symbol.
13684 : : & -- print some in-use local-dynamic symbol name.
13685 : : H -- print a memory address offset by 8; used for sse high-parts
13686 : : Y -- print condition for XOP pcom* instruction.
13687 : : V -- print naked full integer register name without %.
13688 : : + -- print a branch hint as 'cs' or 'ds' prefix
13689 : : ; -- print a semicolon (after prefixes due to bug in older gas).
13690 : : ~ -- print "i" if TARGET_AVX2, "f" otherwise.
13691 : : ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
13692 : : M -- print addr32 prefix for TARGET_X32 with VSIB address.
13693 : : ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
13694 : : N -- print maskz if it's constant 0 operand.
13695 : : */
13696 : :
13697 : : void
13698 : 161745189 : ix86_print_operand (FILE *file, rtx x, int code)
13699 : : {
13700 : 161939760 : if (code)
13701 : : {
13702 : 56102081 : switch (code)
13703 : : {
13704 : 194567 : case 'A':
13705 : 194567 : switch (ASSEMBLER_DIALECT)
13706 : : {
13707 : 194567 : case ASM_ATT:
13708 : 194567 : putc ('*', file);
13709 : 194567 : break;
13710 : :
13711 : 0 : case ASM_INTEL:
13712 : : /* Intel syntax. For absolute addresses, registers should not
13713 : : be surrounded by braces. */
13714 : 0 : if (!REG_P (x))
13715 : : {
13716 : 0 : putc ('[', file);
13717 : 0 : ix86_print_operand (file, x, 0);
13718 : 0 : putc (']', file);
13719 : 0 : return;
13720 : : }
13721 : : break;
13722 : :
13723 : 0 : default:
13724 : 0 : gcc_unreachable ();
13725 : : }
13726 : :
13727 : 194567 : ix86_print_operand (file, x, 0);
13728 : 194567 : return;
13729 : :
13730 : 2866559 : case 'E':
13731 : : /* Wrap address in an UNSPEC to declare special handling. */
13732 : 2866559 : if (TARGET_64BIT)
13733 : 2403550 : x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
13734 : :
13735 : 2866559 : output_address (VOIDmode, x);
13736 : 2866559 : return;
13737 : :
13738 : 0 : case 'L':
13739 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13740 : 0 : putc ('l', file);
13741 : 0 : return;
13742 : :
13743 : 0 : case 'W':
13744 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13745 : 0 : putc ('w', file);
13746 : 0 : return;
13747 : :
13748 : 0 : case 'B':
13749 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13750 : 0 : putc ('b', file);
13751 : 0 : return;
13752 : :
13753 : 0 : case 'Q':
13754 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13755 : 0 : putc ('l', file);
13756 : 0 : return;
13757 : :
13758 : 0 : case 'S':
13759 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13760 : 0 : putc ('s', file);
13761 : 0 : return;
13762 : :
13763 : 0 : case 'T':
13764 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
13765 : 0 : putc ('t', file);
13766 : 0 : return;
13767 : :
13768 : : case 'O':
13769 : : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
13770 : : if (ASSEMBLER_DIALECT != ASM_ATT)
13771 : : return;
13772 : :
13773 : : switch (GET_MODE_SIZE (GET_MODE (x)))
13774 : : {
13775 : : case 2:
13776 : : putc ('w', file);
13777 : : break;
13778 : :
13779 : : case 4:
13780 : : putc ('l', file);
13781 : : break;
13782 : :
13783 : : case 8:
13784 : : putc ('q', file);
13785 : : break;
13786 : :
13787 : : default:
13788 : : output_operand_lossage ("invalid operand size for operand "
13789 : : "code 'O'");
13790 : : return;
13791 : : }
13792 : :
13793 : : putc ('.', file);
13794 : : #endif
13795 : : return;
13796 : :
13797 : 36203 : case 'z':
13798 : 36203 : if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
13799 : : {
13800 : : /* Opcodes don't get size suffixes if using Intel opcodes. */
13801 : 36201 : if (ASSEMBLER_DIALECT == ASM_INTEL)
13802 : : return;
13803 : :
13804 : 72402 : switch (GET_MODE_SIZE (GET_MODE (x)))
13805 : : {
13806 : 6 : case 1:
13807 : 6 : putc ('b', file);
13808 : 6 : return;
13809 : :
13810 : 6 : case 2:
13811 : 6 : putc ('w', file);
13812 : 6 : return;
13813 : :
13814 : 35709 : case 4:
13815 : 35709 : putc ('l', file);
13816 : 35709 : return;
13817 : :
13818 : 480 : case 8:
13819 : 480 : putc ('q', file);
13820 : 480 : return;
13821 : :
13822 : 0 : default:
13823 : 0 : output_operand_lossage ("invalid operand size for operand "
13824 : : "code 'z'");
13825 : 0 : return;
13826 : : }
13827 : : }
13828 : :
13829 : 2 : if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
13830 : : {
13831 : 1 : if (this_is_asm_operands)
13832 : 1 : warning_for_asm (this_is_asm_operands,
13833 : : "non-integer operand used with operand code %<z%>");
13834 : : else
13835 : 0 : warning (0, "non-integer operand used with operand code %<z%>");
13836 : : }
13837 : : /* FALLTHRU */
13838 : :
13839 : 385642 : case 'Z':
13840 : : /* 387 opcodes don't get size suffixes if using Intel opcodes. */
13841 : 385642 : if (ASSEMBLER_DIALECT == ASM_INTEL)
13842 : : return;
13843 : :
13844 : 385642 : if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
13845 : : {
13846 : 29972 : switch (GET_MODE_SIZE (GET_MODE (x)))
13847 : : {
13848 : 3576 : case 2:
13849 : : #ifdef HAVE_AS_IX86_FILDS
13850 : 3576 : putc ('s', file);
13851 : : #endif
13852 : 3576 : return;
13853 : :
13854 : 3939 : case 4:
13855 : 3939 : putc ('l', file);
13856 : 3939 : return;
13857 : :
13858 : 7471 : case 8:
13859 : : #ifdef HAVE_AS_IX86_FILDQ
13860 : 7471 : putc ('q', file);
13861 : : #else
13862 : : fputs ("ll", file);
13863 : : #endif
13864 : 7471 : return;
13865 : :
13866 : : default:
13867 : : break;
13868 : : }
13869 : : }
13870 : 370656 : else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
13871 : : {
13872 : : /* 387 opcodes don't get size suffixes
13873 : : if the operands are registers. */
13874 : 370654 : if (STACK_REG_P (x))
13875 : : return;
13876 : :
13877 : 694046 : switch (GET_MODE_SIZE (GET_MODE (x)))
13878 : : {
13879 : 23163 : case 4:
13880 : 23163 : putc ('s', file);
13881 : 23163 : return;
13882 : :
13883 : 32679 : case 8:
13884 : 32679 : putc ('l', file);
13885 : 32679 : return;
13886 : :
13887 : 291179 : case 12:
13888 : 291179 : case 16:
13889 : 291179 : putc ('t', file);
13890 : 291179 : return;
13891 : :
13892 : : default:
13893 : : break;
13894 : : }
13895 : : }
13896 : : else
13897 : : {
13898 : 2 : output_operand_lossage ("invalid operand type used with "
13899 : : "operand code '%c'", code);
13900 : 2 : return;
13901 : : }
13902 : :
13903 : 2 : output_operand_lossage ("invalid operand size for operand code '%c'",
13904 : : code);
13905 : 2 : return;
13906 : :
13907 : : case 'd':
13908 : : case 'b':
13909 : : case 'w':
13910 : : case 'k':
13911 : : case 'q':
13912 : : case 'h':
13913 : : case 't':
13914 : : case 'g':
13915 : : case 'y':
13916 : : case 'x':
13917 : : case 'X':
13918 : : case 'P':
13919 : : case 'p':
13920 : : case 'V':
13921 : : break;
13922 : :
13923 : 0 : case 's':
13924 : 0 : if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
13925 : : {
13926 : 0 : ix86_print_operand (file, x, 0);
13927 : 0 : fputs (", ", file);
13928 : : }
13929 : 0 : return;
13930 : :
13931 : 531 : case 'Y':
13932 : 531 : switch (GET_CODE (x))
13933 : : {
13934 : 182 : case NE:
13935 : 182 : fputs ("neq", file);
13936 : 182 : break;
13937 : 32 : case EQ:
13938 : 32 : fputs ("eq", file);
13939 : 32 : break;
13940 : 64 : case GE:
13941 : 64 : case GEU:
13942 : 64 : fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
13943 : 64 : break;
13944 : 42 : case GT:
13945 : 42 : case GTU:
13946 : 42 : fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
13947 : 42 : break;
13948 : 64 : case LE:
13949 : 64 : case LEU:
13950 : 64 : fputs ("le", file);
13951 : 64 : break;
13952 : 147 : case LT:
13953 : 147 : case LTU:
13954 : 147 : fputs ("lt", file);
13955 : 147 : break;
13956 : 0 : case UNORDERED:
13957 : 0 : fputs ("unord", file);
13958 : 0 : break;
13959 : 0 : case ORDERED:
13960 : 0 : fputs ("ord", file);
13961 : 0 : break;
13962 : 0 : case UNEQ:
13963 : 0 : fputs ("ueq", file);
13964 : 0 : break;
13965 : 0 : case UNGE:
13966 : 0 : fputs ("nlt", file);
13967 : 0 : break;
13968 : 0 : case UNGT:
13969 : 0 : fputs ("nle", file);
13970 : 0 : break;
13971 : 0 : case UNLE:
13972 : 0 : fputs ("ule", file);
13973 : 0 : break;
13974 : 0 : case UNLT:
13975 : 0 : fputs ("ult", file);
13976 : 0 : break;
13977 : 0 : case LTGT:
13978 : 0 : fputs ("une", file);
13979 : 0 : break;
13980 : 0 : default:
13981 : 0 : output_operand_lossage ("operand is not a condition code, "
13982 : : "invalid operand code 'Y'");
13983 : 0 : return;
13984 : : }
13985 : 531 : return;
13986 : :
13987 : 8546 : case 'D':
13988 : : /* Little bit of braindamage here. The SSE compare instructions
13989 : : does use completely different names for the comparisons that the
13990 : : fp conditional moves. */
13991 : 8546 : switch (GET_CODE (x))
13992 : : {
13993 : 14 : case UNEQ:
13994 : 14 : if (TARGET_AVX)
13995 : : {
13996 : 14 : fputs ("eq_us", file);
13997 : 14 : break;
13998 : : }
13999 : : /* FALLTHRU */
14000 : 4356 : case EQ:
14001 : 4356 : fputs ("eq", file);
14002 : 4356 : break;
14003 : 0 : case UNLT:
14004 : 0 : if (TARGET_AVX)
14005 : : {
14006 : 0 : fputs ("nge", file);
14007 : 0 : break;
14008 : : }
14009 : : /* FALLTHRU */
14010 : 1410 : case LT:
14011 : 1410 : fputs ("lt", file);
14012 : 1410 : break;
14013 : 0 : case UNLE:
14014 : 0 : if (TARGET_AVX)
14015 : : {
14016 : 0 : fputs ("ngt", file);
14017 : 0 : break;
14018 : : }
14019 : : /* FALLTHRU */
14020 : 427 : case LE:
14021 : 427 : fputs ("le", file);
14022 : 427 : break;
14023 : 87 : case UNORDERED:
14024 : 87 : fputs ("unord", file);
14025 : 87 : break;
14026 : 0 : case LTGT:
14027 : 0 : if (TARGET_AVX)
14028 : : {
14029 : 0 : fputs ("neq_oq", file);
14030 : 0 : break;
14031 : : }
14032 : : /* FALLTHRU */
14033 : 1063 : case NE:
14034 : 1063 : fputs ("neq", file);
14035 : 1063 : break;
14036 : 0 : case GE:
14037 : 0 : if (TARGET_AVX)
14038 : : {
14039 : 0 : fputs ("ge", file);
14040 : 0 : break;
14041 : : }
14042 : : /* FALLTHRU */
14043 : 313 : case UNGE:
14044 : 313 : fputs ("nlt", file);
14045 : 313 : break;
14046 : 0 : case GT:
14047 : 0 : if (TARGET_AVX)
14048 : : {
14049 : 0 : fputs ("gt", file);
14050 : 0 : break;
14051 : : }
14052 : : /* FALLTHRU */
14053 : 785 : case UNGT:
14054 : 785 : fputs ("nle", file);
14055 : 785 : break;
14056 : 91 : case ORDERED:
14057 : 91 : fputs ("ord", file);
14058 : 91 : break;
14059 : 0 : default:
14060 : 0 : output_operand_lossage ("operand is not a condition code, "
14061 : : "invalid operand code 'D'");
14062 : 0 : return;
14063 : : }
14064 : 8546 : return;
14065 : :
14066 : 6240837 : case 'F':
14067 : 6240837 : case 'f':
14068 : : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
14069 : : if (ASSEMBLER_DIALECT == ASM_ATT)
14070 : : putc ('.', file);
14071 : : gcc_fallthrough ();
14072 : : #endif
14073 : :
14074 : 6240837 : case 'C':
14075 : 6240837 : case 'c':
14076 : 6240837 : if (!COMPARISON_P (x))
14077 : : {
14078 : 0 : output_operand_lossage ("operand is not a condition code, "
14079 : : "invalid operand code '%c'", code);
14080 : 0 : return;
14081 : : }
14082 : 6240837 : put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
14083 : 6240837 : code == 'c' || code == 'f',
14084 : 6240837 : code == 'F' || code == 'f',
14085 : : file);
14086 : 6240837 : return;
14087 : :
14088 : 395 : case 'H':
14089 : 395 : if (!offsettable_memref_p (x))
14090 : : {
14091 : 1 : output_operand_lossage ("operand is not an offsettable memory "
14092 : : "reference, invalid operand code 'H'");
14093 : 1 : return;
14094 : : }
14095 : : /* It doesn't actually matter what mode we use here, as we're
14096 : : only going to use this for printing. */
14097 : 394 : x = adjust_address_nv (x, DImode, 8);
14098 : : /* Output 'qword ptr' for intel assembler dialect. */
14099 : 394 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14100 : 0 : code = 'q';
14101 : : break;
14102 : :
14103 : 73789 : case 'K':
14104 : 73789 : if (!CONST_INT_P (x))
14105 : : {
14106 : 1 : output_operand_lossage ("operand is not an integer, invalid "
14107 : : "operand code 'K'");
14108 : 1 : return;
14109 : : }
14110 : :
14111 : 73788 : if (INTVAL (x) & IX86_HLE_ACQUIRE)
14112 : : #ifdef HAVE_AS_IX86_HLE
14113 : 22 : fputs ("xacquire ", file);
14114 : : #else
14115 : : fputs ("\n" ASM_BYTE "0xf2\n\t", file);
14116 : : #endif
14117 : 73766 : else if (INTVAL (x) & IX86_HLE_RELEASE)
14118 : : #ifdef HAVE_AS_IX86_HLE
14119 : 24 : fputs ("xrelease ", file);
14120 : : #else
14121 : : fputs ("\n" ASM_BYTE "0xf3\n\t", file);
14122 : : #endif
14123 : : /* We do not want to print value of the operand. */
14124 : 73788 : return;
14125 : :
14126 : 35171 : case 'N':
14127 : 35171 : if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
14128 : 12061 : fputs ("{z}", file);
14129 : 35171 : return;
14130 : :
14131 : 3731 : case 'r':
14132 : 3731 : if (!CONST_INT_P (x) || INTVAL (x) != ROUND_SAE)
14133 : : {
14134 : 2 : output_operand_lossage ("operand is not a specific integer, "
14135 : : "invalid operand code 'r'");
14136 : 2 : return;
14137 : : }
14138 : :
14139 : 3729 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14140 : 1 : fputs (", ", file);
14141 : :
14142 : 3729 : fputs ("{sae}", file);
14143 : :
14144 : 3729 : if (ASSEMBLER_DIALECT == ASM_ATT)
14145 : 3728 : fputs (", ", file);
14146 : :
14147 : 3729 : return;
14148 : :
14149 : 5823 : case 'R':
14150 : 5823 : if (!CONST_INT_P (x))
14151 : : {
14152 : 1 : output_operand_lossage ("operand is not an integer, invalid "
14153 : : "operand code 'R'");
14154 : 1 : return;
14155 : : }
14156 : :
14157 : 5822 : if (ASSEMBLER_DIALECT == ASM_INTEL)
14158 : 2 : fputs (", ", file);
14159 : :
14160 : 5822 : switch (INTVAL (x))
14161 : : {
14162 : 5015 : case ROUND_NEAREST_INT | ROUND_SAE:
14163 : 5015 : fputs ("{rn-sae}", file);
14164 : 5015 : break;
14165 : 637 : case ROUND_NEG_INF | ROUND_SAE:
14166 : 637 : fputs ("{rd-sae}", file);
14167 : 637 : break;
14168 : 52 : case ROUND_POS_INF | ROUND_SAE:
14169 : 52 : fputs ("{ru-sae}", file);
14170 : 52 : break;
14171 : 117 : case ROUND_ZERO | ROUND_SAE:
14172 : 117 : fputs ("{rz-sae}", file);
14173 : 117 : break;
14174 : 1 : default:
14175 : 1 : output_operand_lossage ("operand is not a specific integer, "
14176 : : "invalid operand code 'R'");
14177 : : }
14178 : :
14179 : 5822 : if (ASSEMBLER_DIALECT == ASM_ATT)
14180 : 5820 : fputs (", ", file);
14181 : :
14182 : 5822 : return;
14183 : :
14184 : 0 : case '*':
14185 : 0 : if (ASSEMBLER_DIALECT == ASM_ATT)
14186 : 0 : putc ('*', file);
14187 : 0 : return;
14188 : :
14189 : 269 : case '&':
14190 : 269 : {
14191 : 269 : const char *name = get_some_local_dynamic_name ();
14192 : 269 : if (name == NULL)
14193 : 1 : output_operand_lossage ("'%%&' used without any "
14194 : : "local dynamic TLS references");
14195 : : else
14196 : 268 : assemble_name (file, name);
14197 : 269 : return;
14198 : : }
14199 : :
14200 : 5710876 : case '+':
14201 : 5710876 : {
14202 : 5710876 : rtx x;
14203 : :
14204 : 5710876 : if (!optimize
14205 : 4477908 : || optimize_function_for_size_p (cfun)
14206 : 10016845 : || !TARGET_BRANCH_PREDICTION_HINTS)
14207 : 5710876 : return;
14208 : :
14209 : 0 : x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
14210 : 0 : if (x)
14211 : : {
14212 : 0 : int pred_val = profile_probability::from_reg_br_prob_note
14213 : 0 : (XINT (x, 0)).to_reg_br_prob_base ();
14214 : :
14215 : 0 : if (pred_val < REG_BR_PROB_BASE * 45 / 100
14216 : 0 : || pred_val > REG_BR_PROB_BASE * 55 / 100)
14217 : : {
14218 : 0 : bool taken = pred_val > REG_BR_PROB_BASE / 2;
14219 : 0 : bool cputaken
14220 : 0 : = final_forward_branch_p (current_output_insn) == 0;
14221 : :
14222 : : /* Emit hints only in the case default branch prediction
14223 : : heuristics would fail. */
14224 : 0 : if (taken != cputaken)
14225 : : {
14226 : : /* We use 3e (DS) prefix for taken branches and
14227 : : 2e (CS) prefix for not taken branches. */
14228 : 0 : if (taken)
14229 : 0 : fputs ("ds ; ", file);
14230 : : else
14231 : 0 : fputs ("cs ; ", file);
14232 : : }
14233 : : }
14234 : : }
14235 : 0 : return;
14236 : : }
14237 : :
14238 : : case ';':
14239 : : #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
14240 : : putc (';', file);
14241 : : #endif
14242 : : return;
14243 : :
14244 : 3421 : case '~':
14245 : 3421 : putc (TARGET_AVX2 ? 'i' : 'f', file);
14246 : 3421 : return;
14247 : :
14248 : 1900 : case 'M':
14249 : 1900 : if (TARGET_X32)
14250 : : {
14251 : : /* NB: 32-bit indices in VSIB address are sign-extended
14252 : : to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
14253 : : sign-extended to 0xfffffffff7fa3010 which is invalid
14254 : : address. Add addr32 prefix if there is no base
14255 : : register nor symbol. */
14256 : 44 : bool ok;
14257 : 44 : struct ix86_address parts;
14258 : 44 : ok = ix86_decompose_address (x, &parts);
14259 : 44 : gcc_assert (ok && parts.index == NULL_RTX);
14260 : 44 : if (parts.base == NULL_RTX
14261 : 44 : && (parts.disp == NULL_RTX
14262 : 36 : || !symbolic_operand (parts.disp,
14263 : 36 : GET_MODE (parts.disp))))
14264 : 36 : fputs ("addr32 ", file);
14265 : : }
14266 : 1900 : return;
14267 : :
14268 : 49718 : case '^':
14269 : 49718 : if (TARGET_64BIT && Pmode != word_mode)
14270 : 0 : fputs ("addr32 ", file);
14271 : 49718 : return;
14272 : :
14273 : 13439297 : case '!':
14274 : 13439297 : if (ix86_notrack_prefixed_insn_p (current_output_insn))
14275 : 3751 : fputs ("notrack ", file);
14276 : 13439297 : return;
14277 : :
14278 : 1 : default:
14279 : 1 : output_operand_lossage ("invalid operand code '%c'", code);
14280 : : }
14281 : : }
14282 : :
14283 : 132555591 : if (REG_P (x))
14284 : 79954702 : print_reg (x, code, file);
14285 : :
14286 : 52600889 : else if (MEM_P (x))
14287 : : {
14288 : 29886668 : rtx addr = XEXP (x, 0);
14289 : :
14290 : : /* No `byte ptr' prefix for call instructions ... */
14291 : 29886668 : if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
14292 : : {
14293 : 201 : machine_mode mode = GET_MODE (x);
14294 : 201 : const char *size;
14295 : :
14296 : : /* Check for explicit size override codes. */
14297 : 201 : if (code == 'b')
14298 : : size = "BYTE";
14299 : : else if (code == 'w')
14300 : : size = "WORD";
14301 : : else if (code == 'k')
14302 : : size = "DWORD";
14303 : : else if (code == 'q')
14304 : : size = "QWORD";
14305 : : else if (code == 'x')
14306 : : size = "XMMWORD";
14307 : : else if (code == 't')
14308 : : size = "YMMWORD";
14309 : : else if (code == 'g')
14310 : : size = "ZMMWORD";
14311 : 146 : else if (mode == BLKmode)
14312 : : /* ... or BLKmode operands, when not overridden. */
14313 : : size = NULL;
14314 : : else
14315 : 292 : switch (GET_MODE_SIZE (mode))
14316 : : {
14317 : : case 1: size = "BYTE"; break;
14318 : : case 2: size = "WORD"; break;
14319 : : case 4: size = "DWORD"; break;
14320 : : case 8: size = "QWORD"; break;
14321 : : case 12: size = "TBYTE"; break;
14322 : 4 : case 16:
14323 : 4 : if (mode == XFmode)
14324 : : size = "TBYTE";
14325 : : else
14326 : : size = "XMMWORD";
14327 : : break;
14328 : : case 32: size = "YMMWORD"; break;
14329 : : case 64: size = "ZMMWORD"; break;
14330 : 0 : default:
14331 : 0 : gcc_unreachable ();
14332 : : }
14333 : : if (size)
14334 : : {
14335 : 201 : fputs (size, file);
14336 : 201 : fputs (" PTR ", file);
14337 : : }
14338 : : }
14339 : :
14340 : 29886668 : if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
14341 : 0 : output_operand_lossage ("invalid constraints for operand");
14342 : : else
14343 : 29886668 : ix86_print_operand_address_as
14344 : 29886668 : (file, addr, MEM_ADDR_SPACE (x), code == 'p' || code == 'P');
14345 : : }
14346 : :
14347 : 22714221 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == HFmode)
14348 : : {
14349 : 750 : long l = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
14350 : 750 : REAL_MODE_FORMAT (HFmode));
14351 : 750 : if (ASSEMBLER_DIALECT == ASM_ATT)
14352 : 750 : putc ('$', file);
14353 : 750 : fprintf (file, "0x%04x", (unsigned int) l);
14354 : : }
14355 : :
14356 : 22713471 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
14357 : : {
14358 : 17866 : long l;
14359 : :
14360 : 17866 : REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
14361 : :
14362 : 17866 : if (ASSEMBLER_DIALECT == ASM_ATT)
14363 : 17866 : putc ('$', file);
14364 : : /* Sign extend 32bit SFmode immediate to 8 bytes. */
14365 : 17866 : if (code == 'q')
14366 : 370 : fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
14367 : : (unsigned long long) (int) l);
14368 : : else
14369 : 17496 : fprintf (file, "0x%08x", (unsigned int) l);
14370 : : }
14371 : :
14372 : 22695605 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == DFmode)
14373 : : {
14374 : 3020 : long l[2];
14375 : :
14376 : 3020 : REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
14377 : :
14378 : 3020 : if (ASSEMBLER_DIALECT == ASM_ATT)
14379 : 3020 : putc ('$', file);
14380 : 3020 : fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
14381 : : }
14382 : :
14383 : : /* These float cases don't actually occur as immediate operands. */
14384 : 22692585 : else if (CONST_DOUBLE_P (x) && GET_MODE (x) == XFmode)
14385 : : {
14386 : 0 : char dstr[30];
14387 : :
14388 : 0 : real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
14389 : 0 : fputs (dstr, file);
14390 : : }
14391 : :
14392 : : /* Print bcst_mem_operand. */
14393 : 22692585 : else if (GET_CODE (x) == VEC_DUPLICATE)
14394 : : {
14395 : 318 : machine_mode vmode = GET_MODE (x);
14396 : : /* Must be bcst_memory_operand. */
14397 : 318 : gcc_assert (bcst_mem_operand (x, vmode));
14398 : :
14399 : 318 : rtx mem = XEXP (x,0);
14400 : 318 : ix86_print_operand (file, mem, 0);
14401 : :
14402 : 318 : switch (vmode)
14403 : : {
14404 : 28 : case E_V2DImode:
14405 : 28 : case E_V2DFmode:
14406 : 28 : fputs ("{1to2}", file);
14407 : 28 : break;
14408 : 77 : case E_V4SImode:
14409 : 77 : case E_V4SFmode:
14410 : 77 : case E_V4DImode:
14411 : 77 : case E_V4DFmode:
14412 : 77 : fputs ("{1to4}", file);
14413 : 77 : break;
14414 : 93 : case E_V8SImode:
14415 : 93 : case E_V8SFmode:
14416 : 93 : case E_V8DFmode:
14417 : 93 : case E_V8DImode:
14418 : 93 : case E_V8HFmode:
14419 : 93 : fputs ("{1to8}", file);
14420 : 93 : break;
14421 : 112 : case E_V16SFmode:
14422 : 112 : case E_V16SImode:
14423 : 112 : case E_V16HFmode:
14424 : 112 : fputs ("{1to16}", file);
14425 : 112 : break;
14426 : 8 : case E_V32HFmode:
14427 : 8 : fputs ("{1to32}", file);
14428 : 8 : break;
14429 : 0 : default:
14430 : 0 : gcc_unreachable ();
14431 : : }
14432 : : }
14433 : :
14434 : : else
14435 : : {
14436 : : /* We have patterns that allow zero sets of memory, for instance.
14437 : : In 64-bit mode, we should probably support all 8-byte vectors,
14438 : : since we can in fact encode that into an immediate. */
14439 : 22692267 : if (GET_CODE (x) == CONST_VECTOR)
14440 : : {
14441 : 112 : if (x != CONST0_RTX (GET_MODE (x)))
14442 : 2 : output_operand_lossage ("invalid vector immediate");
14443 : 112 : x = const0_rtx;
14444 : : }
14445 : :
14446 : 22692267 : if (code == 'P')
14447 : : {
14448 : 5557772 : if (ix86_force_load_from_GOT_p (x, true))
14449 : : {
14450 : : /* For inline assembly statement, load function address
14451 : : from GOT with 'P' operand modifier to avoid PLT. */
14452 : 4 : x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
14453 : : (TARGET_64BIT
14454 : : ? UNSPEC_GOTPCREL
14455 : : : UNSPEC_GOT));
14456 : 4 : x = gen_rtx_CONST (Pmode, x);
14457 : 4 : x = gen_const_mem (Pmode, x);
14458 : 4 : ix86_print_operand (file, x, 'A');
14459 : 4 : return;
14460 : : }
14461 : : }
14462 : 17134495 : else if (code != 'p')
14463 : : {
14464 : 17134386 : if (CONST_INT_P (x))
14465 : : {
14466 : 14052536 : if (ASSEMBLER_DIALECT == ASM_ATT)
14467 : 14052358 : putc ('$', file);
14468 : : }
14469 : 3081850 : else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
14470 : 9402 : || GET_CODE (x) == LABEL_REF)
14471 : : {
14472 : 3081848 : if (ASSEMBLER_DIALECT == ASM_ATT)
14473 : 3081848 : putc ('$', file);
14474 : : else
14475 : 0 : fputs ("OFFSET FLAT:", file);
14476 : : }
14477 : : }
14478 : 22692263 : if (CONST_INT_P (x))
14479 : 14052622 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
14480 : 8639641 : else if (flag_pic || MACHOPIC_INDIRECT)
14481 : 509840 : output_pic_addr_const (file, x, code);
14482 : : else
14483 : 8129801 : output_addr_const (file, x);
14484 : : }
14485 : : }
14486 : :
14487 : : static bool
14488 : 19312113 : ix86_print_operand_punct_valid_p (unsigned char code)
14489 : : {
14490 : 19312113 : return (code == '*' || code == '+' || code == '&' || code == ';'
14491 : 13489015 : || code == '~' || code == '^' || code == '!');
14492 : : }
14493 : :
14494 : : /* Print a memory operand whose address is ADDR. */
14495 : :
14496 : : static void
14497 : 32755330 : ix86_print_operand_address_as (FILE *file, rtx addr,
14498 : : addr_space_t as, bool raw)
14499 : : {
14500 : 32755330 : struct ix86_address parts;
14501 : 32755330 : rtx base, index, disp;
14502 : 32755330 : int scale;
14503 : 32755330 : int ok;
14504 : 32755330 : bool vsib = false;
14505 : 32755330 : int code = 0;
14506 : :
14507 : 32755330 : if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
14508 : : {
14509 : 1900 : ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
14510 : 1900 : gcc_assert (parts.index == NULL_RTX);
14511 : 1900 : parts.index = XVECEXP (addr, 0, 1);
14512 : 1900 : parts.scale = INTVAL (XVECEXP (addr, 0, 2));
14513 : 1900 : addr = XVECEXP (addr, 0, 0);
14514 : 1900 : vsib = true;
14515 : : }
14516 : 32753430 : else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
14517 : : {
14518 : 2403550 : gcc_assert (TARGET_64BIT);
14519 : 2403550 : ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
14520 : 2403550 : code = 'q';
14521 : : }
14522 : : else
14523 : 30349880 : ok = ix86_decompose_address (addr, &parts);
14524 : :
14525 : 32755330 : gcc_assert (ok);
14526 : :
14527 : 32755330 : base = parts.base;
14528 : 32755330 : index = parts.index;
14529 : 32755330 : disp = parts.disp;
14530 : 32755330 : scale = parts.scale;
14531 : :
14532 : 32755330 : if (ADDR_SPACE_GENERIC_P (as))
14533 : 32476664 : as = parts.seg;
14534 : : else
14535 : 278666 : gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg));
14536 : :
14537 : 32755330 : if (!ADDR_SPACE_GENERIC_P (as) && !raw)
14538 : : {
14539 : 278676 : if (ASSEMBLER_DIALECT == ASM_ATT)
14540 : 278674 : putc ('%', file);
14541 : :
14542 : 278676 : switch (as)
14543 : : {
14544 : 179137 : case ADDR_SPACE_SEG_FS:
14545 : 179137 : fputs ("fs:", file);
14546 : 179137 : break;
14547 : 99539 : case ADDR_SPACE_SEG_GS:
14548 : 99539 : fputs ("gs:", file);
14549 : 99539 : break;
14550 : 0 : default:
14551 : 0 : gcc_unreachable ();
14552 : : }
14553 : : }
14554 : :
14555 : : /* Use one byte shorter RIP relative addressing for 64bit mode. */
14556 : 32755330 : if (TARGET_64BIT && !base && !index && !raw)
14557 : : {
14558 : 5720682 : rtx symbol = disp;
14559 : :
14560 : 5720682 : if (GET_CODE (disp) == CONST
14561 : 2053061 : && GET_CODE (XEXP (disp, 0)) == PLUS
14562 : 1975057 : && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
14563 : 1975057 : symbol = XEXP (XEXP (disp, 0), 0);
14564 : :
14565 : 5720682 : if (GET_CODE (symbol) == LABEL_REF
14566 : 5720682 : || (GET_CODE (symbol) == SYMBOL_REF
14567 : 5468378 : && SYMBOL_REF_TLS_MODEL (symbol) == 0))
14568 : 5467394 : base = pc_rtx;
14569 : : }
14570 : :
14571 : 32755330 : if (!base && !index)
14572 : : {
14573 : : /* Displacement only requires special attention. */
14574 : 596372 : if (CONST_INT_P (disp))
14575 : : {
14576 : 267565 : if (ASSEMBLER_DIALECT == ASM_INTEL && ADDR_SPACE_GENERIC_P (as))
14577 : 1 : fputs ("ds:", file);
14578 : 267565 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
14579 : : }
14580 : : /* Load the external function address via the GOT slot to avoid PLT. */
14581 : 328807 : else if (GET_CODE (disp) == CONST
14582 : 105539 : && GET_CODE (XEXP (disp, 0)) == UNSPEC
14583 : 78227 : && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
14584 : 6974 : || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
14585 : 400060 : && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
14586 : 16 : output_pic_addr_const (file, disp, 0);
14587 : 328791 : else if (flag_pic)
14588 : 108936 : output_pic_addr_const (file, disp, 0);
14589 : : else
14590 : 219855 : output_addr_const (file, disp);
14591 : : }
14592 : : else
14593 : : {
14594 : : /* Print SImode register names to force addr32 prefix. */
14595 : 32158958 : if (SImode_address_operand (addr, VOIDmode))
14596 : : {
14597 : 26 : if (flag_checking)
14598 : : {
14599 : 26 : gcc_assert (TARGET_64BIT);
14600 : 26 : switch (GET_CODE (addr))
14601 : : {
14602 : 0 : case SUBREG:
14603 : 0 : gcc_assert (GET_MODE (addr) == SImode);
14604 : 0 : gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
14605 : : break;
14606 : 26 : case ZERO_EXTEND:
14607 : 26 : case AND:
14608 : 26 : gcc_assert (GET_MODE (addr) == DImode);
14609 : : break;
14610 : 0 : default:
14611 : 0 : gcc_unreachable ();
14612 : : }
14613 : : }
14614 : 26 : gcc_assert (!code);
14615 : : code = 'k';
14616 : : }
14617 : 32158932 : else if (code == 0
14618 : 29757869 : && TARGET_X32
14619 : 237 : && disp
14620 : 181 : && CONST_INT_P (disp)
14621 : 114 : && INTVAL (disp) < -16*1024*1024)
14622 : : {
14623 : : /* X32 runs in 64-bit mode, where displacement, DISP, in
14624 : : address DISP(%r64), is encoded as 32-bit immediate sign-
14625 : : extended from 32-bit to 64-bit. For -0x40000300(%r64),
14626 : : address is %r64 + 0xffffffffbffffd00. When %r64 <
14627 : : 0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
14628 : : which is invalid for x32. The correct address is %r64
14629 : : - 0x40000300 == 0xf7ffdd64. To properly encode
14630 : : -0x40000300(%r64) for x32, we zero-extend negative
14631 : : displacement by forcing addr32 prefix which truncates
14632 : : 0xfffffffff7ffdd64 to 0xf7ffdd64. In theory, we should
14633 : : zero-extend all negative displacements, including -1(%rsp).
14634 : : However, for small negative displacements, sign-extension
14635 : : won't cause overflow. We only zero-extend negative
14636 : : displacements if they < -16*1024*1024, which is also used
14637 : : to check legitimate address displacements for PIC. */
14638 : 27 : code = 'k';
14639 : : }
14640 : :
14641 : : /* Since the upper 32 bits of RSP are always zero for x32,
14642 : : we can encode %esp as %rsp to avoid 0x67 prefix if
14643 : : there is no index register. */
14644 : 313 : if (TARGET_X32 && Pmode == SImode
14645 : 32159148 : && !index && base && REG_P (base) && REGNO (base) == SP_REG)
14646 : : code = 'q';
14647 : :
14648 : 32158958 : if (ASSEMBLER_DIALECT == ASM_ATT)
14649 : : {
14650 : 32158708 : if (disp)
14651 : : {
14652 : 28564300 : if (flag_pic)
14653 : 2507855 : output_pic_addr_const (file, disp, 0);
14654 : 26056445 : else if (GET_CODE (disp) == LABEL_REF)
14655 : 15283 : output_asm_label (disp);
14656 : : else
14657 : 26041162 : output_addr_const (file, disp);
14658 : : }
14659 : :
14660 : 32158708 : putc ('(', file);
14661 : 32158708 : if (base)
14662 : 31754005 : print_reg (base, code, file);
14663 : 32158708 : if (index)
14664 : : {
14665 : 1556849 : putc (',', file);
14666 : 3111846 : print_reg (index, vsib ? 0 : code, file);
14667 : 1556849 : if (scale != 1 || vsib)
14668 : 895920 : fprintf (file, ",%d", scale);
14669 : : }
14670 : 32158708 : putc (')', file);
14671 : : }
14672 : : else
14673 : : {
14674 : 250 : rtx offset = NULL_RTX;
14675 : :
14676 : 250 : if (disp)
14677 : : {
14678 : : /* Pull out the offset of a symbol; print any symbol itself. */
14679 : 189 : if (GET_CODE (disp) == CONST
14680 : 16 : && GET_CODE (XEXP (disp, 0)) == PLUS
14681 : 16 : && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
14682 : : {
14683 : 16 : offset = XEXP (XEXP (disp, 0), 1);
14684 : 16 : disp = gen_rtx_CONST (VOIDmode,
14685 : : XEXP (XEXP (disp, 0), 0));
14686 : : }
14687 : :
14688 : 189 : if (flag_pic)
14689 : 0 : output_pic_addr_const (file, disp, 0);
14690 : 189 : else if (GET_CODE (disp) == LABEL_REF)
14691 : 0 : output_asm_label (disp);
14692 : 189 : else if (CONST_INT_P (disp))
14693 : : offset = disp;
14694 : : else
14695 : 91 : output_addr_const (file, disp);
14696 : : }
14697 : :
14698 : 250 : putc ('[', file);
14699 : 250 : if (base)
14700 : : {
14701 : 210 : print_reg (base, code, file);
14702 : 210 : if (offset)
14703 : : {
14704 : 114 : if (INTVAL (offset) >= 0)
14705 : 18 : putc ('+', file);
14706 : 114 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
14707 : : }
14708 : : }
14709 : 40 : else if (offset)
14710 : 0 : fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
14711 : : else
14712 : 40 : putc ('0', file);
14713 : :
14714 : 250 : if (index)
14715 : : {
14716 : 93 : putc ('+', file);
14717 : 138 : print_reg (index, vsib ? 0 : code, file);
14718 : 93 : if (scale != 1 || vsib)
14719 : 91 : fprintf (file, "*%d", scale);
14720 : : }
14721 : 250 : putc (']', file);
14722 : : }
14723 : : }
14724 : 32755330 : }
14725 : :
14726 : : static void
14727 : 2868663 : ix86_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
14728 : : {
14729 : 2868663 : if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
14730 : 1 : output_operand_lossage ("invalid constraints for operand");
14731 : : else
14732 : 2868662 : ix86_print_operand_address_as (file, addr, ADDR_SPACE_GENERIC, false);
14733 : 2868663 : }
14734 : :
14735 : : /* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
14736 : :
14737 : : static bool
14738 : 12451 : i386_asm_output_addr_const_extra (FILE *file, rtx x)
14739 : : {
14740 : 12451 : rtx op;
14741 : :
14742 : 12451 : if (GET_CODE (x) != UNSPEC)
14743 : : return false;
14744 : :
14745 : 12451 : op = XVECEXP (x, 0, 0);
14746 : 12451 : switch (XINT (x, 1))
14747 : : {
14748 : 1495 : case UNSPEC_GOTOFF:
14749 : 1495 : output_addr_const (file, op);
14750 : 1495 : fputs ("@gotoff", file);
14751 : 1495 : break;
14752 : 0 : case UNSPEC_GOTTPOFF:
14753 : 0 : output_addr_const (file, op);
14754 : : /* FIXME: This might be @TPOFF in Sun ld. */
14755 : 0 : fputs ("@gottpoff", file);
14756 : 0 : break;
14757 : 0 : case UNSPEC_TPOFF:
14758 : 0 : output_addr_const (file, op);
14759 : 0 : fputs ("@tpoff", file);
14760 : 0 : break;
14761 : 9537 : case UNSPEC_NTPOFF:
14762 : 9537 : output_addr_const (file, op);
14763 : 9537 : if (TARGET_64BIT)
14764 : 8827 : fputs ("@tpoff", file);
14765 : : else
14766 : 710 : fputs ("@ntpoff", file);
14767 : : break;
14768 : 30 : case UNSPEC_DTPOFF:
14769 : 30 : output_addr_const (file, op);
14770 : 30 : fputs ("@dtpoff", file);
14771 : 30 : break;
14772 : 1388 : case UNSPEC_GOTNTPOFF:
14773 : 1388 : output_addr_const (file, op);
14774 : 1388 : if (TARGET_64BIT)
14775 : 1388 : fputs (ASSEMBLER_DIALECT == ASM_ATT ?
14776 : : "@gottpoff(%rip)" : "@gottpoff[rip]", file);
14777 : : else
14778 : 0 : fputs ("@gotntpoff", file);
14779 : : break;
14780 : 1 : case UNSPEC_INDNTPOFF:
14781 : 1 : output_addr_const (file, op);
14782 : 1 : fputs ("@indntpoff", file);
14783 : 1 : break;
14784 : : #if TARGET_MACHO
14785 : : case UNSPEC_MACHOPIC_OFFSET:
14786 : : output_addr_const (file, op);
14787 : : putc ('-', file);
14788 : : machopic_output_function_base_name (file);
14789 : : break;
14790 : : #endif
14791 : :
14792 : : default:
14793 : : return false;
14794 : : }
14795 : :
14796 : : return true;
14797 : : }
14798 : :
14799 : :
14800 : : /* Output code to perform a 387 binary operation in INSN, one of PLUS,
14801 : : MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
14802 : : is the expression of the binary operation. The output may either be
14803 : : emitted here, or returned to the caller, like all output_* functions.
14804 : :
14805 : : There is no guarantee that the operands are the same mode, as they
14806 : : might be within FLOAT or FLOAT_EXTEND expressions. */
14807 : :
14808 : : #ifndef SYSV386_COMPAT
14809 : : /* Set to 1 for compatibility with brain-damaged assemblers. No-one
14810 : : wants to fix the assemblers because that causes incompatibility
14811 : : with gcc. No-one wants to fix gcc because that causes
14812 : : incompatibility with assemblers... You can use the option of
14813 : : -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way. */
14814 : : #define SYSV386_COMPAT 1
14815 : : #endif
14816 : :
14817 : : const char *
14818 : 597229 : output_387_binary_op (rtx_insn *insn, rtx *operands)
14819 : : {
14820 : 597229 : static char buf[40];
14821 : 597229 : const char *p;
14822 : 597229 : bool is_sse
14823 : 597229 : = (SSE_REG_P (operands[0])
14824 : 652960 : || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]));
14825 : :
14826 : 55731 : if (is_sse)
14827 : : p = "%v";
14828 : 55731 : else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
14829 : 55724 : || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
14830 : : p = "fi";
14831 : : else
14832 : 597229 : p = "f";
14833 : :
14834 : 597229 : strcpy (buf, p);
14835 : :
14836 : 597229 : switch (GET_CODE (operands[3]))
14837 : : {
14838 : : case PLUS:
14839 : : p = "add"; break;
14840 : 56101 : case MINUS:
14841 : 56101 : p = "sub"; break;
14842 : 93027 : case MULT:
14843 : 93027 : p = "mul"; break;
14844 : 25981 : case DIV:
14845 : 25981 : p = "div"; break;
14846 : 0 : default:
14847 : 0 : gcc_unreachable ();
14848 : : }
14849 : :
14850 : 597229 : strcat (buf, p);
14851 : :
14852 : 597229 : if (is_sse)
14853 : : {
14854 : 541498 : p = GET_MODE (operands[0]) == SFmode ? "ss" : "sd";
14855 : 541498 : strcat (buf, p);
14856 : :
14857 : 541498 : if (TARGET_AVX)
14858 : : p = "\t{%2, %1, %0|%0, %1, %2}";
14859 : : else
14860 : 525846 : p = "\t{%2, %0|%0, %2}";
14861 : :
14862 : 541498 : strcat (buf, p);
14863 : 541498 : return buf;
14864 : : }
14865 : :
14866 : : /* Even if we do not want to check the inputs, this documents input
14867 : : constraints. Which helps in understanding the following code. */
14868 : 55731 : if (flag_checking)
14869 : : {
14870 : 55730 : if (STACK_REG_P (operands[0])
14871 : 55730 : && ((REG_P (operands[1])
14872 : 54121 : && REGNO (operands[0]) == REGNO (operands[1])
14873 : 49978 : && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
14874 : 5752 : || (REG_P (operands[2])
14875 : 5752 : && REGNO (operands[0]) == REGNO (operands[2])
14876 : 5752 : && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
14877 : 111460 : && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
14878 : : ; /* ok */
14879 : : else
14880 : 0 : gcc_unreachable ();
14881 : : }
14882 : :
14883 : 55731 : switch (GET_CODE (operands[3]))
14884 : : {
14885 : 40791 : case MULT:
14886 : 40791 : case PLUS:
14887 : 40791 : if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
14888 : 1943 : std::swap (operands[1], operands[2]);
14889 : :
14890 : : /* know operands[0] == operands[1]. */
14891 : :
14892 : 40791 : if (MEM_P (operands[2]))
14893 : : {
14894 : : p = "%Z2\t%2";
14895 : : break;
14896 : : }
14897 : :
14898 : 36789 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
14899 : : {
14900 : 21790 : if (STACK_TOP_P (operands[0]))
14901 : : /* How is it that we are storing to a dead operand[2]?
14902 : : Well, presumably operands[1] is dead too. We can't
14903 : : store the result to st(0) as st(0) gets popped on this
14904 : : instruction. Instead store to operands[2] (which I
14905 : : think has to be st(1)). st(1) will be popped later.
14906 : : gcc <= 2.8.1 didn't have this check and generated
14907 : : assembly code that the Unixware assembler rejected. */
14908 : : p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
14909 : : else
14910 : : p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
14911 : : break;
14912 : : }
14913 : :
14914 : 14999 : if (STACK_TOP_P (operands[0]))
14915 : : p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
14916 : : else
14917 : : p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
14918 : : break;
14919 : :
14920 : 14940 : case MINUS:
14921 : 14940 : case DIV:
14922 : 14940 : if (MEM_P (operands[1]))
14923 : : {
14924 : : p = "r%Z1\t%1";
14925 : : break;
14926 : : }
14927 : :
14928 : 14500 : if (MEM_P (operands[2]))
14929 : : {
14930 : : p = "%Z2\t%2";
14931 : : break;
14932 : : }
14933 : :
14934 : 13242 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
14935 : : {
14936 : : #if SYSV386_COMPAT
14937 : : /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
14938 : : derived assemblers, confusingly reverse the direction of
14939 : : the operation for fsub{r} and fdiv{r} when the
14940 : : destination register is not st(0). The Intel assembler
14941 : : doesn't have this brain damage. Read !SYSV386_COMPAT to
14942 : : figure out what the hardware really does. */
14943 : 6378 : if (STACK_TOP_P (operands[0]))
14944 : : p = "{p\t%0, %2|rp\t%2, %0}";
14945 : : else
14946 : : p = "{rp\t%2, %0|p\t%0, %2}";
14947 : : #else
14948 : : if (STACK_TOP_P (operands[0]))
14949 : : /* As above for fmul/fadd, we can't store to st(0). */
14950 : : p = "rp\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
14951 : : else
14952 : : p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
14953 : : #endif
14954 : : break;
14955 : : }
14956 : :
14957 : 6864 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
14958 : : {
14959 : : #if SYSV386_COMPAT
14960 : 3160 : if (STACK_TOP_P (operands[0]))
14961 : : p = "{rp\t%0, %1|p\t%1, %0}";
14962 : : else
14963 : : p = "{p\t%1, %0|rp\t%0, %1}";
14964 : : #else
14965 : : if (STACK_TOP_P (operands[0]))
14966 : : p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
14967 : : else
14968 : : p = "rp\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2); pop */
14969 : : #endif
14970 : : break;
14971 : : }
14972 : :
14973 : 3704 : if (STACK_TOP_P (operands[0]))
14974 : : {
14975 : 2898 : if (STACK_TOP_P (operands[1]))
14976 : : p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
14977 : : else
14978 : : p = "r\t{%y1, %0|%0, %y1}"; /* st(0) = st(r1) op st(0) */
14979 : : break;
14980 : : }
14981 : 806 : else if (STACK_TOP_P (operands[1]))
14982 : : {
14983 : : #if SYSV386_COMPAT
14984 : : p = "{\t%1, %0|r\t%0, %1}";
14985 : : #else
14986 : : p = "r\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2) */
14987 : : #endif
14988 : : }
14989 : : else
14990 : : {
14991 : : #if SYSV386_COMPAT
14992 : : p = "{r\t%2, %0|\t%0, %2}";
14993 : : #else
14994 : : p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
14995 : : #endif
14996 : : }
14997 : : break;
14998 : :
14999 : 0 : default:
15000 : 0 : gcc_unreachable ();
15001 : : }
15002 : :
15003 : 55731 : strcat (buf, p);
15004 : 55731 : return buf;
15005 : : }
15006 : :
15007 : : /* Return needed mode for entity in optimize_mode_switching pass. */
15008 : :
15009 : : static int
15010 : 1655 : ix86_dirflag_mode_needed (rtx_insn *insn)
15011 : : {
15012 : 1655 : if (CALL_P (insn))
15013 : : {
15014 : 337 : if (cfun->machine->func_type == TYPE_NORMAL)
15015 : : return X86_DIRFLAG_ANY;
15016 : : else
15017 : : /* No need to emit CLD in interrupt handler for TARGET_CLD. */
15018 : 337 : return TARGET_CLD ? X86_DIRFLAG_ANY : X86_DIRFLAG_RESET;
15019 : : }
15020 : :
15021 : 1318 : if (recog_memoized (insn) < 0)
15022 : : return X86_DIRFLAG_ANY;
15023 : :
15024 : 1316 : if (get_attr_type (insn) == TYPE_STR)
15025 : : {
15026 : : /* Emit cld instruction if stringops are used in the function. */
15027 : 1 : if (cfun->machine->func_type == TYPE_NORMAL)
15028 : 0 : return TARGET_CLD ? X86_DIRFLAG_RESET : X86_DIRFLAG_ANY;
15029 : : else
15030 : : return X86_DIRFLAG_RESET;
15031 : : }
15032 : :
15033 : : return X86_DIRFLAG_ANY;
15034 : : }
15035 : :
15036 : : /* Check if a 256bit or 512 bit AVX register is referenced inside of EXP. */
15037 : :
15038 : : static bool
15039 : 8017783 : ix86_check_avx_upper_register (const_rtx exp)
15040 : : {
15041 : 3895380 : return (SSE_REG_P (exp)
15042 : 1264165 : && !EXT_REX_SSE_REG_P (exp)
15043 : 10525031 : && GET_MODE_BITSIZE (GET_MODE (exp)) > 128);
15044 : : }
15045 : :
15046 : : /* Check if a 256bit or 512bit AVX register is referenced in stores. */
15047 : :
15048 : : static void
15049 : 44163 : ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
15050 : : {
15051 : 44163 : if (ix86_check_avx_upper_register (dest))
15052 : : {
15053 : 704 : bool *used = (bool *) data;
15054 : 704 : *used = true;
15055 : : }
15056 : 44163 : }
15057 : :
15058 : : /* Return needed mode for entity in optimize_mode_switching pass. */
15059 : :
15060 : : static int
15061 : 1984299 : ix86_avx_u128_mode_needed (rtx_insn *insn)
15062 : : {
15063 : 1984299 : if (DEBUG_INSN_P (insn))
15064 : : return AVX_U128_ANY;
15065 : :
15066 : 1984299 : if (CALL_P (insn))
15067 : : {
15068 : 44953 : rtx link;
15069 : :
15070 : : /* Needed mode is set to AVX_U128_CLEAN if there are
15071 : : no 256bit or 512bit modes used in function arguments. */
15072 : 44953 : for (link = CALL_INSN_FUNCTION_USAGE (insn);
15073 : 116742 : link;
15074 : 71789 : link = XEXP (link, 1))
15075 : : {
15076 : 72788 : if (GET_CODE (XEXP (link, 0)) == USE)
15077 : : {
15078 : 71851 : rtx arg = XEXP (XEXP (link, 0), 0);
15079 : :
15080 : 71851 : if (ix86_check_avx_upper_register (arg))
15081 : : return AVX_U128_DIRTY;
15082 : : }
15083 : : }
15084 : :
15085 : : /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit
15086 : : nor 512bit registers used in the function return register. */
15087 : 43954 : bool avx_upper_reg_found = false;
15088 : 43954 : note_stores (insn, ix86_check_avx_upper_stores,
15089 : : &avx_upper_reg_found);
15090 : 43954 : if (avx_upper_reg_found)
15091 : : return AVX_U128_DIRTY;
15092 : :
15093 : : /* If the function is known to preserve some SSE registers,
15094 : : RA and previous passes can legitimately rely on that for
15095 : : modes wider than 256 bits. It's only safe to issue a
15096 : : vzeroupper if all SSE registers are clobbered. */
15097 : 43774 : const function_abi &abi = insn_callee_abi (insn);
15098 : 43774 : if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
15099 : : /* Should be safe to issue an vzeroupper before sibling_call_p.
15100 : : Also there not mode_exit for sibling_call, so there could be
15101 : : missing vzeroupper for that. */
15102 : 43774 : || !(SIBLING_CALL_P (insn)
15103 : 42534 : || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
15104 : 42534 : abi.mode_clobbers (V4DImode))))
15105 : 9333 : return AVX_U128_ANY;
15106 : :
15107 : 34441 : return AVX_U128_CLEAN;
15108 : : }
15109 : :
15110 : 1939346 : subrtx_iterator::array_type array;
15111 : :
15112 : 1939346 : rtx set = single_set (insn);
15113 : 1939346 : if (set)
15114 : : {
15115 : 1872348 : rtx dest = SET_DEST (set);
15116 : 1872348 : rtx src = SET_SRC (set);
15117 : 1872348 : if (ix86_check_avx_upper_register (dest))
15118 : : {
15119 : : /* This is an YMM/ZMM load. Return AVX_U128_DIRTY if the
15120 : : source isn't zero. */
15121 : 159672 : if (standard_sse_constant_p (src, GET_MODE (dest)) != 1)
15122 : : return AVX_U128_DIRTY;
15123 : : else
15124 : : return AVX_U128_ANY;
15125 : : }
15126 : : else
15127 : : {
15128 : 7044896 : FOR_EACH_SUBRTX (iter, array, src, NONCONST)
15129 : 5400190 : if (ix86_check_avx_upper_register (*iter))
15130 : 67970 : return AVX_U128_DIRTY;
15131 : : }
15132 : :
15133 : : /* This isn't YMM/ZMM load/store. */
15134 : 1644706 : return AVX_U128_ANY;
15135 : : }
15136 : :
15137 : : /* Require DIRTY mode if a 256bit or 512bit AVX register is referenced.
15138 : : Hardware changes state only when a 256bit register is written to,
15139 : : but we need to prevent the compiler from moving optimal insertion
15140 : : point above eventual read from 256bit or 512 bit register. */
15141 : 426973 : FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
15142 : 381152 : if (ix86_check_avx_upper_register (*iter))
15143 : 21177 : return AVX_U128_DIRTY;
15144 : :
15145 : 45821 : return AVX_U128_ANY;
15146 : 1939346 : }
15147 : :
15148 : : /* Return mode that i387 must be switched into
15149 : : prior to the execution of insn. */
15150 : :
15151 : : static int
15152 : 476225 : ix86_i387_mode_needed (int entity, rtx_insn *insn)
15153 : : {
15154 : 476225 : enum attr_i387_cw mode;
15155 : :
15156 : : /* The mode UNINITIALIZED is used to store control word after a
15157 : : function call or ASM pattern. The mode ANY specify that function
15158 : : has no requirements on the control word and make no changes in the
15159 : : bits we are interested in. */
15160 : :
15161 : 476225 : if (CALL_P (insn)
15162 : 476225 : || (NONJUMP_INSN_P (insn)
15163 : 392250 : && (asm_noperands (PATTERN (insn)) >= 0
15164 : 392250 : || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
15165 : 17162 : return I387_CW_UNINITIALIZED;
15166 : :
15167 : 459063 : if (recog_memoized (insn) < 0)
15168 : : return I387_CW_ANY;
15169 : :
15170 : 458038 : mode = get_attr_i387_cw (insn);
15171 : :
15172 : 458038 : switch (entity)
15173 : : {
15174 : 6 : case I387_ROUNDEVEN:
15175 : 6 : if (mode == I387_CW_ROUNDEVEN)
15176 : : return mode;
15177 : : break;
15178 : :
15179 : 450426 : case I387_TRUNC:
15180 : 450426 : if (mode == I387_CW_TRUNC)
15181 : : return mode;
15182 : : break;
15183 : :
15184 : 6040 : case I387_FLOOR:
15185 : 6040 : if (mode == I387_CW_FLOOR)
15186 : : return mode;
15187 : : break;
15188 : :
15189 : 1566 : case I387_CEIL:
15190 : 1566 : if (mode == I387_CW_CEIL)
15191 : : return mode;
15192 : : break;
15193 : :
15194 : 0 : default:
15195 : 0 : gcc_unreachable ();
15196 : : }
15197 : :
15198 : : return I387_CW_ANY;
15199 : : }
15200 : :
15201 : : /* Return mode that entity must be switched into
15202 : : prior to the execution of insn. */
15203 : :
15204 : : static int
15205 : 2462179 : ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
15206 : : {
15207 : 2462179 : switch (entity)
15208 : : {
15209 : 1655 : case X86_DIRFLAG:
15210 : 1655 : return ix86_dirflag_mode_needed (insn);
15211 : 1984299 : case AVX_U128:
15212 : 1984299 : return ix86_avx_u128_mode_needed (insn);
15213 : 476225 : case I387_ROUNDEVEN:
15214 : 476225 : case I387_TRUNC:
15215 : 476225 : case I387_FLOOR:
15216 : 476225 : case I387_CEIL:
15217 : 476225 : return ix86_i387_mode_needed (entity, insn);
15218 : 0 : default:
15219 : 0 : gcc_unreachable ();
15220 : : }
15221 : : return 0;
15222 : : }
15223 : :
15224 : : /* Calculate mode of upper 128bit AVX registers after the insn. */
15225 : :
15226 : : static int
15227 : 1984299 : ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
15228 : : {
15229 : 1984299 : rtx pat = PATTERN (insn);
15230 : :
15231 : 1984299 : if (vzeroupper_pattern (pat, VOIDmode)
15232 : 1984299 : || vzeroall_pattern (pat, VOIDmode))
15233 : 180 : return AVX_U128_CLEAN;
15234 : :
15235 : : /* We know that state is clean after CALL insn if there are no
15236 : : 256bit or 512bit registers used in the function return register. */
15237 : 1984119 : if (CALL_P (insn))
15238 : : {
15239 : 44907 : bool avx_upper_reg_found = false;
15240 : 44907 : note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found);
15241 : :
15242 : 44907 : if (avx_upper_reg_found)
15243 : : return AVX_U128_DIRTY;
15244 : :
15245 : : /* If the function desn't clobber any sse registers or only clobber
15246 : : 128-bit part, Then vzeroupper isn't issued before the function exit.
15247 : : the status not CLEAN but ANY after the function. */
15248 : 44383 : const function_abi &abi = insn_callee_abi (insn);
15249 : 44383 : if (!(SIBLING_CALL_P (insn)
15250 : 43144 : || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
15251 : 43144 : abi.mode_clobbers (V4DImode))))
15252 : 9628 : return AVX_U128_ANY;
15253 : :
15254 : 34755 : return AVX_U128_CLEAN;
15255 : : }
15256 : :
15257 : : /* Otherwise, return current mode. Remember that if insn
15258 : : references AVX 256bit or 512bit registers, the mode was already
15259 : : changed to DIRTY from MODE_NEEDED. */
15260 : : return mode;
15261 : : }
15262 : :
15263 : : /* Return the mode that an insn results in. */
15264 : :
15265 : : static int
15266 : 2461253 : ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
15267 : : {
15268 : 2461253 : switch (entity)
15269 : : {
15270 : : case X86_DIRFLAG:
15271 : : return mode;
15272 : 1984299 : case AVX_U128:
15273 : 1984299 : return ix86_avx_u128_mode_after (mode, insn);
15274 : : case I387_ROUNDEVEN:
15275 : : case I387_TRUNC:
15276 : : case I387_FLOOR:
15277 : : case I387_CEIL:
15278 : : return mode;
15279 : 0 : default:
15280 : 0 : gcc_unreachable ();
15281 : : }
15282 : : }
15283 : :
15284 : : static int
15285 : 118 : ix86_dirflag_mode_entry (void)
15286 : : {
15287 : : /* For TARGET_CLD or in the interrupt handler we can't assume
15288 : : direction flag state at function entry. */
15289 : 118 : if (TARGET_CLD
15290 : 116 : || cfun->machine->func_type != TYPE_NORMAL)
15291 : 118 : return X86_DIRFLAG_ANY;
15292 : :
15293 : : return X86_DIRFLAG_RESET;
15294 : : }
15295 : :
15296 : : static int
15297 : 109523 : ix86_avx_u128_mode_entry (void)
15298 : : {
15299 : 109523 : tree arg;
15300 : :
15301 : : /* Entry mode is set to AVX_U128_DIRTY if there are
15302 : : 256bit or 512bit modes used in function arguments. */
15303 : 278181 : for (arg = DECL_ARGUMENTS (current_function_decl); arg;
15304 : 168658 : arg = TREE_CHAIN (arg))
15305 : : {
15306 : 197979 : rtx incoming = DECL_INCOMING_RTL (arg);
15307 : :
15308 : 197979 : if (incoming && ix86_check_avx_upper_register (incoming))
15309 : : return AVX_U128_DIRTY;
15310 : : }
15311 : :
15312 : : return AVX_U128_CLEAN;
15313 : : }
15314 : :
15315 : : /* Return a mode that ENTITY is assumed to be
15316 : : switched to at function entry. */
15317 : :
15318 : : static int
15319 : 67090 : ix86_mode_entry (int entity)
15320 : : {
15321 : 67090 : switch (entity)
15322 : : {
15323 : 118 : case X86_DIRFLAG:
15324 : 118 : return ix86_dirflag_mode_entry ();
15325 : 65746 : case AVX_U128:
15326 : 65746 : return ix86_avx_u128_mode_entry ();
15327 : : case I387_ROUNDEVEN:
15328 : : case I387_TRUNC:
15329 : : case I387_FLOOR:
15330 : : case I387_CEIL:
15331 : : return I387_CW_ANY;
15332 : 0 : default:
15333 : 0 : gcc_unreachable ();
15334 : : }
15335 : : }
15336 : :
15337 : : static int
15338 : 64504 : ix86_avx_u128_mode_exit (void)
15339 : : {
15340 : 64504 : rtx reg = crtl->return_rtx;
15341 : :
15342 : : /* Exit mode is set to AVX_U128_DIRTY if there are 256bit
15343 : : or 512 bit modes used in the function return register. */
15344 : 64504 : if (reg && ix86_check_avx_upper_register (reg))
15345 : : return AVX_U128_DIRTY;
15346 : :
15347 : : /* Exit mode is set to AVX_U128_DIRTY if there are 256bit or 512bit
15348 : : modes used in function arguments, otherwise return AVX_U128_CLEAN.
15349 : : */
15350 : 43777 : return ix86_avx_u128_mode_entry ();
15351 : : }
15352 : :
15353 : : /* Return a mode that ENTITY is assumed to be
15354 : : switched to at function exit. */
15355 : :
15356 : : static int
15357 : 65706 : ix86_mode_exit (int entity)
15358 : : {
15359 : 65706 : switch (entity)
15360 : : {
15361 : : case X86_DIRFLAG:
15362 : : return X86_DIRFLAG_ANY;
15363 : 64504 : case AVX_U128:
15364 : 64504 : return ix86_avx_u128_mode_exit ();
15365 : 1170 : case I387_ROUNDEVEN:
15366 : 1170 : case I387_TRUNC:
15367 : 1170 : case I387_FLOOR:
15368 : 1170 : case I387_CEIL:
15369 : 1170 : return I387_CW_ANY;
15370 : 0 : default:
15371 : 0 : gcc_unreachable ();
15372 : : }
15373 : : }
15374 : :
15375 : : static int
15376 : 2104892 : ix86_mode_priority (int, int n)
15377 : : {
15378 : 2104892 : return n;
15379 : : }
15380 : :
15381 : : /* Output code to initialize control word copies used by trunc?f?i and
15382 : : rounding patterns. CURRENT_MODE is set to current control word,
15383 : : while NEW_MODE is set to new control word. */
15384 : :
15385 : : static void
15386 : 3480 : emit_i387_cw_initialization (int mode)
15387 : : {
15388 : 3480 : rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
15389 : 3480 : rtx new_mode;
15390 : :
15391 : 3480 : enum ix86_stack_slot slot;
15392 : :
15393 : 3480 : rtx reg = gen_reg_rtx (HImode);
15394 : :
15395 : 3480 : emit_insn (gen_x86_fnstcw_1 (stored_mode));
15396 : 3480 : emit_move_insn (reg, copy_rtx (stored_mode));
15397 : :
15398 : 3480 : switch (mode)
15399 : : {
15400 : 1 : case I387_CW_ROUNDEVEN:
15401 : : /* round to nearest */
15402 : 1 : emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
15403 : 1 : slot = SLOT_CW_ROUNDEVEN;
15404 : 1 : break;
15405 : :
15406 : 3213 : case I387_CW_TRUNC:
15407 : : /* round toward zero (truncate) */
15408 : 3213 : emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
15409 : 3213 : slot = SLOT_CW_TRUNC;
15410 : 3213 : break;
15411 : :
15412 : 177 : case I387_CW_FLOOR:
15413 : : /* round down toward -oo */
15414 : 177 : emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
15415 : 177 : emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
15416 : 177 : slot = SLOT_CW_FLOOR;
15417 : 177 : break;
15418 : :
15419 : 89 : case I387_CW_CEIL:
15420 : : /* round up toward +oo */
15421 : 89 : emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
15422 : 89 : emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
15423 : 89 : slot = SLOT_CW_CEIL;
15424 : 89 : break;
15425 : :
15426 : 0 : default:
15427 : 0 : gcc_unreachable ();
15428 : : }
15429 : :
15430 : 3480 : gcc_assert (slot < MAX_386_STACK_LOCALS);
15431 : :
15432 : 3480 : new_mode = assign_386_stack_local (HImode, slot);
15433 : 3480 : emit_move_insn (new_mode, reg);
15434 : 3480 : }
15435 : :
15436 : : /* Generate one or more insns to set ENTITY to MODE. */
15437 : :
15438 : : static void
15439 : 45251 : ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
15440 : : HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
15441 : : {
15442 : 45251 : switch (entity)
15443 : : {
15444 : 263 : case X86_DIRFLAG:
15445 : 263 : if (mode == X86_DIRFLAG_RESET)
15446 : 263 : emit_insn (gen_cld ());
15447 : : break;
15448 : 35887 : case AVX_U128:
15449 : 35887 : if (mode == AVX_U128_CLEAN)
15450 : 17282 : ix86_expand_avx_vzeroupper ();
15451 : : break;
15452 : 9101 : case I387_ROUNDEVEN:
15453 : 9101 : case I387_TRUNC:
15454 : 9101 : case I387_FLOOR:
15455 : 9101 : case I387_CEIL:
15456 : 9101 : if (mode != I387_CW_ANY
15457 : 9101 : && mode != I387_CW_UNINITIALIZED)
15458 : 3480 : emit_i387_cw_initialization (mode);
15459 : : break;
15460 : 0 : default:
15461 : 0 : gcc_unreachable ();
15462 : : }
15463 : 45251 : }
15464 : :
15465 : : /* Output code for INSN to convert a float to a signed int. OPERANDS
15466 : : are the insn operands. The output may be [HSD]Imode and the input
15467 : : operand may be [SDX]Fmode. */
15468 : :
15469 : : const char *
15470 : 7585 : output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
15471 : : {
15472 : 7585 : bool stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
15473 : 7585 : bool dimode_p = GET_MODE (operands[0]) == DImode;
15474 : 7585 : int round_mode = get_attr_i387_cw (insn);
15475 : :
15476 : 7585 : static char buf[40];
15477 : 7585 : const char *p;
15478 : :
15479 : : /* Jump through a hoop or two for DImode, since the hardware has no
15480 : : non-popping instruction. We used to do this a different way, but
15481 : : that was somewhat fragile and broke with post-reload splitters. */
15482 : 7585 : if ((dimode_p || fisttp) && !stack_top_dies)
15483 : 25 : output_asm_insn ("fld\t%y1", operands);
15484 : :
15485 : 7585 : gcc_assert (STACK_TOP_P (operands[1]));
15486 : 7585 : gcc_assert (MEM_P (operands[0]));
15487 : 7585 : gcc_assert (GET_MODE (operands[1]) != TFmode);
15488 : :
15489 : 7585 : if (fisttp)
15490 : : return "fisttp%Z0\t%0";
15491 : :
15492 : 7584 : strcpy (buf, "fist");
15493 : :
15494 : 7584 : if (round_mode != I387_CW_ANY)
15495 : 7536 : output_asm_insn ("fldcw\t%3", operands);
15496 : :
15497 : 7584 : p = "p%Z0\t%0";
15498 : 7584 : strcat (buf, p + !(stack_top_dies || dimode_p));
15499 : :
15500 : 7584 : output_asm_insn (buf, operands);
15501 : :
15502 : 7584 : if (round_mode != I387_CW_ANY)
15503 : 7536 : output_asm_insn ("fldcw\t%2", operands);
15504 : :
15505 : : return "";
15506 : : }
15507 : :
15508 : : /* Output code for x87 ffreep insn. The OPNO argument, which may only
15509 : : have the values zero or one, indicates the ffreep insn's operand
15510 : : from the OPERANDS array. */
15511 : :
15512 : : static const char *
15513 : 282177 : output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
15514 : : {
15515 : 0 : if (TARGET_USE_FFREEP)
15516 : : #ifdef HAVE_AS_IX86_FFREEP
15517 : 0 : return opno ? "ffreep\t%y1" : "ffreep\t%y0";
15518 : : #else
15519 : : {
15520 : : static char retval[32];
15521 : : int regno = REGNO (operands[opno]);
15522 : :
15523 : : gcc_assert (STACK_REGNO_P (regno));
15524 : :
15525 : : regno -= FIRST_STACK_REG;
15526 : :
15527 : : snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
15528 : : return retval;
15529 : : }
15530 : : #endif
15531 : :
15532 : 0 : return opno ? "fstp\t%y1" : "fstp\t%y0";
15533 : : }
15534 : :
15535 : :
15536 : : /* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi
15537 : : should be used. UNORDERED_P is true when fucom should be used. */
15538 : :
15539 : : const char *
15540 : 107636 : output_fp_compare (rtx_insn *insn, rtx *operands,
15541 : : bool eflags_p, bool unordered_p)
15542 : : {
15543 : 107636 : rtx *xops = eflags_p ? &operands[0] : &operands[1];
15544 : 107636 : bool stack_top_dies;
15545 : :
15546 : 107636 : static char buf[40];
15547 : 107636 : const char *p;
15548 : :
15549 : 107636 : gcc_assert (STACK_TOP_P (xops[0]));
15550 : :
15551 : 107636 : stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
15552 : :
15553 : 107636 : if (eflags_p)
15554 : : {
15555 : 107636 : p = unordered_p ? "fucomi" : "fcomi";
15556 : 107636 : strcpy (buf, p);
15557 : :
15558 : 107636 : p = "p\t{%y1, %0|%0, %y1}";
15559 : 107636 : strcat (buf, p + !stack_top_dies);
15560 : :
15561 : 107636 : return buf;
15562 : : }
15563 : :
15564 : 0 : if (STACK_REG_P (xops[1])
15565 : 0 : && stack_top_dies
15566 : 0 : && find_regno_note (insn, REG_DEAD, FIRST_STACK_REG + 1))
15567 : : {
15568 : 0 : gcc_assert (REGNO (xops[1]) == FIRST_STACK_REG + 1);
15569 : :
15570 : : /* If both the top of the 387 stack die, and the other operand
15571 : : is also a stack register that dies, then this must be a
15572 : : `fcompp' float compare. */
15573 : 0 : p = unordered_p ? "fucompp" : "fcompp";
15574 : 0 : strcpy (buf, p);
15575 : : }
15576 : 0 : else if (const0_operand (xops[1], VOIDmode))
15577 : : {
15578 : 0 : gcc_assert (!unordered_p);
15579 : 0 : strcpy (buf, "ftst");
15580 : : }
15581 : : else
15582 : : {
15583 : 0 : if (GET_MODE_CLASS (GET_MODE (xops[1])) == MODE_INT)
15584 : : {
15585 : 0 : gcc_assert (!unordered_p);
15586 : : p = "ficom";
15587 : : }
15588 : : else
15589 : 0 : p = unordered_p ? "fucom" : "fcom";
15590 : :
15591 : 0 : strcpy (buf, p);
15592 : :
15593 : 0 : p = "p%Z2\t%y2";
15594 : 0 : strcat (buf, p + !stack_top_dies);
15595 : : }
15596 : :
15597 : 0 : output_asm_insn (buf, operands);
15598 : 0 : return "fnstsw\t%0";
15599 : : }
15600 : :
15601 : : void
15602 : 333927 : ix86_output_addr_vec_elt (FILE *file, int value)
15603 : : {
15604 : 333927 : const char *directive = ASM_LONG;
15605 : :
15606 : : #ifdef ASM_QUAD
15607 : 333927 : if (TARGET_LP64)
15608 : 320909 : directive = ASM_QUAD;
15609 : : #else
15610 : : gcc_assert (!TARGET_64BIT);
15611 : : #endif
15612 : :
15613 : 333927 : fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
15614 : 333927 : }
15615 : :
15616 : : void
15617 : 27747 : ix86_output_addr_diff_elt (FILE *file, int value, int rel)
15618 : : {
15619 : 27747 : const char *directive = ASM_LONG;
15620 : :
15621 : : #ifdef ASM_QUAD
15622 : 42409 : if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
15623 : : directive = ASM_QUAD;
15624 : : #else
15625 : : gcc_assert (!TARGET_64BIT);
15626 : : #endif
15627 : : /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand. */
15628 : 27747 : if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15629 : 14662 : fprintf (file, "%s%s%d-%s%d\n",
15630 : : directive, LPREFIX, value, LPREFIX, rel);
15631 : : #if TARGET_MACHO
15632 : : else if (TARGET_MACHO)
15633 : : {
15634 : : fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
15635 : : machopic_output_function_base_name (file);
15636 : : putc ('\n', file);
15637 : : }
15638 : : #endif
15639 : 13085 : else if (HAVE_AS_GOTOFF_IN_DATA)
15640 : 13085 : fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
15641 : : else
15642 : : asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
15643 : : GOT_SYMBOL_NAME, LPREFIX, value);
15644 : 27747 : }
15645 : :
15646 : : #define LEA_MAX_STALL (3)
15647 : : #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
15648 : :
15649 : : /* Increase given DISTANCE in half-cycles according to
15650 : : dependencies between PREV and NEXT instructions.
15651 : : Add 1 half-cycle if there is no dependency and
15652 : : go to next cycle if there is some dependecy. */
15653 : :
15654 : : static unsigned int
15655 : 2416 : increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
15656 : : {
15657 : 2416 : df_ref def, use;
15658 : :
15659 : 2416 : if (!prev || !next)
15660 : 880 : return distance + (distance & 1) + 2;
15661 : :
15662 : 1536 : if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
15663 : 259 : return distance + 1;
15664 : :
15665 : 2123 : FOR_EACH_INSN_USE (use, next)
15666 : 2668 : FOR_EACH_INSN_DEF (def, prev)
15667 : 1822 : if (!DF_REF_IS_ARTIFICIAL (def)
15668 : 1822 : && DF_REF_REGNO (use) == DF_REF_REGNO (def))
15669 : 769 : return distance + (distance & 1) + 2;
15670 : :
15671 : 508 : return distance + 1;
15672 : : }
15673 : :
15674 : : /* Function checks if instruction INSN defines register number
15675 : : REGNO1 or REGNO2. */
15676 : :
15677 : : bool
15678 : 2383 : insn_defines_reg (unsigned int regno1, unsigned int regno2,
15679 : : rtx_insn *insn)
15680 : : {
15681 : 2383 : df_ref def;
15682 : :
15683 : 4320 : FOR_EACH_INSN_DEF (def, insn)
15684 : 2411 : if (DF_REF_REG_DEF_P (def)
15685 : 2411 : && !DF_REF_IS_ARTIFICIAL (def)
15686 : 2411 : && (regno1 == DF_REF_REGNO (def)
15687 : 1968 : || regno2 == DF_REF_REGNO (def)))
15688 : : return true;
15689 : :
15690 : : return false;
15691 : : }
15692 : :
15693 : : /* Function checks if instruction INSN uses register number
15694 : : REGNO as a part of address expression. */
15695 : :
15696 : : static bool
15697 : 1355 : insn_uses_reg_mem (unsigned int regno, rtx insn)
15698 : : {
15699 : 1355 : df_ref use;
15700 : :
15701 : 2857 : FOR_EACH_INSN_USE (use, insn)
15702 : 1570 : if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
15703 : : return true;
15704 : :
15705 : : return false;
15706 : : }
15707 : :
15708 : : /* Search backward for non-agu definition of register number REGNO1
15709 : : or register number REGNO2 in basic block starting from instruction
15710 : : START up to head of basic block or instruction INSN.
15711 : :
15712 : : Function puts true value into *FOUND var if definition was found
15713 : : and false otherwise.
15714 : :
15715 : : Distance in half-cycles between START and found instruction or head
15716 : : of BB is added to DISTANCE and returned. */
15717 : :
15718 : : static int
15719 : 703 : distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
15720 : : rtx_insn *insn, int distance,
15721 : : rtx_insn *start, bool *found)
15722 : : {
15723 : 703 : basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
15724 : 703 : rtx_insn *prev = start;
15725 : 703 : rtx_insn *next = NULL;
15726 : :
15727 : 703 : *found = false;
15728 : :
15729 : 703 : while (prev
15730 : 2117 : && prev != insn
15731 : 2117 : && distance < LEA_SEARCH_THRESHOLD)
15732 : : {
15733 : 1915 : if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
15734 : : {
15735 : 1061 : distance = increase_distance (prev, next, distance);
15736 : 1061 : if (insn_defines_reg (regno1, regno2, prev))
15737 : : {
15738 : 287 : if (recog_memoized (prev) < 0
15739 : 287 : || get_attr_type (prev) != TYPE_LEA)
15740 : : {
15741 : 253 : *found = true;
15742 : 253 : return distance;
15743 : : }
15744 : : }
15745 : :
15746 : : next = prev;
15747 : : }
15748 : 1662 : if (prev == BB_HEAD (bb))
15749 : : break;
15750 : :
15751 : 1414 : prev = PREV_INSN (prev);
15752 : : }
15753 : :
15754 : : return distance;
15755 : : }
15756 : :
15757 : : /* Search backward for non-agu definition of register number REGNO1
15758 : : or register number REGNO2 in INSN's basic block until
15759 : : 1. Pass LEA_SEARCH_THRESHOLD instructions, or
15760 : : 2. Reach neighbor BBs boundary, or
15761 : : 3. Reach agu definition.
15762 : : Returns the distance between the non-agu definition point and INSN.
15763 : : If no definition point, returns -1. */
15764 : :
15765 : : static int
15766 : 480 : distance_non_agu_define (unsigned int regno1, unsigned int regno2,
15767 : : rtx_insn *insn)
15768 : : {
15769 : 480 : basic_block bb = BLOCK_FOR_INSN (insn);
15770 : 480 : int distance = 0;
15771 : 480 : bool found = false;
15772 : :
15773 : 480 : if (insn != BB_HEAD (bb))
15774 : 480 : distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
15775 : : distance, PREV_INSN (insn),
15776 : : &found);
15777 : :
15778 : 480 : if (!found && distance < LEA_SEARCH_THRESHOLD)
15779 : : {
15780 : 180 : edge e;
15781 : 180 : edge_iterator ei;
15782 : 180 : bool simple_loop = false;
15783 : :
15784 : 379 : FOR_EACH_EDGE (e, ei, bb->preds)
15785 : 239 : if (e->src == bb)
15786 : : {
15787 : : simple_loop = true;
15788 : : break;
15789 : : }
15790 : :
15791 : 180 : if (simple_loop)
15792 : 40 : distance = distance_non_agu_define_in_bb (regno1, regno2,
15793 : : insn, distance,
15794 : 40 : BB_END (bb), &found);
15795 : : else
15796 : : {
15797 : 140 : int shortest_dist = -1;
15798 : 140 : bool found_in_bb = false;
15799 : :
15800 : 323 : FOR_EACH_EDGE (e, ei, bb->preds)
15801 : : {
15802 : 183 : int bb_dist
15803 : 366 : = distance_non_agu_define_in_bb (regno1, regno2,
15804 : : insn, distance,
15805 : 183 : BB_END (e->src),
15806 : : &found_in_bb);
15807 : 183 : if (found_in_bb)
15808 : : {
15809 : 29 : if (shortest_dist < 0)
15810 : : shortest_dist = bb_dist;
15811 : 0 : else if (bb_dist > 0)
15812 : 0 : shortest_dist = MIN (bb_dist, shortest_dist);
15813 : :
15814 : 29 : found = true;
15815 : : }
15816 : : }
15817 : :
15818 : 140 : distance = shortest_dist;
15819 : : }
15820 : : }
15821 : :
15822 : 480 : if (!found)
15823 : : return -1;
15824 : :
15825 : 253 : return distance >> 1;
15826 : : }
15827 : :
15828 : : /* Return the distance in half-cycles between INSN and the next
15829 : : insn that uses register number REGNO in memory address added
15830 : : to DISTANCE. Return -1 if REGNO0 is set.
15831 : :
15832 : : Put true value into *FOUND if register usage was found and
15833 : : false otherwise.
15834 : : Put true value into *REDEFINED if register redefinition was
15835 : : found and false otherwise. */
15836 : :
15837 : : static int
15838 : 842 : distance_agu_use_in_bb (unsigned int regno,
15839 : : rtx_insn *insn, int distance, rtx_insn *start,
15840 : : bool *found, bool *redefined)
15841 : : {
15842 : 842 : basic_block bb = NULL;
15843 : 842 : rtx_insn *next = start;
15844 : 842 : rtx_insn *prev = NULL;
15845 : :
15846 : 842 : *found = false;
15847 : 842 : *redefined = false;
15848 : :
15849 : 842 : if (start != NULL_RTX)
15850 : : {
15851 : 825 : bb = BLOCK_FOR_INSN (start);
15852 : 825 : if (start != BB_HEAD (bb))
15853 : : /* If insn and start belong to the same bb, set prev to insn,
15854 : : so the call to increase_distance will increase the distance
15855 : : between insns by 1. */
15856 : 446 : prev = insn;
15857 : : }
15858 : :
15859 : 2923 : while (next
15860 : 2923 : && next != insn
15861 : 2923 : && distance < LEA_SEARCH_THRESHOLD)
15862 : : {
15863 : 2698 : if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
15864 : : {
15865 : 1355 : distance = increase_distance(prev, next, distance);
15866 : 1355 : if (insn_uses_reg_mem (regno, next))
15867 : : {
15868 : : /* Return DISTANCE if OP0 is used in memory
15869 : : address in NEXT. */
15870 : 68 : *found = true;
15871 : 68 : return distance;
15872 : : }
15873 : :
15874 : 1287 : if (insn_defines_reg (regno, INVALID_REGNUM, next))
15875 : : {
15876 : : /* Return -1 if OP0 is set in NEXT. */
15877 : 182 : *redefined = true;
15878 : 182 : return -1;
15879 : : }
15880 : :
15881 : : prev = next;
15882 : : }
15883 : :
15884 : 2448 : if (next == BB_END (bb))
15885 : : break;
15886 : :
15887 : 2081 : next = NEXT_INSN (next);
15888 : : }
15889 : :
15890 : : return distance;
15891 : : }
15892 : :
15893 : : /* Return the distance between INSN and the next insn that uses
15894 : : register number REGNO0 in memory address. Return -1 if no such
15895 : : a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set. */
15896 : :
15897 : : static int
15898 : 480 : distance_agu_use (unsigned int regno0, rtx_insn *insn)
15899 : : {
15900 : 480 : basic_block bb = BLOCK_FOR_INSN (insn);
15901 : 480 : int distance = 0;
15902 : 480 : bool found = false;
15903 : 480 : bool redefined = false;
15904 : :
15905 : 480 : if (insn != BB_END (bb))
15906 : 446 : distance = distance_agu_use_in_bb (regno0, insn, distance,
15907 : : NEXT_INSN (insn),
15908 : : &found, &redefined);
15909 : :
15910 : 480 : if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
15911 : : {
15912 : 276 : edge e;
15913 : 276 : edge_iterator ei;
15914 : 276 : bool simple_loop = false;
15915 : :
15916 : 608 : FOR_EACH_EDGE (e, ei, bb->succs)
15917 : 396 : if (e->dest == bb)
15918 : : {
15919 : : simple_loop = true;
15920 : : break;
15921 : : }
15922 : :
15923 : 276 : if (simple_loop)
15924 : 64 : distance = distance_agu_use_in_bb (regno0, insn,
15925 : : distance, BB_HEAD (bb),
15926 : : &found, &redefined);
15927 : : else
15928 : : {
15929 : 212 : int shortest_dist = -1;
15930 : 212 : bool found_in_bb = false;
15931 : 212 : bool redefined_in_bb = false;
15932 : :
15933 : 544 : FOR_EACH_EDGE (e, ei, bb->succs)
15934 : : {
15935 : 332 : int bb_dist
15936 : 664 : = distance_agu_use_in_bb (regno0, insn,
15937 : 332 : distance, BB_HEAD (e->dest),
15938 : : &found_in_bb, &redefined_in_bb);
15939 : 332 : if (found_in_bb)
15940 : : {
15941 : 10 : if (shortest_dist < 0)
15942 : : shortest_dist = bb_dist;
15943 : 0 : else if (bb_dist > 0)
15944 : 0 : shortest_dist = MIN (bb_dist, shortest_dist);
15945 : :
15946 : 10 : found = true;
15947 : : }
15948 : : }
15949 : :
15950 : 212 : distance = shortest_dist;
15951 : : }
15952 : : }
15953 : :
15954 : 480 : if (!found || redefined)
15955 : : return -1;
15956 : :
15957 : 68 : return distance >> 1;
15958 : : }
15959 : :
15960 : : /* Define this macro to tune LEA priority vs ADD, it take effect when
15961 : : there is a dilemma of choosing LEA or ADD
15962 : : Negative value: ADD is more preferred than LEA
15963 : : Zero: Neutral
15964 : : Positive value: LEA is more preferred than ADD. */
15965 : : #define IX86_LEA_PRIORITY 0
15966 : :
15967 : : /* Return true if usage of lea INSN has performance advantage
15968 : : over a sequence of instructions. Instructions sequence has
15969 : : SPLIT_COST cycles higher latency than lea latency. */
15970 : :
15971 : : static bool
15972 : 1802 : ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
15973 : : unsigned int regno2, int split_cost, bool has_scale)
15974 : : {
15975 : 1802 : int dist_define, dist_use;
15976 : :
15977 : : /* For Atom processors newer than Bonnell, if using a 2-source or
15978 : : 3-source LEA for non-destructive destination purposes, or due to
15979 : : wanting ability to use SCALE, the use of LEA is justified. */
15980 : 1802 : if (!TARGET_CPU_P (BONNELL))
15981 : : {
15982 : 1322 : if (has_scale)
15983 : : return true;
15984 : 1303 : if (split_cost < 1)
15985 : : return false;
15986 : 483 : if (regno0 == regno1 || regno0 == regno2)
15987 : : return false;
15988 : : return true;
15989 : : }
15990 : :
15991 : : /* Remember recog_data content. */
15992 : 480 : struct recog_data_d recog_data_save = recog_data;
15993 : :
15994 : 480 : dist_define = distance_non_agu_define (regno1, regno2, insn);
15995 : 480 : dist_use = distance_agu_use (regno0, insn);
15996 : :
15997 : : /* distance_non_agu_define can call get_attr_type which can call
15998 : : recog_memoized, restore recog_data back to previous content. */
15999 : 480 : recog_data = recog_data_save;
16000 : :
16001 : 480 : if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
16002 : : {
16003 : : /* If there is no non AGU operand definition, no AGU
16004 : : operand usage and split cost is 0 then both lea
16005 : : and non lea variants have same priority. Currently
16006 : : we prefer lea for 64 bit code and non lea on 32 bit
16007 : : code. */
16008 : 233 : if (dist_use < 0 && split_cost == 0)
16009 : 136 : return TARGET_64BIT || IX86_LEA_PRIORITY;
16010 : : else
16011 : : return true;
16012 : : }
16013 : :
16014 : : /* With longer definitions distance lea is more preferable.
16015 : : Here we change it to take into account splitting cost and
16016 : : lea priority. */
16017 : 247 : dist_define += split_cost + IX86_LEA_PRIORITY;
16018 : :
16019 : : /* If there is no use in memory addess then we just check
16020 : : that split cost exceeds AGU stall. */
16021 : 247 : if (dist_use < 0)
16022 : 242 : return dist_define > LEA_MAX_STALL;
16023 : :
16024 : : /* If this insn has both backward non-agu dependence and forward
16025 : : agu dependence, the one with short distance takes effect. */
16026 : 5 : return dist_define >= dist_use;
16027 : : }
16028 : :
16029 : : /* Return true if we need to split op0 = op1 + op2 into a sequence of
16030 : : move and add to avoid AGU stalls. */
16031 : :
16032 : : bool
16033 : 8665355 : ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
16034 : : {
16035 : 8665355 : unsigned int regno0, regno1, regno2;
16036 : :
16037 : : /* Check if we need to optimize. */
16038 : 8665355 : if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
16039 : 8664430 : return false;
16040 : :
16041 : 925 : regno0 = true_regnum (operands[0]);
16042 : 925 : regno1 = true_regnum (operands[1]);
16043 : 925 : regno2 = true_regnum (operands[2]);
16044 : :
16045 : : /* We need to split only adds with non destructive
16046 : : destination operand. */
16047 : 925 : if (regno0 == regno1 || regno0 == regno2)
16048 : : return false;
16049 : : else
16050 : 313 : return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
16051 : : }
16052 : :
16053 : : /* Return true if we should emit lea instruction instead of mov
16054 : : instruction. */
16055 : :
16056 : : bool
16057 : 27016272 : ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
16058 : : {
16059 : 27016272 : unsigned int regno0, regno1;
16060 : :
16061 : : /* Check if we need to optimize. */
16062 : 27016272 : if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
16063 : 27014078 : return false;
16064 : :
16065 : : /* Use lea for reg to reg moves only. */
16066 : 2194 : if (!REG_P (operands[0]) || !REG_P (operands[1]))
16067 : : return false;
16068 : :
16069 : 516 : regno0 = true_regnum (operands[0]);
16070 : 516 : regno1 = true_regnum (operands[1]);
16071 : :
16072 : 516 : return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
16073 : : }
16074 : :
16075 : : /* Return true if we need to split lea into a sequence of
16076 : : instructions to avoid AGU stalls during peephole2. */
16077 : :
16078 : : bool
16079 : 10482873 : ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
16080 : : {
16081 : 10482873 : unsigned int regno0, regno1, regno2;
16082 : 10482873 : int split_cost;
16083 : 10482873 : struct ix86_address parts;
16084 : 10482873 : int ok;
16085 : :
16086 : : /* The "at least two components" test below might not catch simple
16087 : : move or zero extension insns if parts.base is non-NULL and parts.disp
16088 : : is const0_rtx as the only components in the address, e.g. if the
16089 : : register is %rbp or %r13. As this test is much cheaper and moves or
16090 : : zero extensions are the common case, do this check first. */
16091 : 10482873 : if (REG_P (operands[1])
16092 : 10482873 : || (SImode_address_operand (operands[1], VOIDmode)
16093 : 90832 : && REG_P (XEXP (operands[1], 0))))
16094 : 4403457 : return false;
16095 : :
16096 : 6079416 : ok = ix86_decompose_address (operands[1], &parts);
16097 : 6079416 : gcc_assert (ok);
16098 : :
16099 : : /* There should be at least two components in the address. */
16100 : 6079416 : if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
16101 : 6079416 : + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
16102 : : return false;
16103 : :
16104 : : /* We should not split into add if non legitimate pic
16105 : : operand is used as displacement. */
16106 : 2048665 : if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
16107 : : return false;
16108 : :
16109 : 1998674 : regno0 = true_regnum (operands[0]) ;
16110 : 1998674 : regno1 = INVALID_REGNUM;
16111 : 1998674 : regno2 = INVALID_REGNUM;
16112 : :
16113 : 1998674 : if (parts.base)
16114 : 1935936 : regno1 = true_regnum (parts.base);
16115 : 1998674 : if (parts.index)
16116 : 385280 : regno2 = true_regnum (parts.index);
16117 : :
16118 : : /* Use add for a = a + b and a = b + a since it is faster and shorter
16119 : : than lea for most processors. For the processors like BONNELL, if
16120 : : the destination register of LEA holds an actual address which will
16121 : : be used soon, LEA is better and otherwise ADD is better. */
16122 : 1998674 : if (!TARGET_CPU_P (BONNELL)
16123 : 1998551 : && parts.scale == 1
16124 : 1793855 : && (!parts.disp || parts.disp == const0_rtx)
16125 : 141744 : && (regno0 == regno1 || regno0 == regno2))
16126 : : return true;
16127 : :
16128 : : /* Split with -Oz if the encoding requires fewer bytes. */
16129 : 1996691 : if (optimize_size > 1
16130 : 23 : && parts.scale > 1
16131 : 4 : && !parts.base
16132 : 4 : && (!parts.disp || parts.disp == const0_rtx))
16133 : : return true;
16134 : :
16135 : : /* Check we need to optimize. */
16136 : 1996687 : if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
16137 : 1996341 : return false;
16138 : :
16139 : 346 : split_cost = 0;
16140 : :
16141 : : /* Compute how many cycles we will add to execution time
16142 : : if split lea into a sequence of instructions. */
16143 : 346 : if (parts.base || parts.index)
16144 : : {
16145 : : /* Have to use mov instruction if non desctructive
16146 : : destination form is used. */
16147 : 346 : if (regno1 != regno0 && regno2 != regno0)
16148 : 260 : split_cost += 1;
16149 : :
16150 : : /* Have to add index to base if both exist. */
16151 : 346 : if (parts.base && parts.index)
16152 : 49 : split_cost += 1;
16153 : :
16154 : : /* Have to use shift and adds if scale is 2 or greater. */
16155 : 346 : if (parts.scale > 1)
16156 : : {
16157 : 28 : if (regno0 != regno1)
16158 : 20 : split_cost += 1;
16159 : 8 : else if (regno2 == regno0)
16160 : 2 : split_cost += 4;
16161 : : else
16162 : 6 : split_cost += parts.scale;
16163 : : }
16164 : :
16165 : : /* Have to use add instruction with immediate if
16166 : : disp is non zero. */
16167 : 346 : if (parts.disp && parts.disp != const0_rtx)
16168 : 296 : split_cost += 1;
16169 : :
16170 : : /* Subtract the price of lea. */
16171 : 346 : split_cost -= 1;
16172 : : }
16173 : :
16174 : 346 : return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
16175 : 346 : parts.scale > 1);
16176 : : }
16177 : :
16178 : : /* Return true if it is ok to optimize an ADD operation to LEA
16179 : : operation to avoid flag register consumation. For most processors,
16180 : : ADD is faster than LEA. For the processors like BONNELL, if the
16181 : : destination register of LEA holds an actual address which will be
16182 : : used soon, LEA is better and otherwise ADD is better. */
16183 : :
16184 : : bool
16185 : 8718407 : ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
16186 : : {
16187 : 8718407 : unsigned int regno0 = true_regnum (operands[0]);
16188 : 8718407 : unsigned int regno1 = true_regnum (operands[1]);
16189 : 8718407 : unsigned int regno2 = true_regnum (operands[2]);
16190 : :
16191 : : /* If a = b + c, (a!=b && a!=c), must use lea form. */
16192 : 8718407 : if (regno0 != regno1 && regno0 != regno2)
16193 : : return true;
16194 : :
16195 : 6785827 : if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
16196 : 6785200 : return false;
16197 : :
16198 : 627 : return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
16199 : : }
16200 : :
16201 : : /* Return true if destination reg of SET_BODY is shift count of
16202 : : USE_BODY. */
16203 : :
16204 : : static bool
16205 : 375 : ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
16206 : : {
16207 : 375 : rtx set_dest;
16208 : 375 : rtx shift_rtx;
16209 : 375 : int i;
16210 : :
16211 : : /* Retrieve destination of SET_BODY. */
16212 : 375 : switch (GET_CODE (set_body))
16213 : : {
16214 : 301 : case SET:
16215 : 301 : set_dest = SET_DEST (set_body);
16216 : 301 : if (!set_dest || !REG_P (set_dest))
16217 : : return false;
16218 : 300 : break;
16219 : 37 : case PARALLEL:
16220 : 111 : for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
16221 : 74 : if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
16222 : : use_body))
16223 : : return true;
16224 : : /* FALLTHROUGH */
16225 : : default:
16226 : : return false;
16227 : : }
16228 : :
16229 : : /* Retrieve shift count of USE_BODY. */
16230 : 300 : switch (GET_CODE (use_body))
16231 : : {
16232 : 100 : case SET:
16233 : 100 : shift_rtx = XEXP (use_body, 1);
16234 : 100 : break;
16235 : 100 : case PARALLEL:
16236 : 300 : for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
16237 : 200 : if (ix86_dep_by_shift_count_body (set_body,
16238 : 200 : XVECEXP (use_body, 0, i)))
16239 : : return true;
16240 : : /* FALLTHROUGH */
16241 : : default:
16242 : : return false;
16243 : : }
16244 : :
16245 : 100 : if (shift_rtx
16246 : 100 : && (GET_CODE (shift_rtx) == ASHIFT
16247 : 64 : || GET_CODE (shift_rtx) == LSHIFTRT
16248 : 24 : || GET_CODE (shift_rtx) == ASHIFTRT
16249 : 13 : || GET_CODE (shift_rtx) == ROTATE
16250 : 13 : || GET_CODE (shift_rtx) == ROTATERT))
16251 : : {
16252 : 87 : rtx shift_count = XEXP (shift_rtx, 1);
16253 : :
16254 : : /* Return true if shift count is dest of SET_BODY. */
16255 : 87 : if (REG_P (shift_count))
16256 : : {
16257 : : /* Add check since it can be invoked before register
16258 : : allocation in pre-reload schedule. */
16259 : 0 : if (reload_completed
16260 : 0 : && true_regnum (set_dest) == true_regnum (shift_count))
16261 : : return true;
16262 : 0 : else if (REGNO(set_dest) == REGNO(shift_count))
16263 : : return true;
16264 : : }
16265 : : }
16266 : :
16267 : : return false;
16268 : : }
16269 : :
16270 : : /* Return true if destination reg of SET_INSN is shift count of
16271 : : USE_INSN. */
16272 : :
16273 : : bool
16274 : 101 : ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
16275 : : {
16276 : 101 : return ix86_dep_by_shift_count_body (PATTERN (set_insn),
16277 : 101 : PATTERN (use_insn));
16278 : : }
16279 : :
16280 : : /* Return TRUE if the operands to a vec_interleave_{high,low}v2df
16281 : : are ok, keeping in mind the possible movddup alternative. */
16282 : :
16283 : : bool
16284 : 27009 : ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
16285 : : {
16286 : 27009 : if (MEM_P (operands[0]))
16287 : 332 : return rtx_equal_p (operands[0], operands[1 + high]);
16288 : 26677 : if (MEM_P (operands[1]) && MEM_P (operands[2]))
16289 : 540 : return false;
16290 : : return true;
16291 : : }
16292 : :
16293 : : /* A subroutine of ix86_build_signbit_mask. If VECT is true,
16294 : : then replicate the value for all elements of the vector
16295 : : register. */
16296 : :
16297 : : rtx
16298 : 72652 : ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
16299 : : {
16300 : 72652 : int i, n_elt;
16301 : 72652 : rtvec v;
16302 : 72652 : machine_mode scalar_mode;
16303 : :
16304 : 72652 : switch (mode)
16305 : : {
16306 : 962 : case E_V64QImode:
16307 : 962 : case E_V32QImode:
16308 : 962 : case E_V16QImode:
16309 : 962 : case E_V32HImode:
16310 : 962 : case E_V16HImode:
16311 : 962 : case E_V8HImode:
16312 : 962 : case E_V16SImode:
16313 : 962 : case E_V8SImode:
16314 : 962 : case E_V4SImode:
16315 : 962 : case E_V2SImode:
16316 : 962 : case E_V8DImode:
16317 : 962 : case E_V4DImode:
16318 : 962 : case E_V2DImode:
16319 : 962 : gcc_assert (vect);
16320 : : /* FALLTHRU */
16321 : 72652 : case E_V2HFmode:
16322 : 72652 : case E_V4HFmode:
16323 : 72652 : case E_V8HFmode:
16324 : 72652 : case E_V16HFmode:
16325 : 72652 : case E_V32HFmode:
16326 : 72652 : case E_V16SFmode:
16327 : 72652 : case E_V8SFmode:
16328 : 72652 : case E_V4SFmode:
16329 : 72652 : case E_V2SFmode:
16330 : 72652 : case E_V8DFmode:
16331 : 72652 : case E_V4DFmode:
16332 : 72652 : case E_V2DFmode:
16333 : 72652 : n_elt = GET_MODE_NUNITS (mode);
16334 : 72652 : v = rtvec_alloc (n_elt);
16335 : 72652 : scalar_mode = GET_MODE_INNER (mode);
16336 : :
16337 : 72652 : RTVEC_ELT (v, 0) = value;
16338 : :
16339 : 224970 : for (i = 1; i < n_elt; ++i)
16340 : 152318 : RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
16341 : :
16342 : 72652 : return gen_rtx_CONST_VECTOR (mode, v);
16343 : :
16344 : 0 : default:
16345 : 0 : gcc_unreachable ();
16346 : : }
16347 : : }
16348 : :
16349 : : /* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
16350 : : and ix86_expand_int_vcond. Create a mask for the sign bit in MODE
16351 : : for an SSE register. If VECT is true, then replicate the mask for
16352 : : all elements of the vector register. If INVERT is true, then create
16353 : : a mask excluding the sign bit. */
16354 : :
16355 : : rtx
16356 : 51589 : ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
16357 : : {
16358 : 51589 : machine_mode vec_mode, imode;
16359 : 51589 : wide_int w;
16360 : 51589 : rtx mask, v;
16361 : :
16362 : 51589 : switch (mode)
16363 : : {
16364 : : case E_V2HFmode:
16365 : : case E_V4HFmode:
16366 : : case E_V8HFmode:
16367 : : case E_V16HFmode:
16368 : : case E_V32HFmode:
16369 : : vec_mode = mode;
16370 : : imode = HImode;
16371 : : break;
16372 : :
16373 : 22157 : case E_V16SImode:
16374 : 22157 : case E_V16SFmode:
16375 : 22157 : case E_V8SImode:
16376 : 22157 : case E_V4SImode:
16377 : 22157 : case E_V8SFmode:
16378 : 22157 : case E_V4SFmode:
16379 : 22157 : case E_V2SFmode:
16380 : 22157 : case E_V2SImode:
16381 : 22157 : vec_mode = mode;
16382 : 22157 : imode = SImode;
16383 : 22157 : break;
16384 : :
16385 : 26866 : case E_V8DImode:
16386 : 26866 : case E_V4DImode:
16387 : 26866 : case E_V2DImode:
16388 : 26866 : case E_V8DFmode:
16389 : 26866 : case E_V4DFmode:
16390 : 26866 : case E_V2DFmode:
16391 : 26866 : vec_mode = mode;
16392 : 26866 : imode = DImode;
16393 : 26866 : break;
16394 : :
16395 : 2184 : case E_TImode:
16396 : 2184 : case E_TFmode:
16397 : 2184 : vec_mode = VOIDmode;
16398 : 2184 : imode = TImode;
16399 : 2184 : break;
16400 : :
16401 : 0 : default:
16402 : 0 : gcc_unreachable ();
16403 : : }
16404 : :
16405 : 51589 : machine_mode inner_mode = GET_MODE_INNER (mode);
16406 : 103178 : w = wi::set_bit_in_zero (GET_MODE_BITSIZE (inner_mode) - 1,
16407 : 103178 : GET_MODE_BITSIZE (inner_mode));
16408 : 51589 : if (invert)
16409 : 15843 : w = wi::bit_not (w);
16410 : :
16411 : : /* Force this value into the low part of a fp vector constant. */
16412 : 51589 : mask = immed_wide_int_const (w, imode);
16413 : 51589 : mask = gen_lowpart (inner_mode, mask);
16414 : :
16415 : 51589 : if (vec_mode == VOIDmode)
16416 : 2184 : return force_reg (inner_mode, mask);
16417 : :
16418 : 49405 : v = ix86_build_const_vector (vec_mode, vect, mask);
16419 : 49405 : return force_reg (vec_mode, v);
16420 : 51589 : }
16421 : :
16422 : : /* Return HOST_WIDE_INT for const vector OP in MODE. */
16423 : :
16424 : : HOST_WIDE_INT
16425 : 106294 : ix86_convert_const_vector_to_integer (rtx op, machine_mode mode)
16426 : : {
16427 : 228533 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
16428 : 0 : gcc_unreachable ();
16429 : :
16430 : 106294 : int nunits = GET_MODE_NUNITS (mode);
16431 : 212588 : wide_int val = wi::zero (GET_MODE_BITSIZE (mode));
16432 : 106294 : machine_mode innermode = GET_MODE_INNER (mode);
16433 : 106294 : unsigned int innermode_bits = GET_MODE_BITSIZE (innermode);
16434 : :
16435 : 106294 : switch (mode)
16436 : : {
16437 : : case E_V2QImode:
16438 : : case E_V4QImode:
16439 : : case E_V2HImode:
16440 : : case E_V8QImode:
16441 : : case E_V4HImode:
16442 : : case E_V2SImode:
16443 : 358251 : for (int i = 0; i < nunits; ++i)
16444 : : {
16445 : 255360 : int v = INTVAL (XVECEXP (op, 0, i));
16446 : 255360 : wide_int wv = wi::shwi (v, innermode_bits);
16447 : 255360 : val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
16448 : 255360 : }
16449 : : break;
16450 : : case E_V2HFmode:
16451 : : case E_V2BFmode:
16452 : : case E_V4HFmode:
16453 : : case E_V4BFmode:
16454 : : case E_V2SFmode:
16455 : 10285 : for (int i = 0; i < nunits; ++i)
16456 : : {
16457 : 6882 : rtx x = XVECEXP (op, 0, i);
16458 : 6882 : int v = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
16459 : 6882 : REAL_MODE_FORMAT (innermode));
16460 : 6882 : wide_int wv = wi::shwi (v, innermode_bits);
16461 : 6882 : val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
16462 : 6882 : }
16463 : : break;
16464 : 0 : default:
16465 : 0 : gcc_unreachable ();
16466 : : }
16467 : :
16468 : 212588 : return val.to_shwi ();
16469 : 106294 : }
16470 : :
16471 : : /* Return TRUE or FALSE depending on whether the first SET in INSN
16472 : : has source and destination with matching CC modes, and that the
16473 : : CC mode is at least as constrained as REQ_MODE. */
16474 : :
16475 : : bool
16476 : 11368360 : ix86_match_ccmode (rtx insn, machine_mode req_mode)
16477 : : {
16478 : 11368360 : rtx set;
16479 : 11368360 : machine_mode set_mode;
16480 : :
16481 : 11368360 : set = PATTERN (insn);
16482 : 11368360 : if (GET_CODE (set) == PARALLEL)
16483 : 322614 : set = XVECEXP (set, 0, 0);
16484 : 11368360 : gcc_assert (GET_CODE (set) == SET);
16485 : 11368360 : gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
16486 : :
16487 : 11368360 : set_mode = GET_MODE (SET_DEST (set));
16488 : 11368360 : switch (set_mode)
16489 : : {
16490 : 274741 : case E_CCNOmode:
16491 : 274741 : if (req_mode != CCNOmode
16492 : 33033 : && (req_mode != CCmode
16493 : 0 : || XEXP (SET_SRC (set), 1) != const0_rtx))
16494 : : return false;
16495 : : break;
16496 : 1038354 : case E_CCmode:
16497 : 1038354 : if (req_mode == CCGCmode)
16498 : : return false;
16499 : : /* FALLTHRU */
16500 : 1766843 : case E_CCGCmode:
16501 : 1766843 : if (req_mode == CCGOCmode || req_mode == CCNOmode)
16502 : : return false;
16503 : : /* FALLTHRU */
16504 : 2107763 : case E_CCGOCmode:
16505 : 2107763 : if (req_mode == CCZmode)
16506 : : return false;
16507 : : /* FALLTHRU */
16508 : : case E_CCZmode:
16509 : : break;
16510 : :
16511 : 356 : case E_CCGZmode:
16512 : :
16513 : 356 : case E_CCAmode:
16514 : 356 : case E_CCCmode:
16515 : 356 : case E_CCOmode:
16516 : 356 : case E_CCPmode:
16517 : 356 : case E_CCSmode:
16518 : 356 : if (set_mode != req_mode)
16519 : : return false;
16520 : : break;
16521 : :
16522 : 0 : default:
16523 : 0 : gcc_unreachable ();
16524 : : }
16525 : :
16526 : 11329290 : return GET_MODE (SET_SRC (set)) == set_mode;
16527 : : }
16528 : :
16529 : : machine_mode
16530 : 11764276 : ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
16531 : : {
16532 : 11764276 : machine_mode mode = GET_MODE (op0);
16533 : :
16534 : 11764276 : if (SCALAR_FLOAT_MODE_P (mode))
16535 : : {
16536 : 107091 : gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
16537 : : return CCFPmode;
16538 : : }
16539 : :
16540 : 11657185 : switch (code)
16541 : : {
16542 : : /* Only zero flag is needed. */
16543 : : case EQ: /* ZF=0 */
16544 : : case NE: /* ZF!=0 */
16545 : : return CCZmode;
16546 : : /* Codes needing carry flag. */
16547 : 789948 : case GEU: /* CF=0 */
16548 : 789948 : case LTU: /* CF=1 */
16549 : 789948 : rtx geu;
16550 : : /* Detect overflow checks. They need just the carry flag. */
16551 : 789948 : if (GET_CODE (op0) == PLUS
16552 : 789948 : && (rtx_equal_p (op1, XEXP (op0, 0))
16553 : 95908 : || rtx_equal_p (op1, XEXP (op0, 1))))
16554 : 17852 : return CCCmode;
16555 : : /* Similarly for *setcc_qi_addqi3_cconly_overflow_1_* patterns.
16556 : : Match LTU of op0
16557 : : (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
16558 : : and op1
16559 : : (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
16560 : : where CC_CCC is either CC or CCC. */
16561 : 772096 : else if (code == LTU
16562 : 275464 : && GET_CODE (op0) == NEG
16563 : 2465 : && GET_CODE (geu = XEXP (op0, 0)) == GEU
16564 : 1142 : && REG_P (XEXP (geu, 0))
16565 : 816 : && (GET_MODE (XEXP (geu, 0)) == CCCmode
16566 : 14 : || GET_MODE (XEXP (geu, 0)) == CCmode)
16567 : 810 : && REGNO (XEXP (geu, 0)) == FLAGS_REG
16568 : 810 : && XEXP (geu, 1) == const0_rtx
16569 : 810 : && GET_CODE (op1) == LTU
16570 : 810 : && REG_P (XEXP (op1, 0))
16571 : 810 : && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
16572 : 810 : && REGNO (XEXP (op1, 0)) == FLAGS_REG
16573 : 772906 : && XEXP (op1, 1) == const0_rtx)
16574 : : return CCCmode;
16575 : : /* Similarly for *x86_cmc pattern.
16576 : : Match LTU of op0 (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
16577 : : and op1 (geu:QI (reg:CCC FLAGS_REG) (const_int 0)).
16578 : : It is sufficient to test that the operand modes are CCCmode. */
16579 : 771286 : else if (code == LTU
16580 : 274654 : && GET_CODE (op0) == NEG
16581 : 1655 : && GET_CODE (XEXP (op0, 0)) == LTU
16582 : 340 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
16583 : 3 : && GET_CODE (op1) == GEU
16584 : 3 : && GET_MODE (XEXP (op1, 0)) == CCCmode)
16585 : : return CCCmode;
16586 : : else
16587 : : return CCmode;
16588 : : case GTU: /* CF=0 & ZF=0 */
16589 : : case LEU: /* CF=1 | ZF=1 */
16590 : : return CCmode;
16591 : : /* Codes possibly doable only with sign flag when
16592 : : comparing against zero. */
16593 : 654848 : case GE: /* SF=OF or SF=0 */
16594 : 654848 : case LT: /* SF<>OF or SF=1 */
16595 : 654848 : if (op1 == const0_rtx)
16596 : : return CCGOCmode;
16597 : : else
16598 : : /* For other cases Carry flag is not required. */
16599 : 335615 : return CCGCmode;
16600 : : /* Codes doable only with sign flag when comparing
16601 : : against zero, but we miss jump instruction for it
16602 : : so we need to use relational tests against overflow
16603 : : that thus needs to be zero. */
16604 : 740562 : case GT: /* ZF=0 & SF=OF */
16605 : 740562 : case LE: /* ZF=1 | SF<>OF */
16606 : 740562 : if (op1 == const0_rtx)
16607 : : return CCNOmode;
16608 : : else
16609 : 478000 : return CCGCmode;
16610 : : default:
16611 : : /* CCmode should be used in all other cases. */
16612 : : return CCmode;
16613 : : }
16614 : : }
16615 : :
16616 : : /* Return TRUE or FALSE depending on whether the ptest instruction
16617 : : INSN has source and destination with suitable matching CC modes. */
16618 : :
16619 : : bool
16620 : 7549 : ix86_match_ptest_ccmode (rtx insn)
16621 : : {
16622 : 7549 : rtx set, src;
16623 : 7549 : machine_mode set_mode;
16624 : :
16625 : 7549 : set = PATTERN (insn);
16626 : 7549 : gcc_assert (GET_CODE (set) == SET);
16627 : 7549 : src = SET_SRC (set);
16628 : 7549 : gcc_assert (GET_CODE (src) == UNSPEC
16629 : : && XINT (src, 1) == UNSPEC_PTEST);
16630 : :
16631 : 7549 : set_mode = GET_MODE (src);
16632 : 7549 : if (set_mode != CCZmode
16633 : : && set_mode != CCCmode
16634 : : && set_mode != CCmode)
16635 : : return false;
16636 : 7549 : return GET_MODE (SET_DEST (set)) == set_mode;
16637 : : }
16638 : :
16639 : : /* Return the fixed registers used for condition codes. */
16640 : :
16641 : : static bool
16642 : 9153338 : ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
16643 : : {
16644 : 9153338 : *p1 = FLAGS_REG;
16645 : 9153338 : *p2 = INVALID_REGNUM;
16646 : 9153338 : return true;
16647 : : }
16648 : :
16649 : : /* If two condition code modes are compatible, return a condition code
16650 : : mode which is compatible with both. Otherwise, return
16651 : : VOIDmode. */
16652 : :
16653 : : static machine_mode
16654 : 30202 : ix86_cc_modes_compatible (machine_mode m1, machine_mode m2)
16655 : : {
16656 : 30202 : if (m1 == m2)
16657 : : return m1;
16658 : :
16659 : 30110 : if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
16660 : : return VOIDmode;
16661 : :
16662 : 30110 : if ((m1 == CCGCmode && m2 == CCGOCmode)
16663 : 30110 : || (m1 == CCGOCmode && m2 == CCGCmode))
16664 : : return CCGCmode;
16665 : :
16666 : 30110 : if ((m1 == CCNOmode && m2 == CCGOCmode)
16667 : 29888 : || (m1 == CCGOCmode && m2 == CCNOmode))
16668 : : return CCNOmode;
16669 : :
16670 : 29738 : if (m1 == CCZmode
16671 : 18387 : && (m2 == CCGCmode || m2 == CCGOCmode || m2 == CCNOmode))
16672 : : return m2;
16673 : 15689 : else if (m2 == CCZmode
16674 : 11142 : && (m1 == CCGCmode || m1 == CCGOCmode || m1 == CCNOmode))
16675 : : return m1;
16676 : :
16677 : 5676 : switch (m1)
16678 : : {
16679 : 0 : default:
16680 : 0 : gcc_unreachable ();
16681 : :
16682 : 5676 : case E_CCmode:
16683 : 5676 : case E_CCGCmode:
16684 : 5676 : case E_CCGOCmode:
16685 : 5676 : case E_CCNOmode:
16686 : 5676 : case E_CCAmode:
16687 : 5676 : case E_CCCmode:
16688 : 5676 : case E_CCOmode:
16689 : 5676 : case E_CCPmode:
16690 : 5676 : case E_CCSmode:
16691 : 5676 : case E_CCZmode:
16692 : 5676 : switch (m2)
16693 : : {
16694 : : default:
16695 : : return VOIDmode;
16696 : :
16697 : : case E_CCmode:
16698 : : case E_CCGCmode:
16699 : : case E_CCGOCmode:
16700 : : case E_CCNOmode:
16701 : : case E_CCAmode:
16702 : : case E_CCCmode:
16703 : : case E_CCOmode:
16704 : : case E_CCPmode:
16705 : : case E_CCSmode:
16706 : : case E_CCZmode:
16707 : : return CCmode;
16708 : : }
16709 : :
16710 : : case E_CCFPmode:
16711 : : /* These are only compatible with themselves, which we already
16712 : : checked above. */
16713 : : return VOIDmode;
16714 : : }
16715 : : }
16716 : :
16717 : : /* Return strategy to use for floating-point. We assume that fcomi is always
16718 : : preferrable where available, since that is also true when looking at size
16719 : : (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test). */
16720 : :
16721 : : enum ix86_fpcmp_strategy
16722 : 5264584 : ix86_fp_comparison_strategy (enum rtx_code)
16723 : : {
16724 : : /* Do fcomi/sahf based test when profitable. */
16725 : :
16726 : 5264584 : if (TARGET_CMOVE)
16727 : : return IX86_FPCMP_COMI;
16728 : :
16729 : 0 : if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
16730 : 0 : return IX86_FPCMP_SAHF;
16731 : :
16732 : : return IX86_FPCMP_ARITH;
16733 : : }
16734 : :
16735 : : /* Convert comparison codes we use to represent FP comparison to integer
16736 : : code that will result in proper branch. Return UNKNOWN if no such code
16737 : : is available. */
16738 : :
16739 : : enum rtx_code
16740 : 556093 : ix86_fp_compare_code_to_integer (enum rtx_code code)
16741 : : {
16742 : 556093 : switch (code)
16743 : : {
16744 : : case GT:
16745 : : return GTU;
16746 : 13641 : case GE:
16747 : 13641 : return GEU;
16748 : 234221 : case ORDERED:
16749 : 234221 : case UNORDERED:
16750 : 234221 : return code;
16751 : 117677 : case UNEQ:
16752 : 117677 : return EQ;
16753 : 15625 : case UNLT:
16754 : 15625 : return LTU;
16755 : 31915 : case UNLE:
16756 : 31915 : return LEU;
16757 : 109958 : case LTGT:
16758 : 109958 : return NE;
16759 : 173 : default:
16760 : 173 : return UNKNOWN;
16761 : : }
16762 : : }
16763 : :
16764 : : /* Zero extend possibly SImode EXP to Pmode register. */
16765 : : rtx
16766 : 63018 : ix86_zero_extend_to_Pmode (rtx exp)
16767 : : {
16768 : 63018 : return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
16769 : : }
16770 : :
16771 : : /* Return true if the function is called via PLT. */
16772 : :
16773 : : bool
16774 : 959256 : ix86_call_use_plt_p (rtx call_op)
16775 : : {
16776 : 959256 : if (SYMBOL_REF_LOCAL_P (call_op))
16777 : : {
16778 : 184688 : if (SYMBOL_REF_DECL (call_op)
16779 : 184688 : && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
16780 : : {
16781 : : /* NB: All ifunc functions must be called via PLT. */
16782 : 101582 : cgraph_node *node
16783 : 101582 : = cgraph_node::get (SYMBOL_REF_DECL (call_op));
16784 : 101582 : if (node && node->ifunc_resolver)
16785 : : return true;
16786 : : }
16787 : 184662 : return false;
16788 : : }
16789 : : return true;
16790 : : }
16791 : :
16792 : : /* Implement TARGET_IFUNC_REF_LOCAL_OK. If this hook returns true,
16793 : : the PLT entry will be used as the function address for local IFUNC
16794 : : functions. When the PIC register is needed for PLT call, indirect
16795 : : call via the PLT entry will fail since the PIC register may not be
16796 : : set up properly for indirect call. In this case, we should return
16797 : : false. */
16798 : :
16799 : : static bool
16800 : 636884010 : ix86_ifunc_ref_local_ok (void)
16801 : : {
16802 : 636884010 : return !flag_pic || (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC);
16803 : : }
16804 : :
16805 : : /* Return true if the function being called was marked with attribute
16806 : : "noplt" or using -fno-plt and we are compiling for non-PIC. We need
16807 : : to handle the non-PIC case in the backend because there is no easy
16808 : : interface for the front-end to force non-PLT calls to use the GOT.
16809 : : This is currently used only with 64-bit or 32-bit GOT32X ELF targets
16810 : : to call the function marked "noplt" indirectly. */
16811 : :
16812 : : static bool
16813 : 5539839 : ix86_nopic_noplt_attribute_p (rtx call_op)
16814 : : {
16815 : 5066265 : if (flag_pic || ix86_cmodel == CM_LARGE
16816 : : || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
16817 : : || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
16818 : 10606104 : || SYMBOL_REF_LOCAL_P (call_op))
16819 : : return false;
16820 : :
16821 : 3556336 : tree symbol_decl = SYMBOL_REF_DECL (call_op);
16822 : :
16823 : 3556336 : if (!flag_plt
16824 : 3556336 : || (symbol_decl != NULL_TREE
16825 : 3556328 : && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl))))
16826 : 10 : return true;
16827 : :
16828 : : return false;
16829 : : }
16830 : :
16831 : : /* Helper to output the jmp/call. */
16832 : : static void
16833 : 33 : ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno)
16834 : : {
16835 : 33 : if (thunk_name != NULL)
16836 : : {
16837 : 22 : if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
16838 : 1 : && ix86_indirect_branch_cs_prefix)
16839 : 1 : fprintf (asm_out_file, "\tcs\n");
16840 : 22 : fprintf (asm_out_file, "\tjmp\t");
16841 : 22 : assemble_name (asm_out_file, thunk_name);
16842 : 22 : putc ('\n', asm_out_file);
16843 : 22 : if ((ix86_harden_sls & harden_sls_indirect_jmp))
16844 : 2 : fputs ("\tint3\n", asm_out_file);
16845 : : }
16846 : : else
16847 : 11 : output_indirect_thunk (regno);
16848 : 33 : }
16849 : :
16850 : : /* Output indirect branch via a call and return thunk. CALL_OP is a
16851 : : register which contains the branch target. XASM is the assembly
16852 : : template for CALL_OP. Branch is a tail call if SIBCALL_P is true.
16853 : : A normal call is converted to:
16854 : :
16855 : : call __x86_indirect_thunk_reg
16856 : :
16857 : : and a tail call is converted to:
16858 : :
16859 : : jmp __x86_indirect_thunk_reg
16860 : : */
16861 : :
16862 : : static void
16863 : 50 : ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
16864 : : {
16865 : 50 : char thunk_name_buf[32];
16866 : 50 : char *thunk_name;
16867 : 50 : enum indirect_thunk_prefix need_prefix
16868 : 50 : = indirect_thunk_need_prefix (current_output_insn);
16869 : 50 : int regno = REGNO (call_op);
16870 : :
16871 : 50 : if (cfun->machine->indirect_branch_type
16872 : 50 : != indirect_branch_thunk_inline)
16873 : : {
16874 : 39 : if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
16875 : 16 : SET_HARD_REG_BIT (indirect_thunks_used, regno);
16876 : :
16877 : 39 : indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
16878 : 39 : thunk_name = thunk_name_buf;
16879 : : }
16880 : : else
16881 : : thunk_name = NULL;
16882 : :
16883 : 50 : if (sibcall_p)
16884 : 27 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
16885 : : else
16886 : : {
16887 : 23 : if (thunk_name != NULL)
16888 : : {
16889 : 17 : if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
16890 : 1 : && ix86_indirect_branch_cs_prefix)
16891 : 1 : fprintf (asm_out_file, "\tcs\n");
16892 : 17 : fprintf (asm_out_file, "\tcall\t");
16893 : 17 : assemble_name (asm_out_file, thunk_name);
16894 : 17 : putc ('\n', asm_out_file);
16895 : 17 : return;
16896 : : }
16897 : :
16898 : 6 : char indirectlabel1[32];
16899 : 6 : char indirectlabel2[32];
16900 : :
16901 : 6 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
16902 : : INDIRECT_LABEL,
16903 : : indirectlabelno++);
16904 : 6 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
16905 : : INDIRECT_LABEL,
16906 : : indirectlabelno++);
16907 : :
16908 : : /* Jump. */
16909 : 6 : fputs ("\tjmp\t", asm_out_file);
16910 : 6 : assemble_name_raw (asm_out_file, indirectlabel2);
16911 : 6 : fputc ('\n', asm_out_file);
16912 : :
16913 : 6 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
16914 : :
16915 : 6 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
16916 : :
16917 : 6 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
16918 : :
16919 : : /* Call. */
16920 : 6 : fputs ("\tcall\t", asm_out_file);
16921 : 6 : assemble_name_raw (asm_out_file, indirectlabel1);
16922 : 6 : fputc ('\n', asm_out_file);
16923 : : }
16924 : : }
16925 : :
16926 : : /* Output indirect branch via a call and return thunk. CALL_OP is
16927 : : the branch target. XASM is the assembly template for CALL_OP.
16928 : : Branch is a tail call if SIBCALL_P is true. A normal call is
16929 : : converted to:
16930 : :
16931 : : jmp L2
16932 : : L1:
16933 : : push CALL_OP
16934 : : jmp __x86_indirect_thunk
16935 : : L2:
16936 : : call L1
16937 : :
16938 : : and a tail call is converted to:
16939 : :
16940 : : push CALL_OP
16941 : : jmp __x86_indirect_thunk
16942 : : */
16943 : :
16944 : : static void
16945 : 0 : ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
16946 : : bool sibcall_p)
16947 : : {
16948 : 0 : char thunk_name_buf[32];
16949 : 0 : char *thunk_name;
16950 : 0 : char push_buf[64];
16951 : 0 : enum indirect_thunk_prefix need_prefix
16952 : 0 : = indirect_thunk_need_prefix (current_output_insn);
16953 : 0 : int regno = -1;
16954 : :
16955 : 0 : if (cfun->machine->indirect_branch_type
16956 : 0 : != indirect_branch_thunk_inline)
16957 : : {
16958 : 0 : if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
16959 : 0 : indirect_thunk_needed = true;
16960 : 0 : indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
16961 : 0 : thunk_name = thunk_name_buf;
16962 : : }
16963 : : else
16964 : : thunk_name = NULL;
16965 : :
16966 : 0 : snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
16967 : 0 : TARGET_64BIT ? 'q' : 'l', xasm);
16968 : :
16969 : 0 : if (sibcall_p)
16970 : : {
16971 : 0 : output_asm_insn (push_buf, &call_op);
16972 : 0 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
16973 : : }
16974 : : else
16975 : : {
16976 : 0 : char indirectlabel1[32];
16977 : 0 : char indirectlabel2[32];
16978 : :
16979 : 0 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
16980 : : INDIRECT_LABEL,
16981 : : indirectlabelno++);
16982 : 0 : ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
16983 : : INDIRECT_LABEL,
16984 : : indirectlabelno++);
16985 : :
16986 : : /* Jump. */
16987 : 0 : fputs ("\tjmp\t", asm_out_file);
16988 : 0 : assemble_name_raw (asm_out_file, indirectlabel2);
16989 : 0 : fputc ('\n', asm_out_file);
16990 : :
16991 : 0 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
16992 : :
16993 : : /* An external function may be called via GOT, instead of PLT. */
16994 : 0 : if (MEM_P (call_op))
16995 : : {
16996 : 0 : struct ix86_address parts;
16997 : 0 : rtx addr = XEXP (call_op, 0);
16998 : 0 : if (ix86_decompose_address (addr, &parts)
16999 : 0 : && parts.base == stack_pointer_rtx)
17000 : : {
17001 : : /* Since call will adjust stack by -UNITS_PER_WORD,
17002 : : we must convert "disp(stack, index, scale)" to
17003 : : "disp+UNITS_PER_WORD(stack, index, scale)". */
17004 : 0 : if (parts.index)
17005 : : {
17006 : 0 : addr = gen_rtx_MULT (Pmode, parts.index,
17007 : : GEN_INT (parts.scale));
17008 : 0 : addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
17009 : : addr);
17010 : : }
17011 : : else
17012 : : addr = stack_pointer_rtx;
17013 : :
17014 : 0 : rtx disp;
17015 : 0 : if (parts.disp != NULL_RTX)
17016 : 0 : disp = plus_constant (Pmode, parts.disp,
17017 : 0 : UNITS_PER_WORD);
17018 : : else
17019 : 0 : disp = GEN_INT (UNITS_PER_WORD);
17020 : :
17021 : 0 : addr = gen_rtx_PLUS (Pmode, addr, disp);
17022 : 0 : call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
17023 : : }
17024 : : }
17025 : :
17026 : 0 : output_asm_insn (push_buf, &call_op);
17027 : :
17028 : 0 : ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
17029 : :
17030 : 0 : ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
17031 : :
17032 : : /* Call. */
17033 : 0 : fputs ("\tcall\t", asm_out_file);
17034 : 0 : assemble_name_raw (asm_out_file, indirectlabel1);
17035 : 0 : fputc ('\n', asm_out_file);
17036 : : }
17037 : 0 : }
17038 : :
17039 : : /* Output indirect branch via a call and return thunk. CALL_OP is
17040 : : the branch target. XASM is the assembly template for CALL_OP.
17041 : : Branch is a tail call if SIBCALL_P is true. */
17042 : :
17043 : : static void
17044 : 50 : ix86_output_indirect_branch (rtx call_op, const char *xasm,
17045 : : bool sibcall_p)
17046 : : {
17047 : 50 : if (REG_P (call_op))
17048 : 50 : ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
17049 : : else
17050 : 0 : ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
17051 : 50 : }
17052 : :
17053 : : /* Output indirect jump. CALL_OP is the jump target. */
17054 : :
17055 : : const char *
17056 : 17683 : ix86_output_indirect_jmp (rtx call_op)
17057 : : {
17058 : 17683 : if (cfun->machine->indirect_branch_type != indirect_branch_keep)
17059 : : {
17060 : : /* We can't have red-zone since "call" in the indirect thunk
17061 : : pushes the return address onto stack, destroying red-zone. */
17062 : 4 : if (ix86_red_zone_used)
17063 : 0 : gcc_unreachable ();
17064 : :
17065 : 4 : ix86_output_indirect_branch (call_op, "%0", true);
17066 : : }
17067 : : else
17068 : 17679 : output_asm_insn ("%!jmp\t%A0", &call_op);
17069 : 17683 : return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
17070 : : }
17071 : :
17072 : : /* Output return instrumentation for current function if needed. */
17073 : :
17074 : : static void
17075 : 1609924 : output_return_instrumentation (void)
17076 : : {
17077 : 1609924 : if (ix86_instrument_return != instrument_return_none
17078 : 6 : && flag_fentry
17079 : 1609930 : && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
17080 : : {
17081 : 5 : if (ix86_flag_record_return)
17082 : 5 : fprintf (asm_out_file, "1:\n");
17083 : 5 : switch (ix86_instrument_return)
17084 : : {
17085 : 2 : case instrument_return_call:
17086 : 2 : fprintf (asm_out_file, "\tcall\t__return__\n");
17087 : 2 : break;
17088 : 3 : case instrument_return_nop5:
17089 : : /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
17090 : 3 : fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
17091 : 3 : break;
17092 : : case instrument_return_none:
17093 : : break;
17094 : : }
17095 : :
17096 : 5 : if (ix86_flag_record_return)
17097 : : {
17098 : 5 : fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
17099 : 5 : fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
17100 : 5 : fprintf (asm_out_file, "\t.previous\n");
17101 : : }
17102 : : }
17103 : 1609924 : }
17104 : :
17105 : : /* Output function return. CALL_OP is the jump target. Add a REP
17106 : : prefix to RET if LONG_P is true and function return is kept. */
17107 : :
17108 : : const char *
17109 : 1496141 : ix86_output_function_return (bool long_p)
17110 : : {
17111 : 1496141 : output_return_instrumentation ();
17112 : :
17113 : 1496141 : if (cfun->machine->function_return_type != indirect_branch_keep)
17114 : : {
17115 : 17 : char thunk_name[32];
17116 : 17 : enum indirect_thunk_prefix need_prefix
17117 : 17 : = indirect_thunk_need_prefix (current_output_insn);
17118 : :
17119 : 17 : if (cfun->machine->function_return_type
17120 : 17 : != indirect_branch_thunk_inline)
17121 : : {
17122 : 12 : bool need_thunk = (cfun->machine->function_return_type
17123 : : == indirect_branch_thunk);
17124 : 12 : indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
17125 : : true);
17126 : 12 : indirect_return_needed |= need_thunk;
17127 : 12 : fprintf (asm_out_file, "\tjmp\t");
17128 : 12 : assemble_name (asm_out_file, thunk_name);
17129 : 12 : putc ('\n', asm_out_file);
17130 : : }
17131 : : else
17132 : 5 : output_indirect_thunk (INVALID_REGNUM);
17133 : :
17134 : 17 : return "";
17135 : : }
17136 : :
17137 : 2991696 : output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr);
17138 : 1496124 : return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
17139 : : }
17140 : :
17141 : : /* Output indirect function return. RET_OP is the function return
17142 : : target. */
17143 : :
17144 : : const char *
17145 : 17 : ix86_output_indirect_function_return (rtx ret_op)
17146 : : {
17147 : 17 : if (cfun->machine->function_return_type != indirect_branch_keep)
17148 : : {
17149 : 0 : char thunk_name[32];
17150 : 0 : enum indirect_thunk_prefix need_prefix
17151 : 0 : = indirect_thunk_need_prefix (current_output_insn);
17152 : 0 : unsigned int regno = REGNO (ret_op);
17153 : 0 : gcc_assert (regno == CX_REG);
17154 : :
17155 : 0 : if (cfun->machine->function_return_type
17156 : 0 : != indirect_branch_thunk_inline)
17157 : : {
17158 : 0 : bool need_thunk = (cfun->machine->function_return_type
17159 : : == indirect_branch_thunk);
17160 : 0 : indirect_thunk_name (thunk_name, regno, need_prefix, true);
17161 : :
17162 : 0 : if (need_thunk)
17163 : : {
17164 : 0 : indirect_return_via_cx = true;
17165 : 0 : SET_HARD_REG_BIT (indirect_thunks_used, CX_REG);
17166 : : }
17167 : 0 : fprintf (asm_out_file, "\tjmp\t");
17168 : 0 : assemble_name (asm_out_file, thunk_name);
17169 : 0 : putc ('\n', asm_out_file);
17170 : : }
17171 : : else
17172 : 0 : output_indirect_thunk (regno);
17173 : : }
17174 : : else
17175 : : {
17176 : 17 : output_asm_insn ("%!jmp\t%A0", &ret_op);
17177 : 17 : if (ix86_harden_sls & harden_sls_indirect_jmp)
17178 : 1 : fputs ("\tint3\n", asm_out_file);
17179 : : }
17180 : 17 : return "";
17181 : : }
17182 : :
17183 : : /* Output the assembly for a call instruction. */
17184 : :
17185 : : const char *
17186 : 5716752 : ix86_output_call_insn (rtx_insn *insn, rtx call_op)
17187 : : {
17188 : 5716752 : bool direct_p = constant_call_address_operand (call_op, VOIDmode);
17189 : 5716752 : bool output_indirect_p
17190 : : = (!TARGET_SEH
17191 : 5716752 : && cfun->machine->indirect_branch_type != indirect_branch_keep);
17192 : 5716752 : bool seh_nop_p = false;
17193 : 5716752 : const char *xasm;
17194 : :
17195 : 5716752 : if (SIBLING_CALL_P (insn))
17196 : : {
17197 : 113783 : output_return_instrumentation ();
17198 : 113783 : if (direct_p)
17199 : : {
17200 : 105139 : if (ix86_nopic_noplt_attribute_p (call_op))
17201 : : {
17202 : 4 : direct_p = false;
17203 : 4 : if (TARGET_64BIT)
17204 : : {
17205 : 4 : if (output_indirect_p)
17206 : : xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17207 : : else
17208 : 4 : xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17209 : : }
17210 : : else
17211 : : {
17212 : 0 : if (output_indirect_p)
17213 : : xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
17214 : : else
17215 : 0 : xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
17216 : : }
17217 : : }
17218 : : else
17219 : : xasm = "%!jmp\t%P0";
17220 : : }
17221 : : /* SEH epilogue detection requires the indirect branch case
17222 : : to include REX.W. */
17223 : 8644 : else if (TARGET_SEH)
17224 : : xasm = "%!rex.W jmp\t%A0";
17225 : : else
17226 : : {
17227 : 8644 : if (output_indirect_p)
17228 : : xasm = "%0";
17229 : : else
17230 : 8621 : xasm = "%!jmp\t%A0";
17231 : : }
17232 : :
17233 : 113783 : if (output_indirect_p && !direct_p)
17234 : 23 : ix86_output_indirect_branch (call_op, xasm, true);
17235 : : else
17236 : : {
17237 : 113760 : output_asm_insn (xasm, &call_op);
17238 : 113760 : if (!direct_p
17239 : 8625 : && (ix86_harden_sls & harden_sls_indirect_jmp))
17240 : : return "int3";
17241 : : }
17242 : 113782 : return "";
17243 : : }
17244 : :
17245 : : /* SEH unwinding can require an extra nop to be emitted in several
17246 : : circumstances. Determine if we have one of those. */
17247 : 5602969 : if (TARGET_SEH)
17248 : : {
17249 : : rtx_insn *i;
17250 : :
17251 : : for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
17252 : : {
17253 : : /* Prevent a catch region from being adjacent to a jump that would
17254 : : be interpreted as an epilogue sequence by the unwinder. */
17255 : : if (JUMP_P(i) && CROSSING_JUMP_P (i))
17256 : : {
17257 : : seh_nop_p = true;
17258 : : break;
17259 : : }
17260 : :
17261 : : /* If we get to another real insn, we don't need the nop. */
17262 : : if (INSN_P (i))
17263 : : break;
17264 : :
17265 : : /* If we get to the epilogue note, prevent a catch region from
17266 : : being adjacent to the standard epilogue sequence. Note that,
17267 : : if non-call exceptions are enabled, we already did it during
17268 : : epilogue expansion, or else, if the insn can throw internally,
17269 : : we already did it during the reorg pass. */
17270 : : if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
17271 : : && !flag_non_call_exceptions
17272 : : && !can_throw_internal (insn))
17273 : : {
17274 : : seh_nop_p = true;
17275 : : break;
17276 : : }
17277 : : }
17278 : :
17279 : : /* If we didn't find a real insn following the call, prevent the
17280 : : unwinder from looking into the next function. */
17281 : : if (i == NULL)
17282 : : seh_nop_p = true;
17283 : : }
17284 : :
17285 : 5602969 : if (direct_p)
17286 : : {
17287 : 5434700 : if (ix86_nopic_noplt_attribute_p (call_op))
17288 : : {
17289 : 6 : direct_p = false;
17290 : 6 : if (TARGET_64BIT)
17291 : : {
17292 : 6 : if (output_indirect_p)
17293 : : xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17294 : : else
17295 : 6 : xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
17296 : : }
17297 : : else
17298 : : {
17299 : 0 : if (output_indirect_p)
17300 : : xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
17301 : : else
17302 : 0 : xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
17303 : : }
17304 : : }
17305 : : else
17306 : : xasm = "%!call\t%P0";
17307 : : }
17308 : : else
17309 : : {
17310 : 168269 : if (output_indirect_p)
17311 : : xasm = "%0";
17312 : : else
17313 : 168246 : xasm = "%!call\t%A0";
17314 : : }
17315 : :
17316 : 5602969 : if (output_indirect_p && !direct_p)
17317 : 23 : ix86_output_indirect_branch (call_op, xasm, false);
17318 : : else
17319 : 5602946 : output_asm_insn (xasm, &call_op);
17320 : :
17321 : : if (seh_nop_p)
17322 : : return "nop";
17323 : :
17324 : : return "";
17325 : : }
17326 : :
17327 : : /* Return a MEM corresponding to a stack slot with mode MODE.
17328 : : Allocate a new slot if necessary.
17329 : :
17330 : : The RTL for a function can have several slots available: N is
17331 : : which slot to use. */
17332 : :
17333 : : rtx
17334 : 60939 : assign_386_stack_local (machine_mode mode, enum ix86_stack_slot n)
17335 : : {
17336 : 60939 : struct stack_local_entry *s;
17337 : :
17338 : 60939 : gcc_assert (n < MAX_386_STACK_LOCALS);
17339 : :
17340 : 72847 : for (s = ix86_stack_locals; s; s = s->next)
17341 : 67869 : if (s->mode == mode && s->n == n)
17342 : 55961 : return validize_mem (copy_rtx (s->rtl));
17343 : :
17344 : 4978 : int align = 0;
17345 : : /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
17346 : : alignment with -m32 -mpreferred-stack-boundary=2. */
17347 : 4978 : if (mode == DImode
17348 : 523 : && !TARGET_64BIT
17349 : 523 : && n == SLOT_FLOATxFDI_387
17350 : 5326 : && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
17351 : : align = 32;
17352 : 4978 : s = ggc_alloc<stack_local_entry> ();
17353 : 4978 : s->n = n;
17354 : 4978 : s->mode = mode;
17355 : 9956 : s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
17356 : :
17357 : 4978 : s->next = ix86_stack_locals;
17358 : 4978 : ix86_stack_locals = s;
17359 : 4978 : return validize_mem (copy_rtx (s->rtl));
17360 : : }
17361 : :
17362 : : static void
17363 : 1392354 : ix86_instantiate_decls (void)
17364 : : {
17365 : 1392354 : struct stack_local_entry *s;
17366 : :
17367 : 1394548 : for (s = ix86_stack_locals; s; s = s->next)
17368 : 2194 : if (s->rtl != NULL_RTX)
17369 : 2194 : instantiate_decl_rtl (s->rtl);
17370 : 1392354 : }
17371 : :
17372 : : /* Check whether x86 address PARTS is a pc-relative address. */
17373 : :
17374 : : bool
17375 : 21769146 : ix86_rip_relative_addr_p (struct ix86_address *parts)
17376 : : {
17377 : 21769146 : rtx base, index, disp;
17378 : :
17379 : 21769146 : base = parts->base;
17380 : 21769146 : index = parts->index;
17381 : 21769146 : disp = parts->disp;
17382 : :
17383 : 21769146 : if (disp && !base && !index)
17384 : : {
17385 : 21545133 : if (TARGET_64BIT)
17386 : : {
17387 : 20052246 : rtx symbol = disp;
17388 : :
17389 : 20052246 : if (GET_CODE (disp) == CONST)
17390 : 5673458 : symbol = XEXP (disp, 0);
17391 : 20052246 : if (GET_CODE (symbol) == PLUS
17392 : 5228879 : && CONST_INT_P (XEXP (symbol, 1)))
17393 : 5228879 : symbol = XEXP (symbol, 0);
17394 : :
17395 : 20052246 : if (GET_CODE (symbol) == LABEL_REF
17396 : 20044961 : || (GET_CODE (symbol) == SYMBOL_REF
17397 : 18996549 : && SYMBOL_REF_TLS_MODEL (symbol) == 0)
17398 : 21100658 : || (GET_CODE (symbol) == UNSPEC
17399 : 462623 : && (XINT (symbol, 1) == UNSPEC_GOTPCREL
17400 : : || XINT (symbol, 1) == UNSPEC_PCREL
17401 : : || XINT (symbol, 1) == UNSPEC_GOTNTPOFF)))
17402 : 19441837 : return true;
17403 : : }
17404 : : }
17405 : : return false;
17406 : : }
17407 : :
17408 : : /* Calculate the length of the memory address in the instruction encoding.
17409 : : Includes addr32 prefix, does not include the one-byte modrm, opcode,
17410 : : or other prefixes. We never generate addr32 prefix for LEA insn. */
17411 : :
17412 : : int
17413 : 222341895 : memory_address_length (rtx addr, bool lea)
17414 : : {
17415 : 222341895 : struct ix86_address parts;
17416 : 222341895 : rtx base, index, disp;
17417 : 222341895 : int len;
17418 : 222341895 : int ok;
17419 : :
17420 : 222341895 : if (GET_CODE (addr) == PRE_DEC
17421 : 213304195 : || GET_CODE (addr) == POST_INC
17422 : 207573913 : || GET_CODE (addr) == PRE_MODIFY
17423 : 207573913 : || GET_CODE (addr) == POST_MODIFY)
17424 : : return 0;
17425 : :
17426 : 207573913 : ok = ix86_decompose_address (addr, &parts);
17427 : 207573913 : gcc_assert (ok);
17428 : :
17429 : 207573913 : len = (parts.seg == ADDR_SPACE_GENERIC) ? 0 : 1;
17430 : :
17431 : : /* If this is not LEA instruction, add the length of addr32 prefix. */
17432 : 170518119 : if (TARGET_64BIT && !lea
17433 : 360321107 : && (SImode_address_operand (addr, VOIDmode)
17434 : 152747116 : || (parts.base && GET_MODE (parts.base) == SImode)
17435 : 152746893 : || (parts.index && GET_MODE (parts.index) == SImode)))
17436 : 301 : len++;
17437 : :
17438 : 207573913 : base = parts.base;
17439 : 207573913 : index = parts.index;
17440 : 207573913 : disp = parts.disp;
17441 : :
17442 : 207573913 : if (base && SUBREG_P (base))
17443 : 2 : base = SUBREG_REG (base);
17444 : 207573913 : if (index && SUBREG_P (index))
17445 : 0 : index = SUBREG_REG (index);
17446 : :
17447 : 207573913 : gcc_assert (base == NULL_RTX || REG_P (base));
17448 : 207573913 : gcc_assert (index == NULL_RTX || REG_P (index));
17449 : :
17450 : : /* Rule of thumb:
17451 : : - esp as the base always wants an index,
17452 : : - ebp as the base always wants a displacement,
17453 : : - r12 as the base always wants an index,
17454 : : - r13 as the base always wants a displacement. */
17455 : :
17456 : : /* Register Indirect. */
17457 : 207573913 : if (base && !index && !disp)
17458 : : {
17459 : : /* esp (for its index) and ebp (for its displacement) need
17460 : : the two-byte modrm form. Similarly for r12 and r13 in 64-bit
17461 : : code. */
17462 : 13301199 : if (base == arg_pointer_rtx
17463 : 13301199 : || base == frame_pointer_rtx
17464 : 13301199 : || REGNO (base) == SP_REG
17465 : 8962923 : || REGNO (base) == BP_REG
17466 : 8962923 : || REGNO (base) == R12_REG
17467 : 21846365 : || REGNO (base) == R13_REG)
17468 : 4756033 : len++;
17469 : : }
17470 : :
17471 : : /* Direct Addressing. In 64-bit mode mod 00 r/m 5
17472 : : is not disp32, but disp32(%rip), so for disp32
17473 : : SIB byte is needed, unless print_operand_address
17474 : : optimizes it into disp32(%rip) or (%rip) is implied
17475 : : by UNSPEC. */
17476 : 194272714 : else if (disp && !base && !index)
17477 : : {
17478 : 21288577 : len += 4;
17479 : 21288577 : if (!ix86_rip_relative_addr_p (&parts))
17480 : 1864299 : len++;
17481 : : }
17482 : : else
17483 : : {
17484 : : /* Find the length of the displacement constant. */
17485 : 172984137 : if (disp)
17486 : : {
17487 : 169417494 : if (base && satisfies_constraint_K (disp))
17488 : 94093150 : len += 1;
17489 : : else
17490 : 75324344 : len += 4;
17491 : : }
17492 : : /* ebp always wants a displacement. Similarly r13. */
17493 : 3566643 : else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
17494 : 5817 : len++;
17495 : :
17496 : : /* An index requires the two-byte modrm form.... */
17497 : 172984137 : if (index
17498 : : /* ...like esp (or r12), which always wants an index. */
17499 : 165078397 : || base == arg_pointer_rtx
17500 : 165078397 : || base == frame_pointer_rtx
17501 : 338062534 : || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
17502 : 118446588 : len++;
17503 : : }
17504 : :
17505 : : return len;
17506 : : }
17507 : :
17508 : : /* Compute default value for "length_immediate" attribute. When SHORTFORM
17509 : : is set, expect that insn have 8bit immediate alternative. */
17510 : : int
17511 : 266460138 : ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
17512 : : {
17513 : 266460138 : int len = 0;
17514 : 266460138 : int i;
17515 : 266460138 : extract_insn_cached (insn);
17516 : 832632327 : for (i = recog_data.n_operands - 1; i >= 0; --i)
17517 : 566172189 : if (CONSTANT_P (recog_data.operand[i]))
17518 : : {
17519 : 116208646 : enum attr_mode mode = get_attr_mode (insn);
17520 : :
17521 : 116208646 : gcc_assert (!len);
17522 : 116208646 : if (shortform && CONST_INT_P (recog_data.operand[i]))
17523 : : {
17524 : 30220760 : HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
17525 : 30220760 : switch (mode)
17526 : : {
17527 : 781143 : case MODE_QI:
17528 : 781143 : len = 1;
17529 : 781143 : continue;
17530 : 305945 : case MODE_HI:
17531 : 305945 : ival = trunc_int_for_mode (ival, HImode);
17532 : 305945 : break;
17533 : 13638247 : case MODE_SI:
17534 : 13638247 : ival = trunc_int_for_mode (ival, SImode);
17535 : 13638247 : break;
17536 : : default:
17537 : : break;
17538 : : }
17539 : 29439617 : if (IN_RANGE (ival, -128, 127))
17540 : : {
17541 : 26253029 : len = 1;
17542 : 26253029 : continue;
17543 : : }
17544 : : }
17545 : 89174474 : switch (mode)
17546 : : {
17547 : : case MODE_QI:
17548 : : len = 1;
17549 : : break;
17550 : : case MODE_HI:
17551 : 566172189 : len = 2;
17552 : : break;
17553 : : case MODE_SI:
17554 : 84740031 : len = 4;
17555 : : break;
17556 : : /* Immediates for DImode instructions are encoded
17557 : : as 32bit sign extended values. */
17558 : : case MODE_DI:
17559 : 84740031 : len = 4;
17560 : : break;
17561 : 0 : default:
17562 : 0 : fatal_insn ("unknown insn mode", insn);
17563 : : }
17564 : : }
17565 : 266460138 : return len;
17566 : : }
17567 : :
17568 : : /* Compute default value for "length_address" attribute. */
17569 : : int
17570 : 376998324 : ix86_attr_length_address_default (rtx_insn *insn)
17571 : : {
17572 : 376998324 : int i;
17573 : :
17574 : 376998324 : if (get_attr_type (insn) == TYPE_LEA)
17575 : : {
17576 : 20365390 : rtx set = PATTERN (insn), addr;
17577 : :
17578 : 20365390 : if (GET_CODE (set) == PARALLEL)
17579 : 87218 : set = XVECEXP (set, 0, 0);
17580 : :
17581 : 20365390 : gcc_assert (GET_CODE (set) == SET);
17582 : :
17583 : 20365390 : addr = SET_SRC (set);
17584 : :
17585 : 20365390 : return memory_address_length (addr, true);
17586 : : }
17587 : :
17588 : 356632934 : extract_insn_cached (insn);
17589 : 824958423 : for (i = recog_data.n_operands - 1; i >= 0; --i)
17590 : : {
17591 : 670043116 : rtx op = recog_data.operand[i];
17592 : 670043116 : if (MEM_P (op))
17593 : : {
17594 : 202015937 : constrain_operands_cached (insn, reload_completed);
17595 : 202015937 : if (which_alternative != -1)
17596 : : {
17597 : 202015937 : const char *constraints = recog_data.constraints[i];
17598 : 202015937 : int alt = which_alternative;
17599 : :
17600 : 316846134 : while (*constraints == '=' || *constraints == '+')
17601 : 114830197 : constraints++;
17602 : 888298026 : while (alt-- > 0)
17603 : 1698381530 : while (*constraints++ != ',')
17604 : : ;
17605 : : /* Skip ignored operands. */
17606 : 202015937 : if (*constraints == 'X')
17607 : 298310 : continue;
17608 : : }
17609 : :
17610 : 201717627 : int len = memory_address_length (XEXP (op, 0), false);
17611 : :
17612 : : /* Account for segment prefix for non-default addr spaces. */
17613 : 213809445 : if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)))
17614 : 778707 : len++;
17615 : :
17616 : 201717627 : return len;
17617 : : }
17618 : : }
17619 : : return 0;
17620 : : }
17621 : :
17622 : : /* Compute default value for "length_vex" attribute. It includes
17623 : : 2 or 3 byte VEX prefix and 1 opcode byte. */
17624 : :
17625 : : int
17626 : 4480363 : ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
17627 : : bool has_vex_w)
17628 : : {
17629 : 4480363 : int i, reg_only = 2 + 1;
17630 : 4480363 : bool has_mem = false;
17631 : :
17632 : : /* Only 0f opcode can use 2 byte VEX prefix and VEX W bit uses 3
17633 : : byte VEX prefix. */
17634 : 4480363 : if (!has_0f_opcode || has_vex_w)
17635 : : return 3 + 1;
17636 : :
17637 : : /* We can always use 2 byte VEX prefix in 32bit. */
17638 : 4063256 : if (!TARGET_64BIT)
17639 : : return 2 + 1;
17640 : :
17641 : 3076412 : extract_insn_cached (insn);
17642 : :
17643 : 9555416 : for (i = recog_data.n_operands - 1; i >= 0; --i)
17644 : 6773690 : if (REG_P (recog_data.operand[i]))
17645 : : {
17646 : : /* REX.W bit uses 3 byte VEX prefix.
17647 : : REX2 with vex use extended EVEX prefix length is 4-byte. */
17648 : 4526842 : if (GET_MODE (recog_data.operand[i]) == DImode
17649 : 4526842 : && GENERAL_REG_P (recog_data.operand[i]))
17650 : : return 3 + 1;
17651 : :
17652 : : /* REX.B bit requires 3-byte VEX. Right here we don't know which
17653 : : operand will be encoded using VEX.B, so be conservative.
17654 : : REX2 with vex use extended EVEX prefix length is 4-byte. */
17655 : 4513253 : if (REX_INT_REGNO_P (recog_data.operand[i])
17656 : 4513253 : || REX2_INT_REGNO_P (recog_data.operand[i])
17657 : 4513253 : || REX_SSE_REGNO_P (recog_data.operand[i]))
17658 : 0 : reg_only = 3 + 1;
17659 : : }
17660 : 2246848 : else if (MEM_P (recog_data.operand[i]))
17661 : : {
17662 : : /* REX2.X or REX2.B bits use 3 byte VEX prefix. */
17663 : 1801382 : if (x86_extended_rex2reg_mentioned_p (recog_data.operand[i]))
17664 : : return 4;
17665 : :
17666 : : /* REX.X or REX.B bits use 3 byte VEX prefix. */
17667 : 1801141 : if (x86_extended_reg_mentioned_p (recog_data.operand[i]))
17668 : : return 3 + 1;
17669 : :
17670 : : has_mem = true;
17671 : : }
17672 : :
17673 : 2781726 : return has_mem ? 2 + 1 : reg_only;
17674 : : }
17675 : :
17676 : :
17677 : : static bool
17678 : : ix86_class_likely_spilled_p (reg_class_t);
17679 : :
17680 : : /* Returns true if lhs of insn is HW function argument register and set up
17681 : : is_spilled to true if it is likely spilled HW register. */
17682 : : static bool
17683 : 1167 : insn_is_function_arg (rtx insn, bool* is_spilled)
17684 : : {
17685 : 1167 : rtx dst;
17686 : :
17687 : 1167 : if (!NONDEBUG_INSN_P (insn))
17688 : : return false;
17689 : : /* Call instructions are not movable, ignore it. */
17690 : 1167 : if (CALL_P (insn))
17691 : : return false;
17692 : 1095 : insn = PATTERN (insn);
17693 : 1095 : if (GET_CODE (insn) == PARALLEL)
17694 : 73 : insn = XVECEXP (insn, 0, 0);
17695 : 1095 : if (GET_CODE (insn) != SET)
17696 : : return false;
17697 : 1095 : dst = SET_DEST (insn);
17698 : 1005 : if (REG_P (dst) && HARD_REGISTER_P (dst)
17699 : 2007 : && ix86_function_arg_regno_p (REGNO (dst)))
17700 : : {
17701 : : /* Is it likely spilled HW register? */
17702 : 912 : if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
17703 : 912 : && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
17704 : 859 : *is_spilled = true;
17705 : 912 : return true;
17706 : : }
17707 : : return false;
17708 : : }
17709 : :
17710 : : /* Add output dependencies for chain of function adjacent arguments if only
17711 : : there is a move to likely spilled HW register. Return first argument
17712 : : if at least one dependence was added or NULL otherwise. */
17713 : : static rtx_insn *
17714 : 416 : add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
17715 : : {
17716 : 416 : rtx_insn *insn;
17717 : 416 : rtx_insn *last = call;
17718 : 416 : rtx_insn *first_arg = NULL;
17719 : 416 : bool is_spilled = false;
17720 : :
17721 : 416 : head = PREV_INSN (head);
17722 : :
17723 : : /* Find nearest to call argument passing instruction. */
17724 : 416 : while (true)
17725 : : {
17726 : 416 : last = PREV_INSN (last);
17727 : 416 : if (last == head)
17728 : : return NULL;
17729 : 416 : if (!NONDEBUG_INSN_P (last))
17730 : 0 : continue;
17731 : 416 : if (insn_is_function_arg (last, &is_spilled))
17732 : : break;
17733 : : return NULL;
17734 : : }
17735 : :
17736 : : first_arg = last;
17737 : 1103 : while (true)
17738 : : {
17739 : 1103 : insn = PREV_INSN (last);
17740 : 1103 : if (!INSN_P (insn))
17741 : : break;
17742 : 983 : if (insn == head)
17743 : : break;
17744 : 942 : if (!NONDEBUG_INSN_P (insn))
17745 : : {
17746 : 191 : last = insn;
17747 : 191 : continue;
17748 : : }
17749 : 751 : if (insn_is_function_arg (insn, &is_spilled))
17750 : : {
17751 : : /* Add output depdendence between two function arguments if chain
17752 : : of output arguments contains likely spilled HW registers. */
17753 : 506 : if (is_spilled)
17754 : 506 : add_dependence (first_arg, insn, REG_DEP_OUTPUT);
17755 : : first_arg = last = insn;
17756 : : }
17757 : : else
17758 : : break;
17759 : : }
17760 : 406 : if (!is_spilled)
17761 : : return NULL;
17762 : : return first_arg;
17763 : : }
17764 : :
17765 : : /* Add output or anti dependency from insn to first_arg to restrict its code
17766 : : motion. */
17767 : : static void
17768 : 1901 : avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
17769 : : {
17770 : 1901 : rtx set;
17771 : 1901 : rtx tmp;
17772 : :
17773 : 1901 : set = single_set (insn);
17774 : 1901 : if (!set)
17775 : : return;
17776 : 1089 : tmp = SET_DEST (set);
17777 : 1089 : if (REG_P (tmp))
17778 : : {
17779 : : /* Add output dependency to the first function argument. */
17780 : 906 : add_dependence (first_arg, insn, REG_DEP_OUTPUT);
17781 : 906 : return;
17782 : : }
17783 : : /* Add anti dependency. */
17784 : 183 : add_dependence (first_arg, insn, REG_DEP_ANTI);
17785 : : }
17786 : :
17787 : : /* Avoid cross block motion of function argument through adding dependency
17788 : : from the first non-jump instruction in bb. */
17789 : : static void
17790 : 68 : add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
17791 : : {
17792 : 68 : rtx_insn *insn = BB_END (bb);
17793 : :
17794 : 134 : while (insn)
17795 : : {
17796 : 134 : if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
17797 : : {
17798 : 67 : rtx set = single_set (insn);
17799 : 67 : if (set)
17800 : : {
17801 : 67 : avoid_func_arg_motion (arg, insn);
17802 : 67 : return;
17803 : : }
17804 : : }
17805 : 67 : if (insn == BB_HEAD (bb))
17806 : : return;
17807 : 66 : insn = PREV_INSN (insn);
17808 : : }
17809 : : }
17810 : :
17811 : : /* Hook for pre-reload schedule - avoid motion of function arguments
17812 : : passed in likely spilled HW registers. */
17813 : : static void
17814 : 9131007 : ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
17815 : : {
17816 : 9131007 : rtx_insn *insn;
17817 : 9131007 : rtx_insn *first_arg = NULL;
17818 : 9131007 : if (reload_completed)
17819 : : return;
17820 : 2044 : while (head != tail && DEBUG_INSN_P (head))
17821 : 712 : head = NEXT_INSN (head);
17822 : 8642 : for (insn = tail; insn != head; insn = PREV_INSN (insn))
17823 : 7459 : if (INSN_P (insn) && CALL_P (insn))
17824 : : {
17825 : 416 : first_arg = add_parameter_dependencies (insn, head);
17826 : 416 : if (first_arg)
17827 : : {
17828 : : /* Add dependee for first argument to predecessors if only
17829 : : region contains more than one block. */
17830 : 406 : basic_block bb = BLOCK_FOR_INSN (insn);
17831 : 406 : int rgn = CONTAINING_RGN (bb->index);
17832 : 406 : int nr_blks = RGN_NR_BLOCKS (rgn);
17833 : : /* Skip trivial regions and region head blocks that can have
17834 : : predecessors outside of region. */
17835 : 406 : if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
17836 : : {
17837 : 67 : edge e;
17838 : 67 : edge_iterator ei;
17839 : :
17840 : : /* Regions are SCCs with the exception of selective
17841 : : scheduling with pipelining of outer blocks enabled.
17842 : : So also check that immediate predecessors of a non-head
17843 : : block are in the same region. */
17844 : 137 : FOR_EACH_EDGE (e, ei, bb->preds)
17845 : : {
17846 : : /* Avoid creating of loop-carried dependencies through
17847 : : using topological ordering in the region. */
17848 : 70 : if (rgn == CONTAINING_RGN (e->src->index)
17849 : 69 : && BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
17850 : 68 : add_dependee_for_func_arg (first_arg, e->src);
17851 : : }
17852 : : }
17853 : 406 : insn = first_arg;
17854 : 406 : if (insn == head)
17855 : : break;
17856 : : }
17857 : : }
17858 : 7043 : else if (first_arg)
17859 : 1834 : avoid_func_arg_motion (first_arg, insn);
17860 : : }
17861 : :
17862 : : /* Hook for pre-reload schedule - set priority of moves from likely spilled
17863 : : HW registers to maximum, to schedule them at soon as possible. These are
17864 : : moves from function argument registers at the top of the function entry
17865 : : and moves from function return value registers after call. */
17866 : : static int
17867 : 90083576 : ix86_adjust_priority (rtx_insn *insn, int priority)
17868 : : {
17869 : 90083576 : rtx set;
17870 : :
17871 : 90083576 : if (reload_completed)
17872 : : return priority;
17873 : :
17874 : 13742 : if (!NONDEBUG_INSN_P (insn))
17875 : : return priority;
17876 : :
17877 : 11717 : set = single_set (insn);
17878 : 11717 : if (set)
17879 : : {
17880 : 11185 : rtx tmp = SET_SRC (set);
17881 : 11185 : if (REG_P (tmp)
17882 : 2910 : && HARD_REGISTER_P (tmp)
17883 : 477 : && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
17884 : 11185 : && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
17885 : 427 : return current_sched_info->sched_max_insns_priority;
17886 : : }
17887 : :
17888 : : return priority;
17889 : : }
17890 : :
17891 : : /* Prepare for scheduling pass. */
17892 : : static void
17893 : 901359 : ix86_sched_init_global (FILE *, int, int)
17894 : : {
17895 : : /* Install scheduling hooks for current CPU. Some of these hooks are used
17896 : : in time-critical parts of the scheduler, so we only set them up when
17897 : : they are actually used. */
17898 : 901359 : switch (ix86_tune)
17899 : : {
17900 : 859346 : case PROCESSOR_CORE2:
17901 : 859346 : case PROCESSOR_NEHALEM:
17902 : 859346 : case PROCESSOR_SANDYBRIDGE:
17903 : 859346 : case PROCESSOR_HASWELL:
17904 : 859346 : case PROCESSOR_TREMONT:
17905 : 859346 : case PROCESSOR_ALDERLAKE:
17906 : 859346 : case PROCESSOR_GENERIC:
17907 : : /* Do not perform multipass scheduling for pre-reload schedule
17908 : : to save compile time. */
17909 : 859346 : if (reload_completed)
17910 : : {
17911 : 859062 : ix86_core2i7_init_hooks ();
17912 : 859062 : break;
17913 : : }
17914 : : /* Fall through. */
17915 : 42297 : default:
17916 : 42297 : targetm.sched.dfa_post_advance_cycle = NULL;
17917 : 42297 : targetm.sched.first_cycle_multipass_init = NULL;
17918 : 42297 : targetm.sched.first_cycle_multipass_begin = NULL;
17919 : 42297 : targetm.sched.first_cycle_multipass_issue = NULL;
17920 : 42297 : targetm.sched.first_cycle_multipass_backtrack = NULL;
17921 : 42297 : targetm.sched.first_cycle_multipass_end = NULL;
17922 : 42297 : targetm.sched.first_cycle_multipass_fini = NULL;
17923 : 42297 : break;
17924 : : }
17925 : 901359 : }
17926 : :
17927 : :
17928 : : /* Implement TARGET_STATIC_RTX_ALIGNMENT. */
17929 : :
17930 : : static HOST_WIDE_INT
17931 : 705343 : ix86_static_rtx_alignment (machine_mode mode)
17932 : : {
17933 : 705343 : if (mode == DFmode)
17934 : : return 64;
17935 : : if (ALIGN_MODE_128 (mode))
17936 : 146604 : return MAX (128, GET_MODE_ALIGNMENT (mode));
17937 : 474896 : return GET_MODE_ALIGNMENT (mode);
17938 : : }
17939 : :
17940 : : /* Implement TARGET_CONSTANT_ALIGNMENT. */
17941 : :
17942 : : static HOST_WIDE_INT
17943 : 6616526 : ix86_constant_alignment (const_tree exp, HOST_WIDE_INT align)
17944 : : {
17945 : 6616526 : if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
17946 : : || TREE_CODE (exp) == INTEGER_CST)
17947 : : {
17948 : 359851 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
17949 : 359851 : HOST_WIDE_INT mode_align = ix86_static_rtx_alignment (mode);
17950 : 359851 : return MAX (mode_align, align);
17951 : : }
17952 : 6120951 : else if (!optimize_size && TREE_CODE (exp) == STRING_CST
17953 : 9159915 : && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
17954 : : return BITS_PER_WORD;
17955 : :
17956 : : return align;
17957 : : }
17958 : :
17959 : : /* Implement TARGET_EMPTY_RECORD_P. */
17960 : :
17961 : : static bool
17962 : 1321625723 : ix86_is_empty_record (const_tree type)
17963 : : {
17964 : 1321625723 : if (!TARGET_64BIT)
17965 : : return false;
17966 : 1290010548 : return default_is_empty_record (type);
17967 : : }
17968 : :
17969 : : /* Implement TARGET_WARN_PARAMETER_PASSING_ABI. */
17970 : :
17971 : : static void
17972 : 14261227 : ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
17973 : : {
17974 : 14261227 : CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
17975 : :
17976 : 14261227 : if (!cum->warn_empty)
17977 : : return;
17978 : :
17979 : 14141047 : if (!TYPE_EMPTY_P (type))
17980 : : return;
17981 : :
17982 : : /* Don't warn if the function isn't visible outside of the TU. */
17983 : 14729 : if (cum->decl && !TREE_PUBLIC (cum->decl))
17984 : : return;
17985 : :
17986 : 13124 : const_tree ctx = get_ultimate_context (cum->decl);
17987 : 13124 : if (ctx != NULL_TREE
17988 : 26197 : && !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
17989 : : return;
17990 : :
17991 : : /* If the actual size of the type is zero, then there is no change
17992 : : in how objects of this size are passed. */
17993 : 259 : if (int_size_in_bytes (type) == 0)
17994 : : return;
17995 : :
17996 : 226 : warning (OPT_Wabi, "empty class %qT parameter passing ABI "
17997 : : "changes in %<-fabi-version=12%> (GCC 8)", type);
17998 : :
17999 : : /* Only warn once. */
18000 : 226 : cum->warn_empty = false;
18001 : : }
18002 : :
18003 : : /* This hook returns name of multilib ABI. */
18004 : :
18005 : : static const char *
18006 : 3190755 : ix86_get_multilib_abi_name (void)
18007 : : {
18008 : 3190755 : if (!(TARGET_64BIT_P (ix86_isa_flags)))
18009 : : return "i386";
18010 : 3146799 : else if (TARGET_X32_P (ix86_isa_flags))
18011 : : return "x32";
18012 : : else
18013 : 3146799 : return "x86_64";
18014 : : }
18015 : :
18016 : : /* Compute the alignment for a variable for Intel MCU psABI. TYPE is
18017 : : the data type, and ALIGN is the alignment that the object would
18018 : : ordinarily have. */
18019 : :
18020 : : static int
18021 : 0 : iamcu_alignment (tree type, int align)
18022 : : {
18023 : 0 : machine_mode mode;
18024 : :
18025 : 0 : if (align < 32 || TYPE_USER_ALIGN (type))
18026 : : return align;
18027 : :
18028 : : /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4
18029 : : bytes. */
18030 : 0 : type = strip_array_types (type);
18031 : 0 : if (TYPE_ATOMIC (type))
18032 : : return align;
18033 : :
18034 : 0 : mode = TYPE_MODE (type);
18035 : 0 : switch (GET_MODE_CLASS (mode))
18036 : : {
18037 : : case MODE_INT:
18038 : : case MODE_COMPLEX_INT:
18039 : : case MODE_COMPLEX_FLOAT:
18040 : : case MODE_FLOAT:
18041 : : case MODE_DECIMAL_FLOAT:
18042 : : return 32;
18043 : : default:
18044 : : return align;
18045 : : }
18046 : : }
18047 : :
18048 : : /* Compute the alignment for a static variable.
18049 : : TYPE is the data type, and ALIGN is the alignment that
18050 : : the object would ordinarily have. The value of this function is used
18051 : : instead of that alignment to align the object. */
18052 : :
18053 : : int
18054 : 11822977 : ix86_data_alignment (tree type, unsigned int align, bool opt)
18055 : : {
18056 : : /* GCC 4.8 and earlier used to incorrectly assume this alignment even
18057 : : for symbols from other compilation units or symbols that don't need
18058 : : to bind locally. In order to preserve some ABI compatibility with
18059 : : those compilers, ensure we don't decrease alignment from what we
18060 : : used to assume. */
18061 : :
18062 : 11822977 : unsigned int max_align_compat = MIN (256, MAX_OFILE_ALIGNMENT);
18063 : :
18064 : : /* A data structure, equal or greater than the size of a cache line
18065 : : (64 bytes in the Pentium 4 and other recent Intel processors, including
18066 : : processors based on Intel Core microarchitecture) should be aligned
18067 : : so that its base address is a multiple of a cache line size. */
18068 : :
18069 : 23645954 : unsigned int max_align
18070 : 11822977 : = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
18071 : :
18072 : 14401107 : if (max_align < BITS_PER_WORD)
18073 : 0 : max_align = BITS_PER_WORD;
18074 : :
18075 : 11822977 : switch (ix86_align_data_type)
18076 : : {
18077 : 11822977 : case ix86_align_data_type_abi: opt = false; break;
18078 : 11822957 : case ix86_align_data_type_compat: max_align = BITS_PER_WORD; break;
18079 : : case ix86_align_data_type_cacheline: break;
18080 : : }
18081 : :
18082 : 11822977 : if (TARGET_IAMCU)
18083 : 0 : align = iamcu_alignment (type, align);
18084 : :
18085 : 11822977 : if (opt
18086 : 5727604 : && AGGREGATE_TYPE_P (type)
18087 : 3676179 : && TYPE_SIZE (type)
18088 : 15499125 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
18089 : : {
18090 : 6664149 : if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align_compat)
18091 : 3676148 : && align < max_align_compat)
18092 : 688147 : align = max_align_compat;
18093 : 7295118 : if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align)
18094 : 3676148 : && align < max_align)
18095 : 57178 : align = max_align;
18096 : : }
18097 : :
18098 : : /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
18099 : : to 16byte boundary. */
18100 : 11822977 : if (TARGET_64BIT)
18101 : : {
18102 : 4805676 : if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
18103 : 3219763 : && TYPE_SIZE (type)
18104 : 3219722 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
18105 : 10637975 : && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
18106 : 11235465 : && align < 128)
18107 : 597490 : return 128;
18108 : : }
18109 : :
18110 : 11225487 : if (!opt)
18111 : 5912042 : return align;
18112 : :
18113 : 5313445 : if (TREE_CODE (type) == ARRAY_TYPE)
18114 : : {
18115 : 1091550 : if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
18116 : : return 64;
18117 : 1091550 : if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
18118 : : return 128;
18119 : : }
18120 : 4221895 : else if (TREE_CODE (type) == COMPLEX_TYPE)
18121 : : {
18122 : :
18123 : 12474 : if (TYPE_MODE (type) == DCmode && align < 64)
18124 : : return 64;
18125 : 12474 : if ((TYPE_MODE (type) == XCmode
18126 : 12474 : || TYPE_MODE (type) == TCmode) && align < 128)
18127 : : return 128;
18128 : : }
18129 : 4209421 : else if (RECORD_OR_UNION_TYPE_P (type)
18130 : 4209421 : && TYPE_FIELDS (type))
18131 : : {
18132 : 2168832 : if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
18133 : : return 64;
18134 : 2168832 : if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
18135 : : return 128;
18136 : : }
18137 : 2040589 : else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
18138 : : || TREE_CODE (type) == INTEGER_TYPE)
18139 : : {
18140 : 1898840 : if (TYPE_MODE (type) == DFmode && align < 64)
18141 : : return 64;
18142 : 1898840 : if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
18143 : : return 128;
18144 : : }
18145 : :
18146 : 5313332 : return align;
18147 : : }
18148 : :
18149 : : /* Implememnt TARGET_LOWER_LOCAL_DECL_ALIGNMENT. */
18150 : : static void
18151 : 28269563 : ix86_lower_local_decl_alignment (tree decl)
18152 : : {
18153 : 28269563 : unsigned int new_align = ix86_local_alignment (decl, VOIDmode,
18154 : 28269563 : DECL_ALIGN (decl), true);
18155 : 28269563 : if (new_align < DECL_ALIGN (decl))
18156 : 0 : SET_DECL_ALIGN (decl, new_align);
18157 : 28269563 : }
18158 : :
18159 : : /* Compute the alignment for a local variable or a stack slot. EXP is
18160 : : the data type or decl itself, MODE is the widest mode available and
18161 : : ALIGN is the alignment that the object would ordinarily have. The
18162 : : value of this macro is used instead of that alignment to align the
18163 : : object. */
18164 : :
18165 : : unsigned int
18166 : 43575838 : ix86_local_alignment (tree exp, machine_mode mode,
18167 : : unsigned int align, bool may_lower)
18168 : : {
18169 : 43575838 : tree type, decl;
18170 : :
18171 : 43575838 : if (exp && DECL_P (exp))
18172 : : {
18173 : 41845230 : type = TREE_TYPE (exp);
18174 : 41845230 : decl = exp;
18175 : : }
18176 : : else
18177 : : {
18178 : : type = exp;
18179 : : decl = NULL;
18180 : : }
18181 : :
18182 : : /* Don't do dynamic stack realignment for long long objects with
18183 : : -mpreferred-stack-boundary=2. */
18184 : 43575838 : if (may_lower
18185 : 28269563 : && !TARGET_64BIT
18186 : 239022 : && align == 64
18187 : 39209 : && ix86_preferred_stack_boundary < 64
18188 : 0 : && (mode == DImode || (type && TYPE_MODE (type) == DImode))
18189 : 0 : && (!type || (!TYPE_USER_ALIGN (type)
18190 : 0 : && !TYPE_ATOMIC (strip_array_types (type))))
18191 : 43575838 : && (!decl || !DECL_USER_ALIGN (decl)))
18192 : : align = 32;
18193 : :
18194 : : /* If TYPE is NULL, we are allocating a stack slot for caller-save
18195 : : register in MODE. We will return the largest alignment of XF
18196 : : and DF. */
18197 : 43575838 : if (!type)
18198 : : {
18199 : 1057351 : if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
18200 : 1502 : align = GET_MODE_ALIGNMENT (DFmode);
18201 : 1057351 : return align;
18202 : : }
18203 : :
18204 : : /* Don't increase alignment for Intel MCU psABI. */
18205 : 42518487 : if (TARGET_IAMCU)
18206 : : return align;
18207 : :
18208 : : /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
18209 : : to 16byte boundary. Exact wording is:
18210 : :
18211 : : An array uses the same alignment as its elements, except that a local or
18212 : : global array variable of length at least 16 bytes or
18213 : : a C99 variable-length array variable always has alignment of at least 16 bytes.
18214 : :
18215 : : This was added to allow use of aligned SSE instructions at arrays. This
18216 : : rule is meant for static storage (where compiler cannot do the analysis
18217 : : by itself). We follow it for automatic variables only when convenient.
18218 : : We fully control everything in the function compiled and functions from
18219 : : other unit cannot rely on the alignment.
18220 : :
18221 : : Exclude va_list type. It is the common case of local array where
18222 : : we cannot benefit from the alignment.
18223 : :
18224 : : TODO: Probably one should optimize for size only when var is not escaping. */
18225 : 39663523 : if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
18226 : 81886930 : && TARGET_SSE)
18227 : : {
18228 : 39329998 : if (AGGREGATE_TYPE_P (type)
18229 : 7706035 : && (va_list_type_node == NULL_TREE
18230 : 7706035 : || (TYPE_MAIN_VARIANT (type)
18231 : 7706035 : != TYPE_MAIN_VARIANT (va_list_type_node)))
18232 : 7609910 : && TYPE_SIZE (type)
18233 : 7609910 : && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
18234 : 40238232 : && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
18235 : 44999082 : && align < 128)
18236 : 4760850 : return 128;
18237 : : }
18238 : 37757637 : if (TREE_CODE (type) == ARRAY_TYPE)
18239 : : {
18240 : 735783 : if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
18241 : : return 64;
18242 : 735783 : if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
18243 : : return 128;
18244 : : }
18245 : 37021854 : else if (TREE_CODE (type) == COMPLEX_TYPE)
18246 : : {
18247 : 162369 : if (TYPE_MODE (type) == DCmode && align < 64)
18248 : : return 64;
18249 : 162369 : if ((TYPE_MODE (type) == XCmode
18250 : 162369 : || TYPE_MODE (type) == TCmode) && align < 128)
18251 : : return 128;
18252 : : }
18253 : 36859485 : else if (RECORD_OR_UNION_TYPE_P (type)
18254 : 36859485 : && TYPE_FIELDS (type))
18255 : : {
18256 : 4194518 : if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
18257 : : return 64;
18258 : 4191384 : if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
18259 : : return 128;
18260 : : }
18261 : 32664967 : else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
18262 : : || TREE_CODE (type) == INTEGER_TYPE)
18263 : : {
18264 : :
18265 : 27393119 : if (TYPE_MODE (type) == DFmode && align < 64)
18266 : : return 64;
18267 : 27393119 : if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
18268 : : return 128;
18269 : : }
18270 : : return align;
18271 : : }
18272 : :
18273 : : /* Compute the minimum required alignment for dynamic stack realignment
18274 : : purposes for a local variable, parameter or a stack slot. EXP is
18275 : : the data type or decl itself, MODE is its mode and ALIGN is the
18276 : : alignment that the object would ordinarily have. */
18277 : :
18278 : : unsigned int
18279 : 43846649 : ix86_minimum_alignment (tree exp, machine_mode mode,
18280 : : unsigned int align)
18281 : : {
18282 : 43846649 : tree type, decl;
18283 : :
18284 : 43846649 : if (exp && DECL_P (exp))
18285 : : {
18286 : 14381108 : type = TREE_TYPE (exp);
18287 : 14381108 : decl = exp;
18288 : : }
18289 : : else
18290 : : {
18291 : : type = exp;
18292 : : decl = NULL;
18293 : : }
18294 : :
18295 : 43846649 : if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
18296 : : return align;
18297 : :
18298 : : /* Don't do dynamic stack realignment for long long objects with
18299 : : -mpreferred-stack-boundary=2. */
18300 : 0 : if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
18301 : 0 : && (!type || (!TYPE_USER_ALIGN (type)
18302 : 0 : && !TYPE_ATOMIC (strip_array_types (type))))
18303 : 0 : && (!decl || !DECL_USER_ALIGN (decl)))
18304 : : {
18305 : 0 : gcc_checking_assert (!TARGET_STV);
18306 : : return 32;
18307 : : }
18308 : :
18309 : : return align;
18310 : : }
18311 : :
18312 : : /* Find a location for the static chain incoming to a nested function.
18313 : : This is a register, unless all free registers are used by arguments. */
18314 : :
18315 : : static rtx
18316 : 258372 : ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
18317 : : {
18318 : 258372 : unsigned regno;
18319 : :
18320 : 258372 : if (TARGET_64BIT)
18321 : : {
18322 : : /* We always use R10 in 64-bit mode. */
18323 : : regno = R10_REG;
18324 : : }
18325 : : else
18326 : : {
18327 : 88678 : const_tree fntype, fndecl;
18328 : 88678 : unsigned int ccvt;
18329 : :
18330 : : /* By default in 32-bit mode we use ECX to pass the static chain. */
18331 : 88678 : regno = CX_REG;
18332 : :
18333 : 88678 : if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
18334 : : {
18335 : 78782 : fntype = TREE_TYPE (fndecl_or_type);
18336 : 78782 : fndecl = fndecl_or_type;
18337 : : }
18338 : : else
18339 : : {
18340 : : fntype = fndecl_or_type;
18341 : : fndecl = NULL;
18342 : : }
18343 : :
18344 : 88678 : ccvt = ix86_get_callcvt (fntype);
18345 : 88678 : if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
18346 : : {
18347 : : /* Fastcall functions use ecx/edx for arguments, which leaves
18348 : : us with EAX for the static chain.
18349 : : Thiscall functions use ecx for arguments, which also
18350 : : leaves us with EAX for the static chain. */
18351 : : regno = AX_REG;
18352 : : }
18353 : 88678 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
18354 : : {
18355 : : /* Thiscall functions use ecx for arguments, which leaves
18356 : : us with EAX and EDX for the static chain.
18357 : : We are using for abi-compatibility EAX. */
18358 : : regno = AX_REG;
18359 : : }
18360 : 88678 : else if (ix86_function_regparm (fntype, fndecl) == 3)
18361 : : {
18362 : : /* For regparm 3, we have no free call-clobbered registers in
18363 : : which to store the static chain. In order to implement this,
18364 : : we have the trampoline push the static chain to the stack.
18365 : : However, we can't push a value below the return address when
18366 : : we call the nested function directly, so we have to use an
18367 : : alternate entry point. For this we use ESI, and have the
18368 : : alternate entry point push ESI, so that things appear the
18369 : : same once we're executing the nested function. */
18370 : 0 : if (incoming_p)
18371 : : {
18372 : 0 : if (fndecl == current_function_decl
18373 : 0 : && !ix86_static_chain_on_stack)
18374 : : {
18375 : 0 : gcc_assert (!reload_completed);
18376 : 0 : ix86_static_chain_on_stack = true;
18377 : : }
18378 : 0 : return gen_frame_mem (SImode,
18379 : 0 : plus_constant (Pmode,
18380 : 0 : arg_pointer_rtx, -8));
18381 : : }
18382 : : regno = SI_REG;
18383 : : }
18384 : : }
18385 : :
18386 : 258372 : return gen_rtx_REG (Pmode, regno);
18387 : : }
18388 : :
18389 : : /* Emit RTL insns to initialize the variable parts of a trampoline.
18390 : : FNDECL is the decl of the target address; M_TRAMP is a MEM for
18391 : : the trampoline, and CHAIN_VALUE is an RTX for the static chain
18392 : : to be passed to the target function. */
18393 : :
18394 : : static void
18395 : 269 : ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
18396 : : {
18397 : 269 : rtx mem, fnaddr;
18398 : 269 : int opcode;
18399 : 269 : int offset = 0;
18400 : 269 : bool need_endbr = (flag_cf_protection & CF_BRANCH);
18401 : :
18402 : 269 : fnaddr = XEXP (DECL_RTL (fndecl), 0);
18403 : :
18404 : 269 : if (TARGET_64BIT)
18405 : : {
18406 : 269 : int size;
18407 : :
18408 : 269 : if (need_endbr)
18409 : : {
18410 : : /* Insert ENDBR64. */
18411 : 1 : mem = adjust_address (m_tramp, SImode, offset);
18412 : 1 : emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
18413 : 1 : offset += 4;
18414 : : }
18415 : :
18416 : : /* Load the function address to r11. Try to load address using
18417 : : the shorter movl instead of movabs. We may want to support
18418 : : movq for kernel mode, but kernel does not use trampolines at
18419 : : the moment. FNADDR is a 32bit address and may not be in
18420 : : DImode when ptr_mode == SImode. Always use movl in this
18421 : : case. */
18422 : 269 : if (ptr_mode == SImode
18423 : 269 : || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
18424 : : {
18425 : 237 : fnaddr = copy_addr_to_reg (fnaddr);
18426 : :
18427 : 237 : mem = adjust_address (m_tramp, HImode, offset);
18428 : 237 : emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
18429 : :
18430 : 237 : mem = adjust_address (m_tramp, SImode, offset + 2);
18431 : 237 : emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
18432 : 237 : offset += 6;
18433 : : }
18434 : : else
18435 : : {
18436 : 32 : mem = adjust_address (m_tramp, HImode, offset);
18437 : 32 : emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
18438 : :
18439 : 32 : mem = adjust_address (m_tramp, DImode, offset + 2);
18440 : 32 : emit_move_insn (mem, fnaddr);
18441 : 32 : offset += 10;
18442 : : }
18443 : :
18444 : : /* Load static chain using movabs to r10. Use the shorter movl
18445 : : instead of movabs when ptr_mode == SImode. */
18446 : 269 : if (ptr_mode == SImode)
18447 : : {
18448 : : opcode = 0xba41;
18449 : : size = 6;
18450 : : }
18451 : : else
18452 : : {
18453 : 269 : opcode = 0xba49;
18454 : 269 : size = 10;
18455 : : }
18456 : :
18457 : 269 : mem = adjust_address (m_tramp, HImode, offset);
18458 : 269 : emit_move_insn (mem, gen_int_mode (opcode, HImode));
18459 : :
18460 : 269 : mem = adjust_address (m_tramp, ptr_mode, offset + 2);
18461 : 269 : emit_move_insn (mem, chain_value);
18462 : 269 : offset += size;
18463 : :
18464 : : /* Jump to r11; the last (unused) byte is a nop, only there to
18465 : : pad the write out to a single 32-bit store. */
18466 : 269 : mem = adjust_address (m_tramp, SImode, offset);
18467 : 269 : emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
18468 : 269 : offset += 4;
18469 : : }
18470 : : else
18471 : : {
18472 : 0 : rtx disp, chain;
18473 : :
18474 : : /* Depending on the static chain location, either load a register
18475 : : with a constant, or push the constant to the stack. All of the
18476 : : instructions are the same size. */
18477 : 0 : chain = ix86_static_chain (fndecl, true);
18478 : 0 : if (REG_P (chain))
18479 : : {
18480 : 0 : switch (REGNO (chain))
18481 : : {
18482 : : case AX_REG:
18483 : : opcode = 0xb8; break;
18484 : 0 : case CX_REG:
18485 : 0 : opcode = 0xb9; break;
18486 : 0 : default:
18487 : 0 : gcc_unreachable ();
18488 : : }
18489 : : }
18490 : : else
18491 : : opcode = 0x68;
18492 : :
18493 : 0 : if (need_endbr)
18494 : : {
18495 : : /* Insert ENDBR32. */
18496 : 0 : mem = adjust_address (m_tramp, SImode, offset);
18497 : 0 : emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
18498 : 0 : offset += 4;
18499 : : }
18500 : :
18501 : 0 : mem = adjust_address (m_tramp, QImode, offset);
18502 : 0 : emit_move_insn (mem, gen_int_mode (opcode, QImode));
18503 : :
18504 : 0 : mem = adjust_address (m_tramp, SImode, offset + 1);
18505 : 0 : emit_move_insn (mem, chain_value);
18506 : 0 : offset += 5;
18507 : :
18508 : 0 : mem = adjust_address (m_tramp, QImode, offset);
18509 : 0 : emit_move_insn (mem, gen_int_mode (0xe9, QImode));
18510 : :
18511 : 0 : mem = adjust_address (m_tramp, SImode, offset + 1);
18512 : :
18513 : : /* Compute offset from the end of the jmp to the target function.
18514 : : In the case in which the trampoline stores the static chain on
18515 : : the stack, we need to skip the first insn which pushes the
18516 : : (call-saved) register static chain; this push is 1 byte. */
18517 : 0 : offset += 5;
18518 : 0 : int skip = MEM_P (chain) ? 1 : 0;
18519 : : /* Skip ENDBR32 at the entry of the target function. */
18520 : 0 : if (need_endbr
18521 : 0 : && !cgraph_node::get (fndecl)->only_called_directly_p ())
18522 : 0 : skip += 4;
18523 : 0 : disp = expand_binop (SImode, sub_optab, fnaddr,
18524 : 0 : plus_constant (Pmode, XEXP (m_tramp, 0),
18525 : 0 : offset - skip),
18526 : : NULL_RTX, 1, OPTAB_DIRECT);
18527 : 0 : emit_move_insn (mem, disp);
18528 : : }
18529 : :
18530 : 269 : gcc_assert (offset <= TRAMPOLINE_SIZE);
18531 : :
18532 : : #ifdef HAVE_ENABLE_EXECUTE_STACK
18533 : : #ifdef CHECK_EXECUTE_STACK_ENABLED
18534 : : if (CHECK_EXECUTE_STACK_ENABLED)
18535 : : #endif
18536 : : emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
18537 : : LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
18538 : : #endif
18539 : 269 : }
18540 : :
18541 : : static bool
18542 : 49234076 : ix86_allocate_stack_slots_for_args (void)
18543 : : {
18544 : : /* Naked functions should not allocate stack slots for arguments. */
18545 : 49234076 : return !ix86_function_naked (current_function_decl);
18546 : : }
18547 : :
18548 : : static bool
18549 : 29449220 : ix86_warn_func_return (tree decl)
18550 : : {
18551 : : /* Naked functions are implemented entirely in assembly, including the
18552 : : return sequence, so suppress warnings about this. */
18553 : 29449220 : return !ix86_function_naked (decl);
18554 : : }
18555 : :
18556 : : /* Return the shift count of a vector by scalar shift builtin second argument
18557 : : ARG1. */
18558 : : static tree
18559 : 13594 : ix86_vector_shift_count (tree arg1)
18560 : : {
18561 : 13594 : if (tree_fits_uhwi_p (arg1))
18562 : : return arg1;
18563 : 8271 : else if (TREE_CODE (arg1) == VECTOR_CST && CHAR_BIT == 8)
18564 : : {
18565 : : /* The count argument is weird, passed in as various 128-bit
18566 : : (or 64-bit) vectors, the low 64 bits from it are the count. */
18567 : 162 : unsigned char buf[16];
18568 : 162 : int len = native_encode_expr (arg1, buf, 16);
18569 : 162 : if (len == 0)
18570 : 162 : return NULL_TREE;
18571 : 162 : tree t = native_interpret_expr (uint64_type_node, buf, len);
18572 : 162 : if (t && tree_fits_uhwi_p (t))
18573 : : return t;
18574 : : }
18575 : : return NULL_TREE;
18576 : : }
18577 : :
18578 : : /* Return true if arg_mask is all ones, ELEMS is elements number of
18579 : : corresponding vector. */
18580 : : static bool
18581 : 20949 : ix86_masked_all_ones (unsigned HOST_WIDE_INT elems, tree arg_mask)
18582 : : {
18583 : 20949 : if (TREE_CODE (arg_mask) != INTEGER_CST)
18584 : : return false;
18585 : :
18586 : 6332 : unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg_mask);
18587 : 6332 : if (elems == HOST_BITS_PER_WIDE_INT)
18588 : 33 : return mask == HOST_WIDE_INT_M1U;
18589 : 6299 : if ((mask | (HOST_WIDE_INT_M1U << elems)) != HOST_WIDE_INT_M1U)
18590 : 2233 : return false;
18591 : :
18592 : : return true;
18593 : : }
18594 : :
18595 : : static tree
18596 : 58781605 : ix86_fold_builtin (tree fndecl, int n_args,
18597 : : tree *args, bool ignore ATTRIBUTE_UNUSED)
18598 : : {
18599 : 58781605 : if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
18600 : : {
18601 : 58781605 : enum ix86_builtins fn_code
18602 : 58781605 : = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
18603 : 58781605 : enum rtx_code rcode;
18604 : 58781605 : bool is_vshift;
18605 : 58781605 : unsigned HOST_WIDE_INT mask;
18606 : :
18607 : 58781605 : switch (fn_code)
18608 : : {
18609 : 6374 : case IX86_BUILTIN_CPU_IS:
18610 : 6374 : case IX86_BUILTIN_CPU_SUPPORTS:
18611 : 6374 : gcc_assert (n_args == 1);
18612 : 6374 : return fold_builtin_cpu (fndecl, args);
18613 : :
18614 : 19699 : case IX86_BUILTIN_NANQ:
18615 : 19699 : case IX86_BUILTIN_NANSQ:
18616 : 19699 : {
18617 : 19699 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18618 : 19699 : const char *str = c_getstr (*args);
18619 : 19699 : int quiet = fn_code == IX86_BUILTIN_NANQ;
18620 : 19699 : REAL_VALUE_TYPE real;
18621 : :
18622 : 19699 : if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
18623 : 19699 : return build_real (type, real);
18624 : 0 : return NULL_TREE;
18625 : : }
18626 : :
18627 : 108 : case IX86_BUILTIN_INFQ:
18628 : 108 : case IX86_BUILTIN_HUGE_VALQ:
18629 : 108 : {
18630 : 108 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18631 : 108 : REAL_VALUE_TYPE inf;
18632 : 108 : real_inf (&inf);
18633 : 108 : return build_real (type, inf);
18634 : : }
18635 : :
18636 : 60157 : case IX86_BUILTIN_TZCNT16:
18637 : 60157 : case IX86_BUILTIN_CTZS:
18638 : 60157 : case IX86_BUILTIN_TZCNT32:
18639 : 60157 : case IX86_BUILTIN_TZCNT64:
18640 : 60157 : gcc_assert (n_args == 1);
18641 : 60157 : if (TREE_CODE (args[0]) == INTEGER_CST)
18642 : : {
18643 : 45 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18644 : 45 : tree arg = args[0];
18645 : 45 : if (fn_code == IX86_BUILTIN_TZCNT16
18646 : 45 : || fn_code == IX86_BUILTIN_CTZS)
18647 : 3 : arg = fold_convert (short_unsigned_type_node, arg);
18648 : 45 : if (integer_zerop (arg))
18649 : 6 : return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
18650 : : else
18651 : 39 : return fold_const_call (CFN_CTZ, type, arg);
18652 : : }
18653 : : break;
18654 : :
18655 : 50078 : case IX86_BUILTIN_LZCNT16:
18656 : 50078 : case IX86_BUILTIN_CLZS:
18657 : 50078 : case IX86_BUILTIN_LZCNT32:
18658 : 50078 : case IX86_BUILTIN_LZCNT64:
18659 : 50078 : gcc_assert (n_args == 1);
18660 : 50078 : if (TREE_CODE (args[0]) == INTEGER_CST)
18661 : : {
18662 : 54 : tree type = TREE_TYPE (TREE_TYPE (fndecl));
18663 : 54 : tree arg = args[0];
18664 : 54 : if (fn_code == IX86_BUILTIN_LZCNT16
18665 : 54 : || fn_code == IX86_BUILTIN_CLZS)
18666 : 18 : arg = fold_convert (short_unsigned_type_node, arg);
18667 : 54 : if (integer_zerop (arg))
18668 : 3 : return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
18669 : : else
18670 : 51 : return fold_const_call (CFN_CLZ, type, arg);
18671 : : }
18672 : : break;
18673 : :
18674 : 59133 : case IX86_BUILTIN_BEXTR32:
18675 : 59133 : case IX86_BUILTIN_BEXTR64:
18676 : 59133 : case IX86_BUILTIN_BEXTRI32:
18677 : 59133 : case IX86_BUILTIN_BEXTRI64:
18678 : 59133 : gcc_assert (n_args == 2);
18679 : 59133 : if (tree_fits_uhwi_p (args[1]))
18680 : : {
18681 : 144 : unsigned HOST_WIDE_INT res = 0;
18682 : 144 : unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
18683 : 144 : unsigned int start = tree_to_uhwi (args[1]);
18684 : 144 : unsigned int len = (start & 0xff00) >> 8;
18685 : 144 : start &= 0xff;
18686 : 144 : if (start >= prec || len == 0)
18687 : : res = 0;
18688 : 41 : else if (!tree_fits_uhwi_p (args[0]))
18689 : : break;
18690 : : else
18691 : 24 : res = tree_to_uhwi (args[0]) >> start;
18692 : 127 : if (len > prec)
18693 : : len = prec;
18694 : 127 : if (len < HOST_BITS_PER_WIDE_INT)
18695 : 118 : res &= (HOST_WIDE_INT_1U << len) - 1;
18696 : 127 : return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
18697 : : }
18698 : : break;
18699 : :
18700 : 20272 : case IX86_BUILTIN_BZHI32:
18701 : 20272 : case IX86_BUILTIN_BZHI64:
18702 : 20272 : gcc_assert (n_args == 2);
18703 : 20272 : if (tree_fits_uhwi_p (args[1]))
18704 : : {
18705 : 188 : unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
18706 : 188 : if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
18707 : : return args[0];
18708 : 188 : if (idx == 0)
18709 : 50 : return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
18710 : 138 : if (!tree_fits_uhwi_p (args[0]))
18711 : : break;
18712 : 12 : unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
18713 : 12 : res &= ~(HOST_WIDE_INT_M1U << idx);
18714 : 12 : return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
18715 : : }
18716 : : break;
18717 : :
18718 : 20032 : case IX86_BUILTIN_PDEP32:
18719 : 20032 : case IX86_BUILTIN_PDEP64:
18720 : 20032 : gcc_assert (n_args == 2);
18721 : 20032 : if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
18722 : : {
18723 : 46 : unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
18724 : 46 : unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
18725 : 46 : unsigned HOST_WIDE_INT res = 0;
18726 : 46 : unsigned HOST_WIDE_INT m, k = 1;
18727 : 2990 : for (m = 1; m; m <<= 1)
18728 : 2944 : if ((mask & m) != 0)
18729 : : {
18730 : 1440 : if ((src & k) != 0)
18731 : 789 : res |= m;
18732 : 1440 : k <<= 1;
18733 : : }
18734 : 46 : return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
18735 : : }
18736 : : break;
18737 : :
18738 : 20034 : case IX86_BUILTIN_PEXT32:
18739 : 20034 : case IX86_BUILTIN_PEXT64:
18740 : 20034 : gcc_assert (n_args == 2);
18741 : 20034 : if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
18742 : : {
18743 : 46 : unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
18744 : 46 : unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
18745 : 46 : unsigned HOST_WIDE_INT res = 0;
18746 : 46 : unsigned HOST_WIDE_INT m, k = 1;
18747 : 2990 : for (m = 1; m; m <<= 1)
18748 : 2944 : if ((mask & m) != 0)
18749 : : {
18750 : 2016 : if ((src & m) != 0)
18751 : 1063 : res |= k;
18752 : 2016 : k <<= 1;
18753 : : }
18754 : 46 : return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
18755 : : }
18756 : : break;
18757 : :
18758 : 78521 : case IX86_BUILTIN_MOVMSKPS:
18759 : 78521 : case IX86_BUILTIN_PMOVMSKB:
18760 : 78521 : case IX86_BUILTIN_MOVMSKPD:
18761 : 78521 : case IX86_BUILTIN_PMOVMSKB128:
18762 : 78521 : case IX86_BUILTIN_MOVMSKPD256:
18763 : 78521 : case IX86_BUILTIN_MOVMSKPS256:
18764 : 78521 : case IX86_BUILTIN_PMOVMSKB256:
18765 : 78521 : gcc_assert (n_args == 1);
18766 : 78521 : if (TREE_CODE (args[0]) == VECTOR_CST)
18767 : : {
18768 : : HOST_WIDE_INT res = 0;
18769 : 139 : for (unsigned i = 0; i < VECTOR_CST_NELTS (args[0]); ++i)
18770 : : {
18771 : 124 : tree e = VECTOR_CST_ELT (args[0], i);
18772 : 124 : if (TREE_CODE (e) == INTEGER_CST && !TREE_OVERFLOW (e))
18773 : : {
18774 : 80 : if (wi::neg_p (wi::to_wide (e)))
18775 : 31 : res |= HOST_WIDE_INT_1 << i;
18776 : : }
18777 : 44 : else if (TREE_CODE (e) == REAL_CST && !TREE_OVERFLOW (e))
18778 : : {
18779 : 44 : if (TREE_REAL_CST (e).sign)
18780 : 19 : res |= HOST_WIDE_INT_1 << i;
18781 : : }
18782 : : else
18783 : : return NULL_TREE;
18784 : : }
18785 : 15 : return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
18786 : : }
18787 : : break;
18788 : :
18789 : 636099 : case IX86_BUILTIN_PSLLD:
18790 : 636099 : case IX86_BUILTIN_PSLLD128:
18791 : 636099 : case IX86_BUILTIN_PSLLD128_MASK:
18792 : 636099 : case IX86_BUILTIN_PSLLD256:
18793 : 636099 : case IX86_BUILTIN_PSLLD256_MASK:
18794 : 636099 : case IX86_BUILTIN_PSLLD512:
18795 : 636099 : case IX86_BUILTIN_PSLLDI:
18796 : 636099 : case IX86_BUILTIN_PSLLDI128:
18797 : 636099 : case IX86_BUILTIN_PSLLDI128_MASK:
18798 : 636099 : case IX86_BUILTIN_PSLLDI256:
18799 : 636099 : case IX86_BUILTIN_PSLLDI256_MASK:
18800 : 636099 : case IX86_BUILTIN_PSLLDI512:
18801 : 636099 : case IX86_BUILTIN_PSLLQ:
18802 : 636099 : case IX86_BUILTIN_PSLLQ128:
18803 : 636099 : case IX86_BUILTIN_PSLLQ128_MASK:
18804 : 636099 : case IX86_BUILTIN_PSLLQ256:
18805 : 636099 : case IX86_BUILTIN_PSLLQ256_MASK:
18806 : 636099 : case IX86_BUILTIN_PSLLQ512:
18807 : 636099 : case IX86_BUILTIN_PSLLQI:
18808 : 636099 : case IX86_BUILTIN_PSLLQI128:
18809 : 636099 : case IX86_BUILTIN_PSLLQI128_MASK:
18810 : 636099 : case IX86_BUILTIN_PSLLQI256:
18811 : 636099 : case IX86_BUILTIN_PSLLQI256_MASK:
18812 : 636099 : case IX86_BUILTIN_PSLLQI512:
18813 : 636099 : case IX86_BUILTIN_PSLLW:
18814 : 636099 : case IX86_BUILTIN_PSLLW128:
18815 : 636099 : case IX86_BUILTIN_PSLLW128_MASK:
18816 : 636099 : case IX86_BUILTIN_PSLLW256:
18817 : 636099 : case IX86_BUILTIN_PSLLW256_MASK:
18818 : 636099 : case IX86_BUILTIN_PSLLW512_MASK:
18819 : 636099 : case IX86_BUILTIN_PSLLWI:
18820 : 636099 : case IX86_BUILTIN_PSLLWI128:
18821 : 636099 : case IX86_BUILTIN_PSLLWI128_MASK:
18822 : 636099 : case IX86_BUILTIN_PSLLWI256:
18823 : 636099 : case IX86_BUILTIN_PSLLWI256_MASK:
18824 : 636099 : case IX86_BUILTIN_PSLLWI512_MASK:
18825 : 636099 : rcode = ASHIFT;
18826 : 636099 : is_vshift = false;
18827 : 636099 : goto do_shift;
18828 : 582532 : case IX86_BUILTIN_PSRAD:
18829 : 582532 : case IX86_BUILTIN_PSRAD128:
18830 : 582532 : case IX86_BUILTIN_PSRAD128_MASK:
18831 : 582532 : case IX86_BUILTIN_PSRAD256:
18832 : 582532 : case IX86_BUILTIN_PSRAD256_MASK:
18833 : 582532 : case IX86_BUILTIN_PSRAD512:
18834 : 582532 : case IX86_BUILTIN_PSRADI:
18835 : 582532 : case IX86_BUILTIN_PSRADI128:
18836 : 582532 : case IX86_BUILTIN_PSRADI128_MASK:
18837 : 582532 : case IX86_BUILTIN_PSRADI256:
18838 : 582532 : case IX86_BUILTIN_PSRADI256_MASK:
18839 : 582532 : case IX86_BUILTIN_PSRADI512:
18840 : 582532 : case IX86_BUILTIN_PSRAQ128_MASK:
18841 : 582532 : case IX86_BUILTIN_PSRAQ256_MASK:
18842 : 582532 : case IX86_BUILTIN_PSRAQ512:
18843 : 582532 : case IX86_BUILTIN_PSRAQI128_MASK:
18844 : 582532 : case IX86_BUILTIN_PSRAQI256_MASK:
18845 : 582532 : case IX86_BUILTIN_PSRAQI512:
18846 : 582532 : case IX86_BUILTIN_PSRAW:
18847 : 582532 : case IX86_BUILTIN_PSRAW128:
18848 : 582532 : case IX86_BUILTIN_PSRAW128_MASK:
18849 : 582532 : case IX86_BUILTIN_PSRAW256:
18850 : 582532 : case IX86_BUILTIN_PSRAW256_MASK:
18851 : 582532 : case IX86_BUILTIN_PSRAW512:
18852 : 582532 : case IX86_BUILTIN_PSRAWI:
18853 : 582532 : case IX86_BUILTIN_PSRAWI128:
18854 : 582532 : case IX86_BUILTIN_PSRAWI128_MASK:
18855 : 582532 : case IX86_BUILTIN_PSRAWI256:
18856 : 582532 : case IX86_BUILTIN_PSRAWI256_MASK:
18857 : 582532 : case IX86_BUILTIN_PSRAWI512:
18858 : 582532 : rcode = ASHIFTRT;
18859 : 582532 : is_vshift = false;
18860 : 582532 : goto do_shift;
18861 : 613948 : case IX86_BUILTIN_PSRLD:
18862 : 613948 : case IX86_BUILTIN_PSRLD128:
18863 : 613948 : case IX86_BUILTIN_PSRLD128_MASK:
18864 : 613948 : case IX86_BUILTIN_PSRLD256:
18865 : 613948 : case IX86_BUILTIN_PSRLD256_MASK:
18866 : 613948 : case IX86_BUILTIN_PSRLD512:
18867 : 613948 : case IX86_BUILTIN_PSRLDI:
18868 : 613948 : case IX86_BUILTIN_PSRLDI128:
18869 : 613948 : case IX86_BUILTIN_PSRLDI128_MASK:
18870 : 613948 : case IX86_BUILTIN_PSRLDI256:
18871 : 613948 : case IX86_BUILTIN_PSRLDI256_MASK:
18872 : 613948 : case IX86_BUILTIN_PSRLDI512:
18873 : 613948 : case IX86_BUILTIN_PSRLQ:
18874 : 613948 : case IX86_BUILTIN_PSRLQ128:
18875 : 613948 : case IX86_BUILTIN_PSRLQ128_MASK:
18876 : 613948 : case IX86_BUILTIN_PSRLQ256:
18877 : 613948 : case IX86_BUILTIN_PSRLQ256_MASK:
18878 : 613948 : case IX86_BUILTIN_PSRLQ512:
18879 : 613948 : case IX86_BUILTIN_PSRLQI:
18880 : 613948 : case IX86_BUILTIN_PSRLQI128:
18881 : 613948 : case IX86_BUILTIN_PSRLQI128_MASK:
18882 : 613948 : case IX86_BUILTIN_PSRLQI256:
18883 : 613948 : case IX86_BUILTIN_PSRLQI256_MASK:
18884 : 613948 : case IX86_BUILTIN_PSRLQI512:
18885 : 613948 : case IX86_BUILTIN_PSRLW:
18886 : 613948 : case IX86_BUILTIN_PSRLW128:
18887 : 613948 : case IX86_BUILTIN_PSRLW128_MASK:
18888 : 613948 : case IX86_BUILTIN_PSRLW256:
18889 : 613948 : case IX86_BUILTIN_PSRLW256_MASK:
18890 : 613948 : case IX86_BUILTIN_PSRLW512:
18891 : 613948 : case IX86_BUILTIN_PSRLWI:
18892 : 613948 : case IX86_BUILTIN_PSRLWI128:
18893 : 613948 : case IX86_BUILTIN_PSRLWI128_MASK:
18894 : 613948 : case IX86_BUILTIN_PSRLWI256:
18895 : 613948 : case IX86_BUILTIN_PSRLWI256_MASK:
18896 : 613948 : case IX86_BUILTIN_PSRLWI512:
18897 : 613948 : rcode = LSHIFTRT;
18898 : 613948 : is_vshift = false;
18899 : 613948 : goto do_shift;
18900 : 266081 : case IX86_BUILTIN_PSLLVV16HI:
18901 : 266081 : case IX86_BUILTIN_PSLLVV16SI:
18902 : 266081 : case IX86_BUILTIN_PSLLVV2DI:
18903 : 266081 : case IX86_BUILTIN_PSLLVV2DI_MASK:
18904 : 266081 : case IX86_BUILTIN_PSLLVV32HI:
18905 : 266081 : case IX86_BUILTIN_PSLLVV4DI:
18906 : 266081 : case IX86_BUILTIN_PSLLVV4DI_MASK:
18907 : 266081 : case IX86_BUILTIN_PSLLVV4SI:
18908 : 266081 : case IX86_BUILTIN_PSLLVV4SI_MASK:
18909 : 266081 : case IX86_BUILTIN_PSLLVV8DI:
18910 : 266081 : case IX86_BUILTIN_PSLLVV8HI:
18911 : 266081 : case IX86_BUILTIN_PSLLVV8SI:
18912 : 266081 : case IX86_BUILTIN_PSLLVV8SI_MASK:
18913 : 266081 : rcode = ASHIFT;
18914 : 266081 : is_vshift = true;
18915 : 266081 : goto do_shift;
18916 : 265692 : case IX86_BUILTIN_PSRAVQ128:
18917 : 265692 : case IX86_BUILTIN_PSRAVQ256:
18918 : 265692 : case IX86_BUILTIN_PSRAVV16HI:
18919 : 265692 : case IX86_BUILTIN_PSRAVV16SI:
18920 : 265692 : case IX86_BUILTIN_PSRAVV32HI:
18921 : 265692 : case IX86_BUILTIN_PSRAVV4SI:
18922 : 265692 : case IX86_BUILTIN_PSRAVV4SI_MASK:
18923 : 265692 : case IX86_BUILTIN_PSRAVV8DI:
18924 : 265692 : case IX86_BUILTIN_PSRAVV8HI:
18925 : 265692 : case IX86_BUILTIN_PSRAVV8SI:
18926 : 265692 : case IX86_BUILTIN_PSRAVV8SI_MASK:
18927 : 265692 : rcode = ASHIFTRT;
18928 : 265692 : is_vshift = true;
18929 : 265692 : goto do_shift;
18930 : 266072 : case IX86_BUILTIN_PSRLVV16HI:
18931 : 266072 : case IX86_BUILTIN_PSRLVV16SI:
18932 : 266072 : case IX86_BUILTIN_PSRLVV2DI:
18933 : 266072 : case IX86_BUILTIN_PSRLVV2DI_MASK:
18934 : 266072 : case IX86_BUILTIN_PSRLVV32HI:
18935 : 266072 : case IX86_BUILTIN_PSRLVV4DI:
18936 : 266072 : case IX86_BUILTIN_PSRLVV4DI_MASK:
18937 : 266072 : case IX86_BUILTIN_PSRLVV4SI:
18938 : 266072 : case IX86_BUILTIN_PSRLVV4SI_MASK:
18939 : 266072 : case IX86_BUILTIN_PSRLVV8DI:
18940 : 266072 : case IX86_BUILTIN_PSRLVV8HI:
18941 : 266072 : case IX86_BUILTIN_PSRLVV8SI:
18942 : 266072 : case IX86_BUILTIN_PSRLVV8SI_MASK:
18943 : 266072 : rcode = LSHIFTRT;
18944 : 266072 : is_vshift = true;
18945 : 266072 : goto do_shift;
18946 : :
18947 : 2630424 : do_shift:
18948 : 2630424 : gcc_assert (n_args >= 2);
18949 : 2630424 : if (TREE_CODE (args[0]) != VECTOR_CST)
18950 : : break;
18951 : 912 : mask = HOST_WIDE_INT_M1U;
18952 : 912 : if (n_args > 2)
18953 : : {
18954 : : /* This is masked shift. */
18955 : 667 : if (!tree_fits_uhwi_p (args[n_args - 1])
18956 : 667 : || TREE_SIDE_EFFECTS (args[n_args - 2]))
18957 : : break;
18958 : 667 : mask = tree_to_uhwi (args[n_args - 1]);
18959 : 667 : unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
18960 : 667 : mask |= HOST_WIDE_INT_M1U << elems;
18961 : 667 : if (mask != HOST_WIDE_INT_M1U
18962 : 556 : && TREE_CODE (args[n_args - 2]) != VECTOR_CST)
18963 : : break;
18964 : 633 : if (mask == (HOST_WIDE_INT_M1U << elems))
18965 : : return args[n_args - 2];
18966 : : }
18967 : 875 : if (is_vshift && TREE_CODE (args[1]) != VECTOR_CST)
18968 : : break;
18969 : 178 : if (tree tem = (is_vshift ? integer_one_node
18970 : 875 : : ix86_vector_shift_count (args[1])))
18971 : : {
18972 : 554 : unsigned HOST_WIDE_INT count = tree_to_uhwi (tem);
18973 : 554 : unsigned HOST_WIDE_INT prec
18974 : 554 : = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (args[0])));
18975 : 554 : if (count == 0 && mask == HOST_WIDE_INT_M1U)
18976 : : return args[0];
18977 : 554 : if (count >= prec)
18978 : : {
18979 : 72 : if (rcode == ASHIFTRT)
18980 : 27 : count = prec - 1;
18981 : 45 : else if (mask == HOST_WIDE_INT_M1U)
18982 : 3 : return build_zero_cst (TREE_TYPE (args[0]));
18983 : : }
18984 : 551 : tree countt = NULL_TREE;
18985 : 551 : if (!is_vshift)
18986 : : {
18987 : 373 : if (count >= prec)
18988 : 42 : countt = integer_zero_node;
18989 : : else
18990 : 331 : countt = build_int_cst (integer_type_node, count);
18991 : : }
18992 : 551 : tree_vector_builder builder;
18993 : 551 : if (mask != HOST_WIDE_INT_M1U || is_vshift)
18994 : 392 : builder.new_vector (TREE_TYPE (args[0]),
18995 : 784 : TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0])),
18996 : : 1);
18997 : : else
18998 : 159 : builder.new_unary_operation (TREE_TYPE (args[0]), args[0],
18999 : : false);
19000 : 551 : unsigned int cnt = builder.encoded_nelts ();
19001 : 5959 : for (unsigned int i = 0; i < cnt; ++i)
19002 : : {
19003 : 5408 : tree elt = VECTOR_CST_ELT (args[0], i);
19004 : 5408 : if (TREE_CODE (elt) != INTEGER_CST || TREE_OVERFLOW (elt))
19005 : 0 : return NULL_TREE;
19006 : 5408 : tree type = TREE_TYPE (elt);
19007 : 5408 : if (rcode == LSHIFTRT)
19008 : 2036 : elt = fold_convert (unsigned_type_for (type), elt);
19009 : 5408 : if (is_vshift)
19010 : : {
19011 : 1846 : countt = VECTOR_CST_ELT (args[1], i);
19012 : 1846 : if (TREE_CODE (countt) != INTEGER_CST
19013 : 1846 : || TREE_OVERFLOW (countt))
19014 : : return NULL_TREE;
19015 : 1846 : if (wi::neg_p (wi::to_wide (countt))
19016 : 3610 : || wi::to_widest (countt) >= prec)
19017 : : {
19018 : 325 : if (rcode == ASHIFTRT)
19019 : 108 : countt = build_int_cst (TREE_TYPE (countt),
19020 : 108 : prec - 1);
19021 : : else
19022 : : {
19023 : 217 : elt = build_zero_cst (TREE_TYPE (elt));
19024 : 217 : countt = build_zero_cst (TREE_TYPE (countt));
19025 : : }
19026 : : }
19027 : : }
19028 : 3562 : else if (count >= prec)
19029 : 504 : elt = build_zero_cst (TREE_TYPE (elt));
19030 : 8942 : elt = const_binop (rcode == ASHIFT
19031 : : ? LSHIFT_EXPR : RSHIFT_EXPR,
19032 : 5408 : TREE_TYPE (elt), elt, countt);
19033 : 5408 : if (!elt || TREE_CODE (elt) != INTEGER_CST)
19034 : : return NULL_TREE;
19035 : 5408 : if (rcode == LSHIFTRT)
19036 : 2036 : elt = fold_convert (type, elt);
19037 : 5408 : if ((mask & (HOST_WIDE_INT_1U << i)) == 0)
19038 : : {
19039 : 1566 : elt = VECTOR_CST_ELT (args[n_args - 2], i);
19040 : 1566 : if (TREE_CODE (elt) != INTEGER_CST
19041 : 1566 : || TREE_OVERFLOW (elt))
19042 : : return NULL_TREE;
19043 : : }
19044 : 5408 : builder.quick_push (elt);
19045 : : }
19046 : 551 : return builder.build ();
19047 : 551 : }
19048 : : break;
19049 : :
19050 : : default:
19051 : : break;
19052 : : }
19053 : : }
19054 : :
19055 : : #ifdef SUBTARGET_FOLD_BUILTIN
19056 : : return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
19057 : : #endif
19058 : :
19059 : : return NULL_TREE;
19060 : : }
19061 : :
19062 : : /* Fold a MD builtin (use ix86_fold_builtin for folding into
19063 : : constant) in GIMPLE. */
19064 : :
19065 : : bool
19066 : 1034475 : ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
19067 : : {
19068 : 1034475 : gimple *stmt = gsi_stmt (*gsi), *g;
19069 : 1034475 : gimple_seq stmts = NULL;
19070 : 1034475 : tree fndecl = gimple_call_fndecl (stmt);
19071 : 1034475 : gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
19072 : 1034475 : int n_args = gimple_call_num_args (stmt);
19073 : 1034475 : enum ix86_builtins fn_code
19074 : 1034475 : = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
19075 : 1034475 : tree decl = NULL_TREE;
19076 : 1034475 : tree arg0, arg1, arg2;
19077 : 1034475 : enum rtx_code rcode;
19078 : 1034475 : enum tree_code tcode;
19079 : 1034475 : unsigned HOST_WIDE_INT count;
19080 : 1034475 : bool is_vshift;
19081 : 1034475 : unsigned HOST_WIDE_INT elems;
19082 : 1034475 : location_t loc;
19083 : :
19084 : : /* Don't fold when there's isa mismatch. */
19085 : 1034475 : if (!ix86_check_builtin_isa_match (fn_code, NULL, NULL))
19086 : : return false;
19087 : :
19088 : 1034364 : switch (fn_code)
19089 : : {
19090 : 284 : case IX86_BUILTIN_TZCNT32:
19091 : 284 : decl = builtin_decl_implicit (BUILT_IN_CTZ);
19092 : 284 : goto fold_tzcnt_lzcnt;
19093 : :
19094 : 237 : case IX86_BUILTIN_TZCNT64:
19095 : 237 : decl = builtin_decl_implicit (BUILT_IN_CTZLL);
19096 : 237 : goto fold_tzcnt_lzcnt;
19097 : :
19098 : 215 : case IX86_BUILTIN_LZCNT32:
19099 : 215 : decl = builtin_decl_implicit (BUILT_IN_CLZ);
19100 : 215 : goto fold_tzcnt_lzcnt;
19101 : :
19102 : 224 : case IX86_BUILTIN_LZCNT64:
19103 : 224 : decl = builtin_decl_implicit (BUILT_IN_CLZLL);
19104 : 224 : goto fold_tzcnt_lzcnt;
19105 : :
19106 : 960 : fold_tzcnt_lzcnt:
19107 : 960 : gcc_assert (n_args == 1);
19108 : 960 : arg0 = gimple_call_arg (stmt, 0);
19109 : 960 : if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
19110 : : {
19111 : 796 : int prec = TYPE_PRECISION (TREE_TYPE (arg0));
19112 : : /* If arg0 is provably non-zero, optimize into generic
19113 : : __builtin_c[tl]z{,ll} function the middle-end handles
19114 : : better. */
19115 : 796 : if (!expr_not_equal_to (arg0, wi::zero (prec)))
19116 : : return false;
19117 : :
19118 : 9 : loc = gimple_location (stmt);
19119 : 9 : g = gimple_build_call (decl, 1, arg0);
19120 : 9 : gimple_set_location (g, loc);
19121 : 9 : tree lhs = make_ssa_name (integer_type_node);
19122 : 9 : gimple_call_set_lhs (g, lhs);
19123 : 9 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
19124 : 9 : g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
19125 : 9 : gimple_set_location (g, loc);
19126 : 9 : gsi_replace (gsi, g, false);
19127 : 9 : return true;
19128 : : }
19129 : : break;
19130 : :
19131 : 491 : case IX86_BUILTIN_BZHI32:
19132 : 491 : case IX86_BUILTIN_BZHI64:
19133 : 491 : gcc_assert (n_args == 2);
19134 : 491 : arg1 = gimple_call_arg (stmt, 1);
19135 : 491 : if (tree_fits_uhwi_p (arg1) && gimple_call_lhs (stmt))
19136 : : {
19137 : 195 : unsigned int idx = tree_to_uhwi (arg1) & 0xff;
19138 : 195 : arg0 = gimple_call_arg (stmt, 0);
19139 : 195 : if (idx < TYPE_PRECISION (TREE_TYPE (arg0)))
19140 : : break;
19141 : 31 : loc = gimple_location (stmt);
19142 : 31 : g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
19143 : 31 : gimple_set_location (g, loc);
19144 : 31 : gsi_replace (gsi, g, false);
19145 : 31 : return true;
19146 : : }
19147 : : break;
19148 : :
19149 : 502 : case IX86_BUILTIN_PDEP32:
19150 : 502 : case IX86_BUILTIN_PDEP64:
19151 : 502 : case IX86_BUILTIN_PEXT32:
19152 : 502 : case IX86_BUILTIN_PEXT64:
19153 : 502 : gcc_assert (n_args == 2);
19154 : 502 : arg1 = gimple_call_arg (stmt, 1);
19155 : 502 : if (integer_all_onesp (arg1) && gimple_call_lhs (stmt))
19156 : : {
19157 : 4 : loc = gimple_location (stmt);
19158 : 4 : arg0 = gimple_call_arg (stmt, 0);
19159 : 4 : g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
19160 : 4 : gimple_set_location (g, loc);
19161 : 4 : gsi_replace (gsi, g, false);
19162 : 4 : return true;
19163 : : }
19164 : : break;
19165 : :
19166 : 145 : case IX86_BUILTIN_PBLENDVB256:
19167 : 145 : case IX86_BUILTIN_BLENDVPS256:
19168 : 145 : case IX86_BUILTIN_BLENDVPD256:
19169 : : /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
19170 : : to scalar operations and not combined back. */
19171 : 145 : if (!TARGET_AVX2)
19172 : : break;
19173 : :
19174 : : /* FALLTHRU. */
19175 : 112 : case IX86_BUILTIN_BLENDVPD:
19176 : : /* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
19177 : : w/o sse4.2, it's veclowered to scalar operations and
19178 : : not combined back. */
19179 : 112 : if (!TARGET_SSE4_2)
19180 : : break;
19181 : : /* FALLTHRU. */
19182 : 149 : case IX86_BUILTIN_PBLENDVB128:
19183 : 149 : case IX86_BUILTIN_BLENDVPS:
19184 : 149 : gcc_assert (n_args == 3);
19185 : 149 : arg0 = gimple_call_arg (stmt, 0);
19186 : 149 : arg1 = gimple_call_arg (stmt, 1);
19187 : 149 : arg2 = gimple_call_arg (stmt, 2);
19188 : 149 : if (gimple_call_lhs (stmt))
19189 : : {
19190 : 149 : loc = gimple_location (stmt);
19191 : 149 : tree type = TREE_TYPE (arg2);
19192 : 149 : if (VECTOR_FLOAT_TYPE_P (type))
19193 : : {
19194 : 71 : tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
19195 : 71 : ? intSI_type_node : intDI_type_node;
19196 : 71 : type = get_same_sized_vectype (itype, type);
19197 : : }
19198 : : else
19199 : 78 : type = signed_type_for (type);
19200 : 149 : arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
19201 : 149 : tree zero_vec = build_zero_cst (type);
19202 : 149 : tree cmp_type = truth_type_for (type);
19203 : 149 : tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
19204 : 149 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
19205 : 149 : g = gimple_build_assign (gimple_call_lhs (stmt),
19206 : : VEC_COND_EXPR, cmp,
19207 : : arg1, arg0);
19208 : 149 : gimple_set_location (g, loc);
19209 : 149 : gsi_replace (gsi, g, false);
19210 : : }
19211 : : else
19212 : 0 : gsi_replace (gsi, gimple_build_nop (), false);
19213 : : return true;
19214 : :
19215 : :
19216 : 16 : case IX86_BUILTIN_PCMPEQB128:
19217 : 16 : case IX86_BUILTIN_PCMPEQW128:
19218 : 16 : case IX86_BUILTIN_PCMPEQD128:
19219 : 16 : case IX86_BUILTIN_PCMPEQQ:
19220 : 16 : case IX86_BUILTIN_PCMPEQB256:
19221 : 16 : case IX86_BUILTIN_PCMPEQW256:
19222 : 16 : case IX86_BUILTIN_PCMPEQD256:
19223 : 16 : case IX86_BUILTIN_PCMPEQQ256:
19224 : 16 : tcode = EQ_EXPR;
19225 : 16 : goto do_cmp;
19226 : :
19227 : : case IX86_BUILTIN_PCMPGTB128:
19228 : : case IX86_BUILTIN_PCMPGTW128:
19229 : : case IX86_BUILTIN_PCMPGTD128:
19230 : : case IX86_BUILTIN_PCMPGTQ:
19231 : : case IX86_BUILTIN_PCMPGTB256:
19232 : : case IX86_BUILTIN_PCMPGTW256:
19233 : : case IX86_BUILTIN_PCMPGTD256:
19234 : : case IX86_BUILTIN_PCMPGTQ256:
19235 : : tcode = GT_EXPR;
19236 : :
19237 : 33 : do_cmp:
19238 : 33 : gcc_assert (n_args == 2);
19239 : 33 : arg0 = gimple_call_arg (stmt, 0);
19240 : 33 : arg1 = gimple_call_arg (stmt, 1);
19241 : 33 : if (gimple_call_lhs (stmt))
19242 : : {
19243 : 32 : loc = gimple_location (stmt);
19244 : 32 : tree type = TREE_TYPE (arg0);
19245 : 32 : tree zero_vec = build_zero_cst (type);
19246 : 32 : tree minus_one_vec = build_minus_one_cst (type);
19247 : 32 : tree cmp_type = truth_type_for (type);
19248 : 32 : tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1);
19249 : 32 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
19250 : 32 : g = gimple_build_assign (gimple_call_lhs (stmt),
19251 : : VEC_COND_EXPR, cmp,
19252 : : minus_one_vec, zero_vec);
19253 : 32 : gimple_set_location (g, loc);
19254 : 32 : gsi_replace (gsi, g, false);
19255 : : }
19256 : : else
19257 : 1 : gsi_replace (gsi, gimple_build_nop (), false);
19258 : : return true;
19259 : :
19260 : 8591 : case IX86_BUILTIN_PSLLD:
19261 : 8591 : case IX86_BUILTIN_PSLLD128:
19262 : 8591 : case IX86_BUILTIN_PSLLD128_MASK:
19263 : 8591 : case IX86_BUILTIN_PSLLD256:
19264 : 8591 : case IX86_BUILTIN_PSLLD256_MASK:
19265 : 8591 : case IX86_BUILTIN_PSLLD512:
19266 : 8591 : case IX86_BUILTIN_PSLLDI:
19267 : 8591 : case IX86_BUILTIN_PSLLDI128:
19268 : 8591 : case IX86_BUILTIN_PSLLDI128_MASK:
19269 : 8591 : case IX86_BUILTIN_PSLLDI256:
19270 : 8591 : case IX86_BUILTIN_PSLLDI256_MASK:
19271 : 8591 : case IX86_BUILTIN_PSLLDI512:
19272 : 8591 : case IX86_BUILTIN_PSLLQ:
19273 : 8591 : case IX86_BUILTIN_PSLLQ128:
19274 : 8591 : case IX86_BUILTIN_PSLLQ128_MASK:
19275 : 8591 : case IX86_BUILTIN_PSLLQ256:
19276 : 8591 : case IX86_BUILTIN_PSLLQ256_MASK:
19277 : 8591 : case IX86_BUILTIN_PSLLQ512:
19278 : 8591 : case IX86_BUILTIN_PSLLQI:
19279 : 8591 : case IX86_BUILTIN_PSLLQI128:
19280 : 8591 : case IX86_BUILTIN_PSLLQI128_MASK:
19281 : 8591 : case IX86_BUILTIN_PSLLQI256:
19282 : 8591 : case IX86_BUILTIN_PSLLQI256_MASK:
19283 : 8591 : case IX86_BUILTIN_PSLLQI512:
19284 : 8591 : case IX86_BUILTIN_PSLLW:
19285 : 8591 : case IX86_BUILTIN_PSLLW128:
19286 : 8591 : case IX86_BUILTIN_PSLLW128_MASK:
19287 : 8591 : case IX86_BUILTIN_PSLLW256:
19288 : 8591 : case IX86_BUILTIN_PSLLW256_MASK:
19289 : 8591 : case IX86_BUILTIN_PSLLW512_MASK:
19290 : 8591 : case IX86_BUILTIN_PSLLWI:
19291 : 8591 : case IX86_BUILTIN_PSLLWI128:
19292 : 8591 : case IX86_BUILTIN_PSLLWI128_MASK:
19293 : 8591 : case IX86_BUILTIN_PSLLWI256:
19294 : 8591 : case IX86_BUILTIN_PSLLWI256_MASK:
19295 : 8591 : case IX86_BUILTIN_PSLLWI512_MASK:
19296 : 8591 : rcode = ASHIFT;
19297 : 8591 : is_vshift = false;
19298 : 8591 : goto do_shift;
19299 : 6510 : case IX86_BUILTIN_PSRAD:
19300 : 6510 : case IX86_BUILTIN_PSRAD128:
19301 : 6510 : case IX86_BUILTIN_PSRAD128_MASK:
19302 : 6510 : case IX86_BUILTIN_PSRAD256:
19303 : 6510 : case IX86_BUILTIN_PSRAD256_MASK:
19304 : 6510 : case IX86_BUILTIN_PSRAD512:
19305 : 6510 : case IX86_BUILTIN_PSRADI:
19306 : 6510 : case IX86_BUILTIN_PSRADI128:
19307 : 6510 : case IX86_BUILTIN_PSRADI128_MASK:
19308 : 6510 : case IX86_BUILTIN_PSRADI256:
19309 : 6510 : case IX86_BUILTIN_PSRADI256_MASK:
19310 : 6510 : case IX86_BUILTIN_PSRADI512:
19311 : 6510 : case IX86_BUILTIN_PSRAQ128_MASK:
19312 : 6510 : case IX86_BUILTIN_PSRAQ256_MASK:
19313 : 6510 : case IX86_BUILTIN_PSRAQ512:
19314 : 6510 : case IX86_BUILTIN_PSRAQI128_MASK:
19315 : 6510 : case IX86_BUILTIN_PSRAQI256_MASK:
19316 : 6510 : case IX86_BUILTIN_PSRAQI512:
19317 : 6510 : case IX86_BUILTIN_PSRAW:
19318 : 6510 : case IX86_BUILTIN_PSRAW128:
19319 : 6510 : case IX86_BUILTIN_PSRAW128_MASK:
19320 : 6510 : case IX86_BUILTIN_PSRAW256:
19321 : 6510 : case IX86_BUILTIN_PSRAW256_MASK:
19322 : 6510 : case IX86_BUILTIN_PSRAW512:
19323 : 6510 : case IX86_BUILTIN_PSRAWI:
19324 : 6510 : case IX86_BUILTIN_PSRAWI128:
19325 : 6510 : case IX86_BUILTIN_PSRAWI128_MASK:
19326 : 6510 : case IX86_BUILTIN_PSRAWI256:
19327 : 6510 : case IX86_BUILTIN_PSRAWI256_MASK:
19328 : 6510 : case IX86_BUILTIN_PSRAWI512:
19329 : 6510 : rcode = ASHIFTRT;
19330 : 6510 : is_vshift = false;
19331 : 6510 : goto do_shift;
19332 : 7898 : case IX86_BUILTIN_PSRLD:
19333 : 7898 : case IX86_BUILTIN_PSRLD128:
19334 : 7898 : case IX86_BUILTIN_PSRLD128_MASK:
19335 : 7898 : case IX86_BUILTIN_PSRLD256:
19336 : 7898 : case IX86_BUILTIN_PSRLD256_MASK:
19337 : 7898 : case IX86_BUILTIN_PSRLD512:
19338 : 7898 : case IX86_BUILTIN_PSRLDI:
19339 : 7898 : case IX86_BUILTIN_PSRLDI128:
19340 : 7898 : case IX86_BUILTIN_PSRLDI128_MASK:
19341 : 7898 : case IX86_BUILTIN_PSRLDI256:
19342 : 7898 : case IX86_BUILTIN_PSRLDI256_MASK:
19343 : 7898 : case IX86_BUILTIN_PSRLDI512:
19344 : 7898 : case IX86_BUILTIN_PSRLQ:
19345 : 7898 : case IX86_BUILTIN_PSRLQ128:
19346 : 7898 : case IX86_BUILTIN_PSRLQ128_MASK:
19347 : 7898 : case IX86_BUILTIN_PSRLQ256:
19348 : 7898 : case IX86_BUILTIN_PSRLQ256_MASK:
19349 : 7898 : case IX86_BUILTIN_PSRLQ512:
19350 : 7898 : case IX86_BUILTIN_PSRLQI:
19351 : 7898 : case IX86_BUILTIN_PSRLQI128:
19352 : 7898 : case IX86_BUILTIN_PSRLQI128_MASK:
19353 : 7898 : case IX86_BUILTIN_PSRLQI256:
19354 : 7898 : case IX86_BUILTIN_PSRLQI256_MASK:
19355 : 7898 : case IX86_BUILTIN_PSRLQI512:
19356 : 7898 : case IX86_BUILTIN_PSRLW:
19357 : 7898 : case IX86_BUILTIN_PSRLW128:
19358 : 7898 : case IX86_BUILTIN_PSRLW128_MASK:
19359 : 7898 : case IX86_BUILTIN_PSRLW256:
19360 : 7898 : case IX86_BUILTIN_PSRLW256_MASK:
19361 : 7898 : case IX86_BUILTIN_PSRLW512:
19362 : 7898 : case IX86_BUILTIN_PSRLWI:
19363 : 7898 : case IX86_BUILTIN_PSRLWI128:
19364 : 7898 : case IX86_BUILTIN_PSRLWI128_MASK:
19365 : 7898 : case IX86_BUILTIN_PSRLWI256:
19366 : 7898 : case IX86_BUILTIN_PSRLWI256_MASK:
19367 : 7898 : case IX86_BUILTIN_PSRLWI512:
19368 : 7898 : rcode = LSHIFTRT;
19369 : 7898 : is_vshift = false;
19370 : 7898 : goto do_shift;
19371 : 2385 : case IX86_BUILTIN_PSLLVV16HI:
19372 : 2385 : case IX86_BUILTIN_PSLLVV16SI:
19373 : 2385 : case IX86_BUILTIN_PSLLVV2DI:
19374 : 2385 : case IX86_BUILTIN_PSLLVV2DI_MASK:
19375 : 2385 : case IX86_BUILTIN_PSLLVV32HI:
19376 : 2385 : case IX86_BUILTIN_PSLLVV4DI:
19377 : 2385 : case IX86_BUILTIN_PSLLVV4DI_MASK:
19378 : 2385 : case IX86_BUILTIN_PSLLVV4SI:
19379 : 2385 : case IX86_BUILTIN_PSLLVV4SI_MASK:
19380 : 2385 : case IX86_BUILTIN_PSLLVV8DI:
19381 : 2385 : case IX86_BUILTIN_PSLLVV8HI:
19382 : 2385 : case IX86_BUILTIN_PSLLVV8SI:
19383 : 2385 : case IX86_BUILTIN_PSLLVV8SI_MASK:
19384 : 2385 : rcode = ASHIFT;
19385 : 2385 : is_vshift = true;
19386 : 2385 : goto do_shift;
19387 : 2341 : case IX86_BUILTIN_PSRAVQ128:
19388 : 2341 : case IX86_BUILTIN_PSRAVQ256:
19389 : 2341 : case IX86_BUILTIN_PSRAVV16HI:
19390 : 2341 : case IX86_BUILTIN_PSRAVV16SI:
19391 : 2341 : case IX86_BUILTIN_PSRAVV32HI:
19392 : 2341 : case IX86_BUILTIN_PSRAVV4SI:
19393 : 2341 : case IX86_BUILTIN_PSRAVV4SI_MASK:
19394 : 2341 : case IX86_BUILTIN_PSRAVV8DI:
19395 : 2341 : case IX86_BUILTIN_PSRAVV8HI:
19396 : 2341 : case IX86_BUILTIN_PSRAVV8SI:
19397 : 2341 : case IX86_BUILTIN_PSRAVV8SI_MASK:
19398 : 2341 : rcode = ASHIFTRT;
19399 : 2341 : is_vshift = true;
19400 : 2341 : goto do_shift;
19401 : 2381 : case IX86_BUILTIN_PSRLVV16HI:
19402 : 2381 : case IX86_BUILTIN_PSRLVV16SI:
19403 : 2381 : case IX86_BUILTIN_PSRLVV2DI:
19404 : 2381 : case IX86_BUILTIN_PSRLVV2DI_MASK:
19405 : 2381 : case IX86_BUILTIN_PSRLVV32HI:
19406 : 2381 : case IX86_BUILTIN_PSRLVV4DI:
19407 : 2381 : case IX86_BUILTIN_PSRLVV4DI_MASK:
19408 : 2381 : case IX86_BUILTIN_PSRLVV4SI:
19409 : 2381 : case IX86_BUILTIN_PSRLVV4SI_MASK:
19410 : 2381 : case IX86_BUILTIN_PSRLVV8DI:
19411 : 2381 : case IX86_BUILTIN_PSRLVV8HI:
19412 : 2381 : case IX86_BUILTIN_PSRLVV8SI:
19413 : 2381 : case IX86_BUILTIN_PSRLVV8SI_MASK:
19414 : 2381 : rcode = LSHIFTRT;
19415 : 2381 : is_vshift = true;
19416 : 2381 : goto do_shift;
19417 : :
19418 : 30106 : do_shift:
19419 : 30106 : gcc_assert (n_args >= 2);
19420 : 30106 : if (!gimple_call_lhs (stmt))
19421 : : {
19422 : 1 : gsi_replace (gsi, gimple_build_nop (), false);
19423 : 1 : return true;
19424 : : }
19425 : 30105 : arg0 = gimple_call_arg (stmt, 0);
19426 : 30105 : arg1 = gimple_call_arg (stmt, 1);
19427 : 30105 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
19428 : : /* For masked shift, only optimize if the mask is all ones. */
19429 : 30105 : if (n_args > 2
19430 : 30105 : && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
19431 : : break;
19432 : 15539 : if (is_vshift)
19433 : : {
19434 : 2642 : if (TREE_CODE (arg1) != VECTOR_CST)
19435 : : break;
19436 : 69 : count = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0)));
19437 : 69 : if (integer_zerop (arg1))
19438 : 27 : count = 0;
19439 : 42 : else if (rcode == ASHIFTRT)
19440 : : break;
19441 : : else
19442 : 230 : for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg1); ++i)
19443 : : {
19444 : 212 : tree elt = VECTOR_CST_ELT (arg1, i);
19445 : 212 : if (!wi::neg_p (wi::to_wide (elt))
19446 : 375 : && wi::to_widest (elt) < count)
19447 : 16 : return false;
19448 : : }
19449 : : }
19450 : : else
19451 : : {
19452 : 12897 : arg1 = ix86_vector_shift_count (arg1);
19453 : 12897 : if (!arg1)
19454 : : break;
19455 : 5109 : count = tree_to_uhwi (arg1);
19456 : : }
19457 : 5154 : if (count == 0)
19458 : : {
19459 : : /* Just return the first argument for shift by 0. */
19460 : 93 : loc = gimple_location (stmt);
19461 : 93 : g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
19462 : 93 : gimple_set_location (g, loc);
19463 : 93 : gsi_replace (gsi, g, false);
19464 : 93 : return true;
19465 : : }
19466 : 5061 : if (rcode != ASHIFTRT
19467 : 5061 : && count >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0))))
19468 : : {
19469 : : /* For shift counts equal or greater than precision, except for
19470 : : arithmetic right shift the result is zero. */
19471 : 78 : loc = gimple_location (stmt);
19472 : 78 : g = gimple_build_assign (gimple_call_lhs (stmt),
19473 : 78 : build_zero_cst (TREE_TYPE (arg0)));
19474 : 78 : gimple_set_location (g, loc);
19475 : 78 : gsi_replace (gsi, g, false);
19476 : 78 : return true;
19477 : : }
19478 : : break;
19479 : :
19480 : 535 : case IX86_BUILTIN_SHUFPD512:
19481 : 535 : case IX86_BUILTIN_SHUFPS512:
19482 : 535 : case IX86_BUILTIN_SHUFPD:
19483 : 535 : case IX86_BUILTIN_SHUFPD256:
19484 : 535 : case IX86_BUILTIN_SHUFPS:
19485 : 535 : case IX86_BUILTIN_SHUFPS256:
19486 : 535 : arg0 = gimple_call_arg (stmt, 0);
19487 : 535 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
19488 : : /* This is masked shuffle. Only optimize if the mask is all ones. */
19489 : 535 : if (n_args > 3
19490 : 903 : && !ix86_masked_all_ones (elems,
19491 : 368 : gimple_call_arg (stmt, n_args - 1)))
19492 : : break;
19493 : 203 : arg2 = gimple_call_arg (stmt, 2);
19494 : 203 : if (TREE_CODE (arg2) == INTEGER_CST && gimple_call_lhs (stmt))
19495 : : {
19496 : 146 : unsigned HOST_WIDE_INT shuffle_mask = TREE_INT_CST_LOW (arg2);
19497 : : /* Check valid imm, refer to gcc.target/i386/testimm-10.c. */
19498 : 146 : if (shuffle_mask > 255)
19499 : : return false;
19500 : :
19501 : 144 : machine_mode imode = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (arg0)));
19502 : 144 : loc = gimple_location (stmt);
19503 : 288 : tree itype = (imode == E_DFmode
19504 : 144 : ? long_long_integer_type_node : integer_type_node);
19505 : 144 : tree vtype = build_vector_type (itype, elems);
19506 : 144 : tree_vector_builder elts (vtype, elems, 1);
19507 : :
19508 : :
19509 : : /* Transform integer shuffle_mask to vector perm_mask which
19510 : : is used by vec_perm_expr, refer to shuflp[sd]256/512 in sse.md. */
19511 : 840 : for (unsigned i = 0; i != elems; i++)
19512 : : {
19513 : 696 : unsigned sel_idx;
19514 : : /* Imm[1:0](if VL > 128, then use Imm[3:2],Imm[5:4],Imm[7:6])
19515 : : provide 2 select constrols for each element of the
19516 : : destination. */
19517 : 696 : if (imode == E_DFmode)
19518 : 240 : sel_idx = (i & 1) * elems + (i & ~1)
19519 : 240 : + ((shuffle_mask >> i) & 1);
19520 : : else
19521 : : {
19522 : : /* Imm[7:0](if VL > 128, also use Imm[7:0]) provide 4 select
19523 : : controls for each element of the destination. */
19524 : 456 : unsigned j = i % 4;
19525 : 456 : sel_idx = ((i >> 1) & 1) * elems + (i & ~3)
19526 : 456 : + ((shuffle_mask >> 2 * j) & 3);
19527 : : }
19528 : 696 : elts.quick_push (build_int_cst (itype, sel_idx));
19529 : : }
19530 : :
19531 : 144 : tree perm_mask = elts.build ();
19532 : 144 : arg1 = gimple_call_arg (stmt, 1);
19533 : 144 : g = gimple_build_assign (gimple_call_lhs (stmt),
19534 : : VEC_PERM_EXPR,
19535 : : arg0, arg1, perm_mask);
19536 : 144 : gimple_set_location (g, loc);
19537 : 144 : gsi_replace (gsi, g, false);
19538 : 144 : return true;
19539 : 144 : }
19540 : : // Do not error yet, the constant could be propagated later?
19541 : : break;
19542 : :
19543 : 48 : case IX86_BUILTIN_PABSB:
19544 : 48 : case IX86_BUILTIN_PABSW:
19545 : 48 : case IX86_BUILTIN_PABSD:
19546 : : /* 64-bit vector abs<mode>2 is only supported under TARGET_MMX_WITH_SSE. */
19547 : 48 : if (!TARGET_MMX_WITH_SSE)
19548 : : break;
19549 : : /* FALLTHRU. */
19550 : 2203 : case IX86_BUILTIN_PABSB128:
19551 : 2203 : case IX86_BUILTIN_PABSB256:
19552 : 2203 : case IX86_BUILTIN_PABSB512:
19553 : 2203 : case IX86_BUILTIN_PABSW128:
19554 : 2203 : case IX86_BUILTIN_PABSW256:
19555 : 2203 : case IX86_BUILTIN_PABSW512:
19556 : 2203 : case IX86_BUILTIN_PABSD128:
19557 : 2203 : case IX86_BUILTIN_PABSD256:
19558 : 2203 : case IX86_BUILTIN_PABSD512:
19559 : 2203 : case IX86_BUILTIN_PABSQ128:
19560 : 2203 : case IX86_BUILTIN_PABSQ256:
19561 : 2203 : case IX86_BUILTIN_PABSQ512:
19562 : 2203 : case IX86_BUILTIN_PABSB128_MASK:
19563 : 2203 : case IX86_BUILTIN_PABSB256_MASK:
19564 : 2203 : case IX86_BUILTIN_PABSW128_MASK:
19565 : 2203 : case IX86_BUILTIN_PABSW256_MASK:
19566 : 2203 : case IX86_BUILTIN_PABSD128_MASK:
19567 : 2203 : case IX86_BUILTIN_PABSD256_MASK:
19568 : 2203 : gcc_assert (n_args >= 1);
19569 : 2203 : if (!gimple_call_lhs (stmt))
19570 : : {
19571 : 1 : gsi_replace (gsi, gimple_build_nop (), false);
19572 : 1 : return true;
19573 : : }
19574 : 2202 : arg0 = gimple_call_arg (stmt, 0);
19575 : 2202 : elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
19576 : : /* For masked ABS, only optimize if the mask is all ones. */
19577 : 2202 : if (n_args > 1
19578 : 2202 : && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
19579 : : break;
19580 : 230 : {
19581 : 230 : tree utype, ures, vce;
19582 : 230 : utype = unsigned_type_for (TREE_TYPE (arg0));
19583 : : /* PABSB/W/D/Q store the unsigned result in dst, use ABSU_EXPR
19584 : : instead of ABS_EXPR to hanlde overflow case(TYPE_MIN). */
19585 : 230 : ures = gimple_build (&stmts, ABSU_EXPR, utype, arg0);
19586 : 230 : gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
19587 : 230 : loc = gimple_location (stmt);
19588 : 230 : vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg0), ures);
19589 : 230 : g = gimple_build_assign (gimple_call_lhs (stmt),
19590 : : VIEW_CONVERT_EXPR, vce);
19591 : 230 : gsi_replace (gsi, g, false);
19592 : : }
19593 : 230 : return true;
19594 : :
19595 : : default:
19596 : : break;
19597 : : }
19598 : :
19599 : : return false;
19600 : : }
19601 : :
19602 : : /* Handler for an SVML-style interface to
19603 : : a library with vectorized intrinsics. */
19604 : :
19605 : : tree
19606 : 11 : ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
19607 : : {
19608 : 11 : char name[20];
19609 : 11 : tree fntype, new_fndecl, args;
19610 : 11 : unsigned arity;
19611 : 11 : const char *bname;
19612 : 11 : machine_mode el_mode, in_mode;
19613 : 11 : int n, in_n;
19614 : :
19615 : : /* The SVML is suitable for unsafe math only. */
19616 : 11 : if (!flag_unsafe_math_optimizations)
19617 : : return NULL_TREE;
19618 : :
19619 : 11 : el_mode = TYPE_MODE (TREE_TYPE (type_out));
19620 : 11 : n = TYPE_VECTOR_SUBPARTS (type_out);
19621 : 11 : in_mode = TYPE_MODE (TREE_TYPE (type_in));
19622 : 11 : in_n = TYPE_VECTOR_SUBPARTS (type_in);
19623 : 11 : if (el_mode != in_mode
19624 : 11 : || n != in_n)
19625 : : return NULL_TREE;
19626 : :
19627 : 11 : switch (fn)
19628 : : {
19629 : 11 : CASE_CFN_EXP:
19630 : 11 : CASE_CFN_LOG:
19631 : 11 : CASE_CFN_LOG10:
19632 : 11 : CASE_CFN_POW:
19633 : 11 : CASE_CFN_TANH:
19634 : 11 : CASE_CFN_TAN:
19635 : 11 : CASE_CFN_ATAN:
19636 : 11 : CASE_CFN_ATAN2:
19637 : 11 : CASE_CFN_ATANH:
19638 : 11 : CASE_CFN_CBRT:
19639 : 11 : CASE_CFN_SINH:
19640 : 11 : CASE_CFN_SIN:
19641 : 11 : CASE_CFN_ASINH:
19642 : 11 : CASE_CFN_ASIN:
19643 : 11 : CASE_CFN_COSH:
19644 : 11 : CASE_CFN_COS:
19645 : 11 : CASE_CFN_ACOSH:
19646 : 11 : CASE_CFN_ACOS:
19647 : 11 : if ((el_mode != DFmode || n != 2)
19648 : 9 : && (el_mode != SFmode || n != 4))
19649 : : return NULL_TREE;
19650 : 6 : break;
19651 : :
19652 : : default:
19653 : : return NULL_TREE;
19654 : : }
19655 : :
19656 : 6 : tree fndecl = mathfn_built_in (el_mode == DFmode
19657 : : ? double_type_node : float_type_node, fn);
19658 : 6 : bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
19659 : :
19660 : 6 : if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
19661 : 2 : strcpy (name, "vmlsLn4");
19662 : 4 : else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
19663 : 0 : strcpy (name, "vmldLn2");
19664 : 4 : else if (n == 4)
19665 : : {
19666 : 2 : sprintf (name, "vmls%s", bname+10);
19667 : 2 : name[strlen (name)-1] = '4';
19668 : : }
19669 : : else
19670 : 2 : sprintf (name, "vmld%s2", bname+10);
19671 : :
19672 : : /* Convert to uppercase. */
19673 : 6 : name[4] &= ~0x20;
19674 : :
19675 : 6 : arity = 0;
19676 : 6 : for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
19677 : 0 : arity++;
19678 : :
19679 : 6 : if (arity == 1)
19680 : 0 : fntype = build_function_type_list (type_out, type_in, NULL);
19681 : : else
19682 : 6 : fntype = build_function_type_list (type_out, type_in, type_in, NULL);
19683 : :
19684 : : /* Build a function declaration for the vectorized function. */
19685 : 6 : new_fndecl = build_decl (BUILTINS_LOCATION,
19686 : : FUNCTION_DECL, get_identifier (name), fntype);
19687 : 6 : TREE_PUBLIC (new_fndecl) = 1;
19688 : 6 : DECL_EXTERNAL (new_fndecl) = 1;
19689 : 6 : DECL_IS_NOVOPS (new_fndecl) = 1;
19690 : 6 : TREE_READONLY (new_fndecl) = 1;
19691 : :
19692 : 6 : return new_fndecl;
19693 : : }
19694 : :
19695 : : /* Handler for an ACML-style interface to
19696 : : a library with vectorized intrinsics. */
19697 : :
19698 : : tree
19699 : 3 : ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
19700 : : {
19701 : 3 : char name[20] = "__vr.._";
19702 : 3 : tree fntype, new_fndecl, args;
19703 : 3 : unsigned arity;
19704 : 3 : const char *bname;
19705 : 3 : machine_mode el_mode, in_mode;
19706 : 3 : int n, in_n;
19707 : :
19708 : : /* The ACML is 64bits only and suitable for unsafe math only as
19709 : : it does not correctly support parts of IEEE with the required
19710 : : precision such as denormals. */
19711 : 3 : if (!TARGET_64BIT
19712 : 3 : || !flag_unsafe_math_optimizations)
19713 : : return NULL_TREE;
19714 : :
19715 : 3 : el_mode = TYPE_MODE (TREE_TYPE (type_out));
19716 : 3 : n = TYPE_VECTOR_SUBPARTS (type_out);
19717 : 3 : in_mode = TYPE_MODE (TREE_TYPE (type_in));
19718 : 3 : in_n = TYPE_VECTOR_SUBPARTS (type_in);
19719 : 3 : if (el_mode != in_mode
19720 : 3 : || n != in_n)
19721 : : return NULL_TREE;
19722 : :
19723 : 3 : switch (fn)
19724 : : {
19725 : 3 : CASE_CFN_SIN:
19726 : 3 : CASE_CFN_COS:
19727 : 3 : CASE_CFN_EXP:
19728 : 3 : CASE_CFN_LOG:
19729 : 3 : CASE_CFN_LOG2:
19730 : 3 : CASE_CFN_LOG10:
19731 : 3 : if (el_mode == DFmode && n == 2)
19732 : : {
19733 : 3 : name[4] = 'd';
19734 : 3 : name[5] = '2';
19735 : : }
19736 : 0 : else if (el_mode == SFmode && n == 4)
19737 : : {
19738 : 0 : name[4] = 's';
19739 : 0 : name[5] = '4';
19740 : : }
19741 : : else
19742 : : return NULL_TREE;
19743 : 3 : break;
19744 : :
19745 : : default:
19746 : : return NULL_TREE;
19747 : : }
19748 : :
19749 : 3 : tree fndecl = mathfn_built_in (el_mode == DFmode
19750 : : ? double_type_node : float_type_node, fn);
19751 : 3 : bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
19752 : 3 : sprintf (name + 7, "%s", bname+10);
19753 : :
19754 : 3 : arity = 0;
19755 : 3 : for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
19756 : 0 : arity++;
19757 : :
19758 : 3 : if (arity == 1)
19759 : 0 : fntype = build_function_type_list (type_out, type_in, NULL);
19760 : : else
19761 : 3 : fntype = build_function_type_list (type_out, type_in, type_in, NULL);
19762 : :
19763 : : /* Build a function declaration for the vectorized function. */
19764 : 3 : new_fndecl = build_decl (BUILTINS_LOCATION,
19765 : : FUNCTION_DECL, get_identifier (name), fntype);
19766 : 3 : TREE_PUBLIC (new_fndecl) = 1;
19767 : 3 : DECL_EXTERNAL (new_fndecl) = 1;
19768 : 3 : DECL_IS_NOVOPS (new_fndecl) = 1;
19769 : 3 : TREE_READONLY (new_fndecl) = 1;
19770 : :
19771 : 3 : return new_fndecl;
19772 : : }
19773 : :
19774 : : /* Returns a decl of a function that implements scatter store with
19775 : : register type VECTYPE and index type INDEX_TYPE and SCALE.
19776 : : Return NULL_TREE if it is not available. */
19777 : :
19778 : : static tree
19779 : 71050 : ix86_vectorize_builtin_scatter (const_tree vectype,
19780 : : const_tree index_type, int scale)
19781 : : {
19782 : 71050 : bool si;
19783 : 71050 : enum ix86_builtins code;
19784 : 71050 : const machine_mode mode = TYPE_MODE (TREE_TYPE (vectype));
19785 : :
19786 : 71050 : if (!TARGET_AVX512F)
19787 : : return NULL_TREE;
19788 : :
19789 : 2932 : if (!TARGET_EVEX512 && GET_MODE_SIZE (mode) == 64)
19790 : : return NULL_TREE;
19791 : :
19792 : 2932 : if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 2u)
19793 : 5343 : ? !TARGET_USE_SCATTER_2PARTS
19794 : 5343 : : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
19795 : 2411 : ? !TARGET_USE_SCATTER_4PARTS
19796 : 1681 : : !TARGET_USE_SCATTER_8PARTS))
19797 : : return NULL_TREE;
19798 : :
19799 : 2932 : if ((TREE_CODE (index_type) != INTEGER_TYPE
19800 : 335 : && !POINTER_TYPE_P (index_type))
19801 : 3267 : || (TYPE_MODE (index_type) != SImode
19802 : 1093 : && TYPE_MODE (index_type) != DImode))
19803 : 0 : return NULL_TREE;
19804 : :
19805 : 3064 : if (TYPE_PRECISION (index_type) > POINTER_SIZE)
19806 : : return NULL_TREE;
19807 : :
19808 : : /* v*scatter* insn sign extends index to pointer mode. */
19809 : 2932 : if (TYPE_PRECISION (index_type) < POINTER_SIZE
19810 : 2932 : && TYPE_UNSIGNED (index_type))
19811 : : return NULL_TREE;
19812 : :
19813 : : /* Scale can be 1, 2, 4 or 8. */
19814 : 2932 : if (scale <= 0
19815 : 2932 : || scale > 8
19816 : 2922 : || (scale & (scale - 1)) != 0)
19817 : : return NULL_TREE;
19818 : :
19819 : 2922 : si = TYPE_MODE (index_type) == SImode;
19820 : 2922 : switch (TYPE_MODE (vectype))
19821 : : {
19822 : 201 : case E_V8DFmode:
19823 : 201 : code = si ? IX86_BUILTIN_SCATTERALTSIV8DF : IX86_BUILTIN_SCATTERDIV8DF;
19824 : : break;
19825 : 131 : case E_V8DImode:
19826 : 131 : code = si ? IX86_BUILTIN_SCATTERALTSIV8DI : IX86_BUILTIN_SCATTERDIV8DI;
19827 : : break;
19828 : 202 : case E_V16SFmode:
19829 : 202 : code = si ? IX86_BUILTIN_SCATTERSIV16SF : IX86_BUILTIN_SCATTERALTDIV16SF;
19830 : : break;
19831 : 240 : case E_V16SImode:
19832 : 240 : code = si ? IX86_BUILTIN_SCATTERSIV16SI : IX86_BUILTIN_SCATTERALTDIV16SI;
19833 : : break;
19834 : 128 : case E_V4DFmode:
19835 : 128 : if (TARGET_AVX512VL)
19836 : 60 : code = si ? IX86_BUILTIN_SCATTERALTSIV4DF : IX86_BUILTIN_SCATTERDIV4DF;
19837 : : else
19838 : : return NULL_TREE;
19839 : : break;
19840 : 112 : case E_V4DImode:
19841 : 112 : if (TARGET_AVX512VL)
19842 : 60 : code = si ? IX86_BUILTIN_SCATTERALTSIV4DI : IX86_BUILTIN_SCATTERDIV4DI;
19843 : : else
19844 : : return NULL_TREE;
19845 : : break;
19846 : 126 : case E_V8SFmode:
19847 : 126 : if (TARGET_AVX512VL)
19848 : 66 : code = si ? IX86_BUILTIN_SCATTERSIV8SF : IX86_BUILTIN_SCATTERALTDIV8SF;
19849 : : else
19850 : : return NULL_TREE;
19851 : : break;
19852 : 242 : case E_V8SImode:
19853 : 242 : if (TARGET_AVX512VL)
19854 : 156 : code = si ? IX86_BUILTIN_SCATTERSIV8SI : IX86_BUILTIN_SCATTERALTDIV8SI;
19855 : : else
19856 : : return NULL_TREE;
19857 : : break;
19858 : 156 : case E_V2DFmode:
19859 : 156 : if (TARGET_AVX512VL)
19860 : 90 : code = si ? IX86_BUILTIN_SCATTERALTSIV2DF : IX86_BUILTIN_SCATTERDIV2DF;
19861 : : else
19862 : : return NULL_TREE;
19863 : : break;
19864 : 134 : case E_V2DImode:
19865 : 134 : if (TARGET_AVX512VL)
19866 : 88 : code = si ? IX86_BUILTIN_SCATTERALTSIV2DI : IX86_BUILTIN_SCATTERDIV2DI;
19867 : : else
19868 : : return NULL_TREE;
19869 : : break;
19870 : 152 : case E_V4SFmode:
19871 : 152 : if (TARGET_AVX512VL)
19872 : 96 : code = si ? IX86_BUILTIN_SCATTERSIV4SF : IX86_BUILTIN_SCATTERALTDIV4SF;
19873 : : else
19874 : : return NULL_TREE;
19875 : : break;
19876 : 234 : case E_V4SImode:
19877 : 234 : if (TARGET_AVX512VL)
19878 : 146 : code = si ? IX86_BUILTIN_SCATTERSIV4SI : IX86_BUILTIN_SCATTERALTDIV4SI;
19879 : : else
19880 : : return NULL_TREE;
19881 : : break;
19882 : : default:
19883 : : return NULL_TREE;
19884 : : }
19885 : :
19886 : 1536 : return get_ix86_builtin (code);
19887 : : }
19888 : :
19889 : : /* Return true if it is safe to use the rsqrt optabs to optimize
19890 : : 1.0/sqrt. */
19891 : :
19892 : : static bool
19893 : 86 : use_rsqrt_p (machine_mode mode)
19894 : : {
19895 : 86 : return ((mode == HFmode
19896 : 38 : || (TARGET_SSE && TARGET_SSE_MATH))
19897 : 86 : && flag_finite_math_only
19898 : 85 : && !flag_trapping_math
19899 : 153 : && flag_unsafe_math_optimizations);
19900 : : }
19901 : :
19902 : : /* Helper for avx_vpermilps256_operand et al. This is also used by
19903 : : the expansion functions to turn the parallel back into a mask.
19904 : : The return value is 0 for no match and the imm8+1 for a match. */
19905 : :
19906 : : int
19907 : 49953 : avx_vpermilp_parallel (rtx par, machine_mode mode)
19908 : : {
19909 : 49953 : unsigned i, nelt = GET_MODE_NUNITS (mode);
19910 : 49953 : unsigned mask = 0;
19911 : 49953 : unsigned char ipar[16] = {}; /* Silence -Wuninitialized warning. */
19912 : :
19913 : 49953 : if (XVECLEN (par, 0) != (int) nelt)
19914 : : return 0;
19915 : :
19916 : : /* Validate that all of the elements are constants, and not totally
19917 : : out of range. Copy the data into an integral array to make the
19918 : : subsequent checks easier. */
19919 : 297177 : for (i = 0; i < nelt; ++i)
19920 : : {
19921 : 247224 : rtx er = XVECEXP (par, 0, i);
19922 : 247224 : unsigned HOST_WIDE_INT ei;
19923 : :
19924 : 247224 : if (!CONST_INT_P (er))
19925 : : return 0;
19926 : 247224 : ei = INTVAL (er);
19927 : 247224 : if (ei >= nelt)
19928 : : return 0;
19929 : 247224 : ipar[i] = ei;
19930 : : }
19931 : :
19932 : 49953 : switch (mode)
19933 : : {
19934 : : case E_V8DFmode:
19935 : : /* In the 512-bit DFmode case, we can only move elements within
19936 : : a 128-bit lane. First fill the second part of the mask,
19937 : : then fallthru. */
19938 : 5600 : for (i = 4; i < 6; ++i)
19939 : : {
19940 : 3773 : if (ipar[i] < 4 || ipar[i] >= 6)
19941 : : return 0;
19942 : 3699 : mask |= (ipar[i] - 4) << i;
19943 : : }
19944 : 5139 : for (i = 6; i < 8; ++i)
19945 : : {
19946 : 3483 : if (ipar[i] < 6)
19947 : : return 0;
19948 : 3312 : mask |= (ipar[i] - 6) << i;
19949 : : }
19950 : : /* FALLTHRU */
19951 : :
19952 : : case E_V4DFmode:
19953 : : /* In the 256-bit DFmode case, we can only move elements within
19954 : : a 128-bit lane. */
19955 : 36350 : for (i = 0; i < 2; ++i)
19956 : : {
19957 : 25613 : if (ipar[i] >= 2)
19958 : : return 0;
19959 : 23453 : mask |= ipar[i] << i;
19960 : : }
19961 : 31239 : for (i = 2; i < 4; ++i)
19962 : : {
19963 : 20988 : if (ipar[i] < 2)
19964 : : return 0;
19965 : 20502 : mask |= (ipar[i] - 2) << i;
19966 : : }
19967 : : break;
19968 : :
19969 : : case E_V16SFmode:
19970 : : /* In 512 bit SFmode case, permutation in the upper 256 bits
19971 : : must mirror the permutation in the lower 256-bits. */
19972 : 14080 : for (i = 0; i < 8; ++i)
19973 : 12517 : if (ipar[i] + 8 != ipar[i + 8])
19974 : : return 0;
19975 : : /* FALLTHRU */
19976 : :
19977 : : case E_V8SFmode:
19978 : : /* In 256 bit SFmode case, we have full freedom of
19979 : : movement within the low 128-bit lane, but the high 128-bit
19980 : : lane must mirror the exact same pattern. */
19981 : 58292 : for (i = 0; i < 4; ++i)
19982 : 48295 : if (ipar[i] + 4 != ipar[i + 4])
19983 : : return 0;
19984 : : nelt = 4;
19985 : : /* FALLTHRU */
19986 : :
19987 : 32734 : case E_V2DFmode:
19988 : 32734 : case E_V4SFmode:
19989 : : /* In the 128-bit case, we've full freedom in the placement of
19990 : : the elements from the source operand. */
19991 : 134574 : for (i = 0; i < nelt; ++i)
19992 : 101840 : mask |= ipar[i] << (i * (nelt / 2));
19993 : : break;
19994 : :
19995 : 0 : default:
19996 : 0 : gcc_unreachable ();
19997 : : }
19998 : :
19999 : : /* Make sure success has a non-zero value by adding one. */
20000 : 42985 : return mask + 1;
20001 : : }
20002 : :
20003 : : /* Helper for avx_vperm2f128_v4df_operand et al. This is also used by
20004 : : the expansion functions to turn the parallel back into a mask.
20005 : : The return value is 0 for no match and the imm8+1 for a match. */
20006 : :
20007 : : int
20008 : 33392 : avx_vperm2f128_parallel (rtx par, machine_mode mode)
20009 : : {
20010 : 33392 : unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
20011 : 33392 : unsigned mask = 0;
20012 : 33392 : unsigned char ipar[8] = {}; /* Silence -Wuninitialized warning. */
20013 : :
20014 : 33392 : if (XVECLEN (par, 0) != (int) nelt)
20015 : : return 0;
20016 : :
20017 : : /* Validate that all of the elements are constants, and not totally
20018 : : out of range. Copy the data into an integral array to make the
20019 : : subsequent checks easier. */
20020 : 271004 : for (i = 0; i < nelt; ++i)
20021 : : {
20022 : 237612 : rtx er = XVECEXP (par, 0, i);
20023 : 237612 : unsigned HOST_WIDE_INT ei;
20024 : :
20025 : 237612 : if (!CONST_INT_P (er))
20026 : : return 0;
20027 : 237612 : ei = INTVAL (er);
20028 : 237612 : if (ei >= 2 * nelt)
20029 : : return 0;
20030 : 237612 : ipar[i] = ei;
20031 : : }
20032 : :
20033 : : /* Validate that the halves of the permute are halves. */
20034 : 53365 : for (i = 0; i < nelt2 - 1; ++i)
20035 : 46147 : if (ipar[i] + 1 != ipar[i + 1])
20036 : : return 0;
20037 : 20685 : for (i = nelt2; i < nelt - 1; ++i)
20038 : 14605 : if (ipar[i] + 1 != ipar[i + 1])
20039 : : return 0;
20040 : :
20041 : : /* Reconstruct the mask. */
20042 : 18198 : for (i = 0; i < 2; ++i)
20043 : : {
20044 : 12141 : unsigned e = ipar[i * nelt2];
20045 : 12141 : if (e % nelt2)
20046 : : return 0;
20047 : 12118 : e /= nelt2;
20048 : 12118 : mask |= e << (i * 4);
20049 : : }
20050 : :
20051 : : /* Make sure success has a non-zero value by adding one. */
20052 : 6057 : return mask + 1;
20053 : : }
20054 : :
20055 : : /* Return a mask of VPTERNLOG operands that do not affect output. */
20056 : :
20057 : : int
20058 : 492 : vpternlog_redundant_operand_mask (rtx pternlog_imm)
20059 : : {
20060 : 492 : int mask = 0;
20061 : 492 : int imm8 = INTVAL (pternlog_imm);
20062 : :
20063 : 492 : if (((imm8 >> 4) & 0x0F) == (imm8 & 0x0F))
20064 : 9 : mask |= 1;
20065 : 492 : if (((imm8 >> 2) & 0x33) == (imm8 & 0x33))
20066 : 33 : mask |= 2;
20067 : 492 : if (((imm8 >> 1) & 0x55) == (imm8 & 0x55))
20068 : 29 : mask |= 4;
20069 : :
20070 : 492 : return mask;
20071 : : }
20072 : :
20073 : : /* Eliminate false dependencies on operands that do not affect output
20074 : : by substituting other operands of a VPTERNLOG. */
20075 : :
20076 : : void
20077 : 19 : substitute_vpternlog_operands (rtx *operands)
20078 : : {
20079 : 19 : int mask = vpternlog_redundant_operand_mask (operands[4]);
20080 : :
20081 : 19 : if (mask & 1) /* The first operand is redundant. */
20082 : 3 : operands[1] = operands[2];
20083 : :
20084 : 19 : if (mask & 2) /* The second operand is redundant. */
20085 : 15 : operands[2] = operands[1];
20086 : :
20087 : 19 : if (mask & 4) /* The third operand is redundant. */
20088 : 14 : operands[3] = operands[1];
20089 : 5 : else if (REG_P (operands[3]))
20090 : : {
20091 : 1 : if (mask & 1)
20092 : 1 : operands[1] = operands[3];
20093 : 1 : if (mask & 2)
20094 : 1 : operands[2] = operands[3];
20095 : : }
20096 : 19 : }
20097 : :
20098 : : /* Return a register priority for hard reg REGNO. */
20099 : : static int
20100 : 45613263 : ix86_register_priority (int hard_regno)
20101 : : {
20102 : : /* ebp and r13 as the base always wants a displacement, r12 as the
20103 : : base always wants an index. So discourage their usage in an
20104 : : address. */
20105 : 45613263 : if (hard_regno == R12_REG || hard_regno == R13_REG)
20106 : : return 0;
20107 : 42690516 : if (hard_regno == BP_REG)
20108 : : return 1;
20109 : : /* New x86-64 int registers result in bigger code size. Discourage them. */
20110 : 41377520 : if (REX_INT_REGNO_P (hard_regno))
20111 : : return 2;
20112 : 29463574 : if (REX2_INT_REGNO_P (hard_regno))
20113 : : return 2;
20114 : : /* New x86-64 SSE registers result in bigger code size. Discourage them. */
20115 : 29461417 : if (REX_SSE_REGNO_P (hard_regno))
20116 : : return 2;
20117 : 24134151 : if (EXT_REX_SSE_REGNO_P (hard_regno))
20118 : : return 1;
20119 : : /* Usage of AX register results in smaller code. Prefer it. */
20120 : 23953915 : if (hard_regno == AX_REG)
20121 : 2981495 : return 4;
20122 : : return 3;
20123 : : }
20124 : :
20125 : : /* Implement TARGET_PREFERRED_RELOAD_CLASS.
20126 : :
20127 : : Put float CONST_DOUBLE in the constant pool instead of fp regs.
20128 : : QImode must go into class Q_REGS.
20129 : : Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
20130 : : movdf to do mem-to-mem moves through integer regs. */
20131 : :
20132 : : static reg_class_t
20133 : 466309011 : ix86_preferred_reload_class (rtx x, reg_class_t regclass)
20134 : : {
20135 : 466309011 : machine_mode mode = GET_MODE (x);
20136 : :
20137 : : /* We're only allowed to return a subclass of CLASS. Many of the
20138 : : following checks fail for NO_REGS, so eliminate that early. */
20139 : 466309011 : if (regclass == NO_REGS)
20140 : : return NO_REGS;
20141 : :
20142 : : /* All classes can load zeros. */
20143 : 465521524 : if (x == CONST0_RTX (mode))
20144 : : return regclass;
20145 : :
20146 : : /* Force constants into memory if we are loading a (nonzero) constant into
20147 : : an MMX, SSE or MASK register. This is because there are no MMX/SSE/MASK
20148 : : instructions to load from a constant. */
20149 : 442239859 : if (CONSTANT_P (x)
20150 : 442239859 : && (MAYBE_MMX_CLASS_P (regclass)
20151 : 117935389 : || MAYBE_SSE_CLASS_P (regclass)
20152 : 90582787 : || MAYBE_MASK_CLASS_P (regclass)))
20153 : 27477674 : return NO_REGS;
20154 : :
20155 : : /* Floating-point constants need more complex checks. */
20156 : 414762185 : if (CONST_DOUBLE_P (x))
20157 : : {
20158 : : /* General regs can load everything. */
20159 : 276529 : if (INTEGER_CLASS_P (regclass))
20160 : : return regclass;
20161 : :
20162 : : /* Floats can load 0 and 1 plus some others. Note that we eliminated
20163 : : zero above. We only want to wind up preferring 80387 registers if
20164 : : we plan on doing computation with them. */
20165 : 172958 : if (IS_STACK_MODE (mode)
20166 : 230675 : && standard_80387_constant_p (x) > 0)
20167 : : {
20168 : : /* Limit class to FP regs. */
20169 : 40489 : if (FLOAT_CLASS_P (regclass))
20170 : : return FLOAT_REGS;
20171 : : }
20172 : :
20173 : 132469 : return NO_REGS;
20174 : : }
20175 : :
20176 : : /* Prefer SSE if we can use them for math. Also allow integer regs
20177 : : when moves between register units are cheap. */
20178 : 414485656 : if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
20179 : : {
20180 : 30509660 : if (TARGET_INTER_UNIT_MOVES_FROM_VEC
20181 : 30494130 : && TARGET_INTER_UNIT_MOVES_TO_VEC
20182 : 91485814 : && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
20183 : 30352574 : return INT_SSE_CLASS_P (regclass) ? regclass : NO_REGS;
20184 : : else
20185 : 157086 : return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
20186 : : }
20187 : :
20188 : : /* Generally when we see PLUS here, it's the function invariant
20189 : : (plus soft-fp const_int). Which can only be computed into general
20190 : : regs. */
20191 : 383975996 : if (GET_CODE (x) == PLUS)
20192 : 708804 : return INTEGER_CLASS_P (regclass) ? regclass : NO_REGS;
20193 : :
20194 : : /* QImode constants are easy to load, but non-constant QImode data
20195 : : must go into Q_REGS or ALL_MASK_REGS. */
20196 : 383267192 : if (GET_MODE (x) == QImode && !CONSTANT_P (x))
20197 : : {
20198 : 21111602 : if (Q_CLASS_P (regclass))
20199 : : return regclass;
20200 : 16766381 : else if (reg_class_subset_p (Q_REGS, regclass))
20201 : : return Q_REGS;
20202 : 27457 : else if (MASK_CLASS_P (regclass))
20203 : : return regclass;
20204 : : else
20205 : : return NO_REGS;
20206 : : }
20207 : :
20208 : : return regclass;
20209 : : }
20210 : :
20211 : : /* Discourage putting floating-point values in SSE registers unless
20212 : : SSE math is being used, and likewise for the 387 registers. */
20213 : : static reg_class_t
20214 : 62945092 : ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
20215 : : {
20216 : : /* Restrict the output reload class to the register bank that we are doing
20217 : : math on. If we would like not to return a subset of CLASS, reject this
20218 : : alternative: if reload cannot do this, it will still use its choice. */
20219 : 62945092 : machine_mode mode = GET_MODE (x);
20220 : 62945092 : if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
20221 : 7041209 : return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
20222 : :
20223 : 55903883 : if (IS_STACK_MODE (mode))
20224 : 200793 : return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
20225 : :
20226 : : return regclass;
20227 : : }
20228 : :
20229 : : static reg_class_t
20230 : 338532039 : ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
20231 : : machine_mode mode, secondary_reload_info *sri)
20232 : : {
20233 : : /* Double-word spills from general registers to non-offsettable memory
20234 : : references (zero-extended addresses) require special handling. */
20235 : 338532039 : if (TARGET_64BIT
20236 : 290417130 : && MEM_P (x)
20237 : 162273047 : && GET_MODE_SIZE (mode) > UNITS_PER_WORD
20238 : 16437518 : && INTEGER_CLASS_P (rclass)
20239 : 341176736 : && !offsettable_memref_p (x))
20240 : : {
20241 : 2447112 : sri->icode = (in_p
20242 : 1223556 : ? CODE_FOR_reload_noff_load
20243 : : : CODE_FOR_reload_noff_store);
20244 : : /* Add the cost of moving address to a temporary. */
20245 : 1223556 : sri->extra_cost = 1;
20246 : :
20247 : 1223556 : return NO_REGS;
20248 : : }
20249 : :
20250 : : /* QImode spills from non-QI registers require
20251 : : intermediate register on 32bit targets. */
20252 : 337308483 : if (mode == QImode
20253 : 337308483 : && ((!TARGET_64BIT && !in_p
20254 : 544346 : && INTEGER_CLASS_P (rclass)
20255 : 544314 : && MAYBE_NON_Q_CLASS_P (rclass))
20256 : 20719521 : || (!TARGET_AVX512DQ
20257 : 20593620 : && MAYBE_MASK_CLASS_P (rclass))))
20258 : : {
20259 : 6629 : int regno = true_regnum (x);
20260 : :
20261 : : /* Return Q_REGS if the operand is in memory. */
20262 : 6629 : if (regno == -1)
20263 : : return Q_REGS;
20264 : :
20265 : : return NO_REGS;
20266 : : }
20267 : :
20268 : : /* Require movement to gpr, and then store to memory. */
20269 : 337301854 : if ((mode == HFmode || mode == HImode || mode == V2QImode
20270 : : || mode == BFmode)
20271 : 3272418 : && !TARGET_SSE4_1
20272 : 2738374 : && SSE_CLASS_P (rclass)
20273 : 177483 : && !in_p && MEM_P (x))
20274 : : {
20275 : 83140 : sri->extra_cost = 1;
20276 : 83140 : return GENERAL_REGS;
20277 : : }
20278 : :
20279 : : /* This condition handles corner case where an expression involving
20280 : : pointers gets vectorized. We're trying to use the address of a
20281 : : stack slot as a vector initializer.
20282 : :
20283 : : (set (reg:V2DI 74 [ vect_cst_.2 ])
20284 : : (vec_duplicate:V2DI (reg/f:DI 20 frame)))
20285 : :
20286 : : Eventually frame gets turned into sp+offset like this:
20287 : :
20288 : : (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20289 : : (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
20290 : : (const_int 392 [0x188]))))
20291 : :
20292 : : That later gets turned into:
20293 : :
20294 : : (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20295 : : (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
20296 : : (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
20297 : :
20298 : : We'll have the following reload recorded:
20299 : :
20300 : : Reload 0: reload_in (DI) =
20301 : : (plus:DI (reg/f:DI 7 sp)
20302 : : (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
20303 : : reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20304 : : SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
20305 : : reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
20306 : : reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
20307 : : reload_reg_rtx: (reg:V2DI 22 xmm1)
20308 : :
20309 : : Which isn't going to work since SSE instructions can't handle scalar
20310 : : additions. Returning GENERAL_REGS forces the addition into integer
20311 : : register and reload can handle subsequent reloads without problems. */
20312 : :
20313 : 192633258 : if (in_p && GET_CODE (x) == PLUS
20314 : 2 : && SSE_CLASS_P (rclass)
20315 : 337218714 : && SCALAR_INT_MODE_P (mode))
20316 : : return GENERAL_REGS;
20317 : :
20318 : : return NO_REGS;
20319 : : }
20320 : :
20321 : : /* Implement TARGET_CLASS_LIKELY_SPILLED_P. */
20322 : :
20323 : : static bool
20324 : 505672676 : ix86_class_likely_spilled_p (reg_class_t rclass)
20325 : : {
20326 : 497063320 : switch (rclass)
20327 : : {
20328 : : case AREG:
20329 : : case DREG:
20330 : : case CREG:
20331 : : case BREG:
20332 : : case AD_REGS:
20333 : : case SIREG:
20334 : : case DIREG:
20335 : : case SSE_FIRST_REG:
20336 : : case FP_TOP_REG:
20337 : : case FP_SECOND_REG:
20338 : : return true;
20339 : :
20340 : 477242138 : default:
20341 : 477242138 : break;
20342 : : }
20343 : :
20344 : 477242138 : return false;
20345 : : }
20346 : :
20347 : : /* Return true if a set of DST by the expression SRC should be allowed.
20348 : : This prevents complex sets of likely_spilled hard regs before reload. */
20349 : :
20350 : : bool
20351 : 391805826 : ix86_hardreg_mov_ok (rtx dst, rtx src)
20352 : : {
20353 : : /* Avoid complex sets of likely_spilled hard registers before reload. */
20354 : 325988544 : if (REG_P (dst) && HARD_REGISTER_P (dst)
20355 : 225302427 : && !REG_P (src) && !MEM_P (src)
20356 : 45280311 : && !(VECTOR_MODE_P (GET_MODE (dst))
20357 : 45280311 : ? standard_sse_constant_p (src, GET_MODE (dst))
20358 : 22425316 : : x86_64_immediate_operand (src, GET_MODE (dst)))
20359 : 8609356 : && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
20360 : 399264047 : && !reload_completed)
20361 : : return false;
20362 : : return true;
20363 : : }
20364 : :
20365 : : /* If we are copying between registers from different register sets
20366 : : (e.g. FP and integer), we may need a memory location.
20367 : :
20368 : : The function can't work reliably when one of the CLASSES is a class
20369 : : containing registers from multiple sets. We avoid this by never combining
20370 : : different sets in a single alternative in the machine description.
20371 : : Ensure that this constraint holds to avoid unexpected surprises.
20372 : :
20373 : : When STRICT is false, we are being called from REGISTER_MOVE_COST,
20374 : : so do not enforce these sanity checks.
20375 : :
20376 : : To optimize register_move_cost performance, define inline variant. */
20377 : :
20378 : : static inline bool
20379 : 5436407639 : inline_secondary_memory_needed (machine_mode mode, reg_class_t class1,
20380 : : reg_class_t class2, int strict)
20381 : : {
20382 : 5436407639 : if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
20383 : : return false;
20384 : :
20385 : 5407907016 : if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
20386 : 4607749030 : || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
20387 : 3934056680 : || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
20388 : 3753272770 : || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
20389 : 3582185506 : || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
20390 : 3582185506 : || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
20391 : 3582185506 : || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
20392 : 8827061552 : || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
20393 : : {
20394 : 2144102590 : gcc_assert (!strict || lra_in_progress);
20395 : : return true;
20396 : : }
20397 : :
20398 : 3263804426 : if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
20399 : : return true;
20400 : :
20401 : : /* ??? This is a lie. We do have moves between mmx/general, and for
20402 : : mmx/sse2. But by saying we need secondary memory we discourage the
20403 : : register allocator from using the mmx registers unless needed. */
20404 : 3120769793 : if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
20405 : : return true;
20406 : :
20407 : : /* Between mask and general, we have moves no larger than word size. */
20408 : 3029387618 : if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
20409 : : {
20410 : 2375800 : if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2))
20411 : 2994092 : || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
20412 : 206510 : return true;
20413 : : }
20414 : :
20415 : 3029181108 : if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
20416 : : {
20417 : : /* SSE1 doesn't have any direct moves from other classes. */
20418 : 658327933 : if (!TARGET_SSE2)
20419 : : return true;
20420 : :
20421 : 655884745 : if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)))
20422 : : return true;
20423 : :
20424 : 655884745 : int msize = GET_MODE_SIZE (mode);
20425 : :
20426 : : /* Between SSE and general, we have moves no larger than word size. */
20427 : 672006045 : if (msize > UNITS_PER_WORD)
20428 : : return true;
20429 : :
20430 : : /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
20431 : : Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16. */
20432 : 565366987 : int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
20433 : :
20434 : 565366987 : if (msize < minsize)
20435 : : return true;
20436 : :
20437 : : /* If the target says that inter-unit moves are more expensive
20438 : : than moving through memory, then don't generate them. */
20439 : 846254701 : if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC)
20440 : 845770285 : || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC))
20441 : 1292627 : return true;
20442 : : }
20443 : :
20444 : : return false;
20445 : : }
20446 : :
20447 : : /* Implement TARGET_SECONDARY_MEMORY_NEEDED. */
20448 : :
20449 : : static bool
20450 : 59849946 : ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1,
20451 : : reg_class_t class2)
20452 : : {
20453 : 59849946 : return inline_secondary_memory_needed (mode, class1, class2, true);
20454 : : }
20455 : :
20456 : : /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
20457 : :
20458 : : get_secondary_mem widens integral modes to BITS_PER_WORD.
20459 : : There is no need to emit full 64 bit move on 64 bit targets
20460 : : for integral modes that can be moved using 32 bit move. */
20461 : :
20462 : : static machine_mode
20463 : 12703 : ix86_secondary_memory_needed_mode (machine_mode mode)
20464 : : {
20465 : 25406 : if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
20466 : 8 : return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
20467 : : return mode;
20468 : : }
20469 : :
20470 : : /* Implement the TARGET_CLASS_MAX_NREGS hook.
20471 : :
20472 : : On the 80386, this is the size of MODE in words,
20473 : : except in the FP regs, where a single reg is always enough. */
20474 : :
20475 : : static unsigned char
20476 : 6016622750 : ix86_class_max_nregs (reg_class_t rclass, machine_mode mode)
20477 : : {
20478 : 6016622750 : if (MAYBE_INTEGER_CLASS_P (rclass))
20479 : : {
20480 : 4037557215 : if (mode == XFmode)
20481 : 140355029 : return (TARGET_64BIT ? 2 : 3);
20482 : 3897202186 : else if (mode == XCmode)
20483 : 140354676 : return (TARGET_64BIT ? 4 : 6);
20484 : : else
20485 : 7618930412 : return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
20486 : : }
20487 : : else
20488 : : {
20489 : 1979065535 : if (COMPLEX_MODE_P (mode))
20490 : : return 2;
20491 : : else
20492 : 1701770503 : return 1;
20493 : : }
20494 : : }
20495 : :
20496 : : /* Implement TARGET_CAN_CHANGE_MODE_CLASS. */
20497 : :
20498 : : static bool
20499 : 35937356 : ix86_can_change_mode_class (machine_mode from, machine_mode to,
20500 : : reg_class_t regclass)
20501 : : {
20502 : 35937356 : if (from == to)
20503 : : return true;
20504 : :
20505 : : /* x87 registers can't do subreg at all, as all values are reformatted
20506 : : to extended precision. */
20507 : 34424343 : if (MAYBE_FLOAT_CLASS_P (regclass))
20508 : : return false;
20509 : :
20510 : 30803695 : if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
20511 : : {
20512 : : /* Vector registers do not support QI or HImode loads. If we don't
20513 : : disallow a change to these modes, reload will assume it's ok to
20514 : : drop the subreg from (subreg:SI (reg:HI 100) 0). This affects
20515 : : the vec_dupv4hi pattern.
20516 : : NB: SSE2 can load 16bit data to sse register via pinsrw. */
20517 : 14470260 : int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
20518 : 14470260 : if (GET_MODE_SIZE (from) < mov_size
20519 : 28940449 : || GET_MODE_SIZE (to) < mov_size)
20520 : 2227100 : return false;
20521 : : }
20522 : :
20523 : : return true;
20524 : : }
20525 : :
20526 : : /* Return index of MODE in the sse load/store tables. */
20527 : :
20528 : : static inline int
20529 : 752055052 : sse_store_index (machine_mode mode)
20530 : : {
20531 : : /* NB: Use SFmode cost for HFmode instead of adding HFmode load/store
20532 : : costs to processor_costs, which requires changes to all entries in
20533 : : processor cost table. */
20534 : 752055052 : if (mode == E_HFmode)
20535 : 131408729 : mode = E_SFmode;
20536 : :
20537 : 1504110104 : switch (GET_MODE_SIZE (mode))
20538 : : {
20539 : : case 4:
20540 : : return 0;
20541 : 145644684 : case 8:
20542 : 145644684 : return 1;
20543 : 205415273 : case 16:
20544 : 205415273 : return 2;
20545 : 27904026 : case 32:
20546 : 27904026 : return 3;
20547 : 23269971 : case 64:
20548 : 23269971 : return 4;
20549 : 90586990 : default:
20550 : 90586990 : return -1;
20551 : : }
20552 : : }
20553 : :
20554 : : /* Return the cost of moving data of mode M between a
20555 : : register and memory. A value of 2 is the default; this cost is
20556 : : relative to those in `REGISTER_MOVE_COST'.
20557 : :
20558 : : This function is used extensively by register_move_cost that is used to
20559 : : build tables at startup. Make it inline in this case.
20560 : : When IN is 2, return maximum of in and out move cost.
20561 : :
20562 : : If moving between registers and memory is more expensive than
20563 : : between two registers, you should define this macro to express the
20564 : : relative cost.
20565 : :
20566 : : Model also increased moving costs of QImode registers in non
20567 : : Q_REGS classes.
20568 : : */
20569 : : static inline int
20570 : 6711149735 : inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
20571 : : {
20572 : 6711149735 : int cost;
20573 : :
20574 : 6711149735 : if (FLOAT_CLASS_P (regclass))
20575 : : {
20576 : 345863186 : int index;
20577 : 345863186 : switch (mode)
20578 : : {
20579 : : case E_SFmode:
20580 : : index = 0;
20581 : : break;
20582 : : case E_DFmode:
20583 : : index = 1;
20584 : : break;
20585 : : case E_XFmode:
20586 : : index = 2;
20587 : : break;
20588 : : default:
20589 : : return 100;
20590 : : }
20591 : 101148324 : if (in == 2)
20592 : 97371619 : return MAX (ix86_cost->hard_register.fp_load [index],
20593 : : ix86_cost->hard_register.fp_store [index]);
20594 : 3776705 : return in ? ix86_cost->hard_register.fp_load [index]
20595 : 3776705 : : ix86_cost->hard_register.fp_store [index];
20596 : : }
20597 : 6365286549 : if (SSE_CLASS_P (regclass))
20598 : : {
20599 : 629415986 : int index = sse_store_index (mode);
20600 : 629415986 : if (index == -1)
20601 : : return 100;
20602 : 539017178 : if (in == 2)
20603 : 382476369 : return MAX (ix86_cost->hard_register.sse_load [index],
20604 : : ix86_cost->hard_register.sse_store [index]);
20605 : 156540809 : return in ? ix86_cost->hard_register.sse_load [index]
20606 : 156540809 : : ix86_cost->hard_register.sse_store [index];
20607 : : }
20608 : 5735870563 : if (MASK_CLASS_P (regclass))
20609 : : {
20610 : 108741512 : int index;
20611 : 217483024 : switch (GET_MODE_SIZE (mode))
20612 : : {
20613 : : case 1:
20614 : : index = 0;
20615 : : break;
20616 : 8561702 : case 2:
20617 : 8561702 : index = 1;
20618 : 8561702 : break;
20619 : : /* DImode loads and stores assumed to cost the same as SImode. */
20620 : 38496026 : case 4:
20621 : 38496026 : case 8:
20622 : 38496026 : index = 2;
20623 : 38496026 : break;
20624 : : default:
20625 : : return 100;
20626 : : }
20627 : :
20628 : 50486392 : if (in == 2)
20629 : 553397 : return MAX (ix86_cost->hard_register.mask_load[index],
20630 : : ix86_cost->hard_register.mask_store[index]);
20631 : 49932995 : return in ? ix86_cost->hard_register.mask_load[2]
20632 : 49932995 : : ix86_cost->hard_register.mask_store[2];
20633 : : }
20634 : 5627129051 : if (MMX_CLASS_P (regclass))
20635 : : {
20636 : 167707515 : int index;
20637 : 335415030 : switch (GET_MODE_SIZE (mode))
20638 : : {
20639 : : case 4:
20640 : : index = 0;
20641 : : break;
20642 : 96961239 : case 8:
20643 : 96961239 : index = 1;
20644 : 96961239 : break;
20645 : : default:
20646 : : return 100;
20647 : : }
20648 : 132754443 : if (in == 2)
20649 : 113613453 : return MAX (ix86_cost->hard_register.mmx_load [index],
20650 : : ix86_cost->hard_register.mmx_store [index]);
20651 : 19140990 : return in ? ix86_cost->hard_register.mmx_load [index]
20652 : 19140990 : : ix86_cost->hard_register.mmx_store [index];
20653 : : }
20654 : 10918843072 : switch (GET_MODE_SIZE (mode))
20655 : : {
20656 : 119544945 : case 1:
20657 : 119544945 : if (Q_CLASS_P (regclass) || TARGET_64BIT)
20658 : : {
20659 : 117013061 : if (!in)
20660 : 18771592 : return ix86_cost->hard_register.int_store[0];
20661 : 98241469 : if (TARGET_PARTIAL_REG_DEPENDENCY
20662 : 98241469 : && optimize_function_for_speed_p (cfun))
20663 : 91786074 : cost = ix86_cost->hard_register.movzbl_load;
20664 : : else
20665 : 6455395 : cost = ix86_cost->hard_register.int_load[0];
20666 : 98241469 : if (in == 2)
20667 : 79447800 : return MAX (cost, ix86_cost->hard_register.int_store[0]);
20668 : : return cost;
20669 : : }
20670 : : else
20671 : : {
20672 : 2531884 : if (in == 2)
20673 : 1793060 : return MAX (ix86_cost->hard_register.movzbl_load,
20674 : : ix86_cost->hard_register.int_store[0] + 4);
20675 : 738824 : if (in)
20676 : 369448 : return ix86_cost->hard_register.movzbl_load;
20677 : : else
20678 : 369376 : return ix86_cost->hard_register.int_store[0] + 4;
20679 : : }
20680 : 616918800 : break;
20681 : 616918800 : case 2:
20682 : 616918800 : {
20683 : 616918800 : int cost;
20684 : 616918800 : if (in == 2)
20685 : 521191627 : cost = MAX (ix86_cost->hard_register.int_load[1],
20686 : : ix86_cost->hard_register.int_store[1]);
20687 : : else
20688 : 95727173 : cost = in ? ix86_cost->hard_register.int_load[1]
20689 : : : ix86_cost->hard_register.int_store[1];
20690 : :
20691 : 616918800 : if (mode == E_HFmode)
20692 : : {
20693 : : /* Prefer SSE over GPR for HFmode. */
20694 : 119589224 : int sse_cost;
20695 : 119589224 : int index = sse_store_index (mode);
20696 : 119589224 : if (in == 2)
20697 : 110018704 : sse_cost = MAX (ix86_cost->hard_register.sse_load[index],
20698 : : ix86_cost->hard_register.sse_store[index]);
20699 : : else
20700 : 9570520 : sse_cost = (in
20701 : 9570520 : ? ix86_cost->hard_register.sse_load [index]
20702 : : : ix86_cost->hard_register.sse_store [index]);
20703 : 119589224 : if (sse_cost >= cost)
20704 : 119589224 : cost = sse_cost + 1;
20705 : : }
20706 : : return cost;
20707 : : }
20708 : 4722957791 : default:
20709 : 4722957791 : if (in == 2)
20710 : 3612457606 : cost = MAX (ix86_cost->hard_register.int_load[2],
20711 : : ix86_cost->hard_register.int_store[2]);
20712 : 1110500185 : else if (in)
20713 : 555412113 : cost = ix86_cost->hard_register.int_load[2];
20714 : : else
20715 : 555088072 : cost = ix86_cost->hard_register.int_store[2];
20716 : : /* Multiply with the number of GPR moves needed. */
20717 : 9562005254 : return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
20718 : : }
20719 : : }
20720 : :
20721 : : static int
20722 : 1785675697 : ix86_memory_move_cost (machine_mode mode, reg_class_t regclass, bool in)
20723 : : {
20724 : 2678227357 : return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
20725 : : }
20726 : :
20727 : :
20728 : : /* Return the cost of moving data from a register in class CLASS1 to
20729 : : one in class CLASS2.
20730 : :
20731 : : It is not required that the cost always equal 2 when FROM is the same as TO;
20732 : : on some machines it is expensive to move between registers if they are not
20733 : : general registers. */
20734 : :
20735 : : static int
20736 : 5376557693 : ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
20737 : : reg_class_t class2_i)
20738 : : {
20739 : 5376557693 : enum reg_class class1 = (enum reg_class) class1_i;
20740 : 5376557693 : enum reg_class class2 = (enum reg_class) class2_i;
20741 : :
20742 : : /* In case we require secondary memory, compute cost of the store followed
20743 : : by load. In order to avoid bad register allocation choices, we need
20744 : : for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */
20745 : :
20746 : 5376557693 : if (inline_secondary_memory_needed (mode, class1, class2, false))
20747 : : {
20748 : 2462737019 : int cost = 1;
20749 : :
20750 : 2462737019 : cost += inline_memory_move_cost (mode, class1, 2);
20751 : 2462737019 : cost += inline_memory_move_cost (mode, class2, 2);
20752 : :
20753 : : /* In case of copying from general_purpose_register we may emit multiple
20754 : : stores followed by single load causing memory size mismatch stall.
20755 : : Count this as arbitrarily high cost of 20. */
20756 : 4925474038 : if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD
20757 : 738429215 : && TARGET_MEMORY_MISMATCH_STALL
20758 : 3939595449 : && targetm.class_max_nregs (class1, mode)
20759 : 738429215 : > targetm.class_max_nregs (class2, mode))
20760 : 140978549 : cost += 20;
20761 : :
20762 : : /* In the case of FP/MMX moves, the registers actually overlap, and we
20763 : : have to switch modes in order to treat them differently. */
20764 : 56806763 : if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
20765 : 2510597460 : || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
20766 : 17892644 : cost += 20;
20767 : :
20768 : 2462737019 : return cost;
20769 : : }
20770 : :
20771 : : /* Moves between MMX and non-MMX units require secondary memory. */
20772 : 2913820674 : if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
20773 : 0 : gcc_unreachable ();
20774 : :
20775 : 2913820674 : if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
20776 : 556266003 : return (SSE_CLASS_P (class1)
20777 : 556266003 : ? ix86_cost->hard_register.sse_to_integer
20778 : : : ix86_cost->hard_register.integer_to_sse);
20779 : :
20780 : : /* Moves between mask register and GPR. */
20781 : 2357554671 : if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
20782 : : {
20783 : 979584 : return (MASK_CLASS_P (class1)
20784 : 979584 : ? ix86_cost->hard_register.mask_to_integer
20785 : : : ix86_cost->hard_register.integer_to_mask);
20786 : : }
20787 : : /* Moving between mask registers. */
20788 : 2356575087 : if (MASK_CLASS_P (class1) && MASK_CLASS_P (class2))
20789 : 96705 : return ix86_cost->hard_register.mask_move;
20790 : :
20791 : 2356478382 : if (MAYBE_FLOAT_CLASS_P (class1))
20792 : 11313471 : return ix86_cost->hard_register.fp_move;
20793 : 2345164911 : if (MAYBE_SSE_CLASS_P (class1))
20794 : : {
20795 : 220054876 : if (GET_MODE_BITSIZE (mode) <= 128)
20796 : 107666816 : return ix86_cost->hard_register.xmm_move;
20797 : 4721244 : if (GET_MODE_BITSIZE (mode) <= 256)
20798 : 1508899 : return ix86_cost->hard_register.ymm_move;
20799 : 851723 : return ix86_cost->hard_register.zmm_move;
20800 : : }
20801 : 2235137473 : if (MAYBE_MMX_CLASS_P (class1))
20802 : 2080543 : return ix86_cost->hard_register.mmx_move;
20803 : : return 2;
20804 : : }
20805 : :
20806 : : /* Implement TARGET_HARD_REGNO_NREGS. This is ordinarily the length in
20807 : : words of a value of mode MODE but can be less for certain modes in
20808 : : special long registers.
20809 : :
20810 : : Actually there are no two word move instructions for consecutive
20811 : : registers. And only registers 0-3 may have mov byte instructions
20812 : : applied to them. */
20813 : :
20814 : : static unsigned int
20815 : 9251119800 : ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
20816 : : {
20817 : 9251119800 : if (GENERAL_REGNO_P (regno))
20818 : : {
20819 : 3217780800 : if (mode == XFmode)
20820 : 25226944 : return TARGET_64BIT ? 2 : 3;
20821 : 3193028640 : if (mode == XCmode)
20822 : 25226944 : return TARGET_64BIT ? 4 : 6;
20823 : 6397325312 : return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
20824 : : }
20825 : 6033339000 : if (COMPLEX_MODE_P (mode))
20826 : : return 2;
20827 : : /* Register pair for mask registers. */
20828 : 5290774200 : if (mode == P2QImode || mode == P2HImode)
20829 : : return 2;
20830 : 5197953600 : if (mode == V64SFmode || mode == V64SImode)
20831 : 92820600 : return 4;
20832 : : return 1;
20833 : : }
20834 : :
20835 : : /* Implement REGMODE_NATURAL_SIZE(MODE). */
20836 : : unsigned int
20837 : 96837765 : ix86_regmode_natural_size (machine_mode mode)
20838 : : {
20839 : 96837765 : if (mode == P2HImode || mode == P2QImode)
20840 : 2456 : return GET_MODE_SIZE (mode) / 2;
20841 : 96836537 : return UNITS_PER_WORD;
20842 : : }
20843 : :
20844 : : /* Implement TARGET_HARD_REGNO_MODE_OK. */
20845 : :
20846 : : static bool
20847 : 55400461973 : ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
20848 : : {
20849 : : /* Flags and only flags can only hold CCmode values. */
20850 : 55400461973 : if (CC_REGNO_P (regno))
20851 : 443146893 : return GET_MODE_CLASS (mode) == MODE_CC;
20852 : 54957315080 : if (GET_MODE_CLASS (mode) == MODE_CC
20853 : : || GET_MODE_CLASS (mode) == MODE_RANDOM)
20854 : : return false;
20855 : 49539588558 : if (STACK_REGNO_P (regno))
20856 : 4840872871 : return VALID_FP_MODE_P (mode);
20857 : 44698715687 : if (MASK_REGNO_P (regno))
20858 : : {
20859 : : /* Register pair only starts at even register number. */
20860 : 3804719174 : if ((mode == P2QImode || mode == P2HImode))
20861 : 50651196 : return MASK_PAIR_REGNO_P(regno);
20862 : :
20863 : 1128877362 : return ((TARGET_AVX512F && VALID_MASK_REG_MODE (mode))
20864 : 4861338004 : || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
20865 : : }
20866 : :
20867 : 40893996513 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
20868 : : return false;
20869 : :
20870 : 39935943478 : if (SSE_REGNO_P (regno))
20871 : : {
20872 : : /* We implement the move patterns for all vector modes into and
20873 : : out of SSE registers, even when no operation instructions
20874 : : are available. */
20875 : :
20876 : : /* For AVX-512 we allow, regardless of regno:
20877 : : - XI mode
20878 : : - any of 512-bit wide vector mode
20879 : : - any scalar mode. */
20880 : 17360428370 : if (TARGET_AVX512F
20881 : 4507565946 : && ((VALID_AVX512F_REG_OR_XI_MODE (mode) && TARGET_EVEX512)
20882 : 4206514702 : || VALID_AVX512F_SCALAR_MODE (mode)))
20883 : : return true;
20884 : :
20885 : : /* For AVX-5124FMAPS or AVX-5124VNNIW
20886 : : allow V64SF and V64SI modes for special regnos. */
20887 : 16759311357 : if ((TARGET_AVX5124FMAPS || TARGET_AVX5124VNNIW)
20888 : 147318838 : && (mode == V64SFmode || mode == V64SImode)
20889 : 2674752 : && MOD4_SSE_REGNO_P (regno))
20890 : : return true;
20891 : :
20892 : : /* TODO check for QI/HI scalars. */
20893 : : /* AVX512VL allows sse regs16+ for 128/256 bit modes. */
20894 : 16758642105 : if (TARGET_AVX512VL
20895 : 1876513759 : && (VALID_AVX256_REG_OR_OI_MODE (mode)
20896 : 1674838176 : || VALID_AVX512VL_128_REG_MODE (mode)))
20897 : : return true;
20898 : :
20899 : : /* xmm16-xmm31 are only available for AVX-512. */
20900 : 16334303833 : if (EXT_REX_SSE_REGNO_P (regno))
20901 : : return false;
20902 : :
20903 : : /* Use pinsrw/pextrw to mov 16-bit data from/to sse to/from integer. */
20904 : 9393439687 : if (TARGET_SSE2 && mode == HImode)
20905 : : return true;
20906 : :
20907 : : /* OImode and AVX modes are available only when AVX is enabled. */
20908 : 9335699182 : return ((TARGET_AVX
20909 : 2187439144 : && VALID_AVX256_REG_OR_OI_MODE (mode))
20910 : : || VALID_SSE_REG_MODE (mode)
20911 : : || VALID_SSE2_REG_MODE (mode)
20912 : : || VALID_MMX_REG_MODE (mode)
20913 : 9335699182 : || VALID_MMX_REG_MODE_3DNOW (mode));
20914 : : }
20915 : 22575515108 : if (MMX_REGNO_P (regno))
20916 : : {
20917 : : /* We implement the move patterns for 3DNOW modes even in MMX mode,
20918 : : so if the register is available at all, then we can move data of
20919 : : the given mode into or out of it. */
20920 : 4055852802 : return (VALID_MMX_REG_MODE (mode)
20921 : : || VALID_MMX_REG_MODE_3DNOW (mode));
20922 : : }
20923 : :
20924 : 18519662306 : if (mode == QImode)
20925 : : {
20926 : : /* Take care for QImode values - they can be in non-QI regs,
20927 : : but then they do cause partial register stalls. */
20928 : 196418863 : if (ANY_QI_REGNO_P (regno))
20929 : : return true;
20930 : 13347316 : if (!TARGET_PARTIAL_REG_STALL)
20931 : : return true;
20932 : : /* LRA checks if the hard register is OK for the given mode.
20933 : : QImode values can live in non-QI regs, so we allow all
20934 : : registers here. */
20935 : 0 : if (lra_in_progress)
20936 : : return true;
20937 : 0 : return !can_create_pseudo_p ();
20938 : : }
20939 : : /* We handle both integer and floats in the general purpose registers. */
20940 : 18323243443 : else if (VALID_INT_MODE_P (mode)
20941 : 13734577266 : || VALID_FP_MODE_P (mode))
20942 : : return true;
20943 : : /* Lots of MMX code casts 8 byte vector modes to DImode. If we then go
20944 : : on to use that value in smaller contexts, this can easily force a
20945 : : pseudo to be allocated to GENERAL_REGS. Since this is no worse than
20946 : : supporting DImode, allow it. */
20947 : 12715099496 : else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
20948 : : return true;
20949 : :
20950 : : return false;
20951 : : }
20952 : :
20953 : : /* Implement TARGET_INSN_CALLEE_ABI. */
20954 : :
20955 : : const predefined_function_abi &
20956 : 243722291 : ix86_insn_callee_abi (const rtx_insn *insn)
20957 : : {
20958 : 243722291 : unsigned int abi_id = 0;
20959 : 243722291 : rtx pat = PATTERN (insn);
20960 : 243722291 : if (vzeroupper_pattern (pat, VOIDmode))
20961 : 227536 : abi_id = ABI_VZEROUPPER;
20962 : :
20963 : 243722291 : return function_abis[abi_id];
20964 : : }
20965 : :
20966 : : /* Initialize function_abis with corresponding abi_id,
20967 : : currently only handle vzeroupper. */
20968 : : void
20969 : 17334 : ix86_initialize_callee_abi (unsigned int abi_id)
20970 : : {
20971 : 17334 : gcc_assert (abi_id == ABI_VZEROUPPER);
20972 : 17334 : predefined_function_abi &vzeroupper_abi = function_abis[abi_id];
20973 : 17334 : if (!vzeroupper_abi.initialized_p ())
20974 : : {
20975 : : HARD_REG_SET full_reg_clobbers;
20976 : 3997 : CLEAR_HARD_REG_SET (full_reg_clobbers);
20977 : 3997 : vzeroupper_abi.initialize (ABI_VZEROUPPER, full_reg_clobbers);
20978 : : }
20979 : 17334 : }
20980 : :
20981 : : void
20982 : 17334 : ix86_expand_avx_vzeroupper (void)
20983 : : {
20984 : : /* Initialize vzeroupper_abi here. */
20985 : 17334 : ix86_initialize_callee_abi (ABI_VZEROUPPER);
20986 : 17334 : rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
20987 : : /* Return false for non-local goto in can_nonlocal_goto. */
20988 : 17334 : make_reg_eh_region_note (insn, 0, INT_MIN);
20989 : : /* Flag used for call_insn indicates it's a fake call. */
20990 : 17334 : RTX_FLAG (insn, used) = 1;
20991 : 17334 : }
20992 : :
20993 : :
20994 : : /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The only ABI that
20995 : : saves SSE registers across calls is Win64 (thus no need to check the
20996 : : current ABI here), and with AVX enabled Win64 only guarantees that
20997 : : the low 16 bytes are saved. */
20998 : :
20999 : : static bool
21000 : 1994421818 : ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
21001 : : machine_mode mode)
21002 : : {
21003 : : /* Special ABI for vzeroupper which only clobber higher part of sse regs. */
21004 : 1994421818 : if (abi_id == ABI_VZEROUPPER)
21005 : 28816397 : return (GET_MODE_SIZE (mode) > 16
21006 : 28816397 : && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
21007 : 4388762 : || LEGACY_SSE_REGNO_P (regno)));
21008 : :
21009 : 2573477497 : return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
21010 : : }
21011 : :
21012 : : /* A subroutine of ix86_modes_tieable_p. Return true if MODE is a
21013 : : tieable integer mode. */
21014 : :
21015 : : static bool
21016 : 48647052 : ix86_tieable_integer_mode_p (machine_mode mode)
21017 : : {
21018 : 48647052 : switch (mode)
21019 : : {
21020 : : case E_HImode:
21021 : : case E_SImode:
21022 : : return true;
21023 : :
21024 : 5286699 : case E_QImode:
21025 : 5286699 : return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
21026 : :
21027 : 9218295 : case E_DImode:
21028 : 9218295 : return TARGET_64BIT;
21029 : :
21030 : : default:
21031 : : return false;
21032 : : }
21033 : : }
21034 : :
21035 : : /* Implement TARGET_MODES_TIEABLE_P.
21036 : :
21037 : : Return true if MODE1 is accessible in a register that can hold MODE2
21038 : : without copying. That is, all register classes that can hold MODE2
21039 : : can also hold MODE1. */
21040 : :
21041 : : static bool
21042 : 31385905 : ix86_modes_tieable_p (machine_mode mode1, machine_mode mode2)
21043 : : {
21044 : 31385905 : if (mode1 == mode2)
21045 : : return true;
21046 : :
21047 : 31290858 : if (ix86_tieable_integer_mode_p (mode1)
21048 : 31290858 : && ix86_tieable_integer_mode_p (mode2))
21049 : : return true;
21050 : :
21051 : : /* MODE2 being XFmode implies fp stack or general regs, which means we
21052 : : can tie any smaller floating point modes to it. Note that we do not
21053 : : tie this with TFmode. */
21054 : 22829764 : if (mode2 == XFmode)
21055 : 4319 : return mode1 == SFmode || mode1 == DFmode;
21056 : :
21057 : : /* MODE2 being DFmode implies fp stack, general or sse regs, which means
21058 : : that we can tie it with SFmode. */
21059 : 22825445 : if (mode2 == DFmode)
21060 : 259277 : return mode1 == SFmode;
21061 : :
21062 : : /* If MODE2 is only appropriate for an SSE register, then tie with
21063 : : any other mode acceptable to SSE registers. */
21064 : 22566168 : if (GET_MODE_SIZE (mode2) == 64
21065 : 22566168 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
21066 : 307123 : return (GET_MODE_SIZE (mode1) == 64
21067 : 307123 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
21068 : 22259045 : if (GET_MODE_SIZE (mode2) == 32
21069 : 22259045 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
21070 : 439717 : return (GET_MODE_SIZE (mode1) == 32
21071 : 439717 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
21072 : 21819328 : if (GET_MODE_SIZE (mode2) == 16
21073 : 21819328 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
21074 : 8926030 : return (GET_MODE_SIZE (mode1) == 16
21075 : 8926030 : && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1));
21076 : :
21077 : : /* If MODE2 is appropriate for an MMX register, then tie
21078 : : with any other mode acceptable to MMX registers. */
21079 : 12893298 : if (GET_MODE_SIZE (mode2) == 8
21080 : 12893298 : && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
21081 : 3362187 : return (GET_MODE_SIZE (mode1) == 8
21082 : 3362187 : && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
21083 : :
21084 : : /* SCmode and DImode can be tied. */
21085 : 9531111 : if ((mode1 == E_SCmode && mode2 == E_DImode)
21086 : 9531111 : || (mode1 == E_DImode && mode2 == E_SCmode))
21087 : 108 : return TARGET_64BIT;
21088 : :
21089 : : /* [SD]Cmode and V2[SD]Fmode modes can be tied. */
21090 : 9531003 : if ((mode1 == E_SCmode && mode2 == E_V2SFmode)
21091 : 9531003 : || (mode1 == E_V2SFmode && mode2 == E_SCmode)
21092 : 9531003 : || (mode1 == E_DCmode && mode2 == E_V2DFmode)
21093 : 9531003 : || (mode1 == E_V2DFmode && mode2 == E_DCmode))
21094 : : return true;
21095 : :
21096 : : return false;
21097 : : }
21098 : :
21099 : : /* Return the cost of moving between two registers of mode MODE. */
21100 : :
21101 : : static int
21102 : 30498449 : ix86_set_reg_reg_cost (machine_mode mode)
21103 : : {
21104 : 30498449 : unsigned int units = UNITS_PER_WORD;
21105 : :
21106 : 30498449 : switch (GET_MODE_CLASS (mode))
21107 : : {
21108 : : default:
21109 : : break;
21110 : :
21111 : 0 : case MODE_CC:
21112 : 0 : units = GET_MODE_SIZE (CCmode);
21113 : 0 : break;
21114 : :
21115 : 1124843 : case MODE_FLOAT:
21116 : 1124843 : if ((TARGET_SSE && mode == TFmode)
21117 : 660951 : || (TARGET_80387 && mode == XFmode)
21118 : 204938 : || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
21119 : 142917 : || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
21120 : 2220380 : units = GET_MODE_SIZE (mode);
21121 : : break;
21122 : :
21123 : 1252750 : case MODE_COMPLEX_FLOAT:
21124 : 1252750 : if ((TARGET_SSE && mode == TCmode)
21125 : 839920 : || (TARGET_80387 && mode == XCmode)
21126 : 426984 : || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
21127 : 14034 : || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
21128 : 2499160 : units = GET_MODE_SIZE (mode);
21129 : : break;
21130 : :
21131 : 20415788 : case MODE_VECTOR_INT:
21132 : 20415788 : case MODE_VECTOR_FLOAT:
21133 : 20415788 : if ((TARGET_AVX512F && TARGET_EVEX512 && VALID_AVX512F_REG_MODE (mode))
21134 : 20323829 : || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
21135 : 20153894 : || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
21136 : 17634805 : || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
21137 : 16382581 : || ((TARGET_MMX || TARGET_MMX_WITH_SSE)
21138 : 16331507 : && VALID_MMX_REG_MODE (mode)))
21139 : 8167934 : units = GET_MODE_SIZE (mode);
21140 : : }
21141 : :
21142 : : /* Return the cost of moving between two registers of mode MODE,
21143 : : assuming that the move will be in pieces of at most UNITS bytes. */
21144 : 30498449 : return COSTS_N_INSNS (CEIL (GET_MODE_SIZE (mode), units));
21145 : : }
21146 : :
21147 : : /* Return cost of vector operation in MODE given that scalar version has
21148 : : COST. */
21149 : :
21150 : : static int
21151 : 2803969236 : ix86_vec_cost (machine_mode mode, int cost)
21152 : : {
21153 : 2803969236 : if (!VECTOR_MODE_P (mode))
21154 : : return cost;
21155 : :
21156 : 2802949302 : if (GET_MODE_BITSIZE (mode) == 128
21157 : 2802949302 : && TARGET_SSE_SPLIT_REGS)
21158 : 3085568 : return cost * GET_MODE_BITSIZE (mode) / 64;
21159 : 2801406518 : else if (GET_MODE_BITSIZE (mode) > 128
21160 : 2801406518 : && TARGET_AVX256_SPLIT_REGS)
21161 : 1659712 : return cost * GET_MODE_BITSIZE (mode) / 128;
21162 : 2800576662 : else if (GET_MODE_BITSIZE (mode) > 256
21163 : 2800576662 : && TARGET_AVX512_SPLIT_REGS)
21164 : 99248 : return cost * GET_MODE_BITSIZE (mode) / 256;
21165 : : return cost;
21166 : : }
21167 : :
21168 : : /* Return cost of vec_widen_<s>mult_hi/lo_<mode>,
21169 : : vec_widen_<s>mul_hi/lo_<mode> is only available for VI124_AVX2. */
21170 : : static int
21171 : 1460 : ix86_widen_mult_cost (const struct processor_costs *cost,
21172 : : enum machine_mode mode, bool uns_p)
21173 : : {
21174 : 1460 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
21175 : 1460 : int extra_cost = 0;
21176 : 1460 : int basic_cost = 0;
21177 : 1460 : switch (mode)
21178 : : {
21179 : 225 : case V8HImode:
21180 : 225 : case V16HImode:
21181 : 225 : if (!uns_p || mode == V16HImode)
21182 : 47 : extra_cost = cost->sse_op * 2;
21183 : 225 : basic_cost = cost->mulss * 2 + cost->sse_op * 4;
21184 : 225 : break;
21185 : 319 : case V4SImode:
21186 : 319 : case V8SImode:
21187 : : /* pmulhw/pmullw can be used. */
21188 : 319 : basic_cost = cost->mulss * 2 + cost->sse_op * 2;
21189 : 319 : break;
21190 : 843 : case V2DImode:
21191 : : /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
21192 : : require extra 4 mul, 4 add, 4 cmp and 2 shift. */
21193 : 843 : if (!TARGET_SSE4_1 && !uns_p)
21194 : 438 : extra_cost = (cost->mulss + cost->addss + cost->sse_op) * 4
21195 : 438 : + cost->sse_op * 2;
21196 : : /* Fallthru. */
21197 : 913 : case V4DImode:
21198 : 913 : basic_cost = cost->mulss * 2 + cost->sse_op * 4;
21199 : 913 : break;
21200 : : default:
21201 : : /* Not implemented. */
21202 : : return 100;
21203 : : }
21204 : 1457 : return ix86_vec_cost (mode, basic_cost + extra_cost);
21205 : : }
21206 : :
21207 : : /* Return cost of multiplication in MODE. */
21208 : :
21209 : : static int
21210 : 1196841745 : ix86_multiplication_cost (const struct processor_costs *cost,
21211 : : enum machine_mode mode)
21212 : : {
21213 : 1196841745 : machine_mode inner_mode = mode;
21214 : 1196841745 : if (VECTOR_MODE_P (mode))
21215 : 1195912910 : inner_mode = GET_MODE_INNER (mode);
21216 : :
21217 : 1196841745 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
21218 : 694425 : return inner_mode == DFmode ? cost->mulsd : cost->mulss;
21219 : 1196147320 : else if (X87_FLOAT_MODE_P (mode))
21220 : 166002 : return cost->fmul;
21221 : 1195981318 : else if (FLOAT_MODE_P (mode))
21222 : 183921 : return ix86_vec_cost (mode,
21223 : 183921 : inner_mode == DFmode ? cost->mulsd : cost->mulss);
21224 : 1195797397 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
21225 : : {
21226 : 1195753029 : int nmults, nops;
21227 : : /* Cost of reading the memory. */
21228 : 1195753029 : int extra;
21229 : :
21230 : 1195753029 : switch (mode)
21231 : : {
21232 : 18216139 : case V4QImode:
21233 : 18216139 : case V8QImode:
21234 : : /* Partial V*QImode is emulated with 4-6 insns. */
21235 : 18216139 : nmults = 1;
21236 : 18216139 : nops = 3;
21237 : 18216139 : extra = 0;
21238 : :
21239 : 18216139 : if (TARGET_AVX512BW && TARGET_AVX512VL)
21240 : : ;
21241 : 18122566 : else if (TARGET_AVX2)
21242 : : nops += 2;
21243 : 17630996 : else if (TARGET_XOP)
21244 : 10472 : extra += cost->sse_load[2];
21245 : : else
21246 : : {
21247 : 17620524 : nops += 1;
21248 : 17620524 : extra += cost->sse_load[2];
21249 : : }
21250 : 18216139 : goto do_qimode;
21251 : :
21252 : 9109281 : case V16QImode:
21253 : : /* V*QImode is emulated with 4-11 insns. */
21254 : 9109281 : nmults = 1;
21255 : 9109281 : nops = 3;
21256 : 9109281 : extra = 0;
21257 : :
21258 : 9109281 : if (TARGET_AVX2 && !TARGET_PREFER_AVX128)
21259 : : {
21260 : 291020 : if (!(TARGET_AVX512BW && TARGET_AVX512VL))
21261 : 244416 : nops += 3;
21262 : : }
21263 : 8818261 : else if (TARGET_XOP)
21264 : : {
21265 : 5728 : nmults += 1;
21266 : 5728 : nops += 2;
21267 : 5728 : extra += cost->sse_load[2];
21268 : : }
21269 : : else
21270 : : {
21271 : 8812533 : nmults += 1;
21272 : 8812533 : nops += 4;
21273 : 8812533 : extra += cost->sse_load[2];
21274 : : }
21275 : 9109281 : goto do_qimode;
21276 : :
21277 : 9108090 : case V32QImode:
21278 : 9108090 : nmults = 1;
21279 : 9108090 : nops = 3;
21280 : 9108090 : extra = 0;
21281 : :
21282 : 9108090 : if (!TARGET_AVX512BW || TARGET_PREFER_AVX256)
21283 : : {
21284 : 9033973 : nmults += 1;
21285 : 9033973 : nops += 4;
21286 : 9033973 : extra += cost->sse_load[3] * 2;
21287 : : }
21288 : 9108090 : goto do_qimode;
21289 : :
21290 : 9107568 : case V64QImode:
21291 : 9107568 : nmults = 2;
21292 : 9107568 : nops = 9;
21293 : 9107568 : extra = cost->sse_load[3] * 2 + cost->sse_load[4] * 2;
21294 : :
21295 : 45541078 : do_qimode:
21296 : 45541078 : return ix86_vec_cost (mode, cost->mulss * nmults
21297 : 45541078 : + cost->sse_op * nops) + extra;
21298 : :
21299 : 38942617 : case V4SImode:
21300 : : /* pmulld is used in this case. No emulation is needed. */
21301 : 38942617 : if (TARGET_SSE4_1)
21302 : 1870644 : goto do_native;
21303 : : /* V4SImode is emulated with 7 insns. */
21304 : : else
21305 : 37071973 : return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 5);
21306 : :
21307 : 157402773 : case V2DImode:
21308 : 157402773 : case V4DImode:
21309 : : /* vpmullq is used in this case. No emulation is needed. */
21310 : 157402773 : if (TARGET_AVX512DQ && TARGET_AVX512VL)
21311 : 428921 : goto do_native;
21312 : : /* V*DImode is emulated with 6-8 insns. */
21313 : 156973852 : else if (TARGET_XOP && mode == V2DImode)
21314 : 57883 : return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 4);
21315 : : /* FALLTHRU */
21316 : 235573299 : case V8DImode:
21317 : : /* vpmullq is used in this case. No emulation is needed. */
21318 : 235573299 : if (TARGET_AVX512DQ && mode == V8DImode)
21319 : 304815 : goto do_native;
21320 : : else
21321 : 235268484 : return ix86_vec_cost (mode, cost->mulss * 3 + cost->sse_op * 5);
21322 : :
21323 : 877813611 : default:
21324 : 877813611 : do_native:
21325 : 877813611 : return ix86_vec_cost (mode, cost->mulss);
21326 : : }
21327 : : }
21328 : : else
21329 : 88736 : return (cost->mult_init[MODE_INDEX (mode)] + cost->mult_bit * 7);
21330 : : }
21331 : :
21332 : : /* Return cost of multiplication in MODE. */
21333 : :
21334 : : static int
21335 : 71024058 : ix86_division_cost (const struct processor_costs *cost,
21336 : : enum machine_mode mode)
21337 : : {
21338 : 71024058 : machine_mode inner_mode = mode;
21339 : 71024058 : if (VECTOR_MODE_P (mode))
21340 : 52998542 : inner_mode = GET_MODE_INNER (mode);
21341 : :
21342 : 71024058 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
21343 : 222320 : return inner_mode == DFmode ? cost->divsd : cost->divss;
21344 : 70801738 : else if (X87_FLOAT_MODE_P (mode))
21345 : 47032 : return cost->fdiv;
21346 : 70754706 : else if (FLOAT_MODE_P (mode))
21347 : 13008 : return ix86_vec_cost (mode,
21348 : 13008 : inner_mode == DFmode ? cost->divsd : cost->divss);
21349 : : else
21350 : 141483396 : return cost->divide[MODE_INDEX (mode)];
21351 : : }
21352 : :
21353 : : /* Return cost of shift in MODE.
21354 : : If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
21355 : : AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE
21356 : : if op1 is a result of subreg.
21357 : :
21358 : : SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored. */
21359 : :
21360 : : static int
21361 : 756072024 : ix86_shift_rotate_cost (const struct processor_costs *cost,
21362 : : enum rtx_code code,
21363 : : enum machine_mode mode, bool constant_op1,
21364 : : HOST_WIDE_INT op1_val,
21365 : : bool and_in_op1,
21366 : : bool shift_and_truncate,
21367 : : bool *skip_op0, bool *skip_op1)
21368 : : {
21369 : 756072024 : if (skip_op0)
21370 : 756034310 : *skip_op0 = *skip_op1 = false;
21371 : :
21372 : 756072024 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
21373 : : {
21374 : 394484997 : int count;
21375 : : /* Cost of reading the memory. */
21376 : 394484997 : int extra;
21377 : :
21378 : 394484997 : switch (mode)
21379 : : {
21380 : 5795642 : case V4QImode:
21381 : 5795642 : case V8QImode:
21382 : 5795642 : if (TARGET_AVX2)
21383 : : /* Use vpbroadcast. */
21384 : 186156 : extra = cost->sse_op;
21385 : : else
21386 : 5609486 : extra = cost->sse_load[2];
21387 : :
21388 : 5795642 : if (constant_op1)
21389 : : {
21390 : 5795630 : if (code == ASHIFTRT)
21391 : : {
21392 : 38 : count = 4;
21393 : 38 : extra *= 2;
21394 : : }
21395 : : else
21396 : : count = 2;
21397 : : }
21398 : 12 : else if (TARGET_AVX512BW && TARGET_AVX512VL)
21399 : 12 : return ix86_vec_cost (mode, cost->sse_op * 4);
21400 : 0 : else if (TARGET_SSE4_1)
21401 : : count = 5;
21402 : 0 : else if (code == ASHIFTRT)
21403 : : count = 6;
21404 : : else
21405 : 0 : count = 5;
21406 : 5795630 : return ix86_vec_cost (mode, cost->sse_op * count) + extra;
21407 : :
21408 : 2900090 : case V16QImode:
21409 : 2900090 : if (TARGET_XOP)
21410 : : {
21411 : : /* For XOP we use vpshab, which requires a broadcast of the
21412 : : value to the variable shift insn. For constants this
21413 : : means a V16Q const in mem; even when we can perform the
21414 : : shift with one insn set the cost to prefer paddb. */
21415 : 4002 : if (constant_op1)
21416 : : {
21417 : 3044 : extra = cost->sse_load[2];
21418 : 3044 : return ix86_vec_cost (mode, cost->sse_op) + extra;
21419 : : }
21420 : : else
21421 : : {
21422 : 958 : count = (code == ASHIFT) ? 3 : 4;
21423 : 958 : return ix86_vec_cost (mode, cost->sse_op * count);
21424 : : }
21425 : : }
21426 : : /* FALLTHRU */
21427 : 5793864 : case V32QImode:
21428 : 5793864 : if (TARGET_AVX2)
21429 : : /* Use vpbroadcast. */
21430 : 185099 : extra = cost->sse_op;
21431 : : else
21432 : 5608765 : extra = (mode == V16QImode) ? cost->sse_load[2] : cost->sse_load[3];
21433 : :
21434 : 5793864 : if (constant_op1)
21435 : : {
21436 : 5793812 : if (code == ASHIFTRT)
21437 : : {
21438 : 66 : count = 4;
21439 : 66 : extra *= 2;
21440 : : }
21441 : : else
21442 : : count = 2;
21443 : : }
21444 : 52 : else if (TARGET_AVX512BW
21445 : 36 : && ((mode == V32QImode && !TARGET_PREFER_AVX256)
21446 : 18 : || (mode == V16QImode && TARGET_AVX512VL
21447 : 18 : && !TARGET_PREFER_AVX128)))
21448 : 36 : return ix86_vec_cost (mode, cost->sse_op * 4);
21449 : 16 : else if (TARGET_AVX2
21450 : 0 : && mode == V16QImode && !TARGET_PREFER_AVX128)
21451 : : count = 6;
21452 : 16 : else if (TARGET_SSE4_1)
21453 : : count = 9;
21454 : 16 : else if (code == ASHIFTRT)
21455 : : count = 10;
21456 : : else
21457 : 16 : count = 9;
21458 : 5793828 : return ix86_vec_cost (mode, cost->sse_op * count) + extra;
21459 : :
21460 : 52239119 : case V2DImode:
21461 : 52239119 : case V4DImode:
21462 : : /* V*DImode arithmetic right shift is emulated. */
21463 : 52239119 : if (code == ASHIFTRT && !TARGET_AVX512VL)
21464 : : {
21465 : 1315 : if (constant_op1)
21466 : : {
21467 : 492 : if (op1_val == 63)
21468 : 14 : count = TARGET_SSE4_2 ? 1 : 2;
21469 : 478 : else if (TARGET_XOP)
21470 : : count = 2;
21471 : 81 : else if (TARGET_SSE4_1)
21472 : : count = 3;
21473 : : else
21474 : 80 : count = 4;
21475 : : }
21476 : 823 : else if (TARGET_XOP)
21477 : : count = 3;
21478 : 10 : else if (TARGET_SSE4_2)
21479 : : count = 4;
21480 : : else
21481 : 1315 : count = 5;
21482 : :
21483 : 1315 : return ix86_vec_cost (mode, cost->sse_op * count);
21484 : : }
21485 : : /* FALLTHRU */
21486 : 382890174 : default:
21487 : 382890174 : return ix86_vec_cost (mode, cost->sse_op);
21488 : : }
21489 : : }
21490 : :
21491 : 731487234 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21492 : : {
21493 : 186006312 : if (constant_op1)
21494 : : {
21495 : 185971731 : if (op1_val > 32)
21496 : 132403842 : return cost->shift_const + COSTS_N_INSNS (2);
21497 : : else
21498 : 53567889 : return cost->shift_const * 2;
21499 : : }
21500 : : else
21501 : : {
21502 : 34581 : if (and_in_op1)
21503 : 63 : return cost->shift_var * 2;
21504 : : else
21505 : 34518 : return cost->shift_var * 6 + COSTS_N_INSNS (2);
21506 : : }
21507 : : }
21508 : : else
21509 : : {
21510 : 175580715 : if (constant_op1)
21511 : 174932329 : return cost->shift_const;
21512 : 648386 : else if (shift_and_truncate)
21513 : : {
21514 : 19057 : if (skip_op0)
21515 : 19057 : *skip_op0 = *skip_op1 = true;
21516 : : /* Return the cost after shift-and truncation. */
21517 : 19057 : return cost->shift_var;
21518 : : }
21519 : : else
21520 : 629329 : return cost->shift_var;
21521 : : }
21522 : : }
21523 : :
21524 : : /* Compute a (partial) cost for rtx X. Return true if the complete
21525 : : cost has been computed, and false if subexpressions should be
21526 : : scanned. In either case, *TOTAL contains the cost result. */
21527 : :
21528 : : static bool
21529 : 7572906080 : ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
21530 : : int *total, bool speed)
21531 : : {
21532 : 7572906080 : rtx mask;
21533 : 7572906080 : enum rtx_code code = GET_CODE (x);
21534 : 7572906080 : enum rtx_code outer_code = (enum rtx_code) outer_code_i;
21535 : 15145812160 : const struct processor_costs *cost
21536 : 7572906080 : = speed ? ix86_tune_cost : &ix86_size_cost;
21537 : 7572906080 : int src_cost;
21538 : :
21539 : 7572906080 : switch (code)
21540 : : {
21541 : 46964716 : case SET:
21542 : 46964716 : if (register_operand (SET_DEST (x), VOIDmode)
21543 : 46964716 : && register_operand (SET_SRC (x), VOIDmode))
21544 : : {
21545 : 30498449 : *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
21546 : 30498449 : return true;
21547 : : }
21548 : :
21549 : 16466267 : if (register_operand (SET_SRC (x), VOIDmode))
21550 : : /* Avoid potentially incorrect high cost from rtx_costs
21551 : : for non-tieable SUBREGs. */
21552 : : src_cost = 0;
21553 : : else
21554 : : {
21555 : 14213466 : src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed);
21556 : :
21557 : 14213466 : if (CONSTANT_P (SET_SRC (x)))
21558 : : /* Constant costs assume a base value of COSTS_N_INSNS (1) and add
21559 : : a small value, possibly zero for cheap constants. */
21560 : 6375128 : src_cost += COSTS_N_INSNS (1);
21561 : : }
21562 : :
21563 : 16466267 : *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed);
21564 : 16466267 : return true;
21565 : :
21566 : 2801806269 : case CONST_INT:
21567 : 2801806269 : case CONST:
21568 : 2801806269 : case LABEL_REF:
21569 : 2801806269 : case SYMBOL_REF:
21570 : 2801806269 : if (x86_64_immediate_operand (x, VOIDmode))
21571 : 2221176384 : *total = 0;
21572 : : else
21573 : 580629885 : *total = 1;
21574 : : return true;
21575 : :
21576 : 7288571 : case CONST_DOUBLE:
21577 : 7288571 : if (IS_STACK_MODE (mode))
21578 : 1283395 : switch (standard_80387_constant_p (x))
21579 : : {
21580 : : case -1:
21581 : : case 0:
21582 : : break;
21583 : 260439 : case 1: /* 0.0 */
21584 : 260439 : *total = 1;
21585 : 260439 : return true;
21586 : 485551 : default: /* Other constants */
21587 : 485551 : *total = 2;
21588 : 485551 : return true;
21589 : : }
21590 : : /* FALLTHRU */
21591 : :
21592 : 12518444 : case CONST_VECTOR:
21593 : 12518444 : switch (standard_sse_constant_p (x, mode))
21594 : : {
21595 : : case 0:
21596 : : break;
21597 : 3336052 : case 1: /* 0: xor eliminates false dependency */
21598 : 3336052 : *total = 0;
21599 : 3336052 : return true;
21600 : 39191 : default: /* -1: cmp contains false dependency */
21601 : 39191 : *total = 1;
21602 : 39191 : return true;
21603 : : }
21604 : : /* FALLTHRU */
21605 : :
21606 : 10756227 : case CONST_WIDE_INT:
21607 : : /* Fall back to (MEM (SYMBOL_REF)), since that's where
21608 : : it'll probably end up. Add a penalty for size. */
21609 : 21512454 : *total = (COSTS_N_INSNS (1)
21610 : 21293452 : + (!TARGET_64BIT && flag_pic)
21611 : 21512454 : + (GET_MODE_SIZE (mode) <= 4
21612 : 18901933 : ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
21613 : 10756227 : return true;
21614 : :
21615 : 21614004 : case ZERO_EXTEND:
21616 : : /* The zero extensions is often completely free on x86_64, so make
21617 : : it as cheap as possible. */
21618 : 21614004 : if (TARGET_64BIT && mode == DImode
21619 : 3732880 : && GET_MODE (XEXP (x, 0)) == SImode)
21620 : 1957834 : *total = 1;
21621 : 19656170 : else if (TARGET_ZERO_EXTEND_WITH_AND)
21622 : 0 : *total = cost->add;
21623 : : else
21624 : 19656170 : *total = cost->movzx;
21625 : : return false;
21626 : :
21627 : 2621933 : case SIGN_EXTEND:
21628 : 2621933 : *total = cost->movsx;
21629 : 2621933 : return false;
21630 : :
21631 : 624774687 : case ASHIFT:
21632 : 624774687 : if (SCALAR_INT_MODE_P (mode)
21633 : 236716310 : && GET_MODE_SIZE (mode) < UNITS_PER_WORD
21634 : 665964326 : && CONST_INT_P (XEXP (x, 1)))
21635 : : {
21636 : 41036560 : HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
21637 : 41036560 : if (value == 1)
21638 : : {
21639 : 2326721 : *total = cost->add;
21640 : 2326721 : return false;
21641 : : }
21642 : 38709839 : if ((value == 2 || value == 3)
21643 : 4297531 : && cost->lea <= cost->shift_const)
21644 : : {
21645 : 2058396 : *total = cost->lea;
21646 : 2058396 : return false;
21647 : : }
21648 : : }
21649 : : /* FALLTHRU */
21650 : :
21651 : 756034310 : case ROTATE:
21652 : 756034310 : case ASHIFTRT:
21653 : 756034310 : case LSHIFTRT:
21654 : 756034310 : case ROTATERT:
21655 : 756034310 : bool skip_op0, skip_op1;
21656 : 756034310 : *total = ix86_shift_rotate_cost (cost, code, mode,
21657 : 756034310 : CONSTANT_P (XEXP (x, 1)),
21658 : : CONST_INT_P (XEXP (x, 1))
21659 : : ? INTVAL (XEXP (x, 1)) : -1,
21660 : : GET_CODE (XEXP (x, 1)) == AND,
21661 : 756034310 : SUBREG_P (XEXP (x, 1))
21662 : 756034310 : && GET_CODE (XEXP (XEXP (x, 1),
21663 : : 0)) == AND,
21664 : : &skip_op0, &skip_op1);
21665 : 756034310 : if (skip_op0 || skip_op1)
21666 : : {
21667 : 19057 : if (!skip_op0)
21668 : 0 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
21669 : 19057 : if (!skip_op1)
21670 : 0 : *total += rtx_cost (XEXP (x, 1), mode, code, 0, speed);
21671 : 19057 : return true;
21672 : : }
21673 : : return false;
21674 : :
21675 : 157415 : case FMA:
21676 : 157415 : {
21677 : 157415 : rtx sub;
21678 : :
21679 : 157415 : gcc_assert (FLOAT_MODE_P (mode));
21680 : 157415 : gcc_assert (TARGET_FMA || TARGET_FMA4 || TARGET_AVX512F);
21681 : :
21682 : 314830 : *total = ix86_vec_cost (mode,
21683 : 157415 : GET_MODE_INNER (mode) == SFmode
21684 : : ? cost->fmass : cost->fmasd);
21685 : 157415 : *total += rtx_cost (XEXP (x, 1), mode, FMA, 1, speed);
21686 : :
21687 : : /* Negate in op0 or op2 is free: FMS, FNMA, FNMS. */
21688 : 157415 : sub = XEXP (x, 0);
21689 : 157415 : if (GET_CODE (sub) == NEG)
21690 : 36539 : sub = XEXP (sub, 0);
21691 : 157415 : *total += rtx_cost (sub, mode, FMA, 0, speed);
21692 : :
21693 : 157415 : sub = XEXP (x, 2);
21694 : 157415 : if (GET_CODE (sub) == NEG)
21695 : 31583 : sub = XEXP (sub, 0);
21696 : 157415 : *total += rtx_cost (sub, mode, FMA, 2, speed);
21697 : 157415 : return true;
21698 : : }
21699 : :
21700 : 1724602315 : case MULT:
21701 : 1724602315 : if (!FLOAT_MODE_P (mode) && !VECTOR_MODE_P (mode))
21702 : : {
21703 : 527917392 : rtx op0 = XEXP (x, 0);
21704 : 527917392 : rtx op1 = XEXP (x, 1);
21705 : 527917392 : int nbits;
21706 : 527917392 : if (CONST_INT_P (XEXP (x, 1)))
21707 : : {
21708 : 511498832 : unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
21709 : 1038212969 : for (nbits = 0; value != 0; value &= value - 1)
21710 : 526714137 : nbits++;
21711 : : }
21712 : : else
21713 : : /* This is arbitrary. */
21714 : : nbits = 7;
21715 : :
21716 : : /* Compute costs correctly for widening multiplication. */
21717 : 527917392 : if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
21718 : 533203289 : && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
21719 : 5285897 : == GET_MODE_SIZE (mode))
21720 : : {
21721 : 5285308 : int is_mulwiden = 0;
21722 : 5285308 : machine_mode inner_mode = GET_MODE (op0);
21723 : :
21724 : 5285308 : if (GET_CODE (op0) == GET_CODE (op1))
21725 : 5202774 : is_mulwiden = 1, op1 = XEXP (op1, 0);
21726 : 82534 : else if (CONST_INT_P (op1))
21727 : : {
21728 : 72385 : if (GET_CODE (op0) == SIGN_EXTEND)
21729 : 19430 : is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
21730 : 19430 : == INTVAL (op1);
21731 : : else
21732 : 52955 : is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
21733 : : }
21734 : :
21735 : 5275159 : if (is_mulwiden)
21736 : 5275159 : op0 = XEXP (op0, 0), mode = GET_MODE (op0);
21737 : : }
21738 : :
21739 : 527917392 : int mult_init;
21740 : : // Double word multiplication requires 3 mults and 2 adds.
21741 : 1070839470 : if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21742 : : {
21743 : 318388136 : mult_init = 3 * cost->mult_init[MODE_INDEX (word_mode)]
21744 : 318388136 : + 2 * cost->add;
21745 : 318388136 : nbits *= 3;
21746 : : }
21747 : 419058512 : else mult_init = cost->mult_init[MODE_INDEX (mode)];
21748 : :
21749 : 1055834784 : *total = (mult_init
21750 : 527917392 : + nbits * cost->mult_bit
21751 : 527917392 : + rtx_cost (op0, mode, outer_code, opno, speed)
21752 : 527917392 : + rtx_cost (op1, mode, outer_code, opno, speed));
21753 : :
21754 : 527917392 : return true;
21755 : : }
21756 : 1196684923 : *total = ix86_multiplication_cost (cost, mode);
21757 : 1196684923 : return false;
21758 : :
21759 : 71016649 : case DIV:
21760 : 71016649 : case UDIV:
21761 : 71016649 : case MOD:
21762 : 71016649 : case UMOD:
21763 : 71016649 : *total = ix86_division_cost (cost, mode);
21764 : 71016649 : return false;
21765 : :
21766 : 714118129 : case PLUS:
21767 : 714118129 : if (GET_MODE_CLASS (mode) == MODE_INT
21768 : 1012722097 : && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
21769 : : {
21770 : 176651212 : if (GET_CODE (XEXP (x, 0)) == PLUS
21771 : 2299168 : && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
21772 : 626597 : && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
21773 : 626592 : && CONSTANT_P (XEXP (x, 1)))
21774 : : {
21775 : 626540 : HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
21776 : 626540 : if (val == 2 || val == 4 || val == 8)
21777 : : {
21778 : 626484 : *total = cost->lea;
21779 : 626484 : *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
21780 : : outer_code, opno, speed);
21781 : 626484 : *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0), mode,
21782 : : outer_code, opno, speed);
21783 : 626484 : *total += rtx_cost (XEXP (x, 1), mode,
21784 : : outer_code, opno, speed);
21785 : 626484 : return true;
21786 : : }
21787 : : }
21788 : 176024672 : else if (GET_CODE (XEXP (x, 0)) == MULT
21789 : 49891893 : && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
21790 : : {
21791 : 49844187 : HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
21792 : 49844187 : if (val == 2 || val == 4 || val == 8)
21793 : : {
21794 : 7370856 : *total = cost->lea;
21795 : 7370856 : *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21796 : : outer_code, opno, speed);
21797 : 7370856 : *total += rtx_cost (XEXP (x, 1), mode,
21798 : : outer_code, opno, speed);
21799 : 7370856 : return true;
21800 : : }
21801 : : }
21802 : 126180485 : else if (GET_CODE (XEXP (x, 0)) == PLUS)
21803 : : {
21804 : 1672628 : rtx op = XEXP (XEXP (x, 0), 0);
21805 : :
21806 : : /* Add with carry, ignore the cost of adding a carry flag. */
21807 : 1672628 : if (ix86_carry_flag_operator (op, mode)
21808 : 1672628 : || ix86_carry_flag_unset_operator (op, mode))
21809 : 82802 : *total = cost->add;
21810 : : else
21811 : : {
21812 : 1589826 : *total = cost->lea;
21813 : 1589826 : *total += rtx_cost (op, mode,
21814 : : outer_code, opno, speed);
21815 : : }
21816 : :
21817 : 1672628 : *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
21818 : : outer_code, opno, speed);
21819 : 1672628 : *total += rtx_cost (XEXP (x, 1), mode,
21820 : : outer_code, opno, speed);
21821 : 1672628 : return true;
21822 : : }
21823 : : }
21824 : : /* FALLTHRU */
21825 : :
21826 : 1840798615 : case MINUS:
21827 : : /* Subtract with borrow, ignore the cost of subtracting a carry flag. */
21828 : 1840798615 : if (GET_MODE_CLASS (mode) == MODE_INT
21829 : 552439042 : && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
21830 : 266282453 : && GET_CODE (XEXP (x, 0)) == MINUS
21831 : 1840835551 : && (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode)
21832 : 9833 : || ix86_carry_flag_unset_operator (XEXP (XEXP (x, 0), 1), mode)))
21833 : : {
21834 : 27103 : *total = cost->add;
21835 : 27103 : *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21836 : : outer_code, opno, speed);
21837 : 27103 : *total += rtx_cost (XEXP (x, 1), mode,
21838 : : outer_code, opno, speed);
21839 : 27103 : return true;
21840 : : }
21841 : :
21842 : 1840771512 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
21843 : 2261161 : *total = cost->addss;
21844 : 1838510351 : else if (X87_FLOAT_MODE_P (mode))
21845 : 220233 : *total = cost->fadd;
21846 : 1838290118 : else if (FLOAT_MODE_P (mode))
21847 : 312663 : *total = ix86_vec_cost (mode, cost->addss);
21848 : 1837977455 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
21849 : 1196280130 : *total = ix86_vec_cost (mode, cost->sse_op);
21850 : 1334319640 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21851 : 317487295 : *total = cost->add * 2;
21852 : : else
21853 : 324210030 : *total = cost->add;
21854 : : return false;
21855 : :
21856 : 3530451 : case IOR:
21857 : 3530451 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
21858 : 3455462 : || SSE_FLOAT_MODE_P (mode))
21859 : : {
21860 : : /* (ior (not ...) ...) can be a single insn in AVX512. */
21861 : 29 : if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
21862 : 84404 : && ((TARGET_EVEX512
21863 : 29 : && GET_MODE_SIZE (mode) == 64)
21864 : 14 : || (TARGET_AVX512VL
21865 : 14 : && (GET_MODE_SIZE (mode) == 32
21866 : 0 : || GET_MODE_SIZE (mode) == 16))))
21867 : : {
21868 : 58 : rtx right = GET_CODE (XEXP (x, 1)) != NOT
21869 : 29 : ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
21870 : :
21871 : 29 : *total = ix86_vec_cost (mode, cost->sse_op)
21872 : 29 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21873 : : outer_code, opno, speed)
21874 : 29 : + rtx_cost (right, mode, outer_code, opno, speed);
21875 : 29 : return true;
21876 : : }
21877 : 84346 : *total = ix86_vec_cost (mode, cost->sse_op);
21878 : 84346 : }
21879 : 7162509 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21880 : 1687610 : *total = cost->add * 2;
21881 : : else
21882 : 1758466 : *total = cost->add;
21883 : : return false;
21884 : :
21885 : 450845 : case XOR:
21886 : 450845 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
21887 : 392563 : || SSE_FLOAT_MODE_P (mode))
21888 : 58282 : *total = ix86_vec_cost (mode, cost->sse_op);
21889 : 843708 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21890 : 16164 : *total = cost->add * 2;
21891 : : else
21892 : 376399 : *total = cost->add;
21893 : : return false;
21894 : :
21895 : 6905586 : case AND:
21896 : 6905586 : if (address_no_seg_operand (x, mode))
21897 : : {
21898 : 10563 : *total = cost->lea;
21899 : 10563 : return true;
21900 : : }
21901 : 6895023 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
21902 : 6627107 : || SSE_FLOAT_MODE_P (mode))
21903 : : {
21904 : : /* pandn is a single instruction. */
21905 : 301304 : if (GET_CODE (XEXP (x, 0)) == NOT)
21906 : : {
21907 : 37732 : rtx right = XEXP (x, 1);
21908 : :
21909 : : /* (and (not ...) (not ...)) can be a single insn in AVX512. */
21910 : 72 : if (GET_CODE (right) == NOT && TARGET_AVX512F
21911 : 37732 : && ((TARGET_EVEX512
21912 : 0 : && GET_MODE_SIZE (mode) == 64)
21913 : 0 : || (TARGET_AVX512VL
21914 : 0 : && (GET_MODE_SIZE (mode) == 32
21915 : 0 : || GET_MODE_SIZE (mode) == 16))))
21916 : 0 : right = XEXP (right, 0);
21917 : :
21918 : 37732 : *total = ix86_vec_cost (mode, cost->sse_op)
21919 : 37732 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21920 : : outer_code, opno, speed)
21921 : 37732 : + rtx_cost (right, mode, outer_code, opno, speed);
21922 : 37732 : return true;
21923 : : }
21924 : 263572 : else if (GET_CODE (XEXP (x, 1)) == NOT)
21925 : : {
21926 : 153 : *total = ix86_vec_cost (mode, cost->sse_op)
21927 : 153 : + rtx_cost (XEXP (x, 0), mode,
21928 : : outer_code, opno, speed)
21929 : 153 : + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
21930 : : outer_code, opno, speed);
21931 : 153 : return true;
21932 : : }
21933 : 263419 : *total = ix86_vec_cost (mode, cost->sse_op);
21934 : 263419 : }
21935 : 13822086 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
21936 : : {
21937 : 1661527 : if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
21938 : : {
21939 : 1700 : *total = cost->add * 2
21940 : 850 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21941 : : outer_code, opno, speed)
21942 : 850 : + rtx_cost (XEXP (x, 1), mode,
21943 : : outer_code, opno, speed);
21944 : 850 : return true;
21945 : : }
21946 : 1660677 : else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT)
21947 : : {
21948 : 0 : *total = cost->add * 2
21949 : 0 : + rtx_cost (XEXP (x, 0), mode,
21950 : : outer_code, opno, speed)
21951 : 0 : + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
21952 : : outer_code, opno, speed);
21953 : 0 : return true;
21954 : : }
21955 : 1660677 : *total = cost->add * 2;
21956 : : }
21957 : 4932192 : else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
21958 : : {
21959 : 804 : *total = cost->add
21960 : 402 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21961 : : outer_code, opno, speed)
21962 : 402 : + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
21963 : 402 : return true;
21964 : : }
21965 : 4931790 : else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT)
21966 : : {
21967 : 112 : *total = cost->add
21968 : 56 : + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
21969 : 56 : + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
21970 : : outer_code, opno, speed);
21971 : 56 : return true;
21972 : : }
21973 : : else
21974 : 4931734 : *total = cost->add;
21975 : : return false;
21976 : :
21977 : 465314 : case NOT:
21978 : 465314 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
21979 : : {
21980 : : /* (not (xor ...)) can be a single insn in AVX512. */
21981 : 4 : if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
21982 : 5058 : && ((TARGET_EVEX512
21983 : 4 : && GET_MODE_SIZE (mode) == 64)
21984 : 0 : || (TARGET_AVX512VL
21985 : 0 : && (GET_MODE_SIZE (mode) == 32
21986 : 0 : || GET_MODE_SIZE (mode) == 16))))
21987 : : {
21988 : 4 : *total = ix86_vec_cost (mode, cost->sse_op)
21989 : 4 : + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
21990 : : outer_code, opno, speed)
21991 : 4 : + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
21992 : : outer_code, opno, speed);
21993 : 4 : return true;
21994 : : }
21995 : :
21996 : : // vnot is pxor -1.
21997 : 5050 : *total = ix86_vec_cost (mode, cost->sse_op) + 1;
21998 : : }
21999 : 1067377 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22000 : 66442 : *total = cost->add * 2;
22001 : : else
22002 : 393818 : *total = cost->add;
22003 : : return false;
22004 : :
22005 : 17838390 : case NEG:
22006 : 17838390 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
22007 : 48143 : *total = cost->sse_op;
22008 : 17790247 : else if (X87_FLOAT_MODE_P (mode))
22009 : 15912 : *total = cost->fchs;
22010 : 17774335 : else if (FLOAT_MODE_P (mode))
22011 : 29513 : *total = ix86_vec_cost (mode, cost->sse_op);
22012 : 17744822 : else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
22013 : 13257534 : *total = ix86_vec_cost (mode, cost->sse_op);
22014 : 9119074 : else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
22015 : 1690559 : *total = cost->add * 3;
22016 : : else
22017 : 2796729 : *total = cost->add;
22018 : : return false;
22019 : :
22020 : 47305731 : case COMPARE:
22021 : 47305731 : rtx op0, op1;
22022 : 47305731 : op0 = XEXP (x, 0);
22023 : 47305731 : op1 = XEXP (x, 1);
22024 : 47305731 : if (GET_CODE (op0) == ZERO_EXTRACT
22025 : 122382 : && XEXP (op0, 1) == const1_rtx
22026 : 105899 : && CONST_INT_P (XEXP (op0, 2))
22027 : 105799 : && op1 == const0_rtx)
22028 : : {
22029 : : /* This kind of construct is implemented using test[bwl].
22030 : : Treat it as if we had an AND. */
22031 : 105799 : mode = GET_MODE (XEXP (op0, 0));
22032 : 211598 : *total = (cost->add
22033 : 105799 : + rtx_cost (XEXP (op0, 0), mode, outer_code,
22034 : : opno, speed)
22035 : 105799 : + rtx_cost (const1_rtx, mode, outer_code, opno, speed));
22036 : 105799 : return true;
22037 : : }
22038 : :
22039 : 47199932 : if (GET_CODE (op0) == PLUS && rtx_equal_p (XEXP (op0, 0), op1))
22040 : : {
22041 : : /* This is an overflow detection, count it as a normal compare. */
22042 : 137578 : *total = rtx_cost (op0, GET_MODE (op0), COMPARE, 0, speed);
22043 : 137578 : return true;
22044 : : }
22045 : :
22046 : 47062354 : rtx geu;
22047 : : /* Match x
22048 : : (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
22049 : : (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))) */
22050 : 47062354 : if (mode == CCCmode
22051 : 350092 : && GET_CODE (op0) == NEG
22052 : 23012 : && GET_CODE (geu = XEXP (op0, 0)) == GEU
22053 : 22337 : && REG_P (XEXP (geu, 0))
22054 : 22337 : && (GET_MODE (XEXP (geu, 0)) == CCCmode
22055 : 2016 : || GET_MODE (XEXP (geu, 0)) == CCmode)
22056 : 22337 : && REGNO (XEXP (geu, 0)) == FLAGS_REG
22057 : 22337 : && XEXP (geu, 1) == const0_rtx
22058 : 22337 : && GET_CODE (op1) == LTU
22059 : 22337 : && REG_P (XEXP (op1, 0))
22060 : 22337 : && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
22061 : 22337 : && REGNO (XEXP (op1, 0)) == FLAGS_REG
22062 : 47084691 : && XEXP (op1, 1) == const0_rtx)
22063 : : {
22064 : : /* This is *setcc_qi_addqi3_cconly_overflow_1_* patterns, a nop. */
22065 : 22337 : *total = 0;
22066 : 22337 : return true;
22067 : : }
22068 : : /* Match x
22069 : : (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
22070 : : (geu:QI (reg:CCC FLAGS_REG) (const_int 0))) */
22071 : 47040017 : if (mode == CCCmode
22072 : 327755 : && GET_CODE (op0) == NEG
22073 : 675 : && GET_CODE (XEXP (op0, 0)) == LTU
22074 : 395 : && REG_P (XEXP (XEXP (op0, 0), 0))
22075 : 395 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
22076 : 3 : && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
22077 : 3 : && XEXP (XEXP (op0, 0), 1) == const0_rtx
22078 : 3 : && GET_CODE (op1) == GEU
22079 : 3 : && REG_P (XEXP (op1, 0))
22080 : 3 : && GET_MODE (XEXP (op1, 0)) == CCCmode
22081 : 3 : && REGNO (XEXP (op1, 0)) == FLAGS_REG
22082 : 47040020 : && XEXP (op1, 1) == const0_rtx)
22083 : : {
22084 : : /* This is *x86_cmc. */
22085 : 3 : if (!speed)
22086 : 0 : *total = COSTS_N_BYTES (1);
22087 : 3 : else if (TARGET_SLOW_STC)
22088 : 0 : *total = COSTS_N_INSNS (2);
22089 : : else
22090 : 3 : *total = COSTS_N_INSNS (1);
22091 : 3 : return true;
22092 : : }
22093 : :
22094 : 47040014 : if (SCALAR_INT_MODE_P (GET_MODE (op0))
22095 : 98004642 : && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
22096 : : {
22097 : 691521 : if (op1 == const0_rtx)
22098 : 220556 : *total = cost->add
22099 : 110278 : + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed);
22100 : : else
22101 : 1162486 : *total = 3*cost->add
22102 : 581243 : + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed)
22103 : 581243 : + rtx_cost (op1, GET_MODE (op0), outer_code, opno, speed);
22104 : 691521 : return true;
22105 : : }
22106 : :
22107 : : /* The embedded comparison operand is completely free. */
22108 : 46348493 : if (!general_operand (op0, GET_MODE (op0)) && op1 == const0_rtx)
22109 : 303786 : *total = 0;
22110 : :
22111 : : return false;
22112 : :
22113 : 1280605 : case FLOAT_EXTEND:
22114 : 1280605 : if (!SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
22115 : 644299 : *total = 0;
22116 : : else
22117 : 636306 : *total = ix86_vec_cost (mode, cost->addss);
22118 : : return false;
22119 : :
22120 : 79222 : case FLOAT_TRUNCATE:
22121 : 79222 : if (!SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
22122 : 54114 : *total = cost->fadd;
22123 : : else
22124 : 25108 : *total = ix86_vec_cost (mode, cost->addss);
22125 : : return false;
22126 : :
22127 : 302809 : case ABS:
22128 : : /* SSE requires memory load for the constant operand. It may make
22129 : : sense to account for this. Of course the constant operand may or
22130 : : may not be reused. */
22131 : 302809 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
22132 : 213439 : *total = cost->sse_op;
22133 : 89370 : else if (X87_FLOAT_MODE_P (mode))
22134 : 32336 : *total = cost->fabs;
22135 : 57034 : else if (FLOAT_MODE_P (mode))
22136 : 23493 : *total = ix86_vec_cost (mode, cost->sse_op);
22137 : : return false;
22138 : :
22139 : 25701 : case SQRT:
22140 : 25701 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
22141 : 17662 : *total = mode == SFmode ? cost->sqrtss : cost->sqrtsd;
22142 : 8039 : else if (X87_FLOAT_MODE_P (mode))
22143 : 4239 : *total = cost->fsqrt;
22144 : 3800 : else if (FLOAT_MODE_P (mode))
22145 : 3800 : *total = ix86_vec_cost (mode,
22146 : : mode == SFmode ? cost->sqrtss : cost->sqrtsd);
22147 : : return false;
22148 : :
22149 : 3574439 : case UNSPEC:
22150 : 3574439 : if (XINT (x, 1) == UNSPEC_TP)
22151 : 114540 : *total = 0;
22152 : 3459899 : else if (XINT (x, 1) == UNSPEC_VTERNLOG)
22153 : : {
22154 : 2516 : *total = cost->sse_op;
22155 : 2516 : return true;
22156 : : }
22157 : 3457383 : else if (XINT (x, 1) == UNSPEC_PTEST)
22158 : : {
22159 : 43416 : *total = cost->sse_op;
22160 : 43416 : rtx test_op0 = XVECEXP (x, 0, 0);
22161 : 43416 : if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
22162 : : return false;
22163 : 42763 : if (GET_CODE (test_op0) == AND)
22164 : : {
22165 : 25 : rtx and_op0 = XEXP (test_op0, 0);
22166 : 25 : if (GET_CODE (and_op0) == NOT)
22167 : 0 : and_op0 = XEXP (and_op0, 0);
22168 : 25 : *total += rtx_cost (and_op0, GET_MODE (and_op0),
22169 : : AND, 0, speed)
22170 : 25 : + rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
22171 : : AND, 1, speed);
22172 : : }
22173 : : else
22174 : 42738 : *total = rtx_cost (test_op0, GET_MODE (test_op0),
22175 : : UNSPEC, 0, speed);
22176 : 42763 : return true;
22177 : : }
22178 : : return false;
22179 : :
22180 : 5345965 : case VEC_SELECT:
22181 : 5345965 : case VEC_CONCAT:
22182 : 5345965 : case VEC_DUPLICATE:
22183 : : /* ??? Assume all of these vector manipulation patterns are
22184 : : recognizable. In which case they all pretty much have the
22185 : : same cost. */
22186 : 5345965 : *total = cost->sse_op;
22187 : 5345965 : return true;
22188 : 579002 : case VEC_MERGE:
22189 : 579002 : mask = XEXP (x, 2);
22190 : : /* This is masked instruction, assume the same cost,
22191 : : as nonmasked variant. */
22192 : 579002 : if (TARGET_AVX512F && register_operand (mask, GET_MODE (mask)))
22193 : 333609 : *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed);
22194 : : else
22195 : 245393 : *total = cost->sse_op;
22196 : : return true;
22197 : :
22198 : 92891087 : case MEM:
22199 : : /* An insn that accesses memory is slightly more expensive
22200 : : than one that does not. */
22201 : 92891087 : if (speed)
22202 : 83612249 : *total += 1;
22203 : : return false;
22204 : :
22205 : 50810 : case ZERO_EXTRACT:
22206 : 50810 : if (XEXP (x, 1) == const1_rtx
22207 : 9689 : && GET_CODE (XEXP (x, 2)) == ZERO_EXTEND
22208 : 9689 : && GET_MODE (XEXP (x, 2)) == SImode
22209 : 0 : && GET_MODE (XEXP (XEXP (x, 2), 0)) == QImode)
22210 : : {
22211 : : /* Ignore cost of zero extension and masking of last argument. */
22212 : 0 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
22213 : 0 : *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
22214 : 0 : *total += rtx_cost (XEXP (XEXP (x, 2), 0), mode, code, 2, speed);
22215 : 0 : return true;
22216 : : }
22217 : : return false;
22218 : :
22219 : 23689518 : case IF_THEN_ELSE:
22220 : 23689518 : if (TARGET_XOP
22221 : 17420 : && VECTOR_MODE_P (mode)
22222 : 23695639 : && (GET_MODE_SIZE (mode) == 16 || GET_MODE_SIZE (mode) == 32))
22223 : : {
22224 : : /* vpcmov. */
22225 : 5053 : *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (6);
22226 : 5053 : if (!REG_P (XEXP (x, 0)))
22227 : 4819 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
22228 : 5053 : if (!REG_P (XEXP (x, 1)))
22229 : 4782 : *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
22230 : 5053 : if (!REG_P (XEXP (x, 2)))
22231 : 4806 : *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
22232 : 5053 : return true;
22233 : : }
22234 : 0 : else if (TARGET_CMOVE
22235 : 23684465 : && SCALAR_INT_MODE_P (mode)
22236 : 25290670 : && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
22237 : : {
22238 : : /* cmov. */
22239 : 1486561 : *total = COSTS_N_INSNS (1);
22240 : 1486561 : if (!REG_P (XEXP (x, 0)))
22241 : 1486561 : *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
22242 : 1486561 : if (!REG_P (XEXP (x, 1)))
22243 : 79262 : *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
22244 : 1486561 : if (!REG_P (XEXP (x, 2)))
22245 : 512912 : *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
22246 : 1486561 : return true;
22247 : : }
22248 : : return false;
22249 : :
22250 : : default:
22251 : : return false;
22252 : : }
22253 : : }
22254 : :
22255 : : #if TARGET_MACHO
22256 : :
22257 : : static int current_machopic_label_num;
22258 : :
22259 : : /* Given a symbol name and its associated stub, write out the
22260 : : definition of the stub. */
22261 : :
22262 : : void
22263 : : machopic_output_stub (FILE *file, const char *symb, const char *stub)
22264 : : {
22265 : : unsigned int length;
22266 : : char *binder_name, *symbol_name, lazy_ptr_name[32];
22267 : : int label = ++current_machopic_label_num;
22268 : :
22269 : : /* For 64-bit we shouldn't get here. */
22270 : : gcc_assert (!TARGET_64BIT);
22271 : :
22272 : : /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
22273 : : symb = targetm.strip_name_encoding (symb);
22274 : :
22275 : : length = strlen (stub);
22276 : : binder_name = XALLOCAVEC (char, length + 32);
22277 : : GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
22278 : :
22279 : : length = strlen (symb);
22280 : : symbol_name = XALLOCAVEC (char, length + 32);
22281 : : GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
22282 : :
22283 : : sprintf (lazy_ptr_name, "L%d$lz", label);
22284 : :
22285 : : if (MACHOPIC_ATT_STUB)
22286 : : switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
22287 : : else if (MACHOPIC_PURE)
22288 : : switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
22289 : : else
22290 : : switch_to_section (darwin_sections[machopic_symbol_stub_section]);
22291 : :
22292 : : fprintf (file, "%s:\n", stub);
22293 : : fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
22294 : :
22295 : : if (MACHOPIC_ATT_STUB)
22296 : : {
22297 : : fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
22298 : : }
22299 : : else if (MACHOPIC_PURE)
22300 : : {
22301 : : /* PIC stub. */
22302 : : /* 25-byte PIC stub using "CALL get_pc_thunk". */
22303 : : rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
22304 : : output_set_got (tmp, NULL_RTX); /* "CALL ___<cpu>.get_pc_thunk.cx". */
22305 : : fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
22306 : : label, lazy_ptr_name, label);
22307 : : fprintf (file, "\tjmp\t*%%ecx\n");
22308 : : }
22309 : : else
22310 : : fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
22311 : :
22312 : : /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
22313 : : it needs no stub-binding-helper. */
22314 : : if (MACHOPIC_ATT_STUB)
22315 : : return;
22316 : :
22317 : : fprintf (file, "%s:\n", binder_name);
22318 : :
22319 : : if (MACHOPIC_PURE)
22320 : : {
22321 : : fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
22322 : : fprintf (file, "\tpushl\t%%ecx\n");
22323 : : }
22324 : : else
22325 : : fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
22326 : :
22327 : : fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
22328 : :
22329 : : /* N.B. Keep the correspondence of these
22330 : : 'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
22331 : : old-pic/new-pic/non-pic stubs; altering this will break
22332 : : compatibility with existing dylibs. */
22333 : : if (MACHOPIC_PURE)
22334 : : {
22335 : : /* 25-byte PIC stub using "CALL get_pc_thunk". */
22336 : : switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
22337 : : }
22338 : : else
22339 : : /* 16-byte -mdynamic-no-pic stub. */
22340 : : switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
22341 : :
22342 : : fprintf (file, "%s:\n", lazy_ptr_name);
22343 : : fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
22344 : : fprintf (file, ASM_LONG "%s\n", binder_name);
22345 : : }
22346 : : #endif /* TARGET_MACHO */
22347 : :
22348 : : /* Order the registers for register allocator. */
22349 : :
22350 : : void
22351 : 208054 : x86_order_regs_for_local_alloc (void)
22352 : : {
22353 : 208054 : int pos = 0;
22354 : 208054 : int i;
22355 : :
22356 : : /* First allocate the local general purpose registers. */
22357 : 19349022 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
22358 : 25798696 : if (GENERAL_REGNO_P (i) && call_used_or_fixed_reg_p (i))
22359 : 5418561 : reg_alloc_order [pos++] = i;
22360 : :
22361 : : /* Global general purpose registers. */
22362 : 19349022 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
22363 : 22218841 : if (GENERAL_REGNO_P (i) && !call_used_or_fixed_reg_p (i))
22364 : 1239167 : reg_alloc_order [pos++] = i;
22365 : :
22366 : : /* x87 registers come first in case we are doing FP math
22367 : : using them. */
22368 : 208054 : if (!TARGET_SSE_MATH)
22369 : 55530 : for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
22370 : 49360 : reg_alloc_order [pos++] = i;
22371 : :
22372 : : /* SSE registers. */
22373 : 1872486 : for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
22374 : 1664432 : reg_alloc_order [pos++] = i;
22375 : 1872486 : for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
22376 : 1664432 : reg_alloc_order [pos++] = i;
22377 : :
22378 : : /* Extended REX SSE registers. */
22379 : 3536918 : for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
22380 : 3328864 : reg_alloc_order [pos++] = i;
22381 : :
22382 : : /* Mask register. */
22383 : 1872486 : for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
22384 : 1664432 : reg_alloc_order [pos++] = i;
22385 : :
22386 : : /* x87 registers. */
22387 : 208054 : if (TARGET_SSE_MATH)
22388 : 1816956 : for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
22389 : 1615072 : reg_alloc_order [pos++] = i;
22390 : :
22391 : 1872486 : for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
22392 : 1664432 : reg_alloc_order [pos++] = i;
22393 : :
22394 : : /* Initialize the rest of array as we do not allocate some registers
22395 : : at all. */
22396 : 1040270 : while (pos < FIRST_PSEUDO_REGISTER)
22397 : 832216 : reg_alloc_order [pos++] = 0;
22398 : 208054 : }
22399 : :
22400 : : static bool
22401 : 196867558 : ix86_ms_bitfield_layout_p (const_tree record_type)
22402 : : {
22403 : 196867558 : return ((TARGET_MS_BITFIELD_LAYOUT
22404 : 215 : && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
22405 : 196867558 : || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
22406 : : }
22407 : :
22408 : : /* Returns an expression indicating where the this parameter is
22409 : : located on entry to the FUNCTION. */
22410 : :
22411 : : static rtx
22412 : 2268 : x86_this_parameter (tree function)
22413 : : {
22414 : 2268 : tree type = TREE_TYPE (function);
22415 : 2268 : bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
22416 : 2268 : int nregs;
22417 : :
22418 : 2268 : if (TARGET_64BIT)
22419 : : {
22420 : 2266 : const int *parm_regs;
22421 : :
22422 : 2266 : if (ix86_function_type_abi (type) == MS_ABI)
22423 : : parm_regs = x86_64_ms_abi_int_parameter_registers;
22424 : : else
22425 : 2266 : parm_regs = x86_64_int_parameter_registers;
22426 : 2266 : return gen_rtx_REG (Pmode, parm_regs[aggr]);
22427 : : }
22428 : :
22429 : 2 : nregs = ix86_function_regparm (type, function);
22430 : :
22431 : 2 : if (nregs > 0 && !stdarg_p (type))
22432 : : {
22433 : 0 : int regno;
22434 : 0 : unsigned int ccvt = ix86_get_callcvt (type);
22435 : :
22436 : 0 : if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
22437 : 0 : regno = aggr ? DX_REG : CX_REG;
22438 : 0 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
22439 : : {
22440 : 0 : regno = CX_REG;
22441 : 0 : if (aggr)
22442 : 0 : return gen_rtx_MEM (SImode,
22443 : 0 : plus_constant (Pmode, stack_pointer_rtx, 4));
22444 : : }
22445 : : else
22446 : : {
22447 : 0 : regno = AX_REG;
22448 : 0 : if (aggr)
22449 : : {
22450 : 0 : regno = DX_REG;
22451 : 0 : if (nregs == 1)
22452 : 0 : return gen_rtx_MEM (SImode,
22453 : 0 : plus_constant (Pmode,
22454 : 0 : stack_pointer_rtx, 4));
22455 : : }
22456 : : }
22457 : 0 : return gen_rtx_REG (SImode, regno);
22458 : : }
22459 : :
22460 : 2 : return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
22461 : 4 : aggr ? 8 : 4));
22462 : : }
22463 : :
22464 : : /* Determine whether x86_output_mi_thunk can succeed. */
22465 : :
22466 : : static bool
22467 : 6067 : x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
22468 : : const_tree function)
22469 : : {
22470 : : /* 64-bit can handle anything. */
22471 : 6067 : if (TARGET_64BIT)
22472 : : return true;
22473 : :
22474 : : /* For 32-bit, everything's fine if we have one free register. */
22475 : 76 : if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
22476 : : return true;
22477 : :
22478 : : /* Need a free register for vcall_offset. */
22479 : 0 : if (vcall_offset)
22480 : : return false;
22481 : :
22482 : : /* Need a free register for GOT references. */
22483 : 0 : if (flag_pic && !targetm.binds_local_p (function))
22484 : : return false;
22485 : :
22486 : : /* Otherwise ok. */
22487 : : return true;
22488 : : }
22489 : :
22490 : : /* Output the assembler code for a thunk function. THUNK_DECL is the
22491 : : declaration for the thunk function itself, FUNCTION is the decl for
22492 : : the target function. DELTA is an immediate constant offset to be
22493 : : added to THIS. If VCALL_OFFSET is nonzero, the word at
22494 : : *(*this + vcall_offset) should be added to THIS. */
22495 : :
22496 : : static void
22497 : 2268 : x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
22498 : : HOST_WIDE_INT vcall_offset, tree function)
22499 : : {
22500 : 2268 : const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
22501 : 2268 : rtx this_param = x86_this_parameter (function);
22502 : 2268 : rtx this_reg, tmp, fnaddr;
22503 : 2268 : unsigned int tmp_regno;
22504 : 2268 : rtx_insn *insn;
22505 : 2268 : int saved_flag_force_indirect_call = flag_force_indirect_call;
22506 : :
22507 : 2268 : if (TARGET_64BIT)
22508 : : tmp_regno = R10_REG;
22509 : : else
22510 : : {
22511 : 2 : unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
22512 : 2 : if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
22513 : : tmp_regno = AX_REG;
22514 : 2 : else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
22515 : : tmp_regno = DX_REG;
22516 : : else
22517 : 2 : tmp_regno = CX_REG;
22518 : :
22519 : 2 : if (flag_pic)
22520 : 2 : flag_force_indirect_call = 0;
22521 : : }
22522 : :
22523 : 2268 : emit_note (NOTE_INSN_PROLOGUE_END);
22524 : :
22525 : : /* CET is enabled, insert EB instruction. */
22526 : 2268 : if ((flag_cf_protection & CF_BRANCH))
22527 : 20 : emit_insn (gen_nop_endbr ());
22528 : :
22529 : : /* If VCALL_OFFSET, we'll need THIS in a register. Might as well
22530 : : pull it in now and let DELTA benefit. */
22531 : 2268 : if (REG_P (this_param))
22532 : : this_reg = this_param;
22533 : 2 : else if (vcall_offset)
22534 : : {
22535 : : /* Put the this parameter into %eax. */
22536 : 1 : this_reg = gen_rtx_REG (Pmode, AX_REG);
22537 : 1 : emit_move_insn (this_reg, this_param);
22538 : : }
22539 : : else
22540 : : this_reg = NULL_RTX;
22541 : :
22542 : : /* Adjust the this parameter by a fixed constant. */
22543 : 2268 : if (delta)
22544 : : {
22545 : 1068 : rtx delta_rtx = GEN_INT (delta);
22546 : 1068 : rtx delta_dst = this_reg ? this_reg : this_param;
22547 : :
22548 : 1068 : if (TARGET_64BIT)
22549 : : {
22550 : 1067 : if (!x86_64_general_operand (delta_rtx, Pmode))
22551 : : {
22552 : 0 : tmp = gen_rtx_REG (Pmode, tmp_regno);
22553 : 0 : emit_move_insn (tmp, delta_rtx);
22554 : 0 : delta_rtx = tmp;
22555 : : }
22556 : : }
22557 : :
22558 : 1068 : ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
22559 : : }
22560 : :
22561 : : /* Adjust the this parameter by a value stored in the vtable. */
22562 : 2268 : if (vcall_offset)
22563 : : {
22564 : 1268 : rtx vcall_addr, vcall_mem, this_mem;
22565 : :
22566 : 1268 : tmp = gen_rtx_REG (Pmode, tmp_regno);
22567 : :
22568 : 1268 : this_mem = gen_rtx_MEM (ptr_mode, this_reg);
22569 : 1268 : if (Pmode != ptr_mode)
22570 : 0 : this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
22571 : 1268 : emit_move_insn (tmp, this_mem);
22572 : :
22573 : : /* Adjust the this parameter. */
22574 : 1268 : vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
22575 : 1268 : if (TARGET_64BIT
22576 : 1268 : && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
22577 : : {
22578 : 0 : rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
22579 : 0 : emit_move_insn (tmp2, GEN_INT (vcall_offset));
22580 : 0 : vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
22581 : : }
22582 : :
22583 : 1268 : vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
22584 : 1268 : if (Pmode != ptr_mode)
22585 : 0 : emit_insn (gen_addsi_1_zext (this_reg,
22586 : : gen_rtx_REG (ptr_mode,
22587 : : REGNO (this_reg)),
22588 : : vcall_mem));
22589 : : else
22590 : 1268 : ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
22591 : : }
22592 : :
22593 : : /* If necessary, drop THIS back to its stack slot. */
22594 : 2268 : if (this_reg && this_reg != this_param)
22595 : 1 : emit_move_insn (this_param, this_reg);
22596 : :
22597 : 2268 : fnaddr = XEXP (DECL_RTL (function), 0);
22598 : 2268 : if (TARGET_64BIT)
22599 : : {
22600 : 29 : if (!flag_pic || targetm.binds_local_p (function)
22601 : 2295 : || TARGET_PECOFF)
22602 : : ;
22603 : : else
22604 : : {
22605 : 0 : tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
22606 : 0 : tmp = gen_rtx_CONST (Pmode, tmp);
22607 : 0 : fnaddr = gen_const_mem (Pmode, tmp);
22608 : : }
22609 : : }
22610 : : else
22611 : : {
22612 : 2 : if (!flag_pic || targetm.binds_local_p (function))
22613 : : ;
22614 : : #if TARGET_MACHO
22615 : : else if (TARGET_MACHO)
22616 : : {
22617 : : fnaddr = machopic_indirect_call_target (DECL_RTL (function));
22618 : : fnaddr = XEXP (fnaddr, 0);
22619 : : }
22620 : : #endif /* TARGET_MACHO */
22621 : : else
22622 : : {
22623 : 0 : tmp = gen_rtx_REG (Pmode, CX_REG);
22624 : 0 : output_set_got (tmp, NULL_RTX);
22625 : :
22626 : 0 : fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
22627 : 0 : fnaddr = gen_rtx_CONST (Pmode, fnaddr);
22628 : 0 : fnaddr = gen_rtx_PLUS (Pmode, tmp, fnaddr);
22629 : 0 : fnaddr = gen_const_mem (Pmode, fnaddr);
22630 : : }
22631 : : }
22632 : :
22633 : : /* Our sibling call patterns do not allow memories, because we have no
22634 : : predicate that can distinguish between frame and non-frame memory.
22635 : : For our purposes here, we can get away with (ab)using a jump pattern,
22636 : : because we're going to do no optimization. */
22637 : 2268 : if (MEM_P (fnaddr))
22638 : : {
22639 : 0 : if (sibcall_insn_operand (fnaddr, word_mode))
22640 : : {
22641 : 0 : fnaddr = XEXP (DECL_RTL (function), 0);
22642 : 0 : tmp = gen_rtx_MEM (QImode, fnaddr);
22643 : 0 : tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
22644 : 0 : tmp = emit_call_insn (tmp);
22645 : 0 : SIBLING_CALL_P (tmp) = 1;
22646 : : }
22647 : : else
22648 : 0 : emit_jump_insn (gen_indirect_jump (fnaddr));
22649 : : }
22650 : : else
22651 : : {
22652 : 2268 : if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
22653 : : {
22654 : : // CM_LARGE_PIC always uses pseudo PIC register which is
22655 : : // uninitialized. Since FUNCTION is local and calling it
22656 : : // doesn't go through PLT, we use scratch register %r11 as
22657 : : // PIC register and initialize it here.
22658 : 4 : pic_offset_table_rtx = gen_rtx_REG (Pmode, R11_REG);
22659 : 4 : ix86_init_large_pic_reg (tmp_regno);
22660 : 4 : fnaddr = legitimize_pic_address (fnaddr,
22661 : 4 : gen_rtx_REG (Pmode, tmp_regno));
22662 : : }
22663 : :
22664 : 2268 : if (!sibcall_insn_operand (fnaddr, word_mode))
22665 : : {
22666 : 12 : tmp = gen_rtx_REG (word_mode, tmp_regno);
22667 : 12 : if (GET_MODE (fnaddr) != word_mode)
22668 : 0 : fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
22669 : 12 : emit_move_insn (tmp, fnaddr);
22670 : 12 : fnaddr = tmp;
22671 : : }
22672 : :
22673 : 2268 : tmp = gen_rtx_MEM (QImode, fnaddr);
22674 : 2268 : tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
22675 : 2268 : tmp = emit_call_insn (tmp);
22676 : 2268 : SIBLING_CALL_P (tmp) = 1;
22677 : : }
22678 : 2268 : emit_barrier ();
22679 : :
22680 : : /* Emit just enough of rest_of_compilation to get the insns emitted. */
22681 : 2268 : insn = get_insns ();
22682 : 2268 : shorten_branches (insn);
22683 : 2268 : assemble_start_function (thunk_fndecl, fnname);
22684 : 2268 : final_start_function (insn, file, 1);
22685 : 2268 : final (insn, file, 1);
22686 : 2268 : final_end_function ();
22687 : 2268 : assemble_end_function (thunk_fndecl, fnname);
22688 : :
22689 : 2268 : flag_force_indirect_call = saved_flag_force_indirect_call;
22690 : 2268 : }
22691 : :
22692 : : static void
22693 : 265705 : x86_file_start (void)
22694 : : {
22695 : 265705 : default_file_start ();
22696 : 265705 : if (TARGET_16BIT)
22697 : 6 : fputs ("\t.code16gcc\n", asm_out_file);
22698 : : #if TARGET_MACHO
22699 : : darwin_file_start ();
22700 : : #endif
22701 : 265705 : if (X86_FILE_START_VERSION_DIRECTIVE)
22702 : : fputs ("\t.version\t\"01.01\"\n", asm_out_file);
22703 : 265705 : if (X86_FILE_START_FLTUSED)
22704 : : fputs ("\t.global\t__fltused\n", asm_out_file);
22705 : 265705 : if (ix86_asm_dialect == ASM_INTEL)
22706 : 47 : fputs ("\t.intel_syntax noprefix\n", asm_out_file);
22707 : 265705 : }
22708 : :
22709 : : int
22710 : 82398960 : x86_field_alignment (tree type, int computed)
22711 : : {
22712 : 82398960 : machine_mode mode;
22713 : :
22714 : 82398960 : if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
22715 : : return computed;
22716 : 8606937 : if (TARGET_IAMCU)
22717 : 0 : return iamcu_alignment (type, computed);
22718 : 8606937 : type = strip_array_types (type);
22719 : 8606937 : mode = TYPE_MODE (type);
22720 : 8606937 : if (mode == DFmode || mode == DCmode
22721 : 8504712 : || GET_MODE_CLASS (mode) == MODE_INT
22722 : 2936048 : || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
22723 : : {
22724 : 5670889 : if (TYPE_ATOMIC (type) && computed > 32)
22725 : : {
22726 : 0 : static bool warned;
22727 : :
22728 : 0 : if (!warned && warn_psabi)
22729 : : {
22730 : 0 : const char *url
22731 : : = CHANGES_ROOT_URL "gcc-11/changes.html#ia32_atomic";
22732 : :
22733 : 0 : warned = true;
22734 : 0 : inform (input_location, "the alignment of %<_Atomic %T%> "
22735 : : "fields changed in %{GCC 11.1%}",
22736 : 0 : TYPE_MAIN_VARIANT (type), url);
22737 : : }
22738 : : }
22739 : : else
22740 : 5670889 : return MIN (32, computed);
22741 : : }
22742 : : return computed;
22743 : : }
22744 : :
22745 : : /* Print call to TARGET to FILE. */
22746 : :
22747 : : static void
22748 : 401 : x86_print_call_or_nop (FILE *file, const char *target)
22749 : : {
22750 : 401 : if (flag_nop_mcount || !strcmp (target, "nop"))
22751 : : /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
22752 : 5 : fprintf (file, "1:" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
22753 : : else
22754 : 396 : fprintf (file, "1:\tcall\t%s\n", target);
22755 : 401 : }
22756 : :
22757 : : static bool
22758 : 415 : current_fentry_name (const char **name)
22759 : : {
22760 : 415 : tree attr = lookup_attribute ("fentry_name",
22761 : 415 : DECL_ATTRIBUTES (current_function_decl));
22762 : 415 : if (!attr)
22763 : : return false;
22764 : 2 : *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
22765 : 2 : return true;
22766 : : }
22767 : :
22768 : : static bool
22769 : 10 : current_fentry_section (const char **name)
22770 : : {
22771 : 10 : tree attr = lookup_attribute ("fentry_section",
22772 : 10 : DECL_ATTRIBUTES (current_function_decl));
22773 : 10 : if (!attr)
22774 : : return false;
22775 : 2 : *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
22776 : 2 : return true;
22777 : : }
22778 : :
22779 : : /* Return a caller-saved register which isn't live or a callee-saved
22780 : : register which has been saved on stack in the prologue at entry for
22781 : : profile. */
22782 : :
22783 : : static int
22784 : 13 : x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
22785 : : {
22786 : : /* Use %r10 if the profiler is emitted before the prologue or it isn't
22787 : : used by DRAP. */
22788 : 13 : if (ix86_profile_before_prologue ()
22789 : 9 : || !crtl->drap_reg
22790 : 16 : || REGNO (crtl->drap_reg) != R10_REG)
22791 : : return R10_REG;
22792 : :
22793 : : /* The profiler is emitted after the prologue. If there is a
22794 : : caller-saved register which isn't live or a callee-saved
22795 : : register saved on stack in the prologue, use it. */
22796 : :
22797 : 3 : bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
22798 : :
22799 : 3 : int i;
22800 : 88 : for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
22801 : 56 : if (GENERAL_REGNO_P (i)
22802 : 29 : && i != R10_REG
22803 : : #ifdef NO_PROFILE_COUNTERS
22804 : 27 : && (r11_ok || i != R11_REG)
22805 : : #else
22806 : : && i != R11_REG
22807 : : #endif
22808 : 26 : && TEST_HARD_REG_BIT (accessible_reg_set, i)
22809 : 111 : && (ix86_save_reg (i, true, true)
22810 : 25 : || (call_used_regs[i]
22811 : 18 : && !fixed_regs[i]
22812 : 16 : && !REGNO_REG_SET_P (reg_live, i))))
22813 : 3 : return i;
22814 : :
22815 : 0 : sorry ("no register available for profiling %<-mcmodel=large%s%>",
22816 : 0 : ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
22817 : :
22818 : 0 : return R10_REG;
22819 : : }
22820 : :
22821 : : /* Output assembler code to FILE to increment profiler label # LABELNO
22822 : : for profiling a function entry. */
22823 : : void
22824 : 415 : x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
22825 : : {
22826 : 415 : if (cfun->machine->insn_queued_at_entrance)
22827 : : {
22828 : 5 : if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
22829 : 4 : fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
22830 : 5 : unsigned int patch_area_size
22831 : 5 : = crtl->patch_area_size - crtl->patch_area_entry;
22832 : 5 : if (patch_area_size)
22833 : 2 : ix86_output_patchable_area (patch_area_size,
22834 : : crtl->patch_area_entry == 0);
22835 : : }
22836 : :
22837 : 415 : const char *mcount_name = MCOUNT_NAME;
22838 : :
22839 : 415 : if (current_fentry_name (&mcount_name))
22840 : : ;
22841 : 413 : else if (fentry_name)
22842 : 1 : mcount_name = fentry_name;
22843 : 412 : else if (flag_fentry)
22844 : 21 : mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
22845 : :
22846 : 415 : if (TARGET_64BIT)
22847 : : {
22848 : : #ifndef NO_PROFILE_COUNTERS
22849 : : if (ASSEMBLER_DIALECT == ASM_INTEL)
22850 : : fprintf (file, "\tlea\tr11, %sP%d[rip]\n", LPREFIX, labelno);
22851 : : else
22852 : : fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
22853 : : #endif
22854 : :
22855 : 415 : int scratch;
22856 : 415 : const char *reg;
22857 : 415 : char legacy_reg[4] = { 0 };
22858 : :
22859 : 415 : if (!TARGET_PECOFF)
22860 : : {
22861 : 415 : switch (ix86_cmodel)
22862 : : {
22863 : 5 : case CM_LARGE:
22864 : 5 : scratch = x86_64_select_profile_regnum (true);
22865 : 5 : reg = hi_reg_name[scratch];
22866 : 5 : if (LEGACY_INT_REGNO_P (scratch))
22867 : : {
22868 : 0 : legacy_reg[0] = 'r';
22869 : 0 : legacy_reg[1] = reg[0];
22870 : 0 : legacy_reg[2] = reg[1];
22871 : 0 : reg = legacy_reg;
22872 : : }
22873 : 5 : if (ASSEMBLER_DIALECT == ASM_INTEL)
22874 : 1 : fprintf (file, "1:\tmovabs\t%s, OFFSET FLAT:%s\n"
22875 : : "\tcall\t%s\n", reg, mcount_name, reg);
22876 : : else
22877 : 4 : fprintf (file, "1:\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n",
22878 : : mcount_name, reg, reg);
22879 : : break;
22880 : 8 : case CM_LARGE_PIC:
22881 : : #ifdef NO_PROFILE_COUNTERS
22882 : 8 : scratch = x86_64_select_profile_regnum (false);
22883 : 8 : reg = hi_reg_name[scratch];
22884 : 8 : if (LEGACY_INT_REGNO_P (scratch))
22885 : : {
22886 : 1 : legacy_reg[0] = 'r';
22887 : 1 : legacy_reg[1] = reg[0];
22888 : 1 : legacy_reg[2] = reg[1];
22889 : 1 : reg = legacy_reg;
22890 : : }
22891 : 8 : if (ASSEMBLER_DIALECT == ASM_INTEL)
22892 : : {
22893 : 1 : fprintf (file, "1:movabs\tr11, "
22894 : : "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
22895 : 1 : fprintf (file, "\tlea\t%s, 1b[rip]\n", reg);
22896 : 1 : fprintf (file, "\tadd\t%s, r11\n", reg);
22897 : 1 : fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
22898 : : mcount_name);
22899 : 1 : fprintf (file, "\tadd\t%s, r11\n", reg);
22900 : 1 : fprintf (file, "\tcall\t%s\n", reg);
22901 : 1 : break;
22902 : : }
22903 : 7 : fprintf (file,
22904 : : "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
22905 : 7 : fprintf (file, "\tleaq\t1b(%%rip), %%%s\n", reg);
22906 : 7 : fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
22907 : 7 : fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
22908 : 7 : fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
22909 : 7 : fprintf (file, "\tcall\t*%%%s\n", reg);
22910 : : #else
22911 : : sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
22912 : : #endif
22913 : 7 : break;
22914 : 5 : case CM_SMALL_PIC:
22915 : 5 : case CM_MEDIUM_PIC:
22916 : 5 : if (!ix86_direct_extern_access)
22917 : : {
22918 : 1 : if (ASSEMBLER_DIALECT == ASM_INTEL)
22919 : 1 : fprintf (file, "1:\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n",
22920 : : mcount_name);
22921 : : else
22922 : 0 : fprintf (file, "1:\tcall\t*%s@GOTPCREL(%%rip)\n",
22923 : : mcount_name);
22924 : : break;
22925 : : }
22926 : : /* fall through */
22927 : 401 : default:
22928 : 401 : x86_print_call_or_nop (file, mcount_name);
22929 : 401 : break;
22930 : : }
22931 : : }
22932 : : else
22933 : : x86_print_call_or_nop (file, mcount_name);
22934 : : }
22935 : 0 : else if (flag_pic)
22936 : : {
22937 : : #ifndef NO_PROFILE_COUNTERS
22938 : : if (ASSEMBLER_DIALECT == ASM_INTEL)
22939 : : fprintf (file,
22940 : : "\tlea\t" PROFILE_COUNT_REGISTER ", %sP%d@GOTOFF[ebx]\n",
22941 : : LPREFIX, labelno);
22942 : : else
22943 : : fprintf (file,
22944 : : "\tleal\t%sP%d@GOTOFF(%%ebx), %%" PROFILE_COUNT_REGISTER "\n",
22945 : : LPREFIX, labelno);
22946 : : #endif
22947 : 0 : if (ASSEMBLER_DIALECT == ASM_INTEL)
22948 : 0 : fprintf (file, "1:\tcall\t[DWORD PTR %s@GOT[ebx]]\n", mcount_name);
22949 : : else
22950 : 0 : fprintf (file, "1:\tcall\t*%s@GOT(%%ebx)\n", mcount_name);
22951 : : }
22952 : : else
22953 : : {
22954 : : #ifndef NO_PROFILE_COUNTERS
22955 : : if (ASSEMBLER_DIALECT == ASM_INTEL)
22956 : : fprintf (file,
22957 : : "\tmov\t" PROFILE_COUNT_REGISTER ", OFFSET FLAT:%sP%d\n",
22958 : : LPREFIX, labelno);
22959 : : else
22960 : : fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n",
22961 : : LPREFIX, labelno);
22962 : : #endif
22963 : 0 : x86_print_call_or_nop (file, mcount_name);
22964 : : }
22965 : :
22966 : 415 : if (flag_record_mcount
22967 : 821 : || lookup_attribute ("fentry_section",
22968 : 406 : DECL_ATTRIBUTES (current_function_decl)))
22969 : : {
22970 : 10 : const char *sname = "__mcount_loc";
22971 : :
22972 : 10 : if (current_fentry_section (&sname))
22973 : : ;
22974 : 8 : else if (fentry_section)
22975 : 1 : sname = fentry_section;
22976 : :
22977 : 10 : fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
22978 : 10 : fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
22979 : 10 : fprintf (file, "\t.previous\n");
22980 : : }
22981 : 415 : }
22982 : :
22983 : : /* We don't have exact information about the insn sizes, but we may assume
22984 : : quite safely that we are informed about all 1 byte insns and memory
22985 : : address sizes. This is enough to eliminate unnecessary padding in
22986 : : 99% of cases. */
22987 : :
22988 : : int
22989 : 320858854 : ix86_min_insn_size (rtx_insn *insn)
22990 : : {
22991 : 320858854 : int l = 0, len;
22992 : :
22993 : 320858854 : if (!INSN_P (insn) || !active_insn_p (insn))
22994 : 471795 : return 0;
22995 : :
22996 : : /* Discard alignments we've emit and jump instructions. */
22997 : 320387059 : if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
22998 : 320387059 : && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
22999 : : return 0;
23000 : :
23001 : : /* Important case - calls are always 5 bytes.
23002 : : It is common to have many calls in the row. */
23003 : 320387054 : if (CALL_P (insn)
23004 : 8304159 : && symbolic_reference_mentioned_p (PATTERN (insn))
23005 : 328383114 : && !SIBLING_CALL_P (insn))
23006 : : return 5;
23007 : 312599020 : len = get_attr_length (insn);
23008 : 312599020 : if (len <= 1)
23009 : : return 1;
23010 : :
23011 : : /* For normal instructions we rely on get_attr_length being exact,
23012 : : with a few exceptions. */
23013 : 303583809 : if (!JUMP_P (insn))
23014 : : {
23015 : 298886411 : enum attr_type type = get_attr_type (insn);
23016 : :
23017 : 298886411 : switch (type)
23018 : : {
23019 : 89384 : case TYPE_MULTI:
23020 : 89384 : if (GET_CODE (PATTERN (insn)) == ASM_INPUT
23021 : 89384 : || asm_noperands (PATTERN (insn)) >= 0)
23022 : 118 : return 0;
23023 : : break;
23024 : : case TYPE_OTHER:
23025 : : case TYPE_FCMP:
23026 : : break;
23027 : : default:
23028 : : /* Otherwise trust get_attr_length. */
23029 : : return len;
23030 : : }
23031 : :
23032 : 443791 : l = get_attr_length_address (insn);
23033 : 443791 : if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
23034 : : l = 4;
23035 : : }
23036 : 356857 : if (l)
23037 : 86934 : return 1+l;
23038 : : else
23039 : 5054255 : return 2;
23040 : : }
23041 : :
23042 : : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
23043 : :
23044 : : /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
23045 : : window. */
23046 : :
23047 : : static void
23048 : 41087 : ix86_avoid_jump_mispredicts (void)
23049 : : {
23050 : 41087 : rtx_insn *insn, *start = get_insns ();
23051 : 41087 : int nbytes = 0, njumps = 0;
23052 : 41087 : bool isjump = false;
23053 : :
23054 : : /* Look for all minimal intervals of instructions containing 4 jumps.
23055 : : The intervals are bounded by START and INSN. NBYTES is the total
23056 : : size of instructions in the interval including INSN and not including
23057 : : START. When the NBYTES is smaller than 16 bytes, it is possible
23058 : : that the end of START and INSN ends up in the same 16byte page.
23059 : :
23060 : : The smallest offset in the page INSN can start is the case where START
23061 : : ends on the offset 0. Offset of INSN is then NBYTES - sizeof (INSN).
23062 : : We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
23063 : :
23064 : : Don't consider asm goto as jump, while it can contain a jump, it doesn't
23065 : : have to, control transfer to label(s) can be performed through other
23066 : : means, and also we estimate minimum length of all asm stmts as 0. */
23067 : 656632 : for (insn = start; insn; insn = NEXT_INSN (insn))
23068 : : {
23069 : 615545 : int min_size;
23070 : :
23071 : 615545 : if (LABEL_P (insn))
23072 : : {
23073 : 1049 : align_flags alignment = label_to_alignment (insn);
23074 : 1049 : int align = alignment.levels[0].log;
23075 : 1049 : int max_skip = alignment.levels[0].maxskip;
23076 : :
23077 : 1049 : if (max_skip > 15)
23078 : : max_skip = 15;
23079 : : /* If align > 3, only up to 16 - max_skip - 1 bytes can be
23080 : : already in the current 16 byte page, because otherwise
23081 : : ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
23082 : : bytes to reach 16 byte boundary. */
23083 : 1049 : if (align <= 0
23084 : 340 : || (align <= 3 && max_skip != (1 << align) - 1))
23085 : 1049 : max_skip = 0;
23086 : 1049 : if (dump_file)
23087 : 0 : fprintf (dump_file, "Label %i with max_skip %i\n",
23088 : 0 : INSN_UID (insn), max_skip);
23089 : 1049 : if (max_skip)
23090 : : {
23091 : 6802 : while (nbytes + max_skip >= 16)
23092 : : {
23093 : 6462 : start = NEXT_INSN (start);
23094 : 332 : if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
23095 : 6480 : || CALL_P (start))
23096 : 362 : njumps--, isjump = true;
23097 : : else
23098 : : isjump = false;
23099 : 6462 : nbytes -= ix86_min_insn_size (start);
23100 : : }
23101 : : }
23102 : 1049 : continue;
23103 : 1049 : }
23104 : :
23105 : 614496 : min_size = ix86_min_insn_size (insn);
23106 : 614496 : nbytes += min_size;
23107 : 614496 : if (dump_file)
23108 : 0 : fprintf (dump_file, "Insn %i estimated to %i bytes\n",
23109 : 0 : INSN_UID (insn), min_size);
23110 : 42365 : if ((JUMP_P (insn) && asm_noperands (PATTERN (insn)) < 0)
23111 : 614516 : || CALL_P (insn))
23112 : 43486 : njumps++;
23113 : : else
23114 : 571010 : continue;
23115 : :
23116 : 53018 : while (njumps > 3)
23117 : : {
23118 : 9532 : start = NEXT_INSN (start);
23119 : 598 : if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
23120 : 9532 : || CALL_P (start))
23121 : 1326 : njumps--, isjump = true;
23122 : : else
23123 : : isjump = false;
23124 : 9532 : nbytes -= ix86_min_insn_size (start);
23125 : : }
23126 : 43486 : gcc_assert (njumps >= 0);
23127 : 43486 : if (dump_file)
23128 : 0 : fprintf (dump_file, "Interval %i to %i has %i bytes\n",
23129 : 0 : INSN_UID (start), INSN_UID (insn), nbytes);
23130 : :
23131 : 43486 : if (njumps == 3 && isjump && nbytes < 16)
23132 : : {
23133 : 55 : int padsize = 15 - nbytes + ix86_min_insn_size (insn);
23134 : :
23135 : 55 : if (dump_file)
23136 : 0 : fprintf (dump_file, "Padding insn %i by %i bytes!\n",
23137 : 0 : INSN_UID (insn), padsize);
23138 : 55 : emit_insn_before (gen_pad (GEN_INT (padsize)), insn);
23139 : : }
23140 : : }
23141 : 41087 : }
23142 : : #endif
23143 : :
23144 : : /* AMD Athlon works faster
23145 : : when RET is not destination of conditional jump or directly preceded
23146 : : by other jump instruction. We avoid the penalty by inserting NOP just
23147 : : before the RET instructions in such cases. */
23148 : : static void
23149 : 40789 : ix86_pad_returns (void)
23150 : : {
23151 : 40789 : edge e;
23152 : 40789 : edge_iterator ei;
23153 : :
23154 : 81606 : FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
23155 : : {
23156 : 40817 : basic_block bb = e->src;
23157 : 40817 : rtx_insn *ret = BB_END (bb);
23158 : 40817 : rtx_insn *prev;
23159 : 40817 : bool replace = false;
23160 : :
23161 : 40804 : if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
23162 : 81621 : || optimize_bb_for_size_p (bb))
23163 : 38 : continue;
23164 : 162083 : for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
23165 : 120887 : if (active_insn_p (prev) || LABEL_P (prev))
23166 : : break;
23167 : 40779 : if (prev && LABEL_P (prev))
23168 : : {
23169 : 69 : edge e;
23170 : 69 : edge_iterator ei;
23171 : :
23172 : 81 : FOR_EACH_EDGE (e, ei, bb->preds)
23173 : 221 : if (EDGE_FREQUENCY (e) && e->src->index >= 0
23174 : 147 : && !(e->flags & EDGE_FALLTHRU))
23175 : : {
23176 : : replace = true;
23177 : : break;
23178 : : }
23179 : : }
23180 : 69 : if (!replace)
23181 : : {
23182 : 40717 : prev = prev_active_insn (ret);
23183 : 40717 : if (prev
23184 : 40717 : && ((JUMP_P (prev) && any_condjump_p (prev))
23185 : 40281 : || CALL_P (prev)))
23186 : : replace = true;
23187 : : /* Empty functions get branch mispredict even when
23188 : : the jump destination is not visible to us. */
23189 : 40717 : if (!prev && !optimize_function_for_size_p (cfun))
23190 : : replace = true;
23191 : : }
23192 : 40300 : if (replace)
23193 : : {
23194 : 552 : emit_jump_insn_before (gen_simple_return_internal_long (), ret);
23195 : 552 : delete_insn (ret);
23196 : : }
23197 : : }
23198 : 40789 : }
23199 : :
23200 : : /* Count the minimum number of instructions in BB. Return 4 if the
23201 : : number of instructions >= 4. */
23202 : :
23203 : : static int
23204 : 43 : ix86_count_insn_bb (basic_block bb)
23205 : : {
23206 : 43 : rtx_insn *insn;
23207 : 43 : int insn_count = 0;
23208 : :
23209 : : /* Count number of instructions in this block. Return 4 if the number
23210 : : of instructions >= 4. */
23211 : 319 : FOR_BB_INSNS (bb, insn)
23212 : : {
23213 : : /* Only happen in exit blocks. */
23214 : 313 : if (JUMP_P (insn)
23215 : 313 : && ANY_RETURN_P (PATTERN (insn)))
23216 : : break;
23217 : :
23218 : 288 : if (NONDEBUG_INSN_P (insn)
23219 : 105 : && GET_CODE (PATTERN (insn)) != USE
23220 : 375 : && GET_CODE (PATTERN (insn)) != CLOBBER)
23221 : : {
23222 : 87 : insn_count++;
23223 : 87 : if (insn_count >= 4)
23224 : 12 : return insn_count;
23225 : : }
23226 : : }
23227 : :
23228 : : return insn_count;
23229 : : }
23230 : :
23231 : :
23232 : : /* Count the minimum number of instructions in code path in BB.
23233 : : Return 4 if the number of instructions >= 4. */
23234 : :
23235 : : static int
23236 : 64 : ix86_count_insn (basic_block bb)
23237 : : {
23238 : 64 : edge e;
23239 : 64 : edge_iterator ei;
23240 : 64 : int min_prev_count;
23241 : :
23242 : : /* Only bother counting instructions along paths with no
23243 : : more than 2 basic blocks between entry and exit. Given
23244 : : that BB has an edge to exit, determine if a predecessor
23245 : : of BB has an edge from entry. If so, compute the number
23246 : : of instructions in the predecessor block. If there
23247 : : happen to be multiple such blocks, compute the minimum. */
23248 : 64 : min_prev_count = 4;
23249 : 148 : FOR_EACH_EDGE (e, ei, bb->preds)
23250 : : {
23251 : 111 : edge prev_e;
23252 : 111 : edge_iterator prev_ei;
23253 : :
23254 : 111 : if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
23255 : : {
23256 : 27 : min_prev_count = 0;
23257 : 27 : break;
23258 : : }
23259 : 186 : FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
23260 : : {
23261 : 112 : if (prev_e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
23262 : : {
23263 : 10 : int count = ix86_count_insn_bb (e->src);
23264 : 10 : if (count < min_prev_count)
23265 : 84 : min_prev_count = count;
23266 : : break;
23267 : : }
23268 : : }
23269 : : }
23270 : :
23271 : 64 : if (min_prev_count < 4)
23272 : 33 : min_prev_count += ix86_count_insn_bb (bb);
23273 : :
23274 : 64 : return min_prev_count;
23275 : : }
23276 : :
23277 : : /* Pad short function to 4 instructions. */
23278 : :
23279 : : static void
23280 : 66 : ix86_pad_short_function (void)
23281 : : {
23282 : 66 : edge e;
23283 : 66 : edge_iterator ei;
23284 : :
23285 : 133 : FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
23286 : : {
23287 : 67 : rtx_insn *ret = BB_END (e->src);
23288 : 67 : if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
23289 : : {
23290 : 64 : int insn_count = ix86_count_insn (e->src);
23291 : :
23292 : : /* Pad short function. */
23293 : 64 : if (insn_count < 4)
23294 : : {
23295 : : rtx_insn *insn = ret;
23296 : :
23297 : : /* Find epilogue. */
23298 : : while (insn
23299 : 56 : && (!NOTE_P (insn)
23300 : 26 : || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
23301 : 32 : insn = PREV_INSN (insn);
23302 : :
23303 : 24 : if (!insn)
23304 : 0 : insn = ret;
23305 : :
23306 : : /* Two NOPs count as one instruction. */
23307 : 24 : insn_count = 2 * (4 - insn_count);
23308 : 24 : emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
23309 : : }
23310 : : }
23311 : : }
23312 : 66 : }
23313 : :
23314 : : /* Fix up a Windows system unwinder issue. If an EH region falls through into
23315 : : the epilogue, the Windows system unwinder will apply epilogue logic and
23316 : : produce incorrect offsets. This can be avoided by adding a nop between
23317 : : the last insn that can throw and the first insn of the epilogue. */
23318 : :
23319 : : static void
23320 : 0 : ix86_seh_fixup_eh_fallthru (void)
23321 : : {
23322 : 0 : edge e;
23323 : 0 : edge_iterator ei;
23324 : :
23325 : 0 : FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
23326 : : {
23327 : 0 : rtx_insn *insn, *next;
23328 : :
23329 : : /* Find the beginning of the epilogue. */
23330 : 0 : for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
23331 : 0 : if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
23332 : : break;
23333 : 0 : if (insn == NULL)
23334 : 0 : continue;
23335 : :
23336 : : /* We only care about preceding insns that can throw. */
23337 : 0 : insn = prev_active_insn (insn);
23338 : 0 : if (insn == NULL || !can_throw_internal (insn))
23339 : 0 : continue;
23340 : :
23341 : : /* Do not separate calls from their debug information. */
23342 : 0 : for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next))
23343 : 0 : if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION)
23344 : 0 : insn = next;
23345 : : else
23346 : : break;
23347 : :
23348 : 0 : emit_insn_after (gen_nops (const1_rtx), insn);
23349 : : }
23350 : 0 : }
23351 : : /* Split vector load from parm_decl to elemental loads to avoid STLF
23352 : : stalls. */
23353 : : static void
23354 : 912331 : ix86_split_stlf_stall_load ()
23355 : : {
23356 : 912331 : rtx_insn* insn, *start = get_insns ();
23357 : 912331 : unsigned window = 0;
23358 : :
23359 : 24788163 : for (insn = start; insn; insn = NEXT_INSN (insn))
23360 : : {
23361 : 24787306 : if (!NONDEBUG_INSN_P (insn))
23362 : 13530453 : continue;
23363 : 11256853 : window++;
23364 : : /* Insert 64 vaddps %xmm18, %xmm19, %xmm20(no dependence between each
23365 : : other, just emulate for pipeline) before stalled load, stlf stall
23366 : : case is as fast as no stall cases on CLX.
23367 : : Since CFG is freed before machine_reorg, just do a rough
23368 : : calculation of the window according to the layout. */
23369 : 11256853 : if (window > (unsigned) x86_stlf_window_ninsns)
23370 : : return;
23371 : :
23372 : 11239676 : if (any_uncondjump_p (insn)
23373 : 11206512 : || ANY_RETURN_P (PATTERN (insn))
23374 : 22099455 : || CALL_P (insn))
23375 : : return;
23376 : :
23377 : 10345379 : rtx set = single_set (insn);
23378 : 10345379 : if (!set)
23379 : 375997 : continue;
23380 : 9969382 : rtx src = SET_SRC (set);
23381 : 19938414 : if (!MEM_P (src)
23382 : : /* Only handle V2DFmode load since it doesn't need any scratch
23383 : : register. */
23384 : 9969382 : || GET_MODE (src) != E_V2DFmode
23385 : 4756 : || !MEM_EXPR (src)
23386 : 9972720 : || TREE_CODE (get_base_address (MEM_EXPR (src))) != PARM_DECL)
23387 : 9969032 : continue;
23388 : :
23389 : 350 : rtx zero = CONST0_RTX (V2DFmode);
23390 : 350 : rtx dest = SET_DEST (set);
23391 : 350 : rtx m = adjust_address (src, DFmode, 0);
23392 : 350 : rtx loadlpd = gen_sse2_loadlpd (dest, zero, m);
23393 : 350 : emit_insn_before (loadlpd, insn);
23394 : 350 : m = adjust_address (src, DFmode, 8);
23395 : 350 : rtx loadhpd = gen_sse2_loadhpd (dest, dest, m);
23396 : 350 : if (dump_file && (dump_flags & TDF_DETAILS))
23397 : : {
23398 : 0 : fputs ("Due to potential STLF stall, split instruction:\n",
23399 : : dump_file);
23400 : 0 : print_rtl_single (dump_file, insn);
23401 : 0 : fputs ("To:\n", dump_file);
23402 : 0 : print_rtl_single (dump_file, loadlpd);
23403 : 0 : print_rtl_single (dump_file, loadhpd);
23404 : : }
23405 : 350 : PATTERN (insn) = loadhpd;
23406 : 350 : INSN_CODE (insn) = -1;
23407 : 350 : gcc_assert (recog_memoized (insn) != -1);
23408 : : }
23409 : : }
23410 : :
23411 : : /* Implement machine specific optimizations. We implement padding of returns
23412 : : for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window. */
23413 : : static void
23414 : 1392360 : ix86_reorg (void)
23415 : : {
23416 : : /* We are freeing block_for_insn in the toplev to keep compatibility
23417 : : with old MDEP_REORGS that are not CFG based. Recompute it now. */
23418 : 1392360 : compute_bb_for_insn ();
23419 : :
23420 : 1392360 : if (TARGET_SEH && current_function_has_exception_handlers ())
23421 : : ix86_seh_fixup_eh_fallthru ();
23422 : :
23423 : 1392360 : if (optimize && optimize_function_for_speed_p (cfun))
23424 : : {
23425 : 914601 : if (TARGET_SSE2)
23426 : 912331 : ix86_split_stlf_stall_load ();
23427 : 914601 : if (TARGET_PAD_SHORT_FUNCTION)
23428 : 66 : ix86_pad_short_function ();
23429 : 914535 : else if (TARGET_PAD_RETURNS)
23430 : 40789 : ix86_pad_returns ();
23431 : : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
23432 : 914601 : if (TARGET_FOUR_JUMP_LIMIT)
23433 : 41087 : ix86_avoid_jump_mispredicts ();
23434 : : #endif
23435 : : }
23436 : 1392360 : }
23437 : :
23438 : : /* Return nonzero when QImode register that must be represented via REX prefix
23439 : : is used. */
23440 : : bool
23441 : 7297972 : x86_extended_QIreg_mentioned_p (rtx_insn *insn)
23442 : : {
23443 : 7297972 : int i;
23444 : 7297972 : extract_insn_cached (insn);
23445 : 27787819 : for (i = 0; i < recog_data.n_operands; i++)
23446 : 3964949 : if (GENERAL_REG_P (recog_data.operand[i])
23447 : 18319279 : && !QI_REGNO_P (REGNO (recog_data.operand[i])))
23448 : : return true;
23449 : : return false;
23450 : : }
23451 : :
23452 : : /* Return true when INSN mentions register that must be encoded using REX
23453 : : prefix. */
23454 : : bool
23455 : 170827334 : x86_extended_reg_mentioned_p (rtx insn)
23456 : : {
23457 : 170827334 : subrtx_iterator::array_type array;
23458 : 887828773 : FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
23459 : : {
23460 : 761055024 : const_rtx x = *iter;
23461 : 761055024 : if (REG_P (x)
23462 : 761055024 : && (REX_INT_REGNO_P (REGNO (x)) || REX_SSE_REGNO_P (REGNO (x))
23463 : 217693461 : || REX2_INT_REGNO_P (REGNO (x))))
23464 : 44053585 : return true;
23465 : : }
23466 : 126773749 : return false;
23467 : 170827334 : }
23468 : :
23469 : : /* Return true when INSN mentions register that must be encoded using REX2
23470 : : prefix. */
23471 : : bool
23472 : 1803904 : x86_extended_rex2reg_mentioned_p (rtx insn)
23473 : : {
23474 : 1803904 : subrtx_iterator::array_type array;
23475 : 8515393 : FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
23476 : : {
23477 : 6712138 : const_rtx x = *iter;
23478 : 6712138 : if (REG_P (x) && REX2_INT_REGNO_P (REGNO (x)))
23479 : 649 : return true;
23480 : : }
23481 : 1803255 : return false;
23482 : 1803904 : }
23483 : :
23484 : : /* Return true when rtx operands mentions register that must be encoded using
23485 : : evex prefix. */
23486 : : bool
23487 : 16 : x86_evex_reg_mentioned_p (rtx operands[], int nops)
23488 : : {
23489 : 16 : int i;
23490 : 52 : for (i = 0; i < nops; i++)
23491 : 36 : if (EXT_REX_SSE_REG_P (operands[i])
23492 : 72 : || x86_extended_rex2reg_mentioned_p (operands[i]))
23493 : 4 : return true;
23494 : : return false;
23495 : : }
23496 : :
23497 : : /* If profitable, negate (without causing overflow) integer constant
23498 : : of mode MODE at location LOC. Return true in this case. */
23499 : : bool
23500 : 5517916 : x86_maybe_negate_const_int (rtx *loc, machine_mode mode)
23501 : : {
23502 : 5517916 : HOST_WIDE_INT val;
23503 : :
23504 : 5517916 : if (!CONST_INT_P (*loc))
23505 : : return false;
23506 : :
23507 : 4674088 : switch (mode)
23508 : : {
23509 : 2573948 : case E_DImode:
23510 : : /* DImode x86_64 constants must fit in 32 bits. */
23511 : 2573948 : gcc_assert (x86_64_immediate_operand (*loc, mode));
23512 : :
23513 : : mode = SImode;
23514 : : break;
23515 : :
23516 : : case E_SImode:
23517 : : case E_HImode:
23518 : : case E_QImode:
23519 : : break;
23520 : :
23521 : 0 : default:
23522 : 0 : gcc_unreachable ();
23523 : : }
23524 : :
23525 : : /* Avoid overflows. */
23526 : 4674088 : if (mode_signbit_p (mode, *loc))
23527 : : return false;
23528 : :
23529 : 4673671 : val = INTVAL (*loc);
23530 : :
23531 : : /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
23532 : : Exceptions: -128 encodes smaller than 128, so swap sign and op. */
23533 : 4673671 : if ((val < 0 && val != -128)
23534 : 3050408 : || val == 128)
23535 : : {
23536 : 1633634 : *loc = GEN_INT (-val);
23537 : 1633634 : return true;
23538 : : }
23539 : :
23540 : : return false;
23541 : : }
23542 : :
23543 : : /* Generate an unsigned DImode/SImode to FP conversion. This is the same code
23544 : : optabs would emit if we didn't have TFmode patterns. */
23545 : :
23546 : : void
23547 : 4602 : x86_emit_floatuns (rtx operands[2])
23548 : : {
23549 : 4602 : rtx_code_label *neglab, *donelab;
23550 : 4602 : rtx i0, i1, f0, in, out;
23551 : 4602 : machine_mode mode, inmode;
23552 : :
23553 : 4602 : inmode = GET_MODE (operands[1]);
23554 : 4602 : gcc_assert (inmode == SImode || inmode == DImode);
23555 : :
23556 : 4602 : out = operands[0];
23557 : 4602 : in = force_reg (inmode, operands[1]);
23558 : 4602 : mode = GET_MODE (out);
23559 : 4602 : neglab = gen_label_rtx ();
23560 : 4602 : donelab = gen_label_rtx ();
23561 : 4602 : f0 = gen_reg_rtx (mode);
23562 : :
23563 : 4602 : emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
23564 : :
23565 : 4602 : expand_float (out, in, 0);
23566 : :
23567 : 4602 : emit_jump_insn (gen_jump (donelab));
23568 : 4602 : emit_barrier ();
23569 : :
23570 : 4602 : emit_label (neglab);
23571 : :
23572 : 4602 : i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
23573 : : 1, OPTAB_DIRECT);
23574 : 4602 : i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
23575 : : 1, OPTAB_DIRECT);
23576 : 4602 : i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
23577 : :
23578 : 4602 : expand_float (f0, i0, 0);
23579 : :
23580 : 4602 : emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
23581 : :
23582 : 4602 : emit_label (donelab);
23583 : 4602 : }
23584 : :
23585 : : /* Return the diagnostic message string if conversion from FROMTYPE to
23586 : : TOTYPE is not allowed, NULL otherwise. */
23587 : :
23588 : : static const char *
23589 : 843536865 : ix86_invalid_conversion (const_tree fromtype, const_tree totype)
23590 : : {
23591 : 843536865 : machine_mode from_mode = element_mode (fromtype);
23592 : 843536865 : machine_mode to_mode = element_mode (totype);
23593 : :
23594 : 843536865 : if (!TARGET_SSE2 && from_mode != to_mode)
23595 : : {
23596 : : /* Do no allow conversions to/from BFmode/HFmode scalar types
23597 : : when TARGET_SSE2 is not available. */
23598 : 524200 : if (from_mode == BFmode)
23599 : : return N_("invalid conversion from type %<__bf16%> "
23600 : : "without option %<-msse2%>");
23601 : 524199 : if (from_mode == HFmode)
23602 : : return N_("invalid conversion from type %<_Float16%> "
23603 : : "without option %<-msse2%>");
23604 : 524199 : if (to_mode == BFmode)
23605 : : return N_("invalid conversion to type %<__bf16%> "
23606 : : "without option %<-msse2%>");
23607 : 524199 : if (to_mode == HFmode)
23608 : : return N_("invalid conversion to type %<_Float16%> "
23609 : : "without option %<-msse2%>");
23610 : : }
23611 : :
23612 : : /* Warn for silent implicit conversion between __bf16 and short,
23613 : : since __bfloat16 is refined as real __bf16 instead of short
23614 : : since GCC13. */
23615 : 843536863 : if (element_mode (fromtype) != element_mode (totype)
23616 : 843536863 : && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
23617 : : {
23618 : : /* Warn for silent implicit conversion where user may expect
23619 : : a bitcast. */
23620 : 879633 : if ((TYPE_MODE (fromtype) == BFmode
23621 : 4 : && TYPE_MODE (totype) == HImode)
23622 : 879636 : || (TYPE_MODE (totype) == BFmode
23623 : 2 : && TYPE_MODE (fromtype) == HImode))
23624 : 1 : warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
23625 : : "to real %<__bf16%> since GCC 13.1, be careful of "
23626 : : "implicit conversion between %<__bf16%> and %<short%>; "
23627 : : "an explicit bitcast may be needed here");
23628 : : }
23629 : :
23630 : : /* Conversion allowed. */
23631 : : return NULL;
23632 : : }
23633 : :
23634 : : /* Return the diagnostic message string if the unary operation OP is
23635 : : not permitted on TYPE, NULL otherwise. */
23636 : :
23637 : : static const char *
23638 : 77011277 : ix86_invalid_unary_op (int op, const_tree type)
23639 : : {
23640 : 77011277 : machine_mode mmode = element_mode (type);
23641 : : /* Reject all single-operand operations on BFmode/HFmode except for &
23642 : : when TARGET_SSE2 is not available. */
23643 : 77011277 : if (!TARGET_SSE2 && op != ADDR_EXPR)
23644 : : {
23645 : 107089 : if (mmode == BFmode)
23646 : : return N_("operation not permitted on type %<__bf16%> "
23647 : : "without option %<-msse2%>");
23648 : 107089 : if (mmode == HFmode)
23649 : 0 : return N_("operation not permitted on type %<_Float16%> "
23650 : : "without option %<-msse2%>");
23651 : : }
23652 : :
23653 : : /* Operation allowed. */
23654 : : return NULL;
23655 : : }
23656 : :
23657 : : /* Return the diagnostic message string if the binary operation OP is
23658 : : not permitted on TYPE1 and TYPE2, NULL otherwise. */
23659 : :
23660 : : static const char *
23661 : 126203614 : ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
23662 : : const_tree type2)
23663 : : {
23664 : 126203614 : machine_mode type1_mode = element_mode (type1);
23665 : 126203614 : machine_mode type2_mode = element_mode (type2);
23666 : : /* Reject all 2-operand operations on BFmode or HFmode
23667 : : when TARGET_SSE2 is not available. */
23668 : 126203614 : if (!TARGET_SSE2)
23669 : : {
23670 : 973568 : if (type1_mode == BFmode || type2_mode == BFmode)
23671 : : return N_("operation not permitted on type %<__bf16%> "
23672 : : "without option %<-msse2%>");
23673 : :
23674 : 973568 : if (type1_mode == HFmode || type2_mode == HFmode)
23675 : 0 : return N_("operation not permitted on type %<_Float16%> "
23676 : : "without option %<-msse2%>");
23677 : : }
23678 : :
23679 : : /* Operation allowed. */
23680 : : return NULL;
23681 : : }
23682 : :
23683 : :
23684 : : /* Target hook for scalar_mode_supported_p. */
23685 : : static bool
23686 : 4240115 : ix86_scalar_mode_supported_p (scalar_mode mode)
23687 : : {
23688 : 4240115 : if (DECIMAL_FLOAT_MODE_P (mode))
23689 : 620567 : return default_decimal_float_supported_p ();
23690 : 3619548 : else if (mode == TFmode)
23691 : : return true;
23692 : 3307365 : else if (mode == HFmode || mode == BFmode)
23693 : : return true;
23694 : : else
23695 : 2684982 : return default_scalar_mode_supported_p (mode);
23696 : : }
23697 : :
23698 : : /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE
23699 : : if MODE is HFmode, and punt to the generic implementation otherwise. */
23700 : :
23701 : : static bool
23702 : 2144462 : ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode)
23703 : : {
23704 : : /* NB: Always return TRUE for HFmode so that the _Float16 type will
23705 : : be defined by the C front-end for AVX512FP16 intrinsics. We will
23706 : : issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't
23707 : : enabled. */
23708 : 1833746 : return ((mode == HFmode || mode == BFmode)
23709 : 3667492 : ? true
23710 : 1523030 : : default_libgcc_floating_mode_supported_p (mode));
23711 : : }
23712 : :
23713 : : /* Implements target hook vector_mode_supported_p. */
23714 : : static bool
23715 : 1457486285 : ix86_vector_mode_supported_p (machine_mode mode)
23716 : : {
23717 : : /* For ia32, scalar TImode isn't supported and so V1TImode shouldn't be
23718 : : either. */
23719 : 1626771208 : if (!TARGET_64BIT && GET_MODE_INNER (mode) == TImode)
23720 : : return false;
23721 : 1457486041 : if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
23722 : : return true;
23723 : 1250652326 : if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
23724 : : return true;
23725 : 449250602 : if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
23726 : : return true;
23727 : 327771556 : if (TARGET_AVX512F && TARGET_EVEX512 && VALID_AVX512F_REG_MODE (mode))
23728 : : return true;
23729 : 218261811 : if ((TARGET_MMX || TARGET_MMX_WITH_SSE)
23730 : 218200202 : && VALID_MMX_REG_MODE (mode))
23731 : : return true;
23732 : 26511667 : if ((TARGET_3DNOW || TARGET_MMX_WITH_SSE)
23733 : 25902166 : && VALID_MMX_REG_MODE_3DNOW (mode))
23734 : : return true;
23735 : 18040476 : if (mode == V2QImode)
23736 : : return true;
23737 : : return false;
23738 : : }
23739 : :
23740 : : /* Target hook for c_mode_for_suffix. */
23741 : : static machine_mode
23742 : 74438 : ix86_c_mode_for_suffix (char suffix)
23743 : : {
23744 : 74438 : if (suffix == 'q')
23745 : : return TFmode;
23746 : 38 : if (suffix == 'w')
23747 : : return XFmode;
23748 : :
23749 : 0 : return VOIDmode;
23750 : : }
23751 : :
23752 : : /* Helper function to map common constraints to non-EGPR ones.
23753 : : All related constraints have h prefix, and h plus Upper letter
23754 : : means the constraint is strictly EGPR enabled, while h plus
23755 : : lower letter indicates the constraint is strictly gpr16 only.
23756 : :
23757 : : Specially for "g" constraint, split it to rmi as there is
23758 : : no corresponding general constraint define for backend.
23759 : :
23760 : : Here is the full list to map constraints that may involve
23761 : : gpr to h prefixed.
23762 : :
23763 : : "g" -> "jrjmi"
23764 : : "r" -> "jr"
23765 : : "m" -> "jm"
23766 : : "<" -> "j<"
23767 : : ">" -> "j>"
23768 : : "o" -> "jo"
23769 : : "V" -> "jV"
23770 : : "p" -> "jp"
23771 : : "Bm" -> "ja"
23772 : : */
23773 : :
23774 : 13 : static void map_egpr_constraints (vec<const char *> &constraints)
23775 : : {
23776 : 46 : for (size_t i = 0; i < constraints.length(); i++)
23777 : : {
23778 : 10 : const char *cur = constraints[i];
23779 : :
23780 : 10 : if (startswith (cur, "=@cc"))
23781 : 0 : continue;
23782 : :
23783 : 10 : int len = strlen (cur);
23784 : 10 : auto_vec<char> buf;
23785 : :
23786 : 24 : for (int j = 0; j < len; j++)
23787 : : {
23788 : 14 : switch (cur[j])
23789 : : {
23790 : 2 : case 'g':
23791 : 2 : buf.safe_push ('j');
23792 : 2 : buf.safe_push ('r');
23793 : 2 : buf.safe_push ('j');
23794 : 2 : buf.safe_push ('m');
23795 : 2 : buf.safe_push ('i');
23796 : 2 : break;
23797 : 8 : case 'r':
23798 : 8 : case 'm':
23799 : 8 : case '<':
23800 : 8 : case '>':
23801 : 8 : case 'o':
23802 : 8 : case 'V':
23803 : 8 : case 'p':
23804 : 8 : buf.safe_push ('j');
23805 : 8 : buf.safe_push (cur[j]);
23806 : 8 : break;
23807 : 0 : case 'B':
23808 : 0 : if (cur[j + 1] == 'm')
23809 : : {
23810 : 0 : buf.safe_push ('j');
23811 : 0 : buf.safe_push ('a');
23812 : 0 : j++;
23813 : : }
23814 : : else
23815 : : {
23816 : 0 : buf.safe_push (cur[j]);
23817 : 0 : buf.safe_push (cur[j + 1]);
23818 : 0 : j++;
23819 : : }
23820 : : break;
23821 : 0 : case 'T':
23822 : 0 : case 'Y':
23823 : 0 : case 'W':
23824 : 0 : case 'j':
23825 : 0 : buf.safe_push (cur[j]);
23826 : 0 : buf.safe_push (cur[j + 1]);
23827 : 0 : j++;
23828 : 0 : break;
23829 : 4 : default:
23830 : 4 : buf.safe_push (cur[j]);
23831 : 4 : break;
23832 : : }
23833 : : }
23834 : 10 : buf.safe_push ('\0');
23835 : 20 : constraints[i] = xstrdup (buf.address ());
23836 : 10 : }
23837 : 13 : }
23838 : :
23839 : : /* Worker function for TARGET_MD_ASM_ADJUST.
23840 : :
23841 : : We implement asm flag outputs, and maintain source compatibility
23842 : : with the old cc0-based compiler. */
23843 : :
23844 : : static rtx_insn *
23845 : 113397 : ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
23846 : : vec<machine_mode> & /*input_modes*/,
23847 : : vec<const char *> &constraints, vec<rtx> &/*uses*/,
23848 : : vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
23849 : : location_t loc)
23850 : : {
23851 : 113397 : bool saw_asm_flag = false;
23852 : :
23853 : 113397 : start_sequence ();
23854 : :
23855 : 113397 : if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
23856 : 13 : map_egpr_constraints (constraints);
23857 : :
23858 : 317610 : for (unsigned i = 0, n = outputs.length (); i < n; ++i)
23859 : : {
23860 : 91538 : const char *con = constraints[i];
23861 : 91538 : if (!startswith (con, "=@cc"))
23862 : 91450 : continue;
23863 : 88 : con += 4;
23864 : 88 : if (strchr (con, ',') != NULL)
23865 : : {
23866 : 1 : error_at (loc, "alternatives not allowed in %<asm%> flag output");
23867 : 1 : continue;
23868 : : }
23869 : :
23870 : 87 : bool invert = false;
23871 : 87 : if (con[0] == 'n')
23872 : 19 : invert = true, con++;
23873 : :
23874 : 87 : machine_mode mode = CCmode;
23875 : 87 : rtx_code code = UNKNOWN;
23876 : :
23877 : 87 : switch (con[0])
23878 : : {
23879 : 15 : case 'a':
23880 : 15 : if (con[1] == 0)
23881 : : mode = CCAmode, code = EQ;
23882 : 4 : else if (con[1] == 'e' && con[2] == 0)
23883 : : mode = CCCmode, code = NE;
23884 : : break;
23885 : 11 : case 'b':
23886 : 11 : if (con[1] == 0)
23887 : : mode = CCCmode, code = EQ;
23888 : 6 : else if (con[1] == 'e' && con[2] == 0)
23889 : : mode = CCAmode, code = NE;
23890 : : break;
23891 : 14 : case 'c':
23892 : 14 : if (con[1] == 0)
23893 : : mode = CCCmode, code = EQ;
23894 : : break;
23895 : 9 : case 'e':
23896 : 9 : if (con[1] == 0)
23897 : : mode = CCZmode, code = EQ;
23898 : : break;
23899 : 11 : case 'g':
23900 : 11 : if (con[1] == 0)
23901 : : mode = CCGCmode, code = GT;
23902 : 5 : else if (con[1] == 'e' && con[2] == 0)
23903 : : mode = CCGCmode, code = GE;
23904 : : break;
23905 : 10 : case 'l':
23906 : 10 : if (con[1] == 0)
23907 : : mode = CCGCmode, code = LT;
23908 : 5 : else if (con[1] == 'e' && con[2] == 0)
23909 : : mode = CCGCmode, code = LE;
23910 : : break;
23911 : 4 : case 'o':
23912 : 4 : if (con[1] == 0)
23913 : : mode = CCOmode, code = EQ;
23914 : : break;
23915 : 4 : case 'p':
23916 : 4 : if (con[1] == 0)
23917 : : mode = CCPmode, code = EQ;
23918 : : break;
23919 : 4 : case 's':
23920 : 4 : if (con[1] == 0)
23921 : : mode = CCSmode, code = EQ;
23922 : : break;
23923 : 5 : case 'z':
23924 : 5 : if (con[1] == 0)
23925 : : mode = CCZmode, code = EQ;
23926 : : break;
23927 : : }
23928 : 1 : if (code == UNKNOWN)
23929 : : {
23930 : 1 : error_at (loc, "unknown %<asm%> flag output %qs", constraints[i]);
23931 : 1 : continue;
23932 : : }
23933 : 86 : if (invert)
23934 : 19 : code = reverse_condition (code);
23935 : :
23936 : 86 : rtx dest = outputs[i];
23937 : 86 : if (!saw_asm_flag)
23938 : : {
23939 : : /* This is the first asm flag output. Here we put the flags
23940 : : register in as the real output and adjust the condition to
23941 : : allow it. */
23942 : 75 : constraints[i] = "=Bf";
23943 : 75 : outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG);
23944 : 75 : saw_asm_flag = true;
23945 : : }
23946 : : else
23947 : : {
23948 : : /* We don't need the flags register as output twice. */
23949 : 11 : constraints[i] = "=X";
23950 : 11 : outputs[i] = gen_rtx_SCRATCH (SImode);
23951 : : }
23952 : :
23953 : 86 : rtx x = gen_rtx_REG (mode, FLAGS_REG);
23954 : 86 : x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx);
23955 : :
23956 : 86 : machine_mode dest_mode = GET_MODE (dest);
23957 : 86 : if (!SCALAR_INT_MODE_P (dest_mode))
23958 : : {
23959 : 3 : error_at (loc, "invalid type for %<asm%> flag output");
23960 : 3 : continue;
23961 : : }
23962 : :
23963 : 83 : if (dest_mode == QImode)
23964 : 73 : emit_insn (gen_rtx_SET (dest, x));
23965 : : else
23966 : : {
23967 : 10 : rtx reg = gen_reg_rtx (QImode);
23968 : 10 : emit_insn (gen_rtx_SET (reg, x));
23969 : :
23970 : 10 : reg = convert_to_mode (dest_mode, reg, 1);
23971 : 10 : emit_move_insn (dest, reg);
23972 : : }
23973 : : }
23974 : :
23975 : 113397 : rtx_insn *seq = get_insns ();
23976 : 113397 : end_sequence ();
23977 : :
23978 : 113397 : if (saw_asm_flag)
23979 : : return seq;
23980 : : else
23981 : : {
23982 : : /* If we had no asm flag outputs, clobber the flags. */
23983 : 113322 : clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG));
23984 : 113322 : SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG);
23985 : 113322 : return NULL;
23986 : : }
23987 : : }
23988 : :
23989 : : /* Implements target vector targetm.asm.encode_section_info. */
23990 : :
23991 : : static void ATTRIBUTE_UNUSED
23992 : 9625302 : ix86_encode_section_info (tree decl, rtx rtl, int first)
23993 : : {
23994 : 9625302 : default_encode_section_info (decl, rtl, first);
23995 : :
23996 : 9625302 : if (ix86_in_large_data_p (decl))
23997 : 36 : SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
23998 : 9625302 : }
23999 : :
24000 : : /* Worker function for REVERSE_CONDITION. */
24001 : :
24002 : : enum rtx_code
24003 : 27522514 : ix86_reverse_condition (enum rtx_code code, machine_mode mode)
24004 : : {
24005 : 27522514 : return (mode == CCFPmode
24006 : 27522514 : ? reverse_condition_maybe_unordered (code)
24007 : 23430116 : : reverse_condition (code));
24008 : : }
24009 : :
24010 : : /* Output code to perform an x87 FP register move, from OPERANDS[1]
24011 : : to OPERANDS[0]. */
24012 : :
24013 : : const char *
24014 : 663611 : output_387_reg_move (rtx_insn *insn, rtx *operands)
24015 : : {
24016 : 663611 : if (REG_P (operands[0]))
24017 : : {
24018 : 554946 : if (REG_P (operands[1])
24019 : 554946 : && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
24020 : : {
24021 : 303004 : if (REGNO (operands[0]) == FIRST_STACK_REG)
24022 : 282177 : return output_387_ffreep (operands, 0);
24023 : : return "fstp\t%y0";
24024 : : }
24025 : 251942 : if (STACK_TOP_P (operands[0]))
24026 : 251942 : return "fld%Z1\t%y1";
24027 : : return "fst\t%y0";
24028 : : }
24029 : 108665 : else if (MEM_P (operands[0]))
24030 : : {
24031 : 108665 : gcc_assert (REG_P (operands[1]));
24032 : 108665 : if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
24033 : : return "fstp%Z0\t%y0";
24034 : : else
24035 : : {
24036 : : /* There is no non-popping store to memory for XFmode.
24037 : : So if we need one, follow the store with a load. */
24038 : 6264 : if (GET_MODE (operands[0]) == XFmode)
24039 : : return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
24040 : : else
24041 : 1912 : return "fst%Z0\t%y0";
24042 : : }
24043 : : }
24044 : : else
24045 : 0 : gcc_unreachable();
24046 : : }
24047 : : #ifdef TARGET_SOLARIS
24048 : : /* Solaris implementation of TARGET_ASM_NAMED_SECTION. */
24049 : :
24050 : : static void
24051 : : i386_solaris_elf_named_section (const char *name, unsigned int flags,
24052 : : tree decl)
24053 : : {
24054 : : /* With Binutils 2.15, the "@unwind" marker must be specified on
24055 : : every occurrence of the ".eh_frame" section, not just the first
24056 : : one. */
24057 : : if (TARGET_64BIT
24058 : : && strcmp (name, ".eh_frame") == 0)
24059 : : {
24060 : : fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
24061 : : flags & SECTION_WRITE ? "aw" : "a");
24062 : : return;
24063 : : }
24064 : :
24065 : : #ifndef USE_GAS
24066 : : if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
24067 : : {
24068 : : solaris_elf_asm_comdat_section (name, flags, decl);
24069 : : return;
24070 : : }
24071 : :
24072 : : /* Solaris/x86 as uses the same syntax for the SHF_EXCLUDE flags as the
24073 : : SPARC assembler. One cannot mix single-letter flags and #exclude, so
24074 : : only emit the latter here. */
24075 : : if (flags & SECTION_EXCLUDE)
24076 : : {
24077 : : fprintf (asm_out_file, "\t.section\t%s,#exclude\n", name);
24078 : : return;
24079 : : }
24080 : : #endif
24081 : :
24082 : : default_elf_asm_named_section (name, flags, decl);
24083 : : }
24084 : : #endif /* TARGET_SOLARIS */
24085 : :
24086 : : /* Return the mangling of TYPE if it is an extended fundamental type. */
24087 : :
24088 : : static const char *
24089 : 577244031 : ix86_mangle_type (const_tree type)
24090 : : {
24091 : 577244031 : type = TYPE_MAIN_VARIANT (type);
24092 : :
24093 : 577244031 : if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
24094 : : && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
24095 : : return NULL;
24096 : :
24097 : 307574925 : if (type == float128_type_node || type == float64x_type_node)
24098 : : return NULL;
24099 : :
24100 : 306811743 : switch (TYPE_MODE (type))
24101 : : {
24102 : : case E_BFmode:
24103 : : return "DF16b";
24104 : 268047 : case E_HFmode:
24105 : : /* _Float16 is "DF16_".
24106 : : Align with clang's decision in https://reviews.llvm.org/D33719. */
24107 : 268047 : return "DF16_";
24108 : 369097 : case E_TFmode:
24109 : : /* __float128 is "g". */
24110 : 369097 : return "g";
24111 : 5466066 : case E_XFmode:
24112 : : /* "long double" or __float80 is "e". */
24113 : 5466066 : return "e";
24114 : : default:
24115 : : return NULL;
24116 : : }
24117 : : }
24118 : :
24119 : : /* Create C++ tinfo symbols for only conditionally available fundamental
24120 : : types. */
24121 : :
24122 : : static void
24123 : 6 : ix86_emit_support_tinfos (emit_support_tinfos_callback callback)
24124 : : {
24125 : 6 : extern tree ix86_float16_type_node;
24126 : 6 : extern tree ix86_bf16_type_node;
24127 : :
24128 : 6 : if (!TARGET_SSE2)
24129 : : {
24130 : 0 : if (!float16_type_node)
24131 : 0 : float16_type_node = ix86_float16_type_node;
24132 : 0 : if (!bfloat16_type_node)
24133 : 0 : bfloat16_type_node = ix86_bf16_type_node;
24134 : 0 : callback (float16_type_node);
24135 : 0 : callback (bfloat16_type_node);
24136 : 0 : float16_type_node = NULL_TREE;
24137 : 0 : bfloat16_type_node = NULL_TREE;
24138 : : }
24139 : 6 : }
24140 : :
24141 : : static GTY(()) tree ix86_tls_stack_chk_guard_decl;
24142 : :
24143 : : static tree
24144 : 204 : ix86_stack_protect_guard (void)
24145 : : {
24146 : 204 : if (TARGET_SSP_TLS_GUARD)
24147 : : {
24148 : 204 : tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
24149 : 204 : int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg);
24150 : 204 : tree type = build_qualified_type (type_node, qual);
24151 : 204 : tree t;
24152 : :
24153 : 204 : if (OPTION_SET_P (ix86_stack_protector_guard_symbol_str))
24154 : : {
24155 : 1 : t = ix86_tls_stack_chk_guard_decl;
24156 : :
24157 : 1 : if (t == NULL)
24158 : : {
24159 : 1 : rtx x;
24160 : :
24161 : 1 : t = build_decl
24162 : 1 : (UNKNOWN_LOCATION, VAR_DECL,
24163 : : get_identifier (ix86_stack_protector_guard_symbol_str),
24164 : : type);
24165 : 1 : TREE_STATIC (t) = 1;
24166 : 1 : TREE_PUBLIC (t) = 1;
24167 : 1 : DECL_EXTERNAL (t) = 1;
24168 : 1 : TREE_USED (t) = 1;
24169 : 1 : TREE_THIS_VOLATILE (t) = 1;
24170 : 1 : DECL_ARTIFICIAL (t) = 1;
24171 : 1 : DECL_IGNORED_P (t) = 1;
24172 : :
24173 : : /* Do not share RTL as the declaration is visible outside of
24174 : : current function. */
24175 : 1 : x = DECL_RTL (t);
24176 : 1 : RTX_FLAG (x, used) = 1;
24177 : :
24178 : 1 : ix86_tls_stack_chk_guard_decl = t;
24179 : : }
24180 : : }
24181 : : else
24182 : : {
24183 : 203 : tree asptrtype = build_pointer_type (type);
24184 : :
24185 : 203 : t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset);
24186 : 203 : t = build2 (MEM_REF, asptrtype, t,
24187 : 203 : build_int_cst (asptrtype, 0));
24188 : 203 : TREE_THIS_VOLATILE (t) = 1;
24189 : : }
24190 : :
24191 : 204 : return t;
24192 : : }
24193 : :
24194 : 0 : return default_stack_protect_guard ();
24195 : : }
24196 : :
24197 : : /* For 32-bit code we can save PIC register setup by using
24198 : : __stack_chk_fail_local hidden function instead of calling
24199 : : __stack_chk_fail directly. 64-bit code doesn't need to setup any PIC
24200 : : register, so it is better to call __stack_chk_fail directly. */
24201 : :
24202 : : static tree ATTRIBUTE_UNUSED
24203 : 217 : ix86_stack_protect_fail (void)
24204 : : {
24205 : 217 : return TARGET_64BIT
24206 : 217 : ? default_external_stack_protect_fail ()
24207 : 1 : : default_hidden_stack_protect_fail ();
24208 : : }
24209 : :
24210 : : /* Select a format to encode pointers in exception handling data. CODE
24211 : : is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
24212 : : true if the symbol may be affected by dynamic relocations.
24213 : :
24214 : : ??? All x86 object file formats are capable of representing this.
24215 : : After all, the relocation needed is the same as for the call insn.
24216 : : Whether or not a particular assembler allows us to enter such, I
24217 : : guess we'll have to see. */
24218 : :
24219 : : int
24220 : 748738 : asm_preferred_eh_data_format (int code, int global)
24221 : : {
24222 : : /* PE-COFF is effectively always -fPIC because of the .reloc section. */
24223 : 748738 : if (flag_pic || TARGET_PECOFF || !ix86_direct_extern_access)
24224 : : {
24225 : 36498 : int type = DW_EH_PE_sdata8;
24226 : 36498 : if (ptr_mode == SImode
24227 : 22996 : || ix86_cmodel == CM_SMALL_PIC
24228 : 36568 : || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
24229 : : type = DW_EH_PE_sdata4;
24230 : 51137 : return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
24231 : : }
24232 : :
24233 : 712240 : if (ix86_cmodel == CM_SMALL
24234 : 18498 : || (ix86_cmodel == CM_MEDIUM && code))
24235 : 693753 : return DW_EH_PE_udata4;
24236 : :
24237 : : return DW_EH_PE_absptr;
24238 : : }
24239 : :
24240 : : /* Implement targetm.vectorize.builtin_vectorization_cost. */
24241 : : static int
24242 : 12391523 : ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
24243 : : tree vectype, int)
24244 : : {
24245 : 12391523 : bool fp = false;
24246 : 12391523 : machine_mode mode = TImode;
24247 : 12391523 : int index;
24248 : 12391523 : if (vectype != NULL)
24249 : : {
24250 : 11984986 : fp = FLOAT_TYPE_P (vectype);
24251 : 11984986 : mode = TYPE_MODE (vectype);
24252 : : }
24253 : :
24254 : 12391523 : switch (type_of_cost)
24255 : : {
24256 : 1163913 : case scalar_stmt:
24257 : 1163913 : return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
24258 : :
24259 : 1355508 : case scalar_load:
24260 : : /* load/store costs are relative to register move which is 2. Recompute
24261 : : it to COSTS_N_INSNS so everything have same base. */
24262 : 2711016 : return COSTS_N_INSNS (fp ? ix86_cost->sse_load[0]
24263 : 1355508 : : ix86_cost->int_load [2]) / 2;
24264 : :
24265 : 3960861 : case scalar_store:
24266 : 7921722 : return COSTS_N_INSNS (fp ? ix86_cost->sse_store[0]
24267 : 3960861 : : ix86_cost->int_store [2]) / 2;
24268 : :
24269 : 779811 : case vector_stmt:
24270 : 1559622 : return ix86_vec_cost (mode,
24271 : 1559622 : fp ? ix86_cost->addss : ix86_cost->sse_op);
24272 : :
24273 : 1118263 : case vector_load:
24274 : 1118263 : index = sse_store_index (mode);
24275 : : /* See PR82713 - we may end up being called on non-vector type. */
24276 : 1118263 : if (index < 0)
24277 : 86207 : index = 2;
24278 : 1118263 : return COSTS_N_INSNS (ix86_cost->sse_load[index]) / 2;
24279 : :
24280 : 832647 : case vector_store:
24281 : 832647 : index = sse_store_index (mode);
24282 : : /* See PR82713 - we may end up being called on non-vector type. */
24283 : 832647 : if (index < 0)
24284 : 83357 : index = 2;
24285 : 832647 : return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
24286 : :
24287 : 1167007 : case vec_to_scalar:
24288 : 1167007 : case scalar_to_vec:
24289 : 1167007 : return ix86_vec_cost (mode, ix86_cost->sse_op);
24290 : :
24291 : : /* We should have separate costs for unaligned loads and gather/scatter.
24292 : : Do that incrementally. */
24293 : 375453 : case unaligned_load:
24294 : 375453 : index = sse_store_index (mode);
24295 : : /* See PR82713 - we may end up being called on non-vector type. */
24296 : 375453 : if (index < 0)
24297 : 2425 : index = 2;
24298 : 375453 : return COSTS_N_INSNS (ix86_cost->sse_unaligned_load[index]) / 2;
24299 : :
24300 : 723479 : case unaligned_store:
24301 : 723479 : index = sse_store_index (mode);
24302 : : /* See PR82713 - we may end up being called on non-vector type. */
24303 : 723479 : if (index < 0)
24304 : 16193 : index = 2;
24305 : 723479 : return COSTS_N_INSNS (ix86_cost->sse_unaligned_store[index]) / 2;
24306 : :
24307 : 0 : case vector_gather_load:
24308 : 0 : return ix86_vec_cost (mode,
24309 : 0 : COSTS_N_INSNS
24310 : : (ix86_cost->gather_static
24311 : : + ix86_cost->gather_per_elt
24312 : 0 : * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
24313 : :
24314 : 0 : case vector_scatter_store:
24315 : 0 : return ix86_vec_cost (mode,
24316 : 0 : COSTS_N_INSNS
24317 : : (ix86_cost->scatter_static
24318 : : + ix86_cost->scatter_per_elt
24319 : 0 : * TYPE_VECTOR_SUBPARTS (vectype)) / 2);
24320 : :
24321 : 119154 : case cond_branch_taken:
24322 : 119154 : return ix86_cost->cond_taken_branch_cost;
24323 : :
24324 : 2867 : case cond_branch_not_taken:
24325 : 2867 : return ix86_cost->cond_not_taken_branch_cost;
24326 : :
24327 : 217116 : case vec_perm:
24328 : 217116 : case vec_promote_demote:
24329 : 217116 : return ix86_vec_cost (mode, ix86_cost->sse_op);
24330 : :
24331 : 575444 : case vec_construct:
24332 : 575444 : {
24333 : 575444 : int n = TYPE_VECTOR_SUBPARTS (vectype);
24334 : : /* N - 1 element inserts into an SSE vector, the possible
24335 : : GPR -> XMM move is accounted for in add_stmt_cost. */
24336 : 1150888 : if (GET_MODE_BITSIZE (mode) <= 128)
24337 : 570185 : return (n - 1) * ix86_cost->sse_op;
24338 : : /* One vinserti128 for combining two SSE vectors for AVX256. */
24339 : 10518 : else if (GET_MODE_BITSIZE (mode) == 256)
24340 : 4226 : return ((n - 2) * ix86_cost->sse_op
24341 : 4226 : + ix86_vec_cost (mode, ix86_cost->addss));
24342 : : /* One vinserti64x4 and two vinserti128 for combining SSE
24343 : : and AVX256 vectors to AVX512. */
24344 : 2066 : else if (GET_MODE_BITSIZE (mode) == 512)
24345 : 1033 : return ((n - 4) * ix86_cost->sse_op
24346 : 1033 : + 3 * ix86_vec_cost (mode, ix86_cost->addss));
24347 : 0 : gcc_unreachable ();
24348 : : }
24349 : :
24350 : 0 : default:
24351 : 0 : gcc_unreachable ();
24352 : : }
24353 : : }
24354 : :
24355 : :
24356 : : /* This function returns the calling abi specific va_list type node.
24357 : : It returns the FNDECL specific va_list type. */
24358 : :
24359 : : static tree
24360 : 46232 : ix86_fn_abi_va_list (tree fndecl)
24361 : : {
24362 : 46232 : if (!TARGET_64BIT)
24363 : 698 : return va_list_type_node;
24364 : 45534 : gcc_assert (fndecl != NULL_TREE);
24365 : :
24366 : 45534 : if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
24367 : 12868 : return ms_va_list_type_node;
24368 : : else
24369 : 32666 : return sysv_va_list_type_node;
24370 : : }
24371 : :
24372 : : /* Returns the canonical va_list type specified by TYPE. If there
24373 : : is no valid TYPE provided, it return NULL_TREE. */
24374 : :
24375 : : static tree
24376 : 245260 : ix86_canonical_va_list_type (tree type)
24377 : : {
24378 : 245260 : if (TARGET_64BIT)
24379 : : {
24380 : 244758 : if (lookup_attribute ("ms_abi va_list", TYPE_ATTRIBUTES (type)))
24381 : 5944 : return ms_va_list_type_node;
24382 : :
24383 : 238814 : if ((TREE_CODE (type) == ARRAY_TYPE
24384 : 49826 : && integer_zerop (array_type_nelts (type)))
24385 : 238814 : || POINTER_TYPE_P (type))
24386 : : {
24387 : 187276 : tree elem_type = TREE_TYPE (type);
24388 : 187276 : if (TREE_CODE (elem_type) == RECORD_TYPE
24389 : 338426 : && lookup_attribute ("sysv_abi va_list",
24390 : 151150 : TYPE_ATTRIBUTES (elem_type)))
24391 : 151150 : return sysv_va_list_type_node;
24392 : : }
24393 : :
24394 : 87664 : return NULL_TREE;
24395 : : }
24396 : :
24397 : 502 : return std_canonical_va_list_type (type);
24398 : : }
24399 : :
24400 : : /* Iterate through the target-specific builtin types for va_list.
24401 : : IDX denotes the iterator, *PTREE is set to the result type of
24402 : : the va_list builtin, and *PNAME to its internal type.
24403 : : Returns zero if there is no element for this index, otherwise
24404 : : IDX should be increased upon the next call.
24405 : : Note, do not iterate a base builtin's name like __builtin_va_list.
24406 : : Used from c_common_nodes_and_builtins. */
24407 : :
24408 : : static int
24409 : 608939 : ix86_enum_va_list (int idx, const char **pname, tree *ptree)
24410 : : {
24411 : 608939 : if (TARGET_64BIT)
24412 : : {
24413 : 603849 : switch (idx)
24414 : : {
24415 : : default:
24416 : : break;
24417 : :
24418 : 201283 : case 0:
24419 : 201283 : *ptree = ms_va_list_type_node;
24420 : 201283 : *pname = "__builtin_ms_va_list";
24421 : 201283 : return 1;
24422 : :
24423 : 201283 : case 1:
24424 : 201283 : *ptree = sysv_va_list_type_node;
24425 : 201283 : *pname = "__builtin_sysv_va_list";
24426 : 201283 : return 1;
24427 : : }
24428 : : }
24429 : :
24430 : : return 0;
24431 : : }
24432 : :
24433 : : #undef TARGET_SCHED_DISPATCH
24434 : : #define TARGET_SCHED_DISPATCH ix86_bd_has_dispatch
24435 : : #undef TARGET_SCHED_DISPATCH_DO
24436 : : #define TARGET_SCHED_DISPATCH_DO ix86_bd_do_dispatch
24437 : : #undef TARGET_SCHED_REASSOCIATION_WIDTH
24438 : : #define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
24439 : : #undef TARGET_SCHED_REORDER
24440 : : #define TARGET_SCHED_REORDER ix86_atom_sched_reorder
24441 : : #undef TARGET_SCHED_ADJUST_PRIORITY
24442 : : #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
24443 : : #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
24444 : : #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
24445 : : ix86_dependencies_evaluation_hook
24446 : :
24447 : :
24448 : : /* Implementation of reassociation_width target hook used by
24449 : : reassoc phase to identify parallelism level in reassociated
24450 : : tree. Statements tree_code is passed in OPC. Arguments type
24451 : : is passed in MODE. */
24452 : :
24453 : : static int
24454 : 22349 : ix86_reassociation_width (unsigned int op, machine_mode mode)
24455 : : {
24456 : 22349 : int width = 1;
24457 : : /* Vector part. */
24458 : 22349 : if (VECTOR_MODE_P (mode))
24459 : : {
24460 : 6621 : int div = 1;
24461 : 6621 : if (INTEGRAL_MODE_P (mode))
24462 : 2538 : width = ix86_cost->reassoc_vec_int;
24463 : 4083 : else if (FLOAT_MODE_P (mode))
24464 : 4083 : width = ix86_cost->reassoc_vec_fp;
24465 : :
24466 : 6621 : if (width == 1)
24467 : : return 1;
24468 : :
24469 : : /* Integer vector instructions execute in FP unit
24470 : : and can execute 3 additions and one multiplication per cycle. */
24471 : 6597 : if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2
24472 : : || ix86_tune == PROCESSOR_ZNVER3 || ix86_tune == PROCESSOR_ZNVER4
24473 : 6597 : || ix86_tune == PROCESSOR_ZNVER5)
24474 : 0 : && INTEGRAL_MODE_P (mode) && op != PLUS && op != MINUS)
24475 : : return 1;
24476 : :
24477 : : /* Account for targets that splits wide vectors into multiple parts. */
24478 : 6597 : if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 256)
24479 : 0 : div = GET_MODE_BITSIZE (mode) / 256;
24480 : 6597 : else if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 128)
24481 : 0 : div = GET_MODE_BITSIZE (mode) / 128;
24482 : 6597 : else if (TARGET_SSE_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 64)
24483 : 0 : div = GET_MODE_BITSIZE (mode) / 64;
24484 : 6597 : width = (width + div - 1) / div;
24485 : 6597 : }
24486 : : /* Scalar part. */
24487 : : else if (INTEGRAL_MODE_P (mode))
24488 : 13224 : width = ix86_cost->reassoc_int;
24489 : : else if (FLOAT_MODE_P (mode))
24490 : 2504 : width = ix86_cost->reassoc_fp;
24491 : :
24492 : : /* Avoid using too many registers in 32bit mode. */
24493 : 22325 : if (!TARGET_64BIT && width > 2)
24494 : 22349 : width = 2;
24495 : : return width;
24496 : : }
24497 : :
24498 : : /* ??? No autovectorization into MMX or 3DNOW until we can reliably
24499 : : place emms and femms instructions. */
24500 : :
24501 : : static machine_mode
24502 : 4642351 : ix86_preferred_simd_mode (scalar_mode mode)
24503 : : {
24504 : 4642351 : if (!TARGET_SSE)
24505 : 848 : return word_mode;
24506 : :
24507 : 4641503 : switch (mode)
24508 : : {
24509 : 339788 : case E_QImode:
24510 : 339788 : if (TARGET_AVX512BW && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24511 : : return V64QImode;
24512 : 333726 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24513 : : return V32QImode;
24514 : : else
24515 : 314124 : return V16QImode;
24516 : :
24517 : 176637 : case E_HImode:
24518 : 176637 : if (TARGET_AVX512BW && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24519 : : return V32HImode;
24520 : 168201 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24521 : : return V16HImode;
24522 : : else
24523 : 150867 : return V8HImode;
24524 : :
24525 : 1399634 : case E_SImode:
24526 : 1399634 : if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24527 : : return V16SImode;
24528 : 1360321 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24529 : : return V8SImode;
24530 : : else
24531 : 1200027 : return V4SImode;
24532 : :
24533 : 1739377 : case E_DImode:
24534 : 1739377 : if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24535 : : return V8DImode;
24536 : 1471509 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24537 : : return V4DImode;
24538 : : else
24539 : 1314316 : return V2DImode;
24540 : :
24541 : 128972 : case E_HFmode:
24542 : 128972 : if (TARGET_AVX512FP16)
24543 : : {
24544 : 128439 : if (TARGET_AVX512VL)
24545 : : {
24546 : 56262 : if (TARGET_PREFER_AVX128)
24547 : : return V8HFmode;
24548 : 56040 : else if (TARGET_PREFER_AVX256 || !TARGET_EVEX512)
24549 : : return V16HFmode;
24550 : : }
24551 : 102559 : if (TARGET_EVEX512)
24552 : : return V32HFmode;
24553 : : }
24554 : 4263 : return word_mode;
24555 : :
24556 : 544014 : case E_SFmode:
24557 : 544014 : if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24558 : : return V16SFmode;
24559 : 382874 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24560 : : return V8SFmode;
24561 : : else
24562 : 304367 : return V4SFmode;
24563 : :
24564 : 250579 : case E_DFmode:
24565 : 250579 : if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24566 : : return V8DFmode;
24567 : 158454 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24568 : : return V4DFmode;
24569 : 87797 : else if (TARGET_SSE2)
24570 : : return V2DFmode;
24571 : : /* FALLTHRU */
24572 : :
24573 : 62558 : default:
24574 : 62558 : return word_mode;
24575 : : }
24576 : : }
24577 : :
24578 : : /* If AVX is enabled then try vectorizing with both 256bit and 128bit
24579 : : vectors. If AVX512F is enabled then try vectorizing with 512bit,
24580 : : 256bit and 128bit vectors. */
24581 : :
24582 : : static unsigned int
24583 : 2176740 : ix86_autovectorize_vector_modes (vector_modes *modes, bool all)
24584 : : {
24585 : 2176740 : if (TARGET_AVX512F && TARGET_EVEX512 && !TARGET_PREFER_AVX256)
24586 : : {
24587 : 48553 : modes->safe_push (V64QImode);
24588 : 48553 : modes->safe_push (V32QImode);
24589 : 48553 : modes->safe_push (V16QImode);
24590 : : }
24591 : 2128187 : else if (TARGET_AVX512F && TARGET_EVEX512 && all)
24592 : : {
24593 : 555 : modes->safe_push (V32QImode);
24594 : 555 : modes->safe_push (V16QImode);
24595 : 555 : modes->safe_push (V64QImode);
24596 : : }
24597 : 2127632 : else if (TARGET_AVX && !TARGET_PREFER_AVX128)
24598 : : {
24599 : 47390 : modes->safe_push (V32QImode);
24600 : 47390 : modes->safe_push (V16QImode);
24601 : : }
24602 : 2080242 : else if (TARGET_AVX && all)
24603 : : {
24604 : 27 : modes->safe_push (V16QImode);
24605 : 27 : modes->safe_push (V32QImode);
24606 : : }
24607 : 2080215 : else if (TARGET_SSE2)
24608 : 2077978 : modes->safe_push (V16QImode);
24609 : :
24610 : 2176740 : if (TARGET_MMX_WITH_SSE)
24611 : 1703437 : modes->safe_push (V8QImode);
24612 : :
24613 : 2176740 : if (TARGET_SSE2)
24614 : 2174503 : modes->safe_push (V4QImode);
24615 : :
24616 : 2176740 : return 0;
24617 : : }
24618 : :
24619 : : /* Implemenation of targetm.vectorize.get_mask_mode. */
24620 : :
24621 : : static opt_machine_mode
24622 : 1727705 : ix86_get_mask_mode (machine_mode data_mode)
24623 : : {
24624 : 1727705 : unsigned vector_size = GET_MODE_SIZE (data_mode);
24625 : 1727705 : unsigned nunits = GET_MODE_NUNITS (data_mode);
24626 : 1727705 : unsigned elem_size = vector_size / nunits;
24627 : :
24628 : : /* Scalar mask case. */
24629 : 141083 : if ((TARGET_AVX512F && TARGET_EVEX512 && vector_size == 64)
24630 : 1699742 : || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
24631 : : /* AVX512FP16 only supports vector comparison
24632 : : to kmask for _Float16. */
24633 : 3379990 : || (TARGET_AVX512VL && TARGET_AVX512FP16
24634 : 562 : && GET_MODE_INNER (data_mode) == E_HFmode))
24635 : : {
24636 : 75623 : if (elem_size == 4
24637 : 75623 : || elem_size == 8
24638 : 23963 : || (TARGET_AVX512BW && (elem_size == 1 || elem_size == 2)))
24639 : 67610 : return smallest_int_mode_for_size (nunits);
24640 : : }
24641 : :
24642 : 1660095 : scalar_int_mode elem_mode
24643 : 1660095 : = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT);
24644 : :
24645 : 1660095 : gcc_assert (elem_size * nunits == vector_size);
24646 : :
24647 : 1660095 : return mode_for_vector (elem_mode, nunits);
24648 : : }
24649 : :
24650 : :
24651 : :
24652 : : /* Return class of registers which could be used for pseudo of MODE
24653 : : and of class RCLASS for spilling instead of memory. Return NO_REGS
24654 : : if it is not possible or non-profitable. */
24655 : :
24656 : : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657. */
24657 : :
24658 : : static reg_class_t
24659 : 6154635156 : ix86_spill_class (reg_class_t rclass, machine_mode mode)
24660 : : {
24661 : 6154635156 : if (0 && TARGET_GENERAL_REGS_SSE_SPILL
24662 : : && TARGET_SSE2
24663 : : && TARGET_INTER_UNIT_MOVES_TO_VEC
24664 : : && TARGET_INTER_UNIT_MOVES_FROM_VEC
24665 : : && (mode == SImode || (TARGET_64BIT && mode == DImode))
24666 : : && INTEGER_CLASS_P (rclass))
24667 : : return ALL_SSE_REGS;
24668 : 6154635156 : return NO_REGS;
24669 : : }
24670 : :
24671 : : /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST. Like the default implementation,
24672 : : but returns a lower bound. */
24673 : :
24674 : : static unsigned int
24675 : 1726971 : ix86_max_noce_ifcvt_seq_cost (edge e)
24676 : : {
24677 : 1726971 : bool predictable_p = predictable_edge_p (e);
24678 : 1726971 : if (predictable_p)
24679 : : {
24680 : 133093 : if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
24681 : 0 : return param_max_rtl_if_conversion_predictable_cost;
24682 : : }
24683 : : else
24684 : : {
24685 : 1593878 : if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
24686 : 92 : return param_max_rtl_if_conversion_unpredictable_cost;
24687 : : }
24688 : :
24689 : 1726879 : return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (2);
24690 : : }
24691 : :
24692 : : /* Return true if SEQ is a good candidate as a replacement for the
24693 : : if-convertible sequence described in IF_INFO. */
24694 : :
24695 : : static bool
24696 : 257160 : ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
24697 : : {
24698 : 257160 : if (TARGET_ONE_IF_CONV_INSN && if_info->speed_p)
24699 : : {
24700 : : int cmov_cnt = 0;
24701 : : /* Punt if SEQ contains more than one CMOV or FCMOV instruction.
24702 : : Maybe we should allow even more conditional moves as long as they
24703 : : are used far enough not to stall the CPU, or also consider
24704 : : IF_INFO->TEST_BB succ edge probabilities. */
24705 : 1007604 : for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
24706 : : {
24707 : 823666 : rtx set = single_set (insn);
24708 : 823666 : if (!set)
24709 : 2062 : continue;
24710 : 821604 : if (GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
24711 : 622165 : continue;
24712 : 199439 : rtx src = SET_SRC (set);
24713 : 199439 : machine_mode mode = GET_MODE (src);
24714 : 199439 : if (GET_MODE_CLASS (mode) != MODE_INT
24715 : 25196 : && GET_MODE_CLASS (mode) != MODE_FLOAT)
24716 : 0 : continue;
24717 : 199439 : if ((!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
24718 : 188208 : || (!REG_P (XEXP (src, 2)) && !MEM_P (XEXP (src, 2))))
24719 : 12857 : continue;
24720 : : /* insn is CMOV or FCMOV. */
24721 : 186582 : if (++cmov_cnt > 1)
24722 : : return false;
24723 : : }
24724 : : }
24725 : 241322 : return default_noce_conversion_profitable_p (seq, if_info);
24726 : : }
24727 : :
24728 : : /* x86-specific vector costs. */
24729 : : class ix86_vector_costs : public vector_costs
24730 : : {
24731 : : public:
24732 : : ix86_vector_costs (vec_info *, bool);
24733 : :
24734 : : unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
24735 : : stmt_vec_info stmt_info, slp_tree node,
24736 : : tree vectype, int misalign,
24737 : : vect_cost_model_location where) override;
24738 : : void finish_cost (const vector_costs *) override;
24739 : :
24740 : : private:
24741 : :
24742 : : /* Estimate register pressure of the vectorized code. */
24743 : : void ix86_vect_estimate_reg_pressure ();
24744 : : /* Number of GENERAL_REGS/SSE_REGS used in the vectorizer, it's used for
24745 : : estimation of register pressure.
24746 : : ??? Currently it's only used by vec_construct/scalar_to_vec
24747 : : where we know it's not loaded from memory. */
24748 : : unsigned m_num_gpr_needed[3];
24749 : : unsigned m_num_sse_needed[3];
24750 : : };
24751 : :
24752 : 1587339 : ix86_vector_costs::ix86_vector_costs (vec_info* vinfo, bool costing_for_scalar)
24753 : : : vector_costs (vinfo, costing_for_scalar),
24754 : 6349356 : m_num_gpr_needed (),
24755 : 9524034 : m_num_sse_needed ()
24756 : : {
24757 : 1587339 : }
24758 : :
24759 : : /* Implement targetm.vectorize.create_costs. */
24760 : :
24761 : : static vector_costs *
24762 : 1587339 : ix86_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
24763 : : {
24764 : 1587339 : return new ix86_vector_costs (vinfo, costing_for_scalar);
24765 : : }
24766 : :
24767 : : unsigned
24768 : 5755457 : ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
24769 : : stmt_vec_info stmt_info, slp_tree node,
24770 : : tree vectype, int misalign,
24771 : : vect_cost_model_location where)
24772 : : {
24773 : 5755457 : unsigned retval = 0;
24774 : 5755457 : bool scalar_p
24775 : : = (kind == scalar_stmt || kind == scalar_load || kind == scalar_store);
24776 : 5755457 : int stmt_cost = - 1;
24777 : :
24778 : 5755457 : bool fp = false;
24779 : 5755457 : machine_mode mode = scalar_p ? SImode : TImode;
24780 : :
24781 : 5755457 : if (vectype != NULL)
24782 : : {
24783 : 5589511 : fp = FLOAT_TYPE_P (vectype);
24784 : 5589511 : mode = TYPE_MODE (vectype);
24785 : 5589511 : if (scalar_p)
24786 : 3150933 : mode = TYPE_MODE (TREE_TYPE (vectype));
24787 : : }
24788 : :
24789 : 5755457 : if ((kind == vector_stmt || kind == scalar_stmt)
24790 : 1053393 : && stmt_info
24791 : 6805424 : && stmt_info->stmt && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
24792 : : {
24793 : 888982 : tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
24794 : : /*machine_mode inner_mode = mode;
24795 : : if (VECTOR_MODE_P (mode))
24796 : : inner_mode = GET_MODE_INNER (mode);*/
24797 : :
24798 : 888982 : switch (subcode)
24799 : : {
24800 : 419629 : case PLUS_EXPR:
24801 : 419629 : case POINTER_PLUS_EXPR:
24802 : 419629 : case MINUS_EXPR:
24803 : 419629 : if (kind == scalar_stmt)
24804 : : {
24805 : 274134 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
24806 : 68067 : stmt_cost = ix86_cost->addss;
24807 : 206067 : else if (X87_FLOAT_MODE_P (mode))
24808 : 62 : stmt_cost = ix86_cost->fadd;
24809 : : else
24810 : 206005 : stmt_cost = ix86_cost->add;
24811 : : }
24812 : : else
24813 : 145495 : stmt_cost = ix86_vec_cost (mode, fp ? ix86_cost->addss
24814 : : : ix86_cost->sse_op);
24815 : : break;
24816 : :
24817 : 156810 : case MULT_EXPR:
24818 : : /* For MULT_HIGHPART_EXPR, x86 only supports pmulhw,
24819 : : take it as MULT_EXPR. */
24820 : 156810 : case MULT_HIGHPART_EXPR:
24821 : 156810 : stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
24822 : 156810 : break;
24823 : : /* There's no direct instruction for WIDEN_MULT_EXPR,
24824 : : take emulation into account. */
24825 : 1460 : case WIDEN_MULT_EXPR:
24826 : 2920 : stmt_cost = ix86_widen_mult_cost (ix86_cost, mode,
24827 : 1460 : TYPE_UNSIGNED (vectype));
24828 : 1460 : break;
24829 : :
24830 : 6197 : case NEGATE_EXPR:
24831 : 6197 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
24832 : 1911 : stmt_cost = ix86_cost->sse_op;
24833 : 4286 : else if (X87_FLOAT_MODE_P (mode))
24834 : 0 : stmt_cost = ix86_cost->fchs;
24835 : 4286 : else if (VECTOR_MODE_P (mode))
24836 : 1899 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
24837 : : else
24838 : 2387 : stmt_cost = ix86_cost->add;
24839 : : break;
24840 : 7409 : case TRUNC_DIV_EXPR:
24841 : 7409 : case CEIL_DIV_EXPR:
24842 : 7409 : case FLOOR_DIV_EXPR:
24843 : 7409 : case ROUND_DIV_EXPR:
24844 : 7409 : case TRUNC_MOD_EXPR:
24845 : 7409 : case CEIL_MOD_EXPR:
24846 : 7409 : case FLOOR_MOD_EXPR:
24847 : 7409 : case RDIV_EXPR:
24848 : 7409 : case ROUND_MOD_EXPR:
24849 : 7409 : case EXACT_DIV_EXPR:
24850 : 7409 : stmt_cost = ix86_division_cost (ix86_cost, mode);
24851 : 7409 : break;
24852 : :
24853 : 37714 : case RSHIFT_EXPR:
24854 : 37714 : case LSHIFT_EXPR:
24855 : 37714 : case LROTATE_EXPR:
24856 : 37714 : case RROTATE_EXPR:
24857 : 37714 : {
24858 : 37714 : tree op1 = gimple_assign_rhs1 (stmt_info->stmt);
24859 : 37714 : tree op2 = gimple_assign_rhs2 (stmt_info->stmt);
24860 : 37714 : stmt_cost = ix86_shift_rotate_cost
24861 : 37714 : (ix86_cost,
24862 : : (subcode == RSHIFT_EXPR
24863 : 24855 : && !TYPE_UNSIGNED (TREE_TYPE (op1)))
24864 : : ? ASHIFTRT : LSHIFTRT, mode,
24865 : 37714 : TREE_CODE (op2) == INTEGER_CST,
24866 : 37714 : cst_and_fits_in_hwi (op2)
24867 : 24565 : ? int_cst_value (op2) : -1,
24868 : : false, false, NULL, NULL);
24869 : : }
24870 : 37714 : break;
24871 : 59577 : case NOP_EXPR:
24872 : : /* Only sign-conversions are free. */
24873 : 59577 : if (tree_nop_conversion_p
24874 : 59577 : (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt)),
24875 : 59577 : TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))))
24876 : 5755457 : stmt_cost = 0;
24877 : : break;
24878 : :
24879 : 104387 : case BIT_IOR_EXPR:
24880 : 104387 : case ABS_EXPR:
24881 : 104387 : case ABSU_EXPR:
24882 : 104387 : case MIN_EXPR:
24883 : 104387 : case MAX_EXPR:
24884 : 104387 : case BIT_XOR_EXPR:
24885 : 104387 : case BIT_AND_EXPR:
24886 : 104387 : case BIT_NOT_EXPR:
24887 : 104387 : if (SSE_FLOAT_MODE_SSEMATH_OR_HF_P (mode))
24888 : 917 : stmt_cost = ix86_cost->sse_op;
24889 : 103470 : else if (VECTOR_MODE_P (mode))
24890 : 41232 : stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
24891 : : else
24892 : 62238 : stmt_cost = ix86_cost->add;
24893 : : break;
24894 : : default:
24895 : : break;
24896 : : }
24897 : : }
24898 : :
24899 : 5755457 : combined_fn cfn;
24900 : 5755457 : if ((kind == vector_stmt || kind == scalar_stmt)
24901 : 1053393 : && stmt_info
24902 : 1049967 : && stmt_info->stmt
24903 : 6805424 : && (cfn = gimple_call_combined_fn (stmt_info->stmt)) != CFN_LAST)
24904 : 15453 : switch (cfn)
24905 : : {
24906 : 28 : case CFN_FMA:
24907 : 28 : stmt_cost = ix86_vec_cost (mode,
24908 : 28 : mode == SFmode ? ix86_cost->fmass
24909 : : : ix86_cost->fmasd);
24910 : 28 : break;
24911 : 12 : case CFN_MULH:
24912 : 12 : stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
24913 : 12 : break;
24914 : : default:
24915 : : break;
24916 : : }
24917 : :
24918 : : /* If we do elementwise loads into a vector then we are bound by
24919 : : latency and execution resources for the many scalar loads
24920 : : (AGU and load ports). Try to account for this by scaling the
24921 : : construction cost by the number of elements involved. */
24922 : 5755457 : if ((kind == vec_construct || kind == vec_to_scalar)
24923 : 518012 : && stmt_info
24924 : 287063 : && (STMT_VINFO_TYPE (stmt_info) == load_vec_info_type
24925 : 287063 : || STMT_VINFO_TYPE (stmt_info) == store_vec_info_type)
24926 : 174672 : && ((STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_ELEMENTWISE
24927 : 135644 : && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF (stmt_info)))
24928 : : != INTEGER_CST))
24929 : 144644 : || STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) == VMAT_GATHER_SCATTER))
24930 : : {
24931 : 34748 : stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
24932 : 34748 : stmt_cost *= (TYPE_VECTOR_SUBPARTS (vectype) + 1);
24933 : : }
24934 : 5720709 : else if ((kind == vec_construct || kind == scalar_to_vec)
24935 : 479840 : && node
24936 : 253119 : && SLP_TREE_DEF_TYPE (node) == vect_external_def)
24937 : : {
24938 : 253119 : stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
24939 : 253119 : unsigned i;
24940 : 253119 : tree op;
24941 : 1100947 : FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
24942 : 594709 : if (TREE_CODE (op) == SSA_NAME)
24943 : 466159 : TREE_VISITED (op) = 0;
24944 : 1100947 : FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
24945 : : {
24946 : 757592 : if (TREE_CODE (op) != SSA_NAME
24947 : 594709 : || TREE_VISITED (op))
24948 : 162883 : continue;
24949 : 431826 : TREE_VISITED (op) = 1;
24950 : 431826 : gimple *def = SSA_NAME_DEF_STMT (op);
24951 : 431826 : tree tem;
24952 : 431826 : if (is_gimple_assign (def)
24953 : 244015 : && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
24954 : 29369 : && ((tem = gimple_assign_rhs1 (def)), true)
24955 : 29369 : && TREE_CODE (tem) == SSA_NAME
24956 : : /* A sign-change expands to nothing. */
24957 : 461027 : && tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (def)),
24958 : 29201 : TREE_TYPE (tem)))
24959 : 7621 : def = SSA_NAME_DEF_STMT (tem);
24960 : : /* When the component is loaded from memory we can directly
24961 : : move it to a vector register, otherwise we have to go
24962 : : via a GPR or via vpinsr which involves similar cost.
24963 : : Likewise with a BIT_FIELD_REF extracting from a vector
24964 : : register we can hope to avoid using a GPR. */
24965 : 431826 : if (!is_gimple_assign (def)
24966 : 431826 : || ((!gimple_assign_load_p (def)
24967 : 117146 : || (!TARGET_SSE4_1
24968 : 225608 : && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op))) == 1))
24969 : 128510 : && (gimple_assign_rhs_code (def) != BIT_FIELD_REF
24970 : 9684 : || !VECTOR_TYPE_P (TREE_TYPE
24971 : : (TREE_OPERAND (gimple_assign_rhs1 (def), 0))))))
24972 : : {
24973 : 308113 : if (fp)
24974 : 11594 : m_num_sse_needed[where]++;
24975 : : else
24976 : : {
24977 : 296519 : m_num_gpr_needed[where]++;
24978 : 296519 : stmt_cost += ix86_cost->sse_to_integer;
24979 : : }
24980 : : }
24981 : : }
24982 : 847828 : FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
24983 : 594709 : if (TREE_CODE (op) == SSA_NAME)
24984 : 466159 : TREE_VISITED (op) = 0;
24985 : : }
24986 : 5755457 : if (stmt_cost == -1)
24987 : 4733944 : stmt_cost = ix86_builtin_vectorization_cost (kind, vectype, misalign);
24988 : :
24989 : : /* Penalize DFmode vector operations for Bonnell. */
24990 : 5755457 : if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
24991 : 5755517 : && vectype && GET_MODE_INNER (TYPE_MODE (vectype)) == DFmode)
24992 : 8 : stmt_cost *= 5; /* FIXME: The value here is arbitrary. */
24993 : :
24994 : : /* Statements in an inner loop relative to the loop being
24995 : : vectorized are weighted more heavily. The value here is
24996 : : arbitrary and could potentially be improved with analysis. */
24997 : 5755457 : retval = adjust_cost_for_freq (stmt_info, where, count * stmt_cost);
24998 : :
24999 : : /* We need to multiply all vector stmt cost by 1.7 (estimated cost)
25000 : : for Silvermont as it has out of order integer pipeline and can execute
25001 : : 2 scalar instruction per tick, but has in order SIMD pipeline. */
25002 : 5755457 : if ((TARGET_CPU_P (SILVERMONT) || TARGET_CPU_P (GOLDMONT)
25003 : 5755457 : || TARGET_CPU_P (GOLDMONT_PLUS) || TARGET_CPU_P (INTEL))
25004 : 2191 : && stmt_info && stmt_info->stmt)
25005 : : {
25006 : 2099 : tree lhs_op = gimple_get_lhs (stmt_info->stmt);
25007 : 2099 : if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE)
25008 : 1655 : retval = (retval * 17) / 10;
25009 : : }
25010 : :
25011 : 5755457 : m_costs[where] += retval;
25012 : :
25013 : 5755457 : return retval;
25014 : : }
25015 : :
25016 : : void
25017 : 1454004 : ix86_vector_costs::ix86_vect_estimate_reg_pressure ()
25018 : : {
25019 : 1454004 : unsigned gpr_spill_cost = COSTS_N_INSNS (ix86_cost->int_store [2]) / 2;
25020 : 1454004 : unsigned sse_spill_cost = COSTS_N_INSNS (ix86_cost->sse_store[0]) / 2;
25021 : :
25022 : : /* Any better way to have target available fp registers, currently use SSE_REGS. */
25023 : 1454004 : unsigned target_avail_sse = TARGET_64BIT ? (TARGET_AVX512F ? 32 : 16) : 8;
25024 : 5816016 : for (unsigned i = 0; i != 3; i++)
25025 : : {
25026 : 4362012 : if (m_num_gpr_needed[i] > target_avail_regs)
25027 : 691 : m_costs[i] += gpr_spill_cost * (m_num_gpr_needed[i] - target_avail_regs);
25028 : : /* Only measure sse registers pressure. */
25029 : 4362012 : if (TARGET_SSE && (m_num_sse_needed[i] > target_avail_sse))
25030 : 103 : m_costs[i] += sse_spill_cost * (m_num_sse_needed[i] - target_avail_sse);
25031 : : }
25032 : 1454004 : }
25033 : :
25034 : : void
25035 : 1454004 : ix86_vector_costs::finish_cost (const vector_costs *scalar_costs)
25036 : : {
25037 : 1454004 : loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
25038 : 207888 : if (loop_vinfo && !m_costing_for_scalar)
25039 : : {
25040 : : /* We are currently not asking the vectorizer to compare costs
25041 : : between different vector mode sizes. When using predication
25042 : : that will end up always choosing the prefered mode size even
25043 : : if there's a smaller mode covering all lanes. Test for this
25044 : : situation and artificially reject the larger mode attempt.
25045 : : ??? We currently lack masked ops for sub-SSE sized modes,
25046 : : so we could restrict this rejection to AVX and AVX512 modes
25047 : : but error on the safe side for now. */
25048 : 37711 : if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
25049 : 8 : && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
25050 : 8 : && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
25051 : 37716 : && (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())
25052 : 10 : > ceil_log2 (LOOP_VINFO_INT_NITERS (loop_vinfo))))
25053 : 3 : m_costs[vect_body] = INT_MAX;
25054 : : }
25055 : :
25056 : 1454004 : ix86_vect_estimate_reg_pressure ();
25057 : :
25058 : 1454004 : vector_costs::finish_cost (scalar_costs);
25059 : 1454004 : }
25060 : :
25061 : : /* Validate target specific memory model bits in VAL. */
25062 : :
25063 : : static unsigned HOST_WIDE_INT
25064 : 479938 : ix86_memmodel_check (unsigned HOST_WIDE_INT val)
25065 : : {
25066 : 479938 : enum memmodel model = memmodel_from_int (val);
25067 : 479938 : bool strong;
25068 : :
25069 : 479938 : if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
25070 : : |MEMMODEL_MASK)
25071 : 479933 : || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
25072 : : {
25073 : 5 : warning (OPT_Winvalid_memory_model,
25074 : : "unknown architecture specific memory model");
25075 : 5 : return MEMMODEL_SEQ_CST;
25076 : : }
25077 : 479933 : strong = (is_mm_acq_rel (model) || is_mm_seq_cst (model));
25078 : 479933 : if (val & IX86_HLE_ACQUIRE && !(is_mm_acquire (model) || strong))
25079 : : {
25080 : 0 : warning (OPT_Winvalid_memory_model,
25081 : : "%<HLE_ACQUIRE%> not used with %<ACQUIRE%> or stronger "
25082 : : "memory model");
25083 : 0 : return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
25084 : : }
25085 : 479933 : if (val & IX86_HLE_RELEASE && !(is_mm_release (model) || strong))
25086 : : {
25087 : 0 : warning (OPT_Winvalid_memory_model,
25088 : : "%<HLE_RELEASE%> not used with %<RELEASE%> or stronger "
25089 : : "memory model");
25090 : 0 : return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
25091 : : }
25092 : : return val;
25093 : : }
25094 : :
25095 : : /* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
25096 : : CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
25097 : : CLONEI->simdlen. Return 0 if SIMD clones shouldn't be emitted,
25098 : : or number of vecsize_mangle variants that should be emitted. */
25099 : :
25100 : : static int
25101 : 8077 : ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
25102 : : struct cgraph_simd_clone *clonei,
25103 : : tree base_type, int num,
25104 : : bool explicit_p)
25105 : : {
25106 : 8077 : int ret = 1;
25107 : :
25108 : 8077 : if (clonei->simdlen
25109 : 8077 : && (clonei->simdlen < 2
25110 : 1361 : || clonei->simdlen > 1024
25111 : 9438 : || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
25112 : : {
25113 : 0 : if (explicit_p)
25114 : 0 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
25115 : : "unsupported simdlen %wd", clonei->simdlen.to_constant ());
25116 : 0 : return 0;
25117 : : }
25118 : :
25119 : 8077 : tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
25120 : 8077 : if (TREE_CODE (ret_type) != VOID_TYPE)
25121 : 7277 : switch (TYPE_MODE (ret_type))
25122 : : {
25123 : 7277 : case E_QImode:
25124 : 7277 : case E_HImode:
25125 : 7277 : case E_SImode:
25126 : 7277 : case E_DImode:
25127 : 7277 : case E_SFmode:
25128 : 7277 : case E_DFmode:
25129 : : /* case E_SCmode: */
25130 : : /* case E_DCmode: */
25131 : 7277 : if (!AGGREGATE_TYPE_P (ret_type))
25132 : : break;
25133 : : /* FALLTHRU */
25134 : 2 : default:
25135 : 2 : if (explicit_p)
25136 : 2 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
25137 : : "unsupported return type %qT for simd", ret_type);
25138 : 2 : return 0;
25139 : : }
25140 : :
25141 : 8075 : tree t;
25142 : 8075 : int i;
25143 : 8075 : tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
25144 : 8075 : bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
25145 : :
25146 : 8075 : for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
25147 : 22080 : t && t != void_list_node; t = TREE_CHAIN (t), i++)
25148 : : {
25149 : 17900 : tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
25150 : 14010 : switch (TYPE_MODE (arg_type))
25151 : : {
25152 : 13989 : case E_QImode:
25153 : 13989 : case E_HImode:
25154 : 13989 : case E_SImode:
25155 : 13989 : case E_DImode:
25156 : 13989 : case E_SFmode:
25157 : 13989 : case E_DFmode:
25158 : : /* case E_SCmode: */
25159 : : /* case E_DCmode: */
25160 : 13989 : if (!AGGREGATE_TYPE_P (arg_type))
25161 : : break;
25162 : : /* FALLTHRU */
25163 : 43 : default:
25164 : 43 : if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
25165 : : break;
25166 : 5 : if (explicit_p)
25167 : 5 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
25168 : : "unsupported argument type %qT for simd", arg_type);
25169 : : return 0;
25170 : : }
25171 : : }
25172 : :
25173 : 8070 : if (!TREE_PUBLIC (node->decl) || !explicit_p)
25174 : : {
25175 : : /* If the function isn't exported, we can pick up just one ISA
25176 : : for the clones. */
25177 : 118 : if (TARGET_AVX512F && TARGET_EVEX512)
25178 : 0 : clonei->vecsize_mangle = 'e';
25179 : 118 : else if (TARGET_AVX2)
25180 : 1 : clonei->vecsize_mangle = 'd';
25181 : 117 : else if (TARGET_AVX)
25182 : 88 : clonei->vecsize_mangle = 'c';
25183 : : else
25184 : 29 : clonei->vecsize_mangle = 'b';
25185 : : ret = 1;
25186 : : }
25187 : : else
25188 : : {
25189 : 7952 : clonei->vecsize_mangle = "bcde"[num];
25190 : 7952 : ret = 4;
25191 : : }
25192 : 8070 : clonei->mask_mode = VOIDmode;
25193 : 8070 : switch (clonei->vecsize_mangle)
25194 : : {
25195 : 2017 : case 'b':
25196 : 2017 : clonei->vecsize_int = 128;
25197 : 2017 : clonei->vecsize_float = 128;
25198 : 2017 : break;
25199 : 2076 : case 'c':
25200 : 2076 : clonei->vecsize_int = 128;
25201 : 2076 : clonei->vecsize_float = 256;
25202 : 2076 : break;
25203 : 1989 : case 'd':
25204 : 1989 : clonei->vecsize_int = 256;
25205 : 1989 : clonei->vecsize_float = 256;
25206 : 1989 : break;
25207 : 1988 : case 'e':
25208 : 1988 : clonei->vecsize_int = 512;
25209 : 1988 : clonei->vecsize_float = 512;
25210 : 1988 : if (TYPE_MODE (base_type) == QImode)
25211 : 15 : clonei->mask_mode = DImode;
25212 : : else
25213 : 1973 : clonei->mask_mode = SImode;
25214 : : break;
25215 : : }
25216 : 8070 : if (clonei->simdlen == 0)
25217 : : {
25218 : 6709 : if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
25219 : 3653 : clonei->simdlen = clonei->vecsize_int;
25220 : : else
25221 : 3056 : clonei->simdlen = clonei->vecsize_float;
25222 : 6709 : clonei->simdlen = clonei->simdlen
25223 : 13418 : / GET_MODE_BITSIZE (TYPE_MODE (base_type));
25224 : : }
25225 : 1361 : else if (clonei->simdlen > 16)
25226 : : {
25227 : : /* For compatibility with ICC, use the same upper bounds
25228 : : for simdlen. In particular, for CTYPE below, use the return type,
25229 : : unless the function returns void, in that case use the characteristic
25230 : : type. If it is possible for given SIMDLEN to pass CTYPE value
25231 : : in registers (8 [XYZ]MM* regs for 32-bit code, 16 [XYZ]MM* regs
25232 : : for 64-bit code), accept that SIMDLEN, otherwise warn and don't
25233 : : emit corresponding clone. */
25234 : 0 : tree ctype = ret_type;
25235 : 0 : if (VOID_TYPE_P (ret_type))
25236 : 0 : ctype = base_type;
25237 : 0 : int cnt = GET_MODE_BITSIZE (TYPE_MODE (ctype)) * clonei->simdlen;
25238 : 0 : if (SCALAR_INT_MODE_P (TYPE_MODE (ctype)))
25239 : 0 : cnt /= clonei->vecsize_int;
25240 : : else
25241 : 0 : cnt /= clonei->vecsize_float;
25242 : 0 : if (cnt > (TARGET_64BIT ? 16 : 8))
25243 : : {
25244 : 0 : if (explicit_p)
25245 : 0 : warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
25246 : : "unsupported simdlen %wd",
25247 : : clonei->simdlen.to_constant ());
25248 : 0 : return 0;
25249 : : }
25250 : : }
25251 : : return ret;
25252 : : }
25253 : :
25254 : : /* If SIMD clone NODE can't be used in a vectorized loop
25255 : : in current function, return -1, otherwise return a badness of using it
25256 : : (0 if it is most desirable from vecsize_mangle point of view, 1
25257 : : slightly less desirable, etc.). */
25258 : :
25259 : : static int
25260 : 1723 : ix86_simd_clone_usable (struct cgraph_node *node)
25261 : : {
25262 : 1723 : switch (node->simdclone->vecsize_mangle)
25263 : : {
25264 : 663 : case 'b':
25265 : 663 : if (!TARGET_SSE2)
25266 : : return -1;
25267 : 663 : if (!TARGET_AVX)
25268 : : return 0;
25269 : 539 : return (TARGET_AVX512F && TARGET_EVEX512) ? 3 : TARGET_AVX2 ? 2 : 1;
25270 : 613 : case 'c':
25271 : 613 : if (!TARGET_AVX)
25272 : : return -1;
25273 : 572 : return (TARGET_AVX512F && TARGET_EVEX512) ? 2 : TARGET_AVX2 ? 1 : 0;
25274 : 295 : case 'd':
25275 : 295 : if (!TARGET_AVX2)
25276 : : return -1;
25277 : 107 : return (TARGET_AVX512F && TARGET_EVEX512) ? 1 : 0;
25278 : 152 : case 'e':
25279 : 152 : if (!TARGET_AVX512F || !TARGET_EVEX512)
25280 : 117 : return -1;
25281 : : return 0;
25282 : 0 : default:
25283 : 0 : gcc_unreachable ();
25284 : : }
25285 : : }
25286 : :
25287 : : /* This function adjusts the unroll factor based on
25288 : : the hardware capabilities. For ex, bdver3 has
25289 : : a loop buffer which makes unrolling of smaller
25290 : : loops less important. This function decides the
25291 : : unroll factor using number of memory references
25292 : : (value 32 is used) as a heuristic. */
25293 : :
25294 : : static unsigned
25295 : 660357 : ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
25296 : : {
25297 : 660357 : basic_block *bbs;
25298 : 660357 : rtx_insn *insn;
25299 : 660357 : unsigned i;
25300 : 660357 : unsigned mem_count = 0;
25301 : :
25302 : : /* Unroll small size loop when unroll factor is not explicitly
25303 : : specified. */
25304 : 660357 : if (ix86_unroll_only_small_loops && !loop->unroll)
25305 : : {
25306 : 622394 : if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
25307 : 62762 : return MIN (nunroll, ix86_cost->small_unroll_factor);
25308 : : else
25309 : : return 1;
25310 : : }
25311 : :
25312 : 37963 : if (!TARGET_ADJUST_UNROLL)
25313 : : return nunroll;
25314 : :
25315 : : /* Count the number of memory references within the loop body.
25316 : : This value determines the unrolling factor for bdver3 and bdver4
25317 : : architectures. */
25318 : 7 : subrtx_iterator::array_type array;
25319 : 7 : bbs = get_loop_body (loop);
25320 : 21 : for (i = 0; i < loop->num_nodes; i++)
25321 : 102 : FOR_BB_INSNS (bbs[i], insn)
25322 : 88 : if (NONDEBUG_INSN_P (insn))
25323 : 464 : FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
25324 : 404 : if (const_rtx x = *iter)
25325 : 404 : if (MEM_P (x))
25326 : : {
25327 : 25 : machine_mode mode = GET_MODE (x);
25328 : 50 : unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
25329 : 25 : if (n_words > 4)
25330 : 0 : mem_count += 2;
25331 : : else
25332 : 25 : mem_count += 1;
25333 : : }
25334 : 7 : free (bbs);
25335 : :
25336 : 7 : if (mem_count && mem_count <=32)
25337 : 7 : return MIN (nunroll, 32 / mem_count);
25338 : :
25339 : : return nunroll;
25340 : 7 : }
25341 : :
25342 : :
25343 : : /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P. */
25344 : :
25345 : : static bool
25346 : 411694 : ix86_float_exceptions_rounding_supported_p (void)
25347 : : {
25348 : : /* For x87 floating point with standard excess precision handling,
25349 : : there is no adddf3 pattern (since x87 floating point only has
25350 : : XFmode operations) so the default hook implementation gets this
25351 : : wrong. */
25352 : 411694 : return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
25353 : : }
25354 : :
25355 : : /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV. */
25356 : :
25357 : : static void
25358 : 7054 : ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
25359 : : {
25360 : 7054 : if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
25361 : : return;
25362 : 7054 : tree exceptions_var = create_tmp_var_raw (integer_type_node);
25363 : 7054 : if (TARGET_80387)
25364 : : {
25365 : 7054 : tree fenv_index_type = build_index_type (size_int (6));
25366 : 7054 : tree fenv_type = build_array_type (unsigned_type_node, fenv_index_type);
25367 : 7054 : tree fenv_var = create_tmp_var_raw (fenv_type);
25368 : 7054 : TREE_ADDRESSABLE (fenv_var) = 1;
25369 : 7054 : tree fenv_ptr = build_pointer_type (fenv_type);
25370 : 7054 : tree fenv_addr = build1 (ADDR_EXPR, fenv_ptr, fenv_var);
25371 : 7054 : fenv_addr = fold_convert (ptr_type_node, fenv_addr);
25372 : 7054 : tree fnstenv = get_ix86_builtin (IX86_BUILTIN_FNSTENV);
25373 : 7054 : tree fldenv = get_ix86_builtin (IX86_BUILTIN_FLDENV);
25374 : 7054 : tree fnstsw = get_ix86_builtin (IX86_BUILTIN_FNSTSW);
25375 : 7054 : tree fnclex = get_ix86_builtin (IX86_BUILTIN_FNCLEX);
25376 : 7054 : tree hold_fnstenv = build_call_expr (fnstenv, 1, fenv_addr);
25377 : 7054 : tree hold_fnclex = build_call_expr (fnclex, 0);
25378 : 7054 : fenv_var = build4 (TARGET_EXPR, fenv_type, fenv_var, hold_fnstenv,
25379 : : NULL_TREE, NULL_TREE);
25380 : 7054 : *hold = build2 (COMPOUND_EXPR, void_type_node, fenv_var,
25381 : : hold_fnclex);
25382 : 7054 : *clear = build_call_expr (fnclex, 0);
25383 : 7054 : tree sw_var = create_tmp_var_raw (short_unsigned_type_node);
25384 : 7054 : tree fnstsw_call = build_call_expr (fnstsw, 0);
25385 : 7054 : tree sw_mod = build4 (TARGET_EXPR, short_unsigned_type_node, sw_var,
25386 : : fnstsw_call, NULL_TREE, NULL_TREE);
25387 : 7054 : tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
25388 : 7054 : tree update_mod = build4 (TARGET_EXPR, integer_type_node,
25389 : : exceptions_var, exceptions_x87,
25390 : : NULL_TREE, NULL_TREE);
25391 : 7054 : *update = build2 (COMPOUND_EXPR, integer_type_node,
25392 : : sw_mod, update_mod);
25393 : 7054 : tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
25394 : 7054 : *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
25395 : : }
25396 : 7054 : if (TARGET_SSE && TARGET_SSE_MATH)
25397 : : {
25398 : 7054 : tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
25399 : 7054 : tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
25400 : 7054 : tree stmxcsr = get_ix86_builtin (IX86_BUILTIN_STMXCSR);
25401 : 7054 : tree ldmxcsr = get_ix86_builtin (IX86_BUILTIN_LDMXCSR);
25402 : 7054 : tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
25403 : 7054 : tree hold_assign_orig = build4 (TARGET_EXPR, unsigned_type_node,
25404 : : mxcsr_orig_var, stmxcsr_hold_call,
25405 : : NULL_TREE, NULL_TREE);
25406 : 7054 : tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
25407 : : mxcsr_orig_var,
25408 : 7054 : build_int_cst (unsigned_type_node, 0x1f80));
25409 : 7054 : hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
25410 : 7054 : build_int_cst (unsigned_type_node, 0xffffffc0));
25411 : 7054 : tree hold_assign_mod = build4 (TARGET_EXPR, unsigned_type_node,
25412 : : mxcsr_mod_var, hold_mod_val,
25413 : : NULL_TREE, NULL_TREE);
25414 : 7054 : tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
25415 : 7054 : tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
25416 : : hold_assign_orig, hold_assign_mod);
25417 : 7054 : hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
25418 : : ldmxcsr_hold_call);
25419 : 7054 : if (*hold)
25420 : 7054 : *hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
25421 : : else
25422 : 0 : *hold = hold_all;
25423 : 7054 : tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
25424 : 7054 : if (*clear)
25425 : 7054 : *clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
25426 : : ldmxcsr_clear_call);
25427 : : else
25428 : 0 : *clear = ldmxcsr_clear_call;
25429 : 7054 : tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
25430 : 7054 : tree exceptions_sse = fold_convert (integer_type_node,
25431 : : stxmcsr_update_call);
25432 : 7054 : if (*update)
25433 : : {
25434 : 7054 : tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
25435 : : exceptions_var, exceptions_sse);
25436 : 7054 : tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
25437 : : exceptions_var, exceptions_mod);
25438 : 7054 : *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
25439 : : exceptions_assign);
25440 : : }
25441 : : else
25442 : 0 : *update = build4 (TARGET_EXPR, integer_type_node, exceptions_var,
25443 : : exceptions_sse, NULL_TREE, NULL_TREE);
25444 : 7054 : tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
25445 : 7054 : *update = build2 (COMPOUND_EXPR, void_type_node, *update,
25446 : : ldmxcsr_update_call);
25447 : : }
25448 : 7054 : tree atomic_feraiseexcept
25449 : 7054 : = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
25450 : 7054 : tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
25451 : : 1, exceptions_var);
25452 : 7054 : *update = build2 (COMPOUND_EXPR, void_type_node, *update,
25453 : : atomic_feraiseexcept_call);
25454 : : }
25455 : :
25456 : : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
25457 : : /* For i386, common symbol is local only for non-PIE binaries. For
25458 : : x86-64, common symbol is local only for non-PIE binaries or linker
25459 : : supports copy reloc in PIE binaries. */
25460 : :
25461 : : static bool
25462 : 640375526 : ix86_binds_local_p (const_tree exp)
25463 : : {
25464 : 640375526 : bool direct_extern_access
25465 : 640375526 : = (ix86_direct_extern_access
25466 : 1277299510 : && !(VAR_OR_FUNCTION_DECL_P (exp)
25467 : 636923984 : && lookup_attribute ("nodirect_extern_access",
25468 : 636923984 : DECL_ATTRIBUTES (exp))));
25469 : 640375526 : if (!direct_extern_access)
25470 : 950 : ix86_has_no_direct_extern_access = true;
25471 : 640375526 : return default_binds_local_p_3 (exp, flag_shlib != 0, true,
25472 : : direct_extern_access,
25473 : : (direct_extern_access
25474 : 640374576 : && (!flag_pic
25475 : 124132620 : || (TARGET_64BIT
25476 : 640375526 : && HAVE_LD_PIE_COPYRELOC != 0))));
25477 : : }
25478 : :
25479 : : /* If flag_pic or ix86_direct_extern_access is false, then neither
25480 : : local nor global relocs should be placed in readonly memory. */
25481 : :
25482 : : static int
25483 : 5154843 : ix86_reloc_rw_mask (void)
25484 : : {
25485 : 5154843 : return (flag_pic || !ix86_direct_extern_access) ? 3 : 0;
25486 : : }
25487 : : #endif
25488 : :
25489 : : /* Return true iff ADDR can be used as a symbolic base address. */
25490 : :
25491 : : static bool
25492 : 3885 : symbolic_base_address_p (rtx addr)
25493 : : {
25494 : 0 : if (GET_CODE (addr) == SYMBOL_REF)
25495 : : return true;
25496 : :
25497 : 3816 : if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
25498 : 0 : return true;
25499 : :
25500 : : return false;
25501 : : }
25502 : :
25503 : : /* Return true iff ADDR can be used as a base address. */
25504 : :
25505 : : static bool
25506 : 6020 : base_address_p (rtx addr)
25507 : : {
25508 : 0 : if (REG_P (addr))
25509 : : return true;
25510 : :
25511 : 3660 : if (symbolic_base_address_p (addr))
25512 : 0 : return true;
25513 : :
25514 : : return false;
25515 : : }
25516 : :
25517 : : /* If MEM is in the form of [(base+symbase)+offset], extract the three
25518 : : parts of address and set to BASE, SYMBASE and OFFSET, otherwise
25519 : : return false. */
25520 : :
25521 : : static bool
25522 : 3671 : extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
25523 : : {
25524 : 3671 : rtx addr;
25525 : :
25526 : 3671 : gcc_assert (MEM_P (mem));
25527 : :
25528 : 3671 : addr = XEXP (mem, 0);
25529 : :
25530 : 3671 : if (GET_CODE (addr) == CONST)
25531 : 52 : addr = XEXP (addr, 0);
25532 : :
25533 : 3671 : if (base_address_p (addr))
25534 : : {
25535 : 1322 : *base = addr;
25536 : 1322 : *symbase = const0_rtx;
25537 : 1322 : *offset = const0_rtx;
25538 : 1322 : return true;
25539 : : }
25540 : :
25541 : 2349 : if (GET_CODE (addr) == PLUS
25542 : 2349 : && base_address_p (XEXP (addr, 0)))
25543 : : {
25544 : 1103 : rtx addend = XEXP (addr, 1);
25545 : :
25546 : 1103 : if (GET_CODE (addend) == CONST)
25547 : 4 : addend = XEXP (addend, 0);
25548 : :
25549 : 1103 : if (CONST_INT_P (addend))
25550 : : {
25551 : 882 : *base = XEXP (addr, 0);
25552 : 882 : *symbase = const0_rtx;
25553 : 882 : *offset = addend;
25554 : 882 : return true;
25555 : : }
25556 : :
25557 : : /* Also accept REG + symbolic ref, with or without a CONST_INT
25558 : : offset. */
25559 : 221 : if (REG_P (XEXP (addr, 0)))
25560 : : {
25561 : 221 : if (symbolic_base_address_p (addend))
25562 : : {
25563 : 0 : *base = XEXP (addr, 0);
25564 : 0 : *symbase = addend;
25565 : 0 : *offset = const0_rtx;
25566 : 0 : return true;
25567 : : }
25568 : :
25569 : 221 : if (GET_CODE (addend) == PLUS
25570 : 4 : && symbolic_base_address_p (XEXP (addend, 0))
25571 : 225 : && CONST_INT_P (XEXP (addend, 1)))
25572 : : {
25573 : 4 : *base = XEXP (addr, 0);
25574 : 4 : *symbase = XEXP (addend, 0);
25575 : 4 : *offset = XEXP (addend, 1);
25576 : 4 : return true;
25577 : : }
25578 : : }
25579 : : }
25580 : :
25581 : : return false;
25582 : : }
25583 : :
25584 : : /* Given OPERANDS of consecutive load/store, check if we can merge
25585 : : them into move multiple. LOAD is true if they are load instructions.
25586 : : MODE is the mode of memory operands. */
25587 : :
25588 : : bool
25589 : 1987 : ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
25590 : : machine_mode mode)
25591 : : {
25592 : 1987 : HOST_WIDE_INT offval_1, offval_2, msize;
25593 : 1987 : rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
25594 : : symbase_1, symbase_2, offset_1, offset_2;
25595 : :
25596 : 1987 : if (load)
25597 : : {
25598 : 1696 : mem_1 = operands[1];
25599 : 1696 : mem_2 = operands[3];
25600 : 1696 : reg_1 = operands[0];
25601 : 1696 : reg_2 = operands[2];
25602 : : }
25603 : : else
25604 : : {
25605 : 291 : mem_1 = operands[0];
25606 : 291 : mem_2 = operands[2];
25607 : 291 : reg_1 = operands[1];
25608 : 291 : reg_2 = operands[3];
25609 : : }
25610 : :
25611 : 1987 : gcc_assert (REG_P (reg_1) && REG_P (reg_2));
25612 : :
25613 : 1987 : if (REGNO (reg_1) != REGNO (reg_2))
25614 : : return false;
25615 : :
25616 : : /* Check if the addresses are in the form of [base+offset]. */
25617 : 1987 : if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
25618 : : return false;
25619 : 1684 : if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
25620 : : return false;
25621 : :
25622 : : /* Check if the bases are the same. */
25623 : 524 : if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))
25624 : 106 : return false;
25625 : :
25626 : 418 : offval_1 = INTVAL (offset_1);
25627 : 418 : offval_2 = INTVAL (offset_2);
25628 : 418 : msize = GET_MODE_SIZE (mode);
25629 : : /* Check if mem_1 is adjacent to mem_2 and mem_1 has lower address. */
25630 : 418 : if (offval_1 + msize != offval_2)
25631 : : return false;
25632 : :
25633 : : return true;
25634 : : }
25635 : :
25636 : : /* Implement the TARGET_OPTAB_SUPPORTED_P hook. */
25637 : :
25638 : : static bool
25639 : 205413 : ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
25640 : : optimization_type opt_type)
25641 : : {
25642 : 205413 : switch (op)
25643 : : {
25644 : 209 : case asin_optab:
25645 : 209 : case acos_optab:
25646 : 209 : case log1p_optab:
25647 : 209 : case exp_optab:
25648 : 209 : case exp10_optab:
25649 : 209 : case exp2_optab:
25650 : 209 : case expm1_optab:
25651 : 209 : case ldexp_optab:
25652 : 209 : case scalb_optab:
25653 : 209 : case round_optab:
25654 : 209 : case lround_optab:
25655 : 209 : return opt_type == OPTIMIZE_FOR_SPEED;
25656 : :
25657 : 264 : case rint_optab:
25658 : 264 : if (SSE_FLOAT_MODE_P (mode1)
25659 : 145 : && TARGET_SSE_MATH
25660 : 129 : && !flag_trapping_math
25661 : 21 : && !TARGET_SSE4_1
25662 : : && mode1 != HFmode)
25663 : 21 : return opt_type == OPTIMIZE_FOR_SPEED;
25664 : : return true;
25665 : :
25666 : 1787 : case floor_optab:
25667 : 1787 : case ceil_optab:
25668 : 1787 : case btrunc_optab:
25669 : 1787 : if (((SSE_FLOAT_MODE_P (mode1)
25670 : 1439 : && TARGET_SSE_MATH
25671 : 1346 : && TARGET_SSE4_1)
25672 : 1738 : || mode1 == HFmode)
25673 : 118 : && !flag_trapping_math)
25674 : : return true;
25675 : 1727 : return opt_type == OPTIMIZE_FOR_SPEED;
25676 : :
25677 : 86 : case rsqrt_optab:
25678 : 86 : return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1);
25679 : :
25680 : : default:
25681 : : return true;
25682 : : }
25683 : : }
25684 : :
25685 : : /* Address space support.
25686 : :
25687 : : This is not "far pointers" in the 16-bit sense, but an easy way
25688 : : to use %fs and %gs segment prefixes. Therefore:
25689 : :
25690 : : (a) All address spaces have the same modes,
25691 : : (b) All address spaces have the same addresss forms,
25692 : : (c) While %fs and %gs are technically subsets of the generic
25693 : : address space, they are probably not subsets of each other.
25694 : : (d) Since we have no access to the segment base register values
25695 : : without resorting to a system call, we cannot convert a
25696 : : non-default address space to a default address space.
25697 : : Therefore we do not claim %fs or %gs are subsets of generic.
25698 : :
25699 : : Therefore we can (mostly) use the default hooks. */
25700 : :
25701 : : /* All use of segmentation is assumed to make address 0 valid. */
25702 : :
25703 : : static bool
25704 : 55491842 : ix86_addr_space_zero_address_valid (addr_space_t as)
25705 : : {
25706 : 55491842 : return as != ADDR_SPACE_GENERIC;
25707 : : }
25708 : :
25709 : : static void
25710 : 773502 : ix86_init_libfuncs (void)
25711 : : {
25712 : 773502 : if (TARGET_64BIT)
25713 : : {
25714 : 758665 : set_optab_libfunc (sdivmod_optab, TImode, "__divmodti4");
25715 : 758665 : set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4");
25716 : : }
25717 : : else
25718 : : {
25719 : 14837 : set_optab_libfunc (sdivmod_optab, DImode, "__divmoddi4");
25720 : 14837 : set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
25721 : : }
25722 : :
25723 : : #if TARGET_MACHO
25724 : : darwin_rename_builtins ();
25725 : : #endif
25726 : 773502 : }
25727 : :
25728 : : /* Set the value of FLT_EVAL_METHOD in float.h. When using only the
25729 : : FPU, assume that the fpcw is set to extended precision; when using
25730 : : only SSE, rounding is correct; when using both SSE and the FPU,
25731 : : the rounding precision is indeterminate, since either may be chosen
25732 : : apparently at random. */
25733 : :
25734 : : static enum flt_eval_method
25735 : 87182078 : ix86_get_excess_precision (enum excess_precision_type type)
25736 : : {
25737 : 87182078 : switch (type)
25738 : : {
25739 : 83472315 : case EXCESS_PRECISION_TYPE_FAST:
25740 : : /* The fastest type to promote to will always be the native type,
25741 : : whether that occurs with implicit excess precision or
25742 : : otherwise. */
25743 : 83472315 : return TARGET_AVX512FP16
25744 : 83472315 : ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
25745 : 83472315 : : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
25746 : 3709719 : case EXCESS_PRECISION_TYPE_STANDARD:
25747 : 3709719 : case EXCESS_PRECISION_TYPE_IMPLICIT:
25748 : : /* Otherwise, the excess precision we want when we are
25749 : : in a standards compliant mode, and the implicit precision we
25750 : : provide would be identical were it not for the unpredictable
25751 : : cases. */
25752 : 3709719 : if (TARGET_AVX512FP16 && TARGET_SSE_MATH)
25753 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
25754 : 3705363 : else if (!TARGET_80387)
25755 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
25756 : 3699555 : else if (!TARGET_MIX_SSE_I387)
25757 : : {
25758 : 3699383 : if (!(TARGET_SSE && TARGET_SSE_MATH))
25759 : : return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
25760 : 2712896 : else if (TARGET_SSE2)
25761 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
25762 : : }
25763 : :
25764 : : /* If we are in standards compliant mode, but we know we will
25765 : : calculate in unpredictable precision, return
25766 : : FLT_EVAL_METHOD_FLOAT. There is no reason to introduce explicit
25767 : : excess precision if the target can't guarantee it will honor
25768 : : it. */
25769 : 322 : return (type == EXCESS_PRECISION_TYPE_STANDARD
25770 : 322 : ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
25771 : : : FLT_EVAL_METHOD_UNPREDICTABLE);
25772 : 44 : case EXCESS_PRECISION_TYPE_FLOAT16:
25773 : 44 : if (TARGET_80387
25774 : 38 : && !(TARGET_SSE_MATH && TARGET_SSE))
25775 : 4 : error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
25776 : : return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
25777 : 0 : default:
25778 : 0 : gcc_unreachable ();
25779 : : }
25780 : :
25781 : : return FLT_EVAL_METHOD_UNPREDICTABLE;
25782 : : }
25783 : :
25784 : : /* Return true if _BitInt(N) is supported and fill its details into *INFO. */
25785 : : bool
25786 : 1718308 : ix86_bitint_type_info (int n, struct bitint_info *info)
25787 : : {
25788 : 1718308 : if (n <= 8)
25789 : 3565 : info->limb_mode = QImode;
25790 : 1714743 : else if (n <= 16)
25791 : 851 : info->limb_mode = HImode;
25792 : 1713892 : else if (n <= 32 || (!TARGET_64BIT && n > 64))
25793 : 18460 : info->limb_mode = SImode;
25794 : : else
25795 : 1695432 : info->limb_mode = DImode;
25796 : 1718308 : info->abi_limb_mode = info->limb_mode;
25797 : 1718308 : info->big_endian = false;
25798 : 1718308 : info->extended = false;
25799 : 1718308 : return true;
25800 : : }
25801 : :
25802 : : /* Implement PUSH_ROUNDING. On 386, we have pushw instruction that
25803 : : decrements by exactly 2 no matter what the position was, there is no pushb.
25804 : :
25805 : : But as CIE data alignment factor on this arch is -4 for 32bit targets
25806 : : and -8 for 64bit targets, we need to make sure all stack pointer adjustments
25807 : : are in multiple of 4 for 32bit targets and 8 for 64bit targets. */
25808 : :
25809 : : poly_int64
25810 : 202567779 : ix86_push_rounding (poly_int64 bytes)
25811 : : {
25812 : 262513701 : return ROUND_UP (bytes, UNITS_PER_WORD);
25813 : : }
25814 : :
25815 : : /* Use 8 bits metadata start from bit48 for LAM_U48,
25816 : : 6 bits metadat start from bit57 for LAM_U57. */
25817 : : #define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48 \
25818 : : ? 48 \
25819 : : : (ix86_lam_type == lam_u57 ? 57 : 0))
25820 : : #define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48 \
25821 : : ? 8 \
25822 : : : (ix86_lam_type == lam_u57 ? 6 : 0))
25823 : :
25824 : : /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES. */
25825 : : bool
25826 : 5849782 : ix86_memtag_can_tag_addresses ()
25827 : : {
25828 : 5849782 : return ix86_lam_type != lam_none && TARGET_LP64;
25829 : : }
25830 : :
25831 : : /* Implement TARGET_MEMTAG_TAG_SIZE. */
25832 : : unsigned char
25833 : 460 : ix86_memtag_tag_size ()
25834 : : {
25835 : 460 : return IX86_HWASAN_TAG_SIZE;
25836 : : }
25837 : :
25838 : : /* Implement TARGET_MEMTAG_SET_TAG. */
25839 : : rtx
25840 : 108 : ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
25841 : : {
25842 : : /* default_memtag_insert_random_tag may
25843 : : generate tag with value more than 6 bits. */
25844 : 108 : if (ix86_lam_type == lam_u57)
25845 : : {
25846 : 108 : unsigned HOST_WIDE_INT and_imm
25847 : : = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
25848 : :
25849 : 108 : emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
25850 : : }
25851 : 108 : tag = expand_simple_binop (Pmode, ASHIFT, tag,
25852 : 108 : GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
25853 : : /* unsignedp = */1, OPTAB_WIDEN);
25854 : 108 : rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
25855 : : /* unsignedp = */1, OPTAB_DIRECT);
25856 : 108 : return ret;
25857 : : }
25858 : :
25859 : : /* Implement TARGET_MEMTAG_EXTRACT_TAG. */
25860 : : rtx
25861 : 184 : ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
25862 : : {
25863 : 184 : rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
25864 : 184 : GEN_INT (IX86_HWASAN_SHIFT), target,
25865 : : /* unsignedp = */0,
25866 : : OPTAB_DIRECT);
25867 : 184 : rtx ret = gen_reg_rtx (QImode);
25868 : : /* Mask off bit63 when LAM_U57. */
25869 : 184 : if (ix86_lam_type == lam_u57)
25870 : : {
25871 : 184 : unsigned HOST_WIDE_INT and_imm
25872 : : = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
25873 : 184 : emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
25874 : : gen_int_mode (and_imm, QImode)));
25875 : : }
25876 : : else
25877 : 0 : emit_move_insn (ret, gen_lowpart (QImode, tag));
25878 : 184 : return ret;
25879 : : }
25880 : :
25881 : : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER. */
25882 : : rtx
25883 : 116 : ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
25884 : : {
25885 : : /* Leave bit63 alone. */
25886 : 116 : rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
25887 : 116 : + (HOST_WIDE_INT_1U << 63) - 1),
25888 : 116 : Pmode);
25889 : 116 : rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
25890 : : tag_mask, target, true,
25891 : : OPTAB_DIRECT);
25892 : 116 : gcc_assert (untagged_base);
25893 : 116 : return untagged_base;
25894 : : }
25895 : :
25896 : : /* Implement TARGET_MEMTAG_ADD_TAG. */
25897 : : rtx
25898 : 92 : ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
25899 : : {
25900 : 92 : rtx base_tag = gen_reg_rtx (QImode);
25901 : 92 : rtx base_addr = gen_reg_rtx (Pmode);
25902 : 92 : rtx tagged_addr = gen_reg_rtx (Pmode);
25903 : 92 : rtx new_tag = gen_reg_rtx (QImode);
25904 : 184 : unsigned HOST_WIDE_INT and_imm
25905 : 92 : = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
25906 : :
25907 : : /* When there's "overflow" in tag adding,
25908 : : need to mask the most significant bit off. */
25909 : 92 : emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
25910 : 92 : emit_move_insn (base_addr,
25911 : : ix86_memtag_untagged_pointer (base, NULL_RTX));
25912 : 92 : emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
25913 : 92 : emit_move_insn (new_tag, base_tag);
25914 : 92 : emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
25915 : 92 : emit_move_insn (tagged_addr,
25916 : : ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
25917 : 92 : return plus_constant (Pmode, tagged_addr, offset);
25918 : : }
25919 : :
25920 : : /* Target-specific selftests. */
25921 : :
25922 : : #if CHECKING_P
25923 : :
25924 : : namespace selftest {
25925 : :
25926 : : /* Verify that hard regs are dumped as expected (in compact mode). */
25927 : :
25928 : : static void
25929 : 4 : ix86_test_dumping_hard_regs ()
25930 : : {
25931 : 4 : ASSERT_RTL_DUMP_EQ ("(reg:SI ax)", gen_raw_REG (SImode, 0));
25932 : 4 : ASSERT_RTL_DUMP_EQ ("(reg:SI dx)", gen_raw_REG (SImode, 1));
25933 : 4 : }
25934 : :
25935 : : /* Test dumping an insn with repeated references to the same SCRATCH,
25936 : : to verify the rtx_reuse code. */
25937 : :
25938 : : static void
25939 : 4 : ix86_test_dumping_memory_blockage ()
25940 : : {
25941 : 4 : set_new_first_and_last_insn (NULL, NULL);
25942 : :
25943 : 4 : rtx pat = gen_memory_blockage ();
25944 : 4 : rtx_reuse_manager r;
25945 : 4 : r.preprocess (pat);
25946 : :
25947 : : /* Verify that the repeated references to the SCRATCH show use
25948 : : reuse IDS. The first should be prefixed with a reuse ID,
25949 : : and the second should be dumped as a "reuse_rtx" of that ID.
25950 : : The expected string assumes Pmode == DImode. */
25951 : 4 : if (Pmode == DImode)
25952 : 4 : ASSERT_RTL_DUMP_EQ_WITH_REUSE
25953 : : ("(cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0 A8])\n"
25954 : : " (unspec:BLK [\n"
25955 : : " (mem/v:BLK (reuse_rtx 0) [0 A8])\n"
25956 : : " ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r);
25957 : 4 : }
25958 : :
25959 : : /* Verify loading an RTL dump; specifically a dump of copying
25960 : : a param on x86_64 from a hard reg into the frame.
25961 : : This test is target-specific since the dump contains target-specific
25962 : : hard reg names. */
25963 : :
25964 : : static void
25965 : 4 : ix86_test_loading_dump_fragment_1 ()
25966 : : {
25967 : 4 : rtl_dump_test t (SELFTEST_LOCATION,
25968 : 4 : locate_file ("x86_64/copy-hard-reg-into-frame.rtl"));
25969 : :
25970 : 4 : rtx_insn *insn = get_insn_by_uid (1);
25971 : :
25972 : : /* The block structure and indentation here is purely for
25973 : : readability; it mirrors the structure of the rtx. */
25974 : 4 : tree mem_expr;
25975 : 4 : {
25976 : 4 : rtx pat = PATTERN (insn);
25977 : 4 : ASSERT_EQ (SET, GET_CODE (pat));
25978 : 4 : {
25979 : 4 : rtx dest = SET_DEST (pat);
25980 : 4 : ASSERT_EQ (MEM, GET_CODE (dest));
25981 : : /* Verify the "/c" was parsed. */
25982 : 4 : ASSERT_TRUE (RTX_FLAG (dest, call));
25983 : 4 : ASSERT_EQ (SImode, GET_MODE (dest));
25984 : 4 : {
25985 : 4 : rtx addr = XEXP (dest, 0);
25986 : 4 : ASSERT_EQ (PLUS, GET_CODE (addr));
25987 : 4 : ASSERT_EQ (DImode, GET_MODE (addr));
25988 : 4 : {
25989 : 4 : rtx lhs = XEXP (addr, 0);
25990 : : /* Verify that the "frame" REG was consolidated. */
25991 : 4 : ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs);
25992 : : }
25993 : 4 : {
25994 : 4 : rtx rhs = XEXP (addr, 1);
25995 : 4 : ASSERT_EQ (CONST_INT, GET_CODE (rhs));
25996 : 4 : ASSERT_EQ (-4, INTVAL (rhs));
25997 : : }
25998 : : }
25999 : : /* Verify the "[1 i+0 S4 A32]" was parsed. */
26000 : 4 : ASSERT_EQ (1, MEM_ALIAS_SET (dest));
26001 : : /* "i" should have been handled by synthesizing a global int
26002 : : variable named "i". */
26003 : 4 : mem_expr = MEM_EXPR (dest);
26004 : 4 : ASSERT_NE (mem_expr, NULL);
26005 : 4 : ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr));
26006 : 4 : ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr));
26007 : 4 : ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr)));
26008 : 4 : ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr)));
26009 : : /* "+0". */
26010 : 4 : ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest));
26011 : 4 : ASSERT_EQ (0, MEM_OFFSET (dest));
26012 : : /* "S4". */
26013 : 4 : ASSERT_EQ (4, MEM_SIZE (dest));
26014 : : /* "A32. */
26015 : 4 : ASSERT_EQ (32, MEM_ALIGN (dest));
26016 : : }
26017 : 4 : {
26018 : 4 : rtx src = SET_SRC (pat);
26019 : 4 : ASSERT_EQ (REG, GET_CODE (src));
26020 : 4 : ASSERT_EQ (SImode, GET_MODE (src));
26021 : 4 : ASSERT_EQ (5, REGNO (src));
26022 : 4 : tree reg_expr = REG_EXPR (src);
26023 : : /* "i" here should point to the same var as for the MEM_EXPR. */
26024 : 4 : ASSERT_EQ (reg_expr, mem_expr);
26025 : : }
26026 : : }
26027 : 4 : }
26028 : :
26029 : : /* Verify that the RTL loader copes with a call_insn dump.
26030 : : This test is target-specific since the dump contains a target-specific
26031 : : hard reg name. */
26032 : :
26033 : : static void
26034 : 4 : ix86_test_loading_call_insn ()
26035 : : {
26036 : : /* The test dump includes register "xmm0", where requires TARGET_SSE
26037 : : to exist. */
26038 : 4 : if (!TARGET_SSE)
26039 : 0 : return;
26040 : :
26041 : 4 : rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl"));
26042 : :
26043 : 4 : rtx_insn *insn = get_insns ();
26044 : 4 : ASSERT_EQ (CALL_INSN, GET_CODE (insn));
26045 : :
26046 : : /* "/j". */
26047 : 4 : ASSERT_TRUE (RTX_FLAG (insn, jump));
26048 : :
26049 : 4 : rtx pat = PATTERN (insn);
26050 : 4 : ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat)));
26051 : :
26052 : : /* Verify REG_NOTES. */
26053 : 4 : {
26054 : : /* "(expr_list:REG_CALL_DECL". */
26055 : 4 : ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn)));
26056 : 4 : rtx_expr_list *note0 = as_a <rtx_expr_list *> (REG_NOTES (insn));
26057 : 4 : ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0));
26058 : :
26059 : : /* "(expr_list:REG_EH_REGION (const_int 0 [0])". */
26060 : 4 : rtx_expr_list *note1 = note0->next ();
26061 : 4 : ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1));
26062 : :
26063 : 4 : ASSERT_EQ (NULL, note1->next ());
26064 : : }
26065 : :
26066 : : /* Verify CALL_INSN_FUNCTION_USAGE. */
26067 : 4 : {
26068 : : /* "(expr_list:DF (use (reg:DF 21 xmm0))". */
26069 : 4 : rtx_expr_list *usage
26070 : 4 : = as_a <rtx_expr_list *> (CALL_INSN_FUNCTION_USAGE (insn));
26071 : 4 : ASSERT_EQ (EXPR_LIST, GET_CODE (usage));
26072 : 4 : ASSERT_EQ (DFmode, GET_MODE (usage));
26073 : 4 : ASSERT_EQ (USE, GET_CODE (usage->element ()));
26074 : 4 : ASSERT_EQ (NULL, usage->next ());
26075 : : }
26076 : 4 : }
26077 : :
26078 : : /* Verify that the RTL loader copes a dump from print_rtx_function.
26079 : : This test is target-specific since the dump contains target-specific
26080 : : hard reg names. */
26081 : :
26082 : : static void
26083 : 4 : ix86_test_loading_full_dump ()
26084 : : {
26085 : 4 : rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl"));
26086 : :
26087 : 4 : ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
26088 : :
26089 : 4 : rtx_insn *insn_1 = get_insn_by_uid (1);
26090 : 4 : ASSERT_EQ (NOTE, GET_CODE (insn_1));
26091 : :
26092 : 4 : rtx_insn *insn_7 = get_insn_by_uid (7);
26093 : 4 : ASSERT_EQ (INSN, GET_CODE (insn_7));
26094 : 4 : ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7)));
26095 : :
26096 : 4 : rtx_insn *insn_15 = get_insn_by_uid (15);
26097 : 4 : ASSERT_EQ (INSN, GET_CODE (insn_15));
26098 : 4 : ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15)));
26099 : :
26100 : : /* Verify crtl->return_rtx. */
26101 : 4 : ASSERT_EQ (REG, GET_CODE (crtl->return_rtx));
26102 : 4 : ASSERT_EQ (0, REGNO (crtl->return_rtx));
26103 : 4 : ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
26104 : 4 : }
26105 : :
26106 : : /* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns.
26107 : : In particular, verify that it correctly loads the 2nd operand.
26108 : : This test is target-specific since these are machine-specific
26109 : : operands (and enums). */
26110 : :
26111 : : static void
26112 : 4 : ix86_test_loading_unspec ()
26113 : : {
26114 : 4 : rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl"));
26115 : :
26116 : 4 : ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
26117 : :
26118 : 4 : ASSERT_TRUE (cfun);
26119 : :
26120 : : /* Test of an UNSPEC. */
26121 : 4 : rtx_insn *insn = get_insns ();
26122 : 4 : ASSERT_EQ (INSN, GET_CODE (insn));
26123 : 4 : rtx set = single_set (insn);
26124 : 4 : ASSERT_NE (NULL, set);
26125 : 4 : rtx dst = SET_DEST (set);
26126 : 4 : ASSERT_EQ (MEM, GET_CODE (dst));
26127 : 4 : rtx src = SET_SRC (set);
26128 : 4 : ASSERT_EQ (UNSPEC, GET_CODE (src));
26129 : 4 : ASSERT_EQ (BLKmode, GET_MODE (src));
26130 : 4 : ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1));
26131 : :
26132 : 4 : rtx v0 = XVECEXP (src, 0, 0);
26133 : :
26134 : : /* Verify that the two uses of the first SCRATCH have pointer
26135 : : equality. */
26136 : 4 : rtx scratch_a = XEXP (dst, 0);
26137 : 4 : ASSERT_EQ (SCRATCH, GET_CODE (scratch_a));
26138 : :
26139 : 4 : rtx scratch_b = XEXP (v0, 0);
26140 : 4 : ASSERT_EQ (SCRATCH, GET_CODE (scratch_b));
26141 : :
26142 : 4 : ASSERT_EQ (scratch_a, scratch_b);
26143 : :
26144 : : /* Verify that the two mems are thus treated as equal. */
26145 : 4 : ASSERT_TRUE (rtx_equal_p (dst, v0));
26146 : :
26147 : : /* Verify that the insn is recognized. */
26148 : 4 : ASSERT_NE(-1, recog_memoized (insn));
26149 : :
26150 : : /* Test of an UNSPEC_VOLATILE, which has its own enum values. */
26151 : 4 : insn = NEXT_INSN (insn);
26152 : 4 : ASSERT_EQ (INSN, GET_CODE (insn));
26153 : :
26154 : 4 : set = single_set (insn);
26155 : 4 : ASSERT_NE (NULL, set);
26156 : :
26157 : 4 : src = SET_SRC (set);
26158 : 4 : ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src));
26159 : 4 : ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1));
26160 : 4 : }
26161 : :
26162 : : /* Run all target-specific selftests. */
26163 : :
26164 : : static void
26165 : 4 : ix86_run_selftests (void)
26166 : : {
26167 : 4 : ix86_test_dumping_hard_regs ();
26168 : 4 : ix86_test_dumping_memory_blockage ();
26169 : :
26170 : : /* Various tests of loading RTL dumps, here because they contain
26171 : : ix86-isms (e.g. names of hard regs). */
26172 : 4 : ix86_test_loading_dump_fragment_1 ();
26173 : 4 : ix86_test_loading_call_insn ();
26174 : 4 : ix86_test_loading_full_dump ();
26175 : 4 : ix86_test_loading_unspec ();
26176 : 4 : }
26177 : :
26178 : : } // namespace selftest
26179 : :
26180 : : #endif /* CHECKING_P */
26181 : :
26182 : : static const scoped_attribute_specs *const ix86_attribute_table[] =
26183 : : {
26184 : : &ix86_gnu_attribute_table
26185 : : };
26186 : :
26187 : : /* Initialize the GCC target structure. */
26188 : : #undef TARGET_RETURN_IN_MEMORY
26189 : : #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
26190 : :
26191 : : #undef TARGET_LEGITIMIZE_ADDRESS
26192 : : #define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
26193 : :
26194 : : #undef TARGET_ATTRIBUTE_TABLE
26195 : : #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
26196 : : #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
26197 : : #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
26198 : : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
26199 : : # undef TARGET_MERGE_DECL_ATTRIBUTES
26200 : : # define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
26201 : : #endif
26202 : :
26203 : : #undef TARGET_INVALID_CONVERSION
26204 : : #define TARGET_INVALID_CONVERSION ix86_invalid_conversion
26205 : :
26206 : : #undef TARGET_INVALID_UNARY_OP
26207 : : #define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op
26208 : :
26209 : : #undef TARGET_INVALID_BINARY_OP
26210 : : #define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op
26211 : :
26212 : : #undef TARGET_COMP_TYPE_ATTRIBUTES
26213 : : #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
26214 : :
26215 : : #undef TARGET_INIT_BUILTINS
26216 : : #define TARGET_INIT_BUILTINS ix86_init_builtins
26217 : : #undef TARGET_BUILTIN_DECL
26218 : : #define TARGET_BUILTIN_DECL ix86_builtin_decl
26219 : : #undef TARGET_EXPAND_BUILTIN
26220 : : #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
26221 : :
26222 : : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
26223 : : #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
26224 : : ix86_builtin_vectorized_function
26225 : :
26226 : : #undef TARGET_VECTORIZE_BUILTIN_GATHER
26227 : : #define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
26228 : :
26229 : : #undef TARGET_VECTORIZE_BUILTIN_SCATTER
26230 : : #define TARGET_VECTORIZE_BUILTIN_SCATTER ix86_vectorize_builtin_scatter
26231 : :
26232 : : #undef TARGET_BUILTIN_RECIPROCAL
26233 : : #define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
26234 : :
26235 : : #undef TARGET_ASM_FUNCTION_EPILOGUE
26236 : : #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
26237 : :
26238 : : #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
26239 : : #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
26240 : : ix86_print_patchable_function_entry
26241 : :
26242 : : #undef TARGET_ENCODE_SECTION_INFO
26243 : : #ifndef SUBTARGET_ENCODE_SECTION_INFO
26244 : : #define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
26245 : : #else
26246 : : #define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
26247 : : #endif
26248 : :
26249 : : #undef TARGET_ASM_OPEN_PAREN
26250 : : #define TARGET_ASM_OPEN_PAREN ""
26251 : : #undef TARGET_ASM_CLOSE_PAREN
26252 : : #define TARGET_ASM_CLOSE_PAREN ""
26253 : :
26254 : : #undef TARGET_ASM_BYTE_OP
26255 : : #define TARGET_ASM_BYTE_OP ASM_BYTE
26256 : :
26257 : : #undef TARGET_ASM_ALIGNED_HI_OP
26258 : : #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
26259 : : #undef TARGET_ASM_ALIGNED_SI_OP
26260 : : #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
26261 : : #ifdef ASM_QUAD
26262 : : #undef TARGET_ASM_ALIGNED_DI_OP
26263 : : #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
26264 : : #endif
26265 : :
26266 : : #undef TARGET_PROFILE_BEFORE_PROLOGUE
26267 : : #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
26268 : :
26269 : : #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
26270 : : #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
26271 : :
26272 : : #undef TARGET_ASM_UNALIGNED_HI_OP
26273 : : #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
26274 : : #undef TARGET_ASM_UNALIGNED_SI_OP
26275 : : #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
26276 : : #undef TARGET_ASM_UNALIGNED_DI_OP
26277 : : #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
26278 : :
26279 : : #undef TARGET_PRINT_OPERAND
26280 : : #define TARGET_PRINT_OPERAND ix86_print_operand
26281 : : #undef TARGET_PRINT_OPERAND_ADDRESS
26282 : : #define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
26283 : : #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
26284 : : #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
26285 : : #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
26286 : : #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
26287 : :
26288 : : #undef TARGET_SCHED_INIT_GLOBAL
26289 : : #define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
26290 : : #undef TARGET_SCHED_ADJUST_COST
26291 : : #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
26292 : : #undef TARGET_SCHED_ISSUE_RATE
26293 : : #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
26294 : : #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
26295 : : #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
26296 : : ia32_multipass_dfa_lookahead
26297 : : #undef TARGET_SCHED_MACRO_FUSION_P
26298 : : #define TARGET_SCHED_MACRO_FUSION_P ix86_macro_fusion_p
26299 : : #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
26300 : : #define TARGET_SCHED_MACRO_FUSION_PAIR_P ix86_macro_fusion_pair_p
26301 : :
26302 : : #undef TARGET_FUNCTION_OK_FOR_SIBCALL
26303 : : #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
26304 : :
26305 : : #undef TARGET_MEMMODEL_CHECK
26306 : : #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
26307 : :
26308 : : #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
26309 : : #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
26310 : :
26311 : : #ifdef HAVE_AS_TLS
26312 : : #undef TARGET_HAVE_TLS
26313 : : #define TARGET_HAVE_TLS true
26314 : : #endif
26315 : : #undef TARGET_CANNOT_FORCE_CONST_MEM
26316 : : #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
26317 : : #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
26318 : : #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
26319 : :
26320 : : #undef TARGET_DELEGITIMIZE_ADDRESS
26321 : : #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
26322 : :
26323 : : #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
26324 : : #define TARGET_CONST_NOT_OK_FOR_DEBUG_P ix86_const_not_ok_for_debug_p
26325 : :
26326 : : #undef TARGET_MS_BITFIELD_LAYOUT_P
26327 : : #define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
26328 : :
26329 : : #if TARGET_MACHO
26330 : : #undef TARGET_BINDS_LOCAL_P
26331 : : #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
26332 : : #else
26333 : : #undef TARGET_BINDS_LOCAL_P
26334 : : #define TARGET_BINDS_LOCAL_P ix86_binds_local_p
26335 : : #endif
26336 : : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
26337 : : #undef TARGET_BINDS_LOCAL_P
26338 : : #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
26339 : : #endif
26340 : :
26341 : : #undef TARGET_ASM_OUTPUT_MI_THUNK
26342 : : #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
26343 : : #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
26344 : : #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
26345 : :
26346 : : #undef TARGET_ASM_FILE_START
26347 : : #define TARGET_ASM_FILE_START x86_file_start
26348 : :
26349 : : #undef TARGET_OPTION_OVERRIDE
26350 : : #define TARGET_OPTION_OVERRIDE ix86_option_override
26351 : :
26352 : : #undef TARGET_REGISTER_MOVE_COST
26353 : : #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
26354 : : #undef TARGET_MEMORY_MOVE_COST
26355 : : #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
26356 : : #undef TARGET_RTX_COSTS
26357 : : #define TARGET_RTX_COSTS ix86_rtx_costs
26358 : : #undef TARGET_ADDRESS_COST
26359 : : #define TARGET_ADDRESS_COST ix86_address_cost
26360 : :
26361 : : #undef TARGET_OVERLAP_OP_BY_PIECES_P
26362 : : #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true
26363 : :
26364 : : #undef TARGET_FLAGS_REGNUM
26365 : : #define TARGET_FLAGS_REGNUM FLAGS_REG
26366 : : #undef TARGET_FIXED_CONDITION_CODE_REGS
26367 : : #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
26368 : : #undef TARGET_CC_MODES_COMPATIBLE
26369 : : #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
26370 : :
26371 : : #undef TARGET_MACHINE_DEPENDENT_REORG
26372 : : #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
26373 : :
26374 : : #undef TARGET_BUILD_BUILTIN_VA_LIST
26375 : : #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
26376 : :
26377 : : #undef TARGET_FOLD_BUILTIN
26378 : : #define TARGET_FOLD_BUILTIN ix86_fold_builtin
26379 : :
26380 : : #undef TARGET_GIMPLE_FOLD_BUILTIN
26381 : : #define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
26382 : :
26383 : : #undef TARGET_COMPARE_VERSION_PRIORITY
26384 : : #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
26385 : :
26386 : : #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
26387 : : #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
26388 : : ix86_generate_version_dispatcher_body
26389 : :
26390 : : #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
26391 : : #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
26392 : : ix86_get_function_versions_dispatcher
26393 : :
26394 : : #undef TARGET_ENUM_VA_LIST_P
26395 : : #define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
26396 : :
26397 : : #undef TARGET_FN_ABI_VA_LIST
26398 : : #define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
26399 : :
26400 : : #undef TARGET_CANONICAL_VA_LIST_TYPE
26401 : : #define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
26402 : :
26403 : : #undef TARGET_EXPAND_BUILTIN_VA_START
26404 : : #define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
26405 : :
26406 : : #undef TARGET_MD_ASM_ADJUST
26407 : : #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
26408 : :
26409 : : #undef TARGET_C_EXCESS_PRECISION
26410 : : #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
26411 : : #undef TARGET_C_BITINT_TYPE_INFO
26412 : : #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
26413 : : #undef TARGET_PROMOTE_PROTOTYPES
26414 : : #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
26415 : : #undef TARGET_PUSH_ARGUMENT
26416 : : #define TARGET_PUSH_ARGUMENT ix86_push_argument
26417 : : #undef TARGET_SETUP_INCOMING_VARARGS
26418 : : #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
26419 : : #undef TARGET_MUST_PASS_IN_STACK
26420 : : #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
26421 : : #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
26422 : : #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args
26423 : : #undef TARGET_FUNCTION_ARG_ADVANCE
26424 : : #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
26425 : : #undef TARGET_FUNCTION_ARG
26426 : : #define TARGET_FUNCTION_ARG ix86_function_arg
26427 : : #undef TARGET_INIT_PIC_REG
26428 : : #define TARGET_INIT_PIC_REG ix86_init_pic_reg
26429 : : #undef TARGET_USE_PSEUDO_PIC_REG
26430 : : #define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
26431 : : #undef TARGET_FUNCTION_ARG_BOUNDARY
26432 : : #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
26433 : : #undef TARGET_PASS_BY_REFERENCE
26434 : : #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
26435 : : #undef TARGET_INTERNAL_ARG_POINTER
26436 : : #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
26437 : : #undef TARGET_UPDATE_STACK_BOUNDARY
26438 : : #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
26439 : : #undef TARGET_GET_DRAP_RTX
26440 : : #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
26441 : : #undef TARGET_STRICT_ARGUMENT_NAMING
26442 : : #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
26443 : : #undef TARGET_STATIC_CHAIN
26444 : : #define TARGET_STATIC_CHAIN ix86_static_chain
26445 : : #undef TARGET_TRAMPOLINE_INIT
26446 : : #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
26447 : : #undef TARGET_RETURN_POPS_ARGS
26448 : : #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
26449 : :
26450 : : #undef TARGET_WARN_FUNC_RETURN
26451 : : #define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
26452 : :
26453 : : #undef TARGET_LEGITIMATE_COMBINED_INSN
26454 : : #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
26455 : :
26456 : : #undef TARGET_ASAN_SHADOW_OFFSET
26457 : : #define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
26458 : :
26459 : : #undef TARGET_GIMPLIFY_VA_ARG_EXPR
26460 : : #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
26461 : :
26462 : : #undef TARGET_SCALAR_MODE_SUPPORTED_P
26463 : : #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
26464 : :
26465 : : #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
26466 : : #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
26467 : : ix86_libgcc_floating_mode_supported_p
26468 : :
26469 : : #undef TARGET_VECTOR_MODE_SUPPORTED_P
26470 : : #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
26471 : :
26472 : : #undef TARGET_C_MODE_FOR_SUFFIX
26473 : : #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
26474 : :
26475 : : #ifdef HAVE_AS_TLS
26476 : : #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
26477 : : #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
26478 : : #endif
26479 : :
26480 : : #ifdef SUBTARGET_INSERT_ATTRIBUTES
26481 : : #undef TARGET_INSERT_ATTRIBUTES
26482 : : #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
26483 : : #endif
26484 : :
26485 : : #undef TARGET_MANGLE_TYPE
26486 : : #define TARGET_MANGLE_TYPE ix86_mangle_type
26487 : :
26488 : : #undef TARGET_EMIT_SUPPORT_TINFOS
26489 : : #define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos
26490 : :
26491 : : #undef TARGET_STACK_PROTECT_GUARD
26492 : : #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard
26493 : :
26494 : : #if !TARGET_MACHO
26495 : : #undef TARGET_STACK_PROTECT_FAIL
26496 : : #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
26497 : : #endif
26498 : :
26499 : : #undef TARGET_FUNCTION_VALUE
26500 : : #define TARGET_FUNCTION_VALUE ix86_function_value
26501 : :
26502 : : #undef TARGET_FUNCTION_VALUE_REGNO_P
26503 : : #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
26504 : :
26505 : : #undef TARGET_ZERO_CALL_USED_REGS
26506 : : #define TARGET_ZERO_CALL_USED_REGS ix86_zero_call_used_regs
26507 : :
26508 : : #undef TARGET_PROMOTE_FUNCTION_MODE
26509 : : #define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
26510 : :
26511 : : #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
26512 : : #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
26513 : :
26514 : : #undef TARGET_MEMBER_TYPE_FORCES_BLK
26515 : : #define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
26516 : :
26517 : : #undef TARGET_INSTANTIATE_DECLS
26518 : : #define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
26519 : :
26520 : : #undef TARGET_SECONDARY_RELOAD
26521 : : #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
26522 : : #undef TARGET_SECONDARY_MEMORY_NEEDED
26523 : : #define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed
26524 : : #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
26525 : : #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
26526 : :
26527 : : #undef TARGET_CLASS_MAX_NREGS
26528 : : #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
26529 : :
26530 : : #undef TARGET_PREFERRED_RELOAD_CLASS
26531 : : #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
26532 : : #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
26533 : : #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
26534 : : #undef TARGET_CLASS_LIKELY_SPILLED_P
26535 : : #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
26536 : :
26537 : : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
26538 : : #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
26539 : : ix86_builtin_vectorization_cost
26540 : : #undef TARGET_VECTORIZE_VEC_PERM_CONST
26541 : : #define TARGET_VECTORIZE_VEC_PERM_CONST ix86_vectorize_vec_perm_const
26542 : : #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
26543 : : #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
26544 : : ix86_preferred_simd_mode
26545 : : #undef TARGET_VECTORIZE_SPLIT_REDUCTION
26546 : : #define TARGET_VECTORIZE_SPLIT_REDUCTION \
26547 : : ix86_split_reduction
26548 : : #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
26549 : : #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
26550 : : ix86_autovectorize_vector_modes
26551 : : #undef TARGET_VECTORIZE_GET_MASK_MODE
26552 : : #define TARGET_VECTORIZE_GET_MASK_MODE ix86_get_mask_mode
26553 : : #undef TARGET_VECTORIZE_CREATE_COSTS
26554 : : #define TARGET_VECTORIZE_CREATE_COSTS ix86_vectorize_create_costs
26555 : :
26556 : : #undef TARGET_SET_CURRENT_FUNCTION
26557 : : #define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
26558 : :
26559 : : #undef TARGET_OPTION_VALID_ATTRIBUTE_P
26560 : : #define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
26561 : :
26562 : : #undef TARGET_OPTION_SAVE
26563 : : #define TARGET_OPTION_SAVE ix86_function_specific_save
26564 : :
26565 : : #undef TARGET_OPTION_RESTORE
26566 : : #define TARGET_OPTION_RESTORE ix86_function_specific_restore
26567 : :
26568 : : #undef TARGET_OPTION_POST_STREAM_IN
26569 : : #define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
26570 : :
26571 : : #undef TARGET_OPTION_PRINT
26572 : : #define TARGET_OPTION_PRINT ix86_function_specific_print
26573 : :
26574 : : #undef TARGET_OPTION_FUNCTION_VERSIONS
26575 : : #define TARGET_OPTION_FUNCTION_VERSIONS common_function_versions
26576 : :
26577 : : #undef TARGET_CAN_INLINE_P
26578 : : #define TARGET_CAN_INLINE_P ix86_can_inline_p
26579 : :
26580 : : #undef TARGET_LEGITIMATE_ADDRESS_P
26581 : : #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
26582 : :
26583 : : #undef TARGET_REGISTER_PRIORITY
26584 : : #define TARGET_REGISTER_PRIORITY ix86_register_priority
26585 : :
26586 : : #undef TARGET_REGISTER_USAGE_LEVELING_P
26587 : : #define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
26588 : :
26589 : : #undef TARGET_LEGITIMATE_CONSTANT_P
26590 : : #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
26591 : :
26592 : : #undef TARGET_COMPUTE_FRAME_LAYOUT
26593 : : #define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
26594 : :
26595 : : #undef TARGET_FRAME_POINTER_REQUIRED
26596 : : #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
26597 : :
26598 : : #undef TARGET_CAN_ELIMINATE
26599 : : #define TARGET_CAN_ELIMINATE ix86_can_eliminate
26600 : :
26601 : : #undef TARGET_EXTRA_LIVE_ON_ENTRY
26602 : : #define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
26603 : :
26604 : : #undef TARGET_ASM_CODE_END
26605 : : #define TARGET_ASM_CODE_END ix86_code_end
26606 : :
26607 : : #undef TARGET_CONDITIONAL_REGISTER_USAGE
26608 : : #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
26609 : :
26610 : : #undef TARGET_CANONICALIZE_COMPARISON
26611 : : #define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison
26612 : :
26613 : : #undef TARGET_LOOP_UNROLL_ADJUST
26614 : : #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust
26615 : :
26616 : : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657. */
26617 : : #undef TARGET_SPILL_CLASS
26618 : : #define TARGET_SPILL_CLASS ix86_spill_class
26619 : :
26620 : : #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
26621 : : #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
26622 : : ix86_simd_clone_compute_vecsize_and_simdlen
26623 : :
26624 : : #undef TARGET_SIMD_CLONE_ADJUST
26625 : : #define TARGET_SIMD_CLONE_ADJUST ix86_simd_clone_adjust
26626 : :
26627 : : #undef TARGET_SIMD_CLONE_USABLE
26628 : : #define TARGET_SIMD_CLONE_USABLE ix86_simd_clone_usable
26629 : :
26630 : : #undef TARGET_OMP_DEVICE_KIND_ARCH_ISA
26631 : : #define TARGET_OMP_DEVICE_KIND_ARCH_ISA ix86_omp_device_kind_arch_isa
26632 : :
26633 : : #undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
26634 : : #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
26635 : : ix86_float_exceptions_rounding_supported_p
26636 : :
26637 : : #undef TARGET_MODE_EMIT
26638 : : #define TARGET_MODE_EMIT ix86_emit_mode_set
26639 : :
26640 : : #undef TARGET_MODE_NEEDED
26641 : : #define TARGET_MODE_NEEDED ix86_mode_needed
26642 : :
26643 : : #undef TARGET_MODE_AFTER
26644 : : #define TARGET_MODE_AFTER ix86_mode_after
26645 : :
26646 : : #undef TARGET_MODE_ENTRY
26647 : : #define TARGET_MODE_ENTRY ix86_mode_entry
26648 : :
26649 : : #undef TARGET_MODE_EXIT
26650 : : #define TARGET_MODE_EXIT ix86_mode_exit
26651 : :
26652 : : #undef TARGET_MODE_PRIORITY
26653 : : #define TARGET_MODE_PRIORITY ix86_mode_priority
26654 : :
26655 : : #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
26656 : : #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
26657 : :
26658 : : #undef TARGET_OFFLOAD_OPTIONS
26659 : : #define TARGET_OFFLOAD_OPTIONS \
26660 : : ix86_offload_options
26661 : :
26662 : : #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
26663 : : #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
26664 : :
26665 : : #undef TARGET_OPTAB_SUPPORTED_P
26666 : : #define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
26667 : :
26668 : : #undef TARGET_HARD_REGNO_SCRATCH_OK
26669 : : #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok
26670 : :
26671 : : #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
26672 : : #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST
26673 : :
26674 : : #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
26675 : : #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid
26676 : :
26677 : : #undef TARGET_INIT_LIBFUNCS
26678 : : #define TARGET_INIT_LIBFUNCS ix86_init_libfuncs
26679 : :
26680 : : #undef TARGET_EXPAND_DIVMOD_LIBFUNC
26681 : : #define TARGET_EXPAND_DIVMOD_LIBFUNC ix86_expand_divmod_libfunc
26682 : :
26683 : : #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
26684 : : #define TARGET_MAX_NOCE_IFCVT_SEQ_COST ix86_max_noce_ifcvt_seq_cost
26685 : :
26686 : : #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
26687 : : #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
26688 : :
26689 : : #undef TARGET_HARD_REGNO_NREGS
26690 : : #define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
26691 : : #undef TARGET_HARD_REGNO_MODE_OK
26692 : : #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
26693 : :
26694 : : #undef TARGET_MODES_TIEABLE_P
26695 : : #define TARGET_MODES_TIEABLE_P ix86_modes_tieable_p
26696 : :
26697 : : #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
26698 : : #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
26699 : : ix86_hard_regno_call_part_clobbered
26700 : :
26701 : : #undef TARGET_INSN_CALLEE_ABI
26702 : : #define TARGET_INSN_CALLEE_ABI ix86_insn_callee_abi
26703 : :
26704 : : #undef TARGET_CAN_CHANGE_MODE_CLASS
26705 : : #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
26706 : :
26707 : : #undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT
26708 : : #define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment
26709 : :
26710 : : #undef TARGET_STATIC_RTX_ALIGNMENT
26711 : : #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
26712 : : #undef TARGET_CONSTANT_ALIGNMENT
26713 : : #define TARGET_CONSTANT_ALIGNMENT ix86_constant_alignment
26714 : :
26715 : : #undef TARGET_EMPTY_RECORD_P
26716 : : #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
26717 : :
26718 : : #undef TARGET_WARN_PARAMETER_PASSING_ABI
26719 : : #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
26720 : :
26721 : : #undef TARGET_GET_MULTILIB_ABI_NAME
26722 : : #define TARGET_GET_MULTILIB_ABI_NAME \
26723 : : ix86_get_multilib_abi_name
26724 : :
26725 : : #undef TARGET_IFUNC_REF_LOCAL_OK
26726 : : #define TARGET_IFUNC_REF_LOCAL_OK ix86_ifunc_ref_local_ok
26727 : :
26728 : : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
26729 : : # undef TARGET_ASM_RELOC_RW_MASK
26730 : : # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
26731 : : #endif
26732 : :
26733 : : #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
26734 : : #define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
26735 : :
26736 : : #undef TARGET_MEMTAG_ADD_TAG
26737 : : #define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
26738 : :
26739 : : #undef TARGET_MEMTAG_SET_TAG
26740 : : #define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
26741 : :
26742 : : #undef TARGET_MEMTAG_EXTRACT_TAG
26743 : : #define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
26744 : :
26745 : : #undef TARGET_MEMTAG_UNTAGGED_POINTER
26746 : : #define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
26747 : :
26748 : : #undef TARGET_MEMTAG_TAG_SIZE
26749 : : #define TARGET_MEMTAG_TAG_SIZE ix86_memtag_tag_size
26750 : :
26751 : : static bool
26752 : 68272 : ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
26753 : : {
26754 : : #ifdef OPTION_GLIBC
26755 : 68272 : if (OPTION_GLIBC)
26756 : 68272 : return (built_in_function)fcode == BUILT_IN_MEMPCPY;
26757 : : else
26758 : : return false;
26759 : : #else
26760 : : return false;
26761 : : #endif
26762 : : }
26763 : :
26764 : : #undef TARGET_LIBC_HAS_FAST_FUNCTION
26765 : : #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function
26766 : :
26767 : : static unsigned
26768 : 72079 : ix86_libm_function_max_error (unsigned cfn, machine_mode mode,
26769 : : bool boundary_p)
26770 : : {
26771 : : #ifdef OPTION_GLIBC
26772 : 72079 : bool glibc_p = OPTION_GLIBC;
26773 : : #else
26774 : : bool glibc_p = false;
26775 : : #endif
26776 : 72079 : if (glibc_p)
26777 : : {
26778 : : /* If __FAST_MATH__ is defined, glibc provides libmvec. */
26779 : 72079 : unsigned int libmvec_ret = 0;
26780 : 72079 : if (!flag_trapping_math
26781 : 7809 : && flag_unsafe_math_optimizations
26782 : 3024 : && flag_finite_math_only
26783 : 2998 : && !flag_signed_zeros
26784 : 2998 : && !flag_errno_math)
26785 : 2998 : switch (cfn)
26786 : : {
26787 : 1308 : CASE_CFN_COS:
26788 : 1308 : CASE_CFN_COS_FN:
26789 : 1308 : CASE_CFN_SIN:
26790 : 1308 : CASE_CFN_SIN_FN:
26791 : 1308 : if (!boundary_p)
26792 : : {
26793 : : /* With non-default rounding modes, libmvec provides
26794 : : complete garbage in results. E.g.
26795 : : _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD
26796 : : returns 0.00333309174f rather than 1.40129846e-45f. */
26797 : 543 : if (flag_rounding_math)
26798 : : return ~0U;
26799 : : /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
26800 : : claims libmvec maximum error is 4ulps.
26801 : : My own random testing indicates 2ulps for SFmode and
26802 : : 0.5ulps for DFmode, but let's go with the 4ulps. */
26803 : : libmvec_ret = 4;
26804 : : }
26805 : : break;
26806 : : default:
26807 : : break;
26808 : : }
26809 : 72079 : unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode,
26810 : : boundary_p);
26811 : 72079 : return MAX (ret, libmvec_ret);
26812 : : }
26813 : 0 : return default_libm_function_max_error (cfn, mode, boundary_p);
26814 : : }
26815 : :
26816 : : #undef TARGET_LIBM_FUNCTION_MAX_ERROR
26817 : : #define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error
26818 : :
26819 : : #if CHECKING_P
26820 : : #undef TARGET_RUN_TARGET_SELFTESTS
26821 : : #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
26822 : : #endif /* #if CHECKING_P */
26823 : :
26824 : : struct gcc_target targetm = TARGET_INITIALIZER;
26825 : :
26826 : : #include "gt-i386.h"
|