LCOV - code coverage report
Current view: top level - gcc/config/i386 - i386.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.3 % 13181 11773
Test Date: 2026-08-01 15:33:25 Functions: 97.1 % 483 469
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Subroutines used for code generation on IA-32.
       2              :    Copyright (C) 1988-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify
       7              : it under the terms of the GNU General Public License as published by
       8              : the Free Software Foundation; either version 3, or (at your option)
       9              : any later version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful,
      12              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      13              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14              : GNU General Public License for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #define INCLUDE_STRING
      21              : #define IN_TARGET_CODE 1
      22              : 
      23              : #include "config.h"
      24              : #include "system.h"
      25              : #include "coretypes.h"
      26              : #include "backend.h"
      27              : #include "rtl.h"
      28              : #include "tree.h"
      29              : #include "memmodel.h"
      30              : #include "gimple.h"
      31              : #include "cfghooks.h"
      32              : #include "cfgloop.h"
      33              : #include "df.h"
      34              : #include "tm_p.h"
      35              : #include "stringpool.h"
      36              : #include "expmed.h"
      37              : #include "optabs.h"
      38              : #include "regs.h"
      39              : #include "emit-rtl.h"
      40              : #include "recog.h"
      41              : #include "cgraph.h"
      42              : #include "diagnostic.h"
      43              : #include "cfgbuild.h"
      44              : #include "alias.h"
      45              : #include "fold-const.h"
      46              : #include "attribs.h"
      47              : #include "calls.h"
      48              : #include "stor-layout.h"
      49              : #include "varasm.h"
      50              : #include "output.h"
      51              : #include "insn-attr.h"
      52              : #include "flags.h"
      53              : #include "except.h"
      54              : #include "explow.h"
      55              : #include "expr.h"
      56              : #include "cfgrtl.h"
      57              : #include "common/common-target.h"
      58              : #include "langhooks.h"
      59              : #include "reload.h"
      60              : #include "gimplify.h"
      61              : #include "dwarf2.h"
      62              : #include "tm-constrs.h"
      63              : #include "cselib.h"
      64              : #include "sched-int.h"
      65              : #include "opts.h"
      66              : #include "tree-pass.h"
      67              : #include "context.h"
      68              : #include "pass_manager.h"
      69              : #include "target-globals.h"
      70              : #include "gimple-iterator.h"
      71              : #include "gimple-fold.h"
      72              : #include "tree-vectorizer.h"
      73              : #include "shrink-wrap.h"
      74              : #include "builtins.h"
      75              : #include "rtl-iter.h"
      76              : #include "tree-iterator.h"
      77              : #include "dbgcnt.h"
      78              : #include "case-cfn-macros.h"
      79              : #include "dojump.h"
      80              : #include "fold-const-call.h"
      81              : #include "tree-vrp.h"
      82              : #include "tree-ssanames.h"
      83              : #include "selftest.h"
      84              : #include "selftest-rtl.h"
      85              : #include "print-rtl.h"
      86              : #include "intl.h"
      87              : #include "ifcvt.h"
      88              : #include "symbol-summary.h"
      89              : #include "sreal.h"
      90              : #include "ipa-cp.h"
      91              : #include "ipa-prop.h"
      92              : #include "ipa-fnsummary.h"
      93              : #include "wide-int-bitmask.h"
      94              : #include "tree-vector-builder.h"
      95              : #include "debug.h"
      96              : #include "dwarf2out.h"
      97              : #include "i386-options.h"
      98              : #include "i386-builtins.h"
      99              : #include "i386-expand.h"
     100              : #include "i386-features.h"
     101              : #include "function-abi.h"
     102              : #include "rtl-error.h"
     103              : #include "gimple-pretty-print.h"
     104              : 
     105              : /* This file should be included last.  */
     106              : #include "target-def.h"
     107              : 
     108              : static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
     109              : static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
     110              : static const predefined_function_abi & ix86_alternate_abi (void);
     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              : unsigned 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              : unsigned 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 integer 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              : unsigned 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              : /* Similar as Clang's preserve_none function parameter passing.
     340              :    NB: Use DI_REG and SI_REG, see ix86_function_arg_regno_p.  */
     341              : 
     342              : static int const x86_64_preserve_none_int_parameter_registers[6] =
     343              : {
     344              :   R12_REG, R13_REG, R14_REG, R15_REG, DI_REG, SI_REG
     345              : };
     346              : 
     347              : static int const x86_64_int_return_registers[2] =
     348              : {
     349              :   AX_REG, DX_REG
     350              : };
     351              : 
     352              : /* Define the structure for the machine field in struct function.  */
     353              : 
     354              : struct GTY(()) stack_local_entry {
     355              :   unsigned short mode;
     356              :   unsigned short n;
     357              :   rtx rtl;
     358              :   struct stack_local_entry *next;
     359              : };
     360              : 
     361              : /* Which cpu are we scheduling for.  */
     362              : enum attr_cpu ix86_schedule;
     363              : 
     364              : /* Which cpu are we optimizing for.  */
     365              : enum processor_type ix86_tune;
     366              : 
     367              : /* Which instruction set architecture to use.  */
     368              : enum processor_type ix86_arch;
     369              : 
     370              : /* True if processor has SSE prefetch instruction.  */
     371              : unsigned char ix86_prefetch_sse;
     372              : 
     373              : /* Preferred alignment for stack boundary in bits.  */
     374              : unsigned int ix86_preferred_stack_boundary;
     375              : 
     376              : /* Alignment for incoming stack boundary in bits specified at
     377              :    command line.  */
     378              : unsigned int ix86_user_incoming_stack_boundary;
     379              : 
     380              : /* Default alignment for incoming stack boundary in bits.  */
     381              : unsigned int ix86_default_incoming_stack_boundary;
     382              : 
     383              : /* Alignment for incoming stack boundary in bits.  */
     384              : unsigned int ix86_incoming_stack_boundary;
     385              : 
     386              : /* True if there is no direct access to extern symbols.  */
     387              : bool ix86_has_no_direct_extern_access;
     388              : 
     389              : /* Calling abi specific va_list type nodes.  */
     390              : tree sysv_va_list_type_node;
     391              : tree ms_va_list_type_node;
     392              : 
     393              : /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
     394              : char internal_label_prefix[16];
     395              : int internal_label_prefix_len;
     396              : 
     397              : /* Fence to use after loop using movnt.  */
     398              : tree x86_mfence;
     399              : 
     400              : /* Register class used for passing given 64bit part of the argument.
     401              :    These represent classes as documented by the PS ABI, with the exception
     402              :    of SSESF, SSEDF classes, that are basically SSE class, just gcc will
     403              :    use SF or DFmode move instead of DImode to avoid reformatting penalties.
     404              : 
     405              :    Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
     406              :    whenever possible (upper half does contain padding).  */
     407              : enum x86_64_reg_class
     408              :   {
     409              :     X86_64_NO_CLASS,
     410              :     X86_64_INTEGER_CLASS,
     411              :     X86_64_INTEGERSI_CLASS,
     412              :     X86_64_SSE_CLASS,
     413              :     X86_64_SSEHF_CLASS,
     414              :     X86_64_SSESF_CLASS,
     415              :     X86_64_SSEDF_CLASS,
     416              :     X86_64_SSEUP_CLASS,
     417              :     X86_64_X87_CLASS,
     418              :     X86_64_X87UP_CLASS,
     419              :     X86_64_COMPLEX_X87_CLASS,
     420              :     X86_64_MEMORY_CLASS
     421              :   };
     422              : 
     423              : #define MAX_CLASSES 8
     424              : 
     425              : /* Table of constants used by fldpi, fldln2, etc....  */
     426              : static REAL_VALUE_TYPE ext_80387_constants_table [5];
     427              : static bool ext_80387_constants_init;
     428              : 
     429              : 
     430              : static rtx ix86_function_value (const_tree, const_tree, bool);
     431              : static bool ix86_function_value_regno_p (const unsigned int);
     432              : static unsigned int ix86_function_arg_boundary (machine_mode,
     433              :                                                 const_tree);
     434              : static rtx ix86_static_chain (const_tree, bool);
     435              : static int ix86_function_regparm (const_tree, const_tree);
     436              : static void ix86_compute_frame_layout (void);
     437              : static tree ix86_canonical_va_list_type (tree);
     438              : static unsigned int split_stack_prologue_scratch_regno (void);
     439              : static bool i386_asm_output_addr_const_extra (FILE *, rtx);
     440              : 
     441              : static bool ix86_can_inline_p (tree, tree);
     442              : static unsigned int ix86_minimum_incoming_stack_boundary (bool);
     443              : 
     444              : typedef enum ix86_flags_cc
     445              : {
     446              :   X86_CCO = 0, X86_CCNO, X86_CCB, X86_CCNB,
     447              :   X86_CCE, X86_CCNE, X86_CCBE, X86_CCNBE,
     448              :   X86_CCS, X86_CCNS, X86_CCP, X86_CCNP,
     449              :   X86_CCL, X86_CCNL, X86_CCLE, X86_CCNLE
     450              : } ix86_cc;
     451              : 
     452              : static const char *ix86_ccmp_dfv_mapping[] =
     453              : {
     454              :   "{dfv=of}", "{dfv=}", "{dfv=cf}", "{dfv=}",
     455              :   "{dfv=zf}", "{dfv=}", "{dfv=cf, zf}", "{dfv=}",
     456              :   "{dfv=sf}", "{dfv=}", "{dfv=cf}", "{dfv=}",
     457              :   "{dfv=sf}", "{dfv=sf, of}", "{dfv=sf, of, zf}", "{dfv=sf, of}"
     458              : };
     459              : 
     460              : 
     461              : /* Whether -mtune= or -march= were specified */
     462              : int ix86_tune_defaulted;
     463              : int ix86_arch_specified;
     464              : 
     465              : /* Return true if a red-zone is in use.  We can't use red-zone when
     466              :    there are local indirect jumps, like "indirect_jump" or "tablejump",
     467              :    which jumps to another place in the function, since "call" in the
     468              :    indirect thunk pushes the return address onto stack, destroying
     469              :    red-zone.
     470              : 
     471              :    NB: Don't use red-zone for functions with no_caller_saved_registers
     472              :    and 32 GPRs or 16 XMM registers since 128-byte red-zone is too small
     473              :    for 31 GPRs or 15 GPRs + 16 XMM registers.
     474              : 
     475              :    TODO: If we can reserve the first 2 WORDs, for PUSH and, another
     476              :    for CALL, in red-zone, we can allow local indirect jumps with
     477              :    indirect thunk.  */
     478              : 
     479              : bool
     480      9977279 : ix86_using_red_zone (void)
     481              : {
     482      9977279 :   return (TARGET_RED_ZONE
     483      9033573 :           && !TARGET_64BIT_MS_ABI
     484      8730646 :           && ((!TARGET_APX_EGPR && !TARGET_SSE)
     485      8707502 :               || (cfun->machine->call_saved_registers
     486      8707502 :                   != TYPE_NO_CALLER_SAVED_REGISTERS))
     487     18707830 :           && (!cfun->machine->has_local_indirect_jump
     488        49190 :               || cfun->machine->indirect_branch_type == indirect_branch_keep));
     489              : }
     490              : 
     491              : /* Return true, if profiling code should be emitted before
     492              :    prologue. Otherwise it returns false.
     493              :    Note: For x86 with "hotfix" it is sorried.  */
     494              : static bool
     495      4533273 : ix86_profile_before_prologue (void)
     496              : {
     497      4533273 :   return flag_fentry != 0;
     498              : }
     499              : 
     500              : /* Update register usage after having seen the compiler flags.  */
     501              : 
     502              : static void
     503       778760 : ix86_conditional_register_usage (void)
     504              : {
     505       778760 :   int i, c_mask;
     506              : 
     507              :   /* For 32-bit targets, disable the REX registers.  */
     508       778760 :   if (! TARGET_64BIT)
     509              :     {
     510       133830 :       for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
     511       118960 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     512       133830 :       for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
     513       118960 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     514       252790 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     515       237920 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     516              :     }
     517              : 
     518              :   /* Set up the call-used registers based on the system ABI (ix86_abi).
     519              : 
     520              :      See the definition of CALL_USED_REGISTERS in i386.h.  */
     521       778760 :   c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT && ix86_abi == MS_ABI);
     522              : 
     523       778760 :   CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
     524              : 
     525     72424680 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     526              :     {
     527              :       /* Set/reset conditionally defined registers from
     528              :          CALL_USED_REGISTERS initializer.  */
     529     71645920 :       if (call_used_regs[i] > 1)
     530     12460105 :         call_used_regs[i] = !!(call_used_regs[i] & c_mask);
     531              : 
     532              :       /* Calculate registers of CLOBBERED_REGS register set
     533              :          as call used registers from GENERAL_REGS register set.  */
     534     71645920 :       if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
     535     71645920 :           && call_used_regs[i])
     536     21833750 :         SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
     537              :     }
     538              : 
     539              :   /* If MMX is disabled, disable the registers.  */
     540       778760 :   if (! TARGET_MMX)
     541       382328 :     accessible_reg_set &= ~reg_class_contents[MMX_REGS];
     542              : 
     543              :   /* If SSE is disabled, disable the registers.  */
     544       778760 :   if (! TARGET_SSE)
     545       377162 :     accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS];
     546              : 
     547              :   /* If the FPU is disabled, disable the registers.  */
     548       778760 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
     549       377588 :     accessible_reg_set &= ~reg_class_contents[FLOAT_REGS];
     550              : 
     551              :   /* If AVX512F is disabled, disable the registers.  */
     552       778760 :   if (! TARGET_AVX512F)
     553              :     {
     554      9204786 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     555      8663328 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     556              : 
     557      1082916 :       accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS];
     558              :     }
     559              : 
     560              :   /* If APX is disabled, disable the registers.  */
     561       778760 :   if (! (TARGET_APX_EGPR && TARGET_64BIT))
     562              :     {
     563     13230947 :       for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)
     564     12452656 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     565              :     }
     566       778760 : }
     567              : 
     568              : /* Canonicalize a comparison from one we don't have to one we do have.  */
     569              : 
     570              : static void
     571     24782708 : ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
     572              :                               bool op0_preserve_value)
     573              : {
     574              :   /* The order of operands in x87 ficom compare is forced by combine in
     575              :      simplify_comparison () function. Float operator is treated as RTX_OBJ
     576              :      with a precedence over other operators and is always put in the first
     577              :      place. Swap condition and operands to match ficom instruction.  */
     578     24782708 :   if (!op0_preserve_value
     579     23977363 :       && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1))
     580              :     {
     581           26 :       enum rtx_code scode = swap_condition ((enum rtx_code) *code);
     582              : 
     583              :       /* We are called only for compares that are split to SAHF instruction.
     584              :          Ensure that we have setcc/jcc insn for the swapped condition.  */
     585           26 :       if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN)
     586              :         {
     587            6 :           std::swap (*op0, *op1);
     588            6 :           *code = (int) scode;
     589            6 :           return;
     590              :         }
     591              :     }
     592              : 
     593              :   /* SUB (a, b) underflows precisely when a < b.  Convert
     594              :      (compare (minus (a b)) a) to (compare (a b))
     595              :      to match *sub<mode>_3 pattern.  */
     596     23977357 :   if (!op0_preserve_value
     597     23977357 :       && (*code == GTU || *code == LEU)
     598      1884229 :       && GET_CODE (*op0) == MINUS
     599        79376 :       && rtx_equal_p (XEXP (*op0, 0), *op1))
     600              :     {
     601          487 :       *op1 = XEXP (*op0, 1);
     602          487 :       *op0 = XEXP (*op0, 0);
     603          487 :       *code = (int) swap_condition ((enum rtx_code) *code);
     604          487 :       return;
     605              :     }
     606              : 
     607              :   /* Swap operands of GTU comparison to canonicalize
     608              :      addcarry/subborrow comparison.  */
     609     24782215 :   if (!op0_preserve_value
     610     23976870 :       && *code == GTU
     611       883945 :       && GET_CODE (*op0) == PLUS
     612       318106 :       && ix86_carry_flag_operator (XEXP (*op0, 0), VOIDmode)
     613        44696 :       && GET_CODE (XEXP (*op0, 1)) == ZERO_EXTEND
     614     24822820 :       && GET_CODE (*op1) == ZERO_EXTEND)
     615              :     {
     616        37252 :       std::swap (*op0, *op1);
     617        37252 :       *code = (int) swap_condition ((enum rtx_code) *code);
     618        37252 :       return;
     619              :     }
     620              : }
     621              : 
     622              : /* Hook to determine if one function can safely inline another.  */
     623              : 
     624              : static bool
     625     10190045 : ix86_can_inline_p (tree caller, tree callee)
     626              : {
     627     10190045 :   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
     628     10190045 :   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
     629              : 
     630              :   /* Changes of those flags can be tolerated for always inlines. Lets hope
     631              :      user knows what he is doing.  */
     632     10190045 :   unsigned HOST_WIDE_INT always_inline_safe_mask
     633              :          = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
     634              :             | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
     635              :             | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
     636              :             | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
     637              :             | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
     638              :             | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
     639              :             | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
     640              : 
     641              : 
     642     10190045 :   if (!callee_tree)
     643      9592543 :     callee_tree = target_option_default_node;
     644     10190045 :   if (!caller_tree)
     645      9592608 :     caller_tree = target_option_default_node;
     646     10190045 :   if (callee_tree == caller_tree)
     647              :     return true;
     648              : 
     649         5292 :   struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
     650         5292 :   struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
     651         5292 :   bool ret = false;
     652         5292 :   bool always_inline
     653         5292 :     = (DECL_DISREGARD_INLINE_LIMITS (callee)
     654         9939 :        && lookup_attribute ("always_inline",
     655         4647 :                             DECL_ATTRIBUTES (callee)));
     656              : 
     657              :   /* If callee only uses GPRs, ignore MASK_80387.  */
     658         5292 :   if (TARGET_GENERAL_REGS_ONLY_P (callee_opts->x_ix86_target_flags))
     659         1030 :     always_inline_safe_mask |= MASK_80387;
     660              : 
     661         5292 :   cgraph_node *callee_node = cgraph_node::get (callee);
     662              :   /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
     663              :      function can inline a SSE2 function but a SSE2 function can't inline
     664              :      a SSE4 function.  */
     665         5292 :   if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
     666              :        != callee_opts->x_ix86_isa_flags)
     667         5056 :       || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
     668              :           != callee_opts->x_ix86_isa_flags2))
     669              :     ret = false;
     670              : 
     671              :   /* See if we have the same non-isa options.  */
     672         5019 :   else if ((!always_inline
     673          388 :             && caller_opts->x_target_flags != callee_opts->x_target_flags)
     674         4975 :            || (caller_opts->x_target_flags & ~always_inline_safe_mask)
     675         4975 :                != (callee_opts->x_target_flags & ~always_inline_safe_mask))
     676              :     ret = false;
     677              : 
     678         4975 :   else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
     679              :            /* If the callee doesn't use FP expressions differences in
     680              :               ix86_fpmath can be ignored.  We are called from FEs
     681              :               for multi-versioning call optimization, so beware of
     682              :               ipa_fn_summaries not available.  */
     683         1247 :            && (! ipa_fn_summaries
     684         1247 :                || ipa_fn_summaries->get (callee_node) == NULL
     685         1247 :                || ipa_fn_summaries->get (callee_node)->fp_expressions))
     686              :     ret = false;
     687              : 
     688              :   /* At this point we cannot identify whether arch or tune setting
     689              :      comes from target attribute or not. So the most conservative way
     690              :      is to allow the callee that uses default arch and tune string to
     691              :      be inlined.  */
     692         4701 :   else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
     693         1430 :            && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
     694              :     ret = true;
     695              : 
     696              :   /* See if arch, tune, etc. are the same. As previous ISA flags already
     697              :      checks if callee's ISA is subset of caller's, do not block
     698              :      always_inline attribute for callee even it has different arch. */
     699         3279 :   else if (!always_inline && caller_opts->arch != callee_opts->arch)
     700              :     ret = false;
     701              : 
     702           15 :   else if (!always_inline && caller_opts->tune != callee_opts->tune)
     703              :     ret = false;
     704              : 
     705         3279 :   else if (!always_inline
     706           15 :            && caller_opts->branch_cost != callee_opts->branch_cost)
     707              :     ret = false;
     708              : 
     709              :   else
     710     10189454 :     ret = true;
     711              : 
     712              :   return ret;
     713              : }
     714              : 
     715              : /* Return true if this goes in large data/bss.  */
     716              : 
     717              : static bool
     718     83187442 : ix86_in_large_data_p (tree exp)
     719              : {
     720     83187442 :   if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC
     721     83187204 :       && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC)
     722              :     return false;
     723              : 
     724         1147 :   if (exp == NULL_TREE)
     725              :     return false;
     726              : 
     727              :   /* Functions are never large data.  */
     728         1147 :   if (TREE_CODE (exp) == FUNCTION_DECL)
     729              :     return false;
     730              : 
     731              :   /* Automatic variables are never large data.  */
     732          279 :   if (VAR_P (exp) && !is_global_var (exp))
     733              :     return false;
     734              : 
     735          279 :   if (VAR_P (exp) && DECL_SECTION_NAME (exp))
     736              :     {
     737           51 :       const char *section = DECL_SECTION_NAME (exp);
     738           51 :       if (strcmp (section, ".ldata") == 0
     739           51 :           || startswith (section, ".ldata.")
     740           51 :           || strcmp (section, ".lbss") == 0
     741           51 :           || startswith (section, ".lbss.")
     742           99 :           || startswith (section, ".gnu.linkonce.lb."))
     743              :         return true;
     744              :       return false;
     745              :     }
     746              :   else
     747              :     {
     748          228 :       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
     749              : 
     750              :       /* If this is an incomplete type with size 0, then we can't put it
     751              :          in data because it might be too big when completed.  Also,
     752              :          int_size_in_bytes returns -1 if size can vary or is larger than
     753              :          an integer in which case also it is safer to assume that it goes in
     754              :          large data.  */
     755          228 :       if (size <= 0 || size > ix86_section_threshold)
     756              :         return true;
     757              :     }
     758              : 
     759              :   return false;
     760              : }
     761              : 
     762              : /* i386-specific section flag to mark large sections.  */
     763              : #define SECTION_LARGE SECTION_MACH_DEP
     764              : 
     765              : /* Switch to the appropriate section for output of DECL.
     766              :    DECL is either a `VAR_DECL' node or a constant of some sort.
     767              :    RELOC indicates whether forming the initial value of DECL requires
     768              :    link-time relocations.  */
     769              : 
     770              : ATTRIBUTE_UNUSED static section *
     771      1672884 : x86_64_elf_select_section (tree decl, int reloc,
     772              :                            unsigned HOST_WIDE_INT align)
     773              : {
     774      1672884 :   if (ix86_in_large_data_p (decl))
     775              :     {
     776            6 :       const char *sname = NULL;
     777            6 :       unsigned int flags = SECTION_WRITE | SECTION_LARGE;
     778            6 :       switch (categorize_decl_for_section (decl, reloc))
     779              :         {
     780            1 :         case SECCAT_DATA:
     781            1 :           sname = ".ldata";
     782            1 :           break;
     783            0 :         case SECCAT_DATA_REL:
     784            0 :           sname = ".ldata.rel";
     785            0 :           break;
     786            0 :         case SECCAT_DATA_REL_LOCAL:
     787            0 :           sname = ".ldata.rel.local";
     788            0 :           break;
     789            0 :         case SECCAT_DATA_REL_RO:
     790            0 :           sname = ".ldata.rel.ro";
     791            0 :           break;
     792            0 :         case SECCAT_DATA_REL_RO_LOCAL:
     793            0 :           sname = ".ldata.rel.ro.local";
     794            0 :           break;
     795            0 :         case SECCAT_BSS:
     796            0 :           sname = ".lbss";
     797            0 :           flags |= SECTION_BSS;
     798            0 :           break;
     799              :         case SECCAT_RODATA:
     800              :         case SECCAT_RODATA_MERGE_STR:
     801              :         case SECCAT_RODATA_MERGE_STR_INIT:
     802              :         case SECCAT_RODATA_MERGE_CONST:
     803              :           sname = ".lrodata";
     804              :           flags &= ~SECTION_WRITE;
     805              :           break;
     806            0 :         case SECCAT_SRODATA:
     807            0 :         case SECCAT_SDATA:
     808            0 :         case SECCAT_SBSS:
     809            0 :           gcc_unreachable ();
     810              :         case SECCAT_TEXT:
     811              :         case SECCAT_TDATA:
     812              :         case SECCAT_TBSS:
     813              :           /* We don't split these for medium model.  Place them into
     814              :              default sections and hope for best.  */
     815              :           break;
     816              :         }
     817            1 :       if (sname)
     818              :         {
     819              :           /* We might get called with string constants, but get_named_section
     820              :              doesn't like them as they are not DECLs.  Also, we need to set
     821              :              flags in that case.  */
     822            6 :           if (!DECL_P (decl))
     823            3 :             return get_section (sname, flags, NULL);
     824            3 :           return get_named_section (decl, sname, reloc);
     825              :         }
     826              :     }
     827      1672878 :   return default_elf_select_section (decl, reloc, align);
     828              : }
     829              : 
     830              : /* Select a set of attributes for section NAME based on the properties
     831              :    of DECL and whether or not RELOC indicates that DECL's initializer
     832              :    might contain runtime relocations.  */
     833              : 
     834              : static unsigned int ATTRIBUTE_UNUSED
     835     69699788 : x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
     836              : {
     837     69699788 :   unsigned int flags = default_section_type_flags (decl, name, reloc);
     838              : 
     839     69699788 :   if (ix86_in_large_data_p (decl))
     840           10 :     flags |= SECTION_LARGE;
     841              : 
     842     69699788 :   if (decl == NULL_TREE
     843          375 :       && (strcmp (name, ".ldata.rel.ro") == 0
     844          375 :           || strcmp (name, ".ldata.rel.ro.local") == 0))
     845            0 :     flags |= SECTION_RELRO;
     846              : 
     847     69699788 :   if (strcmp (name, ".lbss") == 0
     848     69699784 :       || startswith (name, ".lbss.")
     849    139399569 :       || startswith (name, ".gnu.linkonce.lb."))
     850              :     {
     851            7 :       flags |= SECTION_BSS;
     852              :       /* Clear SECTION_NOTYPE so .lbss etc. are marked @nobits in
     853              :          default_elf_asm_named_section.  */
     854            7 :       flags &= ~SECTION_NOTYPE;
     855              :     }
     856              : 
     857     69699788 :   return flags;
     858              : }
     859              : 
     860              : /* Build up a unique section name, expressed as a
     861              :    STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
     862              :    RELOC indicates whether the initial value of EXP requires
     863              :    link-time relocations.  */
     864              : 
     865              : static void ATTRIBUTE_UNUSED
     866      1814317 : x86_64_elf_unique_section (tree decl, int reloc)
     867              : {
     868      1814317 :   if (ix86_in_large_data_p (decl))
     869              :     {
     870            3 :       const char *prefix = NULL;
     871              :       /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
     872            3 :       bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
     873              : 
     874            3 :       switch (categorize_decl_for_section (decl, reloc))
     875              :         {
     876            0 :         case SECCAT_DATA:
     877            0 :         case SECCAT_DATA_REL:
     878            0 :         case SECCAT_DATA_REL_LOCAL:
     879            0 :         case SECCAT_DATA_REL_RO:
     880            0 :         case SECCAT_DATA_REL_RO_LOCAL:
     881            0 :           prefix = one_only ? ".ld" : ".ldata";
     882              :           break;
     883            3 :         case SECCAT_BSS:
     884            3 :           prefix = one_only ? ".lb" : ".lbss";
     885              :           break;
     886              :         case SECCAT_RODATA:
     887              :         case SECCAT_RODATA_MERGE_STR:
     888              :         case SECCAT_RODATA_MERGE_STR_INIT:
     889              :         case SECCAT_RODATA_MERGE_CONST:
     890              :           prefix = one_only ? ".lr" : ".lrodata";
     891              :           break;
     892            0 :         case SECCAT_SRODATA:
     893            0 :         case SECCAT_SDATA:
     894            0 :         case SECCAT_SBSS:
     895            0 :           gcc_unreachable ();
     896              :         case SECCAT_TEXT:
     897              :         case SECCAT_TDATA:
     898              :         case SECCAT_TBSS:
     899              :           /* We don't split these for medium model.  Place them into
     900              :              default sections and hope for best.  */
     901              :           break;
     902              :         }
     903            3 :       if (prefix)
     904              :         {
     905            3 :           const char *name, *linkonce;
     906            3 :           char *string;
     907              : 
     908            3 :           name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     909            3 :           name = targetm.strip_name_encoding (name);
     910              : 
     911              :           /* If we're using one_only, then there needs to be a .gnu.linkonce
     912              :              prefix to the section name.  */
     913            3 :           linkonce = one_only ? ".gnu.linkonce" : "";
     914              : 
     915            3 :           string = ACONCAT ((linkonce, prefix, ".", name, NULL));
     916              : 
     917            3 :           set_decl_section_name (decl, string);
     918            3 :           return;
     919              :         }
     920              :     }
     921      1814314 :   default_unique_section (decl, reloc);
     922              : }
     923              : 
     924              : /* Return true if TYPE has no_callee_saved_registers or preserve_none
     925              :    attribute.  */
     926              : 
     927              : static bool
     928      1585766 : ix86_type_no_callee_saved_registers_p (const_tree fntype)
     929              : {
     930       132328 :   auto type = ix86_fntype_call_saved_registers (fntype);
     931      1585766 :   return type == TYPE_PRESERVE_NONE || type == TYPE_NO_CALLEE_SAVED_REGISTERS;
     932              : }
     933              : 
     934              : #ifdef COMMON_ASM_OP
     935              : 
     936              : #ifndef LARGECOMM_SECTION_ASM_OP
     937              : #define LARGECOMM_SECTION_ASM_OP "\t.largecomm\t"
     938              : #endif
     939              : 
     940              : /* This says how to output assembler code to declare an
     941              :    uninitialized external linkage data object.
     942              : 
     943              :    For medium model x86-64 we need to use LARGECOMM_SECTION_ASM_OP opcode for
     944              :    large objects.  */
     945              : void
     946       171447 : x86_elf_aligned_decl_common (FILE *file, tree decl,
     947              :                         const char *name, unsigned HOST_WIDE_INT size,
     948              :                         unsigned align)
     949              : {
     950       171447 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     951       171441 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     952            7 :       && size > (unsigned int)ix86_section_threshold)
     953              :     {
     954            1 :       switch_to_section (get_named_section (decl, ".lbss", 0));
     955            1 :       fputs (LARGECOMM_SECTION_ASM_OP, file);
     956              :     }
     957              :   else
     958       171446 :     fputs (COMMON_ASM_OP, file);
     959       171447 :   assemble_name (file, name);
     960       171447 :   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
     961              :            size, align / BITS_PER_UNIT);
     962       171447 : }
     963              : #endif
     964              : 
     965              : /* Utility function for targets to use in implementing
     966              :    ASM_OUTPUT_ALIGNED_BSS.  */
     967              : 
     968              : void
     969       770020 : x86_output_aligned_bss (FILE *file, tree decl, const char *name,
     970              :                         unsigned HOST_WIDE_INT size, unsigned align)
     971              : {
     972       770020 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     973       770010 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     974           42 :       && size > (unsigned int)ix86_section_threshold)
     975            3 :     switch_to_section (get_named_section (decl, ".lbss", 0));
     976              :   else
     977       770017 :     switch_to_section (bss_section);
     978       925967 :   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
     979              : #ifdef ASM_DECLARE_OBJECT_NAME
     980       770020 :   last_assemble_variable_decl = decl;
     981       770020 :   ASM_DECLARE_OBJECT_NAME (file, name, decl);
     982              : #else
     983              :   /* Standard thing is just output label for the object.  */
     984              :   ASM_OUTPUT_LABEL (file, name);
     985              : #endif /* ASM_DECLARE_OBJECT_NAME */
     986       770020 :   ASM_OUTPUT_SKIP (file, size ? size : 1);
     987       770020 : }
     988              : 
     989              : /* Decide whether we must probe the stack before any space allocation
     990              :    on this target.  It's essentially TARGET_STACK_PROBE except when
     991              :    -fstack-check causes the stack to be already probed differently.  */
     992              : 
     993              : bool
     994       877890 : ix86_target_stack_probe (void)
     995              : {
     996              :   /* Do not probe the stack twice if static stack checking is enabled.  */
     997       877890 :   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
     998              :     return false;
     999              : 
    1000       877890 :   return TARGET_STACK_PROBE;
    1001              : }
    1002              : 
    1003              : /* Decide whether we can make a sibling call to a function.  DECL is the
    1004              :    declaration of the function being targeted by the call and EXP is the
    1005              :    CALL_EXPR representing the call.  */
    1006              : 
    1007              : static bool
    1008       137664 : ix86_function_ok_for_sibcall (tree decl, tree exp)
    1009              : {
    1010       137664 :   tree type, decl_or_type;
    1011       137664 :   rtx a, b;
    1012       137664 :   bool bind_global = decl && !targetm.binds_local_p (decl);
    1013              : 
    1014       137664 :   if (ix86_function_naked (current_function_decl))
    1015              :     return false;
    1016              : 
    1017              :   /* Sibling call isn't OK if there are no caller-saved registers
    1018              :      since all registers must be preserved before return.  */
    1019       137662 :   if (cfun->machine->call_saved_registers
    1020       137662 :       == TYPE_NO_CALLER_SAVED_REGISTERS)
    1021              :     return false;
    1022              : 
    1023              :   /* If we are generating position-independent code, we cannot sibcall
    1024              :      optimize direct calls to global functions, as the PLT requires
    1025              :      %ebx be live. (Darwin does not have a PLT.)  */
    1026       137624 :   if (!TARGET_MACHO
    1027       137624 :       && !TARGET_64BIT
    1028        11360 :       && flag_pic
    1029         8413 :       && flag_plt
    1030         8413 :       && bind_global)
    1031              :     return false;
    1032              : 
    1033              :   /* If we need to align the outgoing stack, then sibcalling would
    1034              :      unalign the stack, which may break the called function.  */
    1035       132962 :   if (ix86_minimum_incoming_stack_boundary (true)
    1036       132962 :       < PREFERRED_STACK_BOUNDARY)
    1037              :     return false;
    1038              : 
    1039       132381 :   if (decl)
    1040              :     {
    1041       121473 :       decl_or_type = decl;
    1042       121473 :       type = TREE_TYPE (decl);
    1043              :     }
    1044              :   else
    1045              :     {
    1046              :       /* We're looking at the CALL_EXPR, we need the type of the function.  */
    1047        10908 :       type = CALL_EXPR_FN (exp);                /* pointer expression */
    1048        10908 :       type = TREE_TYPE (type);                  /* pointer type */
    1049        10908 :       type = TREE_TYPE (type);                  /* function type */
    1050        10908 :       decl_or_type = type;
    1051              :     }
    1052              : 
    1053              :   /* Sibling call isn't OK if callee has no callee-saved registers
    1054              :      and the calling function has callee-saved registers.  */
    1055       132381 :   if ((cfun->machine->call_saved_registers
    1056       132381 :        != TYPE_NO_CALLEE_SAVED_REGISTERS)
    1057       132381 :       && cfun->machine->call_saved_registers != TYPE_PRESERVE_NONE
    1058       264709 :       && ix86_type_no_callee_saved_registers_p (type))
    1059              :     return false;
    1060              : 
    1061              :   /* If outgoing reg parm stack space changes, we cannot do sibcall.  */
    1062       132361 :   if ((OUTGOING_REG_PARM_STACK_SPACE (type)
    1063       132361 :        != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
    1064       263964 :       || (REG_PARM_STACK_SPACE (decl_or_type)
    1065       131603 :           != REG_PARM_STACK_SPACE (current_function_decl)))
    1066              :     {
    1067          758 :       maybe_complain_about_tail_call (exp,
    1068              :                                       "inconsistent size of stack space"
    1069              :                                       " allocated for arguments which are"
    1070              :                                       " passed in registers");
    1071          758 :       return false;
    1072              :     }
    1073              : 
    1074              :   /* Check that the return value locations are the same.  Like
    1075              :      if we are returning floats on the 80387 register stack, we cannot
    1076              :      make a sibcall from a function that doesn't return a float to a
    1077              :      function that does or, conversely, from a function that does return
    1078              :      a float to a function that doesn't; the necessary stack adjustment
    1079              :      would not be executed.  This is also the place we notice
    1080              :      differences in the return value ABI.  Note that it is ok for one
    1081              :      of the functions to have void return type as long as the return
    1082              :      value of the other is passed in a register.  */
    1083       131603 :   a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
    1084       131603 :   b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
    1085       131603 :                            cfun->decl, false);
    1086       131603 :   if (STACK_REG_P (a) || STACK_REG_P (b))
    1087              :     {
    1088         1035 :       if (!rtx_equal_p (a, b))
    1089              :         return false;
    1090              :     }
    1091       130568 :   else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
    1092              :     ;
    1093        24086 :   else if (!rtx_equal_p (a, b))
    1094              :     return false;
    1095              : 
    1096       131214 :   if (TARGET_64BIT)
    1097              :     {
    1098              :       /* The SYSV ABI has more call-clobbered registers;
    1099              :          disallow sibcalls from MS to SYSV.  */
    1100       124516 :       if (cfun->machine->call_abi == MS_ABI
    1101       124516 :           && ix86_function_type_abi (type) == SYSV_ABI)
    1102              :         return false;
    1103              :     }
    1104              :   else
    1105              :     {
    1106              :       /* If this call is indirect, we'll need to be able to use a
    1107              :          call-clobbered register for the address of the target function.
    1108              :          Make sure that all such registers are not used for passing
    1109              :          parameters.  Note that DLLIMPORT functions and call to global
    1110              :          function via GOT slot are indirect.  */
    1111         6698 :       if (!decl
    1112         4803 :           || (bind_global && flag_pic && !flag_plt)
    1113              :           || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl))
    1114         4803 :           || flag_force_indirect_call)
    1115              :         {
    1116              :           /* Check if regparm >= 3 since arg_reg_available is set to
    1117              :              false if regparm == 0.  If regparm is 1 or 2, there is
    1118              :              always a call-clobbered register available.
    1119              : 
    1120              :              ??? The symbol indirect call doesn't need a call-clobbered
    1121              :              register.  But we don't know if this is a symbol indirect
    1122              :              call or not here.  */
    1123         1895 :           if (ix86_function_regparm (type, decl) >= 3
    1124         1895 :               && !cfun->machine->arg_reg_available)
    1125              :             return false;
    1126              :         }
    1127              :     }
    1128              : 
    1129       131214 :   if (decl && ix86_use_pseudo_pic_reg ())
    1130              :     {
    1131              :       /* When PIC register is used, it must be restored after ifunc
    1132              :          function returns.  */
    1133         2066 :        cgraph_node *node = cgraph_node::get (decl);
    1134         2066 :        if (node && node->ifunc_resolver)
    1135              :          return false;
    1136              :     }
    1137              : 
    1138              :   /* Disable sibcall if callee has indirect_return attribute and
    1139              :      caller doesn't since callee will return to the caller's caller
    1140              :      via an indirect jump.  */
    1141       131214 :   if (((flag_cf_protection & (CF_RETURN | CF_BRANCH))
    1142              :        == (CF_RETURN | CF_BRANCH))
    1143        52000 :       && lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (type))
    1144       131218 :       && !lookup_attribute ("indirect_return",
    1145            4 :                             TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
    1146              :     return false;
    1147              : 
    1148              :   /* Otherwise okay.  That also includes certain types of indirect calls.  */
    1149              :   return true;
    1150              : }
    1151              : 
    1152              : /* This function determines from TYPE the calling-convention.  */
    1153              : 
    1154              : unsigned int
    1155      6254283 : ix86_get_callcvt (const_tree type)
    1156              : {
    1157      6254283 :   unsigned int ret = 0;
    1158      6254283 :   bool is_stdarg;
    1159      6254283 :   tree attrs;
    1160              : 
    1161      6254283 :   if (TARGET_64BIT)
    1162              :     return IX86_CALLCVT_CDECL;
    1163              : 
    1164      3271955 :   attrs = TYPE_ATTRIBUTES (type);
    1165      3271955 :   if (attrs != NULL_TREE)
    1166              :     {
    1167        68241 :       if (lookup_attribute ("cdecl", attrs))
    1168              :         ret |= IX86_CALLCVT_CDECL;
    1169        68241 :       else if (lookup_attribute ("stdcall", attrs))
    1170              :         ret |= IX86_CALLCVT_STDCALL;
    1171        68241 :       else if (lookup_attribute ("fastcall", attrs))
    1172              :         ret |= IX86_CALLCVT_FASTCALL;
    1173        68232 :       else if (lookup_attribute ("thiscall", attrs))
    1174              :         ret |= IX86_CALLCVT_THISCALL;
    1175              : 
    1176              :       /* Regparm isn't allowed for thiscall and fastcall.  */
    1177              :       if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
    1178              :         {
    1179        68232 :           if (lookup_attribute ("regparm", attrs))
    1180        15844 :             ret |= IX86_CALLCVT_REGPARM;
    1181        68232 :           if (lookup_attribute ("sseregparm", attrs))
    1182            0 :             ret |= IX86_CALLCVT_SSEREGPARM;
    1183              :         }
    1184              : 
    1185        68241 :       if (IX86_BASE_CALLCVT(ret) != 0)
    1186            9 :         return ret;
    1187              :     }
    1188              : 
    1189      3271946 :   is_stdarg = stdarg_p (type);
    1190      3271946 :   if (TARGET_RTD && !is_stdarg)
    1191            0 :     return IX86_CALLCVT_STDCALL | ret;
    1192              : 
    1193      3271946 :   if (ret != 0
    1194      3271946 :       || is_stdarg
    1195      3247059 :       || TREE_CODE (type) != METHOD_TYPE
    1196      3408624 :       || ix86_function_type_abi (type) != MS_ABI)
    1197      3271946 :     return IX86_CALLCVT_CDECL | ret;
    1198              : 
    1199              :   return IX86_CALLCVT_THISCALL;
    1200              : }
    1201              : 
    1202              : /* Return 0 if the attributes for two types are incompatible, 1 if they
    1203              :    are compatible, and 2 if they are nearly compatible (which causes a
    1204              :    warning to be generated).  */
    1205              : 
    1206              : static int
    1207      1508809 : ix86_comp_type_attributes (const_tree type1, const_tree type2)
    1208              : {
    1209      1508809 :   unsigned int ccvt1, ccvt2;
    1210              : 
    1211      1508809 :   if (TREE_CODE (type1) != FUNCTION_TYPE
    1212      1508809 :       && TREE_CODE (type1) != METHOD_TYPE)
    1213              :     return 1;
    1214              : 
    1215      1502304 :   ccvt1 = ix86_get_callcvt (type1);
    1216      1502304 :   ccvt2 = ix86_get_callcvt (type2);
    1217      1502304 :   if (ccvt1 != ccvt2)
    1218              :     return 0;
    1219      2982448 :   if (ix86_function_regparm (type1, NULL)
    1220      1491224 :       != ix86_function_regparm (type2, NULL))
    1221              :     return 0;
    1222              : 
    1223       726719 :   if (ix86_type_no_callee_saved_registers_p (type1)
    1224       726719 :       != ix86_type_no_callee_saved_registers_p (type2))
    1225              :     return 0;
    1226              : 
    1227              :   /* preserve_none attribute uses a different calling convention is
    1228              :      only for 64-bit.  */
    1229       726506 :   if (TARGET_64BIT
    1230      1452952 :       && (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type1))
    1231       726446 :           != lookup_attribute ("preserve_none",
    1232       726446 :                                TYPE_ATTRIBUTES (type2))))
    1233              :     return 0;
    1234              : 
    1235              :   return 1;
    1236              : }
    1237              : 
    1238              : /* Return the regparm value for a function with the indicated TYPE and DECL.
    1239              :    DECL may be NULL when calling function indirectly
    1240              :    or considering a libcall.  */
    1241              : 
    1242              : static int
    1243      4254638 : ix86_function_regparm (const_tree type, const_tree decl)
    1244              : {
    1245      4254638 :   tree attr;
    1246      4254638 :   int regparm;
    1247      4254638 :   unsigned int ccvt;
    1248              : 
    1249      4254638 :   if (TARGET_64BIT)
    1250      2982328 :     return (ix86_function_type_abi (type) == SYSV_ABI
    1251      2982328 :             ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
    1252      1272310 :   ccvt = ix86_get_callcvt (type);
    1253      1272310 :   regparm = ix86_regparm;
    1254              : 
    1255      1272310 :   if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
    1256              :     {
    1257         2020 :       attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
    1258         2020 :       if (attr)
    1259              :         {
    1260         2020 :           regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
    1261         2020 :           return regparm;
    1262              :         }
    1263              :     }
    1264      1270290 :   else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    1265              :     return 2;
    1266      1270290 :   else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1267              :     return 1;
    1268              : 
    1269              :   /* Use register calling convention for local functions when possible.  */
    1270      1270290 :   if (decl
    1271      1205951 :       && TREE_CODE (decl) == FUNCTION_DECL)
    1272              :     {
    1273      1195860 :       cgraph_node *target = cgraph_node::get (decl);
    1274      1195860 :       if (target)
    1275      1188352 :         target = target->function_symbol ();
    1276              : 
    1277              :       /* Caller and callee must agree on the calling convention, so
    1278              :          checking here just optimize means that with
    1279              :          __attribute__((optimize (...))) caller could use regparm convention
    1280              :          and callee not, or vice versa.  Instead look at whether the callee
    1281              :          is optimized or not.  */
    1282      1188352 :       if (target && opt_for_fn (target->decl, optimize)
    1283      2375812 :           && !(profile_flag && !flag_fentry))
    1284              :         {
    1285      1187460 :           if (target->local && target->can_change_signature)
    1286              :             {
    1287       139912 :               int local_regparm, globals = 0, regno;
    1288              : 
    1289              :               /* Make sure no regparm register is taken by a
    1290              :                  fixed register variable.  */
    1291       139912 :               for (local_regparm = 0; local_regparm < REGPARM_MAX;
    1292              :                    local_regparm++)
    1293       104934 :                 if (fixed_regs[local_regparm])
    1294              :                   break;
    1295              : 
    1296              :               /* We don't want to use regparm(3) for nested functions as
    1297              :                  these use a static chain pointer in the third argument.  */
    1298        34978 :               if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
    1299              :                 local_regparm = 2;
    1300              : 
    1301              :               /* Save a register for the split stack.  */
    1302        34978 :               if (flag_split_stack)
    1303              :                 {
    1304        20628 :                   if (local_regparm == 3)
    1305              :                     local_regparm = 2;
    1306          707 :                   else if (local_regparm == 2
    1307          707 :                            && DECL_STATIC_CHAIN (target->decl))
    1308              :                     local_regparm = 1;
    1309              :                 }
    1310              : 
    1311              :               /* Each fixed register usage increases register pressure,
    1312              :                  so less registers should be used for argument passing.
    1313              :                  This functionality can be overridden by an explicit
    1314              :                  regparm value.  */
    1315       244846 :               for (regno = AX_REG; regno <= DI_REG; regno++)
    1316       209868 :                 if (fixed_regs[regno])
    1317            0 :                   globals++;
    1318              : 
    1319        34978 :               local_regparm
    1320        34978 :                 = globals < local_regparm ? local_regparm - globals : 0;
    1321              : 
    1322        34978 :               if (local_regparm > regparm)
    1323      4254638 :                 regparm = local_regparm;
    1324              :             }
    1325              :         }
    1326              :     }
    1327              : 
    1328              :   return regparm;
    1329              : }
    1330              : 
    1331              : /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
    1332              :    DFmode (2) arguments in SSE registers for a function with the
    1333              :    indicated TYPE and DECL.  DECL may be NULL when calling function
    1334              :    indirectly or considering a libcall.  Return -1 if any FP parameter
    1335              :    should be rejected by error.  This is used in siutation we imply SSE
    1336              :    calling convention but the function is called from another function with
    1337              :    SSE disabled. Otherwise return 0.  */
    1338              : 
    1339              : static int
    1340      1079137 : ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
    1341              : {
    1342      1079137 :   gcc_assert (!TARGET_64BIT);
    1343              : 
    1344              :   /* Use SSE registers to pass SFmode and DFmode arguments if requested
    1345              :      by the sseregparm attribute.  */
    1346      1079137 :   if (TARGET_SSEREGPARM
    1347      1079137 :       || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
    1348              :     {
    1349            0 :       if (!TARGET_SSE)
    1350              :         {
    1351            0 :           if (warn)
    1352              :             {
    1353            0 :               if (decl)
    1354            0 :                 error ("calling %qD with attribute sseregparm without "
    1355              :                        "SSE/SSE2 enabled", decl);
    1356              :               else
    1357            0 :                 error ("calling %qT with attribute sseregparm without "
    1358              :                        "SSE/SSE2 enabled", type);
    1359              :             }
    1360            0 :           return 0;
    1361              :         }
    1362              : 
    1363              :       return 2;
    1364              :     }
    1365              : 
    1366      1079137 :   if (!decl)
    1367              :     return 0;
    1368              : 
    1369       979647 :   cgraph_node *target = cgraph_node::get (decl);
    1370       979647 :   if (target)
    1371       972146 :     target = target->function_symbol ();
    1372              : 
    1373              :   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
    1374              :      (and DFmode for SSE2) arguments in SSE registers.  */
    1375       972146 :   if (target
    1376              :       /* TARGET_SSE_MATH */
    1377       972146 :       && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
    1378         1296 :       && opt_for_fn (target->decl, optimize)
    1379       973442 :       && !(profile_flag && !flag_fentry))
    1380              :     {
    1381         1296 :       if (target->local && target->can_change_signature)
    1382              :         {
    1383              :           /* Refuse to produce wrong code when local function with SSE enabled
    1384              :              is called from SSE disabled function.
    1385              :              FIXME: We need a way to detect these cases cross-ltrans partition
    1386              :              and avoid using SSE calling conventions on local functions called
    1387              :              from function with SSE disabled.  For now at least delay the
    1388              :              warning until we know we are going to produce wrong code.
    1389              :              See PR66047  */
    1390            0 :           if (!TARGET_SSE && warn)
    1391              :             return -1;
    1392            0 :           return TARGET_SSE2_P (target_opts_for_fn (target->decl)
    1393            0 :                                 ->x_ix86_isa_flags) ? 2 : 1;
    1394              :         }
    1395              :     }
    1396              : 
    1397              :   return 0;
    1398              : }
    1399              : 
    1400              : /* Return true if EAX is live at the start of the function.  Used by
    1401              :    ix86_expand_prologue to determine if we need special help before
    1402              :    calling allocate_stack_worker.  */
    1403              : 
    1404              : static bool
    1405         7090 : ix86_eax_live_at_start_p (void)
    1406              : {
    1407              :   /* Cheat.  Don't bother working forward from ix86_function_regparm
    1408              :      to the function type to whether an actual argument is located in
    1409              :      eax.  Instead just look at cfg info, which is still close enough
    1410              :      to correct at this point.  This gives false positives for broken
    1411              :      functions that might use uninitialized data that happens to be
    1412              :      allocated in eax, but who cares?  */
    1413         7090 :   return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 0);
    1414              : }
    1415              : 
    1416              : static bool
    1417       159993 : ix86_keep_aggregate_return_pointer (tree fntype)
    1418              : {
    1419       159993 :   tree attr;
    1420              : 
    1421       159993 :   if (!TARGET_64BIT)
    1422              :     {
    1423       159993 :       attr = lookup_attribute ("callee_pop_aggregate_return",
    1424       159993 :                                TYPE_ATTRIBUTES (fntype));
    1425       159993 :       if (attr)
    1426            0 :         return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
    1427              : 
    1428              :       /* For 32-bit MS-ABI the default is to keep aggregate
    1429              :          return pointer.  */
    1430       159993 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    1431              :         return true;
    1432              :     }
    1433              :   return KEEP_AGGREGATE_RETURN_POINTER != 0;
    1434              : }
    1435              : 
    1436              : /* Value is the number of bytes of arguments automatically
    1437              :    popped when returning from a subroutine call.
    1438              :    FUNDECL is the declaration node of the function (as a tree),
    1439              :    FUNTYPE is the data type of the function (as a tree),
    1440              :    or for a library call it is an identifier node for the subroutine name.
    1441              :    SIZE is the number of bytes of arguments passed on the stack.
    1442              : 
    1443              :    On the 80386, the RTD insn may be used to pop them if the number
    1444              :      of args is fixed, but if the number is variable then the caller
    1445              :      must pop them all.  RTD can't be used for library calls now
    1446              :      because the library is compiled with the Unix compiler.
    1447              :    Use of RTD is a selectable option, since it is incompatible with
    1448              :    standard Unix calling sequences.  If the option is not selected,
    1449              :    the caller must always pop the args.
    1450              : 
    1451              :    The attribute stdcall is equivalent to RTD on a per module basis.  */
    1452              : 
    1453              : static poly_int64
    1454      7665318 : ix86_return_pops_args (tree fundecl, tree funtype, poly_int64 size)
    1455              : {
    1456      7665318 :   unsigned int ccvt;
    1457              : 
    1458              :   /* None of the 64-bit ABIs pop arguments.  */
    1459      7665318 :   if (TARGET_64BIT)
    1460      6791287 :     return 0;
    1461              : 
    1462       874031 :   ccvt = ix86_get_callcvt (funtype);
    1463              : 
    1464       874031 :   if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
    1465              :                | IX86_CALLCVT_THISCALL)) != 0
    1466       874031 :       && ! stdarg_p (funtype))
    1467            3 :     return size;
    1468              : 
    1469              :   /* Lose any fake structure return argument if it is passed on the stack.  */
    1470       874028 :   if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
    1471       874028 :       && !ix86_keep_aggregate_return_pointer (funtype))
    1472              :     {
    1473       159993 :       int nregs = ix86_function_regparm (funtype, fundecl);
    1474       159993 :       if (nregs == 0)
    1475       459120 :         return GET_MODE_SIZE (Pmode);
    1476              :     }
    1477              : 
    1478       720988 :   return 0;
    1479              : }
    1480              : 
    1481              : /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook.  */
    1482              : 
    1483              : static bool
    1484     10138686 : ix86_legitimate_combined_insn (rtx_insn *insn)
    1485              : {
    1486     10138686 :   int i;
    1487              : 
    1488              :   /* Check operand constraints in case hard registers were propagated
    1489              :      into insn pattern.  This check prevents combine pass from
    1490              :      generating insn patterns with invalid hard register operands.
    1491              :      These invalid insns can eventually confuse reload to error out
    1492              :      with a spill failure.  See also PRs 46829 and 46843.  */
    1493              : 
    1494     10138686 :   gcc_assert (INSN_CODE (insn) >= 0);
    1495              : 
    1496     10138686 :   extract_insn (insn);
    1497     10138686 :   preprocess_constraints (insn);
    1498              : 
    1499     10138686 :   int n_operands = recog_data.n_operands;
    1500     10138686 :   int n_alternatives = recog_data.n_alternatives;
    1501     34607854 :   for (i = 0; i < n_operands; i++)
    1502              :     {
    1503     24472810 :       rtx op = recog_data.operand[i];
    1504     24472810 :       machine_mode mode = GET_MODE (op);
    1505     24472810 :       const operand_alternative *op_alt;
    1506     24472810 :       int offset = 0;
    1507     24472810 :       bool win;
    1508     24472810 :       int j;
    1509              : 
    1510              :       /* A unary operator may be accepted by the predicate, but it
    1511              :          is irrelevant for matching constraints.  */
    1512     24472810 :       if (UNARY_P (op))
    1513        47595 :         op = XEXP (op, 0);
    1514              : 
    1515     24472810 :       if (SUBREG_P (op))
    1516              :         {
    1517       867134 :           if (REG_P (SUBREG_REG (op))
    1518       867134 :               && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    1519           54 :             offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    1520           54 :                                           GET_MODE (SUBREG_REG (op)),
    1521           54 :                                           SUBREG_BYTE (op),
    1522           54 :                                           GET_MODE (op));
    1523       867134 :           op = SUBREG_REG (op);
    1524              :         }
    1525              : 
    1526     24472810 :       if (!(REG_P (op) && HARD_REGISTER_P (op)))
    1527     24214254 :         continue;
    1528              : 
    1529       258556 :       op_alt = recog_op_alt;
    1530              : 
    1531              :       /* Operand has no constraints, anything is OK.  */
    1532       258556 :       win = !n_alternatives;
    1533              : 
    1534       258556 :       alternative_mask preferred = get_preferred_alternatives (insn);
    1535       745229 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    1536              :         {
    1537       482954 :           if (!TEST_BIT (preferred, j))
    1538       140945 :             continue;
    1539       342009 :           if (op_alt[i].anything_ok
    1540       203783 :               || (op_alt[i].matches != -1
    1541        33953 :                   && operands_match_p
    1542        33953 :                   (recog_data.operand[i],
    1543        33953 :                    recog_data.operand[op_alt[i].matches]))
    1544       541661 :               || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
    1545              :             {
    1546              :               win = true;
    1547              :               break;
    1548              :             }
    1549              :         }
    1550              : 
    1551       258556 :       if (!win)
    1552              :         return false;
    1553              :     }
    1554              : 
    1555              :   return true;
    1556              : }
    1557              : 
    1558              : /* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
    1559              : 
    1560              : static unsigned HOST_WIDE_INT
    1561         4832 : ix86_asan_shadow_offset (void)
    1562              : {
    1563         4832 :   return SUBTARGET_SHADOW_OFFSET;
    1564              : }
    1565              : 
    1566              : /* Argument support functions.  */
    1567              : 
    1568              : /* Return true when register may be used to pass function parameters.  */
    1569              : bool
    1570   1492775274 : ix86_function_arg_regno_p (int regno)
    1571              : {
    1572   1492775274 :   int i;
    1573   1492775274 :   enum calling_abi call_abi;
    1574   1492775274 :   const int *parm_regs;
    1575              : 
    1576   1489296383 :   if (TARGET_SSE && SSE_REGNO_P (regno)
    1577   2468560568 :       && regno < FIRST_SSE_REG + SSE_REGPARM_MAX)
    1578              :     return true;
    1579              : 
    1580   1372254155 :    if (!TARGET_64BIT)
    1581    129260957 :      return (regno < REGPARM_MAX
    1582    129260957 :              || (TARGET_MMX && MMX_REGNO_P (regno)
    1583     11617592 :                  && regno < FIRST_MMX_REG + MMX_REGPARM_MAX));
    1584              : 
    1585              :   /* TODO: The function should depend on current function ABI but
    1586              :      builtins.cc would need updating then. Therefore we use the
    1587              :      default ABI.  */
    1588   1242993198 :   call_abi = ix86_cfun_abi ();
    1589              : 
    1590              :   /* RAX is used as hidden argument to va_arg functions.  */
    1591   1242993198 :   if (call_abi == SYSV_ABI && regno == AX_REG)
    1592              :     return true;
    1593              : 
    1594   1228647067 :   if (cfun
    1595   1228646735 :       && cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE)
    1596              :     parm_regs = x86_64_preserve_none_int_parameter_registers;
    1597   1228607109 :   else if (call_abi == MS_ABI)
    1598              :     parm_regs = x86_64_ms_abi_int_parameter_registers;
    1599              :   else
    1600   1190849077 :     parm_regs = x86_64_int_parameter_registers;
    1601              : 
    1602  16438379266 :   for (i = 0; i < (call_abi == MS_ABI
    1603   8219189633 :                    ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
    1604   7078384004 :     if (regno == parm_regs[i])
    1605              :       return true;
    1606              :   return false;
    1607              : }
    1608              : 
    1609              : /* Return if we do not know how to pass ARG solely in registers.  */
    1610              : 
    1611              : static bool
    1612    416105609 : ix86_must_pass_in_stack (const function_arg_info &arg)
    1613              : {
    1614    416105609 :   if (must_pass_in_stack_var_size_or_pad (arg))
    1615              :     return true;
    1616              : 
    1617              :   /* For 32-bit, we want TImode aggregates to go on the stack.  But watch out!
    1618              :      The layout_type routine is crafty and tries to trick us into passing
    1619              :      currently unsupported vector types on the stack by using TImode.  */
    1620      1773458 :   return (!TARGET_64BIT && arg.mode == TImode
    1621    416105572 :           && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
    1622              : }
    1623              : 
    1624              : /* It returns the size, in bytes, of the area reserved for arguments passed
    1625              :    in registers for the function represented by fndecl dependent to the used
    1626              :    abi format.  */
    1627              : int
    1628     10846768 : ix86_reg_parm_stack_space (const_tree fndecl)
    1629              : {
    1630     10846768 :   enum calling_abi call_abi = SYSV_ABI;
    1631     10846768 :   if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
    1632     10530685 :     call_abi = ix86_function_abi (fndecl);
    1633              :   else
    1634       316083 :     call_abi = ix86_function_type_abi (fndecl);
    1635     10846768 :   if (TARGET_64BIT && call_abi == MS_ABI)
    1636       119430 :     return 32;
    1637              :   return 0;
    1638              : }
    1639              : 
    1640              : /* We add this as a workaround in order to use libc_has_function
    1641              :    hook in i386.md.  */
    1642              : bool
    1643            0 : ix86_libc_has_function (enum function_class fn_class)
    1644              : {
    1645            0 :   return targetm.libc_has_function (fn_class, NULL_TREE);
    1646              : }
    1647              : 
    1648              : /* Returns value SYSV_ABI, MS_ABI dependent on fntype,
    1649              :    specifying the call abi used.  */
    1650              : enum calling_abi
    1651    862609192 : ix86_function_type_abi (const_tree fntype)
    1652              : {
    1653    862609192 :   enum calling_abi abi = ix86_abi;
    1654              : 
    1655    862609192 :   if (fntype == NULL_TREE || TYPE_ATTRIBUTES (fntype) == NULL_TREE)
    1656              :     return abi;
    1657              : 
    1658     87604139 :   if (abi == SYSV_ABI
    1659     87604139 :       && lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
    1660              :     {
    1661      4251136 :       static int warned;
    1662      4251136 :       if (TARGET_X32 && !warned)
    1663              :         {
    1664            1 :           error ("X32 does not support %<ms_abi%> attribute");
    1665            1 :           warned = 1;
    1666              :         }
    1667              : 
    1668              :       abi = MS_ABI;
    1669              :     }
    1670     83353003 :   else if (abi == MS_ABI
    1671     83353003 :            && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
    1672              :     abi = SYSV_ABI;
    1673              : 
    1674              :   return abi;
    1675              : }
    1676              : 
    1677              : enum calling_abi
    1678    224461278 : ix86_function_abi (const_tree fndecl)
    1679              : {
    1680    224461278 :   return fndecl ? ix86_function_type_abi (TREE_TYPE (fndecl)) : ix86_abi;
    1681              : }
    1682              : 
    1683              : /* Returns value SYSV_ABI, MS_ABI dependent on cfun,
    1684              :    specifying the call abi used.  */
    1685              : enum calling_abi
    1686   2100265060 : ix86_cfun_abi (void)
    1687              : {
    1688   2100265060 :   return cfun ? cfun->machine->call_abi : ix86_abi;
    1689              : }
    1690              : 
    1691              : bool
    1692      5052663 : ix86_function_ms_hook_prologue (const_tree fn)
    1693              : {
    1694      5052663 :   if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
    1695              :     {
    1696            8 :       if (decl_function_context (fn) != NULL_TREE)
    1697            0 :         error_at (DECL_SOURCE_LOCATION (fn),
    1698              :                   "%<ms_hook_prologue%> attribute is not compatible "
    1699              :                   "with nested function");
    1700              :       else
    1701              :         return true;
    1702              :     }
    1703              :   return false;
    1704              : }
    1705              : 
    1706              : bool
    1707    124709405 : ix86_function_naked (const_tree fn)
    1708              : {
    1709    124709405 :   if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
    1710              :     return true;
    1711              : 
    1712              :   return false;
    1713              : }
    1714              : 
    1715              : /* Write the extra assembler code needed to declare a function properly.  */
    1716              : 
    1717              : void
    1718      1563758 : ix86_asm_output_function_label (FILE *out_file, const char *fname,
    1719              :                                 tree decl)
    1720              : {
    1721      1563758 :   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
    1722              : 
    1723      1563758 :   if (cfun)
    1724      1560150 :     cfun->machine->function_label_emitted = true;
    1725              : 
    1726      1563758 :   if (is_ms_hook)
    1727              :     {
    1728            2 :       int i, filler_count = (TARGET_64BIT ? 32 : 16);
    1729            2 :       unsigned int filler_cc = 0xcccccccc;
    1730              : 
    1731           18 :       for (i = 0; i < filler_count; i += 4)
    1732           16 :         fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
    1733              :     }
    1734              : 
    1735              : #ifdef SUBTARGET_ASM_UNWIND_INIT
    1736              :   SUBTARGET_ASM_UNWIND_INIT (out_file);
    1737              : #endif
    1738              : 
    1739      1563758 :   assemble_function_label_raw (out_file, fname);
    1740              : 
    1741              :   /* Output magic byte marker, if hot-patch attribute is set.  */
    1742      1563758 :   if (is_ms_hook)
    1743              :     {
    1744            2 :       if (TARGET_64BIT)
    1745              :         {
    1746              :           /* leaq [%rsp + 0], %rsp  */
    1747            2 :           fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
    1748              :                  out_file);
    1749              :         }
    1750              :       else
    1751              :         {
    1752              :           /* movl.s %edi, %edi
    1753              :              push   %ebp
    1754              :              movl.s %esp, %ebp */
    1755            0 :           fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
    1756              :         }
    1757              :     }
    1758      1563758 : }
    1759              : 
    1760              : /* Output a user-defined label.  In AT&T syntax, registers are prefixed
    1761              :    with %, so labels require no punctuation.  In Intel syntax, registers
    1762              :    are unprefixed, so labels may clash with registers or other operators,
    1763              :    and require quoting.  */
    1764              : void
    1765     35231480 : ix86_asm_output_labelref (FILE *file, const char *prefix, const char *label)
    1766              : {
    1767     35231480 :   if (ASSEMBLER_DIALECT == ASM_ATT)
    1768     35230392 :     fprintf (file, "%s%s", prefix, label);
    1769              :   else
    1770         1088 :     fprintf (file, "\"%s%s\"", prefix, label);
    1771     35231480 : }
    1772              : 
    1773              : /* Implementation of call abi switching target hook. Specific to FNDECL
    1774              :    the specific call register sets are set.  See also
    1775              :    ix86_conditional_register_usage for more details.  */
    1776              : void
    1777    203660771 : ix86_call_abi_override (const_tree fndecl)
    1778              : {
    1779    203660771 :   cfun->machine->call_abi = ix86_function_abi (fndecl);
    1780    203660771 : }
    1781              : 
    1782              : /* Return 1 if pseudo register should be created and used to hold
    1783              :    GOT address for PIC code.  */
    1784              : bool
    1785    166702577 : ix86_use_pseudo_pic_reg (void)
    1786              : {
    1787    166702577 :   if ((TARGET_64BIT
    1788    155644785 :        && (ix86_cmodel == CM_SMALL_PIC
    1789              :            || TARGET_PECOFF))
    1790    160996279 :       || !flag_pic)
    1791    161899083 :     return false;
    1792              :   return true;
    1793              : }
    1794              : 
    1795              : /* Initialize large model PIC register.  */
    1796              : 
    1797              : static void
    1798           56 : ix86_init_large_pic_reg (unsigned int tmp_regno)
    1799              : {
    1800           56 :   rtx_code_label *label;
    1801           56 :   rtx tmp_reg;
    1802              : 
    1803           56 :   gcc_assert (Pmode == DImode);
    1804           56 :   label = gen_label_rtx ();
    1805           56 :   emit_label (label);
    1806           56 :   LABEL_PRESERVE_P (label) = 1;
    1807           56 :   tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
    1808           56 :   gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
    1809           56 :   emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
    1810              :                                 label));
    1811           56 :   emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
    1812           56 :   emit_insn (gen_add2_insn (pic_offset_table_rtx, tmp_reg));
    1813           56 :   const char *name = LABEL_NAME (label);
    1814           56 :   PUT_CODE (label, NOTE);
    1815           56 :   NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
    1816           56 :   NOTE_DELETED_LABEL_NAME (label) = name;
    1817           56 : }
    1818              : 
    1819              : /* Create and initialize PIC register if required.  */
    1820              : static void
    1821      1493940 : ix86_init_pic_reg (void)
    1822              : {
    1823      1493940 :   edge entry_edge;
    1824      1493940 :   rtx_insn *seq;
    1825              : 
    1826      1493940 :   if (!ix86_use_pseudo_pic_reg ())
    1827              :     return;
    1828              : 
    1829        40530 :   start_sequence ();
    1830              : 
    1831        40530 :   if (TARGET_64BIT)
    1832              :     {
    1833           69 :       if (ix86_cmodel == CM_LARGE_PIC)
    1834           53 :         ix86_init_large_pic_reg (R11_REG);
    1835              :       else
    1836           16 :         emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
    1837              :     }
    1838              :   else
    1839              :     {
    1840              :       /*  If there is future mcount call in the function it is more profitable
    1841              :           to emit SET_GOT into ABI defined REAL_PIC_OFFSET_TABLE_REGNUM.  */
    1842        40461 :       rtx reg = crtl->profile
    1843        40461 :                 ? gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM)
    1844        40461 :                 : pic_offset_table_rtx;
    1845        40461 :       rtx_insn *insn = emit_insn (gen_set_got (reg));
    1846        40461 :       RTX_FRAME_RELATED_P (insn) = 1;
    1847        40461 :       if (crtl->profile)
    1848            0 :         emit_move_insn (pic_offset_table_rtx, reg);
    1849        40461 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    1850              :     }
    1851              : 
    1852        40530 :   seq = end_sequence ();
    1853              : 
    1854        40530 :   entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1855        40530 :   insert_insn_on_edge (seq, entry_edge);
    1856        40530 :   commit_one_edge_insertion (entry_edge);
    1857              : }
    1858              : 
    1859              : /* Initialize a variable CUM of type CUMULATIVE_ARGS
    1860              :    for a call to a function whose data type is FNTYPE.
    1861              :    For a library call, FNTYPE is 0.  */
    1862              : 
    1863              : void
    1864     10568346 : init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
    1865              :                       tree fntype,      /* tree ptr for function decl */
    1866              :                       rtx libname,      /* SYMBOL_REF of library name or 0 */
    1867              :                       tree fndecl,
    1868              :                       int caller)
    1869              : {
    1870     10568346 :   struct cgraph_node *local_info_node = NULL;
    1871     10568346 :   struct cgraph_node *target = NULL;
    1872              : 
    1873              :   /* Set silent_p to false to raise an error for invalid calls when
    1874              :      expanding function body.  */
    1875     10568346 :   cfun->machine->silent_p = false;
    1876              : 
    1877     10568346 :   memset (cum, 0, sizeof (*cum));
    1878              : 
    1879     10568346 :   tree preserve_none_type;
    1880     10568346 :   if (fndecl)
    1881              :     {
    1882     10222819 :       target = cgraph_node::get (fndecl);
    1883     10222819 :       if (target)
    1884              :         {
    1885     10071270 :           target = target->function_symbol ();
    1886     10071270 :           local_info_node = cgraph_node::local_info_node (target->decl);
    1887     10071270 :           cum->call_abi = ix86_function_abi (target->decl);
    1888     10071270 :           preserve_none_type = TREE_TYPE (target->decl);
    1889              :         }
    1890              :       else
    1891              :         {
    1892       151549 :           cum->call_abi = ix86_function_abi (fndecl);
    1893       151549 :           preserve_none_type = TREE_TYPE (fndecl);
    1894              :         }
    1895              :     }
    1896              :   else
    1897              :     {
    1898       345527 :       cum->call_abi = ix86_function_type_abi (fntype);
    1899       345527 :       preserve_none_type = fntype;
    1900              :     }
    1901              : 
    1902              :   /* For MS ABI functions, parameter passing scheme is unchanged.  */
    1903     10568346 :   cum->preserve_none_abi
    1904     10568346 :     = (preserve_none_type
    1905     10446872 :        && cum->call_abi != MS_ABI
    1906     20898108 :        && (lookup_attribute ("preserve_none",
    1907     10329762 :                              TYPE_ATTRIBUTES (preserve_none_type))
    1908              :            != nullptr));
    1909              : 
    1910     10568346 :   cum->caller = caller;
    1911              : 
    1912              :   /* Set up the number of registers to use for passing arguments.  */
    1913     10568346 :   cum->nregs = ix86_regparm;
    1914     10568346 :   if (TARGET_64BIT)
    1915              :     {
    1916      9531322 :       cum->nregs = (cum->call_abi == SYSV_ABI
    1917      9531322 :                    ? X86_64_REGPARM_MAX
    1918              :                    : X86_64_MS_REGPARM_MAX);
    1919              :     }
    1920     10568346 :   if (TARGET_SSE)
    1921              :     {
    1922     10559175 :       cum->sse_nregs = SSE_REGPARM_MAX;
    1923     10559175 :       if (TARGET_64BIT)
    1924              :         {
    1925      9522271 :           cum->sse_nregs = (cum->call_abi == SYSV_ABI
    1926      9522271 :                            ? X86_64_SSE_REGPARM_MAX
    1927              :                            : X86_64_MS_SSE_REGPARM_MAX);
    1928              :         }
    1929              :     }
    1930     10568346 :   if (TARGET_MMX)
    1931     11392490 :     cum->mmx_nregs = MMX_REGPARM_MAX;
    1932     10568346 :   cum->warn_avx512f = true;
    1933     10568346 :   cum->warn_avx = true;
    1934     10568346 :   cum->warn_sse = true;
    1935     10568346 :   cum->warn_mmx = true;
    1936              : 
    1937              :   /* Because type might mismatch in between caller and callee, we need to
    1938              :      use actual type of function for local calls.
    1939              :      FIXME: cgraph_analyze can be told to actually record if function uses
    1940              :      va_start so for local functions maybe_vaarg can be made aggressive
    1941              :      helping K&R code.
    1942              :      FIXME: once typesytem is fixed, we won't need this code anymore.  */
    1943     10568346 :   if (local_info_node && local_info_node->local
    1944       422329 :       && local_info_node->can_change_signature)
    1945       399101 :     fntype = TREE_TYPE (target->decl);
    1946     10568346 :   cum->stdarg = stdarg_p (fntype);
    1947     21136692 :   cum->maybe_vaarg = (fntype
    1948     11044781 :                       ? (!prototype_p (fntype) || stdarg_p (fntype))
    1949       121474 :                       : !libname);
    1950              : 
    1951     10568346 :   cum->decl = fndecl;
    1952              : 
    1953     10568346 :   cum->warn_empty = !warn_abi || cum->stdarg;
    1954     10568346 :   if (!cum->warn_empty && fntype)
    1955              :     {
    1956      2786204 :       function_args_iterator iter;
    1957      2786204 :       tree argtype;
    1958      2786204 :       bool seen_empty_type = false;
    1959      7763331 :       FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
    1960              :         {
    1961      7763268 :           if (argtype == error_mark_node || VOID_TYPE_P (argtype))
    1962              :             break;
    1963      5000989 :           if (TYPE_EMPTY_P (argtype))
    1964              :             seen_empty_type = true;
    1965      4917878 :           else if (seen_empty_type)
    1966              :             {
    1967        23862 :               cum->warn_empty = true;
    1968        23862 :               break;
    1969              :             }
    1970              :         }
    1971              :     }
    1972              : 
    1973     10568346 :   if (!TARGET_64BIT)
    1974              :     {
    1975              :       /* If there are variable arguments, then we won't pass anything
    1976              :          in registers in 32-bit mode. */
    1977      1037024 :       if (stdarg_p (fntype))
    1978              :         {
    1979         9100 :           cum->nregs = 0;
    1980              :           /* Since in 32-bit, variable arguments are always passed on
    1981              :              stack, there is scratch register available for indirect
    1982              :              sibcall.  */
    1983         9100 :           cfun->machine->arg_reg_available = true;
    1984         9100 :           cum->sse_nregs = 0;
    1985         9100 :           cum->mmx_nregs = 0;
    1986         9100 :           cum->warn_avx512f = false;
    1987         9100 :           cum->warn_avx = false;
    1988         9100 :           cum->warn_sse = false;
    1989         9100 :           cum->warn_mmx = false;
    1990         9100 :           return;
    1991              :         }
    1992              : 
    1993              :       /* Use ecx and edx registers if function has fastcall attribute,
    1994              :          else look for regparm information.  */
    1995      1027924 :       if (fntype)
    1996              :         {
    1997      1014714 :           unsigned int ccvt = ix86_get_callcvt (fntype);
    1998      1014714 :           if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1999              :             {
    2000            0 :               cum->nregs = 1;
    2001            0 :               cum->fastcall = 1; /* Same first register as in fastcall.  */
    2002              :             }
    2003      1014714 :           else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    2004              :             {
    2005            4 :               cum->nregs = 2;
    2006            4 :               cum->fastcall = 1;
    2007              :             }
    2008              :           else
    2009      1014710 :             cum->nregs = ix86_function_regparm (fntype, fndecl);
    2010              :         }
    2011              : 
    2012              :       /* Set up the number of SSE registers used for passing SFmode
    2013              :          and DFmode arguments.  Warn for mismatching ABI.  */
    2014      1027924 :       cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
    2015              :     }
    2016              : 
    2017     10559246 :   cfun->machine->arg_reg_available = (cum->nregs > 0);
    2018              : }
    2019              : 
    2020              : /* Return the "natural" mode for TYPE.  In most cases, this is just TYPE_MODE.
    2021              :    But in the case of vector types, it is some vector mode.
    2022              : 
    2023              :    When we have only some of our vector isa extensions enabled, then there
    2024              :    are some modes for which vector_mode_supported_p is false.  For these
    2025              :    modes, the generic vector support in gcc will choose some non-vector mode
    2026              :    in order to implement the type.  By computing the natural mode, we'll
    2027              :    select the proper ABI location for the operand and not depend on whatever
    2028              :    the middle-end decides to do with these vector types.
    2029              : 
    2030              :    The midde-end can't deal with the vector types > 16 bytes.  In this
    2031              :    case, we return the original mode and warn ABI change if CUM isn't
    2032              :    NULL.
    2033              : 
    2034              :    If INT_RETURN is true, warn ABI change if the vector mode isn't
    2035              :    available for function return value.  */
    2036              : 
    2037              : static machine_mode
    2038    234362049 : type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
    2039              :                    bool in_return)
    2040              : {
    2041    234362049 :   machine_mode mode = TYPE_MODE (type);
    2042              : 
    2043    234362049 :   if (VECTOR_TYPE_P (type) && !VECTOR_MODE_P (mode))
    2044              :     {
    2045       498314 :       HOST_WIDE_INT size = int_size_in_bytes (type);
    2046       498314 :       if ((size == 8 || size == 16 || size == 32 || size == 64)
    2047              :           /* ??? Generic code allows us to create width 1 vectors.  Ignore.  */
    2048       498314 :           && TYPE_VECTOR_SUBPARTS (type) > 1)
    2049              :         {
    2050       452264 :           machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
    2051              : 
    2052              :           /* There are no XFmode vector modes ...  */
    2053       452264 :           if (innermode == XFmode)
    2054              :             return mode;
    2055              : 
    2056              :           /* ... and no decimal float vector modes.  */
    2057       451711 :           if (DECIMAL_FLOAT_MODE_P (innermode))
    2058              :             return mode;
    2059              : 
    2060       451418 :           if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (type)))
    2061              :             mode = MIN_MODE_VECTOR_FLOAT;
    2062              :           else
    2063       373071 :             mode = MIN_MODE_VECTOR_INT;
    2064              : 
    2065              :           /* Get the mode which has this inner mode and number of units.  */
    2066      9478895 :           FOR_EACH_MODE_FROM (mode, mode)
    2067     19733596 :             if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
    2068     10706119 :                 && GET_MODE_INNER (mode) == innermode)
    2069              :               {
    2070       451418 :                 if (size == 64 && !TARGET_AVX512F && !TARGET_IAMCU)
    2071              :                   {
    2072       300665 :                     static bool warnedavx512f;
    2073       300665 :                     static bool warnedavx512f_ret;
    2074              : 
    2075       300665 :                     if (cum && cum->warn_avx512f && !warnedavx512f)
    2076              :                       {
    2077         1361 :                         if (warning (OPT_Wpsabi, "AVX512F vector argument "
    2078              :                                      "without AVX512F enabled changes the ABI"))
    2079            2 :                           warnedavx512f = true;
    2080              :                       }
    2081       299304 :                     else if (in_return && !warnedavx512f_ret)
    2082              :                       {
    2083       283951 :                         if (warning (OPT_Wpsabi, "AVX512F vector return "
    2084              :                                      "without AVX512F enabled changes the ABI"))
    2085            8 :                           warnedavx512f_ret = true;
    2086              :                       }
    2087              : 
    2088       300665 :                     return TYPE_MODE (type);
    2089              :                   }
    2090       150753 :                 else if (size == 32 && !TARGET_AVX && !TARGET_IAMCU)
    2091              :                   {
    2092       150198 :                     static bool warnedavx;
    2093       150198 :                     static bool warnedavx_ret;
    2094              : 
    2095       150198 :                     if (cum && cum->warn_avx && !warnedavx)
    2096              :                       {
    2097          770 :                         if (warning (OPT_Wpsabi, "AVX vector argument "
    2098              :                                      "without AVX enabled changes the ABI"))
    2099            5 :                           warnedavx = true;
    2100              :                       }
    2101       149428 :                     else if (in_return && !warnedavx_ret)
    2102              :                       {
    2103       121906 :                         if (warning (OPT_Wpsabi, "AVX vector return "
    2104              :                                      "without AVX enabled changes the ABI"))
    2105           13 :                           warnedavx_ret = true;
    2106              :                       }
    2107              : 
    2108       150198 :                     return TYPE_MODE (type);
    2109              :                   }
    2110          555 :                 else if (((size == 8 && TARGET_64BIT) || size == 16)
    2111          552 :                          && !TARGET_SSE
    2112          140 :                          && !TARGET_IAMCU)
    2113              :                   {
    2114          140 :                     static bool warnedsse;
    2115          140 :                     static bool warnedsse_ret;
    2116              : 
    2117          140 :                     if (cum && cum->warn_sse && !warnedsse)
    2118              :                       {
    2119           19 :                         if (warning (OPT_Wpsabi, "SSE vector argument "
    2120              :                                      "without SSE enabled changes the ABI"))
    2121            6 :                           warnedsse = true;
    2122              :                       }
    2123          121 :                     else if (!TARGET_64BIT && in_return && !warnedsse_ret)
    2124              :                       {
    2125            0 :                         if (warning (OPT_Wpsabi, "SSE vector return "
    2126              :                                      "without SSE enabled changes the ABI"))
    2127            0 :                           warnedsse_ret = true;
    2128              :                       }
    2129              :                   }
    2130          415 :                 else if ((size == 8 && !TARGET_64BIT)
    2131            0 :                          && (!cfun
    2132            0 :                              || cfun->machine->func_type == TYPE_NORMAL)
    2133            0 :                          && !TARGET_MMX
    2134            0 :                          && !TARGET_IAMCU)
    2135              :                   {
    2136            0 :                     static bool warnedmmx;
    2137            0 :                     static bool warnedmmx_ret;
    2138              : 
    2139            0 :                     if (cum && cum->warn_mmx && !warnedmmx)
    2140              :                       {
    2141            0 :                         if (warning (OPT_Wpsabi, "MMX vector argument "
    2142              :                                      "without MMX enabled changes the ABI"))
    2143            0 :                           warnedmmx = true;
    2144              :                       }
    2145            0 :                     else if (in_return && !warnedmmx_ret)
    2146              :                       {
    2147            0 :                         if (warning (OPT_Wpsabi, "MMX vector return "
    2148              :                                      "without MMX enabled changes the ABI"))
    2149            0 :                           warnedmmx_ret = true;
    2150              :                       }
    2151              :                   }
    2152          555 :                 return mode;
    2153              :               }
    2154              : 
    2155            0 :           gcc_unreachable ();
    2156              :         }
    2157              :     }
    2158              : 
    2159              :   return mode;
    2160              : }
    2161              : 
    2162              : /* We want to pass a value in REGNO whose "natural" mode is MODE.  However,
    2163              :    this may not agree with the mode that the type system has chosen for the
    2164              :    register, which is ORIG_MODE.  If ORIG_MODE is not BLKmode, then we can
    2165              :    go ahead and use it.  Otherwise we have to build a PARALLEL instead.  */
    2166              : 
    2167              : static rtx
    2168     36779041 : gen_reg_or_parallel (machine_mode mode, machine_mode orig_mode,
    2169              :                      unsigned int regno)
    2170              : {
    2171     36779041 :   rtx tmp;
    2172              : 
    2173     36779041 :   if (orig_mode != BLKmode)
    2174     36779012 :     tmp = gen_rtx_REG (orig_mode, regno);
    2175              :   else
    2176              :     {
    2177           29 :       tmp = gen_rtx_REG (mode, regno);
    2178           29 :       tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
    2179           29 :       tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
    2180              :     }
    2181              : 
    2182     36779041 :   return tmp;
    2183              : }
    2184              : 
    2185              : /* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
    2186              :    of this code is to classify each 8bytes of incoming argument by the register
    2187              :    class and assign registers accordingly.  */
    2188              : 
    2189              : /* Return the union class of CLASS1 and CLASS2.
    2190              :    See the x86-64 PS ABI for details.  */
    2191              : 
    2192              : static enum x86_64_reg_class
    2193     58251615 : merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
    2194              : {
    2195              :   /* Rule #1: If both classes are equal, this is the resulting class.  */
    2196     56974124 :   if (class1 == class2)
    2197              :     return class1;
    2198              : 
    2199              :   /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
    2200              :      the other class.  */
    2201     50218597 :   if (class1 == X86_64_NO_CLASS)
    2202              :     return class2;
    2203     51063701 :   if (class2 == X86_64_NO_CLASS)
    2204              :     return class1;
    2205              : 
    2206              :   /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
    2207      1729706 :   if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
    2208              :     return X86_64_MEMORY_CLASS;
    2209              : 
    2210              :   /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
    2211      1573048 :   if ((class1 == X86_64_INTEGERSI_CLASS
    2212       191058 :        && (class2 == X86_64_SSESF_CLASS || class2 == X86_64_SSEHF_CLASS))
    2213      1571842 :       || (class2 == X86_64_INTEGERSI_CLASS
    2214       949976 :           && (class1 == X86_64_SSESF_CLASS || class1 == X86_64_SSEHF_CLASS)))
    2215              :     return X86_64_INTEGERSI_CLASS;
    2216      1567905 :   if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
    2217       412847 :       || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
    2218              :     return X86_64_INTEGER_CLASS;
    2219              : 
    2220              :   /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
    2221              :      MEMORY is used.  */
    2222       100825 :   if (class1 == X86_64_X87_CLASS
    2223              :       || class1 == X86_64_X87UP_CLASS
    2224       100825 :       || class1 == X86_64_COMPLEX_X87_CLASS
    2225              :       || class2 == X86_64_X87_CLASS
    2226        99920 :       || class2 == X86_64_X87UP_CLASS
    2227        66968 :       || class2 == X86_64_COMPLEX_X87_CLASS)
    2228        33857 :     return X86_64_MEMORY_CLASS;
    2229              : 
    2230              :   /* Rule #6: Otherwise class SSE is used.  */
    2231              :   return X86_64_SSE_CLASS;
    2232              : }
    2233              : 
    2234              : /* Classify the argument of type TYPE and mode MODE.
    2235              :    CLASSES will be filled by the register class used to pass each word
    2236              :    of the operand.  The number of words is returned.  In case the parameter
    2237              :    should be passed in memory, 0 is returned. As a special case for zero
    2238              :    sized containers, classes[0] will be NO_CLASS and 1 is returned.
    2239              : 
    2240              :    BIT_OFFSET is used internally for handling records and specifies offset
    2241              :    of the offset in bits modulo 512 to avoid overflow cases.
    2242              : 
    2243              :    See the x86-64 PS ABI for details.
    2244              : */
    2245              : 
    2246              : static int
    2247    401912349 : classify_argument (machine_mode mode, const_tree type,
    2248              :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset,
    2249              :                    int &zero_width_bitfields)
    2250              : {
    2251    401912349 :   HOST_WIDE_INT bytes
    2252    797461571 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2253    401912349 :   int words = CEIL (bytes + (bit_offset % 64) / 8, UNITS_PER_WORD);
    2254              : 
    2255              :   /* Variable sized entities are always passed/returned in memory.  */
    2256    401912349 :   if (bytes < 0)
    2257              :     return 0;
    2258              : 
    2259    401911150 :   if (mode != VOIDmode)
    2260              :     {
    2261              :       /* The value of "named" doesn't matter.  */
    2262    400669711 :       function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
    2263    400669711 :       if (targetm.calls.must_pass_in_stack (arg))
    2264           37 :         return 0;
    2265              :     }
    2266              : 
    2267    401911113 :   if (type && (AGGREGATE_TYPE_P (type)
    2268    363801539 :                || (BITINT_TYPE_P (type) && words > 1)))
    2269              :     {
    2270     39239159 :       int i;
    2271     39239159 :       tree field;
    2272     39239159 :       enum x86_64_reg_class subclasses[MAX_CLASSES];
    2273              : 
    2274              :       /* On x86-64 we pass structures larger than 64 bytes on the stack.  */
    2275     39239159 :       if (bytes > 64)
    2276              :         return 0;
    2277              : 
    2278     98435685 :       for (i = 0; i < words; i++)
    2279     60043511 :         classes[i] = X86_64_NO_CLASS;
    2280              : 
    2281              :       /* Zero sized arrays or structures are NO_CLASS.  We return 0 to
    2282              :          signalize memory class, so handle it as special case.  */
    2283     38392174 :       if (!words)
    2284              :         {
    2285        82983 :           classes[0] = X86_64_NO_CLASS;
    2286        82983 :           return 1;
    2287              :         }
    2288              : 
    2289              :       /* Classify each field of record and merge classes.  */
    2290     38309191 :       switch (TREE_CODE (type))
    2291              :         {
    2292     36198707 :         case RECORD_TYPE:
    2293              :           /* And now merge the fields of structure.  */
    2294   1002171696 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2295              :             {
    2296    966524212 :               if (TREE_CODE (field) == FIELD_DECL)
    2297              :                 {
    2298     53178475 :                   int num;
    2299              : 
    2300     53178475 :                   if (TREE_TYPE (field) == error_mark_node)
    2301            4 :                     continue;
    2302              : 
    2303              :                   /* Bitfields are always classified as integer.  Handle them
    2304              :                      early, since later code would consider them to be
    2305              :                      misaligned integers.  */
    2306     53178471 :                   if (DECL_BIT_FIELD (field))
    2307              :                     {
    2308      1286710 :                       if (integer_zerop (DECL_SIZE (field)))
    2309              :                         {
    2310        12839 :                           if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
    2311         8021 :                             continue;
    2312         4818 :                           if (zero_width_bitfields != 2)
    2313              :                             {
    2314         4284 :                               zero_width_bitfields = 1;
    2315         4284 :                               continue;
    2316              :                             }
    2317              :                         }
    2318      1274405 :                       for (i = (int_bit_position (field)
    2319      1274405 :                                 + (bit_offset % 64)) / 8 / 8;
    2320      2551896 :                            i < ((int_bit_position (field) + (bit_offset % 64))
    2321      2551896 :                                 + tree_to_shwi (DECL_SIZE (field))
    2322      2551896 :                                 + 63) / 8 / 8; i++)
    2323      1277491 :                         classes[i]
    2324      2554982 :                           = merge_classes (X86_64_INTEGER_CLASS, classes[i]);
    2325              :                     }
    2326              :                   else
    2327              :                     {
    2328     51891761 :                       int pos;
    2329              : 
    2330     51891761 :                       type = TREE_TYPE (field);
    2331              : 
    2332              :                       /* Flexible array member is ignored.  */
    2333     51891761 :                       if (TYPE_MODE (type) == BLKmode
    2334       697589 :                           && TREE_CODE (type) == ARRAY_TYPE
    2335       178027 :                           && TYPE_SIZE (type) == NULL_TREE
    2336         2007 :                           && TYPE_DOMAIN (type) != NULL_TREE
    2337     51893003 :                           && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
    2338              :                               == NULL_TREE))
    2339              :                         {
    2340         1242 :                           static bool warned;
    2341              : 
    2342         1242 :                           if (!warned && warn_psabi)
    2343              :                             {
    2344            3 :                               warned = true;
    2345            3 :                               inform (input_location,
    2346              :                                       "the ABI of passing struct with"
    2347              :                                       " a flexible array member has"
    2348              :                                       " changed in GCC 4.4");
    2349              :                             }
    2350         1242 :                           continue;
    2351         1242 :                         }
    2352     51890519 :                       num = classify_argument (TYPE_MODE (type), type,
    2353              :                                                subclasses,
    2354     51890519 :                                                (int_bit_position (field)
    2355     51890519 :                                                 + bit_offset) % 512,
    2356              :                                                zero_width_bitfields);
    2357     51890519 :                       if (!num)
    2358              :                         return 0;
    2359     51339296 :                       pos = (int_bit_position (field)
    2360     51339296 :                              + (bit_offset % 64)) / 8 / 8;
    2361    106272462 :                       for (i = 0; i < num && (i + pos) < words; i++)
    2362     54933166 :                         classes[i + pos]
    2363     54933166 :                           = merge_classes (subclasses[i], classes[i + pos]);
    2364              :                     }
    2365              :                 }
    2366              :             }
    2367              :           break;
    2368              : 
    2369       491211 :         case ARRAY_TYPE:
    2370              :           /* Arrays are handled as small records.  */
    2371       491211 :           {
    2372       491211 :             int num;
    2373       491211 :             num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
    2374       491211 :                                      TREE_TYPE (type), subclasses, bit_offset,
    2375              :                                      zero_width_bitfields);
    2376       491211 :             if (!num)
    2377              :               return 0;
    2378              : 
    2379              :             /* The partial classes are now full classes.  */
    2380       474929 :             if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
    2381        13919 :               subclasses[0] = X86_64_SSE_CLASS;
    2382       474929 :             if (subclasses[0] == X86_64_SSEHF_CLASS && bytes != 2)
    2383         5292 :               subclasses[0] = X86_64_SSE_CLASS;
    2384       474929 :             if (subclasses[0] == X86_64_INTEGERSI_CLASS
    2385       174517 :                 && !((bit_offset % 64) == 0 && bytes == 4))
    2386       137405 :               subclasses[0] = X86_64_INTEGER_CLASS;
    2387              : 
    2388      1439080 :             for (i = 0; i < words; i++)
    2389       964151 :               classes[i] = subclasses[i % num];
    2390              : 
    2391              :             break;
    2392              :           }
    2393       283958 :         case UNION_TYPE:
    2394       283958 :         case QUAL_UNION_TYPE:
    2395              :           /* Unions are similar to RECORD_TYPE but offset is always 0.
    2396              :              */
    2397      3277632 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2398              :             {
    2399      3028980 :               if (TREE_CODE (field) == FIELD_DECL)
    2400              :                 {
    2401      1300153 :                   int num;
    2402              : 
    2403      1300153 :                   if (TREE_TYPE (field) == error_mark_node)
    2404           10 :                     continue;
    2405              : 
    2406      1300143 :                   num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
    2407      1300143 :                                            TREE_TYPE (field), subclasses,
    2408              :                                            bit_offset, zero_width_bitfields);
    2409      1300143 :                   if (!num)
    2410              :                     return 0;
    2411      3305795 :                   for (i = 0; i < num && i < words; i++)
    2412      2040958 :                     classes[i] = merge_classes (subclasses[i], classes[i]);
    2413              :                 }
    2414              :             }
    2415              :           break;
    2416              : 
    2417      1335315 :         case BITINT_TYPE:
    2418      1335315 :         case ENUMERAL_TYPE:
    2419              :           /* _BitInt(N) for N > 64 is passed as structure containing
    2420              :              (N + 63) / 64 64-bit elements.  */
    2421      1335315 :           if (words > 2)
    2422              :             return 0;
    2423        77361 :           classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2424        77361 :           return 2;
    2425              : 
    2426            0 :         default:
    2427            0 :           gcc_unreachable ();
    2428              :         }
    2429              : 
    2430     36371065 :       if (words > 2)
    2431              :         {
    2432              :           /* When size > 16 bytes, if the first one isn't
    2433              :              X86_64_SSE_CLASS or any other ones aren't
    2434              :              X86_64_SSEUP_CLASS, everything should be passed in
    2435              :              memory.  */
    2436      1710068 :           if (classes[0] != X86_64_SSE_CLASS)
    2437              :             return 0;
    2438              : 
    2439       203643 :           for (i = 1; i < words; i++)
    2440       185456 :             if (classes[i] != X86_64_SSEUP_CLASS)
    2441              :               return 0;
    2442              :         }
    2443              : 
    2444              :       /* Final merger cleanup.  */
    2445     81417710 :       for (i = 0; i < words; i++)
    2446              :         {
    2447              :           /* If one class is MEMORY, everything should be passed in
    2448              :              memory.  */
    2449     46774040 :           if (classes[i] == X86_64_MEMORY_CLASS)
    2450              :             return 0;
    2451              : 
    2452              :           /* The X86_64_SSEUP_CLASS should be always preceded by
    2453              :              X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
    2454     46740896 :           if (classes[i] == X86_64_SSEUP_CLASS
    2455       297596 :               && classes[i - 1] != X86_64_SSE_CLASS
    2456        76546 :               && classes[i - 1] != X86_64_SSEUP_CLASS)
    2457              :             {
    2458              :               /* The first one should never be X86_64_SSEUP_CLASS.  */
    2459         1916 :               gcc_assert (i != 0);
    2460         1916 :               classes[i] = X86_64_SSE_CLASS;
    2461              :             }
    2462              : 
    2463              :           /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
    2464              :              everything should be passed in memory.  */
    2465     46740896 :           if (classes[i] == X86_64_X87UP_CLASS
    2466       184113 :               && (classes[i - 1] != X86_64_X87_CLASS))
    2467              :             {
    2468         2370 :               static bool warned;
    2469              : 
    2470              :               /* The first one should never be X86_64_X87UP_CLASS.  */
    2471         2370 :               gcc_assert (i != 0);
    2472         2370 :               if (!warned && warn_psabi)
    2473              :                 {
    2474            1 :                   warned = true;
    2475            1 :                   inform (input_location,
    2476              :                           "the ABI of passing union with %<long double%>"
    2477              :                           " has changed in GCC 4.4");
    2478              :                 }
    2479         2370 :               return 0;
    2480              :             }
    2481              :         }
    2482              :       return words;
    2483              :     }
    2484              : 
    2485              :   /* Compute alignment needed.  We align all types to natural boundaries with
    2486              :      exception of XFmode that is aligned to 64bits.  */
    2487    362671954 :   if (mode != VOIDmode && mode != BLKmode)
    2488              :     {
    2489    360935714 :       int mode_alignment = GET_MODE_BITSIZE (mode);
    2490              : 
    2491    360935714 :       if (mode == XFmode)
    2492              :         mode_alignment = 128;
    2493    353842484 :       else if (mode == XCmode)
    2494       564953 :         mode_alignment = 256;
    2495    360935714 :       if (COMPLEX_MODE_P (mode))
    2496      2714147 :         mode_alignment /= 2;
    2497              :       /* Misaligned fields are always returned in memory.  */
    2498    360935714 :       if (bit_offset % mode_alignment)
    2499              :         return 0;
    2500              :     }
    2501              : 
    2502              :   /* for V1xx modes, just use the base mode */
    2503    362664321 :   if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
    2504    456429581 :       && GET_MODE_UNIT_SIZE (mode) == bytes)
    2505         6651 :     mode = GET_MODE_INNER (mode);
    2506              : 
    2507              :   /* Classification of atomic types.  */
    2508    362664321 :   switch (mode)
    2509              :     {
    2510       207987 :     case E_SDmode:
    2511       207987 :     case E_DDmode:
    2512       207987 :       classes[0] = X86_64_SSE_CLASS;
    2513       207987 :       return 1;
    2514        99137 :     case E_TDmode:
    2515        99137 :       classes[0] = X86_64_SSE_CLASS;
    2516        99137 :       classes[1] = X86_64_SSEUP_CLASS;
    2517        99137 :       return 2;
    2518    238180590 :     case E_DImode:
    2519    238180590 :     case E_SImode:
    2520    238180590 :     case E_HImode:
    2521    238180590 :     case E_QImode:
    2522    238180590 :     case E_CSImode:
    2523    238180590 :     case E_CHImode:
    2524    238180590 :     case E_CQImode:
    2525    238180590 :       {
    2526    238180590 :         int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
    2527              : 
    2528              :         /* Analyze last 128 bits only.  */
    2529    238180590 :         size = (size - 1) & 0x7f;
    2530              : 
    2531    238180590 :         if (size < 32)
    2532              :           {
    2533    105132948 :             classes[0] = X86_64_INTEGERSI_CLASS;
    2534    105132948 :             return 1;
    2535              :           }
    2536    133047642 :         else if (size < 64)
    2537              :           {
    2538    121851611 :             classes[0] = X86_64_INTEGER_CLASS;
    2539    121851611 :             return 1;
    2540              :           }
    2541     11196031 :         else if (size < 64+32)
    2542              :           {
    2543      4160779 :             classes[0] = X86_64_INTEGER_CLASS;
    2544      4160779 :             classes[1] = X86_64_INTEGERSI_CLASS;
    2545      4160779 :             return 2;
    2546              :           }
    2547      7035252 :         else if (size < 64+64)
    2548              :           {
    2549      7035252 :             classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2550      7035252 :             return 2;
    2551              :           }
    2552              :         else
    2553              :           gcc_unreachable ();
    2554              :       }
    2555      2524550 :     case E_CDImode:
    2556      2524550 :     case E_TImode:
    2557      2524550 :       classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2558      2524550 :       return 2;
    2559            0 :     case E_COImode:
    2560            0 :     case E_OImode:
    2561              :       /* OImode shouldn't be used directly.  */
    2562            0 :       gcc_unreachable ();
    2563              :     case E_CTImode:
    2564              :       return 0;
    2565      1013660 :     case E_HFmode:
    2566      1013660 :     case E_BFmode:
    2567      1013660 :       if (!(bit_offset % 64))
    2568      1000446 :         classes[0] = X86_64_SSEHF_CLASS;
    2569              :       else
    2570        13214 :         classes[0] = X86_64_SSE_CLASS;
    2571              :       return 1;
    2572     10022375 :     case E_SFmode:
    2573     10022375 :       if (!(bit_offset % 64))
    2574      9968796 :         classes[0] = X86_64_SSESF_CLASS;
    2575              :       else
    2576        53579 :         classes[0] = X86_64_SSE_CLASS;
    2577              :       return 1;
    2578      4406147 :     case E_DFmode:
    2579      4406147 :       classes[0] = X86_64_SSEDF_CLASS;
    2580      4406147 :       return 1;
    2581      7092514 :     case E_XFmode:
    2582      7092514 :       classes[0] = X86_64_X87_CLASS;
    2583      7092514 :       classes[1] = X86_64_X87UP_CLASS;
    2584      7092514 :       return 2;
    2585      1384226 :     case E_TFmode:
    2586      1384226 :       classes[0] = X86_64_SSE_CLASS;
    2587      1384226 :       classes[1] = X86_64_SSEUP_CLASS;
    2588      1384226 :       return 2;
    2589       104641 :     case E_HCmode:
    2590       104641 :     case E_BCmode:
    2591       104641 :       classes[0] = X86_64_SSE_CLASS;
    2592       104641 :       if (!(bit_offset % 64))
    2593              :         return 1;
    2594              :       else
    2595              :         {
    2596           98 :           classes[1] = X86_64_SSEHF_CLASS;
    2597           98 :           return 2;
    2598              :         }
    2599       724049 :     case E_SCmode:
    2600       724049 :       classes[0] = X86_64_SSE_CLASS;
    2601       724049 :       if (!(bit_offset % 64))
    2602              :         return 1;
    2603              :       else
    2604              :         {
    2605         1119 :           static bool warned;
    2606              : 
    2607         1119 :           if (!warned && warn_psabi)
    2608              :             {
    2609            2 :               warned = true;
    2610            2 :               inform (input_location,
    2611              :                       "the ABI of passing structure with %<complex float%>"
    2612              :                       " member has changed in GCC 4.4");
    2613              :             }
    2614         1119 :           classes[1] = X86_64_SSESF_CLASS;
    2615         1119 :           return 2;
    2616              :         }
    2617       733961 :     case E_DCmode:
    2618       733961 :       classes[0] = X86_64_SSEDF_CLASS;
    2619       733961 :       classes[1] = X86_64_SSEDF_CLASS;
    2620       733961 :       return 2;
    2621       564953 :     case E_XCmode:
    2622       564953 :       classes[0] = X86_64_COMPLEX_X87_CLASS;
    2623       564953 :       return 1;
    2624              :     case E_TCmode:
    2625              :       /* This modes is larger than 16 bytes.  */
    2626              :       return 0;
    2627     25382110 :     case E_V8SFmode:
    2628     25382110 :     case E_V8SImode:
    2629     25382110 :     case E_V32QImode:
    2630     25382110 :     case E_V16HFmode:
    2631     25382110 :     case E_V16BFmode:
    2632     25382110 :     case E_V16HImode:
    2633     25382110 :     case E_V4DFmode:
    2634     25382110 :     case E_V4DImode:
    2635     25382110 :       classes[0] = X86_64_SSE_CLASS;
    2636     25382110 :       classes[1] = X86_64_SSEUP_CLASS;
    2637     25382110 :       classes[2] = X86_64_SSEUP_CLASS;
    2638     25382110 :       classes[3] = X86_64_SSEUP_CLASS;
    2639     25382110 :       return 4;
    2640     27521081 :     case E_V8DFmode:
    2641     27521081 :     case E_V16SFmode:
    2642     27521081 :     case E_V32HFmode:
    2643     27521081 :     case E_V32BFmode:
    2644     27521081 :     case E_V8DImode:
    2645     27521081 :     case E_V16SImode:
    2646     27521081 :     case E_V32HImode:
    2647     27521081 :     case E_V64QImode:
    2648     27521081 :       classes[0] = X86_64_SSE_CLASS;
    2649     27521081 :       classes[1] = X86_64_SSEUP_CLASS;
    2650     27521081 :       classes[2] = X86_64_SSEUP_CLASS;
    2651     27521081 :       classes[3] = X86_64_SSEUP_CLASS;
    2652     27521081 :       classes[4] = X86_64_SSEUP_CLASS;
    2653     27521081 :       classes[5] = X86_64_SSEUP_CLASS;
    2654     27521081 :       classes[6] = X86_64_SSEUP_CLASS;
    2655     27521081 :       classes[7] = X86_64_SSEUP_CLASS;
    2656     27521081 :       return 8;
    2657     37533395 :     case E_V4SFmode:
    2658     37533395 :     case E_V4SImode:
    2659     37533395 :     case E_V16QImode:
    2660     37533395 :     case E_V8HImode:
    2661     37533395 :     case E_V8HFmode:
    2662     37533395 :     case E_V8BFmode:
    2663     37533395 :     case E_V2DFmode:
    2664     37533395 :     case E_V2DImode:
    2665     37533395 :       classes[0] = X86_64_SSE_CLASS;
    2666     37533395 :       classes[1] = X86_64_SSEUP_CLASS;
    2667     37533395 :       return 2;
    2668      3289360 :     case E_V1TImode:
    2669      3289360 :     case E_V1DImode:
    2670      3289360 :     case E_V2SFmode:
    2671      3289360 :     case E_V2SImode:
    2672      3289360 :     case E_V4HImode:
    2673      3289360 :     case E_V4HFmode:
    2674      3289360 :     case E_V4BFmode:
    2675      3289360 :     case E_V2HFmode:
    2676      3289360 :     case E_V2BFmode:
    2677      3289360 :     case E_V8QImode:
    2678      3289360 :       classes[0] = X86_64_SSE_CLASS;
    2679      3289360 :       return 1;
    2680              :     case E_BLKmode:
    2681              :     case E_VOIDmode:
    2682              :       return 0;
    2683        52806 :     default:
    2684        52806 :       gcc_assert (VECTOR_MODE_P (mode));
    2685              : 
    2686        52806 :       if (bytes > 16)
    2687              :         return 0;
    2688              : 
    2689        75884 :       gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
    2690              : 
    2691        75884 :       if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
    2692        37508 :         classes[0] = X86_64_INTEGERSI_CLASS;
    2693              :       else
    2694          434 :         classes[0] = X86_64_INTEGER_CLASS;
    2695        37942 :       classes[1] = X86_64_INTEGER_CLASS;
    2696        37942 :       return 1 + (bytes > 8);
    2697              :     }
    2698              : }
    2699              : 
    2700              : /* Wrapper around classify_argument with the extra zero_width_bitfields
    2701              :    argument, to diagnose GCC 12.1 ABI differences for C.  */
    2702              : 
    2703              : static int
    2704    348229942 : classify_argument (machine_mode mode, const_tree type,
    2705              :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
    2706              : {
    2707    348229942 :   int zero_width_bitfields = 0;
    2708    348229942 :   static bool warned = false;
    2709    348229942 :   int n = classify_argument (mode, type, classes, bit_offset,
    2710              :                              zero_width_bitfields);
    2711    348229942 :   if (!zero_width_bitfields || warned || !warn_psabi)
    2712              :     return n;
    2713          534 :   enum x86_64_reg_class alt_classes[MAX_CLASSES];
    2714          534 :   zero_width_bitfields = 2;
    2715          534 :   if (classify_argument (mode, type, alt_classes, bit_offset,
    2716              :                          zero_width_bitfields) != n)
    2717            0 :     zero_width_bitfields = 3;
    2718              :   else
    2719         1286 :     for (int i = 0; i < n; i++)
    2720          760 :       if (classes[i] != alt_classes[i])
    2721              :         {
    2722            8 :           zero_width_bitfields = 3;
    2723            8 :           break;
    2724              :         }
    2725          534 :   if (zero_width_bitfields == 3)
    2726              :     {
    2727            8 :       warned = true;
    2728            8 :       const char *url
    2729              :         = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields";
    2730              : 
    2731            8 :       inform (input_location,
    2732              :               "the ABI of passing C structures with zero-width bit-fields"
    2733              :               " has changed in GCC %{12.1%}", url);
    2734              :     }
    2735              :   return n;
    2736              : }
    2737              : 
    2738              : /* Examine the argument and return set number of register required in each
    2739              :    class.  Return true iff parameter should be passed in memory.  */
    2740              : 
    2741              : static bool
    2742    235668175 : examine_argument (machine_mode mode, const_tree type, bool in_return,
    2743              :                   int *int_nregs, int *sse_nregs)
    2744              : {
    2745    235668175 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2746    235668175 :   int n = classify_argument (mode, type, regclass, 0);
    2747              : 
    2748    235668175 :   *int_nregs = 0;
    2749    235668175 :   *sse_nregs = 0;
    2750              : 
    2751    235668175 :   if (!n)
    2752              :     return true;
    2753    677621787 :   for (n--; n >= 0; n--)
    2754    447737712 :     switch (regclass[n])
    2755              :       {
    2756    157814586 :       case X86_64_INTEGER_CLASS:
    2757    157814586 :       case X86_64_INTEGERSI_CLASS:
    2758    157814586 :         (*int_nregs)++;
    2759    157814586 :         break;
    2760     75150412 :       case X86_64_SSE_CLASS:
    2761     75150412 :       case X86_64_SSEHF_CLASS:
    2762     75150412 :       case X86_64_SSESF_CLASS:
    2763     75150412 :       case X86_64_SSEDF_CLASS:
    2764     75150412 :         (*sse_nregs)++;
    2765     75150412 :         break;
    2766              :       case X86_64_NO_CLASS:
    2767              :       case X86_64_SSEUP_CLASS:
    2768              :         break;
    2769      9685631 :       case X86_64_X87_CLASS:
    2770      9685631 :       case X86_64_X87UP_CLASS:
    2771      9685631 :       case X86_64_COMPLEX_X87_CLASS:
    2772      9685631 :         if (!in_return)
    2773              :           return true;
    2774              :         break;
    2775            0 :       case X86_64_MEMORY_CLASS:
    2776            0 :         gcc_unreachable ();
    2777              :       }
    2778              : 
    2779              :   return false;
    2780              : }
    2781              : 
    2782              : /* Construct container for the argument used by GCC interface.  See
    2783              :    FUNCTION_ARG for the detailed description.  */
    2784              : 
    2785              : static rtx
    2786    114180410 : construct_container (machine_mode mode, machine_mode orig_mode,
    2787              :                      const_tree type, bool in_return, int nintregs,
    2788              :                      int nsseregs, const int *intreg, int sse_regno)
    2789              : {
    2790              :   /* The following variables hold the static issued_error state.  */
    2791    114180410 :   static bool issued_sse_arg_error;
    2792    114180410 :   static bool issued_sse_ret_error;
    2793    114180410 :   static bool issued_x87_ret_error;
    2794              : 
    2795    114180410 :   machine_mode tmpmode;
    2796    114180410 :   int bytes
    2797    227665661 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2798    114180410 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2799    114180410 :   int n;
    2800    114180410 :   int i;
    2801    114180410 :   int nexps = 0;
    2802    114180410 :   int needed_sseregs, needed_intregs;
    2803    114180410 :   rtx exp[MAX_CLASSES];
    2804    114180410 :   rtx ret;
    2805              : 
    2806    114180410 :   if (examine_argument (mode, type, in_return, &needed_intregs,
    2807              :                         &needed_sseregs))
    2808              :     return NULL;
    2809              : 
    2810    113667993 :   if (needed_intregs > nintregs || needed_sseregs > nsseregs)
    2811              :     return NULL;
    2812              : 
    2813              :   /* We allowed the user to turn off SSE for kernel mode.  Don't crash if
    2814              :      some less clueful developer tries to use floating-point anyway.  */
    2815    112561835 :   if (needed_sseregs
    2816     37127004 :       && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2)))
    2817              :     {
    2818              :       /* Return early if we shouldn't raise an error for invalid
    2819              :          calls.  */
    2820           68 :       if (cfun != NULL && cfun->machine->silent_p)
    2821              :         return NULL;
    2822           36 :       if (in_return)
    2823              :         {
    2824           31 :           if (!issued_sse_ret_error)
    2825              :             {
    2826           13 :               if (VALID_SSE2_TYPE_MODE (mode))
    2827            5 :                 error ("SSE register return with SSE2 disabled");
    2828              :               else
    2829            8 :                 error ("SSE register return with SSE disabled");
    2830           13 :               issued_sse_ret_error = true;
    2831              :             }
    2832              :         }
    2833            5 :       else if (!issued_sse_arg_error)
    2834              :         {
    2835            5 :           if (VALID_SSE2_TYPE_MODE (mode))
    2836            0 :             error ("SSE register argument with SSE2 disabled");
    2837              :           else
    2838            5 :             error ("SSE register argument with SSE disabled");
    2839            5 :           issued_sse_arg_error = true;
    2840              :         }
    2841           36 :       return NULL;
    2842              :     }
    2843              : 
    2844    112561767 :   n = classify_argument (mode, type, regclass, 0);
    2845    112561767 :   gcc_assert (n);
    2846              : 
    2847              :   /* Likewise, error if the ABI requires us to return values in the
    2848              :      x87 registers and the user specified -mno-80387.  */
    2849    112561767 :   if (!TARGET_FLOAT_RETURNS_IN_80387 && in_return)
    2850      1428805 :     for (i = 0; i < n; i++)
    2851       754012 :       if (regclass[i] == X86_64_X87_CLASS
    2852              :           || regclass[i] == X86_64_X87UP_CLASS
    2853       754012 :           || regclass[i] == X86_64_COMPLEX_X87_CLASS)
    2854              :         {
    2855              :           /* Return early if we shouldn't raise an error for invalid
    2856              :              calls.  */
    2857           13 :           if (cfun != NULL && cfun->machine->silent_p)
    2858              :             return NULL;
    2859           10 :           if (!issued_x87_ret_error)
    2860              :             {
    2861            5 :               error ("x87 register return with x87 disabled");
    2862            5 :               issued_x87_ret_error = true;
    2863              :             }
    2864           10 :           return NULL;
    2865              :         }
    2866              : 
    2867              :   /* First construct simple cases.  Avoid SCmode, since we want to use
    2868              :      single register to pass this type.  */
    2869    112561754 :   if (n == 1 && mode != SCmode && mode != HCmode)
    2870     75313228 :     switch (regclass[0])
    2871              :       {
    2872     69057657 :       case X86_64_INTEGER_CLASS:
    2873     69057657 :       case X86_64_INTEGERSI_CLASS:
    2874     69057657 :         return gen_rtx_REG (mode, intreg[0]);
    2875      6050171 :       case X86_64_SSE_CLASS:
    2876      6050171 :       case X86_64_SSEHF_CLASS:
    2877      6050171 :       case X86_64_SSESF_CLASS:
    2878      6050171 :       case X86_64_SSEDF_CLASS:
    2879      6050171 :         if (mode != BLKmode)
    2880     12099482 :           return gen_reg_or_parallel (mode, orig_mode,
    2881     12099482 :                                       GET_SSE_REGNO (sse_regno));
    2882              :         break;
    2883       176074 :       case X86_64_X87_CLASS:
    2884       176074 :       case X86_64_COMPLEX_X87_CLASS:
    2885       176074 :         return gen_rtx_REG (mode, FIRST_STACK_REG);
    2886              :       case X86_64_NO_CLASS:
    2887              :         /* Zero sized array, struct or class.  */
    2888              :         return NULL;
    2889            0 :       default:
    2890            0 :         gcc_unreachable ();
    2891              :       }
    2892     37248956 :   if (n == 2
    2893     19407041 :       && regclass[0] == X86_64_SSE_CLASS
    2894     12973894 :       && regclass[1] == X86_64_SSEUP_CLASS
    2895     12968291 :       && mode != BLKmode)
    2896     25936582 :     return gen_reg_or_parallel (mode, orig_mode,
    2897     25936582 :                                 GET_SSE_REGNO (sse_regno));
    2898     24280665 :   if (n == 4
    2899      8444688 :       && regclass[0] == X86_64_SSE_CLASS
    2900      8444688 :       && regclass[1] == X86_64_SSEUP_CLASS
    2901      8444688 :       && regclass[2] == X86_64_SSEUP_CLASS
    2902      8444688 :       && regclass[3] == X86_64_SSEUP_CLASS
    2903      8444688 :       && mode != BLKmode)
    2904     16885998 :     return gen_reg_or_parallel (mode, orig_mode,
    2905     16885998 :                                 GET_SSE_REGNO (sse_regno));
    2906     15837666 :   if (n == 8
    2907      9143609 :       && regclass[0] == X86_64_SSE_CLASS
    2908      9143609 :       && regclass[1] == X86_64_SSEUP_CLASS
    2909      9143609 :       && regclass[2] == X86_64_SSEUP_CLASS
    2910      9143609 :       && regclass[3] == X86_64_SSEUP_CLASS
    2911      9143609 :       && regclass[4] == X86_64_SSEUP_CLASS
    2912      9143609 :       && regclass[5] == X86_64_SSEUP_CLASS
    2913      9143609 :       && regclass[6] == X86_64_SSEUP_CLASS
    2914      9143609 :       && regclass[7] == X86_64_SSEUP_CLASS
    2915      9143609 :       && mode != BLKmode)
    2916     18282946 :     return gen_reg_or_parallel (mode, orig_mode,
    2917     18282946 :                                 GET_SSE_REGNO (sse_regno));
    2918      6696193 :   if (n == 2
    2919      6438750 :       && regclass[0] == X86_64_X87_CLASS
    2920      2314067 :       && regclass[1] == X86_64_X87UP_CLASS)
    2921      2314067 :     return gen_rtx_REG (XFmode, FIRST_STACK_REG);
    2922              : 
    2923      4382126 :   if (n == 2
    2924      4124683 :       && regclass[0] == X86_64_INTEGER_CLASS
    2925      3683082 :       && regclass[1] == X86_64_INTEGER_CLASS
    2926      3674641 :       && (mode == CDImode || mode == TImode || mode == BLKmode)
    2927      3674641 :       && intreg[0] + 1 == intreg[1])
    2928              :     {
    2929      3354223 :       if (mode == BLKmode)
    2930              :         {
    2931              :           /* Use TImode for BLKmode values in 2 integer registers.  */
    2932       533044 :           exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
    2933       266522 :                                       gen_rtx_REG (TImode, intreg[0]),
    2934              :                                       GEN_INT (0));
    2935       266522 :           ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
    2936       266522 :           XVECEXP (ret, 0, 0) = exp[0];
    2937       266522 :           return ret;
    2938              :         }
    2939              :       else
    2940      3087701 :         return gen_rtx_REG (mode, intreg[0]);
    2941              :     }
    2942              : 
    2943              :   /* Otherwise figure out the entries of the PARALLEL.  */
    2944      2826266 :   for (i = 0; i < n; i++)
    2945              :     {
    2946      1798363 :       int pos;
    2947              : 
    2948      1798363 :       switch (regclass[i])
    2949              :         {
    2950              :           case X86_64_NO_CLASS:
    2951              :             break;
    2952      1010303 :           case X86_64_INTEGER_CLASS:
    2953      1010303 :           case X86_64_INTEGERSI_CLASS:
    2954              :             /* Merge TImodes on aligned occasions here too.  */
    2955      1010303 :             if (i * 8 + 8 > bytes)
    2956              :               {
    2957         3239 :                 unsigned int tmpbits = (bytes - i * 8) * BITS_PER_UNIT;
    2958         3239 :                 if (!int_mode_for_size (tmpbits, 0).exists (&tmpmode))
    2959              :                   /* We've requested 24 bytes we
    2960              :                      don't have mode for.  Use DImode.  */
    2961          357 :                   tmpmode = DImode;
    2962              :               }
    2963      1007064 :             else if (regclass[i] == X86_64_INTEGERSI_CLASS)
    2964              :               tmpmode = SImode;
    2965              :             else
    2966       828153 :               tmpmode = DImode;
    2967      2020606 :             exp [nexps++]
    2968      1010303 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2969      1010303 :                                    gen_rtx_REG (tmpmode, *intreg),
    2970      1010303 :                                    GEN_INT (i*8));
    2971      1010303 :             intreg++;
    2972      1010303 :             break;
    2973          600 :           case X86_64_SSEHF_CLASS:
    2974          600 :             tmpmode = (mode == BFmode ? BFmode : HFmode);
    2975         1200 :             exp [nexps++]
    2976         1200 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2977              :                                    gen_rtx_REG (tmpmode,
    2978          600 :                                                 GET_SSE_REGNO (sse_regno)),
    2979          600 :                                    GEN_INT (i*8));
    2980          600 :             sse_regno++;
    2981          600 :             break;
    2982         3060 :           case X86_64_SSESF_CLASS:
    2983         6120 :             exp [nexps++]
    2984         6120 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2985              :                                    gen_rtx_REG (SFmode,
    2986         3060 :                                                 GET_SSE_REGNO (sse_regno)),
    2987         3060 :                                    GEN_INT (i*8));
    2988         3060 :             sse_regno++;
    2989         3060 :             break;
    2990       507696 :           case X86_64_SSEDF_CLASS:
    2991      1015392 :             exp [nexps++]
    2992      1015392 :               = gen_rtx_EXPR_LIST (VOIDmode,
    2993              :                                    gen_rtx_REG (DFmode,
    2994       507696 :                                                 GET_SSE_REGNO (sse_regno)),
    2995       507696 :                                    GEN_INT (i*8));
    2996       507696 :             sse_regno++;
    2997       507696 :             break;
    2998       268253 :           case X86_64_SSE_CLASS:
    2999       268253 :             pos = i;
    3000       268253 :             switch (n)
    3001              :               {
    3002              :               case 1:
    3003              :                 tmpmode = DImode;
    3004              :                 break;
    3005        11024 :               case 2:
    3006        11024 :                 if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
    3007              :                   {
    3008            0 :                     tmpmode = TImode;
    3009            0 :                     i++;
    3010              :                   }
    3011              :                 else
    3012              :                   tmpmode = DImode;
    3013              :                 break;
    3014         1689 :               case 4:
    3015         1689 :                 gcc_assert (i == 0
    3016              :                             && regclass[1] == X86_64_SSEUP_CLASS
    3017              :                             && regclass[2] == X86_64_SSEUP_CLASS
    3018              :                             && regclass[3] == X86_64_SSEUP_CLASS);
    3019              :                 tmpmode = OImode;
    3020              :                 i += 3;
    3021              :                 break;
    3022         2136 :               case 8:
    3023         2136 :                 gcc_assert (i == 0
    3024              :                             && regclass[1] == X86_64_SSEUP_CLASS
    3025              :                             && regclass[2] == X86_64_SSEUP_CLASS
    3026              :                             && regclass[3] == X86_64_SSEUP_CLASS
    3027              :                             && regclass[4] == X86_64_SSEUP_CLASS
    3028              :                             && regclass[5] == X86_64_SSEUP_CLASS
    3029              :                             && regclass[6] == X86_64_SSEUP_CLASS
    3030              :                             && regclass[7] == X86_64_SSEUP_CLASS);
    3031              :                 tmpmode = XImode;
    3032              :                 i += 7;
    3033              :                 break;
    3034            0 :               default:
    3035            0 :                 gcc_unreachable ();
    3036              :               }
    3037       536506 :             exp [nexps++]
    3038       536506 :               = gen_rtx_EXPR_LIST (VOIDmode,
    3039              :                                    gen_rtx_REG (tmpmode,
    3040       268253 :                                                 GET_SSE_REGNO (sse_regno)),
    3041       268253 :                                    GEN_INT (pos*8));
    3042       268253 :             sse_regno++;
    3043       268253 :             break;
    3044            0 :           default:
    3045            0 :             gcc_unreachable ();
    3046              :         }
    3047              :     }
    3048              : 
    3049              :   /* Empty aligned struct, union or class.  */
    3050      1027903 :   if (nexps == 0)
    3051              :     return NULL;
    3052              : 
    3053      1027648 :   ret =  gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
    3054      2817560 :   for (i = 0; i < nexps; i++)
    3055      1789912 :     XVECEXP (ret, 0, i) = exp [i];
    3056              :   return ret;
    3057              : }
    3058              : 
    3059              : /* Update the data in CUM to advance over an argument of mode MODE
    3060              :    and data type TYPE.  (TYPE is null for libcalls where that information
    3061              :    may not be available.)
    3062              : 
    3063              :    Return a number of integer registers advanced over.  */
    3064              : 
    3065              : static int
    3066      2131696 : function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3067              :                          const_tree type, HOST_WIDE_INT bytes,
    3068              :                          HOST_WIDE_INT words)
    3069              : {
    3070      2131696 :   int res = 0;
    3071      2131696 :   bool error_p = false;
    3072              : 
    3073      2131696 :   if (TARGET_IAMCU)
    3074              :     {
    3075              :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    3076              :          bytes in registers.  */
    3077            0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3078            0 :         goto pass_in_reg;
    3079              :       return res;
    3080              :     }
    3081              : 
    3082      2131696 :   switch (mode)
    3083              :     {
    3084              :     default:
    3085              :       break;
    3086              : 
    3087        93820 :     case E_BLKmode:
    3088        93820 :       if (bytes < 0)
    3089              :         break;
    3090              :       /* FALLTHRU */
    3091              : 
    3092      2094767 :     case E_DImode:
    3093      2094767 :     case E_SImode:
    3094      2094767 :     case E_HImode:
    3095      2094767 :     case E_QImode:
    3096        93820 : pass_in_reg:
    3097      2094767 :       cum->words += words;
    3098      2094767 :       cum->nregs -= words;
    3099      2094767 :       cum->regno += words;
    3100      2094767 :       if (cum->nregs >= 0)
    3101        47322 :         res = words;
    3102      2094767 :       if (cum->nregs <= 0)
    3103              :         {
    3104      2060667 :           cum->nregs = 0;
    3105      2060667 :           cfun->machine->arg_reg_available = false;
    3106      2060667 :           cum->regno = 0;
    3107              :         }
    3108              :       break;
    3109              : 
    3110            0 :     case E_OImode:
    3111              :       /* OImode shouldn't be used directly.  */
    3112            0 :       gcc_unreachable ();
    3113              : 
    3114         4757 :     case E_DFmode:
    3115         4757 :       if (cum->float_in_sse == -1)
    3116            0 :         error_p = true;
    3117         4757 :       if (cum->float_in_sse < 2)
    3118              :         break;
    3119              :       /* FALLTHRU */
    3120         1374 :     case E_SFmode:
    3121         1374 :       if (cum->float_in_sse == -1)
    3122            0 :         error_p = true;
    3123         1374 :       if (cum->float_in_sse < 1)
    3124              :         break;
    3125              :       /* FALLTHRU */
    3126              : 
    3127           52 :     case E_V16HFmode:
    3128           52 :     case E_V16BFmode:
    3129           52 :     case E_V8SFmode:
    3130           52 :     case E_V8SImode:
    3131           52 :     case E_V64QImode:
    3132           52 :     case E_V32HImode:
    3133           52 :     case E_V16SImode:
    3134           52 :     case E_V8DImode:
    3135           52 :     case E_V32HFmode:
    3136           52 :     case E_V32BFmode:
    3137           52 :     case E_V16SFmode:
    3138           52 :     case E_V8DFmode:
    3139           52 :     case E_V32QImode:
    3140           52 :     case E_V16HImode:
    3141           52 :     case E_V4DFmode:
    3142           52 :     case E_V4DImode:
    3143           52 :     case E_TImode:
    3144           52 :     case E_V16QImode:
    3145           52 :     case E_V8HImode:
    3146           52 :     case E_V4SImode:
    3147           52 :     case E_V2DImode:
    3148           52 :     case E_V8HFmode:
    3149           52 :     case E_V8BFmode:
    3150           52 :     case E_V4SFmode:
    3151           52 :     case E_V2DFmode:
    3152           52 :       if (!type || !AGGREGATE_TYPE_P (type))
    3153              :         {
    3154           52 :           cum->sse_words += words;
    3155           52 :           cum->sse_nregs -= 1;
    3156           52 :           cum->sse_regno += 1;
    3157           52 :           if (cum->sse_nregs <= 0)
    3158              :             {
    3159            4 :               cum->sse_nregs = 0;
    3160            4 :               cum->sse_regno = 0;
    3161              :             }
    3162              :         }
    3163              :       break;
    3164              : 
    3165           16 :     case E_V8QImode:
    3166           16 :     case E_V4HImode:
    3167           16 :     case E_V4HFmode:
    3168           16 :     case E_V4BFmode:
    3169           16 :     case E_V2SImode:
    3170           16 :     case E_V2SFmode:
    3171           16 :     case E_V1TImode:
    3172           16 :     case E_V1DImode:
    3173           16 :       if (!type || !AGGREGATE_TYPE_P (type))
    3174              :         {
    3175           16 :           cum->mmx_words += words;
    3176           16 :           cum->mmx_nregs -= 1;
    3177           16 :           cum->mmx_regno += 1;
    3178           16 :           if (cum->mmx_nregs <= 0)
    3179              :             {
    3180            0 :               cum->mmx_nregs = 0;
    3181            0 :               cum->mmx_regno = 0;
    3182              :             }
    3183              :         }
    3184              :       break;
    3185              :     }
    3186      2066850 :   if (error_p)
    3187              :     {
    3188            0 :       cum->float_in_sse = 0;
    3189            0 :       error ("calling %qD with SSE calling convention without "
    3190              :              "SSE/SSE2 enabled", cum->decl);
    3191            0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3192              :              "attribute used to function called");
    3193              :     }
    3194              : 
    3195              :   return res;
    3196              : }
    3197              : 
    3198              : static int
    3199     19405715 : function_arg_advance_64 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3200              :                          const_tree type, HOST_WIDE_INT words, bool named)
    3201              : {
    3202     19405715 :   int int_nregs, sse_nregs;
    3203              : 
    3204              :   /* Unnamed 512 and 256bit vector mode parameters are passed on stack.  */
    3205     19405715 :   if (!named && (VALID_AVX512F_REG_MODE (mode)
    3206              :                  || VALID_AVX256_REG_MODE (mode)))
    3207              :     return 0;
    3208              : 
    3209     19405351 :   if (!examine_argument (mode, type, false, &int_nregs, &sse_nregs)
    3210     19405351 :       && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
    3211              :     {
    3212     17122813 :       cum->nregs -= int_nregs;
    3213     17122813 :       cum->sse_nregs -= sse_nregs;
    3214     17122813 :       cum->regno += int_nregs;
    3215     17122813 :       cum->sse_regno += sse_nregs;
    3216     17122813 :       return int_nregs;
    3217              :     }
    3218              :   else
    3219              :     {
    3220      2282538 :       int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
    3221      2282538 :       cum->words = ROUND_UP (cum->words, align);
    3222      2282538 :       cum->words += words;
    3223      2282538 :       return 0;
    3224              :     }
    3225              : }
    3226              : 
    3227              : static int
    3228       447474 : function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
    3229              :                             HOST_WIDE_INT words)
    3230              : {
    3231              :   /* Otherwise, this should be passed indirect.  */
    3232       447474 :   gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
    3233              : 
    3234       447474 :   cum->words += words;
    3235       447474 :   if (cum->nregs > 0)
    3236              :     {
    3237       289715 :       cum->nregs -= 1;
    3238       289715 :       cum->regno += 1;
    3239       289715 :       return 1;
    3240              :     }
    3241              :   return 0;
    3242              : }
    3243              : 
    3244              : /* Update the data in CUM to advance over argument ARG.  */
    3245              : 
    3246              : static void
    3247     21985252 : ix86_function_arg_advance (cumulative_args_t cum_v,
    3248              :                            const function_arg_info &arg)
    3249              : {
    3250     21985252 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3251     21985252 :   machine_mode mode = arg.mode;
    3252     21985252 :   HOST_WIDE_INT bytes, words;
    3253     21985252 :   int nregs;
    3254              : 
    3255              :   /* The argument of interrupt handler is a special case and is
    3256              :      handled in ix86_function_arg.  */
    3257     21985252 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3258              :     return;
    3259              : 
    3260     21984885 :   bytes = arg.promoted_size_in_bytes ();
    3261     21984885 :   words = CEIL (bytes, UNITS_PER_WORD);
    3262              : 
    3263     21984885 :   if (arg.type)
    3264     21663668 :     mode = type_natural_mode (arg.type, NULL, false);
    3265              : 
    3266     21984885 :   if (TARGET_64BIT)
    3267              :     {
    3268     19853189 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3269              : 
    3270     19853189 :       if (call_abi == MS_ABI)
    3271       447474 :         nregs = function_arg_advance_ms_64 (cum, bytes, words);
    3272              :       else
    3273     19405715 :         nregs = function_arg_advance_64 (cum, mode, arg.type, words,
    3274     19405715 :                                          arg.named);
    3275              :     }
    3276              :   else
    3277      2131696 :     nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
    3278              : 
    3279     21984885 :   if (!nregs)
    3280              :     {
    3281              :       /* Track if there are outgoing arguments on stack.  */
    3282      5739428 :       if (cum->caller)
    3283      2728961 :         cfun->machine->outgoing_args_on_stack = true;
    3284              :     }
    3285              : }
    3286              : 
    3287              : /* Define where to put the arguments to a function.
    3288              :    Value is zero to push the argument on the stack,
    3289              :    or a hard register in which to store the argument.
    3290              : 
    3291              :    MODE is the argument's machine mode.
    3292              :    TYPE is the data type of the argument (as a tree).
    3293              :     This is null for libcalls where that information may
    3294              :     not be available.
    3295              :    CUM is a variable of type CUMULATIVE_ARGS which gives info about
    3296              :     the preceding args and about the function being called.
    3297              :    NAMED is nonzero if this argument is a named parameter
    3298              :     (otherwise it is an extra parameter matching an ellipsis).  */
    3299              : 
    3300              : static rtx
    3301      2558554 : function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3302              :                  machine_mode orig_mode, const_tree type,
    3303              :                  HOST_WIDE_INT bytes, HOST_WIDE_INT words)
    3304              : {
    3305      2558554 :   bool error_p = false;
    3306              : 
    3307              :   /* Avoid the AL settings for the Unix64 ABI.  */
    3308      2558554 :   if (mode == VOIDmode)
    3309       742433 :     return constm1_rtx;
    3310              : 
    3311      1816121 :   if (TARGET_IAMCU)
    3312              :     {
    3313              :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    3314              :          bytes in registers.  */
    3315            0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3316            0 :         goto pass_in_reg;
    3317              :       return NULL_RTX;
    3318              :     }
    3319              : 
    3320      1816121 :   switch (mode)
    3321              :     {
    3322              :     default:
    3323              :       break;
    3324              : 
    3325        77776 :     case E_BLKmode:
    3326        77776 :       if (bytes < 0)
    3327              :         break;
    3328              :       /* FALLTHRU */
    3329      1782477 :     case E_DImode:
    3330      1782477 :     case E_SImode:
    3331      1782477 :     case E_HImode:
    3332      1782477 :     case E_QImode:
    3333        77776 : pass_in_reg:
    3334      1782477 :       if (words <= cum->nregs)
    3335              :         {
    3336        45490 :           int regno = cum->regno;
    3337              : 
    3338              :           /* Fastcall allocates the first two DWORD (SImode) or
    3339              :             smaller arguments to ECX and EDX if it isn't an
    3340              :             aggregate type .  */
    3341        45490 :           if (cum->fastcall)
    3342              :             {
    3343            6 :               if (mode == BLKmode
    3344            6 :                   || mode == DImode
    3345            6 :                   || (type && AGGREGATE_TYPE_P (type)))
    3346              :                 break;
    3347              : 
    3348              :               /* ECX not EAX is the first allocated register.  */
    3349            6 :               if (regno == AX_REG)
    3350        45490 :                 regno = CX_REG;
    3351              :             }
    3352        45490 :           return gen_rtx_REG (mode, regno);
    3353              :         }
    3354              :       break;
    3355              : 
    3356         3367 :     case E_DFmode:
    3357         3367 :       if (cum->float_in_sse == -1)
    3358            0 :         error_p = true;
    3359         3367 :       if (cum->float_in_sse < 2)
    3360              :         break;
    3361              :       /* FALLTHRU */
    3362          974 :     case E_SFmode:
    3363          974 :       if (cum->float_in_sse == -1)
    3364            0 :         error_p = true;
    3365          974 :       if (cum->float_in_sse < 1)
    3366              :         break;
    3367              :       /* FALLTHRU */
    3368           12 :     case E_TImode:
    3369              :       /* In 32bit, we pass TImode in xmm registers.  */
    3370           12 :     case E_V16QImode:
    3371           12 :     case E_V8HImode:
    3372           12 :     case E_V4SImode:
    3373           12 :     case E_V2DImode:
    3374           12 :     case E_V8HFmode:
    3375           12 :     case E_V8BFmode:
    3376           12 :     case E_V4SFmode:
    3377           12 :     case E_V2DFmode:
    3378           12 :       if (!type || !AGGREGATE_TYPE_P (type))
    3379              :         {
    3380           12 :           if (cum->sse_nregs)
    3381           12 :             return gen_reg_or_parallel (mode, orig_mode,
    3382           12 :                                         cum->sse_regno + FIRST_SSE_REG);
    3383              :         }
    3384              :       break;
    3385              : 
    3386            0 :     case E_OImode:
    3387            0 :     case E_XImode:
    3388              :       /* OImode and XImode shouldn't be used directly.  */
    3389            0 :       gcc_unreachable ();
    3390              : 
    3391            9 :     case E_V64QImode:
    3392            9 :     case E_V32HImode:
    3393            9 :     case E_V16SImode:
    3394            9 :     case E_V8DImode:
    3395            9 :     case E_V32HFmode:
    3396            9 :     case E_V32BFmode:
    3397            9 :     case E_V16SFmode:
    3398            9 :     case E_V8DFmode:
    3399            9 :     case E_V16HFmode:
    3400            9 :     case E_V16BFmode:
    3401            9 :     case E_V8SFmode:
    3402            9 :     case E_V8SImode:
    3403            9 :     case E_V32QImode:
    3404            9 :     case E_V16HImode:
    3405            9 :     case E_V4DFmode:
    3406            9 :     case E_V4DImode:
    3407            9 :       if (!type || !AGGREGATE_TYPE_P (type))
    3408              :         {
    3409            9 :           if (cum->sse_nregs)
    3410            9 :             return gen_reg_or_parallel (mode, orig_mode,
    3411            9 :                                         cum->sse_regno + FIRST_SSE_REG);
    3412              :         }
    3413              :       break;
    3414              : 
    3415            8 :     case E_V8QImode:
    3416            8 :     case E_V4HImode:
    3417            8 :     case E_V4HFmode:
    3418            8 :     case E_V4BFmode:
    3419            8 :     case E_V2SImode:
    3420            8 :     case E_V2SFmode:
    3421            8 :     case E_V1TImode:
    3422            8 :     case E_V1DImode:
    3423            8 :       if (!type || !AGGREGATE_TYPE_P (type))
    3424              :         {
    3425            8 :           if (cum->mmx_nregs)
    3426            8 :             return gen_reg_or_parallel (mode, orig_mode,
    3427            8 :                                         cum->mmx_regno + FIRST_MMX_REG);
    3428              :         }
    3429              :       break;
    3430              :     }
    3431         4341 :   if (error_p)
    3432              :     {
    3433            0 :       cum->float_in_sse = 0;
    3434            0 :       error ("calling %qD with SSE calling convention without "
    3435              :              "SSE/SSE2 enabled", cum->decl);
    3436            0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3437              :              "attribute used to function called");
    3438              :     }
    3439              : 
    3440              :   return NULL_RTX;
    3441              : }
    3442              : 
    3443              : static rtx
    3444     19015962 : function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3445              :                  machine_mode orig_mode, const_tree type, bool named)
    3446              : {
    3447              :   /* Handle a hidden AL argument containing number of registers
    3448              :      for varargs x86-64 functions.  */
    3449     19015962 :   if (mode == VOIDmode)
    3450      5264089 :     return GEN_INT (cum->maybe_vaarg
    3451              :                     ? (cum->sse_nregs < 0
    3452              :                        ? X86_64_SSE_REGPARM_MAX
    3453              :                        : cum->sse_regno)
    3454              :                     : -1);
    3455              : 
    3456     13751873 :   switch (mode)
    3457              :     {
    3458              :     default:
    3459              :       break;
    3460              : 
    3461        90093 :     case E_V16HFmode:
    3462        90093 :     case E_V16BFmode:
    3463        90093 :     case E_V8SFmode:
    3464        90093 :     case E_V8SImode:
    3465        90093 :     case E_V32QImode:
    3466        90093 :     case E_V16HImode:
    3467        90093 :     case E_V4DFmode:
    3468        90093 :     case E_V4DImode:
    3469        90093 :     case E_V32HFmode:
    3470        90093 :     case E_V32BFmode:
    3471        90093 :     case E_V16SFmode:
    3472        90093 :     case E_V16SImode:
    3473        90093 :     case E_V64QImode:
    3474        90093 :     case E_V32HImode:
    3475        90093 :     case E_V8DFmode:
    3476        90093 :     case E_V8DImode:
    3477              :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    3478        90093 :       if (!named)
    3479              :         return NULL;
    3480              :       break;
    3481              :     }
    3482              : 
    3483     13751509 :   const int *parm_regs;
    3484     13751509 :   if (cum->preserve_none_abi)
    3485              :     parm_regs = x86_64_preserve_none_int_parameter_registers;
    3486              :   else
    3487     13751309 :     parm_regs = x86_64_int_parameter_registers;
    3488              : 
    3489     13751509 :   return construct_container (mode, orig_mode, type, false,
    3490     13751509 :                               cum->nregs, cum->sse_nregs,
    3491     13751509 :                               &parm_regs[cum->regno],
    3492     13751509 :                               cum->sse_regno);
    3493              : }
    3494              : 
    3495              : static rtx
    3496       296679 : function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3497              :                     machine_mode orig_mode, bool named, const_tree type,
    3498              :                     HOST_WIDE_INT bytes)
    3499              : {
    3500       296679 :   unsigned int regno;
    3501              : 
    3502              :   /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
    3503              :      We use value of -2 to specify that current function call is MSABI.  */
    3504       296679 :   if (mode == VOIDmode)
    3505        36329 :     return GEN_INT (-2);
    3506              : 
    3507              :   /* If we've run out of registers, it goes on the stack.  */
    3508       260350 :   if (cum->nregs == 0)
    3509              :     return NULL_RTX;
    3510              : 
    3511       176508 :   regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
    3512              : 
    3513              :   /* Only floating point modes less than 64 bits are passed in anything but
    3514              :      integer regs.  Larger floating point types are excluded as the Windows
    3515              :      ABI requires vreg args can be shadowed in GPRs (for red zone / varargs). */
    3516       176508 :   if (TARGET_SSE && (mode == HFmode || mode == SFmode || mode == DFmode))
    3517              :     {
    3518        38309 :       if (named)
    3519              :         {
    3520        38309 :           if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
    3521        37312 :             regno = cum->regno + FIRST_SSE_REG;
    3522              :         }
    3523              :       else
    3524              :         {
    3525            0 :           rtx t1, t2;
    3526              : 
    3527              :           /* Unnamed floating parameters are passed in both the
    3528              :              SSE and integer registers.  */
    3529            0 :           t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
    3530            0 :           t2 = gen_rtx_REG (mode, regno);
    3531            0 :           t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
    3532            0 :           t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
    3533            0 :           return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
    3534              :         }
    3535              :     }
    3536              :   /* Handle aggregated types passed in register.  */
    3537       176508 :   if (orig_mode == BLKmode)
    3538              :     {
    3539            0 :       if (bytes > 0 && bytes <= 8)
    3540            0 :         mode = (bytes > 4 ? DImode : SImode);
    3541            0 :       if (mode == BLKmode)
    3542            0 :         mode = DImode;
    3543              :     }
    3544              : 
    3545       176508 :   return gen_reg_or_parallel (mode, orig_mode, regno);
    3546              : }
    3547              : 
    3548              : /* Return where to put the arguments to a function.
    3549              :    Return zero to push the argument on the stack, or a hard register in which to store the argument.
    3550              : 
    3551              :    ARG describes the argument while CUM gives information about the
    3552              :    preceding args and about the function being called.  */
    3553              : 
    3554              : static rtx
    3555     21871382 : ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    3556              : {
    3557     21871382 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3558     21871382 :   machine_mode mode = arg.mode;
    3559     21871382 :   HOST_WIDE_INT bytes, words;
    3560     21871382 :   rtx reg;
    3561              : 
    3562     21871382 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3563              :     {
    3564          187 :       gcc_assert (arg.type != NULL_TREE);
    3565          187 :       if (POINTER_TYPE_P (arg.type))
    3566              :         {
    3567              :           /* This is the pointer argument.  */
    3568          122 :           gcc_assert (TYPE_MODE (arg.type) == ptr_mode);
    3569              :           /* It is at -WORD(AP) in the current frame in interrupt and
    3570              :              exception handlers.  */
    3571          122 :           reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
    3572              :         }
    3573              :       else
    3574              :         {
    3575           65 :           gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
    3576              :                       && TREE_CODE (arg.type) == INTEGER_TYPE
    3577              :                       && TYPE_MODE (arg.type) == word_mode);
    3578              :           /* The error code is the word-mode integer argument at
    3579              :              -2 * WORD(AP) in the current frame of the exception
    3580              :              handler.  */
    3581           65 :           reg = gen_rtx_MEM (word_mode,
    3582           65 :                              plus_constant (Pmode,
    3583              :                                             arg_pointer_rtx,
    3584           65 :                                             -2 * UNITS_PER_WORD));
    3585              :         }
    3586          187 :       return reg;
    3587              :     }
    3588              : 
    3589     21871195 :   bytes = arg.promoted_size_in_bytes ();
    3590     21871195 :   words = CEIL (bytes, UNITS_PER_WORD);
    3591              : 
    3592              :   /* To simplify the code below, represent vector types with a vector mode
    3593              :      even if MMX/SSE are not active.  */
    3594     21871195 :   if (arg.type && VECTOR_TYPE_P (arg.type))
    3595       172020 :     mode = type_natural_mode (arg.type, cum, false);
    3596              : 
    3597     21871195 :   if (TARGET_64BIT)
    3598              :     {
    3599     19312641 :       if (cum->call_abi == MS_ABI)
    3600       296679 :         reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
    3601       296679 :                                   arg.type, bytes);
    3602              :       else
    3603     19015962 :         reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
    3604              :     }
    3605              :   else
    3606      2558554 :     reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
    3607              : 
    3608              :   /* Track if there are outgoing arguments on stack.  */
    3609     21871195 :   if (reg == NULL_RTX && cum->caller)
    3610      2203490 :     cfun->machine->outgoing_args_on_stack = true;
    3611              : 
    3612              :   return reg;
    3613              : }
    3614              : 
    3615              : /* A C expression that indicates when an argument must be passed by
    3616              :    reference.  If nonzero for an argument, a copy of that argument is
    3617              :    made in memory and a pointer to the argument is passed instead of
    3618              :    the argument itself.  The pointer is passed in whatever way is
    3619              :    appropriate for passing a pointer to that type.  */
    3620              : 
    3621              : static bool
    3622     21903556 : ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
    3623              : {
    3624     21903556 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3625              : 
    3626     21903556 :   if (TARGET_64BIT)
    3627              :     {
    3628     19782108 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3629              : 
    3630              :       /* See Windows x64 Software Convention.  */
    3631     19782108 :       if (call_abi == MS_ABI)
    3632              :         {
    3633       441871 :           HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
    3634              : 
    3635       441871 :           if (tree type = arg.type)
    3636              :             {
    3637              :               /* Arrays are passed by reference.  */
    3638       441871 :               if (TREE_CODE (type) == ARRAY_TYPE)
    3639              :                 return true;
    3640              : 
    3641       441871 :               if (RECORD_OR_UNION_TYPE_P (type))
    3642              :                 {
    3643              :                   /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
    3644              :                      are passed by reference.  */
    3645        15103 :                   msize = int_size_in_bytes (type);
    3646              :                 }
    3647              :             }
    3648              : 
    3649              :           /* __m128 is passed by reference.  */
    3650       873737 :           return msize != 1 && msize != 2 && msize != 4 && msize != 8;
    3651              :         }
    3652     19340237 :       else if (arg.type && int_size_in_bytes (arg.type) == -1)
    3653              :         return true;
    3654              :     }
    3655              : 
    3656              :   return false;
    3657              : }
    3658              : 
    3659              : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3660              :    passing ABI.  XXX: This function is obsolete and is only used for
    3661              :    checking psABI compatibility with previous versions of GCC.  */
    3662              : 
    3663              : static bool
    3664      1976687 : ix86_compat_aligned_value_p (const_tree type)
    3665              : {
    3666      1976687 :   machine_mode mode = TYPE_MODE (type);
    3667      1976687 :   if (((TARGET_SSE && SSE_REG_MODE_P (mode))
    3668      1976645 :        || mode == TDmode
    3669      1976645 :        || mode == TFmode
    3670              :        || mode == TCmode)
    3671      1976899 :       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
    3672              :     return true;
    3673      1976475 :   if (TYPE_ALIGN (type) < 128)
    3674              :     return false;
    3675              : 
    3676            0 :   if (AGGREGATE_TYPE_P (type))
    3677              :     {
    3678              :       /* Walk the aggregates recursively.  */
    3679            0 :       switch (TREE_CODE (type))
    3680              :         {
    3681            0 :         case RECORD_TYPE:
    3682            0 :         case UNION_TYPE:
    3683            0 :         case QUAL_UNION_TYPE:
    3684            0 :           {
    3685            0 :             tree field;
    3686              : 
    3687              :             /* Walk all the structure fields.  */
    3688            0 :             for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    3689              :               {
    3690            0 :                 if (TREE_CODE (field) == FIELD_DECL
    3691            0 :                     && ix86_compat_aligned_value_p (TREE_TYPE (field)))
    3692              :                   return true;
    3693              :               }
    3694              :             break;
    3695              :           }
    3696              : 
    3697            0 :         case ARRAY_TYPE:
    3698              :           /* Just for use if some languages passes arrays by value.  */
    3699            0 :           if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
    3700              :             return true;
    3701              :           break;
    3702              : 
    3703              :         default:
    3704              :           gcc_unreachable ();
    3705              :         }
    3706              :     }
    3707              :   return false;
    3708              : }
    3709              : 
    3710              : /* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
    3711              :    XXX: This function is obsolete and is only used for checking psABI
    3712              :    compatibility with previous versions of GCC.  */
    3713              : 
    3714              : static unsigned int
    3715      5583805 : ix86_compat_function_arg_boundary (machine_mode mode,
    3716              :                                    const_tree type, unsigned int align)
    3717              : {
    3718              :   /* In 32bit, only _Decimal128 and __float128 are aligned to their
    3719              :      natural boundaries.  */
    3720      5583805 :   if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
    3721              :     {
    3722              :       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
    3723              :          make an exception for SSE modes since these require 128bit
    3724              :          alignment.
    3725              : 
    3726              :          The handling here differs from field_alignment.  ICC aligns MMX
    3727              :          arguments to 4 byte boundaries, while structure fields are aligned
    3728              :          to 8 byte boundaries.  */
    3729      1988603 :       if (!type)
    3730              :         {
    3731        11916 :           if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
    3732      1988391 :             align = PARM_BOUNDARY;
    3733              :         }
    3734              :       else
    3735              :         {
    3736      1976687 :           if (!ix86_compat_aligned_value_p (type))
    3737      1988391 :             align = PARM_BOUNDARY;
    3738              :         }
    3739              :     }
    3740     10767407 :   if (align > BIGGEST_ALIGNMENT)
    3741          104 :     align = BIGGEST_ALIGNMENT;
    3742      5583805 :   return align;
    3743              : }
    3744              : 
    3745              : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3746              :    passing ABI.  */
    3747              : 
    3748              : static bool
    3749      1979384 : ix86_contains_aligned_value_p (const_tree type)
    3750              : {
    3751      1979384 :   machine_mode mode = TYPE_MODE (type);
    3752              : 
    3753      1979384 :   if (mode == XFmode || mode == XCmode)
    3754              :     return false;
    3755              : 
    3756      1977229 :   if (TYPE_ALIGN (type) < 128)
    3757              :     return false;
    3758              : 
    3759         2909 :   if (AGGREGATE_TYPE_P (type))
    3760              :     {
    3761              :       /* Walk the aggregates recursively.  */
    3762            0 :       switch (TREE_CODE (type))
    3763              :         {
    3764            0 :         case RECORD_TYPE:
    3765            0 :         case UNION_TYPE:
    3766            0 :         case QUAL_UNION_TYPE:
    3767            0 :           {
    3768            0 :             tree field;
    3769              : 
    3770              :             /* Walk all the structure fields.  */
    3771            0 :             for (field = TYPE_FIELDS (type);
    3772            0 :                  field;
    3773            0 :                  field = DECL_CHAIN (field))
    3774              :               {
    3775            0 :                 if (TREE_CODE (field) == FIELD_DECL
    3776            0 :                     && ix86_contains_aligned_value_p (TREE_TYPE (field)))
    3777              :                   return true;
    3778              :               }
    3779              :             break;
    3780              :           }
    3781              : 
    3782            0 :         case ARRAY_TYPE:
    3783              :           /* Just for use if some languages passes arrays by value.  */
    3784            0 :           if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
    3785              :             return true;
    3786              :           break;
    3787              : 
    3788              :         default:
    3789              :           gcc_unreachable ();
    3790              :         }
    3791              :     }
    3792              :   else
    3793         2909 :     return TYPE_ALIGN (type) >= 128;
    3794              : 
    3795              :   return false;
    3796              : }
    3797              : 
    3798              : /* Gives the alignment boundary, in bits, of an argument with the
    3799              :    specified mode and type.  */
    3800              : 
    3801              : static unsigned int
    3802     10995280 : ix86_function_arg_boundary (machine_mode mode, const_tree type)
    3803              : {
    3804     10995280 :   unsigned int align;
    3805     10995280 :   if (type)
    3806              :     {
    3807              :       /* Since the main variant type is used for call, we convert it to
    3808              :          the main variant type.  */
    3809     10955431 :       type = TYPE_MAIN_VARIANT (type);
    3810     10955431 :       align = TYPE_ALIGN (type);
    3811     10955431 :       if (TYPE_EMPTY_P (type))
    3812        25294 :         return PARM_BOUNDARY;
    3813              :     }
    3814              :   else
    3815        39849 :     align = GET_MODE_ALIGNMENT (mode);
    3816     12996555 :   if (align < PARM_BOUNDARY)
    3817      4119825 :     align = PARM_BOUNDARY;
    3818              :   else
    3819              :     {
    3820      6850161 :       static bool warned;
    3821      6850161 :       unsigned int saved_align = align;
    3822              : 
    3823      6850161 :       if (!TARGET_64BIT)
    3824              :         {
    3825              :           /* i386 ABI defines XFmode arguments to be 4 byte aligned.  */
    3826      2015218 :           if (!type)
    3827              :             {
    3828        35834 :               if (mode == XFmode || mode == XCmode)
    3829              :                 align = PARM_BOUNDARY;
    3830              :             }
    3831      1979384 :           else if (!ix86_contains_aligned_value_p (type))
    3832              :             align = PARM_BOUNDARY;
    3833              : 
    3834        38743 :           if (align < 128)
    3835      1988391 :             align = PARM_BOUNDARY;
    3836              :         }
    3837              : 
    3838      6850161 :       if (warn_psabi
    3839      5592326 :           && !warned
    3840     12433966 :           && align != ix86_compat_function_arg_boundary (mode, type,
    3841              :                                                          saved_align))
    3842              :         {
    3843          104 :           warned = true;
    3844          104 :           inform (input_location,
    3845              :                   "the ABI for passing parameters with %d-byte"
    3846              :                   " alignment has changed in GCC 4.6",
    3847              :                   align / BITS_PER_UNIT);
    3848              :         }
    3849              :     }
    3850              : 
    3851              :   return align;
    3852              : }
    3853              : 
    3854              : /* Return true if N is a possible register number of function value.  */
    3855              : 
    3856              : static bool
    3857      4354421 : ix86_function_value_regno_p (const unsigned int regno)
    3858              : {
    3859      4354421 :   switch (regno)
    3860              :     {
    3861              :     case AX_REG:
    3862              :       return true;
    3863       104122 :     case DX_REG:
    3864       104122 :       return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI);
    3865              : 
    3866              :       /* Complex values are returned in %st(0)/%st(1) pair.  */
    3867        16296 :     case ST0_REG:
    3868        16296 :     case ST1_REG:
    3869              :       /* TODO: An ABI identifier should be passed as a parameter.
    3870              :          For now, most callers, including those in builtins.cc,
    3871              :          expect us to use the default ABI.  */
    3872        16296 :       if (TARGET_64BIT && ix86_abi == MS_ABI)
    3873              :         return false;
    3874        16296 :       return TARGET_FLOAT_RETURNS_IN_80387;
    3875              : 
    3876              :       /* Complex values are returned in %xmm0/%xmm1 pair.  */
    3877      1285075 :     case XMM0_REG:
    3878      1285075 :     case XMM1_REG:
    3879      1285075 :       return TARGET_SSE;
    3880              : 
    3881         5472 :     case MM0_REG:
    3882         5472 :       if (TARGET_MACHO || TARGET_64BIT)
    3883              :         return false;
    3884         2502 :       return TARGET_MMX;
    3885              :     }
    3886              : 
    3887              :   return false;
    3888              : }
    3889              : 
    3890              : /* Check whether the register REGNO should be zeroed on X86.
    3891              :    When ALL_SSE_ZEROED is true, all SSE registers have been zeroed
    3892              :    together, no need to zero it again.
    3893              :    When NEED_ZERO_MMX is true, MMX registers should be cleared.  */
    3894              : 
    3895              : static bool
    3896         1377 : zero_call_used_regno_p (const unsigned int regno,
    3897              :                         bool all_sse_zeroed,
    3898              :                         bool need_zero_mmx)
    3899              : {
    3900          835 :   return GENERAL_REGNO_P (regno)
    3901          819 :          || (!all_sse_zeroed && SSE_REGNO_P (regno))
    3902          439 :          || MASK_REGNO_P (regno)
    3903         1800 :          || (need_zero_mmx && MMX_REGNO_P (regno));
    3904              : }
    3905              : 
    3906              : /* Return the machine_mode that is used to zero register REGNO.  */
    3907              : 
    3908              : static machine_mode
    3909          954 : zero_call_used_regno_mode (const unsigned int regno)
    3910              : {
    3911              :   /* NB: We only need to zero the lower 32 bits for integer registers
    3912              :      and the lower 128 bits for vector registers since destination are
    3913              :      zero-extended to the full register width.  */
    3914          954 :   if (GENERAL_REGNO_P (regno))
    3915              :     return SImode;
    3916              :   else if (SSE_REGNO_P (regno))
    3917          380 :     return V4SFmode;
    3918              :   else if (MASK_REGNO_P (regno))
    3919              :     return HImode;
    3920              :   else if (MMX_REGNO_P (regno))
    3921            0 :     return V2SImode;
    3922              :   else
    3923            0 :     gcc_unreachable ();
    3924              : }
    3925              : 
    3926              : /* Generate a rtx to zero all vector registers together if possible,
    3927              :    otherwise, return NULL.  */
    3928              : 
    3929              : static rtx
    3930          131 : zero_all_vector_registers (HARD_REG_SET need_zeroed_hardregs)
    3931              : {
    3932          131 :   if (!TARGET_AVX)
    3933              :     return NULL;
    3934              : 
    3935          372 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3936          368 :     if ((LEGACY_SSE_REGNO_P (regno)
    3937          336 :          || (TARGET_64BIT
    3938          336 :              && (REX_SSE_REGNO_P (regno)
    3939          304 :                  || (TARGET_AVX512F && EXT_REX_SSE_REGNO_P (regno)))))
    3940          432 :         && !TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3941              :       return NULL;
    3942              : 
    3943            4 :   return gen_avx_vzeroall ();
    3944              : }
    3945              : 
    3946              : /* Generate insns to zero all st registers together.
    3947              :    Return true when zeroing instructions are generated.
    3948              :    Assume the number of st registers that are zeroed is num_of_st,
    3949              :    we will emit the following sequence to zero them together:
    3950              :                   fldz;         \
    3951              :                   fldz;         \
    3952              :                   ...
    3953              :                   fldz;         \
    3954              :                   fstp %%st(0); \
    3955              :                   fstp %%st(0); \
    3956              :                   ...
    3957              :                   fstp %%st(0);
    3958              :    i.e., num_of_st fldz followed by num_of_st fstp to clear the stack
    3959              :    mark stack slots empty.
    3960              : 
    3961              :    How to compute the num_of_st:
    3962              :    There is no direct mapping from stack registers to hard register
    3963              :    numbers.  If one stack register needs to be cleared, we don't know
    3964              :    where in the stack the value remains.  So, if any stack register
    3965              :    needs to be cleared, the whole stack should be cleared.  However,
    3966              :    x87 stack registers that hold the return value should be excluded.
    3967              :    x87 returns in the top (two for complex values) register, so
    3968              :    num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
    3969              :    return the value of num_of_st.  */
    3970              : 
    3971              : 
    3972              : static int
    3973          131 : zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
    3974              : {
    3975              : 
    3976              :   /* If the FPU is disabled, no need to zero all st registers.  */
    3977          131 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
    3978              :     return 0;
    3979              : 
    3980        10329 :   unsigned int num_of_st = 0;
    3981        10329 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3982        10220 :     if ((STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
    3983        10220 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3984              :       {
    3985              :         num_of_st++;
    3986              :         break;
    3987              :       }
    3988              : 
    3989          130 :   if (num_of_st == 0)
    3990              :     return 0;
    3991              : 
    3992           21 :   bool return_with_x87 = false;
    3993           42 :   return_with_x87 = (crtl->return_rtx
    3994           21 :                      && (STACK_REG_P (crtl->return_rtx)));
    3995              : 
    3996           21 :   bool complex_return = false;
    3997           42 :   complex_return = (crtl->return_rtx
    3998           21 :                     && COMPLEX_MODE_P (GET_MODE (crtl->return_rtx)));
    3999              : 
    4000           21 :   if (return_with_x87)
    4001            2 :     if (complex_return)
    4002              :       num_of_st = 6;
    4003              :     else
    4004            1 :       num_of_st = 7;
    4005              :   else
    4006              :     num_of_st = 8;
    4007              : 
    4008           21 :   rtx st_reg = gen_rtx_REG (XFmode, FIRST_STACK_REG);
    4009          186 :   for (unsigned int i = 0; i < num_of_st; i++)
    4010          165 :     emit_insn (gen_rtx_SET (st_reg, CONST0_RTX (XFmode)));
    4011              : 
    4012          186 :   for (unsigned int i = 0; i < num_of_st; i++)
    4013              :     {
    4014          165 :       rtx insn;
    4015          165 :       insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
    4016          165 :       add_reg_note (insn, REG_DEAD, st_reg);
    4017              :     }
    4018           21 :   return num_of_st;
    4019              : }
    4020              : 
    4021              : 
    4022              : /* When the routine exit in MMX mode, if any ST register needs
    4023              :    to be zeroed, we should clear all MMX registers except the
    4024              :    RET_MMX_REGNO that holds the return value.  */
    4025              : static bool
    4026            0 : zero_all_mm_registers (HARD_REG_SET need_zeroed_hardregs,
    4027              :                        unsigned int ret_mmx_regno)
    4028              : {
    4029            0 :   bool need_zero_all_mm = false;
    4030            0 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4031            0 :     if (STACK_REGNO_P (regno)
    4032            0 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4033              :       {
    4034              :         need_zero_all_mm = true;
    4035              :         break;
    4036              :       }
    4037              : 
    4038            0 :   if (!need_zero_all_mm)
    4039              :     return false;
    4040              : 
    4041              :   machine_mode mode = V2SImode;
    4042            0 :   for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    4043            0 :     if (regno != ret_mmx_regno)
    4044              :       {
    4045            0 :         rtx reg = gen_rtx_REG (mode, regno);
    4046            0 :         emit_insn (gen_rtx_SET (reg, CONST0_RTX (mode)));
    4047              :       }
    4048              :   return true;
    4049              : }
    4050              : 
    4051              : /* TARGET_ZERO_CALL_USED_REGS.  */
    4052              : /* Generate a sequence of instructions that zero registers specified by
    4053              :    NEED_ZEROED_HARDREGS.  Return the ZEROED_HARDREGS that are actually
    4054              :    zeroed.  */
    4055              : static HARD_REG_SET
    4056          131 : ix86_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
    4057              : {
    4058          131 :   HARD_REG_SET zeroed_hardregs;
    4059          131 :   bool all_sse_zeroed = false;
    4060          131 :   int all_st_zeroed_num = 0;
    4061          131 :   bool all_mm_zeroed = false;
    4062              : 
    4063          131 :   CLEAR_HARD_REG_SET (zeroed_hardregs);
    4064              : 
    4065              :   /* first, let's see whether we can zero all vector registers together.  */
    4066          131 :   rtx zero_all_vec_insn = zero_all_vector_registers (need_zeroed_hardregs);
    4067          131 :   if (zero_all_vec_insn)
    4068              :     {
    4069            4 :       emit_insn (zero_all_vec_insn);
    4070            4 :       all_sse_zeroed = true;
    4071            4 :       if (TARGET_64BIT && TARGET_AVX512F)
    4072              :         {
    4073            2 :           rtx zero = CONST0_RTX (V4SFmode);
    4074           34 :           for (unsigned int regno = XMM16_REG;
    4075           34 :                regno <= XMM31_REG;
    4076              :                regno++)
    4077              :             {
    4078           32 :               rtx reg = gen_rtx_REG (V4SFmode, regno);
    4079           32 :               emit_move_insn (reg, zero);
    4080              :             }
    4081              :         }
    4082              :     }
    4083              : 
    4084              :   /* mm/st registers are shared registers set, we should follow the following
    4085              :      rules to clear them:
    4086              :                         MMX exit mode         x87 exit mode
    4087              :         -------------|----------------------|---------------
    4088              :         uses x87 reg | clear all MMX        | clear all x87
    4089              :         uses MMX reg | clear individual MMX | clear all x87
    4090              :         x87 + MMX    | clear all MMX        | clear all x87
    4091              : 
    4092              :      first, we should decide which mode (MMX mode or x87 mode) the function
    4093              :      exit with.  */
    4094              : 
    4095          131 :   bool exit_with_mmx_mode = (crtl->return_rtx
    4096          131 :                              && (MMX_REG_P (crtl->return_rtx)));
    4097              : 
    4098          131 :   if (!exit_with_mmx_mode)
    4099              :     /* x87 exit mode, we should zero all st registers together.  */
    4100              :     {
    4101          131 :       all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
    4102              : 
    4103          131 :       if (all_st_zeroed_num > 0)
    4104          189 :         for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
    4105              :           /* x87 stack registers that hold the return value should be excluded.
    4106              :              x87 returns in the top (two for complex values) register.  */
    4107          168 :           if (all_st_zeroed_num == 8
    4108          168 :               || !((all_st_zeroed_num >= 6 && regno == REGNO (crtl->return_rtx))
    4109              :                    || (all_st_zeroed_num == 6
    4110            7 :                        && (regno == (REGNO (crtl->return_rtx) + 1)))))
    4111          165 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4112              :     }
    4113              :   else
    4114              :     /* MMX exit mode, check whether we can zero all mm registers.  */
    4115              :     {
    4116            0 :       unsigned int exit_mmx_regno = REGNO (crtl->return_rtx);
    4117            0 :       all_mm_zeroed = zero_all_mm_registers (need_zeroed_hardregs,
    4118              :                                              exit_mmx_regno);
    4119            0 :       if (all_mm_zeroed)
    4120            0 :         for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    4121            0 :           if (regno != exit_mmx_regno)
    4122            0 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4123              :     }
    4124              : 
    4125              :   /* Now, generate instructions to zero all the other registers.  */
    4126              : 
    4127        12183 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4128              :     {
    4129        12052 :       if (!TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4130        10675 :         continue;
    4131         1800 :       if (!zero_call_used_regno_p (regno, all_sse_zeroed,
    4132         1377 :                                    exit_with_mmx_mode && !all_mm_zeroed))
    4133          423 :         continue;
    4134              : 
    4135          954 :       SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4136              : 
    4137          954 :       machine_mode mode = zero_call_used_regno_mode (regno);
    4138              : 
    4139          954 :       rtx reg = gen_rtx_REG (mode, regno);
    4140          954 :       rtx tmp = gen_rtx_SET (reg, CONST0_RTX (mode));
    4141              : 
    4142          954 :       switch (mode)
    4143              :         {
    4144          558 :         case E_SImode:
    4145          558 :           if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
    4146              :             {
    4147          558 :               rtx clob = gen_rtx_CLOBBER (VOIDmode,
    4148              :                                           gen_rtx_REG (CCmode,
    4149              :                                                        FLAGS_REG));
    4150          558 :               tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
    4151              :                                                            tmp,
    4152              :                                                            clob));
    4153              :             }
    4154              :           /* FALLTHRU.  */
    4155              : 
    4156          954 :         case E_V4SFmode:
    4157          954 :         case E_HImode:
    4158          954 :         case E_V2SImode:
    4159          954 :           emit_insn (tmp);
    4160          954 :           break;
    4161              : 
    4162            0 :         default:
    4163            0 :           gcc_unreachable ();
    4164              :         }
    4165              :     }
    4166          131 :   return zeroed_hardregs;
    4167              : }
    4168              : 
    4169              : /* Define how to find the value returned by a function.
    4170              :    VALTYPE is the data type of the value (as a tree).
    4171              :    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    4172              :    otherwise, FUNC is 0.  */
    4173              : 
    4174              : static rtx
    4175      3948581 : function_value_32 (machine_mode orig_mode, machine_mode mode,
    4176              :                    const_tree fntype, const_tree fn)
    4177              : {
    4178      3948581 :   unsigned int regno;
    4179              : 
    4180              :   /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
    4181              :      we normally prevent this case when mmx is not available.  However
    4182              :      some ABIs may require the result to be returned like DImode.  */
    4183      4216666 :   if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
    4184              :     regno = FIRST_MMX_REG;
    4185              : 
    4186              :   /* 16-byte vector modes in %xmm0.  See ix86_return_in_memory for where
    4187              :      we prevent this case when sse is not available.  However some ABIs
    4188              :      may require the result to be returned like integer TImode.  */
    4189      3939305 :   else if (mode == TImode
    4190      4198114 :            || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
    4191              :     regno = FIRST_SSE_REG;
    4192              : 
    4193              :   /* 32-byte vector modes in %ymm0.   */
    4194      3980216 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
    4195              :     regno = FIRST_SSE_REG;
    4196              : 
    4197              :   /* 64-byte vector modes in %zmm0.   */
    4198      3836018 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 64)
    4199              :     regno = FIRST_SSE_REG;
    4200              : 
    4201              :   /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387).  */
    4202      3680496 :   else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
    4203              :     regno = FIRST_FLOAT_REG;
    4204              :   else
    4205              :     /* Most things go in %eax.  */
    4206      3614820 :     regno = AX_REG;
    4207              : 
    4208              :   /* Return __bf16/ _Float16/_Complex _Foat16 by sse register.  */
    4209      3948581 :   if (mode == HFmode || mode == BFmode)
    4210              :     {
    4211         1917 :       if (!TARGET_SSE2)
    4212              :         {
    4213            0 :           error ("SSE register return with SSE2 disabled");
    4214            0 :           regno = AX_REG;
    4215              :         }
    4216              :       else
    4217              :         regno = FIRST_SSE_REG;
    4218              :     }
    4219              : 
    4220      3948581 :   if (mode == HCmode)
    4221              :     {
    4222          129 :       if (!TARGET_SSE2)
    4223            0 :         error ("SSE register return with SSE2 disabled");
    4224              : 
    4225          129 :       rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1));
    4226          258 :       XVECEXP (ret, 0, 0)
    4227          258 :         = gen_rtx_EXPR_LIST (VOIDmode,
    4228              :                              gen_rtx_REG (SImode,
    4229          129 :                                           TARGET_SSE2 ? FIRST_SSE_REG : AX_REG),
    4230              :                              GEN_INT (0));
    4231          129 :       return ret;
    4232              :     }
    4233              : 
    4234              :   /* Override FP return register with %xmm0 for local functions when
    4235              :      SSE math is enabled or for functions with sseregparm attribute.  */
    4236      3948452 :   if ((fn || fntype) && (mode == SFmode || mode == DFmode))
    4237              :     {
    4238        51213 :       int sse_level = ix86_function_sseregparm (fntype, fn, false);
    4239        51213 :       if (sse_level == -1)
    4240              :         {
    4241            0 :           error ("calling %qD with SSE calling convention without "
    4242              :                  "SSE/SSE2 enabled", fn);
    4243            0 :           sorry ("this is a GCC bug that can be worked around by adding "
    4244              :                  "attribute used to function called");
    4245              :         }
    4246        51213 :       else if ((sse_level >= 1 && mode == SFmode)
    4247        51213 :                || (sse_level == 2 && mode == DFmode))
    4248              :         regno = FIRST_SSE_REG;
    4249              :     }
    4250              : 
    4251              :   /* OImode shouldn't be used directly.  */
    4252      3948452 :   gcc_assert (mode != OImode);
    4253              : 
    4254      3948452 :   return gen_rtx_REG (orig_mode, regno);
    4255              : }
    4256              : 
    4257              : static rtx
    4258    100483384 : function_value_64 (machine_mode orig_mode, machine_mode mode,
    4259              :                    const_tree valtype)
    4260              : {
    4261    100483384 :   rtx ret;
    4262              : 
    4263              :   /* Handle libcalls, which don't provide a type node.  */
    4264    100483384 :   if (valtype == NULL)
    4265              :     {
    4266       106491 :       unsigned int regno;
    4267              : 
    4268       106491 :       switch (mode)
    4269              :         {
    4270              :         case E_BFmode:
    4271              :         case E_HFmode:
    4272              :         case E_HCmode:
    4273              :         case E_SFmode:
    4274              :         case E_SCmode:
    4275              :         case E_DFmode:
    4276              :         case E_DCmode:
    4277              :         case E_TFmode:
    4278              :         case E_SDmode:
    4279              :         case E_DDmode:
    4280              :         case E_TDmode:
    4281              :           regno = FIRST_SSE_REG;
    4282              :           break;
    4283         1040 :         case E_XFmode:
    4284         1040 :         case E_XCmode:
    4285         1040 :           regno = FIRST_FLOAT_REG;
    4286         1040 :           break;
    4287              :         case E_TCmode:
    4288              :           return NULL;
    4289        57198 :         default:
    4290        57198 :           regno = AX_REG;
    4291              :         }
    4292              : 
    4293       106491 :       return gen_rtx_REG (mode, regno);
    4294              :     }
    4295    100376893 :   else if (POINTER_TYPE_P (valtype))
    4296              :     {
    4297              :       /* Pointers are always returned in word_mode.  */
    4298     16813356 :       mode = word_mode;
    4299              :     }
    4300              : 
    4301    100376893 :   ret = construct_container (mode, orig_mode, valtype, true,
    4302              :                              X86_64_MAX_RETURN_NREGS,
    4303              :                              X86_64_MAX_SSE_RETURN_NREGS,
    4304              :                              x86_64_int_return_registers, 0);
    4305              : 
    4306              :   /* For zero sized structures, construct_container returns NULL, but we
    4307              :      need to keep rest of compiler happy by returning meaningful value.  */
    4308    100376893 :   if (!ret)
    4309       204294 :     ret = gen_rtx_REG (orig_mode, AX_REG);
    4310              : 
    4311              :   return ret;
    4312              : }
    4313              : 
    4314              : static rtx
    4315            0 : function_value_ms_32 (machine_mode orig_mode, machine_mode mode,
    4316              :                       const_tree fntype, const_tree fn, const_tree valtype)
    4317              : {
    4318            0 :   unsigned int regno;
    4319              : 
    4320              :   /* Floating point return values in %st(0)
    4321              :      (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes).  */
    4322            0 :   if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387
    4323            0 :            && (GET_MODE_SIZE (mode) > 8
    4324            0 :                || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype)))
    4325              :   {
    4326            0 :     regno = FIRST_FLOAT_REG;
    4327            0 :     return gen_rtx_REG (orig_mode, regno);
    4328              :   }
    4329              :   else
    4330            0 :     return function_value_32(orig_mode, mode, fntype,fn);
    4331              : }
    4332              : 
    4333              : static rtx
    4334       804596 : function_value_ms_64 (machine_mode orig_mode, machine_mode mode,
    4335              :                       const_tree valtype)
    4336              : {
    4337       804596 :   unsigned int regno = AX_REG;
    4338              : 
    4339       804596 :   if (TARGET_SSE)
    4340              :     {
    4341       803867 :       unsigned int mode_size = GET_MODE_SIZE (mode);
    4342              : 
    4343       803867 :       switch (mode_size)
    4344              :         {
    4345        34397 :         case 16:
    4346        34397 :         case 32:
    4347        34397 :         case 64:
    4348        34397 :           if (mode_size == 32 && !TARGET_AVX)
    4349              :             break;
    4350        34397 :           if (mode_size == 64 && !TARGET_AVX512F)
    4351              :             break;
    4352        34397 :           if (valtype != NULL_TREE
    4353        34397 :               && !VECTOR_INTEGER_TYPE_P (valtype)
    4354        50225 :               && !VECTOR_FLOAT_TYPE_P (valtype))
    4355              :             break;
    4356        34397 :           if (VECTOR_MODE_P (mode)
    4357              :               && !COMPLEX_MODE_P (mode))
    4358       224364 :             regno = FIRST_SSE_REG;
    4359              :           break;
    4360       757831 :         case 8:
    4361       757831 :         case 4:
    4362       757831 :         case 2:
    4363       757831 :           if (valtype != NULL_TREE && AGGREGATE_TYPE_P (valtype))
    4364              :             break;
    4365       740537 :           if (mode == HFmode || mode == SFmode || mode == DFmode)
    4366       224364 :             regno = FIRST_SSE_REG;
    4367              :           break;
    4368              :         default:
    4369              :           break;
    4370              :         }
    4371              :     }
    4372       804596 :   return gen_rtx_REG (orig_mode, regno);
    4373              : }
    4374              : 
    4375              : static rtx
    4376    105236561 : ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
    4377              :                        machine_mode orig_mode, machine_mode mode)
    4378              : {
    4379    105236561 :   const_tree fn, fntype;
    4380              : 
    4381    105236561 :   fn = NULL_TREE;
    4382    105236561 :   if (fntype_or_decl && DECL_P (fntype_or_decl))
    4383      3573743 :     fn = fntype_or_decl;
    4384      3573743 :   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
    4385              : 
    4386    105236561 :   if (ix86_function_type_abi (fntype) == MS_ABI)
    4387              :     {
    4388       804596 :       if (TARGET_64BIT)
    4389       804596 :         return function_value_ms_64 (orig_mode, mode, valtype);
    4390              :       else
    4391            0 :         return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype);
    4392              :     }
    4393    104431965 :   else if (TARGET_64BIT)
    4394    100483384 :     return function_value_64 (orig_mode, mode, valtype);
    4395              :   else
    4396      3948581 :     return function_value_32 (orig_mode, mode, fntype, fn);
    4397              : }
    4398              : 
    4399              : static rtx
    4400    105126916 : ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
    4401              : {
    4402    105126916 :   machine_mode mode, orig_mode;
    4403              : 
    4404    105126916 :   orig_mode = TYPE_MODE (valtype);
    4405    105126916 :   mode = type_natural_mode (valtype, NULL, true);
    4406    105126916 :   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
    4407              : }
    4408              : 
    4409              : /* Pointer function arguments and return values are promoted to
    4410              :    word_mode for normal functions.  */
    4411              : 
    4412              : static machine_mode
    4413     32466835 : ix86_promote_function_mode (const_tree type, machine_mode mode,
    4414              :                             int *punsignedp, const_tree fntype,
    4415              :                             int for_return)
    4416              : {
    4417     32466835 :   if (cfun->machine->func_type == TYPE_NORMAL
    4418     32465812 :       && type != NULL_TREE
    4419     32431419 :       && POINTER_TYPE_P (type))
    4420              :     {
    4421     16309345 :       *punsignedp = POINTERS_EXTEND_UNSIGNED;
    4422     16309345 :       return word_mode;
    4423              :     }
    4424     16157490 :   return default_promote_function_mode (type, mode, punsignedp, fntype,
    4425     16157490 :                                         for_return);
    4426              : }
    4427              : 
    4428              : /* Return true if a structure, union or array with MODE containing FIELD
    4429              :    should be accessed using BLKmode.  */
    4430              : 
    4431              : static bool
    4432    148950777 : ix86_member_type_forces_blk (const_tree field, machine_mode mode)
    4433              : {
    4434              :   /* Union with XFmode must be in BLKmode.  */
    4435    148950777 :   return (mode == XFmode
    4436    149125996 :           && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
    4437       133897 :               || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
    4438              : }
    4439              : 
    4440              : rtx
    4441       109645 : ix86_libcall_value (machine_mode mode)
    4442              : {
    4443       109645 :   return ix86_function_value_1 (NULL, NULL, mode, mode);
    4444              : }
    4445              : 
    4446              : /* Return true iff type is returned in memory.  */
    4447              : 
    4448              : static bool
    4449    107347409 : ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
    4450              : {
    4451    107347409 :   const machine_mode mode = type_natural_mode (type, NULL, true);
    4452    107347409 :   HOST_WIDE_INT size;
    4453              : 
    4454    107347409 :   if (TARGET_64BIT)
    4455              :     {
    4456    102777472 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    4457              :         {
    4458       724001 :           size = int_size_in_bytes (type);
    4459              : 
    4460              :           /* __m128 is returned in xmm0.  256/512-bit vector values are
    4461              :              returned in ymm0/zmm0 when AVX/AVX512 is enabled.  */
    4462       724001 :           if ((!type || VECTOR_INTEGER_TYPE_P (type)
    4463       704430 :                || VECTOR_FLOAT_TYPE_P (type))
    4464        35399 :               && VECTOR_MODE_P (mode)
    4465              :               && !COMPLEX_MODE_P (mode)
    4466       759400 :               && ((GET_MODE_SIZE (mode) == 16 || size == 16)
    4467        42804 :                   || (TARGET_AVX && (GET_MODE_SIZE (mode) == 32 || size == 32))
    4468        11658 :                   || (TARGET_AVX512F
    4469        11154 :                       && (GET_MODE_SIZE (mode) == 64 || size == 64))))
    4470              :             return false;
    4471              : 
    4472              :           /* Otherwise, the size must be exactly in [1248]. */
    4473      1363112 :           return size != 1 && size != 2 && size != 4 && size != 8;
    4474              :         }
    4475              :       else
    4476              :         {
    4477    102053471 :           int needed_intregs, needed_sseregs;
    4478              : 
    4479    102053471 :           return examine_argument (mode, type, true,
    4480              :                                    &needed_intregs, &needed_sseregs);
    4481              :         }
    4482              :     }
    4483              :   else
    4484              :     {
    4485      4569937 :       size = int_size_in_bytes (type);
    4486              : 
    4487              :       /* Intel MCU psABI returns scalars and aggregates no larger than 8
    4488              :          bytes in registers.  */
    4489      4569937 :       if (TARGET_IAMCU)
    4490            0 :         return VECTOR_MODE_P (mode) || size < 0 || size > 8;
    4491              : 
    4492      4569937 :       if (mode == BLKmode)
    4493              :         return true;
    4494              : 
    4495      4569937 :       if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
    4496              :         return false;
    4497              : 
    4498      4569937 :       if (VECTOR_MODE_P (mode) || mode == TImode)
    4499              :         {
    4500              :           /* User-created vectors small enough to fit in EAX.  */
    4501       268055 :           if (size < 8)
    4502              :             return false;
    4503              : 
    4504              :           /* Unless ABI prescribes otherwise,
    4505              :              MMX/3dNow values are returned in MM0 if available.  */
    4506              : 
    4507       268055 :           if (size == 8)
    4508         9266 :             return TARGET_VECT8_RETURNS || !TARGET_MMX;
    4509              : 
    4510              :           /* SSE values are returned in XMM0 if available.  */
    4511       258789 :           if (size == 16)
    4512       108939 :             return !TARGET_SSE;
    4513              : 
    4514              :           /* AVX values are returned in YMM0 if available.  */
    4515       149850 :           if (size == 32)
    4516        72090 :             return !TARGET_AVX;
    4517              : 
    4518              :           /* AVX512F values are returned in ZMM0 if available.  */
    4519        77760 :           if (size == 64)
    4520        77760 :             return !TARGET_AVX512F;
    4521              :         }
    4522              : 
    4523      4301882 :       if (mode == XFmode)
    4524              :         return false;
    4525              : 
    4526      4289802 :       if (size > 12)
    4527              :         return true;
    4528              : 
    4529              :       /* OImode shouldn't be used directly.  */
    4530      3294748 :       gcc_assert (mode != OImode);
    4531              : 
    4532              :       return false;
    4533              :     }
    4534              : }
    4535              : 
    4536              : /* Implement TARGET_PUSH_ARGUMENT.  */
    4537              : 
    4538              : static bool
    4539      9397485 : ix86_push_argument (unsigned int npush)
    4540              : {
    4541              :   /* If SSE2 is available, use vector move to put large argument onto
    4542              :      stack.  NB:  In 32-bit mode, use 8-byte vector move.  */
    4543     11823956 :   return ((!TARGET_SSE2 || npush < (TARGET_64BIT ? 16 : 8))
    4544      9132092 :           && TARGET_PUSH_ARGS
    4545     18529419 :           && !ACCUMULATE_OUTGOING_ARGS);
    4546              : }
    4547              : 
    4548              : 
    4549              : /* Create the va_list data type.  */
    4550              : 
    4551              : static tree
    4552       286366 : ix86_build_builtin_va_list_64 (void)
    4553              : {
    4554       286366 :   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
    4555              : 
    4556       286366 :   record = lang_hooks.types.make_type (RECORD_TYPE);
    4557       286366 :   type_decl = build_decl (BUILTINS_LOCATION,
    4558              :                           TYPE_DECL, get_identifier ("__va_list_tag"), record);
    4559              : 
    4560       286366 :   f_gpr = build_decl (BUILTINS_LOCATION,
    4561              :                       FIELD_DECL, get_identifier ("gp_offset"),
    4562              :                       unsigned_type_node);
    4563       286366 :   f_fpr = build_decl (BUILTINS_LOCATION,
    4564              :                       FIELD_DECL, get_identifier ("fp_offset"),
    4565              :                       unsigned_type_node);
    4566       286366 :   f_ovf = build_decl (BUILTINS_LOCATION,
    4567              :                       FIELD_DECL, get_identifier ("overflow_arg_area"),
    4568              :                       ptr_type_node);
    4569       286366 :   f_sav = build_decl (BUILTINS_LOCATION,
    4570              :                       FIELD_DECL, get_identifier ("reg_save_area"),
    4571              :                       ptr_type_node);
    4572              : 
    4573       286366 :   va_list_gpr_counter_field = f_gpr;
    4574       286366 :   va_list_fpr_counter_field = f_fpr;
    4575              : 
    4576       286366 :   DECL_FIELD_CONTEXT (f_gpr) = record;
    4577       286366 :   DECL_FIELD_CONTEXT (f_fpr) = record;
    4578       286366 :   DECL_FIELD_CONTEXT (f_ovf) = record;
    4579       286366 :   DECL_FIELD_CONTEXT (f_sav) = record;
    4580              : 
    4581       286366 :   TYPE_STUB_DECL (record) = type_decl;
    4582       286366 :   TYPE_NAME (record) = type_decl;
    4583       286366 :   TYPE_FIELDS (record) = f_gpr;
    4584       286366 :   DECL_CHAIN (f_gpr) = f_fpr;
    4585       286366 :   DECL_CHAIN (f_fpr) = f_ovf;
    4586       286366 :   DECL_CHAIN (f_ovf) = f_sav;
    4587       286366 :   TREE_PUBLIC (type_decl) = 1;
    4588              : 
    4589       286366 :   layout_type (record);
    4590              : 
    4591       286366 :   TYPE_ATTRIBUTES (record) = tree_cons (get_identifier ("sysv_abi va_list"),
    4592       286366 :                                         NULL_TREE, TYPE_ATTRIBUTES (record));
    4593              : 
    4594              :   /* The correct type is an array type of one element.  */
    4595       286366 :   return build_array_type (record, build_index_type (size_zero_node));
    4596              : }
    4597              : 
    4598              : /* Setup the builtin va_list data type and for 64-bit the additional
    4599              :    calling convention specific va_list data types.  */
    4600              : 
    4601              : static tree
    4602       293528 : ix86_build_builtin_va_list (void)
    4603              : {
    4604       293528 :   if (TARGET_64BIT)
    4605              :     {
    4606              :       /* Initialize ABI specific va_list builtin types.
    4607              : 
    4608              :          In lto1, we can encounter two va_list types:
    4609              :          - one as a result of the type-merge across TUs, and
    4610              :          - the one constructed here.
    4611              :          These two types will not have the same TYPE_MAIN_VARIANT, and therefore
    4612              :          a type identity check in canonical_va_list_type based on
    4613              :          TYPE_MAIN_VARIANT (which we used to have) will not work.
    4614              :          Instead, we tag each va_list_type_node with its unique attribute, and
    4615              :          look for the attribute in the type identity check in
    4616              :          canonical_va_list_type.
    4617              : 
    4618              :          Tagging sysv_va_list_type_node directly with the attribute is
    4619              :          problematic since it's a array of one record, which will degrade into a
    4620              :          pointer to record when used as parameter (see build_va_arg comments for
    4621              :          an example), dropping the attribute in the process.  So we tag the
    4622              :          record instead.  */
    4623              : 
    4624              :       /* For SYSV_ABI we use an array of one record.  */
    4625       286366 :       sysv_va_list_type_node = ix86_build_builtin_va_list_64 ();
    4626              : 
    4627              :       /* For MS_ABI we use plain pointer to argument area.  */
    4628       286366 :       tree char_ptr_type = build_pointer_type (char_type_node);
    4629       286366 :       tree attr = tree_cons (get_identifier ("ms_abi va_list"), NULL_TREE,
    4630       286366 :                              TYPE_ATTRIBUTES (char_ptr_type));
    4631       286366 :       ms_va_list_type_node = build_type_attribute_variant (char_ptr_type, attr);
    4632              : 
    4633       286366 :       return ((ix86_abi == MS_ABI)
    4634       286366 :               ? ms_va_list_type_node
    4635       286366 :               : sysv_va_list_type_node);
    4636              :     }
    4637              :   else
    4638              :     {
    4639              :       /* For i386 we use plain pointer to argument area.  */
    4640         7162 :       return build_pointer_type (char_type_node);
    4641              :     }
    4642              : }
    4643              : 
    4644              : /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
    4645              : 
    4646              : static void
    4647        15776 : setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
    4648              : {
    4649        15776 :   rtx save_area, mem;
    4650        15776 :   alias_set_type set;
    4651        15776 :   int i, max;
    4652              : 
    4653              :   /* GPR size of varargs save area.  */
    4654        15776 :   if (cfun->va_list_gpr_size)
    4655        15313 :     ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
    4656              :   else
    4657          463 :     ix86_varargs_gpr_size = 0;
    4658              : 
    4659              :   /* FPR size of varargs save area.  We don't need it if we don't pass
    4660              :      anything in SSE registers.  */
    4661        15776 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4662        14712 :     ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
    4663              :   else
    4664         1064 :     ix86_varargs_fpr_size = 0;
    4665              : 
    4666        15776 :   if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
    4667              :     return;
    4668              : 
    4669        15482 :   save_area = frame_pointer_rtx;
    4670        15482 :   set = get_varargs_alias_set ();
    4671              : 
    4672        15482 :   max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
    4673        15482 :   if (max > X86_64_REGPARM_MAX)
    4674              :     max = X86_64_REGPARM_MAX;
    4675              : 
    4676        15482 :   const int *parm_regs;
    4677        15482 :   if (cum->preserve_none_abi)
    4678              :     parm_regs = x86_64_preserve_none_int_parameter_registers;
    4679              :   else
    4680        15480 :     parm_regs = x86_64_int_parameter_registers;
    4681              : 
    4682        86004 :   for (i = cum->regno; i < max; i++)
    4683              :     {
    4684        70522 :       mem = gen_rtx_MEM (word_mode,
    4685        70522 :                          plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
    4686        70522 :       MEM_NOTRAP_P (mem) = 1;
    4687        70522 :       set_mem_alias_set (mem, set);
    4688        70522 :       emit_move_insn (mem,
    4689        70522 :                       gen_rtx_REG (word_mode, parm_regs[i]));
    4690              :     }
    4691              : 
    4692        15482 :   if (ix86_varargs_fpr_size)
    4693              :     {
    4694        14712 :       machine_mode smode;
    4695        14712 :       rtx_code_label *label;
    4696        14712 :       rtx test;
    4697              : 
    4698              :       /* Now emit code to save SSE registers.  The AX parameter contains number
    4699              :          of SSE parameter registers used to call this function, though all we
    4700              :          actually check here is the zero/non-zero status.  */
    4701              : 
    4702        14712 :       label = gen_label_rtx ();
    4703        14712 :       test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
    4704        14712 :       emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
    4705              :                                       label));
    4706              : 
    4707              :       /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
    4708              :          we used movdqa (i.e. TImode) instead?  Perhaps even better would
    4709              :          be if we could determine the real mode of the data, via a hook
    4710              :          into pass_stdarg.  Ignore all that for now.  */
    4711        14712 :       smode = V4SFmode;
    4712        14712 :       if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
    4713         4207 :         crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
    4714              : 
    4715        14712 :       max = cum->sse_regno + cfun->va_list_fpr_size / 16;
    4716        14712 :       if (max > X86_64_SSE_REGPARM_MAX)
    4717              :         max = X86_64_SSE_REGPARM_MAX;
    4718              : 
    4719       130784 :       for (i = cum->sse_regno; i < max; ++i)
    4720              :         {
    4721       116072 :           mem = plus_constant (Pmode, save_area,
    4722       116072 :                                i * 16 + ix86_varargs_gpr_size);
    4723       116072 :           mem = gen_rtx_MEM (smode, mem);
    4724       116072 :           MEM_NOTRAP_P (mem) = 1;
    4725       116072 :           set_mem_alias_set (mem, set);
    4726       116072 :           set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
    4727              : 
    4728       116072 :           emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
    4729              :         }
    4730              : 
    4731        14712 :       emit_label (label);
    4732              :     }
    4733              : }
    4734              : 
    4735              : static void
    4736         5656 : setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
    4737              : {
    4738         5656 :   alias_set_type set = get_varargs_alias_set ();
    4739         5656 :   int i;
    4740              : 
    4741              :   /* Reset to zero, as there might be a sysv vaarg used
    4742              :      before.  */
    4743         5656 :   ix86_varargs_gpr_size = 0;
    4744         5656 :   ix86_varargs_fpr_size = 0;
    4745              : 
    4746        14170 :   for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
    4747              :     {
    4748         8514 :       rtx reg, mem;
    4749              : 
    4750         8514 :       mem = gen_rtx_MEM (Pmode,
    4751         8514 :                          plus_constant (Pmode, virtual_incoming_args_rtx,
    4752         8514 :                                         i * UNITS_PER_WORD));
    4753         8514 :       MEM_NOTRAP_P (mem) = 1;
    4754         8514 :       set_mem_alias_set (mem, set);
    4755              : 
    4756         8514 :       reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
    4757         8514 :       emit_move_insn (mem, reg);
    4758              :     }
    4759         5656 : }
    4760              : 
    4761              : static void
    4762        21586 : ix86_setup_incoming_varargs (cumulative_args_t cum_v,
    4763              :                              const function_arg_info &arg,
    4764              :                              int *, int no_rtl)
    4765              : {
    4766        21586 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    4767        21586 :   CUMULATIVE_ARGS next_cum;
    4768        21586 :   tree fntype;
    4769              : 
    4770              :   /* This argument doesn't appear to be used anymore.  Which is good,
    4771              :      because the old code here didn't suppress rtl generation.  */
    4772        21586 :   gcc_assert (!no_rtl);
    4773              : 
    4774        21586 :   if (!TARGET_64BIT)
    4775          154 :     return;
    4776              : 
    4777        21432 :   fntype = TREE_TYPE (current_function_decl);
    4778              : 
    4779              :   /* For varargs, we do not want to skip the dummy va_dcl argument.
    4780              :      For stdargs, we do want to skip the last named argument.  */
    4781        21432 :   next_cum = *cum;
    4782        21432 :   if ((!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
    4783          151 :        || arg.type != NULL_TREE)
    4784        21469 :       && stdarg_p (fntype))
    4785        21318 :     ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
    4786              : 
    4787        21432 :   if (cum->call_abi == MS_ABI)
    4788         5656 :     setup_incoming_varargs_ms_64 (&next_cum);
    4789              :   else
    4790        15776 :     setup_incoming_varargs_64 (&next_cum);
    4791              : }
    4792              : 
    4793              : /* Checks if TYPE is of kind va_list char *.  */
    4794              : 
    4795              : static bool
    4796        73370 : is_va_list_char_pointer (tree type)
    4797              : {
    4798        73370 :   tree canonic;
    4799              : 
    4800              :   /* For 32-bit it is always true.  */
    4801        73370 :   if (!TARGET_64BIT)
    4802              :     return true;
    4803        73208 :   canonic = ix86_canonical_va_list_type (type);
    4804        73208 :   return (canonic == ms_va_list_type_node
    4805        73208 :           || (ix86_abi == MS_ABI && canonic == va_list_type_node));
    4806              : }
    4807              : 
    4808              : /* Implement va_start.  */
    4809              : 
    4810              : static void
    4811        21074 : ix86_va_start (tree valist, rtx nextarg)
    4812              : {
    4813        21074 :   HOST_WIDE_INT words, n_gpr, n_fpr;
    4814        21074 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4815        21074 :   tree gpr, fpr, ovf, sav, t;
    4816        21074 :   tree type;
    4817        21074 :   rtx ovf_rtx;
    4818              : 
    4819        21074 :   if (flag_split_stack
    4820           12 :       && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4821              :     {
    4822           12 :       unsigned int scratch_regno;
    4823              : 
    4824              :       /* When we are splitting the stack, we can't refer to the stack
    4825              :          arguments using internal_arg_pointer, because they may be on
    4826              :          the old stack.  The split stack prologue will arrange to
    4827              :          leave a pointer to the old stack arguments in a scratch
    4828              :          register, which we here copy to a pseudo-register.  The split
    4829              :          stack prologue can't set the pseudo-register directly because
    4830              :          it (the prologue) runs before any registers have been saved.  */
    4831              : 
    4832           12 :       scratch_regno = split_stack_prologue_scratch_regno ();
    4833           12 :       if (scratch_regno != INVALID_REGNUM)
    4834              :         {
    4835           12 :           rtx reg;
    4836           12 :           rtx_insn *seq;
    4837              : 
    4838           16 :           reg = gen_reg_rtx (Pmode);
    4839           12 :           cfun->machine->split_stack_varargs_pointer = reg;
    4840              : 
    4841           12 :           start_sequence ();
    4842           16 :           emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
    4843           12 :           seq = end_sequence ();
    4844              : 
    4845           12 :           push_topmost_sequence ();
    4846           12 :           emit_insn_after (seq, entry_of_function ());
    4847           12 :           pop_topmost_sequence ();
    4848              :         }
    4849              :     }
    4850              : 
    4851              :   /* Only 64bit target needs something special.  */
    4852        21074 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4853              :     {
    4854         5660 :       if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4855         5656 :         std_expand_builtin_va_start (valist, nextarg);
    4856              :       else
    4857              :         {
    4858            4 :           rtx va_r, next;
    4859              : 
    4860            4 :           va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
    4861            8 :           next = expand_binop (ptr_mode, add_optab,
    4862            4 :                                cfun->machine->split_stack_varargs_pointer,
    4863              :                                crtl->args.arg_offset_rtx,
    4864              :                                NULL_RTX, 0, OPTAB_LIB_WIDEN);
    4865            4 :           convert_move (va_r, next, 0);
    4866              :         }
    4867         5660 :       return;
    4868              :     }
    4869              : 
    4870        15414 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4871        15414 :   f_fpr = DECL_CHAIN (f_gpr);
    4872        15414 :   f_ovf = DECL_CHAIN (f_fpr);
    4873        15414 :   f_sav = DECL_CHAIN (f_ovf);
    4874              : 
    4875        15414 :   valist = build_simple_mem_ref (valist);
    4876        15414 :   TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
    4877              :   /* The following should be folded into the MEM_REF offset.  */
    4878        15414 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
    4879              :                 f_gpr, NULL_TREE);
    4880        15414 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
    4881              :                 f_fpr, NULL_TREE);
    4882        15414 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
    4883              :                 f_ovf, NULL_TREE);
    4884        15414 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
    4885              :                 f_sav, NULL_TREE);
    4886              : 
    4887              :   /* Count number of gp and fp argument registers used.  */
    4888        15414 :   words = crtl->args.info.words;
    4889        15414 :   n_gpr = crtl->args.info.regno;
    4890        15414 :   n_fpr = crtl->args.info.sse_regno;
    4891              : 
    4892        15414 :   if (cfun->va_list_gpr_size)
    4893              :     {
    4894        15167 :       type = TREE_TYPE (gpr);
    4895        15167 :       t = build2 (MODIFY_EXPR, type,
    4896        15167 :                   gpr, build_int_cst (type, n_gpr * 8));
    4897        15167 :       TREE_SIDE_EFFECTS (t) = 1;
    4898        15167 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4899              :     }
    4900              : 
    4901        15414 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4902              :     {
    4903        14554 :       type = TREE_TYPE (fpr);
    4904        14554 :       t = build2 (MODIFY_EXPR, type, fpr,
    4905        14554 :                   build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
    4906        14554 :       TREE_SIDE_EFFECTS (t) = 1;
    4907        14554 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4908              :     }
    4909              : 
    4910              :   /* Find the overflow area.  */
    4911        15414 :   type = TREE_TYPE (ovf);
    4912        15414 :   if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4913        15406 :     ovf_rtx = crtl->args.internal_arg_pointer;
    4914              :   else
    4915              :     ovf_rtx = cfun->machine->split_stack_varargs_pointer;
    4916        15414 :   t = make_tree (type, ovf_rtx);
    4917        15414 :   if (words != 0)
    4918          492 :     t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
    4919              : 
    4920        15414 :   t = build2 (MODIFY_EXPR, type, ovf, t);
    4921        15414 :   TREE_SIDE_EFFECTS (t) = 1;
    4922        15414 :   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4923              : 
    4924        15414 :   if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
    4925              :     {
    4926              :       /* Find the register save area.
    4927              :          Prologue of the function save it right above stack frame.  */
    4928        15336 :       type = TREE_TYPE (sav);
    4929        15336 :       t = make_tree (type, frame_pointer_rtx);
    4930        15336 :       if (!ix86_varargs_gpr_size)
    4931          169 :         t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
    4932              : 
    4933        15336 :       t = build2 (MODIFY_EXPR, type, sav, t);
    4934        15336 :       TREE_SIDE_EFFECTS (t) = 1;
    4935        15336 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4936              :     }
    4937              : }
    4938              : 
    4939              : /* Implement va_arg.  */
    4940              : 
    4941              : static tree
    4942        52296 : ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
    4943              :                       gimple_seq *post_p)
    4944              : {
    4945        52296 :   static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
    4946        52296 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4947        52296 :   tree gpr, fpr, ovf, sav, t;
    4948        52296 :   int size, rsize;
    4949        52296 :   tree lab_false, lab_over = NULL_TREE;
    4950        52296 :   tree addr, t2;
    4951        52296 :   rtx container;
    4952        52296 :   int indirect_p = 0;
    4953        52296 :   tree ptrtype;
    4954        52296 :   machine_mode nat_mode;
    4955        52296 :   unsigned int arg_boundary;
    4956        52296 :   unsigned int type_align;
    4957              : 
    4958              :   /* Only 64bit target needs something special.  */
    4959        52296 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4960          260 :     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
    4961              : 
    4962        52036 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4963        52036 :   f_fpr = DECL_CHAIN (f_gpr);
    4964        52036 :   f_ovf = DECL_CHAIN (f_fpr);
    4965        52036 :   f_sav = DECL_CHAIN (f_ovf);
    4966              : 
    4967        52036 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
    4968              :                 valist, f_gpr, NULL_TREE);
    4969              : 
    4970        52036 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
    4971        52036 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
    4972        52036 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
    4973              : 
    4974        52036 :   indirect_p = pass_va_arg_by_reference (type);
    4975        52036 :   if (indirect_p)
    4976          103 :     type = build_pointer_type (type);
    4977        52036 :   size = arg_int_size_in_bytes (type);
    4978        52036 :   rsize = CEIL (size, UNITS_PER_WORD);
    4979              : 
    4980        52036 :   nat_mode = type_natural_mode (type, NULL, false);
    4981        52036 :   switch (nat_mode)
    4982              :     {
    4983           28 :     case E_V16HFmode:
    4984           28 :     case E_V16BFmode:
    4985           28 :     case E_V8SFmode:
    4986           28 :     case E_V8SImode:
    4987           28 :     case E_V32QImode:
    4988           28 :     case E_V16HImode:
    4989           28 :     case E_V4DFmode:
    4990           28 :     case E_V4DImode:
    4991           28 :     case E_V32HFmode:
    4992           28 :     case E_V32BFmode:
    4993           28 :     case E_V16SFmode:
    4994           28 :     case E_V16SImode:
    4995           28 :     case E_V64QImode:
    4996           28 :     case E_V32HImode:
    4997           28 :     case E_V8DFmode:
    4998           28 :     case E_V8DImode:
    4999              :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    5000           28 :       if (!TARGET_64BIT_MS_ABI)
    5001              :         {
    5002              :           container = NULL;
    5003              :           break;
    5004              :         }
    5005              :       /* FALLTHRU */
    5006              : 
    5007        52008 :     default:
    5008        52008 :       container = construct_container (nat_mode, TYPE_MODE (type),
    5009              :                                        type, false, X86_64_REGPARM_MAX,
    5010              :                                        X86_64_SSE_REGPARM_MAX, intreg, 0);
    5011        52008 :       break;
    5012              :     }
    5013              : 
    5014              :   /* Pull the value out of the saved registers.  */
    5015              : 
    5016        52036 :   addr = create_tmp_var (ptr_type_node, "addr");
    5017        52036 :   type_align = TYPE_ALIGN (type);
    5018              : 
    5019        52036 :   if (container)
    5020              :     {
    5021        28943 :       int needed_intregs, needed_sseregs;
    5022        28943 :       bool need_temp;
    5023        28943 :       tree int_addr, sse_addr;
    5024              : 
    5025        28943 :       lab_false = create_artificial_label (UNKNOWN_LOCATION);
    5026        28943 :       lab_over = create_artificial_label (UNKNOWN_LOCATION);
    5027              : 
    5028        28943 :       examine_argument (nat_mode, type, false,
    5029              :                         &needed_intregs, &needed_sseregs);
    5030              : 
    5031        28943 :       bool container_in_reg = false;
    5032        28943 :       if (REG_P (container))
    5033              :         container_in_reg = true;
    5034         1641 :       else if (GET_CODE (container) == PARALLEL
    5035         1641 :                && GET_MODE (container) == BLKmode
    5036          580 :                && XVECLEN (container, 0) == 1)
    5037              :         {
    5038              :           /* Check if it is a PARALLEL BLKmode container of an EXPR_LIST
    5039              :              expression in a TImode register.  In this case, temp isn't
    5040              :              needed.  Otherwise, the TImode variable will be put in the
    5041              :              GPR save area which guarantees only 8-byte alignment.   */
    5042          509 :           rtx x = XVECEXP (container, 0, 0);
    5043          509 :           if (GET_CODE (x) == EXPR_LIST
    5044          509 :               && REG_P (XEXP (x, 0))
    5045          509 :               && XEXP (x, 1) == const0_rtx)
    5046              :             container_in_reg = true;
    5047              :         }
    5048              : 
    5049          680 :       need_temp = (!container_in_reg
    5050         1150 :                    && ((needed_intregs && TYPE_ALIGN (type) > 64)
    5051          680 :                        || TYPE_ALIGN (type) > 128));
    5052              : 
    5053              :       /* In case we are passing structure, verify that it is consecutive block
    5054              :          on the register save area.  If not we need to do moves.  */
    5055          680 :       if (!need_temp && !container_in_reg)
    5056              :         {
    5057              :           /* Verify that all registers are strictly consecutive  */
    5058          966 :           if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
    5059              :             {
    5060              :               int i;
    5061              : 
    5062          815 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    5063              :                 {
    5064          529 :                   rtx slot = XVECEXP (container, 0, i);
    5065          529 :                   if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
    5066          529 :                       || INTVAL (XEXP (slot, 1)) != i * 16)
    5067              :                     need_temp = true;
    5068              :                 }
    5069              :             }
    5070              :           else
    5071              :             {
    5072              :               int i;
    5073              : 
    5074         1120 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    5075              :                 {
    5076          726 :                   rtx slot = XVECEXP (container, 0, i);
    5077          726 :                   if (REGNO (XEXP (slot, 0)) != (unsigned int) i
    5078          726 :                       || INTVAL (XEXP (slot, 1)) != i * 8)
    5079              :                     need_temp = true;
    5080              :                 }
    5081              :             }
    5082              :         }
    5083        28943 :       if (!need_temp)
    5084              :         {
    5085              :           int_addr = addr;
    5086              :           sse_addr = addr;
    5087              :         }
    5088              :       else
    5089              :         {
    5090          877 :           int_addr = create_tmp_var (ptr_type_node, "int_addr");
    5091          877 :           sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
    5092              :         }
    5093              : 
    5094              :       /* First ensure that we fit completely in registers.  */
    5095        28943 :       if (needed_intregs)
    5096              :         {
    5097        18177 :           t = build_int_cst (TREE_TYPE (gpr),
    5098        18177 :                              (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
    5099        18177 :           t = build2 (GE_EXPR, boolean_type_node, gpr, t);
    5100        18177 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    5101        18177 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    5102        18177 :           gimplify_and_add (t, pre_p);
    5103              :         }
    5104        28943 :       if (needed_sseregs)
    5105              :         {
    5106        11158 :           t = build_int_cst (TREE_TYPE (fpr),
    5107              :                              (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
    5108        11158 :                              + X86_64_REGPARM_MAX * 8);
    5109        11158 :           t = build2 (GE_EXPR, boolean_type_node, fpr, t);
    5110        11158 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    5111        11158 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    5112        11158 :           gimplify_and_add (t, pre_p);
    5113              :         }
    5114              : 
    5115              :       /* Compute index to start of area used for integer regs.  */
    5116        28943 :       if (needed_intregs)
    5117              :         {
    5118              :           /* int_addr = gpr + sav; */
    5119        18177 :           t = fold_build_pointer_plus (sav, gpr);
    5120        18177 :           gimplify_assign (int_addr, t, pre_p);
    5121              :         }
    5122        28943 :       if (needed_sseregs)
    5123              :         {
    5124              :           /* sse_addr = fpr + sav; */
    5125        11158 :           t = fold_build_pointer_plus (sav, fpr);
    5126        11158 :           gimplify_assign (sse_addr, t, pre_p);
    5127              :         }
    5128        28943 :       if (need_temp)
    5129              :         {
    5130          877 :           int i, prev_size = 0;
    5131          877 :           tree temp = create_tmp_var (type, "va_arg_tmp");
    5132          877 :           TREE_ADDRESSABLE (temp) = 1;
    5133              : 
    5134              :           /* addr = &temp; */
    5135          877 :           t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
    5136          877 :           gimplify_assign (addr, t, pre_p);
    5137              : 
    5138         2241 :           for (i = 0; i < XVECLEN (container, 0); i++)
    5139              :             {
    5140         1364 :               rtx slot = XVECEXP (container, 0, i);
    5141         1364 :               rtx reg = XEXP (slot, 0);
    5142         1364 :               machine_mode mode = GET_MODE (reg);
    5143         1364 :               tree piece_type;
    5144         1364 :               tree addr_type;
    5145         1364 :               tree daddr_type;
    5146         1364 :               tree src_addr, src;
    5147         1364 :               int src_offset;
    5148         1364 :               tree dest_addr, dest;
    5149         1364 :               int cur_size = GET_MODE_SIZE (mode);
    5150              : 
    5151         1364 :               gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
    5152         1364 :               prev_size = INTVAL (XEXP (slot, 1));
    5153         1364 :               if (prev_size + cur_size > size)
    5154              :                 {
    5155           30 :                   cur_size = size - prev_size;
    5156           30 :                   unsigned int nbits = cur_size * BITS_PER_UNIT;
    5157           30 :                   if (!int_mode_for_size (nbits, 1).exists (&mode))
    5158           10 :                     mode = QImode;
    5159              :                 }
    5160         1364 :               piece_type = lang_hooks.types.type_for_mode (mode, 1);
    5161         1364 :               if (mode == GET_MODE (reg))
    5162         1334 :                 addr_type = build_pointer_type (piece_type);
    5163              :               else
    5164           30 :                 addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5165              :                                                          true);
    5166         1364 :               daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5167              :                                                         true);
    5168              : 
    5169         1364 :               if (SSE_REGNO_P (REGNO (reg)))
    5170              :                 {
    5171          534 :                   src_addr = sse_addr;
    5172          534 :                   src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
    5173              :                 }
    5174              :               else
    5175              :                 {
    5176          830 :                   src_addr = int_addr;
    5177          830 :                   src_offset = REGNO (reg) * 8;
    5178              :                 }
    5179         1364 :               src_addr = fold_convert (addr_type, src_addr);
    5180         1364 :               src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
    5181              : 
    5182         1364 :               dest_addr = fold_convert (daddr_type, addr);
    5183         1364 :               dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
    5184         2728 :               if (cur_size == GET_MODE_SIZE (mode))
    5185              :                 {
    5186         1354 :                   src = build_va_arg_indirect_ref (src_addr);
    5187         1354 :                   dest = build_va_arg_indirect_ref (dest_addr);
    5188              : 
    5189         1354 :                   gimplify_assign (dest, src, pre_p);
    5190              :                 }
    5191              :               else
    5192              :                 {
    5193           10 :                   tree copy
    5194           20 :                     = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
    5195              :                                        3, dest_addr, src_addr,
    5196           10 :                                        size_int (cur_size));
    5197           10 :                   gimplify_and_add (copy, pre_p);
    5198              :                 }
    5199         1364 :               prev_size += cur_size;
    5200              :             }
    5201              :         }
    5202              : 
    5203        28943 :       if (needed_intregs)
    5204              :         {
    5205        18177 :           t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
    5206        18177 :                       build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
    5207        18177 :           gimplify_assign (gpr, t, pre_p);
    5208              :           /* The GPR save area guarantees only 8-byte alignment.  */
    5209        18177 :           if (!need_temp)
    5210        17373 :             type_align = MIN (type_align, 64);
    5211              :         }
    5212              : 
    5213        28943 :       if (needed_sseregs)
    5214              :         {
    5215        11158 :           t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
    5216        11158 :                       build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
    5217        11158 :           gimplify_assign (unshare_expr (fpr), t, pre_p);
    5218              :         }
    5219              : 
    5220        28943 :       gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
    5221              : 
    5222        28943 :       gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
    5223              :     }
    5224              : 
    5225              :   /* ... otherwise out of the overflow area.  */
    5226              : 
    5227              :   /* When we align parameter on stack for caller, if the parameter
    5228              :      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
    5229              :      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
    5230              :      here with caller.  */
    5231        52036 :   arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
    5232        52036 :   if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
    5233              :     arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
    5234              : 
    5235              :   /* Care for on-stack alignment if needed.  */
    5236        52036 :   if (arg_boundary <= 64 || size == 0)
    5237        34996 :     t = ovf;
    5238              :  else
    5239              :     {
    5240        17040 :       HOST_WIDE_INT align = arg_boundary / 8;
    5241        17040 :       t = fold_build_pointer_plus_hwi (ovf, align - 1);
    5242        17040 :       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
    5243        17040 :                   build_int_cst (TREE_TYPE (t), -align));
    5244              :     }
    5245              : 
    5246        52036 :   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
    5247        52036 :   gimplify_assign (addr, t, pre_p);
    5248              : 
    5249        52036 :   t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
    5250        52036 :   gimplify_assign (unshare_expr (ovf), t, pre_p);
    5251              : 
    5252        52036 :   if (container)
    5253        28943 :     gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
    5254              : 
    5255        52036 :   type = build_aligned_type (type, type_align);
    5256        52036 :   ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
    5257        52036 :   addr = fold_convert (ptrtype, addr);
    5258              : 
    5259        52036 :   if (indirect_p)
    5260          103 :     addr = build_va_arg_indirect_ref (addr);
    5261        52036 :   return build_va_arg_indirect_ref (addr);
    5262              : }
    5263              : 
    5264              : /* Return true if OPNUM's MEM should be matched
    5265              :    in movabs* patterns.  */
    5266              : 
    5267              : bool
    5268          480 : ix86_check_movabs (rtx insn, int opnum)
    5269              : {
    5270          480 :   rtx set, mem;
    5271              : 
    5272          480 :   set = PATTERN (insn);
    5273          480 :   if (GET_CODE (set) == PARALLEL)
    5274            0 :     set = XVECEXP (set, 0, 0);
    5275          480 :   gcc_assert (GET_CODE (set) == SET);
    5276          480 :   mem = XEXP (set, opnum);
    5277          480 :   while (SUBREG_P (mem))
    5278            0 :     mem = SUBREG_REG (mem);
    5279          480 :   gcc_assert (MEM_P (mem));
    5280          480 :   return volatile_ok || !MEM_VOLATILE_P (mem);
    5281              : }
    5282              : 
    5283              : /* Return true if XVECEXP idx of INSN satisfies MOVS arguments.  */
    5284              : bool
    5285       224444 : ix86_check_movs (rtx insn, int idx)
    5286              : {
    5287       224444 :   rtx pat = PATTERN (insn);
    5288       224444 :   gcc_assert (GET_CODE (pat) == PARALLEL);
    5289              : 
    5290       224444 :   rtx set = XVECEXP (pat, 0, idx);
    5291       224444 :   gcc_assert (GET_CODE (set) == SET);
    5292              : 
    5293       224444 :   rtx dst = SET_DEST (set);
    5294       224444 :   gcc_assert (MEM_P (dst));
    5295              : 
    5296       224444 :   rtx src = SET_SRC (set);
    5297       224444 :   gcc_assert (MEM_P (src));
    5298              : 
    5299       224444 :   return (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (dst))
    5300       448888 :           && (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (src))
    5301            0 :               || Pmode == word_mode));
    5302              : }
    5303              : 
    5304              : /* Return false if INSN contains a MEM with a non-default address space.  */
    5305              : bool
    5306        65497 : ix86_check_no_addr_space (rtx insn)
    5307              : {
    5308        65497 :   subrtx_var_iterator::array_type array;
    5309      1441386 :   FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), ALL)
    5310              :     {
    5311      1375889 :       rtx x = *iter;
    5312      1506883 :       if (MEM_P (x) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)))
    5313            0 :         return false;
    5314              :     }
    5315        65497 :   return true;
    5316        65497 : }
    5317              : 
    5318              : /* Initialize the table of extra 80387 mathematical constants.  */
    5319              : 
    5320              : static void
    5321         2381 : init_ext_80387_constants (void)
    5322              : {
    5323         2381 :   static const char * cst[5] =
    5324              :   {
    5325              :     "0.3010299956639811952256464283594894482",  /* 0: fldlg2  */
    5326              :     "0.6931471805599453094286904741849753009",  /* 1: fldln2  */
    5327              :     "1.4426950408889634073876517827983434472",  /* 2: fldl2e  */
    5328              :     "3.3219280948873623478083405569094566090",  /* 3: fldl2t  */
    5329              :     "3.1415926535897932385128089594061862044",  /* 4: fldpi   */
    5330              :   };
    5331         2381 :   int i;
    5332              : 
    5333        14286 :   for (i = 0; i < 5; i++)
    5334              :     {
    5335        11905 :       real_from_string (&ext_80387_constants_table[i], cst[i]);
    5336              :       /* Ensure each constant is rounded to XFmode precision.  */
    5337        11905 :       real_convert (&ext_80387_constants_table[i],
    5338        23810 :                     XFmode, &ext_80387_constants_table[i]);
    5339              :     }
    5340              : 
    5341         2381 :   ext_80387_constants_init = 1;
    5342         2381 : }
    5343              : 
    5344              : /* Return non-zero if the constant is something that
    5345              :    can be loaded with a special instruction.  */
    5346              : 
    5347              : int
    5348      4941090 : standard_80387_constant_p (rtx x)
    5349              : {
    5350      4941090 :   machine_mode mode = GET_MODE (x);
    5351              : 
    5352      4941090 :   const REAL_VALUE_TYPE *r;
    5353              : 
    5354      4941090 :   if (!(CONST_DOUBLE_P (x) && X87_FLOAT_MODE_P (mode)))
    5355              :     return -1;
    5356              : 
    5357      4475205 :   if (x == CONST0_RTX (mode))
    5358              :     return 1;
    5359      2023136 :   if (x == CONST1_RTX (mode))
    5360              :     return 2;
    5361              : 
    5362      1226435 :   r = CONST_DOUBLE_REAL_VALUE (x);
    5363              : 
    5364              :   /* For XFmode constants, try to find a special 80387 instruction when
    5365              :      optimizing for size or on those CPUs that benefit from them.  */
    5366      1226435 :   if (mode == XFmode
    5367       791294 :       && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
    5368      2017729 :       && !flag_rounding_math)
    5369              :     {
    5370       783244 :       int i;
    5371              : 
    5372       783244 :       if (! ext_80387_constants_init)
    5373         2374 :         init_ext_80387_constants ();
    5374              : 
    5375      4688090 :       for (i = 0; i < 5; i++)
    5376      3914503 :         if (real_identical (r, &ext_80387_constants_table[i]))
    5377         9657 :           return i + 3;
    5378              :     }
    5379              : 
    5380              :   /* Load of the constant -0.0 or -1.0 will be split as
    5381              :      fldz;fchs or fld1;fchs sequence.  */
    5382      1216778 :   if (real_isnegzero (r))
    5383              :     return 8;
    5384      1200350 :   if (real_identical (r, &dconstm1))
    5385       280185 :     return 9;
    5386              : 
    5387              :   return 0;
    5388              : }
    5389              : 
    5390              : /* Return the opcode of the special instruction to be used to load
    5391              :    the constant X.  */
    5392              : 
    5393              : const char *
    5394        44593 : standard_80387_constant_opcode (rtx x)
    5395              : {
    5396        44593 :   switch (standard_80387_constant_p (x))
    5397              :     {
    5398              :     case 1:
    5399              :       return "fldz";
    5400        24999 :     case 2:
    5401        24999 :       return "fld1";
    5402            1 :     case 3:
    5403            1 :       return "fldlg2";
    5404           10 :     case 4:
    5405           10 :       return "fldln2";
    5406           12 :     case 5:
    5407           12 :       return "fldl2e";
    5408            2 :     case 6:
    5409            2 :       return "fldl2t";
    5410          210 :     case 7:
    5411          210 :       return "fldpi";
    5412            0 :     case 8:
    5413            0 :     case 9:
    5414            0 :       return "#";
    5415            0 :     default:
    5416            0 :       gcc_unreachable ();
    5417              :     }
    5418              : }
    5419              : 
    5420              : /* Return the CONST_DOUBLE representing the 80387 constant that is
    5421              :    loaded by the specified special instruction.  The argument IDX
    5422              :    matches the return value from standard_80387_constant_p.  */
    5423              : 
    5424              : rtx
    5425           24 : standard_80387_constant_rtx (int idx)
    5426              : {
    5427           24 :   int i;
    5428              : 
    5429           24 :   if (! ext_80387_constants_init)
    5430            7 :     init_ext_80387_constants ();
    5431              : 
    5432           24 :   switch (idx)
    5433              :     {
    5434           24 :     case 3:
    5435           24 :     case 4:
    5436           24 :     case 5:
    5437           24 :     case 6:
    5438           24 :     case 7:
    5439           24 :       i = idx - 3;
    5440           24 :       break;
    5441              : 
    5442            0 :     default:
    5443            0 :       gcc_unreachable ();
    5444              :     }
    5445              : 
    5446           24 :   return const_double_from_real_value (ext_80387_constants_table[i],
    5447           24 :                                        XFmode);
    5448              : }
    5449              : 
    5450              : /* Return 1 if X is all bits 0, 2 if X is all bits 1
    5451              :    and 3 if X is all bits 1 with zero extend
    5452              :    in supported SSE/AVX vector mode.  */
    5453              : 
    5454              : int
    5455     56569801 : standard_sse_constant_p (rtx x, machine_mode pred_mode)
    5456              : {
    5457     56569801 :   machine_mode mode;
    5458              : 
    5459     56569801 :   if (!TARGET_SSE)
    5460              :     return 0;
    5461              : 
    5462     56399041 :   mode = GET_MODE (x);
    5463              : 
    5464     56399041 :   if (x == const0_rtx || const0_operand (x, mode))
    5465     13597432 :     return 1;
    5466              : 
    5467     42801609 :   if (x == constm1_rtx
    5468     42661481 :       || vector_all_ones_operand (x, mode)
    5469     84842229 :       || ((GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5470     35140510 :            || GET_MODE_CLASS (pred_mode) == MODE_VECTOR_FLOAT)
    5471      6901151 :           && float_vector_all_ones_operand (x, mode)))
    5472              :     {
    5473              :       /* VOIDmode integer constant, get mode from the predicate.  */
    5474       763078 :       if (mode == VOIDmode)
    5475       140128 :         mode = pred_mode;
    5476              : 
    5477      1526156 :       switch (GET_MODE_SIZE (mode))
    5478              :         {
    5479        30838 :         case 64:
    5480        30838 :           if (TARGET_AVX512F)
    5481              :             return 2;
    5482              :           break;
    5483        40247 :         case 32:
    5484        40247 :           if (TARGET_AVX2)
    5485              :             return 2;
    5486              :           break;
    5487       678631 :         case 16:
    5488       678631 :           if (TARGET_SSE2)
    5489              :             return 2;
    5490              :           break;
    5491            0 :         case 0:
    5492              :           /* VOIDmode */
    5493            0 :           gcc_unreachable ();
    5494              :         default:
    5495              :           break;
    5496              :         }
    5497              :     }
    5498              : 
    5499     42052824 :   if (vector_all_ones_zero_extend_half_operand (x, mode)
    5500     42052824 :       || vector_all_ones_zero_extend_quarter_operand (x, mode))
    5501          706 :     return 3;
    5502              : 
    5503              :   return 0;
    5504              : }
    5505              : 
    5506              : /* Return the opcode of the special instruction to be used to load
    5507              :    the constant operands[1] into operands[0].  */
    5508              : 
    5509              : const char *
    5510       471636 : standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
    5511              : {
    5512       471636 :   machine_mode mode;
    5513       471636 :   rtx x = operands[1];
    5514              : 
    5515       471636 :   gcc_assert (TARGET_SSE);
    5516              : 
    5517       471636 :   mode = GET_MODE (x);
    5518              : 
    5519       471636 :   if (x == const0_rtx || const0_operand (x, mode))
    5520              :     {
    5521       459314 :       switch (get_attr_mode (insn))
    5522              :         {
    5523       441419 :         case MODE_TI:
    5524       441419 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5525              :             return "%vpxor\t%0, %d0";
    5526              :           /* FALLTHRU */
    5527         6196 :         case MODE_XI:
    5528         6196 :         case MODE_OI:
    5529         6196 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5530              :             {
    5531           67 :               if (TARGET_AVX512VL)
    5532              :                 return "vpxord\t%x0, %x0, %x0";
    5533              :               else
    5534           28 :                 return "vpxord\t%g0, %g0, %g0";
    5535              :             }
    5536              :           return "vpxor\t%x0, %x0, %x0";
    5537              : 
    5538         2102 :         case MODE_V2DF:
    5539         2102 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5540              :             return "%vxorpd\t%0, %d0";
    5541              :           /* FALLTHRU */
    5542          847 :         case MODE_V8DF:
    5543          847 :         case MODE_V4DF:
    5544          847 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5545              :             {
    5546            4 :               if (TARGET_AVX512DQ)
    5547              :                 {
    5548            0 :                   if (TARGET_AVX512VL)
    5549              :                     return "vxorpd\t%x0, %x0, %x0";
    5550              :                   else
    5551            0 :                     return "vxorpd\t%g0, %g0, %g0";
    5552              :                 }
    5553              :               else
    5554              :                 {
    5555            4 :                   if (TARGET_AVX512VL)
    5556              :                     return "vpxorq\t%x0, %x0, %x0";
    5557              :                   else
    5558            4 :                     return "vpxorq\t%g0, %g0, %g0";
    5559              :                 }
    5560              :             }
    5561              :           return "vxorpd\t%x0, %x0, %x0";
    5562              : 
    5563         6793 :         case MODE_V4SF:
    5564         6793 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5565              :             return "%vxorps\t%0, %d0";
    5566              :           /* FALLTHRU */
    5567         2021 :         case MODE_V16SF:
    5568         2021 :         case MODE_V8SF:
    5569         2021 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5570              :             {
    5571           70 :               if (TARGET_AVX512DQ)
    5572              :                 {
    5573           26 :                   if (TARGET_AVX512VL)
    5574              :                     return "vxorps\t%x0, %x0, %x0";
    5575              :                   else
    5576            0 :                     return "vxorps\t%g0, %g0, %g0";
    5577              :                 }
    5578              :               else
    5579              :                 {
    5580           44 :                   if (TARGET_AVX512VL)
    5581              :                     return "vpxord\t%x0, %x0, %x0";
    5582              :                   else
    5583           42 :                     return "vpxord\t%g0, %g0, %g0";
    5584              :                 }
    5585              :             }
    5586              :           return "vxorps\t%x0, %x0, %x0";
    5587              : 
    5588            0 :         default:
    5589            0 :           gcc_unreachable ();
    5590              :         }
    5591              :     }
    5592        12322 :   else if (x == constm1_rtx
    5593        12311 :            || vector_all_ones_operand (x, mode)
    5594        12389 :            || (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5595           45 :                && float_vector_all_ones_operand (x, mode)))
    5596              :     {
    5597        12300 :       enum attr_mode insn_mode = get_attr_mode (insn);
    5598              : 
    5599        12300 :       switch (insn_mode)
    5600              :         {
    5601            3 :         case MODE_XI:
    5602            3 :         case MODE_V8DF:
    5603            3 :         case MODE_V16SF:
    5604            3 :           gcc_assert (TARGET_AVX512F);
    5605              :           return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5606              : 
    5607          960 :         case MODE_OI:
    5608          960 :         case MODE_V4DF:
    5609          960 :         case MODE_V8SF:
    5610          960 :           gcc_assert (TARGET_AVX2);
    5611              :           /* FALLTHRU */
    5612        12297 :         case MODE_TI:
    5613        12297 :         case MODE_V2DF:
    5614        12297 :         case MODE_V4SF:
    5615        12297 :           gcc_assert (TARGET_SSE2);
    5616        12297 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5617              :             {
    5618            2 :               if (TARGET_AVX512VL)
    5619              :                 return "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}";
    5620              :               else
    5621            0 :                 return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5622              :             }
    5623        12295 :           return (TARGET_AVX
    5624        12295 :                   ? "vpcmpeqd\t%0, %0, %0"
    5625        12295 :                   : "pcmpeqd\t%0, %0");
    5626              : 
    5627            0 :         default:
    5628            0 :           gcc_unreachable ();
    5629              :         }
    5630              :    }
    5631           22 :   else if (vector_all_ones_zero_extend_half_operand (x, mode))
    5632              :     {
    5633           40 :       if (GET_MODE_SIZE (mode) == 64)
    5634              :         {
    5635            5 :           gcc_assert (TARGET_AVX512F);
    5636              :           return "vpcmpeqd\t%t0, %t0, %t0";
    5637              :         }
    5638           30 :       else if (GET_MODE_SIZE (mode) == 32)
    5639              :         {
    5640           15 :           gcc_assert (TARGET_AVX);
    5641              :           return "vpcmpeqd\t%x0, %x0, %x0";
    5642              :         }
    5643            0 :       gcc_unreachable ();
    5644              :     }
    5645            2 :   else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
    5646              :     {
    5647            2 :       gcc_assert (TARGET_AVX512F);
    5648              :       return "vpcmpeqd\t%x0, %x0, %x0";
    5649              :     }
    5650              : 
    5651            0 :   gcc_unreachable ();
    5652              : }
    5653              : 
    5654              : /* Returns true if INSN can be transformed from a memory load
    5655              :    to a supported FP constant load.  */
    5656              : 
    5657              : bool
    5658      2151324 : ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
    5659              : {
    5660      2151324 :   rtx src = find_constant_src (insn);
    5661              : 
    5662      2151324 :   gcc_assert (REG_P (dst));
    5663              : 
    5664      2151324 :   if (src == NULL
    5665       593132 :       || (SSE_REGNO_P (REGNO (dst))
    5666       468854 :           && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
    5667       158319 :       || (!TARGET_AVX512VL
    5668       158258 :           && EXT_REX_SSE_REGNO_P (REGNO (dst))
    5669            0 :           && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
    5670      2309643 :       || (STACK_REGNO_P (REGNO (dst))
    5671       124278 :            && standard_80387_constant_p (src) < 1))
    5672      2083693 :     return false;
    5673              : 
    5674              :   return true;
    5675              : }
    5676              : 
    5677              : /* Predicate for pre-reload splitters with associated instructions,
    5678              :    which can match any time before the split1 pass (usually combine),
    5679              :    then are unconditionally split in that pass and should not be
    5680              :    matched again afterwards.  */
    5681              : 
    5682              : bool
    5683     18389002 : ix86_pre_reload_split (void)
    5684              : {
    5685     18389002 :   return (can_create_pseudo_p ()
    5686     28161138 :           && !(cfun->curr_properties & PROP_rtl_split_insns));
    5687              : }
    5688              : 
    5689              : /* Return the opcode of the TYPE_SSEMOV instruction.  To move from
    5690              :    or to xmm16-xmm31/ymm16-ymm31 registers, we either require
    5691              :    TARGET_AVX512VL or it is a register to register move which can
    5692              :    be done with zmm register move. */
    5693              : 
    5694              : static const char *
    5695      4111756 : ix86_get_ssemov (rtx *operands, unsigned size,
    5696              :                  enum attr_mode insn_mode, machine_mode mode)
    5697              : {
    5698      4111756 :   char buf[128];
    5699      4111756 :   bool misaligned_p = (misaligned_operand (operands[0], mode)
    5700      4111756 :                        || misaligned_operand (operands[1], mode));
    5701      4111756 :   bool evex_reg_p = (size == 64
    5702      4025080 :                      || EXT_REX_SSE_REG_P (operands[0])
    5703      8136096 :                      || EXT_REX_SSE_REG_P (operands[1]));
    5704              : 
    5705      4111756 :   bool egpr_p = (TARGET_APX_EGPR
    5706      4111756 :                  && (x86_extended_rex2reg_mentioned_p (operands[0])
    5707          181 :                      || x86_extended_rex2reg_mentioned_p (operands[1])));
    5708          197 :   bool egpr_vl = egpr_p && TARGET_AVX512VL;
    5709              : 
    5710      4111756 :   machine_mode scalar_mode;
    5711              : 
    5712      4111756 :   const char *opcode = NULL;
    5713      4111756 :   enum
    5714              :     {
    5715              :       opcode_int,
    5716              :       opcode_float,
    5717              :       opcode_double
    5718      4111756 :     } type = opcode_int;
    5719              : 
    5720      4111756 :   switch (insn_mode)
    5721              :     {
    5722              :     case MODE_V16SF:
    5723              :     case MODE_V8SF:
    5724              :     case MODE_V4SF:
    5725              :       scalar_mode = E_SFmode;
    5726              :       type = opcode_float;
    5727              :       break;
    5728       212602 :     case MODE_V8DF:
    5729       212602 :     case MODE_V4DF:
    5730       212602 :     case MODE_V2DF:
    5731       212602 :       scalar_mode = E_DFmode;
    5732       212602 :       type = opcode_double;
    5733       212602 :       break;
    5734      1474551 :     case MODE_XI:
    5735      1474551 :     case MODE_OI:
    5736      1474551 :     case MODE_TI:
    5737      1474551 :       scalar_mode = GET_MODE_INNER (mode);
    5738              :       break;
    5739            0 :     default:
    5740            0 :       gcc_unreachable ();
    5741              :     }
    5742              : 
    5743              :   /* NB: To move xmm16-xmm31/ymm16-ymm31 registers without AVX512VL,
    5744              :      we can only use zmm register move without memory operand.  */
    5745      4111756 :   if (evex_reg_p
    5746        88724 :       && !TARGET_AVX512VL
    5747      4161791 :       && GET_MODE_SIZE (mode) < 64)
    5748              :     {
    5749              :       /* NB: Even though ix86_hard_regno_mode_ok doesn't allow
    5750              :          xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when
    5751              :          AVX512VL is disabled, LRA can still generate reg to
    5752              :          reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit
    5753              :          modes.  */
    5754            0 :       if (memory_operand (operands[0], mode)
    5755            0 :           || memory_operand (operands[1], mode))
    5756            0 :         gcc_unreachable ();
    5757            0 :       size = 64;
    5758            0 :       switch (type)
    5759              :         {
    5760            0 :         case opcode_int:
    5761            0 :           if (scalar_mode == E_HFmode || scalar_mode == E_BFmode)
    5762            0 :             opcode = (misaligned_p
    5763            0 :                       ? (TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64")
    5764              :                       : "vmovdqa64");
    5765              :           else
    5766            0 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5767              :           break;
    5768            0 :         case opcode_float:
    5769            0 :           opcode = misaligned_p ? "vmovups" : "vmovaps";
    5770              :           break;
    5771            0 :         case opcode_double:
    5772            0 :           opcode = misaligned_p ? "vmovupd" : "vmovapd";
    5773              :           break;
    5774              :         }
    5775              :     }
    5776      4111756 :   else if (SCALAR_FLOAT_MODE_P (scalar_mode))
    5777              :     {
    5778      2814627 :       switch (scalar_mode)
    5779              :         {
    5780        36799 :         case E_HFmode:
    5781        36799 :         case E_BFmode:
    5782        36799 :           if (evex_reg_p || egpr_vl)
    5783        11597 :             opcode = (misaligned_p
    5784          173 :                       ? (TARGET_AVX512BW
    5785              :                          ? "vmovdqu16"
    5786              :                          : "vmovdqu64")
    5787              :                       : "vmovdqa64");
    5788        25202 :           else if (egpr_p)
    5789       735358 :             opcode = (misaligned_p
    5790            0 :                       ? (TARGET_AVX512BW
    5791            0 :                          ? "vmovdqu16"
    5792              :                          : "%vmovups")
    5793              :                       : "%vmovaps");
    5794              :           else
    5795       363381 :             opcode = (misaligned_p
    5796        25202 :                       ? (TARGET_AVX512BW && evex_reg_p
    5797              :                          ? "vmovdqu16"
    5798              :                          : "%vmovdqu")
    5799              :                       : "%vmovdqa");
    5800              :           break;
    5801      2424603 :         case E_SFmode:
    5802      2424603 :           opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5803              :           break;
    5804       212602 :         case E_DFmode:
    5805       212602 :           opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
    5806              :           break;
    5807       140623 :         case E_TFmode:
    5808       140623 :           if (evex_reg_p || egpr_vl)
    5809           14 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5810       140609 :           else if (egpr_p)
    5811            0 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5812              :           else
    5813       140609 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5814              :           break;
    5815            0 :         default:
    5816            0 :           gcc_unreachable ();
    5817              :         }
    5818              :     }
    5819      1297129 :   else if (SCALAR_INT_MODE_P (scalar_mode))
    5820              :     {
    5821      1297129 :       switch (scalar_mode)
    5822              :         {
    5823        73946 :         case E_QImode:
    5824        73946 :           if (evex_reg_p || egpr_vl)
    5825      4122310 :             opcode = (misaligned_p
    5826        10554 :                       ? (TARGET_AVX512BW
    5827         5264 :                          ? "vmovdqu8"
    5828              :                          : "vmovdqu64")
    5829              :                       : "vmovdqa64");
    5830        63392 :           else if (egpr_p)
    5831           30 :             opcode = (misaligned_p
    5832            0 :                       ? (TARGET_AVX512BW
    5833              :                          ? "vmovdqu8"
    5834              :                          : "%vmovups")
    5835              :                       : "%vmovaps");
    5836              :           else
    5837        63362 :             opcode = (misaligned_p
    5838              :                       ? (TARGET_AVX512BW && evex_reg_p
    5839              :                          ? "vmovdqu8"
    5840              :                          : "%vmovdqu")
    5841              :                       : "%vmovdqa");
    5842              :           break;
    5843        43968 :         case E_HImode:
    5844        43968 :           if (evex_reg_p || egpr_vl)
    5845         3691 :             opcode = (misaligned_p
    5846          304 :                       ? (TARGET_AVX512BW
    5847              :                          ? "vmovdqu16"
    5848              :                          : "vmovdqu64")
    5849              :                       : "vmovdqa64");
    5850        40277 :           else if (egpr_p)
    5851       735358 :             opcode = (misaligned_p
    5852           27 :                       ? (TARGET_AVX512BW
    5853            0 :                          ? "vmovdqu16"
    5854              :                          : "%vmovups")
    5855              :                       : "%vmovaps");
    5856              :           else
    5857       338179 :             opcode = (misaligned_p
    5858        40250 :                       ? (TARGET_AVX512BW && evex_reg_p
    5859              :                          ? "vmovdqu16"
    5860              :                          : "%vmovdqu")
    5861              :                       : "%vmovdqa");
    5862              :           break;
    5863       186973 :         case E_SImode:
    5864       186973 :           if (evex_reg_p || egpr_vl)
    5865         8241 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5866       178732 :           else if (egpr_p)
    5867           14 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5868              :           else
    5869       178718 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5870              :           break;
    5871       980398 :         case E_DImode:
    5872       980398 :         case E_TImode:
    5873       980398 :         case E_OImode:
    5874       980398 :           if (evex_reg_p || egpr_vl)
    5875        18495 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5876       961903 :           else if (egpr_p)
    5877           26 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5878              :           else
    5879       961877 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5880              :           break;
    5881        11844 :         case E_XImode:
    5882        49549 :           opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5883              :           break;
    5884            0 :         default:
    5885            0 :           gcc_unreachable ();
    5886              :         }
    5887              :     }
    5888              :   else
    5889            0 :     gcc_unreachable ();
    5890              : 
    5891      4111756 :   switch (size)
    5892              :     {
    5893        86676 :     case 64:
    5894        86676 :       snprintf (buf, sizeof (buf), "%s\t{%%g1, %%g0|%%g0, %%g1}",
    5895              :                 opcode);
    5896        86676 :       break;
    5897        91696 :     case 32:
    5898        91696 :       snprintf (buf, sizeof (buf), "%s\t{%%t1, %%t0|%%t0, %%t1}",
    5899              :                 opcode);
    5900        91696 :       break;
    5901      3933384 :     case 16:
    5902      3933384 :       snprintf (buf, sizeof (buf), "%s\t{%%x1, %%x0|%%x0, %%x1}",
    5903              :                 opcode);
    5904      3933384 :       break;
    5905            0 :     default:
    5906            0 :       gcc_unreachable ();
    5907              :     }
    5908      4111756 :   output_asm_insn (buf, operands);
    5909      4111756 :   return "";
    5910              : }
    5911              : 
    5912              : /* Return the template of the TYPE_SSEMOV instruction to move
    5913              :    operands[1] into operands[0].  */
    5914              : 
    5915              : const char *
    5916      6504659 : ix86_output_ssemov (rtx_insn *insn, rtx *operands)
    5917              : {
    5918      6504659 :   machine_mode mode = GET_MODE (operands[0]);
    5919      6504659 :   if (get_attr_type (insn) != TYPE_SSEMOV
    5920      6504659 :       || mode != GET_MODE (operands[1]))
    5921            0 :     gcc_unreachable ();
    5922              : 
    5923      6504659 :   enum attr_mode insn_mode = get_attr_mode (insn);
    5924              : 
    5925      6504659 :   switch (insn_mode)
    5926              :     {
    5927        86676 :     case MODE_XI:
    5928        86676 :     case MODE_V8DF:
    5929        86676 :     case MODE_V16SF:
    5930        86676 :       return ix86_get_ssemov (operands, 64, insn_mode, mode);
    5931              : 
    5932        91696 :     case MODE_OI:
    5933        91696 :     case MODE_V4DF:
    5934        91696 :     case MODE_V8SF:
    5935        91696 :       return ix86_get_ssemov (operands, 32, insn_mode, mode);
    5936              : 
    5937      3933384 :     case MODE_TI:
    5938      3933384 :     case MODE_V2DF:
    5939      3933384 :     case MODE_V4SF:
    5940      3933384 :       return ix86_get_ssemov (operands, 16, insn_mode, mode);
    5941              : 
    5942       669421 :     case MODE_DI:
    5943              :       /* Handle broken assemblers that require movd instead of movq. */
    5944       669421 :       if (GENERAL_REG_P (operands[0]))
    5945              :         {
    5946              :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5947              :             return "%vmovq\t{%1, %q0|%q0, %1}";
    5948              :           else
    5949              :             return "%vmovd\t{%1, %q0|%q0, %1}";
    5950              :         }
    5951       591704 :       else if (GENERAL_REG_P (operands[1]))
    5952              :         {
    5953              :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5954              :             return "%vmovq\t{%q1, %0|%0, %q1}";
    5955              :           else
    5956              :             return "%vmovd\t{%q1, %0|%0, %q1}";
    5957              :         }
    5958              :       else
    5959       420402 :         return "%vmovq\t{%1, %0|%0, %1}";
    5960              : 
    5961       210208 :     case MODE_SI:
    5962       210208 :       if (GENERAL_REG_P (operands[0]))
    5963              :         return "%vmovd\t{%1, %k0|%k0, %1}";
    5964       150187 :       else if (GENERAL_REG_P (operands[1]))
    5965              :         return "%vmovd\t{%k1, %0|%0, %k1}";
    5966              :       else
    5967        61593 :         return "%vmovd\t{%1, %0|%0, %1}";
    5968              : 
    5969        54076 :     case MODE_HI:
    5970        54076 :       if (GENERAL_REG_P (operands[0]))
    5971              :         return "vmovw\t{%1, %k0|%k0, %1}";
    5972        53913 :       else if (GENERAL_REG_P (operands[1]))
    5973              :         return "vmovw\t{%k1, %0|%0, %k1}";
    5974              :       else
    5975        53679 :         return "vmovw\t{%1, %0|%0, %1}";
    5976              : 
    5977       784700 :     case MODE_DF:
    5978       784700 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    5979              :         return "vmovsd\t{%d1, %0|%0, %d1}";
    5980              :       else
    5981       783885 :         return "%vmovsd\t{%1, %0|%0, %1}";
    5982              : 
    5983       670312 :     case MODE_SF:
    5984       670312 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    5985              :         return "vmovss\t{%d1, %0|%0, %d1}";
    5986              :       else
    5987       669745 :         return "%vmovss\t{%1, %0|%0, %1}";
    5988              : 
    5989           96 :     case MODE_HF:
    5990           96 :     case MODE_BF:
    5991           96 :       if (REG_P (operands[0]) && REG_P (operands[1]))
    5992              :         return "vmovsh\t{%d1, %0|%0, %d1}";
    5993              :       else
    5994            0 :         return "vmovsh\t{%1, %0|%0, %1}";
    5995              : 
    5996           36 :     case MODE_V1DF:
    5997           36 :       gcc_assert (!TARGET_AVX);
    5998              :       return "movlpd\t{%1, %0|%0, %1}";
    5999              : 
    6000         4054 :     case MODE_V2SF:
    6001         4054 :       if (TARGET_AVX && REG_P (operands[0]))
    6002              :         return "vmovlps\t{%1, %d0|%d0, %1}";
    6003              :       else
    6004         3981 :         return "%vmovlps\t{%1, %0|%0, %1}";
    6005              : 
    6006            0 :     default:
    6007            0 :       gcc_unreachable ();
    6008              :     }
    6009              : }
    6010              : 
    6011              : /* Returns true if OP contains a symbol reference */
    6012              : 
    6013              : bool
    6014    578270616 : symbolic_reference_mentioned_p (const_rtx op)
    6015              : {
    6016    578270616 :   const char *fmt;
    6017    578270616 :   int i;
    6018              : 
    6019    578270616 :   if (SYMBOL_REF_P (op) || LABEL_REF_P (op))
    6020              :     return true;
    6021              : 
    6022    437154362 :   fmt = GET_RTX_FORMAT (GET_CODE (op));
    6023    741922002 :   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
    6024              :     {
    6025    591951693 :       if (fmt[i] == 'E')
    6026              :         {
    6027      2030983 :           int j;
    6028              : 
    6029      4057918 :           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
    6030      3339846 :             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
    6031              :               return true;
    6032              :         }
    6033              : 
    6034    589920710 :       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
    6035              :         return true;
    6036              :     }
    6037              : 
    6038              :   return false;
    6039              : }
    6040              : 
    6041              : /* Return true if it is appropriate to emit `ret' instructions in the
    6042              :    body of a function.  Do this only if the epilogue is simple, needing a
    6043              :    couple of insns.  Prior to reloading, we can't tell how many registers
    6044              :    must be saved, so return false then.  Return false if there is no frame
    6045              :    marker to de-allocate.  */
    6046              : 
    6047              : bool
    6048            0 : ix86_can_use_return_insn_p (void)
    6049              : {
    6050            0 :   if (ix86_function_ms_hook_prologue (current_function_decl))
    6051              :     return false;
    6052              : 
    6053            0 :   if (ix86_function_naked (current_function_decl))
    6054              :     return false;
    6055              : 
    6056              :   /* Don't use `ret' instruction in interrupt handler.  */
    6057            0 :   if (! reload_completed
    6058            0 :       || frame_pointer_needed
    6059            0 :       || cfun->machine->func_type != TYPE_NORMAL)
    6060              :     return 0;
    6061              : 
    6062              :   /* Don't allow more than 32k pop, since that's all we can do
    6063              :      with one instruction.  */
    6064            0 :   if (crtl->args.pops_args && crtl->args.size >= 32768)
    6065              :     return 0;
    6066              : 
    6067            0 :   struct ix86_frame &frame = cfun->machine->frame;
    6068            0 :   return (frame.stack_pointer_offset == UNITS_PER_WORD
    6069            0 :           && (frame.nregs + frame.nsseregs) == 0);
    6070              : }
    6071              : 
    6072              : /* Return stack frame size.  get_frame_size () returns used stack slots
    6073              :    during compilation, which may be optimized out later.  If stack frame
    6074              :    is needed, stack_frame_required should be true.  */
    6075              : 
    6076              : static HOST_WIDE_INT
    6077      8311330 : ix86_get_frame_size (void)
    6078              : {
    6079      8311330 :   if (cfun->machine->stack_frame_required)
    6080      8241921 :     return get_frame_size ();
    6081              :   else
    6082              :     return 0;
    6083              : }
    6084              : 
    6085              : /* Value should be nonzero if functions must have frame pointers.
    6086              :    Zero means the frame pointer need not be set up (and parms may
    6087              :    be accessed via the stack pointer) in functions that seem suitable.  */
    6088              : 
    6089              : static bool
    6090      1234286 : ix86_frame_pointer_required (void)
    6091              : {
    6092              :   /* If we accessed previous frames, then the generated code expects
    6093              :      to be able to access the saved ebp value in our frame.  */
    6094      1234286 :   if (cfun->machine->accesses_prev_frame)
    6095              :     return true;
    6096              : 
    6097              :   /* Several x86 os'es need a frame pointer for other reasons,
    6098              :      usually pertaining to setjmp.  */
    6099      1234253 :   if (SUBTARGET_FRAME_POINTER_REQUIRED)
    6100              :     return true;
    6101              : 
    6102              :   /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
    6103      1234253 :   if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
    6104              :     return true;
    6105              : 
    6106              :   /* Win64 SEH, very large frames need a frame-pointer as maximum stack
    6107              :      allocation is 4GB.  */
    6108      1234253 :   if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
    6109              :     return true;
    6110              : 
    6111              :   /* SSE saves require frame-pointer when stack is misaligned.  */
    6112      1234253 :   if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
    6113              :     return true;
    6114              : 
    6115              :   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
    6116              :      turns off the frame pointer by default.  Turn it back on now if
    6117              :      we've not got a leaf function.  */
    6118      1234252 :   if (TARGET_OMIT_LEAF_FRAME_POINTER
    6119      1234252 :       && (!crtl->is_leaf
    6120            0 :           || ix86_current_function_calls_tls_descriptor))
    6121            0 :     return true;
    6122              : 
    6123              :   /* Several versions of mcount for the x86 assumes that there is a
    6124              :      frame, so we cannot allow profiling without a frame pointer.  */
    6125      1234252 :   if (crtl->profile && !flag_fentry)
    6126              :     return true;
    6127              : 
    6128              :   return false;
    6129              : }
    6130              : 
    6131              : /* Record that the current function accesses previous call frames.  */
    6132              : 
    6133              : void
    6134          966 : ix86_setup_frame_addresses (void)
    6135              : {
    6136          966 :   cfun->machine->accesses_prev_frame = 1;
    6137          966 : }
    6138              : 
    6139              : #if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
    6140              : # define USE_HIDDEN_LINKONCE 1
    6141              : #else
    6142              : # define USE_HIDDEN_LINKONCE 0
    6143              : #endif
    6144              : 
    6145              : /* Label count for call and return thunks.  It is used to make unique
    6146              :    labels in call and return thunks.  */
    6147              : static int indirectlabelno;
    6148              : 
    6149              : /* True if call thunk function is needed.  */
    6150              : static bool indirect_thunk_needed = false;
    6151              : 
    6152              : /* Bit masks of integer registers, which contain branch target, used
    6153              :    by call thunk functions.  */
    6154              : static HARD_REG_SET indirect_thunks_used;
    6155              : 
    6156              : /* True if return thunk function is needed.  */
    6157              : static bool indirect_return_needed = false;
    6158              : 
    6159              : /* True if return thunk function via CX is needed.  */
    6160              : static bool indirect_return_via_cx;
    6161              : 
    6162              : #ifndef INDIRECT_LABEL
    6163              : # define INDIRECT_LABEL "LIND"
    6164              : #endif
    6165              : 
    6166              : /* Indicate what prefix is needed for an indirect branch.  */
    6167              : enum indirect_thunk_prefix
    6168              : {
    6169              :   indirect_thunk_prefix_none,
    6170              :   indirect_thunk_prefix_nt
    6171              : };
    6172              : 
    6173              : /* Return the prefix needed for an indirect branch INSN.  */
    6174              : 
    6175              : enum indirect_thunk_prefix
    6176           67 : indirect_thunk_need_prefix (rtx_insn *insn)
    6177              : {
    6178           67 :   enum indirect_thunk_prefix need_prefix;
    6179           67 :   if ((cfun->machine->indirect_branch_type
    6180           67 :             == indirect_branch_thunk_extern)
    6181           67 :            && ix86_notrack_prefixed_insn_p (insn))
    6182              :     {
    6183              :       /* NOTRACK prefix is only used with external thunk so that it
    6184              :          can be properly updated to support CET at run-time.  */
    6185              :       need_prefix = indirect_thunk_prefix_nt;
    6186              :     }
    6187              :   else
    6188              :     need_prefix = indirect_thunk_prefix_none;
    6189           67 :   return need_prefix;
    6190              : }
    6191              : 
    6192              : /* Fills in the label name that should be used for the indirect thunk.  */
    6193              : 
    6194              : static void
    6195           73 : indirect_thunk_name (char name[32], unsigned int regno,
    6196              :                      enum indirect_thunk_prefix need_prefix,
    6197              :                      bool ret_p)
    6198              : {
    6199           73 :   if (regno != INVALID_REGNUM && regno != CX_REG && ret_p)
    6200            0 :     gcc_unreachable ();
    6201              : 
    6202           73 :   if (USE_HIDDEN_LINKONCE)
    6203              :     {
    6204           73 :       const char *prefix;
    6205              : 
    6206           73 :       if (need_prefix == indirect_thunk_prefix_nt
    6207           73 :           && regno != INVALID_REGNUM)
    6208              :         {
    6209              :           /* NOTRACK prefix is only used with external thunk via
    6210              :              register so that NOTRACK prefix can be added to indirect
    6211              :              branch via register to support CET at run-time.  */
    6212              :           prefix = "_nt";
    6213              :         }
    6214              :       else
    6215           71 :         prefix = "";
    6216              : 
    6217           73 :       const char *ret = ret_p ? "return" : "indirect";
    6218              : 
    6219           73 :       if (regno != INVALID_REGNUM)
    6220              :         {
    6221           55 :           const char *reg_prefix;
    6222           55 :           if (LEGACY_INT_REGNO_P (regno))
    6223           53 :             reg_prefix = TARGET_64BIT ? "r" : "e";
    6224              :           else
    6225              :             reg_prefix = "";
    6226           55 :           sprintf (name, "__x86_%s_thunk%s_%s%s",
    6227              :                    ret, prefix, reg_prefix, reg_names[regno]);
    6228              :         }
    6229              :       else
    6230           18 :         sprintf (name, "__x86_%s_thunk%s", ret, prefix);
    6231              :     }
    6232              :   else
    6233              :     {
    6234              :       if (regno != INVALID_REGNUM)
    6235              :         ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
    6236              :       else
    6237              :         {
    6238              :           if (ret_p)
    6239              :             ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
    6240              :           else
    6241           73 :             ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
    6242              :         }
    6243              :     }
    6244           73 : }
    6245              : 
    6246              : /* Output a call and return thunk for indirect branch.  If REGNO != -1,
    6247              :    the function address is in REGNO and the call and return thunk looks like:
    6248              : 
    6249              :         call    L2
    6250              :    L1:
    6251              :         pause
    6252              :         lfence
    6253              :         jmp     L1
    6254              :    L2:
    6255              :         mov     %REG, (%sp)
    6256              :         ret
    6257              : 
    6258              :    Otherwise, the function address is on the top of stack and the
    6259              :    call and return thunk looks like:
    6260              : 
    6261              :         call L2
    6262              :   L1:
    6263              :         pause
    6264              :         lfence
    6265              :         jmp L1
    6266              :   L2:
    6267              :         lea WORD_SIZE(%sp), %sp
    6268              :         ret
    6269              :  */
    6270              : 
    6271              : static void
    6272           38 : output_indirect_thunk (unsigned int regno)
    6273              : {
    6274           38 :   char indirectlabel1[32];
    6275           38 :   char indirectlabel2[32];
    6276              : 
    6277           38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
    6278              :                                indirectlabelno++);
    6279           38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
    6280              :                                indirectlabelno++);
    6281              : 
    6282              :   /* Call */
    6283           38 :   fputs ("\tcall\t", asm_out_file);
    6284           38 :   assemble_name_raw (asm_out_file, indirectlabel2);
    6285           38 :   fputc ('\n', asm_out_file);
    6286              : 
    6287           38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
    6288              : 
    6289              :   /* AMD and Intel CPUs prefer each a different instruction as loop filler.
    6290              :      Usage of both pause + lfence is compromise solution.  */
    6291           38 :   fprintf (asm_out_file, "\tpause\n\tlfence\n");
    6292              : 
    6293              :   /* Jump.  */
    6294           38 :   fputs ("\tjmp\t", asm_out_file);
    6295           38 :   assemble_name_raw (asm_out_file, indirectlabel1);
    6296           38 :   fputc ('\n', asm_out_file);
    6297              : 
    6298           38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
    6299              : 
    6300              :   /* The above call insn pushed a word to stack.  Adjust CFI info.  */
    6301           38 :   if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
    6302              :     {
    6303           38 :       if (! dwarf2out_do_cfi_asm ())
    6304              :         {
    6305            0 :           dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6306            0 :           xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
    6307            0 :           xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
    6308            0 :           vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6309              :         }
    6310           38 :       dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6311           38 :       xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
    6312           38 :       xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
    6313           38 :       vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6314           38 :       dwarf2out_emit_cfi (xcfi);
    6315              :     }
    6316              : 
    6317           38 :   if (regno != INVALID_REGNUM)
    6318              :     {
    6319              :       /* MOV.  */
    6320           27 :       rtx xops[2];
    6321           27 :       xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
    6322           27 :       xops[1] = gen_rtx_REG (word_mode, regno);
    6323           27 :       output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
    6324              :     }
    6325              :   else
    6326              :     {
    6327              :       /* LEA.  */
    6328           11 :       rtx xops[2];
    6329           11 :       xops[0] = stack_pointer_rtx;
    6330           11 :       xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    6331           11 :       output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
    6332              :     }
    6333              : 
    6334           38 :   fputs ("\tret\n", asm_out_file);
    6335           38 :   if ((ix86_harden_sls & harden_sls_return))
    6336            1 :     fputs ("\tint3\n", asm_out_file);
    6337           38 : }
    6338              : 
    6339              : /* Output a function with a call and return thunk for indirect branch.
    6340              :    If REGNO != INVALID_REGNUM, the function address is in REGNO.
    6341              :    Otherwise, the function address is on the top of stack.  Thunk is
    6342              :    used for function return if RET_P is true.  */
    6343              : 
    6344              : static void
    6345           22 : output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
    6346              :                                 unsigned int regno, bool ret_p)
    6347              : {
    6348           22 :   char name[32];
    6349           22 :   tree decl;
    6350              : 
    6351              :   /* Create __x86_indirect_thunk.  */
    6352           22 :   indirect_thunk_name (name, regno, need_prefix, ret_p);
    6353           22 :   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6354              :                      get_identifier (name),
    6355              :                      build_function_type_list (void_type_node, NULL_TREE));
    6356           22 :   DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6357              :                                    NULL_TREE, void_type_node);
    6358           22 :   TREE_PUBLIC (decl) = 1;
    6359           22 :   TREE_STATIC (decl) = 1;
    6360           22 :   DECL_IGNORED_P (decl) = 1;
    6361              : 
    6362              : #if TARGET_MACHO
    6363              :   if (TARGET_MACHO)
    6364              :     {
    6365              :       switch_to_section (darwin_sections[picbase_thunk_section]);
    6366              :       fputs ("\t.weak_definition\t", asm_out_file);
    6367              :       assemble_name (asm_out_file, name);
    6368              :       fputs ("\n\t.private_extern\t", asm_out_file);
    6369              :       assemble_name (asm_out_file, name);
    6370              :       putc ('\n', asm_out_file);
    6371              :       ASM_OUTPUT_LABEL (asm_out_file, name);
    6372              :       DECL_WEAK (decl) = 1;
    6373              :     }
    6374              :   else
    6375              : #endif
    6376           22 :     if (USE_HIDDEN_LINKONCE)
    6377              :       {
    6378           22 :         cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6379              : 
    6380           22 :         targetm.asm_out.unique_section (decl, 0);
    6381           22 :         switch_to_section (get_named_section (decl, NULL, 0));
    6382              : 
    6383           22 :         targetm.asm_out.globalize_label (asm_out_file, name);
    6384           22 :         fputs ("\t.hidden\t", asm_out_file);
    6385           22 :         assemble_name (asm_out_file, name);
    6386           22 :         putc ('\n', asm_out_file);
    6387           22 :         ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6388              :       }
    6389              :     else
    6390              :       {
    6391              :         switch_to_section (text_section);
    6392           22 :         ASM_OUTPUT_LABEL (asm_out_file, name);
    6393              :       }
    6394              : 
    6395           22 :   DECL_INITIAL (decl) = make_node (BLOCK);
    6396           22 :   current_function_decl = decl;
    6397           22 :   allocate_struct_function (decl, false);
    6398           22 :   init_function_start (decl);
    6399              :   /* We're about to hide the function body from callees of final_* by
    6400              :      emitting it directly; tell them we're a thunk, if they care.  */
    6401           22 :   cfun->is_thunk = true;
    6402           22 :   first_function_block_is_cold = false;
    6403              :   /* Make sure unwind info is emitted for the thunk if needed.  */
    6404           22 :   final_start_function (emit_barrier (), asm_out_file, 1);
    6405              : 
    6406           22 :   output_indirect_thunk (regno);
    6407              : 
    6408           22 :   final_end_function ();
    6409           22 :   init_insn_lengths ();
    6410           22 :   free_after_compilation (cfun);
    6411           22 :   set_cfun (NULL);
    6412           22 :   current_function_decl = NULL;
    6413           22 : }
    6414              : 
    6415              : static int pic_labels_used;
    6416              : 
    6417              : /* Fills in the label name that should be used for a pc thunk for
    6418              :    the given register.  */
    6419              : 
    6420              : static void
    6421        37516 : get_pc_thunk_name (char name[32], unsigned int regno)
    6422              : {
    6423        37516 :   gcc_assert (!TARGET_64BIT);
    6424              : 
    6425        37516 :   if (USE_HIDDEN_LINKONCE)
    6426        37516 :     sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
    6427              :   else
    6428        37516 :     ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
    6429        37516 : }
    6430              : 
    6431              : 
    6432              : /* This function generates code for -fpic that loads %ebx with
    6433              :    the return address of the caller and then returns.  */
    6434              : 
    6435              : static void
    6436       236254 : ix86_code_end (void)
    6437              : {
    6438       236254 :   rtx xops[2];
    6439       236254 :   unsigned int regno;
    6440              : 
    6441       236254 :   if (indirect_return_needed)
    6442            6 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6443              :                                     INVALID_REGNUM, true);
    6444       236254 :   if (indirect_return_via_cx)
    6445            0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6446              :                                     CX_REG, true);
    6447       236254 :   if (indirect_thunk_needed)
    6448            0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6449              :                                     INVALID_REGNUM, false);
    6450              : 
    6451      2126286 :   for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
    6452              :     {
    6453      1890032 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6454            0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6455              :                                         regno, false);
    6456              :     }
    6457              : 
    6458      4016318 :   for (regno = FIRST_REX2_INT_REG; regno <= LAST_REX2_INT_REG; regno++)
    6459              :     {
    6460      3780064 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6461            0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6462              :                                         regno, false);
    6463              :     }
    6464              : 
    6465      2126286 :   for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
    6466              :     {
    6467      1890032 :       char name[32];
    6468      1890032 :       tree decl;
    6469              : 
    6470      1890032 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6471           16 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6472              :                                         regno, false);
    6473              : 
    6474      1890032 :       if (!(pic_labels_used & (1 << regno)))
    6475      1886446 :         continue;
    6476              : 
    6477         3586 :       get_pc_thunk_name (name, regno);
    6478              : 
    6479         3586 :       decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6480              :                          get_identifier (name),
    6481              :                          build_function_type_list (void_type_node, NULL_TREE));
    6482         3586 :       DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6483              :                                        NULL_TREE, void_type_node);
    6484         3586 :       TREE_PUBLIC (decl) = 1;
    6485         3586 :       TREE_STATIC (decl) = 1;
    6486         3586 :       DECL_IGNORED_P (decl) = 1;
    6487              : 
    6488              : #if TARGET_MACHO
    6489              :       if (TARGET_MACHO)
    6490              :         {
    6491              :           switch_to_section (darwin_sections[picbase_thunk_section]);
    6492              :           fputs ("\t.weak_definition\t", asm_out_file);
    6493              :           assemble_name (asm_out_file, name);
    6494              :           fputs ("\n\t.private_extern\t", asm_out_file);
    6495              :           assemble_name (asm_out_file, name);
    6496              :           putc ('\n', asm_out_file);
    6497              :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6498              :           DECL_WEAK (decl) = 1;
    6499              :         }
    6500              :       else
    6501              : #endif
    6502         3586 :       if (USE_HIDDEN_LINKONCE)
    6503              :         {
    6504         3586 :           cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6505              : 
    6506         3586 :           targetm.asm_out.unique_section (decl, 0);
    6507         3586 :           switch_to_section (get_named_section (decl, NULL, 0));
    6508              : 
    6509         3586 :           targetm.asm_out.globalize_label (asm_out_file, name);
    6510         3586 :           fputs ("\t.hidden\t", asm_out_file);
    6511         3586 :           assemble_name (asm_out_file, name);
    6512         3586 :           putc ('\n', asm_out_file);
    6513         3586 :           ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6514              :         }
    6515              :       else
    6516              :         {
    6517              :           switch_to_section (text_section);
    6518         3586 :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6519              :         }
    6520              : 
    6521         3586 :       DECL_INITIAL (decl) = make_node (BLOCK);
    6522         3586 :       current_function_decl = decl;
    6523         3586 :       allocate_struct_function (decl, false);
    6524         3586 :       init_function_start (decl);
    6525              :       /* We're about to hide the function body from callees of final_* by
    6526              :          emitting it directly; tell them we're a thunk, if they care.  */
    6527         3586 :       cfun->is_thunk = true;
    6528         3586 :       first_function_block_is_cold = false;
    6529              :       /* Make sure unwind info is emitted for the thunk if needed.  */
    6530         3586 :       final_start_function (emit_barrier (), asm_out_file, 1);
    6531              : 
    6532              :       /* Pad stack IP move with 4 instructions (two NOPs count
    6533              :          as one instruction).  */
    6534         3586 :       if (TARGET_PAD_SHORT_FUNCTION)
    6535              :         {
    6536              :           int i = 8;
    6537              : 
    6538            0 :           while (i--)
    6539            0 :             fputs ("\tnop\n", asm_out_file);
    6540              :         }
    6541              : 
    6542         7172 :       xops[0] = gen_rtx_REG (Pmode, regno);
    6543         7172 :       xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
    6544         3586 :       output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
    6545         3586 :       fputs ("\tret\n", asm_out_file);
    6546         3586 :       final_end_function ();
    6547         3586 :       init_insn_lengths ();
    6548         3586 :       free_after_compilation (cfun);
    6549         3586 :       set_cfun (NULL);
    6550         3586 :       current_function_decl = NULL;
    6551              :     }
    6552              : 
    6553       236254 :   if (flag_split_stack)
    6554         4712 :     file_end_indicate_split_stack ();
    6555       236254 : }
    6556              : 
    6557              : /* Emit code for the SET_GOT patterns.  */
    6558              : 
    6559              : const char *
    6560        33930 : output_set_got (rtx dest, rtx label)
    6561              : {
    6562        33930 :   rtx xops[3];
    6563              : 
    6564        33930 :   xops[0] = dest;
    6565              : 
    6566        33930 :   if (TARGET_VXWORKS_GOTTPIC && TARGET_VXWORKS_RTP && flag_pic)
    6567              :     {
    6568              :       /* Load (*VXWORKS_GOTT_BASE) into the PIC register.  */
    6569              :       xops[2] = gen_rtx_MEM (Pmode,
    6570              :                              gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
    6571              :       output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
    6572              : 
    6573              :       /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
    6574              :          Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
    6575              :          an unadorned address.  */
    6576              :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
    6577              :       SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
    6578              :       output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
    6579              :       return "";
    6580              :     }
    6581              : 
    6582        67860 :   xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
    6583              : 
    6584        33930 :   if (flag_pic)
    6585              :     {
    6586        33930 :       char name[32];
    6587        33930 :       get_pc_thunk_name (name, REGNO (dest));
    6588        33930 :       pic_labels_used |= 1 << REGNO (dest);
    6589              : 
    6590        67860 :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
    6591        33930 :       xops[2] = gen_rtx_MEM (QImode, xops[2]);
    6592        33930 :       output_asm_insn ("%!call\t%X2", xops);
    6593              : 
    6594              : #if TARGET_MACHO
    6595              :       /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
    6596              :          This is what will be referenced by the Mach-O PIC subsystem.  */
    6597              :       if (machopic_should_output_picbase_label () || !label)
    6598              :         ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
    6599              : 
    6600              :       /* When we are restoring the pic base at the site of a nonlocal label,
    6601              :          and we decided to emit the pic base above, we will still output a
    6602              :          local label used for calculating the correction offset (even though
    6603              :          the offset will be 0 in that case).  */
    6604              :       if (label)
    6605              :         targetm.asm_out.internal_label (asm_out_file, "L",
    6606              :                                            CODE_LABEL_NUMBER (label));
    6607              : #endif
    6608              :     }
    6609              :   else
    6610              :     {
    6611            0 :       if (TARGET_MACHO)
    6612              :         /* We don't need a pic base, we're not producing pic.  */
    6613              :         gcc_unreachable ();
    6614              : 
    6615            0 :       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
    6616            0 :       output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
    6617            0 :       targetm.asm_out.internal_label (asm_out_file, "L",
    6618            0 :                                       CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
    6619              :     }
    6620              : 
    6621        33930 :   if (!TARGET_MACHO)
    6622        33930 :     output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
    6623              : 
    6624        33930 :   return "";
    6625              : }
    6626              : 
    6627              : /* Generate an "push" pattern for input ARG.  */
    6628              : 
    6629              : rtx
    6630      1895000 : gen_push (rtx arg, bool ppx_p)
    6631              : {
    6632      1895000 :   struct machine_function *m = cfun->machine;
    6633              : 
    6634      1895000 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6635      1622681 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6636      1895000 :   m->fs.sp_offset += UNITS_PER_WORD;
    6637              : 
    6638      1895000 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6639           26 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6640              : 
    6641      1895000 :   rtx stack = gen_rtx_MEM (word_mode,
    6642      1895000 :                            gen_rtx_PRE_DEC (Pmode,
    6643              :                                             stack_pointer_rtx));
    6644      3789911 :   return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
    6645              : }
    6646              : 
    6647              : rtx
    6648           21 : gen_pushfl (void)
    6649              : {
    6650           21 :   struct machine_function *m = cfun->machine;
    6651           21 :   rtx flags, mem;
    6652              : 
    6653           21 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6654            0 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6655           21 :   m->fs.sp_offset += UNITS_PER_WORD;
    6656              : 
    6657           21 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6658              : 
    6659           21 :   mem = gen_rtx_MEM (word_mode,
    6660           21 :                      gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
    6661              : 
    6662           21 :   return gen_pushfl2 (word_mode, mem, flags);
    6663              : }
    6664              : 
    6665              : /* Generate an "pop" pattern for input ARG.  */
    6666              : 
    6667              : rtx
    6668      1475243 : gen_pop (rtx arg, bool ppx_p)
    6669              : {
    6670      1475243 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6671           22 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6672              : 
    6673      1475243 :   rtx stack = gen_rtx_MEM (word_mode,
    6674      1475243 :                            gen_rtx_POST_INC (Pmode,
    6675              :                                              stack_pointer_rtx));
    6676              : 
    6677      2950397 :   return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
    6678              : }
    6679              : 
    6680              : rtx
    6681           21 : gen_popfl (void)
    6682              : {
    6683           21 :   rtx flags, mem;
    6684              : 
    6685           21 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6686              : 
    6687           21 :   mem = gen_rtx_MEM (word_mode,
    6688           21 :                      gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
    6689              : 
    6690           21 :   return gen_popfl1 (word_mode, flags, mem);
    6691              : }
    6692              : 
    6693              : /* Generate a "push2" pattern for input ARG.  */
    6694              : rtx
    6695           19 : gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
    6696              : {
    6697           19 :   struct machine_function *m = cfun->machine;
    6698           19 :   const int offset = UNITS_PER_WORD * 2;
    6699              : 
    6700           19 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6701           14 :     m->fs.cfa_offset += offset;
    6702           19 :   m->fs.sp_offset += offset;
    6703              : 
    6704           19 :   if (REG_P (reg1) && GET_MODE (reg1) != word_mode)
    6705            0 :     reg1 = gen_rtx_REG (word_mode, REGNO (reg1));
    6706              : 
    6707           19 :   if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
    6708            0 :     reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
    6709              : 
    6710           19 :   return ppx_p ? gen_push2p_di (mem, reg1, reg2)
    6711            4 :                : gen_push2_di (mem, reg1, reg2);
    6712              : }
    6713              : 
    6714              : /* Return >= 0 if there is an unused call-clobbered register available
    6715              :    for the entire function.  */
    6716              : 
    6717              : static unsigned int
    6718            0 : ix86_select_alt_pic_regnum (void)
    6719              : {
    6720            0 :   if (ix86_use_pseudo_pic_reg ())
    6721              :     return INVALID_REGNUM;
    6722              : 
    6723            0 :   if (crtl->is_leaf
    6724            0 :       && !crtl->profile
    6725            0 :       && !ix86_current_function_calls_tls_descriptor)
    6726              :     {
    6727            0 :       int i, drap;
    6728              :       /* Can't use the same register for both PIC and DRAP.  */
    6729            0 :       if (crtl->drap_reg)
    6730            0 :         drap = REGNO (crtl->drap_reg);
    6731              :       else
    6732              :         drap = -1;
    6733            0 :       for (i = 2; i >= 0; --i)
    6734            0 :         if (i != drap && !df_regs_ever_live_p (i))
    6735              :           return i;
    6736              :     }
    6737              : 
    6738              :   return INVALID_REGNUM;
    6739              : }
    6740              : 
    6741              : /* Return true if REGNO is used by the epilogue.  */
    6742              : 
    6743              : bool
    6744   1678667058 : ix86_epilogue_uses (int regno)
    6745              : {
    6746              :   /* If there are no caller-saved registers, we preserve all registers,
    6747              :      except for MMX and x87 registers which aren't supported when saving
    6748              :      and restoring registers.  Don't explicitly save SP register since
    6749              :      it is always preserved.  */
    6750   1678667058 :   return (epilogue_completed
    6751    265119374 :           && (cfun->machine->call_saved_registers
    6752    265119374 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    6753        29348 :           && !fixed_regs[regno]
    6754         5441 :           && !STACK_REGNO_P (regno)
    6755   1678672499 :           && !MMX_REGNO_P (regno));
    6756              : }
    6757              : 
    6758              : /* Return nonzero if register REGNO can be used as a scratch register
    6759              :    in peephole2.  */
    6760              : 
    6761              : static bool
    6762      1229116 : ix86_hard_regno_scratch_ok (unsigned int regno)
    6763              : {
    6764              :   /* If there are no caller-saved registers, we can't use any register
    6765              :      as a scratch register after epilogue and use REGNO as scratch
    6766              :      register only if it has been used before to avoid saving and
    6767              :      restoring it.  */
    6768      1229116 :   return ((cfun->machine->call_saved_registers
    6769      1229116 :            != TYPE_NO_CALLER_SAVED_REGISTERS)
    6770      1229116 :           || (!epilogue_completed
    6771            0 :               && df_regs_ever_live_p (regno)));
    6772              : }
    6773              : 
    6774              : /* Return TRUE if we need to save REGNO.  */
    6775              : 
    6776              : bool
    6777    356205366 : ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
    6778              : {
    6779              :   /* Save and restore DRAP register between prologue and epilogue so
    6780              :      that stack pointer can be restored.  */
    6781    356205366 :   if (crtl->drap_reg
    6782      2266982 :       && regno == REGNO (crtl->drap_reg)
    6783    356260412 :       && !cfun->machine->no_drap_save_restore)
    6784              :     return true;
    6785              : 
    6786              :   /* ??? Treat no_callee_saved_registers as a special case in order
    6787              :      to cope with -mnoreturn-no-callee-saved-registers, which is not
    6788              :      reflected in crtl->abi.  */
    6789    356150320 :   if (cfun->machine->call_saved_registers == TYPE_NO_CALLEE_SAVED_REGISTERS
    6790        16696 :       && regno != HARD_FRAME_POINTER_REGNUM)
    6791              :     return false;
    6792              : 
    6793    390154745 :   if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
    6794     10837061 :       && pic_offset_table_rtx)
    6795              :     {
    6796       385674 :       if (ix86_use_pseudo_pic_reg ())
    6797              :         {
    6798              :           /* REAL_PIC_OFFSET_TABLE_REGNUM used by call to
    6799              :           _mcount in prologue.  */
    6800       385674 :           if (!TARGET_64BIT && flag_pic && crtl->profile)
    6801              :             return true;
    6802              :         }
    6803            0 :       else if (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
    6804            0 :                || crtl->profile
    6805            0 :                || crtl->calls_eh_return
    6806            0 :                || crtl->uses_const_pool
    6807            0 :                || cfun->has_nonlocal_label)
    6808            0 :         return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
    6809              :     }
    6810              : 
    6811    356134126 :   if (crtl->calls_eh_return && maybe_eh_return)
    6812              :     {
    6813              :       unsigned i;
    6814        13237 :       for (i = 0; ; i++)
    6815              :         {
    6816        20181 :           unsigned test = EH_RETURN_DATA_REGNO (i);
    6817        13671 :           if (test == INVALID_REGNUM)
    6818              :             break;
    6819        13671 :           if (test == regno)
    6820              :             return true;
    6821        13237 :         }
    6822              :     }
    6823              : 
    6824    356133692 :   if (ignore_outlined && cfun->machine->call_ms2sysv)
    6825              :     {
    6826      2642240 :       unsigned count = cfun->machine->call_ms2sysv_extra_regs
    6827              :                        + xlogue_layout::MIN_REGS;
    6828      2642240 :       if (xlogue_layout::is_stub_managed_reg (regno, count))
    6829              :         return false;
    6830              :     }
    6831              : 
    6832    355634599 :   return (df_regs_ever_live_p (regno)
    6833     67802983 :           && !fixed_regs[regno]
    6834     59882195 :           && !crtl->abi->clobbers_full_reg_p (regno)
    6835    374480036 :           && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
    6836              : }
    6837              : 
    6838              : /* Return number of saved general prupose registers.  */
    6839              : 
    6840              : static int
    6841      8235665 : ix86_nsaved_regs (void)
    6842              : {
    6843      8235665 :   int nregs = 0;
    6844      8235665 :   int regno;
    6845              : 
    6846    765916845 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6847    757681180 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6848      8252615 :       nregs ++;
    6849      8235665 :   return nregs;
    6850              : }
    6851              : 
    6852              : /* Return number of saved SSE registers.  */
    6853              : 
    6854              : static int
    6855      8270653 : ix86_nsaved_sseregs (void)
    6856              : {
    6857      8270653 :   int nregs = 0;
    6858      8270653 :   int regno;
    6859              : 
    6860      7467149 :   if (!TARGET_64BIT_MS_ABI
    6861      8270653 :       && (cfun->machine->call_saved_registers
    6862      8044875 :           != TYPE_NO_CALLER_SAVED_REGISTERS))
    6863              :     return 0;
    6864     21072591 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6865     20846004 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6866      1897653 :       nregs ++;
    6867              :   return nregs;
    6868              : }
    6869              : 
    6870              : /* Given FROM and TO register numbers, say whether this elimination is
    6871              :    allowed.  If stack alignment is needed, we can only replace argument
    6872              :    pointer with hard frame pointer, or replace frame pointer with stack
    6873              :    pointer.  Otherwise, frame pointer elimination is automatically
    6874              :    handled and all other eliminations are valid.  */
    6875              : 
    6876              : static bool
    6877     48762477 : ix86_can_eliminate (const int from, const int to)
    6878              : {
    6879     48762477 :   if (stack_realign_fp)
    6880      1691500 :     return ((from == ARG_POINTER_REGNUM
    6881      1691500 :              && to == HARD_FRAME_POINTER_REGNUM)
    6882      1691500 :             || (from == FRAME_POINTER_REGNUM
    6883      1691500 :                 && to == STACK_POINTER_REGNUM));
    6884              :   else
    6885     87527426 :     return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
    6886              : }
    6887              : 
    6888              : /* Return the offset between two registers, one to be eliminated, and the other
    6889              :    its replacement, at the start of a routine.  */
    6890              : 
    6891              : HOST_WIDE_INT
    6892    141612728 : ix86_initial_elimination_offset (int from, int to)
    6893              : {
    6894    141612728 :   struct ix86_frame &frame = cfun->machine->frame;
    6895              : 
    6896    141612728 :   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    6897     10489892 :     return frame.hard_frame_pointer_offset;
    6898    131122836 :   else if (from == FRAME_POINTER_REGNUM
    6899    131122836 :            && to == HARD_FRAME_POINTER_REGNUM)
    6900      8200302 :     return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
    6901              :   else
    6902              :     {
    6903    122922534 :       gcc_assert (to == STACK_POINTER_REGNUM);
    6904              : 
    6905    122922534 :       if (from == ARG_POINTER_REGNUM)
    6906    114722232 :         return frame.stack_pointer_offset;
    6907              : 
    6908      8200302 :       gcc_assert (from == FRAME_POINTER_REGNUM);
    6909      8200302 :       return frame.stack_pointer_offset - frame.frame_pointer_offset;
    6910              :     }
    6911              : }
    6912              : 
    6913              : /* Emits a warning for unsupported msabi to sysv pro/epilogues.  */
    6914              : void
    6915            0 : warn_once_call_ms2sysv_xlogues (const char *feature)
    6916              : {
    6917            0 :   static bool warned_once = false;
    6918            0 :   if (!warned_once)
    6919              :     {
    6920            0 :       warning (0, "%<-mcall-ms2sysv-xlogues%> is not compatible with %s",
    6921              :                feature);
    6922            0 :       warned_once = true;
    6923              :     }
    6924            0 : }
    6925              : 
    6926              : /* Return the probing interval for -fstack-clash-protection.  */
    6927              : 
    6928              : static HOST_WIDE_INT
    6929          494 : get_probe_interval (void)
    6930              : {
    6931          341 :   if (flag_stack_clash_protection)
    6932          412 :     return (HOST_WIDE_INT_1U
    6933          412 :             << param_stack_clash_protection_probe_interval);
    6934              :   else
    6935              :     return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP);
    6936              : }
    6937              : 
    6938              : /* When using -fsplit-stack, the allocation routines set a field in
    6939              :    the TCB to the bottom of the stack plus this much space, measured
    6940              :    in bytes.  */
    6941              : 
    6942              : #define SPLIT_STACK_AVAILABLE 256
    6943              : 
    6944              : /* Return true if push2/pop2 can be generated.  */
    6945              : 
    6946              : static bool
    6947      8236329 : ix86_can_use_push2pop2 (void)
    6948              : {
    6949              :   /* Use push2/pop2 only if the incoming stack is 16-byte aligned.  */
    6950      8236329 :   unsigned int incoming_stack_boundary
    6951      8236329 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    6952      8236329 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    6953      8236329 :   return incoming_stack_boundary % 128 == 0;
    6954              : }
    6955              : 
    6956              : /* Helper function to determine whether push2/pop2 can be used in prologue or
    6957              :    epilogue for register save/restore.  */
    6958              : static bool
    6959      8235665 : ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
    6960              : {
    6961      8235665 :   if (!ix86_can_use_push2pop2 ())
    6962              :     return false;
    6963      8199744 :   int aligned = cfun->machine->fs.sp_offset % 16 == 0;
    6964      8199744 :   return TARGET_APX_PUSH2POP2
    6965         2887 :          && !cfun->machine->frame.save_regs_using_mov
    6966         2875 :          && cfun->machine->func_type == TYPE_NORMAL
    6967      8202611 :          && (nregs + aligned) >= 3;
    6968              : }
    6969              : 
    6970              : /* Check if push/pop should be used to save/restore registers.  */
    6971              : static bool
    6972      8966261 : save_regs_using_push_pop (HOST_WIDE_INT to_allocate)
    6973              : {
    6974      3212430 :   return ((!to_allocate && cfun->machine->frame.nregs <= 1)
    6975      5996842 :           || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
    6976              :           /* If static stack checking is enabled and done with probes,
    6977              :              the registers need to be saved before allocating the frame.  */
    6978      5996181 :           || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
    6979              :           /* If stack clash probing needs a loop, then it needs a
    6980              :              scratch register.  But the returned register is only guaranteed
    6981              :              to be safe to use after register saves are complete.  So if
    6982              :              stack clash protections are enabled and the allocated frame is
    6983              :              larger than the probe interval, then use pushes to save
    6984              :              callee saved registers.  */
    6985     14962368 :           || (flag_stack_clash_protection
    6986          341 :               && !ix86_target_stack_probe ()
    6987          341 :               && to_allocate > get_probe_interval ()));
    6988              : }
    6989              : 
    6990              : /* Fill structure ix86_frame about frame of currently computed function.  */
    6991              : 
    6992              : static void
    6993      8235665 : ix86_compute_frame_layout (void)
    6994              : {
    6995      8235665 :   struct ix86_frame *frame = &cfun->machine->frame;
    6996      8235665 :   struct machine_function *m = cfun->machine;
    6997      8235665 :   unsigned HOST_WIDE_INT stack_alignment_needed;
    6998      8235665 :   HOST_WIDE_INT offset;
    6999      8235665 :   unsigned HOST_WIDE_INT preferred_alignment;
    7000      8235665 :   HOST_WIDE_INT size = ix86_get_frame_size ();
    7001      8235665 :   HOST_WIDE_INT to_allocate;
    7002              : 
    7003              :   /* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
    7004              :    * ms_abi functions that call a sysv function.  We now need to prune away
    7005              :    * cases where it should be disabled.  */
    7006      8235665 :   if (TARGET_64BIT && m->call_ms2sysv)
    7007              :     {
    7008        35225 :       gcc_assert (TARGET_64BIT_MS_ABI);
    7009        35225 :       gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
    7010        35225 :       gcc_assert (!TARGET_SEH);
    7011        35225 :       gcc_assert (TARGET_SSE);
    7012        35225 :       gcc_assert (!ix86_using_red_zone ());
    7013              : 
    7014        35225 :       if (crtl->calls_eh_return)
    7015              :         {
    7016            0 :           gcc_assert (!reload_completed);
    7017            0 :           m->call_ms2sysv = false;
    7018            0 :           warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
    7019              :         }
    7020              : 
    7021        35225 :       else if (ix86_static_chain_on_stack)
    7022              :         {
    7023            0 :           gcc_assert (!reload_completed);
    7024            0 :           m->call_ms2sysv = false;
    7025            0 :           warn_once_call_ms2sysv_xlogues ("static call chains");
    7026              :         }
    7027              : 
    7028              :       /* Finally, compute which registers the stub will manage.  */
    7029              :       else
    7030              :         {
    7031        35225 :           unsigned count = xlogue_layout::count_stub_managed_regs ();
    7032        35225 :           m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
    7033        35225 :           m->call_ms2sysv_pad_in = 0;
    7034              :         }
    7035              :     }
    7036              : 
    7037      8235665 :   frame->nregs = ix86_nsaved_regs ();
    7038      8235665 :   frame->nsseregs = ix86_nsaved_sseregs ();
    7039              : 
    7040              :   /* 64-bit MS ABI seem to require stack alignment to be always 16,
    7041              :      except for function prologues, leaf functions and when the default
    7042              :      incoming stack boundary is overridden at command line or via
    7043              :      force_align_arg_pointer attribute.
    7044              : 
    7045              :      Darwin's ABI specifies 128b alignment for both 32 and  64 bit variants
    7046              :      at call sites, including profile function calls.
    7047              : 
    7048              :      For APX push2/pop2, the stack also requires 128b alignment.  */
    7049      8235665 :   if ((ix86_pro_and_epilogue_can_use_push2pop2 (frame->nregs)
    7050           65 :        && crtl->preferred_stack_boundary < 128)
    7051      8235728 :       || (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
    7052       225776 :            && crtl->preferred_stack_boundary < 128)
    7053            0 :           && (!crtl->is_leaf || cfun->calls_alloca != 0
    7054            0 :               || ix86_current_function_calls_tls_descriptor
    7055            0 :               || (TARGET_MACHO && crtl->profile)
    7056            0 :               || ix86_incoming_stack_boundary < 128)))
    7057              :     {
    7058            2 :       crtl->preferred_stack_boundary = 128;
    7059            2 :       if (crtl->stack_alignment_needed < 128)
    7060            1 :         crtl->stack_alignment_needed = 128;
    7061              :     }
    7062              : 
    7063      8235665 :   stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
    7064      8235665 :   preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
    7065              : 
    7066      8235665 :   gcc_assert (!size || stack_alignment_needed);
    7067      9039140 :   gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
    7068      8235665 :   gcc_assert (preferred_alignment <= stack_alignment_needed);
    7069              : 
    7070              :   /* The only ABI saving SSE regs should be 64-bit ms_abi or with
    7071              :      no_caller_saved_registers attribute.  */
    7072      8235665 :   gcc_assert (TARGET_64BIT
    7073              :               || (cfun->machine->call_saved_registers
    7074              :                   == TYPE_NO_CALLER_SAVED_REGISTERS)
    7075              :               || !frame->nsseregs);
    7076      8235665 :   if (TARGET_64BIT && m->call_ms2sysv)
    7077              :     {
    7078        35225 :       gcc_assert (stack_alignment_needed >= 16);
    7079        35225 :       gcc_assert ((cfun->machine->call_saved_registers
    7080              :                    == TYPE_NO_CALLER_SAVED_REGISTERS)
    7081              :                   || !frame->nsseregs);
    7082              :     }
    7083              : 
    7084              :   /* For SEH we have to limit the amount of code movement into the prologue.
    7085              :      At present we do this via a BLOCKAGE, at which point there's very little
    7086              :      scheduling that can be done, which means that there's very little point
    7087              :      in doing anything except PUSHs.  */
    7088      8235665 :   if (TARGET_SEH)
    7089              :     m->use_fast_prologue_epilogue = false;
    7090      8235665 :   else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    7091              :     {
    7092      7898487 :       int count = frame->nregs;
    7093      7898487 :       struct cgraph_node *node = cgraph_node::get (current_function_decl);
    7094              : 
    7095              :       /* The fast prologue uses move instead of push to save registers.  This
    7096              :          is significantly longer, but also executes faster as modern hardware
    7097              :          can execute the moves in parallel, but can't do that for push/pop.
    7098              : 
    7099              :          Be careful about choosing what prologue to emit:  When function takes
    7100              :          many instructions to execute we may use slow version as well as in
    7101              :          case function is known to be outside hot spot (this is known with
    7102              :          feedback only).  Weight the size of function by number of registers
    7103              :          to save as it is cheap to use one or two push instructions but very
    7104              :          slow to use many of them.
    7105              : 
    7106              :          Calling this hook multiple times with the same frame requirements
    7107              :          must produce the same layout, since the RA might otherwise be
    7108              :          unable to reach a fixed point or might fail its final sanity checks.
    7109              :          This means that once we've assumed that a function does or doesn't
    7110              :          have a particular size, we have to stick to that assumption
    7111              :          regardless of how the function has changed since.  */
    7112      7898487 :       if (count)
    7113      2618212 :         count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
    7114      7898487 :       if (node->frequency < NODE_FREQUENCY_NORMAL
    7115      7197866 :           || (flag_branch_probabilities
    7116          966 :               && node->frequency < NODE_FREQUENCY_HOT))
    7117       700941 :         m->use_fast_prologue_epilogue = false;
    7118              :       else
    7119              :         {
    7120      7197546 :           if (count != frame->expensive_count)
    7121              :             {
    7122       286048 :               frame->expensive_count = count;
    7123       286048 :               frame->expensive_p = expensive_function_p (count);
    7124              :             }
    7125      7197546 :           m->use_fast_prologue_epilogue = !frame->expensive_p;
    7126              :         }
    7127              :     }
    7128              : 
    7129      8235665 :   frame->save_regs_using_mov
    7130      8235665 :     = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
    7131              : 
    7132              :   /* Skip return address and error code in exception handler.  */
    7133      8235665 :   offset = INCOMING_FRAME_SP_OFFSET;
    7134              : 
    7135              :   /* Skip pushed static chain.  */
    7136      8235665 :   if (ix86_static_chain_on_stack)
    7137            0 :     offset += UNITS_PER_WORD;
    7138              : 
    7139              :   /* Skip saved base pointer.  */
    7140      8235665 :   if (frame_pointer_needed)
    7141      2806881 :     offset += UNITS_PER_WORD;
    7142      8235665 :   frame->hfp_save_offset = offset;
    7143              : 
    7144              :   /* The traditional frame pointer location is at the top of the frame.  */
    7145      8235665 :   frame->hard_frame_pointer_offset = offset;
    7146              : 
    7147              :   /* Register save area */
    7148      8235665 :   offset += frame->nregs * UNITS_PER_WORD;
    7149      8235665 :   frame->reg_save_offset = offset;
    7150              : 
    7151              :   /* Calculate the size of the va-arg area (not including padding, if any).  */
    7152      8235665 :   frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
    7153              : 
    7154              :   /* Also adjust stack_realign_offset for the largest alignment of
    7155              :      stack slot actually used.  */
    7156      8235665 :   if (stack_realign_fp
    7157      7931667 :       || (cfun->machine->max_used_stack_alignment != 0
    7158          186 :           && (offset % cfun->machine->max_used_stack_alignment) != 0))
    7159              :     {
    7160              :       /* We may need a 16-byte aligned stack for the remainder of the
    7161              :          register save area, but the stack frame for the local function
    7162              :          may require a greater alignment if using AVX/2/512.  In order
    7163              :          to avoid wasting space, we first calculate the space needed for
    7164              :          the rest of the register saves, add that to the stack pointer,
    7165              :          and then realign the stack to the boundary of the start of the
    7166              :          frame for the local function.  */
    7167       304083 :       HOST_WIDE_INT space_needed = 0;
    7168       304083 :       HOST_WIDE_INT sse_reg_space_needed = 0;
    7169              : 
    7170       304083 :       if (TARGET_64BIT)
    7171              :         {
    7172       302298 :           if (m->call_ms2sysv)
    7173              :             {
    7174         6415 :               m->call_ms2sysv_pad_in = 0;
    7175         6415 :               space_needed = xlogue_layout::get_instance ().get_stack_space_used ();
    7176              :             }
    7177              : 
    7178       295883 :           else if (frame->nsseregs)
    7179              :             /* The only ABI that has saved SSE registers (Win64) also has a
    7180              :                16-byte aligned default stack.  However, many programs violate
    7181              :                the ABI, and Wine64 forces stack realignment to compensate.  */
    7182         6447 :             space_needed = frame->nsseregs * 16;
    7183              : 
    7184       302298 :           sse_reg_space_needed = space_needed = ROUND_UP (space_needed, 16);
    7185              : 
    7186              :           /* 64-bit frame->va_arg_size should always be a multiple of 16, but
    7187              :              rounding to be pedantic.  */
    7188       302298 :           space_needed = ROUND_UP (space_needed + frame->va_arg_size, 16);
    7189              :         }
    7190              :       else
    7191         1785 :         space_needed = frame->va_arg_size;
    7192              : 
    7193              :       /* Record the allocation size required prior to the realignment AND.  */
    7194       304083 :       frame->stack_realign_allocate = space_needed;
    7195              : 
    7196              :       /* The re-aligned stack starts at frame->stack_realign_offset.  Values
    7197              :          before this point are not directly comparable with values below
    7198              :          this point.  Use sp_valid_at to determine if the stack pointer is
    7199              :          valid for a given offset, fp_valid_at for the frame pointer, or
    7200              :          choose_baseaddr to have a base register chosen for you.
    7201              : 
    7202              :          Note that the result of (frame->stack_realign_offset
    7203              :          & (stack_alignment_needed - 1)) may not equal zero.  */
    7204       304083 :       offset = ROUND_UP (offset + space_needed, stack_alignment_needed);
    7205       304083 :       frame->stack_realign_offset = offset - space_needed;
    7206       304083 :       frame->sse_reg_save_offset = frame->stack_realign_offset
    7207       304083 :                                                         + sse_reg_space_needed;
    7208       304083 :     }
    7209              :   else
    7210              :     {
    7211      7931582 :       frame->stack_realign_offset = offset;
    7212              : 
    7213      7931582 :       if (TARGET_64BIT && m->call_ms2sysv)
    7214              :         {
    7215        28810 :           m->call_ms2sysv_pad_in = !!(offset & UNITS_PER_WORD);
    7216        28810 :           offset += xlogue_layout::get_instance ().get_stack_space_used ();
    7217              :         }
    7218              : 
    7219              :       /* Align and set SSE register save area.  */
    7220      7902772 :       else if (frame->nsseregs)
    7221              :         {
    7222              :           /* If the incoming stack boundary is at least 16 bytes, or DRAP is
    7223              :              required and the DRAP re-alignment boundary is at least 16 bytes,
    7224              :              then we want the SSE register save area properly aligned.  */
    7225       183315 :           if (ix86_incoming_stack_boundary >= 128
    7226         6400 :                   || (stack_realign_drap && stack_alignment_needed >= 16))
    7227       183315 :             offset = ROUND_UP (offset, 16);
    7228       183315 :           offset += frame->nsseregs * 16;
    7229              :         }
    7230      7931582 :       frame->sse_reg_save_offset = offset;
    7231      7931582 :       offset += frame->va_arg_size;
    7232              :     }
    7233              : 
    7234              :   /* Align start of frame for local function.  When a function call
    7235              :      is removed, it may become a leaf function.  But if argument may
    7236              :      be passed on stack, we need to align the stack when there is no
    7237              :      tail call.  */
    7238      8235665 :   if (m->call_ms2sysv
    7239      8200440 :       || frame->va_arg_size != 0
    7240      8121052 :       || size != 0
    7241      4414325 :       || !crtl->is_leaf
    7242      2065773 :       || (!crtl->tail_call_emit
    7243      1747896 :           && cfun->machine->outgoing_args_on_stack)
    7244      2065723 :       || cfun->calls_alloca
    7245     10299679 :       || ix86_current_function_calls_tls_descriptor)
    7246      6172065 :     offset = ROUND_UP (offset, stack_alignment_needed);
    7247              : 
    7248              :   /* Frame pointer points here.  */
    7249      8235665 :   frame->frame_pointer_offset = offset;
    7250              : 
    7251      8235665 :   offset += size;
    7252              : 
    7253              :   /* Add outgoing arguments area.  Can be skipped if we eliminated
    7254              :      all the function calls as dead code.
    7255              :      Skipping is however impossible when function calls alloca.  Alloca
    7256              :      expander assumes that last crtl->outgoing_args_size
    7257              :      of stack frame are unused.  */
    7258      8235665 :   if (ACCUMULATE_OUTGOING_ARGS
    7259      8854266 :       && (!crtl->is_leaf || cfun->calls_alloca
    7260       392255 :           || ix86_current_function_calls_tls_descriptor))
    7261              :     {
    7262       226346 :       offset += crtl->outgoing_args_size;
    7263       226346 :       frame->outgoing_arguments_size = crtl->outgoing_args_size;
    7264              :     }
    7265              :   else
    7266      8009319 :     frame->outgoing_arguments_size = 0;
    7267              : 
    7268              :   /* Align stack boundary.  Only needed if we're calling another function
    7269              :      or using alloca.  */
    7270      2788026 :   if (!crtl->is_leaf || cfun->calls_alloca
    7271     11020308 :       || ix86_current_function_calls_tls_descriptor)
    7272      5452832 :     offset = ROUND_UP (offset, preferred_alignment);
    7273              : 
    7274              :   /* We've reached end of stack frame.  */
    7275      8235665 :   frame->stack_pointer_offset = offset;
    7276              : 
    7277              :   /* Size prologue needs to allocate.  */
    7278      8235665 :   to_allocate = offset - frame->sse_reg_save_offset;
    7279              : 
    7280      8235665 :   if (save_regs_using_push_pop (to_allocate))
    7281      2594980 :     frame->save_regs_using_mov = false;
    7282              : 
    7283      8235665 :   if (ix86_using_red_zone ()
    7284      7206195 :       && crtl->sp_is_unchanging
    7285      6560321 :       && crtl->is_leaf
    7286      2688238 :       && !cfun->machine->asm_redzone_clobber_seen
    7287      2688225 :       && !ix86_pc_thunk_call_expanded
    7288     10923890 :       && !ix86_current_function_calls_tls_descriptor)
    7289              :     {
    7290      2688210 :       frame->red_zone_size = to_allocate;
    7291      2688210 :       if (frame->save_regs_using_mov)
    7292       139941 :         frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
    7293      2688210 :       if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
    7294       102669 :         frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
    7295              :     }
    7296              :   else
    7297      5547455 :     frame->red_zone_size = 0;
    7298      8235665 :   frame->stack_pointer_offset -= frame->red_zone_size;
    7299              : 
    7300              :   /* The SEH frame pointer location is near the bottom of the frame.
    7301              :      This is enforced by the fact that the difference between the
    7302              :      stack pointer and the frame pointer is limited to 240 bytes in
    7303              :      the unwind data structure.  */
    7304      8235665 :   if (TARGET_SEH)
    7305              :     {
    7306              :       /* Force the frame pointer to point at or below the lowest register save
    7307              :          area, see the SEH code in config/i386/winnt.cc for the rationale.  */
    7308              :       frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
    7309              : 
    7310              :       /* If we can leave the frame pointer where it is, do so; however return
    7311              :          the establisher frame for __builtin_frame_address (0) or else if the
    7312              :          frame overflows the SEH maximum frame size.
    7313              : 
    7314              :          Note that the value returned by __builtin_frame_address (0) is quite
    7315              :          constrained, because setjmp is piggybacked on the SEH machinery with
    7316              :          recent versions of MinGW:
    7317              : 
    7318              :           #    elif defined(__SEH__)
    7319              :           #     if defined(__aarch64__) || defined(_ARM64_)
    7320              :           #      define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
    7321              :           #     elif (__MINGW_GCC_VERSION < 40702)
    7322              :           #      define setjmp(BUF) _setjmp((BUF), mingw_getsp())
    7323              :           #     else
    7324              :           #      define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
    7325              :           #     endif
    7326              : 
    7327              :          and the second argument passed to _setjmp, if not null, is forwarded
    7328              :          to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
    7329              :          built an ExceptionRecord on the fly describing the setjmp buffer).  */
    7330              :       const HOST_WIDE_INT diff
    7331              :         = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
    7332              :       if (diff <= 255 && !crtl->accesses_prior_frames)
    7333              :         {
    7334              :           /* The resulting diff will be a multiple of 16 lower than 255,
    7335              :              i.e. at most 240 as required by the unwind data structure.  */
    7336              :           frame->hard_frame_pointer_offset += (diff & 15);
    7337              :         }
    7338              :       else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
    7339              :         {
    7340              :           /* Ideally we'd determine what portion of the local stack frame
    7341              :              (within the constraint of the lowest 240) is most heavily used.
    7342              :              But without that complication, simply bias the frame pointer
    7343              :              by 128 bytes so as to maximize the amount of the local stack
    7344              :              frame that is addressable with 8-bit offsets.  */
    7345              :           frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
    7346              :         }
    7347              :       else
    7348              :         frame->hard_frame_pointer_offset = frame->hfp_save_offset;
    7349              :     }
    7350      8235665 : }
    7351              : 
    7352              : /* This is semi-inlined memory_address_length, but simplified
    7353              :    since we know that we're always dealing with reg+offset, and
    7354              :    to avoid having to create and discard all that rtl.  */
    7355              : 
    7356              : static inline int
    7357      1012933 : choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
    7358              : {
    7359      1012933 :   int len = 4;
    7360              : 
    7361            0 :   if (offset == 0)
    7362              :     {
    7363              :       /* EBP and R13 cannot be encoded without an offset.  */
    7364            0 :       len = (regno == BP_REG || regno == R13_REG);
    7365              :     }
    7366      1004845 :   else if (IN_RANGE (offset, -128, 127))
    7367       631716 :     len = 1;
    7368              : 
    7369              :   /* ESP and R12 must be encoded with a SIB byte.  */
    7370            0 :   if (regno == SP_REG || regno == R12_REG)
    7371            0 :     len++;
    7372              : 
    7373      1012933 :   return len;
    7374              : }
    7375              : 
    7376              : /* Determine if the stack pointer is valid for accessing the CFA_OFFSET in
    7377              :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7378              : 
    7379              : static bool
    7380      3510082 : sp_valid_at (HOST_WIDE_INT cfa_offset)
    7381              : {
    7382      3510082 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7383      3510082 :   if (fs.sp_realigned && cfa_offset <= fs.sp_realigned_offset)
    7384              :     {
    7385              :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7386        45724 :       gcc_assert (cfa_offset <= fs.sp_realigned_fp_last);
    7387              :       return false;
    7388              :     }
    7389      3464358 :   return fs.sp_valid;
    7390              : }
    7391              : 
    7392              : /* Determine if the frame pointer is valid for accessing the CFA_OFFSET in
    7393              :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7394              : 
    7395              : static inline bool
    7396      1359781 : fp_valid_at (HOST_WIDE_INT cfa_offset)
    7397              : {
    7398      1359781 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7399      1359781 :   if (fs.sp_realigned && cfa_offset > fs.sp_realigned_fp_last)
    7400              :     {
    7401              :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7402        28328 :       gcc_assert (cfa_offset >= fs.sp_realigned_offset);
    7403              :       return false;
    7404              :     }
    7405      1331453 :   return fs.fp_valid;
    7406              : }
    7407              : 
    7408              : /* Choose a base register based upon alignment requested, speed and/or
    7409              :    size.  */
    7410              : 
    7411              : static void
    7412      1359781 : choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
    7413              :                 HOST_WIDE_INT &base_offset,
    7414              :                 unsigned int align_reqested, unsigned int *align)
    7415              : {
    7416      1359781 :   const struct machine_function *m = cfun->machine;
    7417      1359781 :   unsigned int hfp_align;
    7418      1359781 :   unsigned int drap_align;
    7419      1359781 :   unsigned int sp_align;
    7420      1359781 :   bool hfp_ok  = fp_valid_at (cfa_offset);
    7421      1359781 :   bool drap_ok = m->fs.drap_valid;
    7422      1359781 :   bool sp_ok   = sp_valid_at (cfa_offset);
    7423              : 
    7424      1359781 :   hfp_align = drap_align = sp_align = INCOMING_STACK_BOUNDARY;
    7425              : 
    7426              :   /* Filter out any registers that don't meet the requested alignment
    7427              :      criteria.  */
    7428      1359781 :   if (align_reqested)
    7429              :     {
    7430       963312 :       if (m->fs.realigned)
    7431        28160 :         hfp_align = drap_align = sp_align = crtl->stack_alignment_needed;
    7432              :       /* SEH unwind code does do not currently support REG_CFA_EXPRESSION
    7433              :          notes (which we would need to use a realigned stack pointer),
    7434              :          so disable on SEH targets.  */
    7435       935152 :       else if (m->fs.sp_realigned)
    7436        28328 :         sp_align = crtl->stack_alignment_needed;
    7437              : 
    7438       963312 :       hfp_ok = hfp_ok && hfp_align >= align_reqested;
    7439       963312 :       drap_ok = drap_ok && drap_align >= align_reqested;
    7440       963312 :       sp_ok = sp_ok && sp_align >= align_reqested;
    7441              :     }
    7442              : 
    7443      1359781 :   if (m->use_fast_prologue_epilogue)
    7444              :     {
    7445              :       /* Choose the base register most likely to allow the most scheduling
    7446              :          opportunities.  Generally FP is valid throughout the function,
    7447              :          while DRAP must be reloaded within the epilogue.  But choose either
    7448              :          over the SP due to increased encoding size.  */
    7449              : 
    7450       642177 :       if (hfp_ok)
    7451              :         {
    7452       118543 :           base_reg = hard_frame_pointer_rtx;
    7453       118543 :           base_offset = m->fs.fp_offset - cfa_offset;
    7454              :         }
    7455       523634 :       else if (drap_ok)
    7456              :         {
    7457            0 :           base_reg = crtl->drap_reg;
    7458            0 :           base_offset = 0 - cfa_offset;
    7459              :         }
    7460       523634 :       else if (sp_ok)
    7461              :         {
    7462       523634 :           base_reg = stack_pointer_rtx;
    7463       523634 :           base_offset = m->fs.sp_offset - cfa_offset;
    7464              :         }
    7465              :     }
    7466              :   else
    7467              :     {
    7468       717604 :       HOST_WIDE_INT toffset;
    7469       717604 :       int len = 16, tlen;
    7470              : 
    7471              :       /* Choose the base register with the smallest address encoding.
    7472              :          With a tie, choose FP > DRAP > SP.  */
    7473       717604 :       if (sp_ok)
    7474              :         {
    7475       700284 :           base_reg = stack_pointer_rtx;
    7476       700284 :           base_offset = m->fs.sp_offset - cfa_offset;
    7477      1392480 :           len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
    7478              :         }
    7479       717604 :       if (drap_ok)
    7480              :         {
    7481            0 :           toffset = 0 - cfa_offset;
    7482            0 :           tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
    7483            0 :           if (tlen <= len)
    7484              :             {
    7485            0 :               base_reg = crtl->drap_reg;
    7486            0 :               base_offset = toffset;
    7487            0 :               len = tlen;
    7488              :             }
    7489              :         }
    7490       717604 :       if (hfp_ok)
    7491              :         {
    7492       312649 :           toffset = m->fs.fp_offset - cfa_offset;
    7493       312649 :           tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
    7494       312649 :           if (tlen <= len)
    7495              :             {
    7496       225189 :               base_reg = hard_frame_pointer_rtx;
    7497       225189 :               base_offset = toffset;
    7498              :             }
    7499              :         }
    7500              :     }
    7501              : 
    7502              :     /* Set the align return value.  */
    7503      1359781 :     if (align)
    7504              :       {
    7505       963312 :         if (base_reg == stack_pointer_rtx)
    7506       678380 :           *align = sp_align;
    7507       284932 :         else if (base_reg == crtl->drap_reg)
    7508            0 :           *align = drap_align;
    7509       284932 :         else if (base_reg == hard_frame_pointer_rtx)
    7510       284932 :           *align = hfp_align;
    7511              :       }
    7512      1359781 : }
    7513              : 
    7514              : /* Return an RTX that points to CFA_OFFSET within the stack frame and
    7515              :    the alignment of address.  If ALIGN is non-null, it should point to
    7516              :    an alignment value (in bits) that is preferred or zero and will
    7517              :    receive the alignment of the base register that was selected,
    7518              :    irrespective of rather or not CFA_OFFSET is a multiple of that
    7519              :    alignment value.  If it is possible for the base register offset to be
    7520              :    non-immediate then SCRATCH_REGNO should specify a scratch register to
    7521              :    use.
    7522              : 
    7523              :    The valid base registers are taken from CFUN->MACHINE->FS.  */
    7524              : 
    7525              : static rtx
    7526      1359781 : choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align,
    7527              :                  unsigned int scratch_regno = INVALID_REGNUM)
    7528              : {
    7529      1359781 :   rtx base_reg = NULL;
    7530      1359781 :   HOST_WIDE_INT base_offset = 0;
    7531              : 
    7532              :   /* If a specific alignment is requested, try to get a base register
    7533              :      with that alignment first.  */
    7534      1359781 :   if (align && *align)
    7535       963312 :     choose_basereg (cfa_offset, base_reg, base_offset, *align, align);
    7536              : 
    7537      1359781 :   if (!base_reg)
    7538       396469 :     choose_basereg (cfa_offset, base_reg, base_offset, 0, align);
    7539              : 
    7540      1359781 :   gcc_assert (base_reg != NULL);
    7541              : 
    7542      1359781 :   rtx base_offset_rtx = GEN_INT (base_offset);
    7543              : 
    7544      1410810 :   if (!x86_64_immediate_operand (base_offset_rtx, Pmode))
    7545              :     {
    7546            1 :       gcc_assert (scratch_regno != INVALID_REGNUM);
    7547              : 
    7548            1 :       rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
    7549            1 :       emit_move_insn (scratch_reg, base_offset_rtx);
    7550              : 
    7551            1 :       return gen_rtx_PLUS (Pmode, base_reg, scratch_reg);
    7552              :     }
    7553              : 
    7554      1410809 :   return plus_constant (Pmode, base_reg, base_offset);
    7555              : }
    7556              : 
    7557              : /* Emit code to save registers in the prologue.  */
    7558              : 
    7559              : static void
    7560       429838 : ix86_emit_save_regs (void)
    7561              : {
    7562       429838 :   int regno;
    7563       429838 :   rtx_insn *insn;
    7564       429838 :   bool use_ppx = TARGET_APX_PPX && !crtl->calls_eh_return;
    7565              : 
    7566       429838 :   if (!TARGET_APX_PUSH2POP2
    7567           91 :       || !ix86_can_use_push2pop2 ()
    7568       429927 :       || cfun->machine->func_type != TYPE_NORMAL)
    7569              :     {
    7570     39966750 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7571     39537000 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7572              :           {
    7573      1203723 :             insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7574              :                                         use_ppx));
    7575      1203723 :             RTX_FRAME_RELATED_P (insn) = 1;
    7576              :           }
    7577              :     }
    7578              :   else
    7579              :     {
    7580           88 :       int regno_list[2];
    7581           88 :       regno_list[0] = regno_list[1] = -1;
    7582           88 :       int loaded_regnum = 0;
    7583           88 :       bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
    7584              : 
    7585         8184 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7586         8096 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7587              :           {
    7588          128 :             if (aligned)
    7589              :               {
    7590           45 :                 regno_list[loaded_regnum++] = regno;
    7591           45 :                 if (loaded_regnum == 2)
    7592              :                   {
    7593           19 :                     gcc_assert (regno_list[0] != -1
    7594              :                                 && regno_list[1] != -1
    7595              :                                 && regno_list[0] != regno_list[1]);
    7596           19 :                     const int offset = UNITS_PER_WORD * 2;
    7597           19 :                     rtx mem = gen_rtx_MEM (TImode,
    7598           19 :                                            gen_rtx_PRE_DEC (Pmode,
    7599              :                                                             stack_pointer_rtx));
    7600           19 :                     insn = emit_insn (gen_push2 (mem,
    7601              :                                                  gen_rtx_REG (word_mode,
    7602              :                                                               regno_list[0]),
    7603              :                                                  gen_rtx_REG (word_mode,
    7604              :                                                               regno_list[1]),
    7605              :                                                  use_ppx));
    7606           19 :                     RTX_FRAME_RELATED_P (insn) = 1;
    7607           19 :                     rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
    7608              : 
    7609           57 :                     for (int i = 0; i < 2; i++)
    7610              :                       {
    7611           76 :                         rtx dwarf_reg = gen_rtx_REG (word_mode,
    7612           38 :                                                      regno_list[i]);
    7613           38 :                         rtx sp_offset = plus_constant (Pmode,
    7614              :                                                        stack_pointer_rtx,
    7615           38 :                                                        + UNITS_PER_WORD
    7616           38 :                                                          * (1 - i));
    7617           38 :                         rtx tmp = gen_rtx_SET (gen_frame_mem (DImode,
    7618              :                                                               sp_offset),
    7619              :                                                dwarf_reg);
    7620           38 :                         RTX_FRAME_RELATED_P (tmp) = 1;
    7621           38 :                         XVECEXP (dwarf, 0, i + 1) = tmp;
    7622              :                       }
    7623           19 :                     rtx sp_tmp = gen_rtx_SET (stack_pointer_rtx,
    7624              :                                               plus_constant (Pmode,
    7625              :                                                              stack_pointer_rtx,
    7626              :                                                              -offset));
    7627           19 :                     RTX_FRAME_RELATED_P (sp_tmp) = 1;
    7628           19 :                     XVECEXP (dwarf, 0, 0) = sp_tmp;
    7629           19 :                     add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
    7630              : 
    7631           19 :                     loaded_regnum = 0;
    7632           19 :                     regno_list[0] = regno_list[1] = -1;
    7633              :                   }
    7634              :               }
    7635              :             else
    7636              :               {
    7637           83 :                 insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7638              :                                             use_ppx));
    7639           83 :                 RTX_FRAME_RELATED_P (insn) = 1;
    7640           83 :                 aligned = true;
    7641              :               }
    7642              :           }
    7643           88 :       if (loaded_regnum == 1)
    7644              :         {
    7645            7 :           insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
    7646            7 :                                                    regno_list[0]),
    7647              :                                       use_ppx));
    7648            7 :           RTX_FRAME_RELATED_P (insn) = 1;
    7649              :         }
    7650              :     }
    7651       429838 : }
    7652              : 
    7653              : /* Emit a single register save at CFA - CFA_OFFSET.  */
    7654              : 
    7655              : static void
    7656       609117 : ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
    7657              :                               HOST_WIDE_INT cfa_offset)
    7658              : {
    7659       609117 :   struct machine_function *m = cfun->machine;
    7660       609117 :   rtx reg = gen_rtx_REG (mode, regno);
    7661       609117 :   rtx mem, addr, base, insn;
    7662       609117 :   unsigned int align = GET_MODE_ALIGNMENT (mode);
    7663              : 
    7664       609117 :   addr = choose_baseaddr (cfa_offset, &align);
    7665       609117 :   mem = gen_frame_mem (mode, addr);
    7666              : 
    7667              :   /* The location alignment depends upon the base register.  */
    7668       609117 :   align = MIN (GET_MODE_ALIGNMENT (mode), align);
    7669       609117 :   gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
    7670       609117 :   set_mem_align (mem, align);
    7671              : 
    7672       609117 :   insn = emit_insn (gen_rtx_SET (mem, reg));
    7673       609117 :   RTX_FRAME_RELATED_P (insn) = 1;
    7674              : 
    7675       609117 :   base = addr;
    7676       609117 :   if (GET_CODE (base) == PLUS)
    7677       597424 :     base = XEXP (base, 0);
    7678       609117 :   gcc_checking_assert (REG_P (base));
    7679              : 
    7680              :   /* When saving registers into a re-aligned local stack frame, avoid
    7681              :      any tricky guessing by dwarf2out.  */
    7682       609117 :   if (m->fs.realigned)
    7683              :     {
    7684        12800 :       gcc_checking_assert (stack_realign_drap);
    7685              : 
    7686        12800 :       if (regno == REGNO (crtl->drap_reg))
    7687              :         {
    7688              :           /* A bit of a hack.  We force the DRAP register to be saved in
    7689              :              the re-aligned stack frame, which provides us with a copy
    7690              :              of the CFA that will last past the prologue.  Install it.  */
    7691            0 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7692            0 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7693            0 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7694            0 :           mem = gen_rtx_MEM (mode, addr);
    7695            0 :           add_reg_note (insn, REG_CFA_DEF_CFA, mem);
    7696              :         }
    7697              :       else
    7698              :         {
    7699              :           /* The frame pointer is a stable reference within the
    7700              :              aligned frame.  Use it.  */
    7701        12800 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7702        12800 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7703        12800 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7704        12800 :           mem = gen_rtx_MEM (mode, addr);
    7705        12800 :           add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7706              :         }
    7707              :     }
    7708              : 
    7709       596317 :   else if (base == stack_pointer_rtx && m->fs.sp_realigned
    7710        12881 :            && cfa_offset >= m->fs.sp_realigned_offset)
    7711              :     {
    7712        12881 :       gcc_checking_assert (stack_realign_fp);
    7713        12881 :       add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7714              :     }
    7715              : 
    7716              :   /* The memory may not be relative to the current CFA register,
    7717              :      which means that we may need to generate a new pattern for
    7718              :      use by the unwind info.  */
    7719       583436 :   else if (base != m->fs.cfa_reg)
    7720              :     {
    7721        43473 :       addr = plus_constant (Pmode, m->fs.cfa_reg,
    7722        43473 :                             m->fs.cfa_offset - cfa_offset);
    7723        43473 :       mem = gen_rtx_MEM (mode, addr);
    7724        43473 :       add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
    7725              :     }
    7726       609117 : }
    7727              : 
    7728              : /* Emit code to save registers using MOV insns.
    7729              :    First register is stored at CFA - CFA_OFFSET.  */
    7730              : static void
    7731        44306 : ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7732              : {
    7733        44306 :   unsigned int regno;
    7734              : 
    7735      4120458 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7736      4076152 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7737              :       {
    7738              :         /* Skip registers, already processed by shrink wrap separate.  */
    7739       187986 :         if (!cfun->machine->reg_is_wrapped_separately[regno])
    7740        82234 :           ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
    7741       202698 :         cfa_offset -= UNITS_PER_WORD;
    7742              :       }
    7743        44306 : }
    7744              : 
    7745              : /* Emit code to save SSE registers using MOV insns.
    7746              :    First register is stored at CFA - CFA_OFFSET.  */
    7747              : static void
    7748        33376 : ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7749              : {
    7750        33376 :   unsigned int regno;
    7751              : 
    7752      3103968 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7753      3070592 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7754              :       {
    7755       333769 :         ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
    7756       333769 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
    7757              :       }
    7758        33376 : }
    7759              : 
    7760              : static GTY(()) rtx queued_cfa_restores;
    7761              : 
    7762              : /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
    7763              :    manipulation insn.  The value is on the stack at CFA - CFA_OFFSET.
    7764              :    Don't add the note if the previously saved value will be left untouched
    7765              :    within stack red-zone till return, as unwinders can find the same value
    7766              :    in the register and on the stack.  */
    7767              : 
    7768              : static void
    7769      2297500 : ix86_add_cfa_restore_note (rtx_insn *insn, rtx reg, HOST_WIDE_INT cfa_offset)
    7770              : {
    7771      2297500 :   if (!crtl->shrink_wrapped
    7772      2278718 :       && cfa_offset <= cfun->machine->fs.red_zone_offset)
    7773              :     return;
    7774              : 
    7775       770146 :   if (insn)
    7776              :     {
    7777       359583 :       add_reg_note (insn, REG_CFA_RESTORE, reg);
    7778       359583 :       RTX_FRAME_RELATED_P (insn) = 1;
    7779              :     }
    7780              :   else
    7781       410563 :     queued_cfa_restores
    7782       410563 :       = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
    7783              : }
    7784              : 
    7785              : /* Add queued REG_CFA_RESTORE notes if any to INSN.  */
    7786              : 
    7787              : static void
    7788      2569796 : ix86_add_queued_cfa_restore_notes (rtx insn)
    7789              : {
    7790      2569796 :   rtx last;
    7791      2569796 :   if (!queued_cfa_restores)
    7792              :     return;
    7793       410563 :   for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
    7794              :     ;
    7795        52951 :   XEXP (last, 1) = REG_NOTES (insn);
    7796        52951 :   REG_NOTES (insn) = queued_cfa_restores;
    7797        52951 :   queued_cfa_restores = NULL_RTX;
    7798        52951 :   RTX_FRAME_RELATED_P (insn) = 1;
    7799              : }
    7800              : 
    7801              : /* Expand prologue or epilogue stack adjustment.
    7802              :    The pattern exist to put a dependency on all ebp-based memory accesses.
    7803              :    STYLE should be negative if instructions should be marked as frame related,
    7804              :    zero if %r11 register is live and cannot be freely used and positive
    7805              :    otherwise.  */
    7806              : 
    7807              : static rtx
    7808      1593813 : pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
    7809              :                            int style, bool set_cfa)
    7810              : {
    7811      1593813 :   struct machine_function *m = cfun->machine;
    7812      1593813 :   rtx addend = offset;
    7813      1593813 :   rtx insn;
    7814      1593813 :   bool add_frame_related_expr = false;
    7815              : 
    7816      1812534 :   if (!x86_64_immediate_operand (offset, Pmode))
    7817              :     {
    7818              :       /* r11 is used by indirect sibcall return as well, set before the
    7819              :          epilogue and used after the epilogue.  */
    7820          199 :       if (style)
    7821          174 :         addend = gen_rtx_REG (Pmode, R11_REG);
    7822              :       else
    7823              :         {
    7824           25 :           gcc_assert (src != hard_frame_pointer_rtx
    7825              :                       && dest != hard_frame_pointer_rtx);
    7826              :           addend = hard_frame_pointer_rtx;
    7827              :         }
    7828          199 :       emit_insn (gen_rtx_SET (addend, offset));
    7829          199 :       if (style < 0)
    7830           88 :         add_frame_related_expr = true;
    7831              :     }
    7832              : 
    7833              :   /*  Shrink wrap separate may insert prologue between TEST and JMP.  In order
    7834              :       not to affect EFlags, emit add without reg clobbering.  */
    7835      1593813 :   if (crtl->shrink_wrapped_separate)
    7836        93623 :     insn = emit_insn (gen_pro_epilogue_adjust_stack_add_nocc
    7837        93623 :                       (Pmode, dest, src, addend));
    7838              :   else
    7839      1500190 :     insn = emit_insn (gen_pro_epilogue_adjust_stack_add
    7840      1500190 :                       (Pmode, dest, src, addend));
    7841              : 
    7842      1593813 :   if (style >= 0)
    7843       701880 :     ix86_add_queued_cfa_restore_notes (insn);
    7844              : 
    7845      1593813 :   if (set_cfa)
    7846              :     {
    7847      1229603 :       rtx r;
    7848              : 
    7849      1229603 :       gcc_assert (m->fs.cfa_reg == src);
    7850      1229603 :       m->fs.cfa_offset += INTVAL (offset);
    7851      1229603 :       m->fs.cfa_reg = dest;
    7852              : 
    7853      1425929 :       r = gen_rtx_PLUS (Pmode, src, offset);
    7854      1229603 :       r = gen_rtx_SET (dest, r);
    7855      1229603 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
    7856      1229603 :       RTX_FRAME_RELATED_P (insn) = 1;
    7857              :     }
    7858       364210 :   else if (style < 0)
    7859              :     {
    7860       298140 :       RTX_FRAME_RELATED_P (insn) = 1;
    7861       298140 :       if (add_frame_related_expr)
    7862              :         {
    7863           20 :           rtx r = gen_rtx_PLUS (Pmode, src, offset);
    7864           20 :           r = gen_rtx_SET (dest, r);
    7865           20 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
    7866              :         }
    7867              :     }
    7868              : 
    7869      1593813 :   if (dest == stack_pointer_rtx)
    7870              :     {
    7871      1593813 :       HOST_WIDE_INT ooffset = m->fs.sp_offset;
    7872      1593813 :       bool valid = m->fs.sp_valid;
    7873      1593813 :       bool realigned = m->fs.sp_realigned;
    7874              : 
    7875      1593813 :       if (src == hard_frame_pointer_rtx)
    7876              :         {
    7877        29572 :           valid = m->fs.fp_valid;
    7878        29572 :           realigned = false;
    7879        29572 :           ooffset = m->fs.fp_offset;
    7880              :         }
    7881      1564241 :       else if (src == crtl->drap_reg)
    7882              :         {
    7883            0 :           valid = m->fs.drap_valid;
    7884            0 :           realigned = false;
    7885            0 :           ooffset = 0;
    7886              :         }
    7887              :       else
    7888              :         {
    7889              :           /* Else there are two possibilities: SP itself, which we set
    7890              :              up as the default above.  Or EH_RETURN_STACKADJ_RTX, which is
    7891              :              taken care of this by hand along the eh_return path.  */
    7892      1564241 :           gcc_checking_assert (src == stack_pointer_rtx
    7893              :                                || offset == const0_rtx);
    7894              :         }
    7895              : 
    7896      1593813 :       m->fs.sp_offset = ooffset - INTVAL (offset);
    7897      1593813 :       m->fs.sp_valid = valid;
    7898      1593813 :       m->fs.sp_realigned = realigned;
    7899              :     }
    7900      1593813 :   return insn;
    7901              : }
    7902              : 
    7903              : /* Find an available register to be used as dynamic realign argument
    7904              :    pointer register.  Such a register will be written in prologue and
    7905              :    used in begin of body, so it must not be
    7906              :         1. parameter passing register.
    7907              :         2. GOT pointer.
    7908              :    We reuse static-chain register if it is available.  Otherwise, we
    7909              :    use DI for i386 and R13 for x86-64.  We chose R13 since it has
    7910              :    shorter encoding.
    7911              : 
    7912              :    Return: the regno of chosen register.  */
    7913              : 
    7914              : static unsigned int
    7915         7240 : find_drap_reg (void)
    7916              : {
    7917         7240 :   tree decl = cfun->decl;
    7918              : 
    7919              :   /* Always use callee-saved register if there are no caller-saved
    7920              :      registers.  */
    7921         7240 :   if (TARGET_64BIT)
    7922              :     {
    7923              :       /* In preserve_none functions, any register can be used for DRAP,
    7924              :          except AX, R12–R15, DI, SI (argument registers), SP, and BP.  */
    7925         6955 :       if (cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE)
    7926              :         return R11_REG;
    7927              : 
    7928              :       /* Use R13 for nested function or function need static chain.
    7929              :          Since function with tail call may use any caller-saved
    7930              :          registers in epilogue, DRAP must not use caller-saved
    7931              :          register in such case.  */
    7932         6954 :       if (DECL_STATIC_CHAIN (decl)
    7933         6912 :           || (cfun->machine->call_saved_registers
    7934              :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7935        13866 :           || crtl->tail_call_emit)
    7936          191 :         return R13_REG;
    7937              : 
    7938              :       return R10_REG;
    7939              :     }
    7940              :   else
    7941              :     {
    7942              :       /* Use DI for nested function or function need static chain.
    7943              :          Since function with tail call may use any caller-saved
    7944              :          registers in epilogue, DRAP must not use caller-saved
    7945              :          register in such case.  */
    7946          285 :       if (DECL_STATIC_CHAIN (decl)
    7947          285 :           || (cfun->machine->call_saved_registers
    7948          285 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7949          285 :           || crtl->tail_call_emit
    7950          550 :           || crtl->calls_eh_return)
    7951              :         return DI_REG;
    7952              : 
    7953              :       /* Reuse static chain register if it isn't used for parameter
    7954              :          passing.  */
    7955          265 :       if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
    7956              :         {
    7957          265 :           unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
    7958          265 :           if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
    7959              :             return CX_REG;
    7960              :         }
    7961            0 :       return DI_REG;
    7962              :     }
    7963              : }
    7964              : 
    7965              : /* Return minimum incoming stack alignment.  */
    7966              : 
    7967              : static unsigned int
    7968      1627677 : ix86_minimum_incoming_stack_boundary (bool sibcall)
    7969              : {
    7970      1627677 :   unsigned int incoming_stack_boundary;
    7971              : 
    7972              :   /* Stack of interrupt handler is aligned to 128 bits in 64bit mode.  */
    7973      1627677 :   if (cfun->machine->func_type != TYPE_NORMAL)
    7974          120 :     incoming_stack_boundary = TARGET_64BIT ? 128 : MIN_STACK_BOUNDARY;
    7975              :   /* Prefer the one specified at command line. */
    7976      1627557 :   else if (ix86_user_incoming_stack_boundary)
    7977              :     incoming_stack_boundary = ix86_user_incoming_stack_boundary;
    7978              :   /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
    7979              :      if -mstackrealign is used, it isn't used for sibcall check and
    7980              :      estimated stack alignment is 128bit.  */
    7981      1627535 :   else if (!sibcall
    7982      1494578 :            && ix86_force_align_arg_pointer
    7983         4572 :            && crtl->stack_alignment_estimated == 128)
    7984          596 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    7985              :   else
    7986      1626939 :     incoming_stack_boundary = ix86_default_incoming_stack_boundary;
    7987              : 
    7988              :   /* Incoming stack alignment can be changed on individual functions
    7989              :      via force_align_arg_pointer attribute.  We use the smallest
    7990              :      incoming stack boundary.  */
    7991      1627677 :   if (incoming_stack_boundary > MIN_STACK_BOUNDARY
    7992      3254748 :       && lookup_attribute ("force_align_arg_pointer",
    7993      1627071 :                            TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
    7994         5708 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    7995              : 
    7996              :   /* The incoming stack frame has to be aligned at least at
    7997              :      parm_stack_boundary.  */
    7998      1627677 :   if (incoming_stack_boundary < crtl->parm_stack_boundary)
    7999              :     incoming_stack_boundary = crtl->parm_stack_boundary;
    8000              : 
    8001              :   /* Stack at entrance of main is aligned by runtime.  We use the
    8002              :      smallest incoming stack boundary. */
    8003      1627677 :   if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
    8004       140955 :       && DECL_NAME (current_function_decl)
    8005       140955 :       && MAIN_NAME_P (DECL_NAME (current_function_decl))
    8006      1630153 :       && DECL_FILE_SCOPE_P (current_function_decl))
    8007         2476 :     incoming_stack_boundary = MAIN_STACK_BOUNDARY;
    8008              : 
    8009      1627677 :   return incoming_stack_boundary;
    8010              : }
    8011              : 
    8012              : /* Update incoming stack boundary and estimated stack alignment.  */
    8013              : 
    8014              : static void
    8015      1494715 : ix86_update_stack_boundary (void)
    8016              : {
    8017      1494715 :   ix86_incoming_stack_boundary
    8018      1494715 :     = ix86_minimum_incoming_stack_boundary (false);
    8019              : 
    8020              :   /* x86_64 vararg needs 16byte stack alignment for register save area.  */
    8021      1494715 :   if (TARGET_64BIT
    8022      1368024 :       && cfun->stdarg
    8023        21433 :       && crtl->stack_alignment_estimated < 128)
    8024        10255 :     crtl->stack_alignment_estimated = 128;
    8025              : 
    8026              :   /* __tls_get_addr needs to be called with 16-byte aligned stack.  */
    8027      1494715 :   if (ix86_tls_descriptor_calls_expanded_in_cfun
    8028         1085 :       && crtl->preferred_stack_boundary < 128)
    8029          750 :     crtl->preferred_stack_boundary = 128;
    8030              : 
    8031              :   /* For 32-bit MS ABI, both the incoming and preferred stack boundaries
    8032              :      are 32 bits, but if force_align_arg_pointer is specified, it should
    8033              :      prefer 128 bits for a backward-compatibility reason, which is also
    8034              :      what the doc suggests.  */
    8035      1494715 :   if (lookup_attribute ("force_align_arg_pointer",
    8036      1494715 :                         TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))
    8037      1494715 :       && crtl->preferred_stack_boundary < 128)
    8038            4 :     crtl->preferred_stack_boundary = 128;
    8039      1494715 : }
    8040              : 
    8041              : /* Handle the TARGET_GET_DRAP_RTX hook.  Return NULL if no DRAP is
    8042              :    needed or an rtx for DRAP otherwise.  */
    8043              : 
    8044              : static rtx
    8045      1601002 : ix86_get_drap_rtx (void)
    8046              : {
    8047              :   /* We must use DRAP if there are outgoing arguments on stack or
    8048              :      the stack pointer register is clobbered by asm statement and
    8049              :      ACCUMULATE_OUTGOING_ARGS is false.  */
    8050      1601002 :   if (ix86_force_drap
    8051      1601002 :       || ((cfun->machine->outgoing_args_on_stack
    8052      1267561 :            || crtl->sp_is_clobbered_by_asm)
    8053       331496 :           && !ACCUMULATE_OUTGOING_ARGS))
    8054       311286 :     crtl->need_drap = true;
    8055              : 
    8056      1601002 :   if (stack_realign_drap)
    8057              :     {
    8058              :       /* Assign DRAP to vDRAP and returns vDRAP */
    8059         7240 :       unsigned int regno = find_drap_reg ();
    8060         7240 :       rtx drap_vreg;
    8061         7240 :       rtx arg_ptr;
    8062         7240 :       rtx_insn *seq, *insn;
    8063              : 
    8064         7525 :       arg_ptr = gen_rtx_REG (Pmode, regno);
    8065         7240 :       crtl->drap_reg = arg_ptr;
    8066              : 
    8067         7240 :       start_sequence ();
    8068         7240 :       drap_vreg = copy_to_reg (arg_ptr);
    8069         7240 :       seq = end_sequence ();
    8070              : 
    8071         7240 :       insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
    8072         7240 :       if (!optimize)
    8073              :         {
    8074         1897 :           add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
    8075         1897 :           RTX_FRAME_RELATED_P (insn) = 1;
    8076              :         }
    8077         7240 :       return drap_vreg;
    8078              :     }
    8079              :   else
    8080              :     return NULL;
    8081              : }
    8082              : 
    8083              : /* Handle the TARGET_INTERNAL_ARG_POINTER hook.  */
    8084              : 
    8085              : static rtx
    8086      1494717 : ix86_internal_arg_pointer (void)
    8087              : {
    8088      1494717 :   return virtual_incoming_args_rtx;
    8089              : }
    8090              : 
    8091              : struct scratch_reg {
    8092              :   rtx reg;
    8093              :   bool saved;
    8094              : };
    8095              : 
    8096              : /* Return a short-lived scratch register for use on function entry.
    8097              :    In 32-bit mode, it is valid only after the registers are saved
    8098              :    in the prologue.  This register must be released by means of
    8099              :    release_scratch_register_on_entry once it is dead.  */
    8100              : 
    8101              : static void
    8102           25 : get_scratch_register_on_entry (struct scratch_reg *sr)
    8103              : {
    8104           25 :   int regno;
    8105              : 
    8106           25 :   sr->saved = false;
    8107              : 
    8108           25 :   if (TARGET_64BIT)
    8109              :     {
    8110              :       /* We always use R11 in 64-bit mode.  */
    8111              :       regno = R11_REG;
    8112              :     }
    8113              :   else
    8114              :     {
    8115            0 :       tree decl = current_function_decl, fntype = TREE_TYPE (decl);
    8116            0 :       bool fastcall_p
    8117            0 :         = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    8118            0 :       bool thiscall_p
    8119            0 :         = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    8120            0 :       bool static_chain_p = DECL_STATIC_CHAIN (decl);
    8121            0 :       int regparm = ix86_function_regparm (fntype, decl);
    8122            0 :       int drap_regno
    8123            0 :         = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
    8124              : 
    8125              :       /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
    8126              :           for the static chain register.  */
    8127            0 :       if ((regparm < 1 || (fastcall_p && !static_chain_p))
    8128            0 :           && drap_regno != AX_REG)
    8129              :         regno = AX_REG;
    8130              :       /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
    8131              :           for the static chain register.  */
    8132            0 :       else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
    8133              :         regno = AX_REG;
    8134            0 :       else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
    8135              :         regno = DX_REG;
    8136              :       /* ecx is the static chain register.  */
    8137            0 :       else if (regparm < 3 && !fastcall_p && !thiscall_p
    8138            0 :                && !static_chain_p
    8139            0 :                && drap_regno != CX_REG)
    8140              :         regno = CX_REG;
    8141            0 :       else if (ix86_save_reg (BX_REG, true, false))
    8142              :         regno = BX_REG;
    8143              :       /* esi is the static chain register.  */
    8144            0 :       else if (!(regparm == 3 && static_chain_p)
    8145            0 :                && ix86_save_reg (SI_REG, true, false))
    8146              :         regno = SI_REG;
    8147            0 :       else if (ix86_save_reg (DI_REG, true, false))
    8148              :         regno = DI_REG;
    8149              :       else
    8150              :         {
    8151            0 :           regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
    8152            0 :           sr->saved = true;
    8153              :         }
    8154              :     }
    8155              : 
    8156           25 :   sr->reg = gen_rtx_REG (Pmode, regno);
    8157           25 :   if (sr->saved)
    8158              :     {
    8159            0 :       rtx_insn *insn = emit_insn (gen_push (sr->reg));
    8160            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    8161              :     }
    8162           25 : }
    8163              : 
    8164              : /* Release a scratch register obtained from the preceding function.
    8165              : 
    8166              :    If RELEASE_VIA_POP is true, we just pop the register off the stack
    8167              :    to release it.  This is what non-Linux systems use with -fstack-check.
    8168              : 
    8169              :    Otherwise we use OFFSET to locate the saved register and the
    8170              :    allocated stack space becomes part of the local frame and is
    8171              :    deallocated by the epilogue.  */
    8172              : 
    8173              : static void
    8174           25 : release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
    8175              :                                    bool release_via_pop)
    8176              : {
    8177           25 :   if (sr->saved)
    8178              :     {
    8179            0 :       if (release_via_pop)
    8180              :         {
    8181            0 :           struct machine_function *m = cfun->machine;
    8182            0 :           rtx x, insn = emit_insn (gen_pop (sr->reg));
    8183              : 
    8184              :           /* The RX FRAME_RELATED_P mechanism doesn't know about pop.  */
    8185            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8186            0 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8187            0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8188            0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
    8189            0 :           m->fs.sp_offset -= UNITS_PER_WORD;
    8190              :         }
    8191              :       else
    8192              :         {
    8193            0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    8194            0 :           x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
    8195            0 :           emit_insn (x);
    8196              :         }
    8197              :     }
    8198           25 : }
    8199              : 
    8200              : /* Emit code to adjust the stack pointer by SIZE bytes while probing it.
    8201              : 
    8202              :    If INT_REGISTERS_SAVED is true, then integer registers have already been
    8203              :    pushed on the stack.
    8204              : 
    8205              :    If PROTECTION AREA is true, then probe PROBE_INTERVAL plus a small dope
    8206              :    beyond SIZE bytes.
    8207              : 
    8208              :    This assumes no knowledge of the current probing state, i.e. it is never
    8209              :    allowed to allocate more than PROBE_INTERVAL bytes of stack space without
    8210              :    a suitable probe.  */
    8211              : 
    8212              : static void
    8213          126 : ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
    8214              :                              const bool int_registers_saved,
    8215              :                              const bool protection_area)
    8216              : {
    8217          126 :   struct machine_function *m = cfun->machine;
    8218              : 
    8219              :   /* If this function does not statically allocate stack space, then
    8220              :      no probes are needed.  */
    8221          126 :   if (!size)
    8222              :     {
    8223              :       /* However, the allocation of space via pushes for register
    8224              :          saves could be viewed as allocating space, but without the
    8225              :          need to probe.  */
    8226           43 :       if (m->frame.nregs || m->frame.nsseregs || frame_pointer_needed)
    8227           23 :         dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8228              :       else
    8229           20 :         dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
    8230           43 :       return;
    8231              :     }
    8232              : 
    8233              :   /* If we are a noreturn function, then we have to consider the
    8234              :      possibility that we're called via a jump rather than a call.
    8235              : 
    8236              :      Thus we don't have the implicit probe generated by saving the
    8237              :      return address into the stack at the call.  Thus, the stack
    8238              :      pointer could be anywhere in the guard page.  The safe thing
    8239              :      to do is emit a probe now.
    8240              : 
    8241              :      The probe can be avoided if we have already emitted any callee
    8242              :      register saves into the stack or have a frame pointer (which will
    8243              :      have been saved as well).  Those saves will function as implicit
    8244              :      probes.
    8245              : 
    8246              :      ?!? This should be revamped to work like aarch64 and s390 where
    8247              :      we track the offset from the most recent probe.  Normally that
    8248              :      offset would be zero.  For a noreturn function we would reset
    8249              :      it to PROBE_INTERVAL - (STACK_BOUNDARY / BITS_PER_UNIT).   Then
    8250              :      we just probe when we cross PROBE_INTERVAL.  */
    8251           83 :   if (TREE_THIS_VOLATILE (cfun->decl)
    8252           15 :       && !(m->frame.nregs || m->frame.nsseregs || frame_pointer_needed))
    8253              :     {
    8254              :       /* We can safely use any register here since we're just going to push
    8255              :          its value and immediately pop it back.  But we do try and avoid
    8256              :          argument passing registers so as not to introduce dependencies in
    8257              :          the pipeline.  For 32 bit we use %esi and for 64 bit we use %rax.  */
    8258           15 :       rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
    8259           15 :       rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
    8260           15 :       rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
    8261           15 :       m->fs.sp_offset -= UNITS_PER_WORD;
    8262           15 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8263              :         {
    8264           15 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    8265           15 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    8266           15 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8267           15 :           add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
    8268           15 :           RTX_FRAME_RELATED_P (insn_push) = 1;
    8269           15 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8270           15 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8271           15 :           add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
    8272           15 :           RTX_FRAME_RELATED_P (insn_pop) = 1;
    8273              :         }
    8274           15 :       emit_insn (gen_blockage ());
    8275              :     }
    8276              : 
    8277           83 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8278           83 :   const int dope = 4 * UNITS_PER_WORD;
    8279              : 
    8280              :   /* If there is protection area, take it into account in the size.  */
    8281           83 :   if (protection_area)
    8282           24 :     size += probe_interval + dope;
    8283              : 
    8284              :   /* If we allocate less than the size of the guard statically,
    8285              :      then no probing is necessary, but we do need to allocate
    8286              :      the stack.  */
    8287           59 :   else if (size < (1 << param_stack_clash_protection_guard_size))
    8288              :     {
    8289           38 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8290              :                                  GEN_INT (-size), -1,
    8291           38 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    8292           38 :       dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8293           38 :       return;
    8294              :     }
    8295              : 
    8296              :   /* We're allocating a large enough stack frame that we need to
    8297              :      emit probes.  Either emit them inline or in a loop depending
    8298              :      on the size.  */
    8299           45 :   if (size <= 4 * probe_interval)
    8300              :     {
    8301              :       HOST_WIDE_INT i;
    8302           47 :       for (i = probe_interval; i <= size; i += probe_interval)
    8303              :         {
    8304              :           /* Allocate PROBE_INTERVAL bytes.  */
    8305           27 :           rtx insn
    8306           27 :             = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8307              :                                          GEN_INT (-probe_interval), -1,
    8308           27 :                                          m->fs.cfa_reg == stack_pointer_rtx);
    8309           27 :           add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
    8310              : 
    8311              :           /* And probe at *sp.  */
    8312           27 :           emit_stack_probe (stack_pointer_rtx);
    8313           27 :           emit_insn (gen_blockage ());
    8314              :         }
    8315              : 
    8316              :       /* We need to allocate space for the residual, but we do not need
    8317              :          to probe the residual...  */
    8318           20 :       HOST_WIDE_INT residual = (i - probe_interval - size);
    8319           20 :       if (residual)
    8320              :         {
    8321           20 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8322              :                                      GEN_INT (residual), -1,
    8323           20 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8324              : 
    8325              :           /* ...except if there is a protection area to maintain.  */
    8326           20 :           if (protection_area)
    8327           11 :             emit_stack_probe (stack_pointer_rtx);
    8328              :         }
    8329              : 
    8330           20 :       dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
    8331              :     }
    8332              :   else
    8333              :     {
    8334              :       /* We expect the GP registers to be saved when probes are used
    8335              :          as the probing sequences might need a scratch register and
    8336              :          the routine to allocate one assumes the integer registers
    8337              :          have already been saved.  */
    8338           25 :       gcc_assert (int_registers_saved);
    8339              : 
    8340           25 :       struct scratch_reg sr;
    8341           25 :       get_scratch_register_on_entry (&sr);
    8342              : 
    8343              :       /* If we needed to save a register, then account for any space
    8344              :          that was pushed (we are not going to pop the register when
    8345              :          we do the restore).  */
    8346           25 :       if (sr.saved)
    8347            0 :         size -= UNITS_PER_WORD;
    8348              : 
    8349              :       /* Step 1: round SIZE down to a multiple of the interval.  */
    8350           25 :       HOST_WIDE_INT rounded_size = size & -probe_interval;
    8351              : 
    8352              :       /* Step 2: compute final value of the loop counter.  Use lea if
    8353              :          possible.  */
    8354           25 :       rtx addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
    8355           25 :       rtx insn;
    8356           25 :       if (address_no_seg_operand (addr, Pmode))
    8357           13 :         insn = emit_insn (gen_rtx_SET (sr.reg, addr));
    8358              :       else
    8359              :         {
    8360           12 :           emit_move_insn (sr.reg, GEN_INT (-rounded_size));
    8361           12 :           insn = emit_insn (gen_rtx_SET (sr.reg,
    8362              :                                          gen_rtx_PLUS (Pmode, sr.reg,
    8363              :                                                        stack_pointer_rtx)));
    8364              :         }
    8365           25 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8366              :         {
    8367           22 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8368           22 :                         plus_constant (Pmode, sr.reg,
    8369           22 :                                        m->fs.cfa_offset + rounded_size));
    8370           22 :           RTX_FRAME_RELATED_P (insn) = 1;
    8371              :         }
    8372              : 
    8373              :       /* Step 3: the loop.  */
    8374           25 :       rtx size_rtx = GEN_INT (rounded_size);
    8375           25 :       insn = emit_insn (gen_adjust_stack_and_probe (Pmode, sr.reg, sr.reg,
    8376              :                                                     size_rtx));
    8377           25 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8378              :         {
    8379           22 :           m->fs.cfa_offset += rounded_size;
    8380           22 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8381           22 :                         plus_constant (Pmode, stack_pointer_rtx,
    8382           22 :                                        m->fs.cfa_offset));
    8383           22 :           RTX_FRAME_RELATED_P (insn) = 1;
    8384              :         }
    8385           25 :       m->fs.sp_offset += rounded_size;
    8386           25 :       emit_insn (gen_blockage ());
    8387              : 
    8388              :       /* Step 4: adjust SP if we cannot assert at compile-time that SIZE
    8389              :          is equal to ROUNDED_SIZE.  */
    8390              : 
    8391           25 :       if (size != rounded_size)
    8392              :         {
    8393           25 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8394              :                                      GEN_INT (rounded_size - size), -1,
    8395           25 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8396              : 
    8397           25 :           if (protection_area)
    8398           13 :             emit_stack_probe (stack_pointer_rtx);
    8399              :         }
    8400              : 
    8401           25 :       dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
    8402              : 
    8403              :       /* This does not deallocate the space reserved for the scratch
    8404              :          register.  That will be deallocated in the epilogue.  */
    8405           25 :       release_scratch_register_on_entry (&sr, size, false);
    8406              :     }
    8407              : 
    8408              :   /* Adjust back to account for the protection area.  */
    8409           45 :   if (protection_area)
    8410           24 :     pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8411           24 :                                GEN_INT (probe_interval + dope), -1,
    8412           24 :                                m->fs.cfa_reg == stack_pointer_rtx);
    8413              : 
    8414              :   /* Make sure nothing is scheduled before we are done.  */
    8415           45 :   emit_insn (gen_blockage ());
    8416              : }
    8417              : 
    8418              : /* Adjust the stack pointer up to REG while probing it.  */
    8419              : 
    8420              : const char *
    8421           25 : output_adjust_stack_and_probe (rtx reg)
    8422              : {
    8423           25 :   static int labelno = 0;
    8424           25 :   char loop_lab[32];
    8425           25 :   rtx xops[2];
    8426              : 
    8427           25 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8428              : 
    8429              :   /* Loop.  */
    8430           25 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8431              : 
    8432              :   /* SP = SP + PROBE_INTERVAL.  */
    8433           25 :   xops[0] = stack_pointer_rtx;
    8434           37 :   xops[1] = GEN_INT (get_probe_interval ());
    8435           25 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8436              : 
    8437              :   /* Probe at SP.  */
    8438           25 :   xops[1] = const0_rtx;
    8439           25 :   output_asm_insn ("or{b}\t{%1, (%0)|BYTE PTR [%0], %1}", xops);
    8440              : 
    8441              :   /* Test if SP == LAST_ADDR.  */
    8442           25 :   xops[0] = stack_pointer_rtx;
    8443           25 :   xops[1] = reg;
    8444           25 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8445              : 
    8446              :   /* Branch.  */
    8447           25 :   fputs ("\tjne\t", asm_out_file);
    8448           25 :   assemble_name_raw (asm_out_file, loop_lab);
    8449           25 :   fputc ('\n', asm_out_file);
    8450              : 
    8451           25 :   return "";
    8452              : }
    8453              : 
    8454              : /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
    8455              :    inclusive.  These are offsets from the current stack pointer.
    8456              : 
    8457              :    INT_REGISTERS_SAVED is true if integer registers have already been
    8458              :    pushed on the stack.  */
    8459              : 
    8460              : static void
    8461            0 : ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
    8462              :                              const bool int_registers_saved)
    8463              : {
    8464            0 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8465              : 
    8466              :   /* See if we have a constant small number of probes to generate.  If so,
    8467              :      that's the easy case.  The run-time loop is made up of 6 insns in the
    8468              :      generic case while the compile-time loop is made up of n insns for n #
    8469              :      of intervals.  */
    8470            0 :   if (size <= 6 * probe_interval)
    8471              :     {
    8472              :       HOST_WIDE_INT i;
    8473              : 
    8474              :       /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
    8475              :          it exceeds SIZE.  If only one probe is needed, this will not
    8476              :          generate any code.  Then probe at FIRST + SIZE.  */
    8477            0 :       for (i = probe_interval; i < size; i += probe_interval)
    8478            0 :         emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8479            0 :                                          -(first + i)));
    8480              : 
    8481            0 :       emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8482            0 :                                        -(first + size)));
    8483              :     }
    8484              : 
    8485              :   /* Otherwise, do the same as above, but in a loop.  Note that we must be
    8486              :      extra careful with variables wrapping around because we might be at
    8487              :      the very top (or the very bottom) of the address space and we have
    8488              :      to be able to handle this case properly; in particular, we use an
    8489              :      equality test for the loop condition.  */
    8490              :   else
    8491              :     {
    8492              :       /* We expect the GP registers to be saved when probes are used
    8493              :          as the probing sequences might need a scratch register and
    8494              :          the routine to allocate one assumes the integer registers
    8495              :          have already been saved.  */
    8496            0 :       gcc_assert (int_registers_saved);
    8497              : 
    8498            0 :       HOST_WIDE_INT rounded_size, last;
    8499            0 :       struct scratch_reg sr;
    8500              : 
    8501            0 :       get_scratch_register_on_entry (&sr);
    8502              : 
    8503              : 
    8504              :       /* Step 1: round SIZE to the previous multiple of the interval.  */
    8505              : 
    8506            0 :       rounded_size = ROUND_DOWN (size, probe_interval);
    8507              : 
    8508              : 
    8509              :       /* Step 2: compute initial and final value of the loop counter.  */
    8510              : 
    8511              :       /* TEST_OFFSET = FIRST.  */
    8512            0 :       emit_move_insn (sr.reg, GEN_INT (-first));
    8513              : 
    8514              :       /* LAST_OFFSET = FIRST + ROUNDED_SIZE.  */
    8515            0 :       last = first + rounded_size;
    8516              : 
    8517              : 
    8518              :       /* Step 3: the loop
    8519              : 
    8520              :          do
    8521              :            {
    8522              :              TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
    8523              :              probe at TEST_ADDR
    8524              :            }
    8525              :          while (TEST_ADDR != LAST_ADDR)
    8526              : 
    8527              :          probes at FIRST + N * PROBE_INTERVAL for values of N from 1
    8528              :          until it is equal to ROUNDED_SIZE.  */
    8529              : 
    8530            0 :       emit_insn
    8531            0 :         (gen_probe_stack_range (Pmode, sr.reg, sr.reg, GEN_INT (-last)));
    8532              : 
    8533              : 
    8534              :       /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
    8535              :          that SIZE is equal to ROUNDED_SIZE.  */
    8536              : 
    8537            0 :       if (size != rounded_size)
    8538            0 :         emit_stack_probe (plus_constant (Pmode,
    8539            0 :                                          gen_rtx_PLUS (Pmode,
    8540              :                                                        stack_pointer_rtx,
    8541              :                                                        sr.reg),
    8542            0 :                                          rounded_size - size));
    8543              : 
    8544            0 :       release_scratch_register_on_entry (&sr, size, true);
    8545              :     }
    8546              : 
    8547              :   /* Make sure nothing is scheduled before we are done.  */
    8548            0 :   emit_insn (gen_blockage ());
    8549            0 : }
    8550              : 
    8551              : /* Probe a range of stack addresses from REG to END, inclusive.  These are
    8552              :    offsets from the current stack pointer.  */
    8553              : 
    8554              : const char *
    8555            0 : output_probe_stack_range (rtx reg, rtx end)
    8556              : {
    8557            0 :   static int labelno = 0;
    8558            0 :   char loop_lab[32];
    8559            0 :   rtx xops[3];
    8560              : 
    8561            0 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8562              : 
    8563              :   /* Loop.  */
    8564            0 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8565              : 
    8566              :   /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
    8567            0 :   xops[0] = reg;
    8568            0 :   xops[1] = GEN_INT (get_probe_interval ());
    8569            0 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8570              : 
    8571              :   /* Probe at TEST_ADDR.  */
    8572            0 :   xops[0] = stack_pointer_rtx;
    8573            0 :   xops[1] = reg;
    8574            0 :   xops[2] = const0_rtx;
    8575            0 :   output_asm_insn ("or{b}\t{%2, (%0,%1)|BYTE PTR [%0+%1], %2}", xops);
    8576              : 
    8577              :   /* Test if TEST_ADDR == LAST_ADDR.  */
    8578            0 :   xops[0] = reg;
    8579            0 :   xops[1] = end;
    8580            0 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8581              : 
    8582              :   /* Branch.  */
    8583            0 :   fputs ("\tjne\t", asm_out_file);
    8584            0 :   assemble_name_raw (asm_out_file, loop_lab);
    8585            0 :   fputc ('\n', asm_out_file);
    8586              : 
    8587            0 :   return "";
    8588              : }
    8589              : 
    8590              : /* Data passed to ix86_update_stack_alignment.  */
    8591              : struct stack_access_data
    8592              : {
    8593              :   /* The stack access register.  */
    8594              :   const_rtx reg;
    8595              :   /* Pointer to stack alignment.  */
    8596              :   unsigned int *stack_alignment;
    8597              : };
    8598              : 
    8599              : /* SET stores into OP, a MEM linked to parameter BASE.  Return true if
    8600              :    SET stores BASE's argument register into OP.  This is a spill: the
    8601              :    callee saves its own register argument to the stack.  It is not a
    8602              :    stack argument set up by the caller:
    8603              : 
    8604              :      (set (mem/c:V2DI (plus:DI (reg/f:DI 7 sp)
    8605              :                 (const_int -16 [0xfffffffffffffff0])) [4 a1+0 S16 A128])
    8606              :           (reg:V2DI 20 xmm0 [ a1 ]))
    8607              :  */
    8608              : 
    8609              : static bool
    8610        84993 : ix86_spill_register_argument_p (const_rtx set, const_rtx op, tree base)
    8611              : {
    8612        84993 :   rtx src = SET_SRC (set);
    8613              : 
    8614              :   /* Not a hard register store, so not a spill.  */
    8615        84993 :   if (!REG_P (src) || !HARD_REGISTER_P (src))
    8616              :     return false;
    8617              : 
    8618        24946 :   rtx dest = SET_DEST (set);
    8619        24946 :   tree reg_expr = REG_EXPR (src);
    8620              : 
    8621              :   /* If spilling an SSA_NAME into OP, the argument-linked memory is
    8622              :      also used to store a local variable.  */
    8623        24946 :   return dest == op && (reg_expr == base
    8624         2933 :                         || (reg_expr
    8625          154 :                             && TREE_CODE (reg_expr) == SSA_NAME));
    8626              : }
    8627              : 
    8628              : /* Return true if OP, found in PAT, is a stack argument set up by the
    8629              :    caller.  Return false if OP is a register argument that the callee
    8630              :    spilled to its own stack frame.  Both cases share the same MEM_EXPR,
    8631              :    so we must check PAT to tell them apart.  */
    8632              : 
    8633              : static bool
    8634       112965 : ix86_argument_passed_on_stack_p (const_rtx op, const_rtx pat)
    8635              : {
    8636       112965 :   tree mem_expr = MEM_EXPR (op);
    8637       112965 :   if (!mem_expr)
    8638              :     return false;
    8639              : 
    8640       111083 :   tree var = get_base_address (mem_expr);
    8641       111083 :   if (TREE_CODE (var) != PARM_DECL)
    8642              :     return false;
    8643              : 
    8644              :   /* PAT is always a single SET here: note_stores splits PARALLEL
    8645              :      patterns into separate SETs before calling this function.  */
    8646        84993 :   if (GET_CODE (pat) == SET)
    8647        84993 :     return !ix86_spill_register_argument_p (pat, op, var);
    8648              : 
    8649              :   return true;
    8650              : }
    8651              : 
    8652              : /* Update the maximum stack slot alignment from memory alignment in PAT.  */
    8653              : 
    8654              : static void
    8655       146947 : ix86_update_stack_alignment (rtx, const_rtx pat, void *data)
    8656              : {
    8657              :   /* This insn may reference stack slot.  Update the maximum stack slot
    8658              :      alignment if the memory is referenced by the stack access register. */
    8659       146947 :   stack_access_data *p = (stack_access_data *) data;
    8660              : 
    8661       146947 :   subrtx_iterator::array_type array;
    8662       574907 :   FOR_EACH_SUBRTX (iter, array, pat, ALL)
    8663              :     {
    8664       478008 :       auto op = *iter;
    8665       478008 :       if (MEM_P (op))
    8666              :         {
    8667              :           /* NB: Ignore arguments passed on stack since caller is
    8668              :              responsible to align the outgoing stack for arguments
    8669              :              passed on stack.  */
    8670       143313 :           if (reg_mentioned_p (p->reg, XEXP (op, 0))
    8671       143313 :               && !ix86_argument_passed_on_stack_p (op, pat))
    8672              :             {
    8673        50048 :               unsigned int alignment = MEM_ALIGN (op);
    8674              : 
    8675        50048 :               if (alignment > *p->stack_alignment)
    8676        49962 :                 *p->stack_alignment = alignment;
    8677              :               break;
    8678              :             }
    8679              :           else
    8680        93265 :             iter.skip_subrtxes ();
    8681              :         }
    8682              :     }
    8683       146947 : }
    8684              : 
    8685              : /* Helper function for ix86_find_all_reg_uses.  */
    8686              : 
    8687              : static void
    8688     45780731 : ix86_find_all_reg_uses_1 (HARD_REG_SET &regset,
    8689              :                           rtx set, unsigned int regno,
    8690              :                           auto_bitmap &worklist)
    8691              : {
    8692     45780731 :   rtx dest = SET_DEST (set);
    8693              : 
    8694     45780731 :   if (!REG_P (dest))
    8695     41444210 :     return;
    8696              : 
    8697              :   /* Reject non-Pmode modes.  */
    8698     34646667 :   if (GET_MODE (dest) != Pmode)
    8699              :     return;
    8700              : 
    8701     18451857 :   unsigned int dst_regno = REGNO (dest);
    8702              : 
    8703     18451857 :   if (TEST_HARD_REG_BIT (regset, dst_regno))
    8704              :     return;
    8705              : 
    8706      4336521 :   const_rtx src = SET_SRC (set);
    8707              : 
    8708      4336521 :   subrtx_iterator::array_type array;
    8709      8626912 :   FOR_EACH_SUBRTX (iter, array, src, ALL)
    8710              :     {
    8711      5590054 :       auto op = *iter;
    8712              : 
    8713      5590054 :       if (MEM_P (op))
    8714      3013913 :         iter.skip_subrtxes ();
    8715              : 
    8716      5590054 :       if (REG_P (op) && REGNO (op) == regno)
    8717              :         {
    8718              :           /* Add this register to register set.  */
    8719      1468294 :           add_to_hard_reg_set (&regset, Pmode, dst_regno);
    8720      1299663 :           bitmap_set_bit (worklist, dst_regno);
    8721      1299663 :           break;
    8722              :         }
    8723              :     }
    8724      4336521 : }
    8725              : 
    8726              : /* Find all registers defined with register REGNO.  */
    8727              : 
    8728              : static void
    8729      2327615 : ix86_find_all_reg_uses (HARD_REG_SET &regset,
    8730              :                         unsigned int regno, auto_bitmap &worklist)
    8731              : {
    8732      2327615 :   for (df_ref ref = DF_REG_USE_CHAIN (regno);
    8733     82523658 :        ref != NULL;
    8734     80196043 :        ref = DF_REF_NEXT_REG (ref))
    8735              :     {
    8736     80196043 :       if (DF_REF_IS_ARTIFICIAL (ref))
    8737     16711927 :         continue;
    8738              : 
    8739     63484116 :       rtx_insn *insn = DF_REF_INSN (ref);
    8740              : 
    8741     63484116 :       if (!NONJUMP_INSN_P (insn))
    8742     18404247 :         continue;
    8743              : 
    8744     45079869 :       unsigned int ref_regno = DF_REF_REGNO (ref);
    8745              : 
    8746     45079869 :       rtx set = single_set (insn);
    8747     45079869 :       if (set)
    8748              :         {
    8749     44271752 :           ix86_find_all_reg_uses_1 (regset, set,
    8750              :                                     ref_regno, worklist);
    8751     44271752 :           continue;
    8752              :         }
    8753              : 
    8754       808117 :       rtx pat = PATTERN (insn);
    8755       808117 :       if (GET_CODE (pat) != PARALLEL)
    8756       125731 :         continue;
    8757              : 
    8758      2663279 :       for (int i = 0; i < XVECLEN (pat, 0); i++)
    8759              :         {
    8760      1980893 :           rtx exp = XVECEXP (pat, 0, i);
    8761              : 
    8762      1980893 :           if (GET_CODE (exp) == SET)
    8763      1508979 :             ix86_find_all_reg_uses_1 (regset, exp,
    8764              :                                       ref_regno, worklist);
    8765              :         }
    8766              :     }
    8767      2327615 : }
    8768              : 
    8769              : /* Return true if the hard register REGNO used for a stack access is
    8770              :    defined in a basic block that dominates the block where it is used.  */
    8771              : 
    8772              : static bool
    8773        40071 : ix86_access_stack_p (unsigned int regno, basic_block bb,
    8774              :                      HARD_REG_SET &set_up_by_prologue,
    8775              :                      HARD_REG_SET &prologue_used,
    8776              :                      auto_bitmap reg_dominate_bbs_known[],
    8777              :                      auto_bitmap reg_dominate_bbs[])
    8778              : {
    8779        40071 :   if (bitmap_bit_p (reg_dominate_bbs_known[regno], bb->index))
    8780        11042 :     return bitmap_bit_p (reg_dominate_bbs[regno], bb->index);
    8781              : 
    8782        29029 :   bitmap_set_bit (reg_dominate_bbs_known[regno], bb->index);
    8783              : 
    8784              :   /* Get all BBs which set REGNO and dominate the current BB from all
    8785              :      DEFs of REGNO.  */
    8786        29029 :   for (df_ref def = DF_REG_DEF_CHAIN (regno);
    8787      1524253 :        def;
    8788      1495224 :        def = DF_REF_NEXT_REG (def))
    8789      1522789 :     if (!DF_REF_IS_ARTIFICIAL (def)
    8790      1521086 :         && !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)
    8791      1495890 :         && !DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
    8792              :       {
    8793      1494076 :         basic_block set_bb = DF_REF_BB (def);
    8794      1494076 :         if (dominated_by_p (CDI_DOMINATORS, bb, set_bb))
    8795              :           {
    8796        85228 :             rtx_insn *insn = DF_REF_INSN (def);
    8797              :             /* Return true if INSN requires stack.  */
    8798        85228 :             if (requires_stack_frame_p (insn, prologue_used,
    8799              :                                         set_up_by_prologue))
    8800              :               {
    8801        27565 :                 bitmap_set_bit (reg_dominate_bbs[regno], bb->index);
    8802        27565 :                 return true;
    8803              :               }
    8804              :           }
    8805              :       }
    8806              : 
    8807              :   /* When we get here, REGNO used in the current BB doesn't access
    8808              :      stack.  */
    8809              :   return false;
    8810              : }
    8811              : 
    8812              : /* Return true if OP isn't a memory operand with SYMBOLIC_CONST and
    8813              :    needs alignment > ALIGNMENT.  */
    8814              : 
    8815              : static bool
    8816     27857365 : ix86_need_alignment_p_2 (const_rtx op, unsigned int alignment)
    8817              : {
    8818     27857365 :   bool need_alignment = MEM_ALIGN (op) > alignment;
    8819     27857365 :   tree mem_expr = MEM_EXPR (op);
    8820     27857365 :   if (!mem_expr)
    8821              :     return need_alignment;
    8822              : 
    8823     22965399 :   tree var = get_base_address (mem_expr);
    8824     22965399 :   if (!VAR_P (var) || !DECL_RTL_SET_P (var))
    8825              :     return need_alignment;
    8826              : 
    8827     14541184 :   rtx x = DECL_RTL (var);
    8828     14541184 :   if (!MEM_P (x))
    8829              :     return need_alignment;
    8830              : 
    8831     14541181 :   x = XEXP (x, 0);
    8832     14541181 :   return !SYMBOLIC_CONST (x) && need_alignment;
    8833              : }
    8834              : 
    8835              : /* Return true if SET needs alignment > ALIGNMENT.  */
    8836              : 
    8837              : static bool
    8838     45780000 : ix86_need_alignment_p_1 (rtx set, unsigned int alignment)
    8839              : {
    8840     45780000 :   rtx dest = SET_DEST (set);
    8841              : 
    8842     45780000 :   if (MEM_P (dest))
    8843     17285336 :     return ix86_need_alignment_p_2 (dest, alignment);
    8844              : 
    8845     28494664 :   const_rtx src = SET_SRC (set);
    8846              : 
    8847     28494664 :   subrtx_iterator::array_type array;
    8848     82702412 :   FOR_EACH_SUBRTX (iter, array, src, ALL)
    8849              :     {
    8850     64779777 :       auto op = *iter;
    8851              : 
    8852     64779777 :       if (MEM_P (op))
    8853     10572029 :         return ix86_need_alignment_p_2 (op, alignment);
    8854              :     }
    8855              : 
    8856     17922635 :   return false;
    8857     28494664 : }
    8858              : 
    8859              : /* Return true if INSN needs alignment > ALIGNMENT.  */
    8860              : 
    8861              : static bool
    8862     45079869 : ix86_need_alignment_p (rtx_insn *insn, unsigned int alignment)
    8863              : {
    8864     45079869 :   rtx set = single_set (insn);
    8865     45079869 :   if (set)
    8866     44271752 :     return ix86_need_alignment_p_1 (set, alignment);
    8867              : 
    8868       808117 :   rtx pat = PATTERN (insn);
    8869       808117 :   if (GET_CODE (pat) != PARALLEL)
    8870              :     return false;
    8871              : 
    8872      2661340 :   for (int i = 0; i < XVECLEN (pat, 0); i++)
    8873              :     {
    8874      1979834 :       rtx exp = XVECEXP (pat, 0, i);
    8875              : 
    8876      1979834 :       if (GET_CODE (exp) == SET
    8877      1979834 :           && ix86_need_alignment_p_1 (exp, alignment))
    8878              :         return true;
    8879              :     }
    8880              : 
    8881              :   return false;
    8882              : }
    8883              : 
    8884              : /* Set stack_frame_required to false if stack frame isn't required.
    8885              :    Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
    8886              :    slot used if stack frame is required and CHECK_STACK_SLOT is true.  */
    8887              : 
    8888              : static void
    8889      1493865 : ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
    8890              :                                     bool check_stack_slot)
    8891              : {
    8892      1493865 :   HARD_REG_SET set_up_by_prologue, prologue_used;
    8893      1493865 :   basic_block bb;
    8894              : 
    8895      5975460 :   CLEAR_HARD_REG_SET (prologue_used);
    8896      1493865 :   CLEAR_HARD_REG_SET (set_up_by_prologue);
    8897      1620663 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
    8898      1493865 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
    8899      1493865 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode,
    8900              :                        HARD_FRAME_POINTER_REGNUM);
    8901              : 
    8902      1493865 :   bool require_stack_frame = false;
    8903              : 
    8904     15974175 :   FOR_EACH_BB_FN (bb, cfun)
    8905              :     {
    8906     14480310 :       rtx_insn *insn;
    8907     91160398 :       FOR_BB_INSNS (bb, insn)
    8908     84618629 :         if (NONDEBUG_INSN_P (insn)
    8909     84618629 :             && requires_stack_frame_p (insn, prologue_used,
    8910              :                                        set_up_by_prologue))
    8911              :           {
    8912              :             require_stack_frame = true;
    8913              :             break;
    8914              :           }
    8915              :     }
    8916              : 
    8917      1493865 :   cfun->machine->stack_frame_required = require_stack_frame;
    8918              : 
    8919              :   /* Stop if we don't need to check stack slot.  */
    8920      1493865 :   if (!check_stack_slot)
    8921       794644 :     return;
    8922              : 
    8923              :   /* The preferred stack alignment is the minimum stack alignment.  */
    8924       699221 :   if (stack_alignment > crtl->preferred_stack_boundary)
    8925       142703 :     stack_alignment = crtl->preferred_stack_boundary;
    8926              : 
    8927              :   HARD_REG_SET stack_slot_access;
    8928       699221 :   CLEAR_HARD_REG_SET (stack_slot_access);
    8929              : 
    8930              :   /* Stack slot can be accessed by stack pointer, frame pointer or
    8931              :      registers defined by stack pointer or frame pointer.  */
    8932       699221 :   auto_bitmap worklist;
    8933              : 
    8934       758906 :   add_to_hard_reg_set (&stack_slot_access, Pmode, STACK_POINTER_REGNUM);
    8935       699221 :   bitmap_set_bit (worklist, STACK_POINTER_REGNUM);
    8936              : 
    8937       699221 :   if (frame_pointer_needed)
    8938              :     {
    8939       337780 :       add_to_hard_reg_set (&stack_slot_access, Pmode,
    8940              :                            HARD_FRAME_POINTER_REGNUM);
    8941       328731 :       bitmap_set_bit (worklist, HARD_FRAME_POINTER_REGNUM);
    8942              :     }
    8943              : 
    8944              :   /* Registers on HARD_STACK_SLOT_ACCESS always access stack.  */
    8945       699221 :   HARD_REG_SET hard_stack_slot_access = stack_slot_access;
    8946              : 
    8947       699221 :   calculate_dominance_info (CDI_DOMINATORS);
    8948              : 
    8949      2327615 :   unsigned int regno;
    8950              : 
    8951      2327615 :   do
    8952              :     {
    8953      2327615 :       regno = bitmap_clear_first_set_bit (worklist);
    8954      2327615 :       ix86_find_all_reg_uses (stack_slot_access, regno, worklist);
    8955              :     }
    8956      2327615 :   while (!bitmap_empty_p (worklist));
    8957              : 
    8958              :   hard_reg_set_iterator hrsi;
    8959              :   stack_access_data data;
    8960              : 
    8961    129355885 :   auto_bitmap reg_dominate_bbs_known[FIRST_PSEUDO_REGISTER];
    8962    129355885 :   auto_bitmap reg_dominate_bbs[FIRST_PSEUDO_REGISTER];
    8963              : 
    8964       699221 :   data.stack_alignment = &stack_alignment;
    8965              : 
    8966      3026836 :   EXECUTE_IF_SET_IN_HARD_REG_SET (stack_slot_access, 0, regno, hrsi)
    8967              :     {
    8968      2327615 :       for (df_ref ref = DF_REG_USE_CHAIN (regno);
    8969     82523658 :            ref != NULL;
    8970     80196043 :            ref = DF_REF_NEXT_REG (ref))
    8971              :         {
    8972     80196043 :           if (DF_REF_IS_ARTIFICIAL (ref))
    8973     16711927 :             continue;
    8974              : 
    8975     63484116 :           rtx_insn *insn = DF_REF_INSN (ref);
    8976              : 
    8977     63484116 :           if (!NONJUMP_INSN_P (insn))
    8978     18404247 :             continue;
    8979              : 
    8980              :           /* Call ix86_access_stack_p only if INSN needs alignment >
    8981              :              STACK_ALIGNMENT.  */
    8982     45079869 :           if (ix86_need_alignment_p (insn, stack_alignment)
    8983     45079869 :               && (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
    8984        40071 :                   || ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
    8985              :                                           set_up_by_prologue,
    8986              :                                           prologue_used,
    8987              :                                           reg_dominate_bbs_known,
    8988              :                                           reg_dominate_bbs)))
    8989              :             {
    8990              :               /* Update stack alignment if REGNO is used for stack
    8991              :                  access.  */
    8992       140077 :               data.reg = DF_REF_REG (ref);
    8993       140077 :               note_stores (insn, ix86_update_stack_alignment, &data);
    8994              :             }
    8995              :         }
    8996              :     }
    8997              : 
    8998       699221 :   free_dominance_info (CDI_DOMINATORS);
    8999    130754327 : }
    9000              : 
    9001              : /* Finalize stack_realign_needed and frame_pointer_needed flags, which
    9002              :    will guide prologue/epilogue to be generated in correct form.  */
    9003              : 
    9004              : static void
    9005      3460226 : ix86_finalize_stack_frame_flags (void)
    9006              : {
    9007              :   /* Check if stack realign is really needed after reload, and
    9008              :      stores result in cfun */
    9009      3460226 :   unsigned int incoming_stack_boundary
    9010      3460226 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    9011      3460226 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    9012      3460226 :   unsigned int stack_alignment
    9013      1189934 :     = (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
    9014      4650160 :        ? crtl->max_used_stack_slot_alignment
    9015      3460226 :        : crtl->stack_alignment_needed);
    9016      3460226 :   unsigned int stack_realign
    9017      3460226 :     = (incoming_stack_boundary < stack_alignment);
    9018      3460226 :   bool recompute_frame_layout_p = false;
    9019              : 
    9020      3460226 :   if (crtl->stack_realign_finalized)
    9021              :     {
    9022              :       /* After stack_realign_needed is finalized, we can't no longer
    9023              :          change it.  */
    9024      1966361 :       gcc_assert (crtl->stack_realign_needed == stack_realign);
    9025      1966361 :       return;
    9026              :     }
    9027              : 
    9028              :   /* It is always safe to compute max_used_stack_alignment.  We
    9029              :      compute it only if 128-bit aligned load/store may be generated
    9030              :      on misaligned stack slot which will lead to segfault. */
    9031      2987730 :   bool check_stack_slot
    9032      1493865 :     = (stack_realign || crtl->max_used_stack_slot_alignment >= 128);
    9033      1493865 :   ix86_find_max_used_stack_alignment (stack_alignment,
    9034              :                                       check_stack_slot);
    9035              : 
    9036              :   /* If the only reason for frame_pointer_needed is that we conservatively
    9037              :      assumed stack realignment might be needed or -fno-omit-frame-pointer
    9038              :      is used, but in the end nothing that needed the stack alignment had
    9039              :      been spilled nor stack access, clear frame_pointer_needed and say we
    9040              :      don't need stack realignment.
    9041              : 
    9042              :      When vector register is used for piecewise move and store, we don't
    9043              :      increase stack_alignment_needed as there is no register spill for
    9044              :      piecewise move and store.  Since stack_realign_needed is set to true
    9045              :      by checking stack_alignment_estimated which is updated by pseudo
    9046              :      vector register usage, we also need to check stack_realign_needed to
    9047              :      eliminate frame pointer.  */
    9048      1493865 :   if ((stack_realign
    9049      1428096 :        || (!flag_omit_frame_pointer && optimize)
    9050      1417846 :        || crtl->stack_realign_needed)
    9051        76744 :       && frame_pointer_needed
    9052        76744 :       && crtl->is_leaf
    9053        52563 :       && crtl->sp_is_unchanging
    9054        52514 :       && !ix86_current_function_calls_tls_descriptor
    9055        52514 :       && !crtl->accesses_prior_frames
    9056        52514 :       && !cfun->calls_alloca
    9057        52514 :       && !crtl->calls_eh_return
    9058              :       /* See ira_setup_eliminable_regset for the rationale.  */
    9059        52514 :       && !(STACK_CHECK_MOVING_SP
    9060        52514 :            && flag_stack_check
    9061            0 :            && flag_exceptions
    9062            0 :            && cfun->can_throw_non_call_exceptions)
    9063        52514 :       && !ix86_frame_pointer_required ()
    9064        52513 :       && ix86_get_frame_size () == 0
    9065        34988 :       && ix86_nsaved_sseregs () == 0
    9066      1528853 :       && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
    9067              :     {
    9068        34988 :       if (cfun->machine->stack_frame_required)
    9069              :         {
    9070              :           /* Stack frame is required.  If stack alignment needed is less
    9071              :              than incoming stack boundary, don't realign stack.  */
    9072          285 :           stack_realign = incoming_stack_boundary < stack_alignment;
    9073          285 :           if (!stack_realign)
    9074              :             {
    9075          285 :               crtl->max_used_stack_slot_alignment
    9076          285 :                 = incoming_stack_boundary;
    9077          285 :               crtl->stack_alignment_needed
    9078          285 :                 = incoming_stack_boundary;
    9079              :               /* Also update preferred_stack_boundary for leaf
    9080              :                  functions.  */
    9081          285 :               crtl->preferred_stack_boundary
    9082          285 :                 = incoming_stack_boundary;
    9083              :             }
    9084              :         }
    9085              :       else
    9086              :         {
    9087              :           /* If drap has been set, but it actually isn't live at the
    9088              :              start of the function, there is no reason to set it up.  */
    9089        34703 :           if (crtl->drap_reg)
    9090              :             {
    9091           35 :               basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    9092           70 :               if (! REGNO_REG_SET_P (DF_LR_IN (bb),
    9093              :                                      REGNO (crtl->drap_reg)))
    9094              :                 {
    9095           35 :                   crtl->drap_reg = NULL_RTX;
    9096           35 :                   crtl->need_drap = false;
    9097              :                 }
    9098              :             }
    9099              :           else
    9100        34668 :             cfun->machine->no_drap_save_restore = true;
    9101              : 
    9102        34703 :           frame_pointer_needed = false;
    9103        34703 :           stack_realign = false;
    9104        34703 :           crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
    9105        34703 :           crtl->stack_alignment_needed = incoming_stack_boundary;
    9106        34703 :           crtl->stack_alignment_estimated = incoming_stack_boundary;
    9107        34703 :           if (crtl->preferred_stack_boundary > incoming_stack_boundary)
    9108            1 :             crtl->preferred_stack_boundary = incoming_stack_boundary;
    9109        34703 :           df_finish_pass (true);
    9110        34703 :           df_scan_alloc (NULL);
    9111        34703 :           df_scan_blocks ();
    9112        34703 :           df_compute_regs_ever_live (true);
    9113        34703 :           df_analyze ();
    9114              : 
    9115        34703 :           if (flag_var_tracking)
    9116              :             {
    9117              :               /* Since frame pointer is no longer available, replace it with
    9118              :                  stack pointer - UNITS_PER_WORD in debug insns.  */
    9119          136 :               df_ref ref, next;
    9120          136 :               for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM);
    9121          136 :                    ref; ref = next)
    9122              :                 {
    9123            0 :                   next = DF_REF_NEXT_REG (ref);
    9124            0 :                   if (!DF_REF_INSN_INFO (ref))
    9125            0 :                     continue;
    9126              : 
    9127              :                   /* Make sure the next ref is for a different instruction,
    9128              :                      so that we're not affected by the rescan.  */
    9129            0 :                   rtx_insn *insn = DF_REF_INSN (ref);
    9130            0 :                   while (next && DF_REF_INSN (next) == insn)
    9131            0 :                     next = DF_REF_NEXT_REG (next);
    9132              : 
    9133            0 :                   if (DEBUG_INSN_P (insn))
    9134              :                     {
    9135              :                       bool changed = false;
    9136            0 :                       for (; ref != next; ref = DF_REF_NEXT_REG (ref))
    9137              :                         {
    9138            0 :                           rtx *loc = DF_REF_LOC (ref);
    9139            0 :                           if (*loc == hard_frame_pointer_rtx)
    9140              :                             {
    9141            0 :                               *loc = plus_constant (Pmode,
    9142              :                                                     stack_pointer_rtx,
    9143            0 :                                                     -UNITS_PER_WORD);
    9144            0 :                               changed = true;
    9145              :                             }
    9146              :                         }
    9147            0 :                       if (changed)
    9148            0 :                         df_insn_rescan (insn);
    9149              :                     }
    9150              :                 }
    9151              :             }
    9152              : 
    9153              :           recompute_frame_layout_p = true;
    9154              :         }
    9155              :     }
    9156      1458877 :   else if (crtl->max_used_stack_slot_alignment >= 128
    9157       663224 :            && cfun->machine->stack_frame_required)
    9158              :     {
    9159              :       /* We don't need to realign stack.  max_used_stack_alignment is
    9160              :          used to decide how stack frame should be aligned.  This is
    9161              :          independent of any psABIs nor 32-bit vs 64-bit.  */
    9162       617750 :       cfun->machine->max_used_stack_alignment
    9163       617750 :         = stack_alignment / BITS_PER_UNIT;
    9164              :     }
    9165              : 
    9166      1493865 :   if (crtl->stack_realign_needed != stack_realign)
    9167        35270 :     recompute_frame_layout_p = true;
    9168      1493865 :   crtl->stack_realign_needed = stack_realign;
    9169      1493865 :   crtl->stack_realign_finalized = true;
    9170      1493865 :   if (recompute_frame_layout_p)
    9171        35363 :     ix86_compute_frame_layout ();
    9172              : }
    9173              : 
    9174              : /* Delete SET_GOT right after entry block if it is allocated to reg.  */
    9175              : 
    9176              : static void
    9177            0 : ix86_elim_entry_set_got (rtx reg)
    9178              : {
    9179            0 :   basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    9180            0 :   rtx_insn *c_insn = BB_HEAD (bb);
    9181            0 :   if (!NONDEBUG_INSN_P (c_insn))
    9182            0 :     c_insn = next_nonnote_nondebug_insn (c_insn);
    9183            0 :   if (c_insn && NONJUMP_INSN_P (c_insn))
    9184              :     {
    9185            0 :       rtx pat = PATTERN (c_insn);
    9186            0 :       if (GET_CODE (pat) == PARALLEL)
    9187              :         {
    9188            0 :           rtx set = XVECEXP (pat, 0, 0);
    9189            0 :           if (GET_CODE (set) == SET
    9190            0 :               && GET_CODE (SET_SRC (set)) == UNSPEC
    9191            0 :               && XINT (SET_SRC (set), 1) == UNSPEC_SET_GOT
    9192            0 :               && REGNO (SET_DEST (set)) == REGNO (reg))
    9193            0 :             delete_insn (c_insn);
    9194              :         }
    9195              :     }
    9196            0 : }
    9197              : 
    9198              : static rtx
    9199       192918 : gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store)
    9200              : {
    9201       192918 :   rtx addr, mem;
    9202              : 
    9203       192918 :   if (offset)
    9204       184232 :     addr = plus_constant (Pmode, frame_reg, offset);
    9205       192918 :   mem = gen_frame_mem (GET_MODE (reg), offset ? addr : frame_reg);
    9206       192918 :   return gen_rtx_SET (store ? mem : reg, store ? reg : mem);
    9207              : }
    9208              : 
    9209              : static inline rtx
    9210       100209 : gen_frame_load (rtx reg, rtx frame_reg, int offset)
    9211              : {
    9212       100209 :   return gen_frame_set (reg, frame_reg, offset, false);
    9213              : }
    9214              : 
    9215              : static inline rtx
    9216        92709 : gen_frame_store (rtx reg, rtx frame_reg, int offset)
    9217              : {
    9218        92709 :   return gen_frame_set (reg, frame_reg, offset, true);
    9219              : }
    9220              : 
    9221              : static void
    9222         7045 : ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
    9223              : {
    9224         7045 :   struct machine_function *m = cfun->machine;
    9225         7045 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
    9226         7045 :                           + m->call_ms2sysv_extra_regs;
    9227         7045 :   rtvec v = rtvec_alloc (ncregs + 1);
    9228         7045 :   unsigned int align, i, vi = 0;
    9229         7045 :   rtx_insn *insn;
    9230         7045 :   rtx sym, addr;
    9231         7045 :   rtx rax = gen_rtx_REG (word_mode, AX_REG);
    9232         7045 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
    9233              : 
    9234              :   /* AL should only be live with sysv_abi.  */
    9235         7045 :   gcc_assert (!ix86_eax_live_at_start_p ());
    9236         7045 :   gcc_assert (m->fs.sp_offset >= frame.sse_reg_save_offset);
    9237              : 
    9238              :   /* Setup RAX as the stub's base pointer.  We use stack_realign_offset rather
    9239              :      we've actually realigned the stack or not.  */
    9240         7045 :   align = GET_MODE_ALIGNMENT (V4SFmode);
    9241         7045 :   addr = choose_baseaddr (frame.stack_realign_offset
    9242         7045 :                           + xlogue.get_stub_ptr_offset (), &align, AX_REG);
    9243         7045 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
    9244              : 
    9245         7045 :   emit_insn (gen_rtx_SET (rax, addr));
    9246              : 
    9247              :   /* Get the stub symbol.  */
    9248         8327 :   sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP
    9249              :                                                   : XLOGUE_STUB_SAVE);
    9250         7045 :   RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    9251              : 
    9252        99754 :   for (i = 0; i < ncregs; ++i)
    9253              :     {
    9254        92709 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
    9255        92709 :       rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode),
    9256        92709 :                              r.regno);
    9257        92709 :       RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);
    9258              :     }
    9259              : 
    9260         7045 :   gcc_assert (vi == (unsigned)GET_NUM_ELEM (v));
    9261              : 
    9262         7045 :   insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
    9263         7045 :   RTX_FRAME_RELATED_P (insn) = true;
    9264         7045 : }
    9265              : 
    9266              : /* Generate and return an insn body to AND X with Y.  */
    9267              : 
    9268              : static rtx_insn *
    9269        31224 : gen_and2_insn (rtx x, rtx y)
    9270              : {
    9271        31224 :   enum insn_code icode = optab_handler (and_optab, GET_MODE (x));
    9272              : 
    9273        31224 :   gcc_assert (insn_operand_matches (icode, 0, x));
    9274        31224 :   gcc_assert (insn_operand_matches (icode, 1, x));
    9275        31224 :   gcc_assert (insn_operand_matches (icode, 2, y));
    9276              : 
    9277        31224 :   return GEN_FCN (icode) (x, x, y);
    9278              : }
    9279              : 
    9280              : /* Expand the prologue into a bunch of separate insns.  */
    9281              : 
    9282              : void
    9283      1538185 : ix86_expand_prologue (void)
    9284              : {
    9285      1538185 :   struct machine_function *m = cfun->machine;
    9286      1538185 :   rtx insn, t;
    9287      1538185 :   HOST_WIDE_INT allocate;
    9288      1538185 :   bool int_registers_saved;
    9289      1538185 :   bool sse_registers_saved;
    9290      1538185 :   bool save_stub_call_needed;
    9291      1538185 :   rtx static_chain = NULL_RTX;
    9292              : 
    9293      1538185 :   ix86_last_zero_store_uid = 0;
    9294      1538185 :   if (ix86_function_naked (current_function_decl))
    9295              :     {
    9296           76 :       if (flag_stack_usage_info)
    9297            0 :         current_function_static_stack_size = 0;
    9298           76 :       return;
    9299              :     }
    9300              : 
    9301      1538109 :   ix86_finalize_stack_frame_flags ();
    9302              : 
    9303              :   /* DRAP should not coexist with stack_realign_fp */
    9304      1538109 :   gcc_assert (!(crtl->drap_reg && stack_realign_fp));
    9305              : 
    9306      1538109 :   memset (&m->fs, 0, sizeof (m->fs));
    9307              : 
    9308              :   /* Initialize CFA state for before the prologue.  */
    9309      1538109 :   m->fs.cfa_reg = stack_pointer_rtx;
    9310      1538109 :   m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
    9311              : 
    9312              :   /* Track SP offset to the CFA.  We continue tracking this after we've
    9313              :      swapped the CFA register away from SP.  In the case of re-alignment
    9314              :      this is fudged; we're interested to offsets within the local frame.  */
    9315      1538109 :   m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    9316      1538109 :   m->fs.sp_valid = true;
    9317      1538109 :   m->fs.sp_realigned = false;
    9318              : 
    9319      1538109 :   const struct ix86_frame &frame = cfun->machine->frame;
    9320              : 
    9321      1538109 :   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
    9322              :     {
    9323              :       /* We should have already generated an error for any use of
    9324              :          ms_hook on a nested function.  */
    9325            0 :       gcc_checking_assert (!ix86_static_chain_on_stack);
    9326              : 
    9327              :       /* Check if profiling is active and we shall use profiling before
    9328              :          prologue variant. If so sorry.  */
    9329            0 :       if (crtl->profile && flag_fentry != 0)
    9330            0 :         sorry ("%<ms_hook_prologue%> attribute is not compatible "
    9331              :                "with %<-mfentry%> for 32-bit");
    9332              : 
    9333              :       /* In ix86_asm_output_function_label we emitted:
    9334              :          8b ff     movl.s %edi,%edi
    9335              :          55        push   %ebp
    9336              :          8b ec     movl.s %esp,%ebp
    9337              : 
    9338              :          This matches the hookable function prologue in Win32 API
    9339              :          functions in Microsoft Windows XP Service Pack 2 and newer.
    9340              :          Wine uses this to enable Windows apps to hook the Win32 API
    9341              :          functions provided by Wine.
    9342              : 
    9343              :          What that means is that we've already set up the frame pointer.  */
    9344              : 
    9345            0 :       if (frame_pointer_needed
    9346            0 :           && !(crtl->drap_reg && crtl->stack_realign_needed))
    9347              :         {
    9348            0 :           rtx push, mov;
    9349              : 
    9350              :           /* We've decided to use the frame pointer already set up.
    9351              :              Describe this to the unwinder by pretending that both
    9352              :              push and mov insns happen right here.
    9353              : 
    9354              :              Putting the unwind info here at the end of the ms_hook
    9355              :              is done so that we can make absolutely certain we get
    9356              :              the required byte sequence at the start of the function,
    9357              :              rather than relying on an assembler that can produce
    9358              :              the exact encoding required.
    9359              : 
    9360              :              However it does mean (in the unpatched case) that we have
    9361              :              a 1 insn window where the asynchronous unwind info is
    9362              :              incorrect.  However, if we placed the unwind info at
    9363              :              its correct location we would have incorrect unwind info
    9364              :              in the patched case.  Which is probably all moot since
    9365              :              I don't expect Wine generates dwarf2 unwind info for the
    9366              :              system libraries that use this feature.  */
    9367              : 
    9368            0 :           insn = emit_insn (gen_blockage ());
    9369              : 
    9370            0 :           push = gen_push (hard_frame_pointer_rtx);
    9371            0 :           mov = gen_rtx_SET (hard_frame_pointer_rtx,
    9372              :                              stack_pointer_rtx);
    9373            0 :           RTX_FRAME_RELATED_P (push) = 1;
    9374            0 :           RTX_FRAME_RELATED_P (mov) = 1;
    9375              : 
    9376            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9377            0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9378              :                         gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
    9379              : 
    9380              :           /* Note that gen_push incremented m->fs.cfa_offset, even
    9381              :              though we didn't emit the push insn here.  */
    9382            0 :           m->fs.cfa_reg = hard_frame_pointer_rtx;
    9383            0 :           m->fs.fp_offset = m->fs.cfa_offset;
    9384            0 :           m->fs.fp_valid = true;
    9385            0 :         }
    9386              :       else
    9387              :         {
    9388              :           /* The frame pointer is not needed so pop %ebp again.
    9389              :              This leaves us with a pristine state.  */
    9390            0 :           emit_insn (gen_pop (hard_frame_pointer_rtx));
    9391              :         }
    9392              :     }
    9393              : 
    9394              :   /* The first insn of a function that accepts its static chain on the
    9395              :      stack is to push the register that would be filled in by a direct
    9396              :      call.  This insn will be skipped by the trampoline.  */
    9397      1538109 :   else if (ix86_static_chain_on_stack)
    9398              :     {
    9399            0 :       static_chain = ix86_static_chain (cfun->decl, false);
    9400            0 :       insn = emit_insn (gen_push (static_chain));
    9401            0 :       emit_insn (gen_blockage ());
    9402              : 
    9403              :       /* We don't want to interpret this push insn as a register save,
    9404              :          only as a stack adjustment.  The real copy of the register as
    9405              :          a save will be done later, if needed.  */
    9406            0 :       t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    9407            0 :       t = gen_rtx_SET (stack_pointer_rtx, t);
    9408            0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
    9409            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9410              :     }
    9411              : 
    9412              :   /* Emit prologue code to adjust stack alignment and setup DRAP, in case
    9413              :      of DRAP is needed and stack realignment is really needed after reload */
    9414      1538109 :   if (stack_realign_drap)
    9415              :     {
    9416         7009 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    9417              : 
    9418              :       /* Can't use DRAP in interrupt function.  */
    9419         7009 :       if (cfun->machine->func_type != TYPE_NORMAL)
    9420            0 :         sorry ("Dynamic Realign Argument Pointer (DRAP) not supported "
    9421              :                "in interrupt service routine.  This may be worked "
    9422              :                "around by avoiding functions with aggregate return.");
    9423              : 
    9424              :       /* Only need to push parameter pointer reg if it is caller saved.  */
    9425         7009 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    9426              :         {
    9427              :           /* Push arg pointer reg */
    9428          137 :           insn = emit_insn (gen_push (crtl->drap_reg));
    9429          137 :           RTX_FRAME_RELATED_P (insn) = 1;
    9430              :         }
    9431              : 
    9432              :       /* Grab the argument pointer.  */
    9433         7294 :       t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
    9434         7009 :       insn = emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    9435         7009 :       RTX_FRAME_RELATED_P (insn) = 1;
    9436         7009 :       m->fs.cfa_reg = crtl->drap_reg;
    9437         7009 :       m->fs.cfa_offset = 0;
    9438              : 
    9439              :       /* Align the stack.  */
    9440         7009 :       insn = emit_insn (gen_and2_insn (stack_pointer_rtx,
    9441         7009 :                                        GEN_INT (-align_bytes)));
    9442         7009 :       RTX_FRAME_RELATED_P (insn) = 1;
    9443              : 
    9444              :       /* Replicate the return address on the stack so that return
    9445              :          address can be reached via (argp - 1) slot.  This is needed
    9446              :          to implement macro RETURN_ADDR_RTX and intrinsic function
    9447              :          expand_builtin_return_addr etc.  */
    9448         7579 :       t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
    9449         7009 :       t = gen_frame_mem (word_mode, t);
    9450         7009 :       insn = emit_insn (gen_push (t));
    9451         7009 :       RTX_FRAME_RELATED_P (insn) = 1;
    9452              : 
    9453              :       /* For the purposes of frame and register save area addressing,
    9454              :          we've started over with a new frame.  */
    9455         7009 :       m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    9456         7009 :       m->fs.realigned = true;
    9457              : 
    9458         7009 :       if (static_chain)
    9459              :         {
    9460              :           /* Replicate static chain on the stack so that static chain
    9461              :              can be reached via (argp - 2) slot.  This is needed for
    9462              :              nested function with stack realignment.  */
    9463            0 :           insn = emit_insn (gen_push (static_chain));
    9464            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9465              :         }
    9466              :     }
    9467              : 
    9468      1538109 :   int_registers_saved = (frame.nregs == 0);
    9469      1538109 :   sse_registers_saved = (frame.nsseregs == 0);
    9470      1538109 :   save_stub_call_needed = (m->call_ms2sysv);
    9471      1538109 :   gcc_assert (sse_registers_saved || !save_stub_call_needed);
    9472              : 
    9473      1538109 :   if (frame_pointer_needed && !m->fs.fp_valid)
    9474              :     {
    9475              :       /* Note: AT&T enter does NOT have reversed args.  Enter is probably
    9476              :          slower on all targets.  Also sdb didn't like it.  */
    9477       488003 :       insn = emit_insn (gen_push (hard_frame_pointer_rtx));
    9478       488003 :       RTX_FRAME_RELATED_P (insn) = 1;
    9479              : 
    9480       488003 :       if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
    9481              :         {
    9482       488003 :           insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
    9483       488003 :           RTX_FRAME_RELATED_P (insn) = 1;
    9484              : 
    9485       488003 :           if (m->fs.cfa_reg == stack_pointer_rtx)
    9486       480994 :             m->fs.cfa_reg = hard_frame_pointer_rtx;
    9487       488003 :           m->fs.fp_offset = m->fs.sp_offset;
    9488       488003 :           m->fs.fp_valid = true;
    9489              :         }
    9490              :     }
    9491              : 
    9492      1538109 :   if (!int_registers_saved)
    9493              :     {
    9494              :       /* If saving registers via PUSH, do so now.  */
    9495       474144 :       if (!frame.save_regs_using_mov)
    9496              :         {
    9497       429838 :           ix86_emit_save_regs ();
    9498       429838 :           m->fs.apx_ppx_used = TARGET_APX_PPX && !crtl->calls_eh_return;
    9499       429838 :           int_registers_saved = true;
    9500       429838 :           gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
    9501              :         }
    9502              : 
    9503              :       /* When using red zone we may start register saving before allocating
    9504              :          the stack frame saving one cycle of the prologue.  However, avoid
    9505              :          doing this if we have to probe the stack; at least on x86_64 the
    9506              :          stack probe can turn into a call that clobbers a red zone location. */
    9507        44306 :       else if (ix86_using_red_zone ()
    9508        44306 :                 && (! TARGET_STACK_PROBE
    9509            0 :                     || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
    9510              :         {
    9511        39857 :           HOST_WIDE_INT allocate_offset;
    9512        39857 :           if (crtl->shrink_wrapped_separate)
    9513              :             {
    9514        39801 :               allocate_offset = m->fs.sp_offset - frame.stack_pointer_offset;
    9515              : 
    9516              :               /* Adjust the total offset at the beginning of the function.  */
    9517        39801 :               pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9518              :                                          GEN_INT (allocate_offset), -1,
    9519        39801 :                                          m->fs.cfa_reg == stack_pointer_rtx);
    9520        39801 :               m->fs.sp_offset = cfun->machine->frame.stack_pointer_offset;
    9521              :             }
    9522              : 
    9523        39857 :           ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9524        39857 :           int_registers_saved = true;
    9525              :         }
    9526              :     }
    9527              : 
    9528      1538109 :   if (frame.red_zone_size != 0)
    9529       142415 :     cfun->machine->red_zone_used = true;
    9530              : 
    9531      1538109 :   if (stack_realign_fp)
    9532              :     {
    9533        24215 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    9534        24564 :       gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
    9535              : 
    9536              :       /* Record last valid frame pointer offset.  */
    9537        24215 :       m->fs.sp_realigned_fp_last = frame.reg_save_offset;
    9538              : 
    9539              :       /* The computation of the size of the re-aligned stack frame means
    9540              :          that we must allocate the size of the register save area before
    9541              :          performing the actual alignment.  Otherwise we cannot guarantee
    9542              :          that there's enough storage above the realignment point.  */
    9543        24215 :       allocate = frame.reg_save_offset - m->fs.sp_offset
    9544        24215 :                  + frame.stack_realign_allocate;
    9545        24215 :       if (allocate)
    9546         2691 :         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9547              :                                    GEN_INT (-allocate), -1, false);
    9548              : 
    9549              :       /* Align the stack.  */
    9550        24215 :       emit_insn (gen_and2_insn (stack_pointer_rtx, GEN_INT (-align_bytes)));
    9551        24215 :       m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes);
    9552        24215 :       m->fs.sp_realigned_offset = m->fs.sp_offset
    9553        24215 :                                               - frame.stack_realign_allocate;
    9554              :       /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset.
    9555              :          Beyond this point, stack access should be done via choose_baseaddr or
    9556              :          by using sp_valid_at and fp_valid_at to determine the correct base
    9557              :          register.  Henceforth, any CFA offset should be thought of as logical
    9558              :          and not physical.  */
    9559        24215 :       gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last);
    9560        24215 :       gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset);
    9561        24215 :       m->fs.sp_realigned = true;
    9562              : 
    9563              :       /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which
    9564              :          is needed to describe where a register is saved using a realigned
    9565              :          stack pointer, so we need to invalidate the stack pointer for that
    9566              :          target.  */
    9567        24215 :       if (TARGET_SEH)
    9568              :         m->fs.sp_valid = false;
    9569              : 
    9570              :       /* If SP offset is non-immediate after allocation of the stack frame,
    9571              :          then emit SSE saves or stub call prior to allocating the rest of the
    9572              :          stack frame.  This is less efficient for the out-of-line stub because
    9573              :          we can't combine allocations across the call barrier, but it's better
    9574              :          than using a scratch register.  */
    9575        24215 :       else if (!x86_64_immediate_operand (GEN_INT (frame.stack_pointer_offset
    9576              :                                                    - m->fs.sp_realigned_offset),
    9577        24215 :                                           Pmode))
    9578              :         {
    9579            3 :           if (!sse_registers_saved)
    9580              :             {
    9581            1 :               ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9582            1 :               sse_registers_saved = true;
    9583              :             }
    9584            2 :           else if (save_stub_call_needed)
    9585              :             {
    9586            1 :               ix86_emit_outlined_ms2sysv_save (frame);
    9587            1 :               save_stub_call_needed = false;
    9588              :             }
    9589              :         }
    9590              :     }
    9591              : 
    9592      1538109 :   allocate = frame.stack_pointer_offset - m->fs.sp_offset;
    9593              : 
    9594      1538109 :   if (flag_stack_usage_info)
    9595              :     {
    9596              :       /* We start to count from ARG_POINTER.  */
    9597          355 :       HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
    9598              : 
    9599              :       /* If it was realigned, take into account the fake frame.  */
    9600          355 :       if (stack_realign_drap)
    9601              :         {
    9602            1 :           if (ix86_static_chain_on_stack)
    9603            0 :             stack_size += UNITS_PER_WORD;
    9604              : 
    9605            1 :           if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    9606            0 :             stack_size += UNITS_PER_WORD;
    9607              : 
    9608              :           /* This over-estimates by 1 minimal-stack-alignment-unit but
    9609              :              mitigates that by counting in the new return address slot.  */
    9610            1 :           current_function_dynamic_stack_size
    9611            1 :             += crtl->stack_alignment_needed / BITS_PER_UNIT;
    9612              :         }
    9613              : 
    9614          355 :       current_function_static_stack_size = stack_size;
    9615              :     }
    9616              : 
    9617              :   /* On SEH target with very large frame size, allocate an area to save
    9618              :      SSE registers (as the very large allocation won't be described).  */
    9619      1538109 :   if (TARGET_SEH
    9620              :       && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
    9621              :       && !sse_registers_saved)
    9622              :     {
    9623              :       HOST_WIDE_INT sse_size
    9624              :         = frame.sse_reg_save_offset - frame.reg_save_offset;
    9625              : 
    9626              :       gcc_assert (int_registers_saved);
    9627              : 
    9628              :       /* No need to do stack checking as the area will be immediately
    9629              :          written.  */
    9630              :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9631              :                                  GEN_INT (-sse_size), -1,
    9632              :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9633              :       allocate -= sse_size;
    9634              :       ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9635              :       sse_registers_saved = true;
    9636              :     }
    9637              : 
    9638              :   /* If stack clash protection is requested, then probe the stack, unless it
    9639              :      is already probed on the target.  */
    9640      1538109 :   if (allocate >= 0
    9641      1538105 :       && flag_stack_clash_protection
    9642      1538207 :       && !ix86_target_stack_probe ())
    9643              :     {
    9644           98 :       ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
    9645           98 :       allocate = 0;
    9646              :     }
    9647              : 
    9648              :   /* The stack has already been decremented by the instruction calling us
    9649              :      so probe if the size is non-negative to preserve the protection area.  */
    9650      1538011 :   else if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
    9651              :     {
    9652           45 :       const HOST_WIDE_INT probe_interval = get_probe_interval ();
    9653              : 
    9654           45 :       if (STACK_CHECK_MOVING_SP)
    9655              :         {
    9656           45 :           if (crtl->is_leaf
    9657           18 :               && !cfun->calls_alloca
    9658           18 :               && allocate <= probe_interval)
    9659              :             ;
    9660              : 
    9661              :           else
    9662              :             {
    9663           28 :               ix86_adjust_stack_and_probe (allocate, int_registers_saved, true);
    9664           28 :               allocate = 0;
    9665              :             }
    9666              :         }
    9667              : 
    9668              :       else
    9669              :         {
    9670              :           HOST_WIDE_INT size = allocate;
    9671              : 
    9672              :           if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
    9673              :             size = 0x80000000 - get_stack_check_protect () - 1;
    9674              : 
    9675              :           if (TARGET_STACK_PROBE)
    9676              :             {
    9677              :               if (crtl->is_leaf && !cfun->calls_alloca)
    9678              :                 {
    9679              :                   if (size > probe_interval)
    9680              :                     ix86_emit_probe_stack_range (0, size, int_registers_saved);
    9681              :                 }
    9682              :               else
    9683              :                 ix86_emit_probe_stack_range (0,
    9684              :                                              size + get_stack_check_protect (),
    9685              :                                              int_registers_saved);
    9686              :             }
    9687              :           else
    9688              :             {
    9689              :               if (crtl->is_leaf && !cfun->calls_alloca)
    9690              :                 {
    9691              :                   if (size > probe_interval
    9692              :                       && size > get_stack_check_protect ())
    9693              :                     ix86_emit_probe_stack_range (get_stack_check_protect (),
    9694              :                                                  (size
    9695              :                                                   - get_stack_check_protect ()),
    9696              :                                                  int_registers_saved);
    9697              :                 }
    9698              :               else
    9699              :                 ix86_emit_probe_stack_range (get_stack_check_protect (), size,
    9700              :                                              int_registers_saved);
    9701              :             }
    9702              :         }
    9703              :     }
    9704              : 
    9705      1538105 :   if (allocate == 0)
    9706              :     ;
    9707       849352 :   else if (!ix86_target_stack_probe ()
    9708       849352 :            || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
    9709              :     {
    9710       849307 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9711              :                                  GEN_INT (-allocate), -1,
    9712       849307 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9713              :     }
    9714              :   else
    9715              :     {
    9716           45 :       rtx eax = gen_rtx_REG (Pmode, AX_REG);
    9717           45 :       rtx r10 = NULL;
    9718           45 :       const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
    9719           45 :       bool eax_live = ix86_eax_live_at_start_p ();
    9720           45 :       bool r10_live = false;
    9721              : 
    9722           45 :       if (TARGET_64BIT)
    9723           45 :         r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
    9724              : 
    9725           45 :       if (eax_live)
    9726              :         {
    9727            0 :           insn = emit_insn (gen_push (eax));
    9728            0 :           allocate -= UNITS_PER_WORD;
    9729              :           /* Note that SEH directives need to continue tracking the stack
    9730              :              pointer even after the frame pointer has been set up.  */
    9731            0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9732              :             {
    9733            0 :               if (sp_is_cfa_reg)
    9734            0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9735            0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9736            0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9737            0 :                             gen_rtx_SET (stack_pointer_rtx,
    9738              :                                          plus_constant (Pmode,
    9739              :                                                         stack_pointer_rtx,
    9740              :                                                         -UNITS_PER_WORD)));
    9741              :             }
    9742              :         }
    9743              : 
    9744           45 :       if (r10_live)
    9745              :         {
    9746            0 :           r10 = gen_rtx_REG (Pmode, R10_REG);
    9747            0 :           insn = emit_insn (gen_push (r10));
    9748            0 :           allocate -= UNITS_PER_WORD;
    9749            0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9750              :             {
    9751            0 :               if (sp_is_cfa_reg)
    9752            0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9753            0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9754            0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9755            0 :                             gen_rtx_SET (stack_pointer_rtx,
    9756              :                                          plus_constant (Pmode,
    9757              :                                                         stack_pointer_rtx,
    9758              :                                                         -UNITS_PER_WORD)));
    9759              :             }
    9760              :         }
    9761              : 
    9762           45 :       emit_move_insn (eax, GEN_INT (allocate));
    9763           45 :       emit_insn (gen_allocate_stack_worker_probe (Pmode, eax, eax));
    9764              : 
    9765              :       /* Use the fact that AX still contains ALLOCATE.  */
    9766           45 :       insn = emit_insn (gen_pro_epilogue_adjust_stack_sub
    9767           45 :                         (Pmode, stack_pointer_rtx, stack_pointer_rtx, eax));
    9768              : 
    9769           45 :       if (sp_is_cfa_reg || TARGET_SEH)
    9770              :         {
    9771           37 :           if (sp_is_cfa_reg)
    9772           37 :             m->fs.cfa_offset += allocate;
    9773           37 :           RTX_FRAME_RELATED_P (insn) = 1;
    9774           37 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9775           37 :                         gen_rtx_SET (stack_pointer_rtx,
    9776              :                                      plus_constant (Pmode, stack_pointer_rtx,
    9777              :                                                     -allocate)));
    9778              :         }
    9779           45 :       m->fs.sp_offset += allocate;
    9780              : 
    9781              :       /* Use stack_pointer_rtx for relative addressing so that code works for
    9782              :          realigned stack.  But this means that we need a blockage to prevent
    9783              :          stores based on the frame pointer from being scheduled before.  */
    9784           45 :       if (r10_live && eax_live)
    9785              :         {
    9786            0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9787            0 :           emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
    9788              :                           gen_frame_mem (word_mode, t));
    9789            0 :           t = plus_constant (Pmode, t, UNITS_PER_WORD);
    9790            0 :           emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
    9791              :                           gen_frame_mem (word_mode, t));
    9792            0 :           emit_insn (gen_memory_blockage ());
    9793              :         }
    9794           45 :       else if (eax_live || r10_live)
    9795              :         {
    9796            0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9797            0 :           emit_move_insn (gen_rtx_REG (word_mode,
    9798              :                                        (eax_live ? AX_REG : R10_REG)),
    9799              :                           gen_frame_mem (word_mode, t));
    9800            0 :           emit_insn (gen_memory_blockage ());
    9801              :         }
    9802              :     }
    9803      1538109 :   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
    9804              : 
    9805              :   /* If we haven't already set up the frame pointer, do so now.  */
    9806      1538109 :   if (frame_pointer_needed && !m->fs.fp_valid)
    9807              :     {
    9808            0 :       insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
    9809            0 :                             GEN_INT (frame.stack_pointer_offset
    9810              :                                      - frame.hard_frame_pointer_offset));
    9811            0 :       insn = emit_insn (insn);
    9812            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9813            0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
    9814              : 
    9815            0 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    9816            0 :         m->fs.cfa_reg = hard_frame_pointer_rtx;
    9817            0 :       m->fs.fp_offset = frame.hard_frame_pointer_offset;
    9818            0 :       m->fs.fp_valid = true;
    9819              :     }
    9820              : 
    9821      1538109 :   if (!int_registers_saved)
    9822         4449 :     ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9823      1538109 :   if (!sse_registers_saved)
    9824        33375 :     ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9825      1504734 :   else if (save_stub_call_needed)
    9826         7044 :     ix86_emit_outlined_ms2sysv_save (frame);
    9827              : 
    9828              :   /* For the mcount profiling on 32 bit PIC mode we need to emit SET_GOT
    9829              :      in PROLOGUE.  */
    9830      1538109 :   if (!TARGET_64BIT && pic_offset_table_rtx && crtl->profile && !flag_fentry)
    9831              :     {
    9832            0 :       rtx pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
    9833            0 :       insn = emit_insn (gen_set_got (pic));
    9834            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9835            0 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    9836            0 :       emit_insn (gen_prologue_use (pic));
    9837              :       /* Deleting already emitted SET_GOT if exist and allocated to
    9838              :          REAL_PIC_OFFSET_TABLE_REGNUM.  */
    9839            0 :       ix86_elim_entry_set_got (pic);
    9840              :     }
    9841              : 
    9842      1538109 :   if (crtl->drap_reg && !crtl->stack_realign_needed)
    9843              :     {
    9844              :       /* vDRAP is setup but after reload it turns out stack realign
    9845              :          isn't necessary, here we will emit prologue to setup DRAP
    9846              :          without stack realign adjustment */
    9847          195 :       t = choose_baseaddr (0, NULL);
    9848          195 :       emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    9849              :     }
    9850              : 
    9851              :   /* Prevent instructions from being scheduled into register save push
    9852              :      sequence when access to the redzone area is done through frame pointer.
    9853              :      The offset between the frame pointer and the stack pointer is calculated
    9854              :      relative to the value of the stack pointer at the end of the function
    9855              :      prologue, and moving instructions that access redzone area via frame
    9856              :      pointer inside push sequence violates this assumption.  */
    9857      1538109 :   if (frame_pointer_needed && frame.red_zone_size)
    9858       131658 :     emit_insn (gen_memory_blockage ());
    9859              : 
    9860              :   /* SEH requires that the prologue end within 256 bytes of the start of
    9861              :      the function.  Prevent instruction schedules that would extend that.
    9862              :      Further, prevent alloca modifications to the stack pointer from being
    9863              :      combined with prologue modifications.  */
    9864              :   if (TARGET_SEH)
    9865              :     emit_insn (gen_prologue_use (stack_pointer_rtx));
    9866              : }
    9867              : 
    9868              : /* Emit code to restore REG using a POP or POPP insn.  */
    9869              : 
    9870              : static void
    9871      1475190 : ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
    9872              : {
    9873      1475190 :   struct machine_function *m = cfun->machine;
    9874      1475190 :   rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
    9875              : 
    9876      1475190 :   ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
    9877      1475190 :   m->fs.sp_offset -= UNITS_PER_WORD;
    9878              : 
    9879      1475190 :   if (m->fs.cfa_reg == crtl->drap_reg
    9880      1475190 :       && REGNO (reg) == REGNO (crtl->drap_reg))
    9881              :     {
    9882              :       /* Previously we'd represented the CFA as an expression
    9883              :          like *(%ebp - 8).  We've just popped that value from
    9884              :          the stack, which means we need to reset the CFA to
    9885              :          the drap register.  This will remain until we restore
    9886              :          the stack pointer.  */
    9887         3972 :       add_reg_note (insn, REG_CFA_DEF_CFA, reg);
    9888         3972 :       RTX_FRAME_RELATED_P (insn) = 1;
    9889              : 
    9890              :       /* This means that the DRAP register is valid for addressing too.  */
    9891         3972 :       m->fs.drap_valid = true;
    9892         3972 :       return;
    9893              :     }
    9894              : 
    9895      1471218 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9896              :     {
    9897      1387835 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    9898      1023902 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9899      1023902 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9900      1023902 :       RTX_FRAME_RELATED_P (insn) = 1;
    9901              : 
    9902      1205861 :       m->fs.cfa_offset -= UNITS_PER_WORD;
    9903              :     }
    9904              : 
    9905              :   /* When the frame pointer is the CFA, and we pop it, we are
    9906              :      swapping back to the stack pointer as the CFA.  This happens
    9907              :      for stack frames that don't allocate other data, so we assume
    9908              :      the stack pointer is now pointing at the return address, i.e.
    9909              :      the function entry state, which makes the offset be 1 word.  */
    9910      1471218 :   if (reg == hard_frame_pointer_rtx)
    9911              :     {
    9912       241633 :       m->fs.fp_valid = false;
    9913       241633 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9914              :         {
    9915       237648 :           m->fs.cfa_reg = stack_pointer_rtx;
    9916       237648 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    9917              : 
    9918       237648 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9919       237648 :                         plus_constant (Pmode, stack_pointer_rtx,
    9920       237648 :                                        m->fs.cfa_offset));
    9921       237648 :           RTX_FRAME_RELATED_P (insn) = 1;
    9922              :         }
    9923              :     }
    9924              : }
    9925              : 
    9926              : /* Emit code to restore REG using a POP2 insn.  */
    9927              : static void
    9928           19 : ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
    9929              : {
    9930           19 :   struct machine_function *m = cfun->machine;
    9931           19 :   const int offset = UNITS_PER_WORD * 2;
    9932           19 :   rtx_insn *insn;
    9933              : 
    9934           19 :   rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
    9935              :                                                    stack_pointer_rtx));
    9936              : 
    9937           19 :   if (ppx_p)
    9938           15 :     insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
    9939              :   else
    9940            4 :     insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
    9941              : 
    9942           19 :   RTX_FRAME_RELATED_P (insn) = 1;
    9943              : 
    9944           19 :   rtx dwarf = NULL_RTX;
    9945           19 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf);
    9946           19 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg2, dwarf);
    9947           19 :   REG_NOTES (insn) = dwarf;
    9948           19 :   m->fs.sp_offset -= offset;
    9949              : 
    9950           19 :   if (m->fs.cfa_reg == crtl->drap_reg
    9951           19 :       && (REGNO (reg1) == REGNO (crtl->drap_reg)
    9952            3 :           || REGNO (reg2) == REGNO (crtl->drap_reg)))
    9953              :     {
    9954              :       /* Previously we'd represented the CFA as an expression
    9955              :          like *(%ebp - 8).  We've just popped that value from
    9956              :          the stack, which means we need to reset the CFA to
    9957              :          the drap register.  This will remain until we restore
    9958              :          the stack pointer.  */
    9959            1 :       add_reg_note (insn, REG_CFA_DEF_CFA,
    9960            1 :                     REGNO (reg1) == REGNO (crtl->drap_reg) ? reg1 : reg2);
    9961            1 :       RTX_FRAME_RELATED_P (insn) = 1;
    9962              : 
    9963              :       /* This means that the DRAP register is valid for addressing too.  */
    9964            1 :       m->fs.drap_valid = true;
    9965            1 :       return;
    9966              :     }
    9967              : 
    9968           18 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9969              :     {
    9970           14 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    9971           14 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9972           14 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9973           14 :       RTX_FRAME_RELATED_P (insn) = 1;
    9974              : 
    9975           14 :       m->fs.cfa_offset -= offset;
    9976              :     }
    9977              : 
    9978              :   /* When the frame pointer is the CFA, and we pop it, we are
    9979              :      swapping back to the stack pointer as the CFA.  This happens
    9980              :      for stack frames that don't allocate other data, so we assume
    9981              :      the stack pointer is now pointing at the return address, i.e.
    9982              :      the function entry state, which makes the offset be 1 word.  */
    9983           18 :   if (reg1 == hard_frame_pointer_rtx || reg2 == hard_frame_pointer_rtx)
    9984              :     {
    9985            0 :       m->fs.fp_valid = false;
    9986            0 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9987              :         {
    9988            0 :           m->fs.cfa_reg = stack_pointer_rtx;
    9989            0 :           m->fs.cfa_offset -= offset;
    9990              : 
    9991            0 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9992            0 :                         plus_constant (Pmode, stack_pointer_rtx,
    9993            0 :                                        m->fs.cfa_offset));
    9994            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9995              :         }
    9996              :     }
    9997              : }
    9998              : 
    9999              : /* Emit code to restore saved registers using POP insns.  */
   10000              : 
   10001              : static void
   10002      1364143 : ix86_emit_restore_regs_using_pop (bool ppx_p)
   10003              : {
   10004      1364143 :   unsigned int regno;
   10005              : 
   10006    126865299 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10007    125501156 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
   10008      1233235 :       ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
   10009      1364143 : }
   10010              : 
   10011              : /* Emit code to restore saved registers using POP2 insns.  */
   10012              : 
   10013              : static void
   10014          570 : ix86_emit_restore_regs_using_pop2 (void)
   10015              : {
   10016          570 :   int regno;
   10017          570 :   int regno_list[2];
   10018          570 :   regno_list[0] = regno_list[1] = -1;
   10019          570 :   int loaded_regnum = 0;
   10020          570 :   bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
   10021              : 
   10022        53010 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10023        52440 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
   10024              :       {
   10025          128 :         if (aligned)
   10026              :           {
   10027          121 :             regno_list[loaded_regnum++] = regno;
   10028          121 :             if (loaded_regnum == 2)
   10029              :               {
   10030           19 :                 gcc_assert (regno_list[0] != -1
   10031              :                             && regno_list[1] != -1
   10032              :                             && regno_list[0] != regno_list[1]);
   10033              : 
   10034           19 :                 ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
   10035              :                                                                regno_list[0]),
   10036              :                                                   gen_rtx_REG (word_mode,
   10037              :                                                                regno_list[1]),
   10038           19 :                                                   TARGET_APX_PPX);
   10039           19 :                 loaded_regnum = 0;
   10040           19 :                 regno_list[0] = regno_list[1] = -1;
   10041              :               }
   10042              :           }
   10043              :         else
   10044              :           {
   10045           14 :             ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
   10046            7 :                                              TARGET_APX_PPX);
   10047            7 :             aligned = true;
   10048              :           }
   10049              :       }
   10050              : 
   10051          570 :   if (loaded_regnum == 1)
   10052           83 :     ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
   10053           83 :                                      TARGET_APX_PPX);
   10054          570 : }
   10055              : 
   10056              : /* Emit code and notes for the LEAVE instruction.  If insn is non-null,
   10057              :    omits the emit and only attaches the notes.  */
   10058              : 
   10059              : static void
   10060       247673 : ix86_emit_leave (rtx_insn *insn)
   10061              : {
   10062       247673 :   struct machine_function *m = cfun->machine;
   10063              : 
   10064       247673 :   if (!insn)
   10065       246710 :     insn = emit_insn (gen_leave (word_mode));
   10066              : 
   10067       247673 :   ix86_add_queued_cfa_restore_notes (insn);
   10068              : 
   10069       247673 :   gcc_assert (m->fs.fp_valid);
   10070       247673 :   m->fs.sp_valid = true;
   10071       247673 :   m->fs.sp_realigned = false;
   10072       247673 :   m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
   10073       247673 :   m->fs.fp_valid = false;
   10074              : 
   10075       247673 :   if (m->fs.cfa_reg == hard_frame_pointer_rtx)
   10076              :     {
   10077       244541 :       m->fs.cfa_reg = stack_pointer_rtx;
   10078       244541 :       m->fs.cfa_offset = m->fs.sp_offset;
   10079              : 
   10080       244541 :       add_reg_note (insn, REG_CFA_DEF_CFA,
   10081       244541 :                     plus_constant (Pmode, stack_pointer_rtx,
   10082       244541 :                                    m->fs.sp_offset));
   10083       244541 :       RTX_FRAME_RELATED_P (insn) = 1;
   10084              :     }
   10085       247673 :   ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
   10086              :                              m->fs.fp_offset);
   10087       247673 : }
   10088              : 
   10089              : /* Emit code to restore saved registers using MOV insns.
   10090              :    First register is restored from CFA - CFA_OFFSET.  */
   10091              : static void
   10092        96108 : ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
   10093              :                                   bool maybe_eh_return)
   10094              : {
   10095        96108 :   struct machine_function *m = cfun->machine;
   10096        96108 :   unsigned int regno;
   10097              : 
   10098      8938044 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10099      8841936 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
   10100              :       {
   10101              : 
   10102              :         /* Skip registers, already processed by shrink wrap separate.  */
   10103       261942 :         if (!cfun->machine->reg_is_wrapped_separately[regno])
   10104              :           {
   10105       138031 :             rtx reg = gen_rtx_REG (word_mode, regno);
   10106       138031 :             rtx mem;
   10107       138031 :             rtx_insn *insn;
   10108              : 
   10109       138031 :             mem = choose_baseaddr (cfa_offset, NULL);
   10110       138031 :             mem = gen_frame_mem (word_mode, mem);
   10111       138031 :             insn = emit_move_insn (reg, mem);
   10112              : 
   10113       138031 :             if (m->fs.cfa_reg == crtl->drap_reg
   10114       138031 :                 && regno == REGNO (crtl->drap_reg))
   10115              :               {
   10116              :                 /* Previously we'd represented the CFA as an expression
   10117              :                    like *(%ebp - 8).  We've just popped that value from
   10118              :                    the stack, which means we need to reset the CFA to
   10119              :                    the drap register.  This will remain until we restore
   10120              :                    the stack pointer.  */
   10121         3132 :                 add_reg_note (insn, REG_CFA_DEF_CFA, reg);
   10122         3132 :                 RTX_FRAME_RELATED_P (insn) = 1;
   10123              : 
   10124              :                 /* DRAP register is valid for addressing.  */
   10125         3132 :                 m->fs.drap_valid = true;
   10126              :               }
   10127              :             else
   10128       134899 :               ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
   10129              :           }
   10130       282340 :         cfa_offset -= UNITS_PER_WORD;
   10131              :       }
   10132        96108 : }
   10133              : 
   10134              : /* Emit code to restore saved registers using MOV insns.
   10135              :    First register is restored from CFA - CFA_OFFSET.  */
   10136              : static void
   10137        33952 : ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
   10138              :                                       bool maybe_eh_return)
   10139              : {
   10140        33952 :   unsigned int regno;
   10141              : 
   10142      3157536 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10143      3123584 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
   10144              :       {
   10145       339529 :         rtx reg = gen_rtx_REG (V4SFmode, regno);
   10146       339529 :         rtx mem;
   10147       339529 :         unsigned int align = GET_MODE_ALIGNMENT (V4SFmode);
   10148              : 
   10149       339529 :         mem = choose_baseaddr (cfa_offset, &align);
   10150       339529 :         mem = gen_rtx_MEM (V4SFmode, mem);
   10151              : 
   10152              :         /* The location alignment depends upon the base register.  */
   10153       339529 :         align = MIN (GET_MODE_ALIGNMENT (V4SFmode), align);
   10154       339529 :         gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
   10155       339529 :         set_mem_align (mem, align);
   10156       339529 :         emit_insn (gen_rtx_SET (reg, mem));
   10157              : 
   10158       339529 :         ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
   10159              : 
   10160       339529 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
   10161              :       }
   10162        33952 : }
   10163              : 
   10164              : static void
   10165         7621 : ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
   10166              :                                   bool use_call, int style)
   10167              : {
   10168         7621 :   struct machine_function *m = cfun->machine;
   10169         7621 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
   10170         7621 :                           + m->call_ms2sysv_extra_regs;
   10171         7621 :   rtvec v;
   10172         7621 :   unsigned int elems_needed, align, i, vi = 0;
   10173         7621 :   rtx_insn *insn;
   10174         7621 :   rtx sym, tmp;
   10175         7621 :   rtx rsi = gen_rtx_REG (word_mode, SI_REG);
   10176         7621 :   rtx r10 = NULL_RTX;
   10177         7621 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
   10178         7621 :   HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
   10179         7621 :   HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
   10180         7621 :   rtx rsi_frame_load = NULL_RTX;
   10181         7621 :   HOST_WIDE_INT rsi_restore_offset = (HOST_WIDE_INT)-1;
   10182         7621 :   enum xlogue_stub stub;
   10183              : 
   10184         7621 :   gcc_assert (!m->fs.fp_valid || frame_pointer_needed);
   10185              : 
   10186              :   /* If using a realigned stack, we should never start with padding.  */
   10187         7621 :   gcc_assert (!stack_realign_fp || !xlogue.get_stack_align_off_in ());
   10188              : 
   10189              :   /* Setup RSI as the stub's base pointer.  */
   10190         7621 :   align = GET_MODE_ALIGNMENT (V4SFmode);
   10191         7621 :   tmp = choose_baseaddr (rsi_offset, &align, SI_REG);
   10192         7621 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
   10193              : 
   10194         7621 :   emit_insn (gen_rtx_SET (rsi, tmp));
   10195              : 
   10196              :   /* Get a symbol for the stub.  */
   10197         7621 :   if (frame_pointer_needed)
   10198         5955 :     stub = use_call ? XLOGUE_STUB_RESTORE_HFP
   10199              :                     : XLOGUE_STUB_RESTORE_HFP_TAIL;
   10200              :   else
   10201         1666 :     stub = use_call ? XLOGUE_STUB_RESTORE
   10202              :                     : XLOGUE_STUB_RESTORE_TAIL;
   10203         7621 :   sym = xlogue.get_stub_rtx (stub);
   10204              : 
   10205         7621 :   elems_needed = ncregs;
   10206         7621 :   if (use_call)
   10207         6506 :     elems_needed += 1;
   10208              :   else
   10209         1267 :     elems_needed += frame_pointer_needed ? 5 : 3;
   10210         7621 :   v = rtvec_alloc (elems_needed);
   10211              : 
   10212              :   /* We call the epilogue stub when we need to pop incoming args or we are
   10213              :      doing a sibling call as the tail.  Otherwise, we will emit a jmp to the
   10214              :      epilogue stub and it is the tail-call.  */
   10215         7621 :   if (use_call)
   10216         6506 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
   10217              :   else
   10218              :     {
   10219         1115 :       RTVEC_ELT (v, vi++) = ret_rtx;
   10220         1115 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
   10221         1115 :       if (frame_pointer_needed)
   10222              :         {
   10223          963 :           rtx rbp = gen_rtx_REG (DImode, BP_REG);
   10224          963 :           gcc_assert (m->fs.fp_valid);
   10225          963 :           gcc_assert (m->fs.cfa_reg == hard_frame_pointer_rtx);
   10226              : 
   10227          963 :           tmp = plus_constant (DImode, rbp, 8);
   10228          963 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, tmp);
   10229          963 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (rbp, gen_rtx_MEM (DImode, rbp));
   10230          963 :           tmp = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
   10231          963 :           RTVEC_ELT (v, vi++) = gen_rtx_CLOBBER (VOIDmode, tmp);
   10232              :         }
   10233              :       else
   10234              :         {
   10235              :           /* If no hard frame pointer, we set R10 to the SP restore value.  */
   10236          152 :           gcc_assert (!m->fs.fp_valid);
   10237          152 :           gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
   10238          152 :           gcc_assert (m->fs.sp_valid);
   10239              : 
   10240          152 :           r10 = gen_rtx_REG (DImode, R10_REG);
   10241          152 :           tmp = plus_constant (Pmode, rsi, stub_ptr_offset);
   10242          152 :           emit_insn (gen_rtx_SET (r10, tmp));
   10243              : 
   10244          152 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, r10);
   10245              :         }
   10246              :     }
   10247              : 
   10248              :   /* Generate frame load insns and restore notes.  */
   10249       107830 :   for (i = 0; i < ncregs; ++i)
   10250              :     {
   10251       100209 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
   10252       100209 :       machine_mode mode = SSE_REGNO_P (r.regno) ? V4SFmode : word_mode;
   10253       100209 :       rtx reg, frame_load;
   10254              : 
   10255       100209 :       reg = gen_rtx_REG (mode, r.regno);
   10256       100209 :       frame_load = gen_frame_load (reg, rsi, r.offset);
   10257              : 
   10258              :       /* Save RSI frame load insn & note to add last.  */
   10259       100209 :       if (r.regno == SI_REG)
   10260              :         {
   10261         7621 :           gcc_assert (!rsi_frame_load);
   10262         7621 :           rsi_frame_load = frame_load;
   10263         7621 :           rsi_restore_offset = r.offset;
   10264              :         }
   10265              :       else
   10266              :         {
   10267        92588 :           RTVEC_ELT (v, vi++) = frame_load;
   10268        92588 :           ix86_add_cfa_restore_note (NULL, reg, r.offset);
   10269              :         }
   10270              :     }
   10271              : 
   10272              :   /* Add RSI frame load & restore note at the end.  */
   10273         7621 :   gcc_assert (rsi_frame_load);
   10274         7621 :   gcc_assert (rsi_restore_offset != (HOST_WIDE_INT)-1);
   10275         7621 :   RTVEC_ELT (v, vi++) = rsi_frame_load;
   10276         7621 :   ix86_add_cfa_restore_note (NULL, gen_rtx_REG (DImode, SI_REG),
   10277              :                              rsi_restore_offset);
   10278              : 
   10279              :   /* Finally, for tail-call w/o a hard frame pointer, set SP to R10.  */
   10280         7621 :   if (!use_call && !frame_pointer_needed)
   10281              :     {
   10282          152 :       gcc_assert (m->fs.sp_valid);
   10283          152 :       gcc_assert (!m->fs.sp_realigned);
   10284              : 
   10285              :       /* At this point, R10 should point to frame.stack_realign_offset.  */
   10286          152 :       if (m->fs.cfa_reg == stack_pointer_rtx)
   10287          152 :         m->fs.cfa_offset += m->fs.sp_offset - frame.stack_realign_offset;
   10288          152 :       m->fs.sp_offset = frame.stack_realign_offset;
   10289              :     }
   10290              : 
   10291         7621 :   gcc_assert (vi == (unsigned int)GET_NUM_ELEM (v));
   10292         7621 :   tmp = gen_rtx_PARALLEL (VOIDmode, v);
   10293         7621 :   if (use_call)
   10294         6506 :       insn = emit_insn (tmp);
   10295              :   else
   10296              :     {
   10297         1115 :       insn = emit_jump_insn (tmp);
   10298         1115 :       JUMP_LABEL (insn) = ret_rtx;
   10299              : 
   10300         1115 :       if (frame_pointer_needed)
   10301          963 :         ix86_emit_leave (insn);
   10302              :       else
   10303              :         {
   10304              :           /* Need CFA adjust note.  */
   10305          152 :           tmp = gen_rtx_SET (stack_pointer_rtx, r10);
   10306          152 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, tmp);
   10307              :         }
   10308              :     }
   10309              : 
   10310         7621 :   RTX_FRAME_RELATED_P (insn) = true;
   10311         7621 :   ix86_add_queued_cfa_restore_notes (insn);
   10312              : 
   10313              :   /* If we're not doing a tail-call, we need to adjust the stack.  */
   10314         7621 :   if (use_call && m->fs.sp_valid)
   10315              :     {
   10316         3706 :       HOST_WIDE_INT dealloc = m->fs.sp_offset - frame.stack_realign_offset;
   10317         3706 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10318              :                                 GEN_INT (dealloc), style,
   10319         3706 :                                 m->fs.cfa_reg == stack_pointer_rtx);
   10320              :     }
   10321         7621 : }
   10322              : 
   10323              : /* Restore function stack, frame, and registers.  */
   10324              : 
   10325              : void
   10326      1662157 : ix86_expand_epilogue (int style)
   10327              : {
   10328      1662157 :   struct machine_function *m = cfun->machine;
   10329      1662157 :   struct machine_frame_state frame_state_save = m->fs;
   10330      1662157 :   bool restore_regs_via_mov;
   10331      1662157 :   bool using_drap;
   10332      1662157 :   bool restore_stub_is_tail = false;
   10333              : 
   10334      1662157 :   if (ix86_function_naked (current_function_decl))
   10335              :     {
   10336              :       /* The program should not reach this point.  */
   10337           76 :       emit_insn (gen_ud2 ());
   10338       124095 :       return;
   10339              :     }
   10340              : 
   10341      1662081 :   ix86_finalize_stack_frame_flags ();
   10342      1662081 :   const struct ix86_frame &frame = cfun->machine->frame;
   10343              : 
   10344      1662081 :   m->fs.sp_realigned = stack_realign_fp;
   10345        31359 :   m->fs.sp_valid = stack_realign_fp
   10346      1637827 :                    || !frame_pointer_needed
   10347      2127160 :                    || crtl->sp_is_unchanging;
   10348      1662081 :   gcc_assert (!m->fs.sp_valid
   10349              :               || m->fs.sp_offset == frame.stack_pointer_offset);
   10350              : 
   10351              :   /* The FP must be valid if the frame pointer is present.  */
   10352      1662081 :   gcc_assert (frame_pointer_needed == m->fs.fp_valid);
   10353      1662081 :   gcc_assert (!m->fs.fp_valid
   10354              :               || m->fs.fp_offset == frame.hard_frame_pointer_offset);
   10355              : 
   10356              :   /* We must have *some* valid pointer to the stack frame.  */
   10357      1662081 :   gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
   10358              : 
   10359              :   /* The DRAP is never valid at this point.  */
   10360      1662081 :   gcc_assert (!m->fs.drap_valid);
   10361              : 
   10362              :   /* See the comment about red zone and frame
   10363              :      pointer usage in ix86_expand_prologue.  */
   10364      1662081 :   if (frame_pointer_needed && frame.red_zone_size)
   10365       131688 :     emit_insn (gen_memory_blockage ());
   10366              : 
   10367      1662081 :   using_drap = crtl->drap_reg && crtl->stack_realign_needed;
   10368         7105 :   gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
   10369              : 
   10370              :   /* Determine the CFA offset of the end of the red-zone.  */
   10371      1662081 :   m->fs.red_zone_offset = 0;
   10372      1662081 :   if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
   10373              :     {
   10374              :       /* The red-zone begins below return address and error code in
   10375              :          exception handler.  */
   10376      1484449 :       m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
   10377              : 
   10378              :       /* When the register save area is in the aligned portion of
   10379              :          the stack, determine the maximum runtime displacement that
   10380              :          matches up with the aligned frame.  */
   10381      1484449 :       if (stack_realign_drap)
   10382         8480 :         m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
   10383         4240 :                                   + UNITS_PER_WORD);
   10384              :     }
   10385              : 
   10386      1662081 :   HOST_WIDE_INT reg_save_offset = frame.reg_save_offset;
   10387              : 
   10388              :   /* Special care must be taken for the normal return case of a function
   10389              :      using eh_return: the eax and edx registers are marked as saved, but
   10390              :      not restored along this path.  Adjust the save location to match.  */
   10391      1662081 :   if (crtl->calls_eh_return && style != 2)
   10392           37 :     reg_save_offset -= 2 * UNITS_PER_WORD;
   10393              : 
   10394              :   /* EH_RETURN requires the use of moves to function properly.  */
   10395      1662081 :   if (crtl->calls_eh_return)
   10396              :     restore_regs_via_mov = true;
   10397              :   /* SEH requires the use of pops to identify the epilogue.  */
   10398      1662023 :   else if (TARGET_SEH)
   10399              :     restore_regs_via_mov = false;
   10400              :   /* If we already save reg with pushp, don't use move at epilogue.  */
   10401      1662023 :   else if (m->fs.apx_ppx_used)
   10402              :     restore_regs_via_mov = false;
   10403              :   /* If we're only restoring one register and sp cannot be used then
   10404              :      using a move instruction to restore the register since it's
   10405              :      less work than reloading sp and popping the register.  */
   10406      1661935 :   else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
   10407              :     restore_regs_via_mov = true;
   10408      1601091 :   else if (crtl->shrink_wrapped_separate
   10409      1549348 :            || (TARGET_EPILOGUE_USING_MOVE
   10410        56848 :                && cfun->machine->use_fast_prologue_epilogue
   10411        56792 :                && (frame.nregs > 1
   10412        56778 :                    || m->fs.sp_offset != reg_save_offset)))
   10413              :     restore_regs_via_mov = true;
   10414      1549113 :   else if (frame_pointer_needed
   10415       425873 :            && !frame.nregs
   10416       330673 :            && m->fs.sp_offset != reg_save_offset)
   10417              :     restore_regs_via_mov = true;
   10418      1394913 :   else if (frame_pointer_needed
   10419       271673 :            && TARGET_USE_LEAVE
   10420       271598 :            && cfun->machine->use_fast_prologue_epilogue
   10421       215110 :            && frame.nregs == 1)
   10422              :     restore_regs_via_mov = true;
   10423              :   else
   10424      1662081 :     restore_regs_via_mov = false;
   10425              : 
   10426      1662081 :   if (crtl->shrink_wrapped_separate)
   10427        51774 :     gcc_assert (restore_regs_via_mov);
   10428              : 
   10429      1610307 :   if (restore_regs_via_mov || frame.nsseregs)
   10430              :     {
   10431              :       /* Ensure that the entire register save area is addressable via
   10432              :          the stack pointer, if we will restore SSE regs via sp.  */
   10433       330965 :       if (TARGET_64BIT
   10434       318380 :           && m->fs.sp_offset > 0x7fffffff
   10435           23 :           && sp_valid_at (frame.stack_realign_offset + 1)
   10436       330987 :           && (frame.nsseregs + frame.nregs) != 0)
   10437              :         {
   10438            6 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10439            6 :                                      GEN_INT (m->fs.sp_offset
   10440              :                                               - frame.sse_reg_save_offset),
   10441              :                                      style,
   10442            6 :                                      m->fs.cfa_reg == stack_pointer_rtx);
   10443              :         }
   10444              :     }
   10445              : 
   10446              :   /* If there are any SSE registers to restore, then we have to do it
   10447              :      via moves, since there's obviously no pop for SSE regs.  */
   10448      1662081 :   if (frame.nsseregs)
   10449        33952 :     ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
   10450              :                                           style == 2);
   10451              : 
   10452      1662081 :   if (m->call_ms2sysv)
   10453              :     {
   10454         7621 :       int pop_incoming_args = crtl->args.pops_args && crtl->args.size;
   10455              : 
   10456              :       /* We cannot use a tail-call for the stub if:
   10457              :          1. We have to pop incoming args,
   10458              :          2. We have additional int regs to restore, or
   10459              :          3. A sibling call will be the tail-call, or
   10460              :          4. We are emitting an eh_return_internal epilogue.
   10461              : 
   10462              :          TODO: Item 4 has not yet tested!
   10463              : 
   10464              :          If any of the above are true, we will call the stub rather than
   10465              :          jump to it.  */
   10466         7621 :       restore_stub_is_tail = !(pop_incoming_args || frame.nregs || style != 1);
   10467         7621 :       ix86_emit_outlined_ms2sysv_restore (frame, !restore_stub_is_tail, style);
   10468              :     }
   10469              : 
   10470              :   /* If using out-of-line stub that is a tail-call, then...*/
   10471      1662081 :   if (m->call_ms2sysv && restore_stub_is_tail)
   10472              :     {
   10473              :       /* TODO: parinoid tests. (remove eventually)  */
   10474         1115 :       gcc_assert (m->fs.sp_valid);
   10475         1115 :       gcc_assert (!m->fs.sp_realigned);
   10476         1115 :       gcc_assert (!m->fs.fp_valid);
   10477         1115 :       gcc_assert (!m->fs.realigned);
   10478         1115 :       gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
   10479         1115 :       gcc_assert (!crtl->drap_reg);
   10480         1115 :       gcc_assert (!frame.nregs);
   10481         1115 :       gcc_assert (!crtl->shrink_wrapped_separate);
   10482              :     }
   10483      1660966 :   else if (restore_regs_via_mov)
   10484              :     {
   10485       296253 :       rtx t;
   10486              : 
   10487       296253 :       if (frame.nregs)
   10488        96108 :         ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2);
   10489              : 
   10490              :       /* eh_return epilogues need %ecx added to the stack pointer.  */
   10491       296253 :       if (style == 2)
   10492              :         {
   10493           37 :           rtx sa = EH_RETURN_STACKADJ_RTX;
   10494           29 :           rtx_insn *insn;
   10495              : 
   10496           29 :           gcc_assert (!crtl->shrink_wrapped_separate);
   10497              : 
   10498              :           /* Stack realignment doesn't work with eh_return.  */
   10499           29 :           if (crtl->stack_realign_needed)
   10500            0 :             sorry ("Stack realignment not supported with "
   10501              :                    "%<__builtin_eh_return%>");
   10502              : 
   10503              :           /* regparm nested functions don't work with eh_return.  */
   10504           29 :           if (ix86_static_chain_on_stack)
   10505            0 :             sorry ("regparm nested function not supported with "
   10506              :                    "%<__builtin_eh_return%>");
   10507              : 
   10508           29 :           if (frame_pointer_needed)
   10509              :             {
   10510           35 :               t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
   10511           43 :               t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
   10512           27 :               emit_insn (gen_rtx_SET (sa, t));
   10513              : 
   10514              :               /* NB: eh_return epilogues must restore the frame pointer
   10515              :                  in word_mode since the upper 32 bits of RBP register
   10516              :                  can have any values.  */
   10517           27 :               t = gen_frame_mem (word_mode, hard_frame_pointer_rtx);
   10518           27 :               rtx frame_reg = gen_rtx_REG (word_mode,
   10519              :                                            HARD_FRAME_POINTER_REGNUM);
   10520           27 :               insn = emit_move_insn (frame_reg, t);
   10521              : 
   10522              :               /* Note that we use SA as a temporary CFA, as the return
   10523              :                  address is at the proper place relative to it.  We
   10524              :                  pretend this happens at the FP restore insn because
   10525              :                  prior to this insn the FP would be stored at the wrong
   10526              :                  offset relative to SA, and after this insn we have no
   10527              :                  other reasonable register to use for the CFA.  We don't
   10528              :                  bother resetting the CFA to the SP for the duration of
   10529              :                  the return insn, unless the control flow instrumentation
   10530              :                  is done.  In this case the SP is used later and we have
   10531              :                  to reset CFA to SP.  */
   10532           27 :               add_reg_note (insn, REG_CFA_DEF_CFA,
   10533           35 :                             plus_constant (Pmode, sa, UNITS_PER_WORD));
   10534           27 :               ix86_add_queued_cfa_restore_notes (insn);
   10535           27 :               add_reg_note (insn, REG_CFA_RESTORE, frame_reg);
   10536           27 :               RTX_FRAME_RELATED_P (insn) = 1;
   10537              : 
   10538           27 :               m->fs.cfa_reg = sa;
   10539           27 :               m->fs.cfa_offset = UNITS_PER_WORD;
   10540           27 :               m->fs.fp_valid = false;
   10541              : 
   10542           27 :               pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
   10543              :                                          const0_rtx, style,
   10544           27 :                                          flag_cf_protection);
   10545              :             }
   10546              :           else
   10547              :             {
   10548            2 :               t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
   10549            2 :               t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
   10550            2 :               insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, t));
   10551            2 :               ix86_add_queued_cfa_restore_notes (insn);
   10552              : 
   10553            2 :               gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
   10554            2 :               if (m->fs.cfa_offset != UNITS_PER_WORD)
   10555              :                 {
   10556            2 :                   m->fs.cfa_offset = UNITS_PER_WORD;
   10557            2 :                   add_reg_note (insn, REG_CFA_DEF_CFA,
   10558            2 :                                 plus_constant (Pmode, stack_pointer_rtx,
   10559            2 :                                                UNITS_PER_WORD));
   10560            2 :                   RTX_FRAME_RELATED_P (insn) = 1;
   10561              :                 }
   10562              :             }
   10563           29 :           m->fs.sp_offset = UNITS_PER_WORD;
   10564           29 :           m->fs.sp_valid = true;
   10565           29 :           m->fs.sp_realigned = false;
   10566              :         }
   10567              :     }
   10568              :   else
   10569              :     {
   10570              :       /* SEH requires that the function end with (1) a stack adjustment
   10571              :          if necessary, (2) a sequence of pops, and (3) a return or
   10572              :          jump instruction.  Prevent insns from the function body from
   10573              :          being scheduled into this sequence.  */
   10574      1364713 :       if (TARGET_SEH)
   10575              :         {
   10576              :           /* Prevent a catch region from being adjacent to the standard
   10577              :              epilogue sequence.  Unfortunately neither crtl->uses_eh_lsda
   10578              :              nor several other flags that would be interesting to test are
   10579              :              set up yet.  */
   10580              :           if (flag_non_call_exceptions)
   10581              :             emit_insn (gen_nops (const1_rtx));
   10582              :           else
   10583              :             emit_insn (gen_blockage ());
   10584              :         }
   10585              : 
   10586              :       /* First step is to deallocate the stack frame so that we can
   10587              :          pop the registers.  If the stack pointer was realigned, it needs
   10588              :          to be restored now.  Also do it on SEH target for very large
   10589              :          frame as the emitted instructions aren't allowed by the ABI
   10590              :          in epilogues.  */
   10591      1364713 :       if (!m->fs.sp_valid || m->fs.sp_realigned
   10592              :           || (TARGET_SEH
   10593              :               && (m->fs.sp_offset - reg_save_offset
   10594              :                   >= SEH_MAX_FRAME_SIZE)))
   10595              :         {
   10596        29560 :           pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
   10597        29560 :                                      GEN_INT (m->fs.fp_offset
   10598              :                                               - reg_save_offset),
   10599              :                                      style, false);
   10600              :         }
   10601      1335153 :       else if (m->fs.sp_offset != reg_save_offset)
   10602              :         {
   10603       619081 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10604              :                                      GEN_INT (m->fs.sp_offset
   10605              :                                               - reg_save_offset),
   10606              :                                      style,
   10607       619081 :                                      m->fs.cfa_reg == stack_pointer_rtx);
   10608              :         }
   10609              : 
   10610      1364713 :       if (TARGET_APX_PUSH2POP2
   10611          573 :           && ix86_can_use_push2pop2 ()
   10612      1365284 :           && m->func_type == TYPE_NORMAL)
   10613          570 :         ix86_emit_restore_regs_using_pop2 ();
   10614              :       else
   10615      1364143 :         ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
   10616              :     }
   10617              : 
   10618              :   /* If we used a stack pointer and haven't already got rid of it,
   10619              :      then do so now.  */
   10620      1662081 :   if (m->fs.fp_valid)
   10621              :     {
   10622              :       /* If the stack pointer is valid and pointing at the frame
   10623              :          pointer store address, then we only need a pop.  */
   10624       488343 :       if (sp_valid_at (frame.hfp_save_offset)
   10625       488343 :           && m->fs.sp_offset == frame.hfp_save_offset)
   10626       241621 :         ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10627              :       /* Leave results in shorter dependency chains on CPUs that are
   10628              :          able to grok it fast.  */
   10629       246722 :       else if (TARGET_USE_LEAVE
   10630           12 :                || optimize_bb_for_size_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
   10631       246734 :                || !cfun->machine->use_fast_prologue_epilogue)
   10632       246710 :         ix86_emit_leave (NULL);
   10633              :       else
   10634              :         {
   10635           12 :           pro_epilogue_adjust_stack (stack_pointer_rtx,
   10636              :                                      hard_frame_pointer_rtx,
   10637           12 :                                      const0_rtx, style, !using_drap);
   10638           12 :           ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10639              :         }
   10640              :     }
   10641              : 
   10642      1662081 :   if (using_drap)
   10643              :     {
   10644         7105 :       int param_ptr_offset = UNITS_PER_WORD;
   10645         7105 :       rtx_insn *insn;
   10646              : 
   10647         7105 :       gcc_assert (stack_realign_drap);
   10648              : 
   10649         7105 :       if (ix86_static_chain_on_stack)
   10650            0 :         param_ptr_offset += UNITS_PER_WORD;
   10651         7105 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10652          232 :         param_ptr_offset += UNITS_PER_WORD;
   10653              : 
   10654         7410 :       insn = emit_insn (gen_rtx_SET
   10655              :                         (stack_pointer_rtx,
   10656              :                          plus_constant (Pmode, crtl->drap_reg,
   10657              :                                         -param_ptr_offset)));
   10658         7105 :       m->fs.cfa_reg = stack_pointer_rtx;
   10659         7105 :       m->fs.cfa_offset = param_ptr_offset;
   10660         7105 :       m->fs.sp_offset = param_ptr_offset;
   10661         7105 :       m->fs.realigned = false;
   10662              : 
   10663         7410 :       add_reg_note (insn, REG_CFA_DEF_CFA,
   10664         7105 :                     plus_constant (Pmode, stack_pointer_rtx,
   10665         7105 :                                    param_ptr_offset));
   10666         7105 :       RTX_FRAME_RELATED_P (insn) = 1;
   10667              : 
   10668         7105 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10669          232 :         ix86_emit_restore_reg_using_pop (crtl->drap_reg);
   10670              :     }
   10671              : 
   10672              :   /* At this point the stack pointer must be valid, and we must have
   10673              :      restored all of the registers.  We may not have deallocated the
   10674              :      entire stack frame.  We've delayed this until now because it may
   10675              :      be possible to merge the local stack deallocation with the
   10676              :      deallocation forced by ix86_static_chain_on_stack.   */
   10677      1662081 :   gcc_assert (m->fs.sp_valid);
   10678      1662081 :   gcc_assert (!m->fs.sp_realigned);
   10679      1662081 :   gcc_assert (!m->fs.fp_valid);
   10680      1662081 :   gcc_assert (!m->fs.realigned);
   10681      1797915 :   if (m->fs.sp_offset != UNITS_PER_WORD)
   10682              :     {
   10683        49488 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10684              :                                  GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
   10685              :                                  style, true);
   10686              :     }
   10687              :   else
   10688      1612593 :     ix86_add_queued_cfa_restore_notes (get_last_insn ());
   10689              : 
   10690              :   /* Sibcall epilogues don't want a return instruction.  */
   10691      1662081 :   if (style == 0)
   10692              :     {
   10693       123943 :       m->fs = frame_state_save;
   10694       123943 :       return;
   10695              :     }
   10696              : 
   10697      1538138 :   if (cfun->machine->func_type != TYPE_NORMAL)
   10698          120 :     emit_jump_insn (gen_interrupt_return ());
   10699      1538018 :   else if (crtl->args.pops_args && crtl->args.size)
   10700              :     {
   10701        26005 :       rtx popc = GEN_INT (crtl->args.pops_args);
   10702              : 
   10703              :       /* i386 can only pop 64K bytes.  If asked to pop more, pop return
   10704              :          address, do explicit add, and jump indirectly to the caller.  */
   10705              : 
   10706        26005 :       if (crtl->args.pops_args >= 65536)
   10707              :         {
   10708            0 :           rtx ecx = gen_rtx_REG (SImode, CX_REG);
   10709            0 :           rtx_insn *insn;
   10710              : 
   10711              :           /* There is no "pascal" calling convention in any 64bit ABI.  */
   10712            0 :           gcc_assert (!TARGET_64BIT);
   10713              : 
   10714            0 :           insn = emit_insn (gen_pop (ecx));
   10715            0 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10716            0 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10717              : 
   10718            0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10719            0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10720            0 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10721            0 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10722            0 :           RTX_FRAME_RELATED_P (insn) = 1;
   10723              : 
   10724            0 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10725              :                                      popc, -1, true);
   10726            0 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10727              :         }
   10728              :       else
   10729        26005 :         emit_jump_insn (gen_simple_return_pop_internal (popc));
   10730              :     }
   10731      1512013 :   else if (!m->call_ms2sysv || !restore_stub_is_tail)
   10732              :     {
   10733              :       /* In case of return from EH a simple return cannot be used
   10734              :          as a return address will be compared with a shadow stack
   10735              :          return address.  Use indirect jump instead.  */
   10736      1510898 :       if (style == 2 && flag_cf_protection)
   10737              :         {
   10738              :           /* Register used in indirect jump must be in word_mode.  But
   10739              :              Pmode may not be the same as word_mode for x32.  */
   10740           17 :           rtx ecx = gen_rtx_REG (word_mode, CX_REG);
   10741           17 :           rtx_insn *insn;
   10742              : 
   10743           17 :           insn = emit_insn (gen_pop (ecx));
   10744           17 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10745           17 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10746              : 
   10747           33 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10748           17 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10749           17 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10750           17 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10751           17 :           RTX_FRAME_RELATED_P (insn) = 1;
   10752              : 
   10753           17 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10754           17 :         }
   10755              :       else
   10756      1510881 :         emit_jump_insn (gen_simple_return_internal ());
   10757              :     }
   10758              : 
   10759              :   /* Restore the state back to the state from the prologue,
   10760              :      so that it's correct for the next epilogue.  */
   10761      1538138 :   m->fs = frame_state_save;
   10762              : }
   10763              : 
   10764              : /* Reset from the function's potential modifications.  */
   10765              : 
   10766              : static void
   10767      1499320 : ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
   10768              : {
   10769      1499320 :   if (pic_offset_table_rtx
   10770      1499320 :       && !ix86_use_pseudo_pic_reg ())
   10771            0 :     SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
   10772              : 
   10773      1499320 :   if (TARGET_MACHO)
   10774              :     {
   10775              :       rtx_insn *insn = get_last_insn ();
   10776              :       rtx_insn *deleted_debug_label = NULL;
   10777              : 
   10778              :       /* Mach-O doesn't support labels at the end of objects, so if
   10779              :          it looks like we might want one, take special action.
   10780              :         First, collect any sequence of deleted debug labels.  */
   10781              :       while (insn
   10782              :              && NOTE_P (insn)
   10783              :              && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
   10784              :         {
   10785              :           /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
   10786              :              notes only, instead set their CODE_LABEL_NUMBER to -1,
   10787              :              otherwise there would be code generation differences
   10788              :              in between -g and -g0.  */
   10789              :           if (NOTE_P (insn) && NOTE_KIND (insn)
   10790              :               == NOTE_INSN_DELETED_DEBUG_LABEL)
   10791              :             deleted_debug_label = insn;
   10792              :           insn = PREV_INSN (insn);
   10793              :         }
   10794              : 
   10795              :       /* If we have:
   10796              :          label:
   10797              :             barrier
   10798              :           then this needs to be detected, so skip past the barrier.  */
   10799              : 
   10800              :       if (insn && BARRIER_P (insn))
   10801              :         insn = PREV_INSN (insn);
   10802              : 
   10803              :       /* Up to now we've only seen notes or barriers.  */
   10804              :       if (insn)
   10805              :         {
   10806              :           if (LABEL_P (insn)
   10807              :               || (NOTE_P (insn)
   10808              :                   && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
   10809              :             /* Trailing label.  */
   10810              :             fputs ("\tnop\n", file);
   10811              :           else if (cfun && ! cfun->is_thunk)
   10812              :             {
   10813              :               /* See if we have a completely empty function body, skipping
   10814              :                  the special case of the picbase thunk emitted as asm.  */
   10815              :               while (insn && ! INSN_P (insn))
   10816              :                 insn = PREV_INSN (insn);
   10817              :               /* If we don't find any insns, we've got an empty function body;
   10818              :                  I.e. completely empty - without a return or branch.  This is
   10819              :                  taken as the case where a function body has been removed
   10820              :                  because it contains an inline __builtin_unreachable().  GCC
   10821              :                  declares that reaching __builtin_unreachable() means UB so
   10822              :                  we're not obliged to do anything special; however, we want
   10823              :                  non-zero-sized function bodies.  To meet this, and help the
   10824              :                  user out, let's trap the case.  */
   10825              :               if (insn == NULL)
   10826              :                 fputs ("\tud2\n", file);
   10827              :             }
   10828              :         }
   10829              :       else if (deleted_debug_label)
   10830              :         for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
   10831              :           if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
   10832              :             CODE_LABEL_NUMBER (insn) = -1;
   10833              :     }
   10834      1499320 : }
   10835              : 
   10836              : /* Implement TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY.  */
   10837              : 
   10838              : void
   10839           59 : ix86_print_patchable_function_entry (FILE *file,
   10840              :                                      unsigned HOST_WIDE_INT patch_area_size,
   10841              :                                      bool record_p)
   10842              : {
   10843           59 :   if (cfun->machine->function_label_emitted)
   10844              :     {
   10845              :       /* NB: When ix86_print_patchable_function_entry is called after
   10846              :          function table has been emitted, we have inserted or queued
   10847              :          a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
   10848              :          place.  There is nothing to do here.  */
   10849              :       return;
   10850              :     }
   10851              : 
   10852            8 :   default_print_patchable_function_entry (file, patch_area_size,
   10853              :                                           record_p);
   10854              : }
   10855              : 
   10856              : /* Output patchable area.  NB: default_print_patchable_function_entry
   10857              :    isn't available in i386.md.  */
   10858              : 
   10859              : void
   10860           51 : ix86_output_patchable_area (unsigned int patch_area_size,
   10861              :                             bool record_p)
   10862              : {
   10863           51 :   default_print_patchable_function_entry (asm_out_file,
   10864              :                                           patch_area_size,
   10865              :                                           record_p);
   10866           51 : }
   10867              : 
   10868              : /* Return a scratch register to use in the split stack prologue.  The
   10869              :    split stack prologue is used for -fsplit-stack.  It is the first
   10870              :    instructions in the function, even before the regular prologue.
   10871              :    The scratch register can be any caller-saved register which is not
   10872              :    used for parameters or for the static chain.  */
   10873              : 
   10874              : static unsigned int
   10875        24564 : split_stack_prologue_scratch_regno (void)
   10876              : {
   10877        24564 :   if (TARGET_64BIT)
   10878              :     return R11_REG;
   10879              :   else
   10880              :     {
   10881         6896 :       bool is_fastcall, is_thiscall;
   10882         6896 :       int regparm;
   10883              : 
   10884         6896 :       is_fastcall = (lookup_attribute ("fastcall",
   10885         6896 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10886              :                      != NULL);
   10887         6896 :       is_thiscall = (lookup_attribute ("thiscall",
   10888         6896 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10889              :                      != NULL);
   10890         6896 :       regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
   10891              : 
   10892         6896 :       if (is_fastcall)
   10893              :         {
   10894            0 :           if (DECL_STATIC_CHAIN (cfun->decl))
   10895              :             {
   10896            0 :               sorry ("%<-fsplit-stack%> does not support fastcall with "
   10897              :                      "nested function");
   10898            0 :               return INVALID_REGNUM;
   10899              :             }
   10900              :           return AX_REG;
   10901              :         }
   10902         6896 :       else if (is_thiscall)
   10903              :         {
   10904            0 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10905              :             return DX_REG;
   10906            0 :           return AX_REG;
   10907              :         }
   10908         6896 :       else if (regparm < 3)
   10909              :         {
   10910         6896 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10911              :             return CX_REG;
   10912              :           else
   10913              :             {
   10914          458 :               if (regparm >= 2)
   10915              :                 {
   10916            0 :                   sorry ("%<-fsplit-stack%> does not support 2 register "
   10917              :                          "parameters for a nested function");
   10918            0 :                   return INVALID_REGNUM;
   10919              :                 }
   10920              :               return DX_REG;
   10921              :             }
   10922              :         }
   10923              :       else
   10924              :         {
   10925              :           /* FIXME: We could make this work by pushing a register
   10926              :              around the addition and comparison.  */
   10927            0 :           sorry ("%<-fsplit-stack%> does not support 3 register parameters");
   10928            0 :           return INVALID_REGNUM;
   10929              :         }
   10930              :     }
   10931              : }
   10932              : 
   10933              : /* A SYMBOL_REF for the function which allocates new stackspace for
   10934              :    -fsplit-stack.  */
   10935              : 
   10936              : static GTY(()) rtx split_stack_fn;
   10937              : 
   10938              : /* A SYMBOL_REF for the more stack function when using the large model.  */
   10939              : 
   10940              : static GTY(()) rtx split_stack_fn_large;
   10941              : 
   10942              : /* Return location of the stack guard value in the TLS block.  */
   10943              : 
   10944              : rtx
   10945       260046 : ix86_split_stack_guard (void)
   10946              : {
   10947       260046 :   int offset;
   10948       260046 :   addr_space_t as = DEFAULT_TLS_SEG_REG;
   10949       260046 :   rtx r;
   10950              : 
   10951       260046 :   gcc_assert (flag_split_stack);
   10952              : 
   10953              : #ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
   10954       260046 :   offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
   10955              : #else
   10956              :   gcc_unreachable ();
   10957              : #endif
   10958              : 
   10959       260046 :   r = GEN_INT (offset);
   10960       358047 :   r = gen_const_mem (Pmode, r);
   10961       260046 :   set_mem_addr_space (r, as);
   10962              : 
   10963       260046 :   return r;
   10964              : }
   10965              : 
   10966              : /* Handle -fsplit-stack.  These are the first instructions in the
   10967              :    function, even before the regular prologue.  */
   10968              : 
   10969              : void
   10970       260036 : ix86_expand_split_stack_prologue (void)
   10971              : {
   10972       260036 :   HOST_WIDE_INT allocate;
   10973       260036 :   unsigned HOST_WIDE_INT args_size;
   10974       260036 :   rtx_code_label *label;
   10975       260036 :   rtx limit, current, allocate_rtx, call_fusage;
   10976       260036 :   rtx_insn *call_insn;
   10977       260036 :   unsigned int scratch_regno = INVALID_REGNUM;
   10978       260036 :   rtx scratch_reg = NULL_RTX;
   10979       260036 :   rtx_code_label *varargs_label = NULL;
   10980       260036 :   rtx fn;
   10981              : 
   10982       260036 :   gcc_assert (flag_split_stack && reload_completed);
   10983              : 
   10984       260036 :   ix86_finalize_stack_frame_flags ();
   10985       260036 :   struct ix86_frame &frame = cfun->machine->frame;
   10986       260036 :   allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
   10987              : 
   10988              :   /* This is the label we will branch to if we have enough stack
   10989              :      space.  We expect the basic block reordering pass to reverse this
   10990              :      branch if optimizing, so that we branch in the unlikely case.  */
   10991       260036 :   label = gen_label_rtx ();
   10992              : 
   10993              :   /* We need to compare the stack pointer minus the frame size with
   10994              :      the stack boundary in the TCB.  The stack boundary always gives
   10995              :      us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
   10996              :      can compare directly.  Otherwise we need to do an addition.  */
   10997              : 
   10998       260036 :   limit = ix86_split_stack_guard ();
   10999              : 
   11000       260036 :   if (allocate >= SPLIT_STACK_AVAILABLE
   11001       235635 :       || flag_force_indirect_call)
   11002              :     {
   11003        24416 :       scratch_regno = split_stack_prologue_scratch_regno ();
   11004        24416 :       if (scratch_regno == INVALID_REGNUM)
   11005            0 :         return;
   11006              :     }
   11007              : 
   11008       260036 :   if (allocate >= SPLIT_STACK_AVAILABLE)
   11009              :     {
   11010        24401 :       rtx offset;
   11011              : 
   11012              :       /* We need a scratch register to hold the stack pointer minus
   11013              :          the required frame size.  Since this is the very start of the
   11014              :          function, the scratch register can be any caller-saved
   11015              :          register which is not used for parameters.  */
   11016        24401 :       offset = GEN_INT (- allocate);
   11017              : 
   11018        31243 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   11019        24401 :       if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
   11020              :         {
   11021              :           /* We don't use gen_add in this case because it will
   11022              :              want to split to lea, but when not optimizing the insn
   11023              :              will not be split after this point.  */
   11024        31243 :           emit_insn (gen_rtx_SET (scratch_reg,
   11025              :                                   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   11026              :                                                 offset)));
   11027              :         }
   11028              :       else
   11029              :         {
   11030            0 :           emit_move_insn (scratch_reg, offset);
   11031            0 :           emit_insn (gen_add2_insn (scratch_reg, stack_pointer_rtx));
   11032              :         }
   11033              :       current = scratch_reg;
   11034              :     }
   11035              :   else
   11036       235635 :     current = stack_pointer_rtx;
   11037              : 
   11038       260036 :   ix86_expand_branch (GEU, current, limit, label);
   11039       260036 :   rtx_insn *jump_insn = get_last_insn ();
   11040       260036 :   JUMP_LABEL (jump_insn) = label;
   11041              : 
   11042              :   /* Mark the jump as very likely to be taken.  */
   11043       260036 :   add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
   11044              : 
   11045       260036 :   if (split_stack_fn == NULL_RTX)
   11046              :     {
   11047         5452 :       split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
   11048         4348 :       SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
   11049              :     }
   11050       260036 :   fn = split_stack_fn;
   11051              : 
   11052              :   /* Get more stack space.  We pass in the desired stack space and the
   11053              :      size of the arguments to copy to the new stack.  In 32-bit mode
   11054              :      we push the parameters; __morestack will return on a new stack
   11055              :      anyhow.  In 64-bit mode we pass the parameters in r10 and
   11056              :      r11.  */
   11057       260036 :   allocate_rtx = GEN_INT (allocate);
   11058       260036 :   args_size = crtl->args.size >= 0 ? (HOST_WIDE_INT) crtl->args.size : 0;
   11059       260036 :   call_fusage = NULL_RTX;
   11060       260036 :   rtx pop = NULL_RTX;
   11061       260036 :   if (TARGET_64BIT)
   11062              :     {
   11063       162035 :       rtx reg10, reg11;
   11064              : 
   11065       162035 :       reg10 = gen_rtx_REG (DImode, R10_REG);
   11066       162035 :       reg11 = gen_rtx_REG (DImode, R11_REG);
   11067              : 
   11068              :       /* If this function uses a static chain, it will be in %r10.
   11069              :          Preserve it across the call to __morestack.  */
   11070       162035 :       if (DECL_STATIC_CHAIN (cfun->decl))
   11071              :         {
   11072         7505 :           rtx rax;
   11073              : 
   11074         7505 :           rax = gen_rtx_REG (word_mode, AX_REG);
   11075         7505 :           emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
   11076         7505 :           use_reg (&call_fusage, rax);
   11077              :         }
   11078              : 
   11079       162035 :       if (flag_force_indirect_call
   11080       162020 :           || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
   11081              :         {
   11082           16 :           HOST_WIDE_INT argval;
   11083              : 
   11084           16 :           if (split_stack_fn_large == NULL_RTX)
   11085              :             {
   11086            7 :               split_stack_fn_large
   11087            7 :                 = gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
   11088            7 :               SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
   11089              :             }
   11090              : 
   11091           16 :           fn = split_stack_fn_large;
   11092              : 
   11093           16 :           if (ix86_cmodel == CM_LARGE_PIC)
   11094              :             {
   11095            3 :               rtx_code_label *label;
   11096            3 :               rtx x;
   11097              : 
   11098            3 :               gcc_assert (Pmode == DImode);
   11099              : 
   11100            3 :               label = gen_label_rtx ();
   11101            3 :               emit_label (label);
   11102            3 :               LABEL_PRESERVE_P (label) = 1;
   11103            3 :               emit_insn (gen_set_rip_rex64 (reg10, label));
   11104            3 :               emit_insn (gen_set_got_offset_rex64 (reg11, label));
   11105            3 :               emit_insn (gen_add2_insn (reg10, reg11));
   11106            3 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
   11107            3 :               x = gen_rtx_CONST (Pmode, x);
   11108            3 :               emit_move_insn (reg11, x);
   11109            3 :               x = gen_rtx_PLUS (Pmode, reg10, reg11);
   11110            3 :               x = gen_const_mem (Pmode, x);
   11111            3 :               fn = copy_to_suggested_reg (x, reg11, Pmode);
   11112              :             }
   11113           13 :           else if (ix86_cmodel == CM_LARGE)
   11114            1 :             fn = copy_to_suggested_reg (fn, reg11, Pmode);
   11115              : 
   11116              :           /* When using the large model we need to load the address
   11117              :              into a register, and we've run out of registers.  So we
   11118              :              switch to a different calling convention, and we call a
   11119              :              different function: __morestack_large.  We pass the
   11120              :              argument size in the upper 32 bits of r10 and pass the
   11121              :              frame size in the lower 32 bits.  */
   11122           16 :           gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
   11123           16 :           gcc_assert ((args_size & 0xffffffff) == args_size);
   11124              : 
   11125           16 :           argval = ((args_size << 16) << 16) + allocate;
   11126           16 :           emit_move_insn (reg10, GEN_INT (argval));
   11127           16 :         }
   11128              :       else
   11129              :         {
   11130       162019 :           emit_move_insn (reg10, allocate_rtx);
   11131       162019 :           emit_move_insn (reg11, GEN_INT (args_size));
   11132       162019 :           use_reg (&call_fusage, reg11);
   11133              :         }
   11134              : 
   11135       162035 :       use_reg (&call_fusage, reg10);
   11136              :     }
   11137              :   else
   11138              :     {
   11139        98001 :       if (flag_force_indirect_call && flag_pic)
   11140              :         {
   11141            0 :           rtx x;
   11142              : 
   11143            0 :           gcc_assert (Pmode == SImode);
   11144              : 
   11145            0 :           scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   11146              : 
   11147            0 :           emit_insn (gen_set_got (scratch_reg));
   11148            0 :           x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
   11149              :                               UNSPEC_GOT);
   11150            0 :           x = gen_rtx_CONST (Pmode, x);
   11151            0 :           x = gen_rtx_PLUS (Pmode, scratch_reg, x);
   11152            0 :           x = gen_const_mem (Pmode, x);
   11153            0 :           fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
   11154              :         }
   11155              : 
   11156        98001 :       rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
   11157       196002 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
   11158        98001 :       insn = emit_insn (gen_push (allocate_rtx));
   11159       196002 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
   11160       196002 :       pop = GEN_INT (2 * UNITS_PER_WORD);
   11161              :     }
   11162              : 
   11163       260036 :   if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
   11164              :     {
   11165           12 :       scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
   11166              : 
   11167           12 :       if (GET_MODE (fn) != word_mode)
   11168            0 :         fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
   11169              : 
   11170           12 :       fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
   11171              :     }
   11172              : 
   11173       260036 :   call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
   11174       260036 :                                 GEN_INT (UNITS_PER_WORD), constm1_rtx,
   11175              :                                 pop, false);
   11176       260036 :   add_function_usage_to (call_insn, call_fusage);
   11177       260036 :   if (!TARGET_64BIT)
   11178        98001 :     add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (0));
   11179              :   /* Indicate that this function can't jump to non-local gotos.  */
   11180       260036 :   make_reg_eh_region_note_nothrow_nononlocal (call_insn);
   11181              : 
   11182              :   /* In order to make call/return prediction work right, we now need
   11183              :      to execute a return instruction.  See
   11184              :      libgcc/config/i386/morestack.S for the details on how this works.
   11185              : 
   11186              :      For flow purposes gcc must not see this as a return
   11187              :      instruction--we need control flow to continue at the subsequent
   11188              :      label.  Therefore, we use an unspec.  */
   11189       260036 :   gcc_assert (crtl->args.pops_args < 65536);
   11190       260036 :   rtx_insn *ret_insn
   11191       260036 :     = emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
   11192              : 
   11193       260036 :   if ((flag_cf_protection & CF_BRANCH))
   11194              :     {
   11195              :       /* Insert ENDBR since __morestack will jump back here via indirect
   11196              :          call.  */
   11197           21 :       rtx cet_eb = gen_nop_endbr ();
   11198           21 :       emit_insn_after (cet_eb, ret_insn);
   11199              :     }
   11200              : 
   11201              :   /* If we are in 64-bit mode and this function uses a static chain,
   11202              :      we saved %r10 in %rax before calling _morestack.  */
   11203       260036 :   if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
   11204         7505 :     emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
   11205              :                     gen_rtx_REG (word_mode, AX_REG));
   11206              : 
   11207              :   /* If this function calls va_start, we need to store a pointer to
   11208              :      the arguments on the old stack, because they may not have been
   11209              :      all copied to the new stack.  At this point the old stack can be
   11210              :      found at the frame pointer value used by __morestack, because
   11211              :      __morestack has set that up before calling back to us.  Here we
   11212              :      store that pointer in a scratch register, and in
   11213              :      ix86_expand_prologue we store the scratch register in a stack
   11214              :      slot.  */
   11215       260036 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   11216              :     {
   11217           12 :       rtx frame_reg;
   11218           12 :       int words;
   11219              : 
   11220           12 :       scratch_regno = split_stack_prologue_scratch_regno ();
   11221           16 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   11222           16 :       frame_reg = gen_rtx_REG (Pmode, BP_REG);
   11223              : 
   11224              :       /* 64-bit:
   11225              :          fp -> old fp value
   11226              :                return address within this function
   11227              :                return address of caller of this function
   11228              :                stack arguments
   11229              :          So we add three words to get to the stack arguments.
   11230              : 
   11231              :          32-bit:
   11232              :          fp -> old fp value
   11233              :                return address within this function
   11234              :                first argument to __morestack
   11235              :                second argument to __morestack
   11236              :                return address of caller of this function
   11237              :                stack arguments
   11238              :          So we add five words to get to the stack arguments.
   11239              :       */
   11240           12 :       words = TARGET_64BIT ? 3 : 5;
   11241           20 :       emit_insn (gen_rtx_SET (scratch_reg,
   11242              :                               plus_constant (Pmode, frame_reg,
   11243              :                                              words * UNITS_PER_WORD)));
   11244              : 
   11245           12 :       varargs_label = gen_label_rtx ();
   11246           12 :       emit_jump_insn (gen_jump (varargs_label));
   11247           12 :       JUMP_LABEL (get_last_insn ()) = varargs_label;
   11248              : 
   11249           12 :       emit_barrier ();
   11250              :     }
   11251              : 
   11252       260036 :   emit_label (label);
   11253       260036 :   LABEL_NUSES (label) = 1;
   11254              : 
   11255              :   /* If this function calls va_start, we now have to set the scratch
   11256              :      register for the case where we do not call __morestack.  In this
   11257              :      case we need to set it based on the stack pointer.  */
   11258       260036 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   11259              :     {
   11260           20 :       emit_insn (gen_rtx_SET (scratch_reg,
   11261              :                               plus_constant (Pmode, stack_pointer_rtx,
   11262              :                                              UNITS_PER_WORD)));
   11263              : 
   11264           12 :       emit_label (varargs_label);
   11265           12 :       LABEL_NUSES (varargs_label) = 1;
   11266              :     }
   11267              : }
   11268              : 
   11269              : /* We may have to tell the dataflow pass that the split stack prologue
   11270              :    is initializing a scratch register.  */
   11271              : 
   11272              : static void
   11273     15992731 : ix86_live_on_entry (bitmap regs)
   11274              : {
   11275     15992731 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   11276              :     {
   11277          124 :       gcc_assert (flag_split_stack);
   11278          124 :       bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
   11279              :     }
   11280     15992731 : }
   11281              : 
   11282              : /* Extract the parts of an RTL expression that is a valid memory address
   11283              :    for an instruction.  Return false if the structure of the address is
   11284              :    grossly off.  */
   11285              : 
   11286              : bool
   11287   4291060027 : ix86_decompose_address (rtx addr, struct ix86_address *out)
   11288              : {
   11289   4291060027 :   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
   11290   4291060027 :   rtx base_reg, index_reg;
   11291   4291060027 :   HOST_WIDE_INT scale = 1;
   11292   4291060027 :   rtx scale_rtx = NULL_RTX;
   11293   4291060027 :   rtx tmp;
   11294   4291060027 :   addr_space_t seg = ADDR_SPACE_GENERIC;
   11295              : 
   11296              :   /* Allow zero-extended SImode addresses,
   11297              :      they will be emitted with addr32 prefix.  */
   11298   4291060027 :   if (TARGET_64BIT && GET_MODE (addr) == DImode)
   11299              :     {
   11300   2268276949 :       if (GET_CODE (addr) == ZERO_EXTEND
   11301      2034053 :           && GET_MODE (XEXP (addr, 0)) == SImode)
   11302              :         {
   11303      1930183 :           addr = XEXP (addr, 0);
   11304      1930183 :           if (CONST_INT_P (addr))
   11305              :             return false;
   11306              :         }
   11307   2266346766 :       else if (GET_CODE (addr) == AND)
   11308              :         {
   11309      2867795 :           rtx mask = XEXP (addr, 1);
   11310      2867795 :           rtx shift_val;
   11311              : 
   11312      2867795 :           if (const_32bit_mask (mask, DImode)
   11313              :               /* For ASHIFT inside AND, combine will not generate
   11314              :                  canonical zero-extend. Merge mask for AND and shift_count
   11315              :                  to check if it is canonical zero-extend.  */
   11316      2867795 :               || (CONST_INT_P (mask)
   11317      1879200 :                   && GET_CODE (XEXP (addr, 0)) == ASHIFT
   11318       154118 :                   && CONST_INT_P (shift_val = XEXP (XEXP (addr, 0), 1))
   11319       151015 :                   && ((UINTVAL (mask)
   11320       151015 :                        | ((HOST_WIDE_INT_1U << INTVAL (shift_val)) - 1))
   11321              :                       == HOST_WIDE_INT_UC (0xffffffff))))
   11322              :             {
   11323        82597 :               addr = lowpart_subreg (SImode, XEXP (addr, 0), DImode);
   11324        82597 :               if (addr == NULL_RTX)
   11325              :                 return false;
   11326              : 
   11327        82597 :               if (CONST_INT_P (addr))
   11328              :                 return false;
   11329              :             }
   11330              :         }
   11331              :     }
   11332              : 
   11333              :   /* Allow SImode subregs of DImode addresses,
   11334              :      they will be emitted with addr32 prefix.  */
   11335   4291060027 :   if (TARGET_64BIT && GET_MODE (addr) == SImode)
   11336              :     {
   11337     16599275 :       if (SUBREG_P (addr)
   11338       244503 :           && GET_MODE (SUBREG_REG (addr)) == DImode)
   11339              :         {
   11340       214263 :           addr = SUBREG_REG (addr);
   11341       214263 :           if (CONST_INT_P (addr))
   11342              :             return false;
   11343              :         }
   11344              :     }
   11345              : 
   11346   4291060027 :   if (REG_P (addr))
   11347              :     base = addr;
   11348              :   else if (SUBREG_P (addr))
   11349              :     {
   11350       466580 :       if (REG_P (SUBREG_REG (addr)))
   11351              :         base = addr;
   11352              :       else
   11353              :         return false;
   11354              :     }
   11355              :   else if (GET_CODE (addr) == PLUS)
   11356              :     {
   11357              :       rtx addends[4], op;
   11358              :       int n = 0, i;
   11359              : 
   11360              :       op = addr;
   11361   3118442007 :       do
   11362              :         {
   11363   3118442007 :           if (n >= 4)
   11364    641357740 :             return false;
   11365   3118436125 :           addends[n++] = XEXP (op, 1);
   11366   3118436125 :           op = XEXP (op, 0);
   11367              :         }
   11368   3118436125 :       while (GET_CODE (op) == PLUS);
   11369   3058335410 :       if (n >= 4)
   11370              :         return false;
   11371   3058327349 :       addends[n] = op;
   11372              : 
   11373   7955665846 :       for (i = n; i >= 0; --i)
   11374              :         {
   11375   5538682294 :           op = addends[i];
   11376   5538682294 :           switch (GET_CODE (op))
   11377              :             {
   11378     60584732 :             case MULT:
   11379     60584732 :               if (index)
   11380              :                 return false;
   11381     60541646 :               index = XEXP (op, 0);
   11382     60541646 :               scale_rtx = XEXP (op, 1);
   11383     60541646 :               break;
   11384              : 
   11385     12806508 :             case ASHIFT:
   11386     12806508 :               if (index)
   11387              :                 return false;
   11388     12733028 :               index = XEXP (op, 0);
   11389     12733028 :               tmp = XEXP (op, 1);
   11390     12733028 :               if (!CONST_INT_P (tmp))
   11391              :                 return false;
   11392     12718347 :               scale = INTVAL (tmp);
   11393     12718347 :               if ((unsigned HOST_WIDE_INT) scale > 3)
   11394              :                 return false;
   11395     12293373 :               scale = 1 << scale;
   11396     12293373 :               break;
   11397              : 
   11398       808578 :             case ZERO_EXTEND:
   11399       808578 :               op = XEXP (op, 0);
   11400       808578 :               if (GET_CODE (op) != UNSPEC)
   11401              :                 return false;
   11402              :               /* FALLTHRU */
   11403              : 
   11404       701624 :             case UNSPEC:
   11405       701624 :               if (XINT (op, 1) == UNSPEC_TP
   11406       693281 :                   && TARGET_TLS_DIRECT_SEG_REFS
   11407       693281 :                   && seg == ADDR_SPACE_GENERIC)
   11408       693281 :                 seg = DEFAULT_TLS_SEG_REG;
   11409              :               else
   11410              :                 return false;
   11411              :               break;
   11412              : 
   11413       653019 :             case SUBREG:
   11414       653019 :               if (!REG_P (SUBREG_REG (op)))
   11415              :                 return false;
   11416              :               /* FALLTHRU */
   11417              : 
   11418   2482932713 :             case REG:
   11419   2482932713 :               if (!base)
   11420              :                 base = op;
   11421     77567433 :               else if (!index)
   11422              :                 index = op;
   11423              :               else
   11424              :                 return false;
   11425              :               break;
   11426              : 
   11427   2341728529 :             case CONST:
   11428   2341728529 :             case CONST_INT:
   11429   2341728529 :             case SYMBOL_REF:
   11430   2341728529 :             case LABEL_REF:
   11431   2341728529 :               if (disp)
   11432              :                 return false;
   11433              :               disp = op;
   11434              :               break;
   11435              : 
   11436              :             default:
   11437              :               return false;
   11438              :             }
   11439              :         }
   11440              :     }
   11441              :   else if (GET_CODE (addr) == MULT)
   11442              :     {
   11443      3927843 :       index = XEXP (addr, 0);           /* index*scale */
   11444      3927843 :       scale_rtx = XEXP (addr, 1);
   11445              :     }
   11446              :   else if (GET_CODE (addr) == ASHIFT)
   11447              :     {
   11448              :       /* We're called for lea too, which implements ashift on occasion.  */
   11449      3326203 :       index = XEXP (addr, 0);
   11450      3326203 :       tmp = XEXP (addr, 1);
   11451      3326203 :       if (!CONST_INT_P (tmp))
   11452              :         return false;
   11453      2930494 :       scale = INTVAL (tmp);
   11454      2930494 :       if ((unsigned HOST_WIDE_INT) scale > 3)
   11455              :         return false;
   11456      2158566 :       scale = 1 << scale;
   11457              :     }
   11458              :   else
   11459              :     disp = addr;                        /* displacement */
   11460              : 
   11461   2423069961 :   if (index)
   11462              :     {
   11463    146763179 :       if (REG_P (index))
   11464              :         ;
   11465      4259930 :       else if (SUBREG_P (index)
   11466       448628 :                && REG_P (SUBREG_REG (index)))
   11467              :         ;
   11468              :       else
   11469              :         return false;
   11470              :     }
   11471              : 
   11472              :   /* Extract the integral value of scale.  */
   11473   3644645405 :   if (scale_rtx)
   11474              :     {
   11475     55790133 :       if (!CONST_INT_P (scale_rtx))
   11476              :         return false;
   11477     55135434 :       scale = INTVAL (scale_rtx);
   11478              :     }
   11479              : 
   11480   3643990706 :   base_reg = base && SUBREG_P (base) ? SUBREG_REG (base) : base;
   11481   3643990706 :   index_reg = index && SUBREG_P (index) ? SUBREG_REG (index) : index;
   11482              : 
   11483              :   /* Avoid useless 0 displacement.  */
   11484   3643990706 :   if (disp == const0_rtx && (base || index))
   11485   3643990706 :     disp = NULL_RTX;
   11486              : 
   11487              :   /* Allow arg pointer and stack pointer as index if there is not scaling.  */
   11488   2636400931 :   if (base_reg && index_reg && scale == 1
   11489   3720028617 :       && (REGNO (index_reg) == ARG_POINTER_REGNUM
   11490              :           || REGNO (index_reg) == FRAME_POINTER_REGNUM
   11491              :           || REGNO (index_reg) == SP_REG))
   11492              :     {
   11493              :       std::swap (base, index);
   11494              :       std::swap (base_reg, index_reg);
   11495              :     }
   11496              : 
   11497              :   /* Special case: rewrite index*1+disp into base+disp.  */
   11498   3643990706 :   if (!base && index && scale == 1)
   11499            4 :     base = index, base_reg = index_reg, index = index_reg = NULL_RTX;
   11500              : 
   11501              :   /* Special case: %ebp cannot be encoded as a base without a displacement.
   11502              :      Similarly %r13.  */
   11503    313157762 :   if (!disp && base_reg
   11504   3952672433 :       && (REGNO (base_reg) == ARG_POINTER_REGNUM
   11505              :           || REGNO (base_reg) == FRAME_POINTER_REGNUM
   11506              :           || REGNO (base_reg) == BP_REG
   11507              :           || REGNO (base_reg) == R13_REG))
   11508              :     disp = const0_rtx;
   11509              : 
   11510              :   /* Special case: on K6, [%esi] makes the instruction vector decoded.
   11511              :      Avoid this by transforming to [%esi+0].
   11512              :      Reload calls address legitimization without cfun defined, so we need
   11513              :      to test cfun for being non-NULL. */
   11514            0 :   if (TARGET_CPU_P (K6) && cfun && optimize_function_for_speed_p (cfun)
   11515            0 :       && base_reg && !index_reg && !disp
   11516   3643990706 :       && REGNO (base_reg) == SI_REG)
   11517            0 :     disp = const0_rtx;
   11518              : 
   11519              :   /* Special case: encode reg+reg instead of reg*2.  */
   11520   3643990706 :   if (!base && index && scale == 2)
   11521   1007589771 :     base = index, base_reg = index_reg, scale = 1;
   11522              : 
   11523              :   /* Special case: scaling cannot be encoded without base or displacement.  */
   11524   1007589771 :   if (!base && !disp && index && scale != 1)
   11525      3567636 :     disp = const0_rtx;
   11526              : 
   11527   3643990706 :   out->base = base;
   11528   3643990706 :   out->index = index;
   11529   3643990706 :   out->disp = disp;
   11530   3643990706 :   out->scale = scale;
   11531   3643990706 :   out->seg = seg;
   11532              : 
   11533   3643990706 :   return true;
   11534              : }
   11535              : 
   11536              : /* Return cost of the memory address x.
   11537              :    For i386, it is better to use a complex address than let gcc copy
   11538              :    the address into a reg and make a new pseudo.  But not if the address
   11539              :    requires to two regs - that would mean more pseudos with longer
   11540              :    lifetimes.  */
   11541              : static int
   11542     10661678 : ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
   11543              : {
   11544     10661678 :   struct ix86_address parts;
   11545     10661678 :   int cost = 1;
   11546     10661678 :   int ok = ix86_decompose_address (x, &parts);
   11547              : 
   11548     10661678 :   gcc_assert (ok);
   11549              : 
   11550     10661678 :   if (parts.base && SUBREG_P (parts.base))
   11551          243 :     parts.base = SUBREG_REG (parts.base);
   11552     10661678 :   if (parts.index && SUBREG_P (parts.index))
   11553           52 :     parts.index = SUBREG_REG (parts.index);
   11554              : 
   11555              :   /* Attempt to minimize number of registers in the address by increasing
   11556              :      address cost for each used register.  We don't increase address cost
   11557              :      for "pic_offset_table_rtx".  When a memopt with "pic_offset_table_rtx"
   11558              :      is not invariant itself it most likely means that base or index is not
   11559              :      invariant.  Therefore only "pic_offset_table_rtx" could be hoisted out,
   11560              :      which is not profitable for x86.  */
   11561     10661678 :   if (parts.base
   11562      9243052 :       && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
   11563     19595494 :       && (current_pass->type == GIMPLE_PASS
   11564      2653461 :           || !pic_offset_table_rtx
   11565       126987 :           || !REG_P (parts.base)
   11566       126987 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.base)))
   11567              :     cost++;
   11568              : 
   11569     10661678 :   if (parts.index
   11570      5136232 :       && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
   11571     15786916 :       && (current_pass->type == GIMPLE_PASS
   11572       659937 :           || !pic_offset_table_rtx
   11573        55102 :           || !REG_P (parts.index)
   11574        55102 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
   11575      5123954 :     cost++;
   11576              : 
   11577              :   /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
   11578              :      since it's predecode logic can't detect the length of instructions
   11579              :      and it degenerates to vector decoded.  Increase cost of such
   11580              :      addresses here.  The penalty is minimally 2 cycles.  It may be worthwhile
   11581              :      to split such addresses or even refuse such addresses at all.
   11582              : 
   11583              :      Following addressing modes are affected:
   11584              :       [base+scale*index]
   11585              :       [scale*index+disp]
   11586              :       [base+index]
   11587              : 
   11588              :      The first and last case  may be avoidable by explicitly coding the zero in
   11589              :      memory address, but I don't have AMD-K6 machine handy to check this
   11590              :      theory.  */
   11591              : 
   11592     10661678 :   if (TARGET_CPU_P (K6)
   11593            0 :       && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
   11594            0 :           || (parts.disp && !parts.base && parts.index && parts.scale != 1)
   11595            0 :           || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
   11596            0 :     cost += 10;
   11597              : 
   11598     10661678 :   return cost;
   11599              : }
   11600              : 
   11601              : /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P.  */
   11602              : 
   11603              : bool
   11604      1199549 : ix86_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
   11605              :                                      unsigned int align,
   11606              :                                      enum by_pieces_operation op,
   11607              :                                      bool speed_p)
   11608              : {
   11609              :   /* Return true when we are currently expanding memcpy/memset epilogue
   11610              :      with move_by_pieces or store_by_pieces.  */
   11611      1199549 :   if (cfun->machine->by_pieces_in_use)
   11612              :     return true;
   11613              : 
   11614      1197464 :   return default_use_by_pieces_infrastructure_p (size, align, op,
   11615      1197464 :                                                  speed_p);
   11616              : }
   11617              : 
   11618              : /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
   11619              :    this is used for to form addresses to local data when -fPIC is in
   11620              :    use.  */
   11621              : 
   11622              : static bool
   11623            0 : darwin_local_data_pic (rtx disp)
   11624              : {
   11625            0 :   return (GET_CODE (disp) == UNSPEC
   11626            0 :           && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
   11627              : }
   11628              : 
   11629              : /* True if the function symbol operand X should be loaded from GOT.
   11630              :    If CALL_P is true, X is a call operand.
   11631              : 
   11632              :    NB: -mno-direct-extern-access doesn't force load from GOT for
   11633              :    call.
   11634              : 
   11635              :    NB: In 32-bit mode, only non-PIC is allowed in inline assembly
   11636              :    statements, since a PIC register could not be available at the
   11637              :    call site.  */
   11638              : 
   11639              : bool
   11640   1867791034 : ix86_force_load_from_GOT_p (rtx x, bool call_p)
   11641              : {
   11642     95856895 :   return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X))
   11643              :           && !TARGET_PECOFF && !TARGET_MACHO
   11644   1864929383 :           && (!flag_pic || this_is_asm_operands)
   11645   1844486501 :           && ix86_cmodel != CM_LARGE
   11646   1844480502 :           && ix86_cmodel != CM_LARGE_PIC
   11647   1844480501 :           && SYMBOL_REF_P (x)
   11648   1844480499 :           && ((!call_p
   11649   1838976418 :                && (!ix86_direct_extern_access
   11650   1838974148 :                    || (SYMBOL_REF_DECL (x)
   11651   1658096085 :                        && lookup_attribute ("nodirect_extern_access",
   11652   1658096085 :                                             DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))
   11653   1844477775 :               || (SYMBOL_REF_FUNCTION_P (x)
   11654    698951531 :                   && (!flag_plt
   11655    698947120 :                       || (SYMBOL_REF_DECL (x)
   11656    698947120 :                           && lookup_attribute ("noplt",
   11657    698947120 :                                                DECL_ATTRIBUTES (SYMBOL_REF_DECL (x)))))))
   11658   1867798568 :           && !SYMBOL_REF_LOCAL_P (x));
   11659              : }
   11660              : 
   11661              : /* Determine if a given RTX is a valid constant.  We already know this
   11662              :    satisfies CONSTANT_P.  */
   11663              : 
   11664              : static bool
   11665   1565773507 : ix86_legitimate_constant_p (machine_mode mode, rtx x)
   11666              : {
   11667   1565773507 :   switch (GET_CODE (x))
   11668              :     {
   11669    137039131 :     case CONST:
   11670    137039131 :       x = XEXP (x, 0);
   11671              : 
   11672    137039131 :       if (GET_CODE (x) == PLUS)
   11673              :         {
   11674    136921063 :           if (!CONST_INT_P (XEXP (x, 1)))
   11675              :             return false;
   11676    136921063 :           x = XEXP (x, 0);
   11677              :         }
   11678              : 
   11679    137039131 :       if (TARGET_MACHO && darwin_local_data_pic (x))
   11680              :         return true;
   11681              : 
   11682              :       /* Only some unspecs are valid as "constants".  */
   11683    137039131 :       if (GET_CODE (x) == UNSPEC)
   11684       501692 :         switch (XINT (x, 1))
   11685              :           {
   11686        21131 :           case UNSPEC_GOT:
   11687        21131 :           case UNSPEC_GOTOFF:
   11688        21131 :           case UNSPEC_PLTOFF:
   11689        21131 :             return TARGET_64BIT;
   11690       480198 :           case UNSPEC_TPOFF:
   11691       480198 :           case UNSPEC_NTPOFF:
   11692       480198 :             x = XVECEXP (x, 0, 0);
   11693       480198 :             return (SYMBOL_REF_P (x)
   11694       480198 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11695          275 :           case UNSPEC_DTPOFF:
   11696          275 :             x = XVECEXP (x, 0, 0);
   11697          275 :             return (SYMBOL_REF_P (x)
   11698          275 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
   11699            0 :           case UNSPEC_SECREL32:
   11700            0 :             x = XVECEXP (x, 0, 0);
   11701            0 :             return SYMBOL_REF_P (x);
   11702              :           default:
   11703              :             return false;
   11704              :           }
   11705              : 
   11706              :       /* We must have drilled down to a symbol.  */
   11707    136537439 :       if (LABEL_REF_P (x))
   11708              :         return true;
   11709    136531883 :       if (!SYMBOL_REF_P (x))
   11710              :         return false;
   11711              :       /* FALLTHRU */
   11712              : 
   11713    935482624 :     case SYMBOL_REF:
   11714              :       /* TLS symbols are never valid.  */
   11715    935482624 :       if (SYMBOL_REF_TLS_MODEL (x))
   11716              :         return false;
   11717              : 
   11718              :       /* DLLIMPORT symbols are never valid.  */
   11719    935377784 :       if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
   11720              :           && SYMBOL_REF_DLLIMPORT_P (x))
   11721              :         return false;
   11722              : 
   11723              : #if TARGET_MACHO
   11724              :       /* mdynamic-no-pic */
   11725              :       if (MACHO_DYNAMIC_NO_PIC_P)
   11726              :         return machopic_symbol_defined_p (x);
   11727              : #endif
   11728              : 
   11729              :       /* External function address should be loaded
   11730              :          via the GOT slot to avoid PLT.  */
   11731    935377784 :       if (ix86_force_load_from_GOT_p (x))
   11732              :         return false;
   11733              : 
   11734              :       break;
   11735              : 
   11736    608476026 :     CASE_CONST_SCALAR_INT:
   11737    608476026 :       if (ix86_endbr_immediate_operand (x, VOIDmode))
   11738              :         return false;
   11739              : 
   11740    608475825 :       switch (mode)
   11741              :         {
   11742      1479745 :         case E_TImode:
   11743      1479745 :           if (TARGET_64BIT)
   11744              :             return true;
   11745              :           /* FALLTHRU */
   11746        26049 :         case E_OImode:
   11747        26049 :         case E_XImode:
   11748        26049 :           if (!standard_sse_constant_p (x, mode)
   11749        43326 :               && GET_MODE_SIZE (TARGET_AVX512F
   11750              :                                 ? XImode
   11751              :                                 : (TARGET_AVX
   11752              :                                    ? OImode
   11753              :                                    : (TARGET_SSE2
   11754        17277 :                                       ? TImode : DImode))) < GET_MODE_SIZE (mode))
   11755              :             return false;
   11756              :         default:
   11757              :           break;
   11758              :         }
   11759              :       break;
   11760              : 
   11761      8926891 :     case CONST_VECTOR:
   11762      8926891 :       if (!standard_sse_constant_p (x, mode))
   11763              :         return false;
   11764              :       break;
   11765              : 
   11766      7689180 :     case CONST_DOUBLE:
   11767      7689180 :       if (mode == E_BFmode)
   11768              :         return false;
   11769              : 
   11770              :     default:
   11771              :       break;
   11772              :     }
   11773              : 
   11774              :   /* Otherwise we handle everything else in the move patterns.  */
   11775              :   return true;
   11776              : }
   11777              : 
   11778              : /* Determine if it's legal to put X into the constant pool.  This
   11779              :    is not possible for the address of thread-local symbols, which
   11780              :    is checked above.  */
   11781              : 
   11782              : static bool
   11783     62270956 : ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   11784              : {
   11785              :   /* We can put any immediate constant in memory.  */
   11786     62270956 :   switch (GET_CODE (x))
   11787              :     {
   11788              :     CASE_CONST_ANY:
   11789              :       return false;
   11790              : 
   11791      1812676 :     default:
   11792      1812676 :       break;
   11793              :     }
   11794              : 
   11795      1812676 :   return !ix86_legitimate_constant_p (mode, x);
   11796              : }
   11797              : 
   11798              : /* Return a unique alias set for the GOT.  */
   11799              : 
   11800              : alias_set_type
   11801       189424 : ix86_GOT_alias_set (void)
   11802              : {
   11803       189424 :   static alias_set_type set = -1;
   11804       189424 :   if (set == -1)
   11805         2957 :     set = new_alias_set ();
   11806       189424 :   return set;
   11807              : }
   11808              : 
   11809              : /* Nonzero if the constant value X is a legitimate general operand
   11810              :    when generating PIC code.  It is given that flag_pic is on and
   11811              :    that X satisfies CONSTANT_P.  */
   11812              : 
   11813              : bool
   11814    125876945 : legitimate_pic_operand_p (rtx x)
   11815              : {
   11816    125876945 :   rtx inner;
   11817              : 
   11818    125876945 :   switch (GET_CODE (x))
   11819              :     {
   11820      2505530 :     case CONST:
   11821      2505530 :       inner = XEXP (x, 0);
   11822      2505530 :       if (GET_CODE (inner) == PLUS
   11823       357946 :           && CONST_INT_P (XEXP (inner, 1)))
   11824       357946 :         inner = XEXP (inner, 0);
   11825              : 
   11826              :       /* Only some unspecs are valid as "constants".  */
   11827      2505530 :       if (GET_CODE (inner) == UNSPEC)
   11828      2255545 :         switch (XINT (inner, 1))
   11829              :           {
   11830      2194664 :           case UNSPEC_GOT:
   11831      2194664 :           case UNSPEC_GOTOFF:
   11832      2194664 :           case UNSPEC_PLTOFF:
   11833      2194664 :             return TARGET_64BIT;
   11834            0 :           case UNSPEC_TPOFF:
   11835            0 :             x = XVECEXP (inner, 0, 0);
   11836            0 :             return (SYMBOL_REF_P (x)
   11837            0 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11838            0 :           case UNSPEC_SECREL32:
   11839            0 :             x = XVECEXP (inner, 0, 0);
   11840            0 :             return SYMBOL_REF_P (x);
   11841            0 :           case UNSPEC_MACHOPIC_OFFSET:
   11842            0 :             return legitimate_pic_address_disp_p (x);
   11843              :           default:
   11844              :             return false;
   11845              :           }
   11846              :       /* FALLTHRU */
   11847              : 
   11848      7052339 :     case SYMBOL_REF:
   11849      7052339 :     case LABEL_REF:
   11850      7052339 :       return legitimate_pic_address_disp_p (x);
   11851              : 
   11852              :     default:
   11853              :       return true;
   11854              :     }
   11855              : }
   11856              : 
   11857              : /* Determine if a given CONST RTX is a valid memory displacement
   11858              :    in PIC mode.  */
   11859              : 
   11860              : bool
   11861     65025224 : legitimate_pic_address_disp_p (rtx disp)
   11862              : {
   11863     65025224 :   bool saw_plus;
   11864              : 
   11865              :   /* In 64bit mode we can allow direct addresses of symbols and labels
   11866              :      when they are not dynamic symbols.  */
   11867     65025224 :   if (TARGET_64BIT)
   11868              :     {
   11869     39831706 :       rtx op0 = disp, op1;
   11870              : 
   11871     39831706 :       switch (GET_CODE (disp))
   11872              :         {
   11873              :         case LABEL_REF:
   11874              :           return true;
   11875              : 
   11876     10955833 :         case CONST:
   11877     10955833 :           if (GET_CODE (XEXP (disp, 0)) != PLUS)
   11878              :             break;
   11879      1176685 :           op0 = XEXP (XEXP (disp, 0), 0);
   11880      1176685 :           op1 = XEXP (XEXP (disp, 0), 1);
   11881      1176685 :           if (!CONST_INT_P (op1))
   11882              :             break;
   11883      1176685 :           if (GET_CODE (op0) == UNSPEC
   11884          296 :               && (XINT (op0, 1) == UNSPEC_DTPOFF
   11885          296 :                   || XINT (op0, 1) == UNSPEC_NTPOFF)
   11886      1176981 :               && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
   11887              :             return true;
   11888      1176389 :           if (INTVAL (op1) >= 16*1024*1024
   11889      1176389 :               || INTVAL (op1) < -16*1024*1024)
   11890              :             break;
   11891      1176301 :           if (LABEL_REF_P (op0))
   11892              :             return true;
   11893      1176301 :           if (GET_CODE (op0) == CONST
   11894            0 :               && GET_CODE (XEXP (op0, 0)) == UNSPEC
   11895            0 :               && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
   11896              :             return true;
   11897      1176301 :           if (GET_CODE (op0) == UNSPEC
   11898            0 :               && XINT (op0, 1) == UNSPEC_PCREL)
   11899              :             return true;
   11900      1176301 :           if (!SYMBOL_REF_P (op0))
   11901              :             break;
   11902              :           /* FALLTHRU */
   11903              : 
   11904     29829932 :         case SYMBOL_REF:
   11905              :           /* TLS references should always be enclosed in UNSPEC.
   11906              :              The dllimported symbol needs always to be resolved.  */
   11907     29829932 :           if (SYMBOL_REF_TLS_MODEL (op0)
   11908              :               || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
   11909              :             return false;
   11910              : 
   11911     29673910 :           if (TARGET_PECOFF)
   11912              :             {
   11913              : #if TARGET_PECOFF
   11914              :               if (is_imported_p (op0))
   11915              :                 return true;
   11916              : #endif
   11917              : 
   11918              :               if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
   11919              :                 break;
   11920              : 
   11921              :               /* Non-external-weak function symbols need to be resolved only
   11922              :                  for the large model.  Non-external symbols don't need to be
   11923              :                  resolved for large and medium models.  For the small model,
   11924              :                  we don't need to resolve anything here.  */
   11925              :               if ((ix86_cmodel != CM_LARGE_PIC
   11926              :                    && SYMBOL_REF_FUNCTION_P (op0)
   11927              :                    && !(SYMBOL_REF_EXTERNAL_P (op0) && SYMBOL_REF_WEAK (op0)))
   11928              :                   || !SYMBOL_REF_EXTERNAL_P (op0)
   11929              :                   || ix86_cmodel == CM_SMALL_PIC)
   11930              :                 return true;
   11931              :             }
   11932     29673910 :           else if (!SYMBOL_REF_FAR_ADDR_P (op0)
   11933     29673906 :                    && (SYMBOL_REF_LOCAL_P (op0)
   11934     17958203 :                        || ((ix86_direct_extern_access
   11935     35744360 :                             && !(SYMBOL_REF_DECL (op0)
   11936     17786320 :                                  && lookup_attribute ("nodirect_extern_access",
   11937     17786320 :                                                       DECL_ATTRIBUTES (SYMBOL_REF_DECL (op0)))))
   11938              :                            && HAVE_LD_PIE_COPYRELOC
   11939     17957877 :                            && flag_pie
   11940        34868 :                            && !SYMBOL_REF_WEAK (op0)
   11941        34480 :                            && !SYMBOL_REF_FUNCTION_P (op0)))
   11942     41394166 :                    && ix86_cmodel != CM_LARGE_PIC)
   11943              :             return true;
   11944              :           break;
   11945              : 
   11946              :         default:
   11947              :           break;
   11948              :         }
   11949              :     }
   11950     52930288 :   if (GET_CODE (disp) != CONST)
   11951              :     return false;
   11952     14979355 :   disp = XEXP (disp, 0);
   11953              : 
   11954     14979355 :   if (TARGET_64BIT)
   11955              :     {
   11956              :       /* We are unsafe to allow PLUS expressions.  This limit allowed distance
   11957              :          of GOT tables.  We should not need these anyway.  */
   11958      9831668 :       if (GET_CODE (disp) != UNSPEC
   11959      9779148 :           || (XINT (disp, 1) != UNSPEC_GOTPCREL
   11960      9779148 :               && XINT (disp, 1) != UNSPEC_GOTOFF
   11961              :               && XINT (disp, 1) != UNSPEC_PCREL
   11962              :               && XINT (disp, 1) != UNSPEC_PLTOFF))
   11963              :         return false;
   11964              : 
   11965      9779148 :       if (!SYMBOL_REF_P (XVECEXP (disp, 0, 0))
   11966      9779148 :           && !LABEL_REF_P (XVECEXP (disp, 0, 0)))
   11967              :         return false;
   11968              :       return true;
   11969              :     }
   11970              : 
   11971      5147687 :   saw_plus = false;
   11972      5147687 :   if (GET_CODE (disp) == PLUS)
   11973              :     {
   11974       589622 :       if (!CONST_INT_P (XEXP (disp, 1)))
   11975              :         return false;
   11976       589622 :       disp = XEXP (disp, 0);
   11977       589622 :       saw_plus = true;
   11978              :     }
   11979              : 
   11980      5147687 :   if (TARGET_MACHO && darwin_local_data_pic (disp))
   11981              :     return true;
   11982              : 
   11983      5147687 :   if (GET_CODE (disp) != UNSPEC)
   11984              :     return false;
   11985              : 
   11986      4981983 :   switch (XINT (disp, 1))
   11987              :     {
   11988      2265168 :     case UNSPEC_GOT:
   11989      2265168 :       if (saw_plus)
   11990              :         return false;
   11991              :       /* We need to check for both symbols and labels because VxWorks loads
   11992              :          text labels with @GOT rather than @GOTOFF.  See gotoff_operand for
   11993              :          details.  */
   11994      2265167 :       return (SYMBOL_REF_P (XVECEXP (disp, 0, 0))
   11995      2265167 :               || LABEL_REF_P (XVECEXP (disp, 0, 0)));
   11996      2716815 :     case UNSPEC_GOTOFF:
   11997              :       /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
   11998              :          While ABI specify also 32bit relocation but we don't produce it in
   11999              :          small PIC model at all.  */
   12000      2716815 :       if ((SYMBOL_REF_P (XVECEXP (disp, 0, 0))
   12001      2716815 :            || LABEL_REF_P (XVECEXP (disp, 0, 0)))
   12002              :           && !TARGET_64BIT)
   12003      5433630 :         return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
   12004              :       return false;
   12005            0 :     case UNSPEC_GOTTPOFF:
   12006            0 :     case UNSPEC_GOTNTPOFF:
   12007            0 :     case UNSPEC_INDNTPOFF:
   12008            0 :       if (saw_plus)
   12009              :         return false;
   12010            0 :       disp = XVECEXP (disp, 0, 0);
   12011            0 :       return (SYMBOL_REF_P (disp)
   12012            0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
   12013            0 :     case UNSPEC_NTPOFF:
   12014            0 :       disp = XVECEXP (disp, 0, 0);
   12015            0 :       return (SYMBOL_REF_P (disp)
   12016            0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
   12017            0 :     case UNSPEC_DTPOFF:
   12018            0 :       disp = XVECEXP (disp, 0, 0);
   12019            0 :       return (SYMBOL_REF_P (disp)
   12020            0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
   12021            0 :     case UNSPEC_SECREL32:
   12022            0 :       disp = XVECEXP (disp, 0, 0);
   12023            0 :       return SYMBOL_REF_P (disp);
   12024              :     }
   12025              : 
   12026              :   return false;
   12027              : }
   12028              : 
   12029              : /* Determine if op is suitable RTX for an address register.
   12030              :    Return naked register if a register or a register subreg is
   12031              :    found, otherwise return NULL_RTX.  */
   12032              : 
   12033              : static rtx
   12034   1312818750 : ix86_validate_address_register (rtx op)
   12035              : {
   12036   1312818750 :   machine_mode mode = GET_MODE (op);
   12037              : 
   12038              :   /* Only SImode or DImode registers can form the address.  */
   12039   1312818750 :   if (mode != SImode && mode != DImode)
   12040              :     return NULL_RTX;
   12041              : 
   12042   1312811579 :   if (REG_P (op))
   12043              :     return op;
   12044       864253 :   else if (SUBREG_P (op))
   12045              :     {
   12046       864253 :       rtx reg = SUBREG_REG (op);
   12047              : 
   12048       864253 :       if (!REG_P (reg))
   12049              :         return NULL_RTX;
   12050              : 
   12051       864253 :       mode = GET_MODE (reg);
   12052              : 
   12053              :       /* Don't allow SUBREGs that span more than a word.  It can
   12054              :          lead to spill failures when the register is one word out
   12055              :          of a two word structure.  */
   12056      1773913 :       if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   12057              :         return NULL_RTX;
   12058              : 
   12059              :       /* Allow only SUBREGs of non-eliminable hard registers.  */
   12060       396832 :       if (register_no_elim_operand (reg, mode))
   12061              :         return reg;
   12062              :     }
   12063              : 
   12064              :   /* Op is not a register.  */
   12065              :   return NULL_RTX;
   12066              : }
   12067              : 
   12068              : /* Determine which memory address register set insn can use.  */
   12069              : 
   12070              : static enum attr_addr
   12071    255851228 : ix86_memory_address_reg_class (rtx_insn* insn)
   12072              : {
   12073              :   /* LRA can do some initialization with NULL insn,
   12074              :      return maximum register class in this case.  */
   12075    255851228 :   enum attr_addr addr_rclass = ADDR_GPR32;
   12076              : 
   12077    255851228 :   if (!insn)
   12078              :     return addr_rclass;
   12079              : 
   12080     73215603 :   if (asm_noperands (PATTERN (insn)) >= 0
   12081     73215603 :       || GET_CODE (PATTERN (insn)) == ASM_INPUT)
   12082        87652 :     return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
   12083              : 
   12084              :   /* Return maximum register class for unrecognized instructions.  */
   12085     73171777 :   if (INSN_CODE (insn) < 0)
   12086              :     return addr_rclass;
   12087              : 
   12088              :   /* Try to recognize the insn before calling get_attr_addr.
   12089              :      Save current recog_data and current alternative.  */
   12090     73171777 :   struct recog_data_d saved_recog_data = recog_data;
   12091     73171777 :   int saved_alternative = which_alternative;
   12092              : 
   12093              :   /* Update recog_data for processing of alternatives.  */
   12094     73171777 :   extract_insn_cached (insn);
   12095              : 
   12096              :   /* If current alternative is not set, loop through enabled
   12097              :      alternatives and get the most limited register class.  */
   12098     73171777 :   if (saved_alternative == -1)
   12099              :     {
   12100     73171777 :       alternative_mask enabled = get_enabled_alternatives (insn);
   12101              : 
   12102   1266198772 :       for (int i = 0; i < recog_data.n_alternatives; i++)
   12103              :         {
   12104   1193026995 :           if (!TEST_BIT (enabled, i))
   12105    354664342 :             continue;
   12106              : 
   12107    838362653 :           which_alternative = i;
   12108    838362653 :           addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
   12109              :         }
   12110              :     }
   12111              :   else
   12112              :     {
   12113            0 :       which_alternative = saved_alternative;
   12114            0 :       addr_rclass = get_attr_addr (insn);
   12115              :     }
   12116              : 
   12117     73171777 :   recog_data = saved_recog_data;
   12118     73171777 :   which_alternative = saved_alternative;
   12119              : 
   12120     73171777 :   return addr_rclass;
   12121              : }
   12122              : 
   12123              : /* Return memory address register class insn can use.  */
   12124              : 
   12125              : enum reg_class
   12126    214955284 : ix86_insn_base_reg_class (rtx_insn* insn)
   12127              : {
   12128    214955284 :   switch (ix86_memory_address_reg_class (insn))
   12129              :     {
   12130              :     case ADDR_GPR8:
   12131              :       return LEGACY_GENERAL_REGS;
   12132              :     case ADDR_GPR16:
   12133              :       return GENERAL_GPR16;
   12134              :     case ADDR_GPR32:
   12135              :       break;
   12136            0 :     default:
   12137            0 :       gcc_unreachable ();
   12138              :     }
   12139              : 
   12140              :   return BASE_REG_CLASS;
   12141              : }
   12142              : 
   12143              : bool
   12144      1186011 : ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
   12145              : {
   12146      1186011 :   switch (ix86_memory_address_reg_class (insn))
   12147              :     {
   12148            0 :     case ADDR_GPR8:
   12149            0 :       return LEGACY_INT_REGNO_P (regno);
   12150            0 :     case ADDR_GPR16:
   12151            0 :       return GENERAL_GPR16_REGNO_P (regno);
   12152      1186011 :     case ADDR_GPR32:
   12153      1186011 :       break;
   12154            0 :     default:
   12155            0 :       gcc_unreachable ();
   12156              :     }
   12157              : 
   12158      1186011 :   return GENERAL_REGNO_P (regno);
   12159              : }
   12160              : 
   12161              : enum reg_class
   12162     39709933 : ix86_insn_index_reg_class (rtx_insn* insn)
   12163              : {
   12164     39709933 :   switch (ix86_memory_address_reg_class (insn))
   12165              :     {
   12166              :     case ADDR_GPR8:
   12167              :       return LEGACY_INDEX_REGS;
   12168              :     case ADDR_GPR16:
   12169              :       return INDEX_GPR16;
   12170              :     case ADDR_GPR32:
   12171              :       break;
   12172            0 :     default:
   12173            0 :       gcc_unreachable ();
   12174              :     }
   12175              : 
   12176              :   return INDEX_REG_CLASS;
   12177              : }
   12178              : 
   12179              : /* Recognizes RTL expressions that are valid memory addresses for an
   12180              :    instruction.  The MODE argument is the machine mode for the MEM
   12181              :    expression that wants to use this address.
   12182              : 
   12183              :    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
   12184              :    convert common non-canonical forms to canonical form so that they will
   12185              :    be recognized.  */
   12186              : 
   12187              : static bool
   12188   2198992018 : ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
   12189              :                            code_helper = ERROR_MARK)
   12190              : {
   12191   2198992018 :   struct ix86_address parts;
   12192   2198992018 :   rtx base, index, disp;
   12193   2198992018 :   HOST_WIDE_INT scale;
   12194   2198992018 :   addr_space_t seg;
   12195              : 
   12196   2198992018 :   if (ix86_decompose_address (addr, &parts) == 0)
   12197              :     /* Decomposition failed.  */
   12198              :     return false;
   12199              : 
   12200   2187319342 :   base = parts.base;
   12201   2187319342 :   index = parts.index;
   12202   2187319342 :   disp = parts.disp;
   12203   2187319342 :   scale = parts.scale;
   12204   2187319342 :   seg = parts.seg;
   12205              : 
   12206              :   /* Validate base register.  */
   12207   2187319342 :   if (base)
   12208              :     {
   12209   1229396739 :       rtx reg = ix86_validate_address_register (base);
   12210              : 
   12211   1229396739 :       if (reg == NULL_RTX)
   12212              :         return false;
   12213              : 
   12214   1228960797 :       unsigned int regno = REGNO (reg);
   12215   1228960797 :       if ((strict && !REGNO_OK_FOR_BASE_P (regno))
   12216   1224520378 :           || (!strict && !REGNO_OK_FOR_BASE_NONSTRICT_P (regno)))
   12217              :         /* Base is not valid.  */
   12218              :         return false;
   12219              :     }
   12220              : 
   12221              :   /* Validate index register.  */
   12222   2185545204 :   if (index)
   12223              :     {
   12224     83422011 :       rtx reg = ix86_validate_address_register (index);
   12225              : 
   12226     83422011 :       if (reg == NULL_RTX)
   12227              :         return false;
   12228              : 
   12229     83383191 :       unsigned int regno = REGNO (reg);
   12230     83383191 :       if ((strict && !REGNO_OK_FOR_INDEX_P (regno))
   12231     83374565 :           || (!strict && !REGNO_OK_FOR_INDEX_NONSTRICT_P (regno)))
   12232              :         /* Index is not valid.  */
   12233              :         return false;
   12234              :     }
   12235              : 
   12236              :   /* Index and base should have the same mode.  */
   12237   2185504200 :   if (base && index
   12238     73770411 :       && GET_MODE (base) != GET_MODE (index))
   12239              :     return false;
   12240              : 
   12241              :   /* Address override works only on the (%reg) part of %fs:(%reg).  */
   12242   2185307558 :   if (seg != ADDR_SPACE_GENERIC
   12243   2185307558 :       && ((base && GET_MODE (base) != word_mode)
   12244       341309 :           || (index && GET_MODE (index) != word_mode)))
   12245              :     return false;
   12246              : 
   12247              :   /* Validate scale factor.  */
   12248   2185307529 :   if (scale != 1)
   12249              :     {
   12250     39582424 :       if (!index)
   12251              :         /* Scale without index.  */
   12252              :         return false;
   12253              : 
   12254     39582424 :       if (scale != 2 && scale != 4 && scale != 8)
   12255              :         /* Scale is not a valid multiplier.  */
   12256              :         return false;
   12257              :     }
   12258              : 
   12259              :   /* Validate displacement.  */
   12260   2182177002 :   if (disp)
   12261              :     {
   12262   1965485352 :       if (ix86_endbr_immediate_operand (disp, VOIDmode))
   12263              :         return false;
   12264              : 
   12265   1965485309 :       if (GET_CODE (disp) == CONST
   12266    147554573 :           && GET_CODE (XEXP (disp, 0)) == UNSPEC
   12267     15416760 :           && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
   12268     15416760 :         switch (XINT (XEXP (disp, 0), 1))
   12269              :           {
   12270              :           /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
   12271              :              when used.  While ABI specify also 32bit relocations, we
   12272              :              don't produce them at all and use IP relative instead.
   12273              :              Allow GOT in 32bit mode for both PIC and non-PIC if symbol
   12274              :              should be loaded via GOT.  */
   12275      2265226 :           case UNSPEC_GOT:
   12276      2265226 :             if (!TARGET_64BIT
   12277      2265226 :                 && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   12278            0 :               goto is_legitimate_pic;
   12279              :             /* FALLTHRU */
   12280      4558268 :           case UNSPEC_GOTOFF:
   12281      4558268 :             gcc_assert (flag_pic);
   12282      4558268 :             if (!TARGET_64BIT)
   12283      4558065 :               goto is_legitimate_pic;
   12284              : 
   12285              :             /* 64bit address unspec.  */
   12286              :             return false;
   12287              : 
   12288      9779120 :           case UNSPEC_GOTPCREL:
   12289      9779120 :             if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   12290         2534 :               goto is_legitimate_pic;
   12291              :             /* FALLTHRU */
   12292      9776586 :           case UNSPEC_PCREL:
   12293      9776586 :             gcc_assert (flag_pic);
   12294      9776586 :             goto is_legitimate_pic;
   12295              : 
   12296              :           case UNSPEC_GOTTPOFF:
   12297              :           case UNSPEC_GOTNTPOFF:
   12298              :           case UNSPEC_INDNTPOFF:
   12299              :           case UNSPEC_NTPOFF:
   12300              :           case UNSPEC_DTPOFF:
   12301              :           case UNSPEC_SECREL32:
   12302              :             break;
   12303              : 
   12304              :           default:
   12305              :             /* Invalid address unspec.  */
   12306              :             return false;
   12307              :           }
   12308              : 
   12309   1216922416 :       else if (SYMBOLIC_CONST (disp)
   12310   2082206362 :                && (flag_pic
   12311              : #if TARGET_MACHO
   12312              :                    || (MACHOPIC_INDIRECT
   12313              :                        && !machopic_operand_p (disp))
   12314              : #endif
   12315              :                   ))
   12316              :         {
   12317              : 
   12318     57812274 :         is_legitimate_pic:
   12319     57812274 :           if (TARGET_64BIT && (index || base))
   12320              :             {
   12321              :               /* foo@dtpoff(%rX) is ok.  */
   12322        37045 :               if (GET_CODE (disp) != CONST
   12323         7003 :                   || GET_CODE (XEXP (disp, 0)) != PLUS
   12324         7003 :                   || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
   12325         4637 :                   || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
   12326         4637 :                   || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
   12327         4637 :                       && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF
   12328            6 :                       && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_SECREL32))
   12329              :                 /* Non-constant pic memory reference.  */
   12330              :                 return false;
   12331              :             }
   12332     57775229 :           else if ((!TARGET_MACHO || flag_pic)
   12333     57775229 :                     && ! legitimate_pic_address_disp_p (disp))
   12334              :             /* Displacement is an invalid pic construct.  */
   12335              :             return false;
   12336              : #if TARGET_MACHO
   12337              :           else if (MACHO_DYNAMIC_NO_PIC_P
   12338              :                    && !ix86_legitimate_constant_p (Pmode, disp))
   12339              :             /* displacement must be referenced via non_lazy_pointer */
   12340              :             return false;
   12341              : #endif
   12342              : 
   12343              :           /* This code used to verify that a symbolic pic displacement
   12344              :              includes the pic_offset_table_rtx register.
   12345              : 
   12346              :              While this is good idea, unfortunately these constructs may
   12347              :              be created by "adds using lea" optimization for incorrect
   12348              :              code like:
   12349              : 
   12350              :              int a;
   12351              :              int foo(int i)
   12352              :                {
   12353              :                  return *(&a+i);
   12354              :                }
   12355              : 
   12356              :              This code is nonsensical, but results in addressing
   12357              :              GOT table with pic_offset_table_rtx base.  We can't
   12358              :              just refuse it easily, since it gets matched by
   12359              :              "addsi3" pattern, that later gets split to lea in the
   12360              :              case output register differs from input.  While this
   12361              :              can be handled by separate addsi pattern for this case
   12362              :              that never results in lea, this seems to be easier and
   12363              :              correct fix for crash to disable this test.  */
   12364              :         }
   12365   1906593460 :       else if (!LABEL_REF_P (disp)
   12366   1906434649 :                && !CONST_INT_P (disp)
   12367    879320721 :                && (GET_CODE (disp) != CONST
   12368    133578159 :                    || !ix86_legitimate_constant_p (Pmode, disp))
   12369   2655303960 :                && (!SYMBOL_REF_P (disp)
   12370    756178319 :                    || !ix86_legitimate_constant_p (Pmode, disp)))
   12371              :         /* Displacement is not constant.  */
   12372     57749788 :         return false;
   12373   1848843672 :       else if (TARGET_64BIT
   12374   1848843672 :                && !x86_64_immediate_operand (disp, VOIDmode))
   12375              :         /* Displacement is out of range.  */
   12376              :         return false;
   12377              :       /* In x32 mode, constant addresses are sign extended to 64bit, so
   12378              :          we have to prevent addresses from 0x80000000 to 0xffffffff.  */
   12379        45961 :       else if (TARGET_X32 && !(index || base)
   12380        17399 :                && CONST_INT_P (disp)
   12381   1848328050 :                && val_signbit_known_set_p (SImode, INTVAL (disp)))
   12382              :         return false;
   12383              :     }
   12384              : 
   12385              :   /* Everything looks valid.  */
   12386              :   return true;
   12387              : }
   12388              : 
   12389              : /* Determine if a given RTX is a valid constant address.  */
   12390              : 
   12391              : bool
   12392   2807421028 : constant_address_p (rtx x)
   12393              : {
   12394   2887829532 :   return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
   12395              : }
   12396              : 
   12397              : 
   12398              : /* Return a legitimate reference for ORIG (an address) using the
   12399              :    register REG.  If REG is 0, a new pseudo is generated.
   12400              : 
   12401              :    There are two types of references that must be handled:
   12402              : 
   12403              :    1. Global data references must load the address from the GOT, via
   12404              :       the PIC reg.  An insn is emitted to do this load, and the reg is
   12405              :       returned.
   12406              : 
   12407              :    2. Static data references, constant pool addresses, and code labels
   12408              :       compute the address as an offset from the GOT, whose base is in
   12409              :       the PIC reg.  Static data objects have SYMBOL_FLAG_LOCAL set to
   12410              :       differentiate them from global data objects.  The returned
   12411              :       address is the PIC reg + an unspec constant.
   12412              : 
   12413              :    TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
   12414              :    reg also appears in the address.  */
   12415              : 
   12416              : rtx
   12417       397610 : legitimize_pic_address (rtx orig, rtx reg)
   12418              : {
   12419       397610 :   rtx addr = orig;
   12420       397610 :   rtx new_rtx = orig;
   12421              : 
   12422              : #if TARGET_MACHO
   12423              :   if (TARGET_MACHO && !TARGET_64BIT)
   12424              :     {
   12425              :       if (reg == 0)
   12426              :         reg = gen_reg_rtx (Pmode);
   12427              :       /* Use the generic Mach-O PIC machinery.  */
   12428              :       return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
   12429              :     }
   12430              : #endif
   12431              : 
   12432       397610 :   if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   12433              :     {
   12434              : #if TARGET_PECOFF
   12435              :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   12436              :       if (tmp)
   12437              :         return tmp;
   12438              : #endif
   12439              :     }
   12440              : 
   12441       397610 :   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
   12442              :     new_rtx = addr;
   12443       302405 :   else if ((!TARGET_64BIT
   12444       102451 :             || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
   12445              :            && !TARGET_PECOFF
   12446       502456 :            && gotoff_operand (addr, Pmode))
   12447              :     {
   12448              :       /* This symbol may be referenced via a displacement
   12449              :          from the PIC base address (@GOTOFF).  */
   12450        96585 :       if (GET_CODE (addr) == CONST)
   12451         3048 :         addr = XEXP (addr, 0);
   12452              : 
   12453        96585 :       if (GET_CODE (addr) == PLUS)
   12454              :           {
   12455         6096 :             new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
   12456              :                                       UNSPEC_GOTOFF);
   12457         6096 :             new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
   12458              :           }
   12459              :         else
   12460       187045 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
   12461              : 
   12462       193141 :       new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12463              : 
   12464        96585 :       if (TARGET_64BIT)
   12465           29 :         new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   12466              : 
   12467        96585 :       if (reg != 0)
   12468              :         {
   12469            3 :           gcc_assert (REG_P (reg));
   12470            3 :           new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   12471              :                                          new_rtx, reg, 1, OPTAB_DIRECT);
   12472              :         }
   12473              :       else
   12474       193138 :         new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12475              :     }
   12476       384365 :   else if ((SYMBOL_REF_P (addr) && SYMBOL_REF_TLS_MODEL (addr) == 0)
   12477              :            /* We can't always use @GOTOFF for text labels
   12478              :               on VxWorks, see gotoff_operand.  */
   12479       205820 :            || (TARGET_VXWORKS_VAROFF && LABEL_REF_P (addr)))
   12480              :     {
   12481              : #if TARGET_PECOFF
   12482              :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   12483              :       if (tmp)
   12484              :         return tmp;
   12485              : #endif
   12486              : 
   12487              :       /* For x64 PE-COFF there is no GOT table,
   12488              :          so we use address directly.  */
   12489       178542 :       if (TARGET_64BIT && TARGET_PECOFF)
   12490              :         {
   12491              :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
   12492              :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12493              :         }
   12494       178542 :       else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
   12495              :         {
   12496        95171 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
   12497              :                                     UNSPEC_GOTPCREL);
   12498        95171 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12499        95171 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   12500        95168 :           set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
   12501              :         }
   12502              :       else
   12503              :         {
   12504              :           /* This symbol must be referenced via a load
   12505              :              from the Global Offset Table (@GOT).  */
   12506       166725 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
   12507       166725 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12508              : 
   12509        83374 :           if (TARGET_64BIT)
   12510           23 :             new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   12511              : 
   12512        83374 :           if (reg != 0)
   12513              :             {
   12514            0 :               gcc_assert (REG_P (reg));
   12515            0 :               new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   12516              :                                              new_rtx, reg, 1, OPTAB_DIRECT);
   12517              :             }
   12518              :           else
   12519       166725 :             new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12520              : 
   12521       166725 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   12522        83374 :           set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
   12523              :         }
   12524              : 
   12525       261896 :       new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   12526              :     }
   12527              :   else
   12528              :     {
   12529        27278 :       if (CONST_INT_P (addr)
   12530        27278 :           && !x86_64_immediate_operand (addr, VOIDmode))
   12531            8 :         new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
   12532        27270 :       else if (GET_CODE (addr) == CONST)
   12533              :         {
   12534        16755 :           addr = XEXP (addr, 0);
   12535              : 
   12536              :           /* We must match stuff we generate before.  Assume the only
   12537              :              unspecs that can get here are ours.  Not that we could do
   12538              :              anything with them anyway....  */
   12539        16755 :           if (GET_CODE (addr) == UNSPEC
   12540         8978 :               || (GET_CODE (addr) == PLUS
   12541         8978 :                   && GET_CODE (XEXP (addr, 0)) == UNSPEC))
   12542              :             return orig;
   12543         6850 :           gcc_assert (GET_CODE (addr) == PLUS);
   12544              :         }
   12545              : 
   12546        17373 :       if (GET_CODE (addr) == PLUS)
   12547              :         {
   12548         8687 :           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
   12549              : 
   12550              :           /* Check first to see if this is a constant
   12551              :              offset from a @GOTOFF symbol reference.  */
   12552         8687 :           if (!TARGET_PECOFF
   12553        13758 :               && gotoff_operand (op0, Pmode)
   12554         8687 :               && CONST_INT_P (op1))
   12555              :             {
   12556            4 :               if (!TARGET_64BIT)
   12557              :                 {
   12558            0 :                   new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
   12559              :                                             UNSPEC_GOTOFF);
   12560            0 :                   new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
   12561            0 :                   new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12562              : 
   12563            0 :                   if (reg != 0)
   12564              :                     {
   12565            0 :                       gcc_assert (REG_P (reg));
   12566            0 :                       new_rtx = expand_simple_binop (Pmode, PLUS,
   12567              :                                                      pic_offset_table_rtx,
   12568              :                                                      new_rtx, reg, 1,
   12569              :                                                      OPTAB_DIRECT);
   12570              :                     }
   12571              :                   else
   12572            0 :                     new_rtx
   12573            0 :                       = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12574              :                 }
   12575              :               else
   12576              :                 {
   12577            4 :                   if (INTVAL (op1) < -16*1024*1024
   12578            4 :                       || INTVAL (op1) >= 16*1024*1024)
   12579              :                     {
   12580            4 :                       if (!x86_64_immediate_operand (op1, Pmode))
   12581            4 :                         op1 = force_reg (Pmode, op1);
   12582              : 
   12583            4 :                       new_rtx
   12584            4 :                         = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
   12585              :                     }
   12586              :                 }
   12587              :             }
   12588              :           else
   12589              :             {
   12590         8683 :               rtx base = legitimize_pic_address (op0, reg);
   12591         8683 :               machine_mode mode = GET_MODE (base);
   12592         8683 :               new_rtx
   12593         8683 :                 = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
   12594              : 
   12595         8683 :               if (CONST_INT_P (new_rtx))
   12596              :                 {
   12597         6838 :                   if (INTVAL (new_rtx) < -16*1024*1024
   12598         6838 :                       || INTVAL (new_rtx) >= 16*1024*1024)
   12599              :                     {
   12600            0 :                       if (!x86_64_immediate_operand (new_rtx, mode))
   12601            0 :                         new_rtx = force_reg (mode, new_rtx);
   12602              : 
   12603            0 :                       new_rtx
   12604            0 :                         = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
   12605              :                     }
   12606              :                   else
   12607         6838 :                     new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
   12608              :                 }
   12609              :               else
   12610              :                 {
   12611              :                   /* For %rip addressing, we have to use
   12612              :                      just disp32, not base nor index.  */
   12613         1845 :                   if (TARGET_64BIT
   12614          101 :                       && (SYMBOL_REF_P (base)
   12615          101 :                           || LABEL_REF_P (base)))
   12616            7 :                     base = force_reg (mode, base);
   12617         1845 :                   if (GET_CODE (new_rtx) == PLUS
   12618         1723 :                       && CONSTANT_P (XEXP (new_rtx, 1)))
   12619              :                     {
   12620         1719 :                       base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
   12621         1719 :                       new_rtx = XEXP (new_rtx, 1);
   12622              :                     }
   12623         1845 :                   new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
   12624              :                 }
   12625              :             }
   12626              :         }
   12627              :     }
   12628              :   return new_rtx;
   12629              : }
   12630              : 
   12631              : /* Load the thread pointer.  If TO_REG is true, force it into a register.  */
   12632              : 
   12633              : static rtx
   12634        24588 : get_thread_pointer (machine_mode tp_mode, bool to_reg)
   12635              : {
   12636        24588 :   rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
   12637              : 
   12638        24588 :   if (GET_MODE (tp) != tp_mode)
   12639              :     {
   12640           11 :       gcc_assert (GET_MODE (tp) == SImode);
   12641           11 :       gcc_assert (tp_mode == DImode);
   12642              : 
   12643           11 :       tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
   12644              :     }
   12645              : 
   12646        24588 :   if (to_reg)
   12647         8163 :     tp = copy_to_mode_reg (tp_mode, tp);
   12648              : 
   12649        24588 :   return tp;
   12650              : }
   12651              : 
   12652              : /* Construct the SYMBOL_REF for the _tls_index symbol.  */
   12653              : 
   12654              : static GTY(()) rtx ix86_tls_index_symbol;
   12655              : 
   12656              : static rtx
   12657            0 : ix86_tls_index (void)
   12658              : {
   12659            0 :   if (!ix86_tls_index_symbol)
   12660            0 :     ix86_tls_index_symbol = gen_rtx_SYMBOL_REF (SImode, "_tls_index");
   12661              : 
   12662            0 :   if (flag_pic)
   12663            0 :     return gen_rtx_CONST (Pmode,
   12664              :                           gen_rtx_UNSPEC (Pmode,
   12665              :                                           gen_rtvec (1, ix86_tls_index_symbol),
   12666              :                                           UNSPEC_PCREL));
   12667              :   else
   12668            0 :     return ix86_tls_index_symbol;
   12669              : }
   12670              : 
   12671              : /* Construct the SYMBOL_REF for the tls_get_addr function.  */
   12672              : 
   12673              : static GTY(()) rtx ix86_tls_symbol;
   12674              : 
   12675              : rtx
   12676         6726 : ix86_tls_get_addr (void)
   12677              : {
   12678         6726 :   if (cfun->machine->call_saved_registers
   12679         6726 :       == TYPE_NO_CALLER_SAVED_REGISTERS)
   12680              :     {
   12681              :       /* __tls_get_addr doesn't preserve vector registers.  When a
   12682              :          function with no_caller_saved_registers attribute calls
   12683              :          __tls_get_addr, YMM and ZMM registers will be clobbered.
   12684              :          Issue an error and suggest -mtls-dialect=gnu2 in this case.  */
   12685            3 :       if (cfun->machine->func_type == TYPE_NORMAL)
   12686            1 :         error (G_("%<-mtls-dialect=gnu2%> must be used with a function"
   12687              :                   " with the %<no_caller_saved_registers%> attribute"));
   12688              :       else
   12689            3 :         error (cfun->machine->func_type == TYPE_EXCEPTION
   12690              :                ? G_("%<-mtls-dialect=gnu2%> must be used with an"
   12691              :                     " exception service routine")
   12692              :                : G_("%<-mtls-dialect=gnu2%> must be used with an"
   12693              :                     " interrupt service routine"));
   12694              :       /* Don't issue the same error twice.  */
   12695            3 :       cfun->machine->func_type = TYPE_NORMAL;
   12696            3 :       cfun->machine->call_saved_registers
   12697            3 :         = TYPE_DEFAULT_CALL_SAVED_REGISTERS;
   12698              :     }
   12699              : 
   12700         6726 :   if (!ix86_tls_symbol)
   12701              :     {
   12702          216 :       const char *sym
   12703          253 :         = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
   12704          253 :            ? "___tls_get_addr" : "__tls_get_addr");
   12705              : 
   12706          290 :       ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
   12707              :     }
   12708              : 
   12709         6726 :   if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
   12710              :     {
   12711            2 :       rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
   12712              :                                    UNSPEC_PLTOFF);
   12713            2 :       return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
   12714              :                            gen_rtx_CONST (Pmode, unspec));
   12715              :     }
   12716              : 
   12717         6724 :   return ix86_tls_symbol;
   12718              : }
   12719              : 
   12720              : /* Return the descriptor of the function ABI type for the tls_get_addr
   12721              :    function.  */
   12722              : 
   12723              : const predefined_function_abi &
   12724         5012 : ix86_tls_get_addr_abi (void)
   12725              : {
   12726         5012 :   if (ix86_abi == SYSV_ABI)
   12727         5000 :     return default_function_abi;
   12728              :   else
   12729           12 :     return ix86_alternate_abi ();
   12730              : }
   12731              : 
   12732              : /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
   12733              : 
   12734              : static GTY(()) rtx ix86_tls_module_base_symbol;
   12735              : 
   12736              : rtx
   12737           98 : ix86_tls_module_base (void)
   12738              : {
   12739           98 :   if (!ix86_tls_module_base_symbol)
   12740              :     {
   12741           11 :       ix86_tls_module_base_symbol
   12742           11 :         = gen_rtx_SYMBOL_REF (ptr_mode, "_TLS_MODULE_BASE_");
   12743              : 
   12744           11 :       SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
   12745           11 :         |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
   12746              :     }
   12747              : 
   12748           98 :   return ix86_tls_module_base_symbol;
   12749              : }
   12750              : 
   12751              : /* A subroutine of ix86_legitimize_address and ix86_expand_move.  FOR_MOV is
   12752              :    false if we expect this to be used for a memory address and true if
   12753              :    we expect to load the address into a register.  */
   12754              : 
   12755              : rtx
   12756        31015 : legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
   12757              : {
   12758        31015 :   rtx dest, base, off;
   12759        31015 :   rtx pic = NULL_RTX, tp = NULL_RTX;
   12760        31015 :   machine_mode tp_mode = Pmode;
   12761        31015 :   int type;
   12762              : 
   12763              :   /* Windows implements a single form of TLS.  */
   12764        31015 :   if (TARGET_WIN32_TLS)
   12765              :     {
   12766              :       /* Load the 32-bit index.  */
   12767              :       rtx ind = gen_const_mem (SImode, ix86_tls_index ());
   12768              :       set_mem_alias_set (ind, GOT_ALIAS_SET);
   12769              :       if (TARGET_64BIT)
   12770              :         ind = convert_to_mode (Pmode, ind, 1);
   12771              :       ind = force_reg (Pmode, ind);
   12772              : 
   12773              :       /* Add it to the thread pointer and load the base.  */
   12774              :       tp = get_thread_pointer (Pmode, true);
   12775              :       rtx addr = gen_rtx_PLUS (Pmode, tp,
   12776              :                                gen_rtx_MULT (Pmode, ind,
   12777              :                                              GEN_INT (UNITS_PER_WORD)));
   12778              :       base = gen_const_mem (Pmode, addr);
   12779              :       set_mem_alias_set (base, GOT_ALIAS_SET);
   12780              : 
   12781              :       /* Add the 32-bit section-relative offset to the base.  */
   12782              :       base = force_reg (Pmode, base);
   12783              :       off = gen_rtx_CONST (Pmode,
   12784              :                            gen_rtx_UNSPEC (SImode,
   12785              :                                            gen_rtvec (1, x),
   12786              :                                            UNSPEC_SECREL32));
   12787              :       return gen_rtx_PLUS (Pmode, base, off);
   12788              :     }
   12789              : 
   12790              :   /* Fall back to global dynamic model if tool chain cannot support local
   12791              :      dynamic.  */
   12792        31015 :   if (TARGET_SUN_TLS && !TARGET_64BIT
   12793              :       && !HAVE_AS_IX86_TLSLDMPLT && !HAVE_AS_IX86_TLSLDM
   12794              :       && model == TLS_MODEL_LOCAL_DYNAMIC)
   12795              :     model = TLS_MODEL_GLOBAL_DYNAMIC;
   12796              : 
   12797        31015 :   switch (model)
   12798              :     {
   12799         6112 :     case TLS_MODEL_GLOBAL_DYNAMIC:
   12800         6112 :       if (!TARGET_64BIT)
   12801              :         {
   12802         1922 :           if (flag_pic && !TARGET_PECOFF)
   12803         1922 :             pic = pic_offset_table_rtx;
   12804              :           else
   12805              :             {
   12806            0 :               pic = gen_reg_rtx (Pmode);
   12807            0 :               emit_insn (gen_set_got (pic));
   12808              :             }
   12809              :         }
   12810              : 
   12811         6112 :       if (TARGET_GNU2_TLS)
   12812              :         {
   12813           53 :           dest = gen_reg_rtx (ptr_mode);
   12814           53 :           if (TARGET_64BIT)
   12815           53 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, dest, x));
   12816              :           else
   12817            0 :             emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
   12818              : 
   12819           53 :           tp = get_thread_pointer (ptr_mode, true);
   12820           53 :           dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12821           61 :           if (GET_MODE (dest) != Pmode)
   12822            6 :              dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12823           61 :           dest = force_reg (Pmode, dest);
   12824              : 
   12825           61 :           if (GET_MODE (x) != Pmode)
   12826            3 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12827              : 
   12828           53 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12829              :         }
   12830              :       else
   12831              :         {
   12832         6059 :           rtx caddr = ix86_tls_get_addr ();
   12833              : 
   12834         7981 :           dest = gen_reg_rtx (Pmode);
   12835         6059 :           if (TARGET_64BIT)
   12836              :             {
   12837         4137 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12838         4137 :               rtx rdi = gen_rtx_REG (Pmode, DI_REG);
   12839         4137 :               rtx_insn *insns;
   12840              : 
   12841         4137 :               start_sequence ();
   12842         4137 :               rtx_insn *call_insn = emit_call_insn
   12843         4137 :                 (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr, rdi));
   12844         4137 :               CALL_INSN_ABI_ID (call_insn)
   12845         4137 :                 = ix86_tls_get_addr_abi ().id ();
   12846         4137 :               insns = end_sequence ();
   12847              : 
   12848         4137 :               if (GET_MODE (x) != Pmode)
   12849            1 :                 x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12850              : 
   12851         4137 :               RTL_CONST_CALL_P (insns) = 1;
   12852         4137 :               emit_libcall_block (insns, dest, rax, x);
   12853              :             }
   12854              :           else
   12855         1922 :             emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
   12856              :         }
   12857              :       break;
   12858              : 
   12859          394 :     case TLS_MODEL_LOCAL_DYNAMIC:
   12860          394 :       if (!TARGET_64BIT)
   12861              :         {
   12862           92 :           if (flag_pic)
   12863           92 :             pic = pic_offset_table_rtx;
   12864              :           else
   12865              :             {
   12866            0 :               pic = gen_reg_rtx (Pmode);
   12867            0 :               emit_insn (gen_set_got (pic));
   12868              :             }
   12869              :         }
   12870              : 
   12871          394 :       if (TARGET_GNU2_TLS)
   12872              :         {
   12873           26 :           rtx tmp = ix86_tls_module_base ();
   12874              : 
   12875           26 :           base = gen_reg_rtx (ptr_mode);
   12876           26 :           if (TARGET_64BIT)
   12877           26 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
   12878              :           else
   12879            0 :             emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
   12880              : 
   12881           26 :           tp = get_thread_pointer (ptr_mode, true);
   12882           32 :           if (GET_MODE (base) != Pmode)
   12883            2 :             base = gen_rtx_ZERO_EXTEND (Pmode, base);
   12884           32 :           base = force_reg (Pmode, base);
   12885              :         }
   12886              :       else
   12887              :         {
   12888          368 :           rtx caddr = ix86_tls_get_addr ();
   12889              : 
   12890          460 :           base = gen_reg_rtx (Pmode);
   12891          368 :           if (TARGET_64BIT)
   12892              :             {
   12893          276 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12894          276 :               rtx rdi = gen_rtx_REG (Pmode, DI_REG);
   12895          276 :               rtx_insn *insns;
   12896          276 :               rtx eqv;
   12897              : 
   12898          276 :               start_sequence ();
   12899          276 :               rtx_insn *call_insn = emit_call_insn
   12900          276 :                 (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr, rdi));
   12901          276 :               CALL_INSN_ABI_ID (call_insn)
   12902          276 :                 = ix86_tls_get_addr_abi ().id ();
   12903          276 :               insns = end_sequence ();
   12904              : 
   12905              :               /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
   12906              :                  share the LD_BASE result with other LD model accesses.  */
   12907          276 :               eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
   12908              :                                     UNSPEC_TLS_LD_BASE);
   12909              : 
   12910          276 :               RTL_CONST_CALL_P (insns) = 1;
   12911          276 :               emit_libcall_block (insns, base, rax, eqv);
   12912              :             }
   12913              :           else
   12914           92 :             emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
   12915              :         }
   12916              : 
   12917          492 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
   12918          492 :       off = gen_rtx_CONST (Pmode, off);
   12919              : 
   12920          590 :       dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
   12921              : 
   12922          394 :       if (TARGET_GNU2_TLS)
   12923              :         {
   12924           32 :           if (GET_MODE (tp) != Pmode)
   12925              :             {
   12926            2 :               dest = lowpart_subreg (ptr_mode, dest, Pmode);
   12927            2 :               dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12928            2 :               dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12929              :             }
   12930              :           else
   12931           24 :             dest = gen_rtx_PLUS (Pmode, tp, dest);
   12932           32 :           dest = force_reg (Pmode, dest);
   12933              : 
   12934           32 :           if (GET_MODE (x) != Pmode)
   12935            1 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12936              : 
   12937           26 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12938              :         }
   12939              :       break;
   12940              : 
   12941        10862 :     case TLS_MODEL_INITIAL_EXEC:
   12942        10862 :       if (TARGET_64BIT)
   12943              :         {
   12944              :           /* Generate DImode references to avoid %fs:(%reg32)
   12945              :              problems and linker IE->LE relaxation bug.  */
   12946              :           tp_mode = DImode;
   12947              :           pic = NULL;
   12948              :           type = UNSPEC_GOTNTPOFF;
   12949              :         }
   12950          786 :       else if (flag_pic)
   12951              :         {
   12952          785 :           pic = pic_offset_table_rtx;
   12953          785 :           type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
   12954              :         }
   12955            1 :       else if (!TARGET_ANY_GNU_TLS)
   12956              :         {
   12957            0 :           pic = gen_reg_rtx (Pmode);
   12958            0 :           emit_insn (gen_set_got (pic));
   12959            0 :           type = UNSPEC_GOTTPOFF;
   12960              :         }
   12961              :       else
   12962              :         {
   12963              :           pic = NULL;
   12964              :           type = UNSPEC_INDNTPOFF;
   12965              :         }
   12966              : 
   12967        10862 :       off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
   12968        10862 :       off = gen_rtx_CONST (tp_mode, off);
   12969        10862 :       if (pic)
   12970          785 :         off = gen_rtx_PLUS (tp_mode, pic, off);
   12971        10862 :       off = gen_const_mem (tp_mode, off);
   12972        10862 :       set_mem_alias_set (off, GOT_ALIAS_SET);
   12973              : 
   12974        10862 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12975              :         {
   12976        10862 :           base = get_thread_pointer (tp_mode,
   12977        10862 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   12978        10862 :           off = force_reg (tp_mode, off);
   12979        10862 :           dest = gen_rtx_PLUS (tp_mode, base, off);
   12980        11652 :           if (tp_mode != Pmode)
   12981            4 :             dest = convert_to_mode (Pmode, dest, 1);
   12982              :         }
   12983              :       else
   12984              :         {
   12985            0 :           base = get_thread_pointer (Pmode, true);
   12986            0 :           dest = gen_reg_rtx (Pmode);
   12987            0 :           emit_insn (gen_sub3_insn (dest, base, off));
   12988              :         }
   12989              :       break;
   12990              : 
   12991        13647 :     case TLS_MODEL_LOCAL_EXEC:
   12992        28092 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   12993              :                             (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12994              :                             ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
   12995        14445 :       off = gen_rtx_CONST (Pmode, off);
   12996              : 
   12997        13647 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12998              :         {
   12999        14445 :           base = get_thread_pointer (Pmode,
   13000        13647 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   13001        14445 :           return gen_rtx_PLUS (Pmode, base, off);
   13002              :         }
   13003              :       else
   13004              :         {
   13005            0 :           base = get_thread_pointer (Pmode, true);
   13006            0 :           dest = gen_reg_rtx (Pmode);
   13007            0 :           emit_insn (gen_sub3_insn (dest, base, off));
   13008              :         }
   13009            0 :       break;
   13010              : 
   13011            0 :     default:
   13012            0 :       gcc_unreachable ();
   13013              :     }
   13014              : 
   13015              :   return dest;
   13016              : }
   13017              : 
   13018              : /* Return true if the TLS address requires insn using integer registers.
   13019              :    It's used to prevent KMOV/VMOV in TLS code sequences which require integer
   13020              :    MOV instructions, refer to PR103275.  */
   13021              : bool
   13022     15144710 : ix86_gpr_tls_address_pattern_p (rtx mem)
   13023              : {
   13024     15144710 :   gcc_assert (MEM_P (mem));
   13025              : 
   13026     15144710 :   rtx addr = XEXP (mem, 0);
   13027     15144710 :   subrtx_var_iterator::array_type array;
   13028     52633843 :   FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
   13029              :     {
   13030     37496774 :       rtx op = *iter;
   13031     37496774 :       if (GET_CODE (op) == UNSPEC)
   13032       201468 :         switch (XINT (op, 1))
   13033              :           {
   13034              :           case UNSPEC_GOTNTPOFF:
   13035         7641 :             return true;
   13036            0 :           case UNSPEC_TPOFF:
   13037            0 :             if (!TARGET_64BIT)
   13038              :               return true;
   13039              :             break;
   13040              :           default:
   13041              :             break;
   13042              :           }
   13043              :     }
   13044              : 
   13045     15137069 :   return false;
   13046     15144710 : }
   13047              : 
   13048              : /* Return true if OP refers to a TLS address.  */
   13049              : bool
   13050    235631974 : ix86_tls_address_pattern_p (rtx op)
   13051              : {
   13052    235631974 :   subrtx_var_iterator::array_type array;
   13053   1405304840 :   FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
   13054              :     {
   13055   1169691129 :       rtx op = *iter;
   13056   1169691129 :       if (MEM_P (op))
   13057              :         {
   13058    105853403 :           rtx *x = &XEXP (op, 0);
   13059    167339924 :           while (GET_CODE (*x) == PLUS)
   13060              :             {
   13061              :               int i;
   13062    184477849 :               for (i = 0; i < 2; i++)
   13063              :                 {
   13064    122991328 :                   rtx u = XEXP (*x, i);
   13065    122991328 :                   if (GET_CODE (u) == ZERO_EXTEND)
   13066        30000 :                     u = XEXP (u, 0);
   13067    122991328 :                   if (GET_CODE (u) == UNSPEC
   13068        18295 :                       && XINT (u, 1) == UNSPEC_TP)
   13069        18263 :                     return true;
   13070              :                 }
   13071     61486521 :               x = &XEXP (*x, 0);
   13072              :             }
   13073              : 
   13074    105835140 :           iter.skip_subrtxes ();
   13075              :         }
   13076              :     }
   13077              : 
   13078    235613711 :   return false;
   13079    235631974 : }
   13080              : 
   13081              : /* Rewrite *LOC so that it refers to a default TLS address space.  */
   13082              : static void
   13083        18263 : ix86_rewrite_tls_address_1 (rtx *loc)
   13084              : {
   13085        18263 :   subrtx_ptr_iterator::array_type array;
   13086        54255 :   FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
   13087              :     {
   13088        54255 :       rtx *loc = *iter;
   13089        54255 :       if (MEM_P (*loc))
   13090              :         {
   13091        18452 :           rtx addr = XEXP (*loc, 0);
   13092        18452 :           rtx *x = &addr;
   13093        23363 :           while (GET_CODE (*x) == PLUS)
   13094              :             {
   13095              :               int i;
   13096        33019 :               for (i = 0; i < 2; i++)
   13097              :                 {
   13098        28108 :                   rtx u = XEXP (*x, i);
   13099        28108 :                   if (GET_CODE (u) == ZERO_EXTEND)
   13100           19 :                     u = XEXP (u, 0);
   13101        28108 :                   if (GET_CODE (u) == UNSPEC
   13102        18263 :                       && XINT (u, 1) == UNSPEC_TP)
   13103              :                     {
   13104              :                       /* NB: Since address override only applies to the
   13105              :                          (reg32) part in fs:(reg32), return if address
   13106              :                          override is used.  */
   13107        19962 :                       if (Pmode != word_mode
   13108        18263 :                           && REG_P (XEXP (*x, 1 - i)))
   13109        18263 :                         return;
   13110              : 
   13111        18261 :                       addr_space_t as = DEFAULT_TLS_SEG_REG;
   13112              : 
   13113        18261 :                       *x = XEXP (*x, 1 - i);
   13114              : 
   13115        18261 :                       *loc = replace_equiv_address_nv (*loc, addr, true);
   13116        18261 :                       set_mem_addr_space (*loc, as);
   13117        18261 :                       return;
   13118              :                     }
   13119              :                 }
   13120         4911 :               x = &XEXP (*x, 0);
   13121              :             }
   13122              : 
   13123          189 :           iter.skip_subrtxes ();
   13124              :         }
   13125              :     }
   13126        18263 : }
   13127              : 
   13128              : /* Rewrite instruction pattern involvning TLS address
   13129              :    so that it refers to a default TLS address space.  */
   13130              : rtx
   13131        18263 : ix86_rewrite_tls_address (rtx pattern)
   13132              : {
   13133        18263 :   pattern = copy_insn (pattern);
   13134        18263 :   ix86_rewrite_tls_address_1 (&pattern);
   13135        18263 :   return pattern;
   13136              : }
   13137              : 
   13138              : /* Try machine-dependent ways of modifying an illegitimate address
   13139              :    to be legitimate.  If we find one, return the new, valid address.
   13140              :    This macro is used in only one place: `memory_address' in explow.cc.
   13141              : 
   13142              :    OLDX is the address as it was before break_out_memory_refs was called.
   13143              :    In some cases it is useful to look at this to decide what needs to be done.
   13144              : 
   13145              :    It is always safe for this macro to do nothing.  It exists to recognize
   13146              :    opportunities to optimize the output.
   13147              : 
   13148              :    For the 80386, we handle X+REG by loading X into a register R and
   13149              :    using R+REG.  R will go in a general reg and indexing will be used.
   13150              :    However, if REG is a broken-out memory address or multiplication,
   13151              :    nothing needs to be done because REG can certainly go in a general reg.
   13152              : 
   13153              :    When -fpic is used, special handling is needed for symbolic references.
   13154              :    See comments by legitimize_pic_address in i386.cc for details.  */
   13155              : 
   13156              : static rtx
   13157       661562 : ix86_legitimize_address (rtx x, rtx, machine_mode mode)
   13158              : {
   13159       661562 :   bool changed = false;
   13160       661562 :   unsigned log;
   13161              : 
   13162       661562 :   log = SYMBOL_REF_P (x) ? SYMBOL_REF_TLS_MODEL (x) : 0;
   13163       152022 :   if (log)
   13164        20845 :     return legitimize_tls_address (x, (enum tls_model) log, false);
   13165       640717 :   if (GET_CODE (x) == CONST
   13166          508 :       && GET_CODE (XEXP (x, 0)) == PLUS
   13167          508 :       && SYMBOL_REF_P (XEXP (XEXP (x, 0), 0))
   13168       641225 :       && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
   13169              :     {
   13170            4 :       rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
   13171              :                                       (enum tls_model) log, false);
   13172            5 :       return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
   13173              :     }
   13174              : 
   13175       640713 :   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   13176              :     {
   13177              : #if TARGET_PECOFF
   13178              :       rtx tmp = legitimize_pe_coff_symbol (x, true);
   13179              :       if (tmp)
   13180              :         return tmp;
   13181              : #endif
   13182              :     }
   13183              : 
   13184       640713 :   if (flag_pic && SYMBOLIC_CONST (x))
   13185       131560 :     return legitimize_pic_address (x, 0);
   13186              : 
   13187              : #if TARGET_MACHO
   13188              :   if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
   13189              :     return machopic_indirect_data_reference (x, 0);
   13190              : #endif
   13191              : 
   13192              :   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
   13193       509153 :   if (GET_CODE (x) == ASHIFT
   13194            0 :       && CONST_INT_P (XEXP (x, 1))
   13195            0 :       && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
   13196              :     {
   13197            0 :       changed = true;
   13198            0 :       log = INTVAL (XEXP (x, 1));
   13199            0 :       x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
   13200              :                         GEN_INT (1 << log));
   13201              :     }
   13202              : 
   13203       509153 :   if (GET_CODE (x) == PLUS)
   13204              :     {
   13205              :       /* Canonicalize shifts by 0, 1, 2, 3 into multiply.  */
   13206              : 
   13207       165493 :       if (GET_CODE (XEXP (x, 0)) == ASHIFT
   13208          602 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   13209          602 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
   13210              :         {
   13211          602 :           changed = true;
   13212          602 :           log = INTVAL (XEXP (XEXP (x, 0), 1));
   13213         1762 :           XEXP (x, 0) = gen_rtx_MULT (Pmode,
   13214              :                                       force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
   13215              :                                       GEN_INT (1 << log));
   13216              :         }
   13217              : 
   13218       165493 :       if (GET_CODE (XEXP (x, 1)) == ASHIFT
   13219            0 :           && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   13220            0 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
   13221              :         {
   13222            0 :           changed = true;
   13223            0 :           log = INTVAL (XEXP (XEXP (x, 1), 1));
   13224            0 :           XEXP (x, 1) = gen_rtx_MULT (Pmode,
   13225              :                                       force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
   13226              :                                       GEN_INT (1 << log));
   13227              :         }
   13228              : 
   13229              :       /* Put multiply first if it isn't already.  */
   13230       165493 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   13231              :         {
   13232            0 :           std::swap (XEXP (x, 0), XEXP (x, 1));
   13233            0 :           changed = true;
   13234              :         }
   13235              : 
   13236              :       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
   13237              :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
   13238              :          created by virtual register instantiation, register elimination, and
   13239              :          similar optimizations.  */
   13240       165493 :       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
   13241              :         {
   13242         9536 :           changed = true;
   13243        15140 :           x = gen_rtx_PLUS (Pmode,
   13244              :                             gen_rtx_PLUS (Pmode, XEXP (x, 0),
   13245              :                                           XEXP (XEXP (x, 1), 0)),
   13246              :                             XEXP (XEXP (x, 1), 1));
   13247              :         }
   13248              : 
   13249              :       /* Canonicalize
   13250              :          (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
   13251              :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
   13252       155957 :       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
   13253        60484 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   13254        51643 :                && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
   13255            0 :                && CONSTANT_P (XEXP (x, 1)))
   13256              :         {
   13257            0 :           rtx constant;
   13258            0 :           rtx other = NULL_RTX;
   13259              : 
   13260            0 :           if (CONST_INT_P (XEXP (x, 1)))
   13261              :             {
   13262            0 :               constant = XEXP (x, 1);
   13263            0 :               other = XEXP (XEXP (XEXP (x, 0), 1), 1);
   13264              :             }
   13265            0 :           else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
   13266              :             {
   13267              :               constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
   13268              :               other = XEXP (x, 1);
   13269              :             }
   13270              :           else
   13271              :             constant = 0;
   13272              : 
   13273            0 :           if (constant)
   13274              :             {
   13275            0 :               changed = true;
   13276            0 :               x = gen_rtx_PLUS (Pmode,
   13277              :                                 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
   13278              :                                               XEXP (XEXP (XEXP (x, 0), 1), 0)),
   13279              :                                 plus_constant (Pmode, other,
   13280              :                                                INTVAL (constant)));
   13281              :             }
   13282              :         }
   13283              : 
   13284       165493 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   13285         9572 :         return x;
   13286              : 
   13287       155921 :       if (GET_CODE (XEXP (x, 0)) == MULT)
   13288              :         {
   13289        19849 :           changed = true;
   13290        19849 :           XEXP (x, 0) = copy_addr_to_reg (XEXP (x, 0));
   13291              :         }
   13292              : 
   13293       155921 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   13294              :         {
   13295            0 :           changed = true;
   13296            0 :           XEXP (x, 1) = copy_addr_to_reg (XEXP (x, 1));
   13297              :         }
   13298              : 
   13299       155921 :       if (changed
   13300        19856 :           && REG_P (XEXP (x, 1))
   13301        16282 :           && REG_P (XEXP (x, 0)))
   13302              :         return x;
   13303              : 
   13304       139639 :       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
   13305              :         {
   13306         1837 :           changed = true;
   13307         1837 :           x = legitimize_pic_address (x, 0);
   13308              :         }
   13309              : 
   13310       139639 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   13311         3848 :         return x;
   13312              : 
   13313       135791 :       if (REG_P (XEXP (x, 0)))
   13314              :         {
   13315        77603 :           rtx temp = gen_reg_rtx (Pmode);
   13316        74847 :           rtx val  = force_operand (XEXP (x, 1), temp);
   13317        74847 :           if (val != temp)
   13318              :             {
   13319        66927 :               val = convert_to_mode (Pmode, val, 1);
   13320        66636 :               emit_move_insn (temp, val);
   13321              :             }
   13322              : 
   13323        74847 :           XEXP (x, 1) = temp;
   13324        74847 :           return x;
   13325              :         }
   13326              : 
   13327        60944 :       else if (REG_P (XEXP (x, 1)))
   13328              :         {
   13329         4217 :           rtx temp = gen_reg_rtx (Pmode);
   13330         3393 :           rtx val  = force_operand (XEXP (x, 0), temp);
   13331         3393 :           if (val != temp)
   13332              :             {
   13333            0 :               val = convert_to_mode (Pmode, val, 1);
   13334            0 :               emit_move_insn (temp, val);
   13335              :             }
   13336              : 
   13337         3393 :           XEXP (x, 0) = temp;
   13338         3393 :           return x;
   13339              :         }
   13340              :     }
   13341              : 
   13342              :   return x;
   13343              : }
   13344              : 
   13345              : /* Print an integer constant expression in assembler syntax.  Addition
   13346              :    and subtraction are the only arithmetic that may appear in these
   13347              :    expressions.  FILE is the stdio stream to write to, X is the rtx, and
   13348              :    CODE is the operand print code from the output string.  */
   13349              : 
   13350              : static void
   13351      3690207 : output_pic_addr_const (FILE *file, rtx x, int code)
   13352              : {
   13353      3920362 :   char buf[256];
   13354              : 
   13355      3920362 :   switch (GET_CODE (x))
   13356              :     {
   13357            0 :     case PC:
   13358            0 :       gcc_assert (flag_pic);
   13359            0 :       putc ('.', file);
   13360            0 :       break;
   13361              : 
   13362       865442 :     case SYMBOL_REF:
   13363       865442 :       if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
   13364       865442 :         output_addr_const (file, x);
   13365              :       else
   13366              :         {
   13367              :           const char *name = XSTR (x, 0);
   13368              : 
   13369              :           /* Mark the decl as referenced so that cgraph will
   13370              :              output the function.  */
   13371              :           if (SYMBOL_REF_DECL (x))
   13372              :             mark_decl_referenced (SYMBOL_REF_DECL (x));
   13373              : 
   13374              : #if TARGET_MACHO
   13375              :           if (MACHOPIC_INDIRECT
   13376              :               && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
   13377              :             name = machopic_indirection_name (x, /*stub_p=*/true);
   13378              : #endif
   13379              :           assemble_name (file, name);
   13380              :         }
   13381       865442 :       if (!TARGET_MACHO && !(TARGET_64BIT && TARGET_PECOFF)
   13382       865442 :           && code == 'P' && ix86_call_use_plt_p (x))
   13383       392660 :         fputs ("@PLT", file);
   13384              :       break;
   13385              : 
   13386         2656 :     case LABEL_REF:
   13387         2656 :       x = XEXP (x, 0);
   13388              :       /* FALLTHRU */
   13389         2656 :     case CODE_LABEL:
   13390         2656 :       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   13391         2656 :       assemble_name (asm_out_file, buf);
   13392         2656 :       break;
   13393              : 
   13394      2620712 :     CASE_CONST_SCALAR_INT:
   13395      2620712 :       output_addr_const (file, x);
   13396      2620712 :       break;
   13397              : 
   13398       211042 :     case CONST:
   13399              :       /* This used to output parentheses around the expression,
   13400              :          but that does not work on the 386 (either ATT or BSD assembler).  */
   13401       211042 :       output_pic_addr_const (file, XEXP (x, 0), code);
   13402       211042 :       break;
   13403              : 
   13404            0 :     case CONST_DOUBLE:
   13405              :       /* We can't handle floating point constants;
   13406              :          TARGET_PRINT_OPERAND must handle them.  */
   13407            0 :       output_operand_lossage ("floating constant misused");
   13408            0 :       break;
   13409              : 
   13410        19113 :     case PLUS:
   13411              :       /* Some assemblers need integer constants to appear first.  */
   13412        19113 :       if (CONST_INT_P (XEXP (x, 0)))
   13413              :         {
   13414            0 :           output_pic_addr_const (file, XEXP (x, 0), code);
   13415            0 :           putc ('+', file);
   13416            0 :           output_pic_addr_const (file, XEXP (x, 1), code);
   13417              :         }
   13418              :       else
   13419              :         {
   13420        19113 :           gcc_assert (CONST_INT_P (XEXP (x, 1)));
   13421        19113 :           output_pic_addr_const (file, XEXP (x, 1), code);
   13422        19113 :           putc ('+', file);
   13423        19113 :           output_pic_addr_const (file, XEXP (x, 0), code);
   13424              :         }
   13425              :       break;
   13426              : 
   13427            0 :     case MINUS:
   13428            0 :       if (!TARGET_MACHO)
   13429            0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
   13430            0 :       output_pic_addr_const (file, XEXP (x, 0), code);
   13431            0 :       putc ('-', file);
   13432            0 :       output_pic_addr_const (file, XEXP (x, 1), code);
   13433            0 :       if (!TARGET_MACHO)
   13434            0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
   13435            0 :       break;
   13436              : 
   13437       201397 :     case UNSPEC:
   13438       201397 :       gcc_assert (XVECLEN (x, 0) == 1);
   13439       201397 :       output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
   13440       201397 :       switch (XINT (x, 1))
   13441              :         {
   13442        43295 :         case UNSPEC_GOT:
   13443        43295 :           fputs ("@GOT", file);
   13444        43295 :           break;
   13445        78055 :         case UNSPEC_GOTOFF:
   13446        78055 :           fputs ("@GOTOFF", file);
   13447        78055 :           break;
   13448           36 :         case UNSPEC_PLTOFF:
   13449           36 :           fputs ("@PLTOFF", file);
   13450           36 :           break;
   13451            0 :         case UNSPEC_PCREL:
   13452            0 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   13453              :                  "(%rip)" : "[rip]", file);
   13454            0 :           break;
   13455        75792 :         case UNSPEC_GOTPCREL:
   13456        75792 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   13457              :                  "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
   13458        75792 :           break;
   13459            0 :         case UNSPEC_GOTTPOFF:
   13460              :           /* FIXME: This might be @TPOFF in Sun ld too.  */
   13461            0 :           fputs ("@gottpoff", file);
   13462            0 :           break;
   13463            0 :         case UNSPEC_TPOFF:
   13464            0 :           fputs ("@tpoff", file);
   13465            0 :           break;
   13466         1459 :         case UNSPEC_NTPOFF:
   13467         1459 :           if (TARGET_64BIT)
   13468         1459 :             fputs ("@tpoff", file);
   13469              :           else
   13470            0 :             fputs ("@ntpoff", file);
   13471              :           break;
   13472          319 :         case UNSPEC_DTPOFF:
   13473          319 :           fputs ("@dtpoff", file);
   13474          319 :           break;
   13475         2441 :         case UNSPEC_GOTNTPOFF:
   13476         2441 :           if (TARGET_64BIT)
   13477         2164 :             fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   13478              :                    "@gottpoff(%rip)": "@gottpoff[rip]", file);
   13479              :           else
   13480          277 :             fputs ("@gotntpoff", file);
   13481              :           break;
   13482            0 :         case UNSPEC_INDNTPOFF:
   13483            0 :           fputs ("@indntpoff", file);
   13484            0 :           break;
   13485            0 :         case UNSPEC_SECREL32:
   13486            0 :           fputs ("@secrel32", file);
   13487            0 :           break;
   13488              : #if TARGET_MACHO
   13489              :         case UNSPEC_MACHOPIC_OFFSET:
   13490              :           putc ('-', file);
   13491              :           machopic_output_function_base_name (file);
   13492              :           break;
   13493              : #endif
   13494            0 :         default:
   13495            0 :           output_operand_lossage ("invalid UNSPEC as operand");
   13496            0 :           break;
   13497              :         }
   13498              :        break;
   13499              : 
   13500            0 :     default:
   13501            0 :       output_operand_lossage ("invalid expression as operand");
   13502              :     }
   13503      3690207 : }
   13504              : 
   13505              : /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
   13506              :    We need to emit DTP-relative relocations.  */
   13507              : 
   13508              : static void ATTRIBUTE_UNUSED
   13509          689 : i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
   13510              : {
   13511          689 :   fputs (ASM_LONG, file);
   13512          689 :   output_addr_const (file, x);
   13513              : #if TARGET_WIN32_TLS
   13514              :   fputs ("@secrel32", file);
   13515              : #else
   13516          689 :   fputs ("@dtpoff", file);
   13517              : #endif
   13518          689 :   switch (size)
   13519              :     {
   13520              :     case 4:
   13521              :       break;
   13522          554 :     case 8:
   13523          554 :       fputs (", 0", file);
   13524          554 :       break;
   13525            0 :     default:
   13526            0 :       gcc_unreachable ();
   13527              :    }
   13528          689 : }
   13529              : 
   13530              : /* Return true if X is a representation of the PIC register.  This copes
   13531              :    with calls from ix86_find_base_term, where the register might have
   13532              :    been replaced by a cselib value.  */
   13533              : 
   13534              : static bool
   13535     26860716 : ix86_pic_register_p (rtx x)
   13536              : {
   13537     26860716 :   if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
   13538       753288 :     return (pic_offset_table_rtx
   13539       753288 :             && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
   13540     26107428 :   else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SET_GOT)
   13541              :     return true;
   13542     26104337 :   else if (!REG_P (x))
   13543              :     return false;
   13544     25497246 :   else if (pic_offset_table_rtx)
   13545              :     {
   13546     25477523 :       if (REGNO (x) == REGNO (pic_offset_table_rtx))
   13547              :         return true;
   13548       403826 :       if (HARD_REGISTER_P (x)
   13549       382437 :           && !HARD_REGISTER_P (pic_offset_table_rtx)
   13550       786263 :           && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
   13551              :         return true;
   13552              :       return false;
   13553              :     }
   13554              :   else
   13555        19723 :     return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
   13556              : }
   13557              : 
   13558              : /* Helper function for ix86_delegitimize_address.
   13559              :    Attempt to delegitimize TLS local-exec accesses.  */
   13560              : 
   13561              : static rtx
   13562   3505994139 : ix86_delegitimize_tls_address (rtx orig_x)
   13563              : {
   13564   3505994139 :   rtx x = orig_x, unspec;
   13565   3505994139 :   struct ix86_address addr;
   13566              : 
   13567   3505994139 :   if (!TARGET_TLS_DIRECT_SEG_REFS)
   13568              :     return orig_x;
   13569   3505994139 :   if (MEM_P (x))
   13570     43252726 :     x = XEXP (x, 0);
   13571   5034093433 :   if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
   13572              :     return orig_x;
   13573   1687442216 :   if (ix86_decompose_address (x, &addr) == 0
   13574   1950428090 :       || addr.seg != DEFAULT_TLS_SEG_REG
   13575       270087 :       || addr.disp == NULL_RTX
   13576   1687660491 :       || GET_CODE (addr.disp) != CONST)
   13577              :     return orig_x;
   13578       112395 :   unspec = XEXP (addr.disp, 0);
   13579       112395 :   if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
   13580        65649 :     unspec = XEXP (unspec, 0);
   13581       112395 :   if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
   13582              :     return orig_x;
   13583       112332 :   x = XVECEXP (unspec, 0, 0);
   13584       112332 :   gcc_assert (SYMBOL_REF_P (x));
   13585       112332 :   if (unspec != XEXP (addr.disp, 0))
   13586        87152 :     x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
   13587       112332 :   if (addr.index)
   13588              :     {
   13589          185 :       rtx idx = addr.index;
   13590          185 :       if (addr.scale != 1)
   13591          185 :         idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
   13592          185 :       x = gen_rtx_PLUS (Pmode, idx, x);
   13593              :     }
   13594       112332 :   if (addr.base)
   13595            2 :     x = gen_rtx_PLUS (Pmode, addr.base, x);
   13596       112332 :   if (MEM_P (orig_x))
   13597          198 :     x = replace_equiv_address_nv (orig_x, x);
   13598              :   return x;
   13599              : }
   13600              : 
   13601              : /* In the name of slightly smaller debug output, and to cater to
   13602              :    general assembler lossage, recognize PIC+GOTOFF and turn it back
   13603              :    into a direct symbol reference.
   13604              : 
   13605              :    On Darwin, this is necessary to avoid a crash, because Darwin
   13606              :    has a different PIC label for each routine but the DWARF debugging
   13607              :    information is not associated with any particular routine, so it's
   13608              :    necessary to remove references to the PIC label from RTL stored by
   13609              :    the DWARF output code.
   13610              : 
   13611              :    This helper is used in the normal ix86_delegitimize_address
   13612              :    entrypoint (e.g. used in the target delegitimization hook) and
   13613              :    in ix86_find_base_term.  As compile time memory optimization, we
   13614              :    avoid allocating rtxes that will not change anything on the outcome
   13615              :    of the callers (find_base_value and find_base_term).  */
   13616              : 
   13617              : static inline rtx
   13618   3530829073 : ix86_delegitimize_address_1 (rtx x, bool base_term_p)
   13619              : {
   13620   3530829073 :   rtx orig_x = delegitimize_mem_from_attrs (x);
   13621              :   /* addend is NULL or some rtx if x is something+GOTOFF where
   13622              :      something doesn't include the PIC register.  */
   13623   3530829073 :   rtx addend = NULL_RTX;
   13624              :   /* reg_addend is NULL or a multiple of some register.  */
   13625   3530829073 :   rtx reg_addend = NULL_RTX;
   13626              :   /* const_addend is NULL or a const_int.  */
   13627   3530829073 :   rtx const_addend = NULL_RTX;
   13628              :   /* This is the result, or NULL.  */
   13629   3530829073 :   rtx result = NULL_RTX;
   13630              : 
   13631   3530829073 :   x = orig_x;
   13632              : 
   13633   3530829073 :   if (MEM_P (x))
   13634     62453487 :     x = XEXP (x, 0);
   13635              : 
   13636   3530829073 :   if (TARGET_64BIT)
   13637              :     {
   13638    258723464 :       if (GET_CODE (x) == CONST
   13639      8692020 :           && GET_CODE (XEXP (x, 0)) == PLUS
   13640      6748546 :           && GET_MODE (XEXP (x, 0)) == Pmode
   13641      6748497 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   13642      6748497 :           && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
   13643    258727724 :           && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
   13644              :         {
   13645              :           /* find_base_{value,term} only care about MEMs with arg_pointer_rtx
   13646              :              base.  A CONST can't be arg_pointer_rtx based.  */
   13647            0 :           if (base_term_p && MEM_P (orig_x))
   13648              :             return orig_x;
   13649            0 :           rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
   13650            0 :           x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
   13651            0 :           if (MEM_P (orig_x))
   13652            0 :             x = replace_equiv_address_nv (orig_x, x);
   13653            0 :           return x;
   13654              :         }
   13655              : 
   13656    258723464 :       if (GET_CODE (x) == CONST
   13657      8692020 :           && GET_CODE (XEXP (x, 0)) == UNSPEC
   13658      1943523 :           && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
   13659       656978 :               || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
   13660      1286545 :           && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
   13661              :         {
   13662       294957 :           x = XVECEXP (XEXP (x, 0), 0, 0);
   13663       294957 :           if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
   13664              :             {
   13665            9 :               x = lowpart_subreg (GET_MODE (orig_x), x, GET_MODE (x));
   13666            9 :               if (x == NULL_RTX)
   13667              :                 return orig_x;
   13668              :             }
   13669       294957 :           return x;
   13670              :         }
   13671              : 
   13672    258428507 :       if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
   13673    258426845 :         return ix86_delegitimize_tls_address (orig_x);
   13674              : 
   13675              :       /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
   13676              :          and -mcmodel=medium -fpic.  */
   13677              :     }
   13678              : 
   13679   3272107271 :   if (GET_CODE (x) != PLUS
   13680   1552638847 :       || GET_CODE (XEXP (x, 1)) != CONST)
   13681   3245794960 :     return ix86_delegitimize_tls_address (orig_x);
   13682              : 
   13683     26312311 :   if (ix86_pic_register_p (XEXP (x, 0)))
   13684              :     /* %ebx + GOT/GOTOFF */
   13685              :     ;
   13686      1282201 :   else if (GET_CODE (XEXP (x, 0)) == PLUS)
   13687              :     {
   13688              :       /* %ebx + %reg * scale + GOT/GOTOFF */
   13689       472103 :       reg_addend = XEXP (x, 0);
   13690       472103 :       if (ix86_pic_register_p (XEXP (reg_addend, 0)))
   13691       395801 :         reg_addend = XEXP (reg_addend, 1);
   13692        76302 :       else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
   13693        44749 :         reg_addend = XEXP (reg_addend, 0);
   13694              :       else
   13695              :         {
   13696        31553 :           reg_addend = NULL_RTX;
   13697        31553 :           addend = XEXP (x, 0);
   13698              :         }
   13699              :     }
   13700              :   else
   13701              :     addend = XEXP (x, 0);
   13702              : 
   13703     26312311 :   x = XEXP (XEXP (x, 1), 0);
   13704     26312311 :   if (GET_CODE (x) == PLUS
   13705      1450257 :       && CONST_INT_P (XEXP (x, 1)))
   13706              :     {
   13707      1450257 :       const_addend = XEXP (x, 1);
   13708      1450257 :       x = XEXP (x, 0);
   13709              :     }
   13710              : 
   13711     26312311 :   if (GET_CODE (x) == UNSPEC
   13712     25635928 :       && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
   13713      6730124 :           || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
   13714      1095955 :           || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
   13715            4 :               && !MEM_P (orig_x) && !addend)))
   13716     24539977 :     result = XVECEXP (x, 0, 0);
   13717              : 
   13718     24539977 :   if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
   13719              :       && !MEM_P (orig_x))
   13720              :     result = XVECEXP (x, 0, 0);
   13721              : 
   13722     24539977 :   if (! result)
   13723      1772334 :     return ix86_delegitimize_tls_address (orig_x);
   13724              : 
   13725              :   /* For (PLUS something CONST_INT) both find_base_{value,term} just
   13726              :      recurse on the first operand.  */
   13727     24539977 :   if (const_addend && !base_term_p)
   13728       356190 :     result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
   13729     24539977 :   if (reg_addend)
   13730       856908 :     result = gen_rtx_PLUS (Pmode, reg_addend, result);
   13731     24539977 :   if (addend)
   13732              :     {
   13733              :       /* If the rest of original X doesn't involve the PIC register, add
   13734              :          addend and subtract pic_offset_table_rtx.  This can happen e.g.
   13735              :          for code like:
   13736              :          leal (%ebx, %ecx, 4), %ecx
   13737              :          ...
   13738              :          movl foo@GOTOFF(%ecx), %edx
   13739              :          in which case we return (%ecx - %ebx) + foo
   13740              :          or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
   13741              :          and reload has completed.  Don't do the latter for debug,
   13742              :          as _GLOBAL_OFFSET_TABLE_ can't be expressed in the assembly.  */
   13743       137444 :       if (pic_offset_table_rtx
   13744       137444 :           && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
   13745         2364 :         result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
   13746              :                                                      pic_offset_table_rtx),
   13747              :                                result);
   13748       136656 :       else if (base_term_p
   13749       130384 :                && pic_offset_table_rtx
   13750              :                && !TARGET_MACHO
   13751              :                && !TARGET_VXWORKS_VAROFF)
   13752              :         {
   13753       260768 :           rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
   13754       260768 :           tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
   13755       260768 :           result = gen_rtx_PLUS (Pmode, tmp, result);
   13756       130384 :         }
   13757              :       else
   13758              :         return orig_x;
   13759              :     }
   13760     49067325 :   if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
   13761              :     {
   13762            0 :       result = lowpart_subreg (GET_MODE (orig_x), result, Pmode);
   13763            0 :       if (result == NULL_RTX)
   13764              :         return orig_x;
   13765              :     }
   13766              :   return result;
   13767              : }
   13768              : 
   13769              : /* The normal instantiation of the above template.  */
   13770              : 
   13771              : static rtx
   13772    329556950 : ix86_delegitimize_address (rtx x)
   13773              : {
   13774    329556950 :   return ix86_delegitimize_address_1 (x, false);
   13775              : }
   13776              : 
   13777              : /* If X is a machine specific address (i.e. a symbol or label being
   13778              :    referenced as a displacement from the GOT implemented using an
   13779              :    UNSPEC), then return the base term.  Otherwise return X.  */
   13780              : 
   13781              : rtx
   13782   6721052652 : ix86_find_base_term (rtx x)
   13783              : {
   13784   6721052652 :   rtx term;
   13785              : 
   13786   6721052652 :   if (TARGET_64BIT)
   13787              :     {
   13788   3519780529 :       if (GET_CODE (x) != CONST)
   13789              :         return x;
   13790     42321833 :       term = XEXP (x, 0);
   13791     42321833 :       if (GET_CODE (term) == PLUS
   13792     42306982 :           && CONST_INT_P (XEXP (term, 1)))
   13793     42306982 :         term = XEXP (term, 0);
   13794     42321833 :       if (GET_CODE (term) != UNSPEC
   13795        39853 :           || (XINT (term, 1) != UNSPEC_GOTPCREL
   13796        39821 :               && XINT (term, 1) != UNSPEC_PCREL))
   13797              :         return x;
   13798              : 
   13799           32 :       return XVECEXP (term, 0, 0);
   13800              :     }
   13801              : 
   13802   3201272123 :   return ix86_delegitimize_address_1 (x, true);
   13803              : }
   13804              : 
   13805              : /* Return true if X shouldn't be emitted into the debug info.
   13806              :    Disallow UNSPECs other than @gotoff - we can't emit _GLOBAL_OFFSET_TABLE_
   13807              :    symbol easily into the .debug_info section, so we need not to
   13808              :    delegitimize, but instead assemble as @gotoff.
   13809              :    Disallow _GLOBAL_OFFSET_TABLE_ SYMBOL_REF - the assembler magically
   13810              :    assembles that as _GLOBAL_OFFSET_TABLE_-. expression.  */
   13811              : 
   13812              : static bool
   13813      1860781 : ix86_const_not_ok_for_debug_p (rtx x)
   13814              : {
   13815      1860781 :   if (GET_CODE (x) == UNSPEC && XINT (x, 1) != UNSPEC_GOTOFF)
   13816              :     return true;
   13817              : 
   13818      1860761 :   if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
   13819            0 :     return true;
   13820              : 
   13821              :   return false;
   13822              : }
   13823              : 
   13824              : static void
   13825      7226679 : put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
   13826              :                     bool fp, FILE *file)
   13827              : {
   13828      7226679 :   const char *suffix;
   13829              : 
   13830      7226679 :   if (mode == CCFPmode)
   13831              :     {
   13832       570087 :       code = ix86_fp_compare_code_to_integer (code);
   13833       570087 :       mode = CCmode;
   13834              :     }
   13835      7226679 :   if (reverse)
   13836       225321 :     code = reverse_condition (code);
   13837              : 
   13838      7226679 :   switch (code)
   13839              :     {
   13840      2788472 :     case EQ:
   13841      2788472 :       gcc_assert (mode != CCGZmode);
   13842      2788472 :       switch (mode)
   13843              :         {
   13844              :         case E_CCAmode:
   13845              :           suffix = "a";
   13846              :           break;
   13847              :         case E_CCCmode:
   13848        26541 :           suffix = "c";
   13849              :           break;
   13850              :         case E_CCOmode:
   13851      7226679 :           suffix = "o";
   13852              :           break;
   13853              :         case E_CCPmode:
   13854       235017 :           suffix = "p";
   13855              :           break;
   13856              :         case E_CCSmode:
   13857       133079 :           suffix = "s";
   13858              :           break;
   13859      2768681 :         default:
   13860      2768681 :           suffix = "e";
   13861      2768681 :           break;
   13862              :         }
   13863              :       break;
   13864      2343086 :     case NE:
   13865      2343086 :       gcc_assert (mode != CCGZmode);
   13866      2343086 :       switch (mode)
   13867              :         {
   13868              :         case E_CCAmode:
   13869              :           suffix = "na";
   13870              :           break;
   13871              :         case E_CCCmode:
   13872        12001 :           suffix = "nc";
   13873              :           break;
   13874        11037 :         case E_CCOmode:
   13875        11037 :           suffix = "no";
   13876        11037 :           break;
   13877              :         case E_CCPmode:
   13878         5006 :           suffix = "np";
   13879              :           break;
   13880              :         case E_CCSmode:
   13881        53455 :           suffix = "ns";
   13882              :           break;
   13883      2330163 :         default:
   13884      2330163 :           suffix = "ne";
   13885      2330163 :           break;
   13886              :         }
   13887              :       break;
   13888       264255 :     case GT:
   13889       264255 :       gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
   13890              :       suffix = "g";
   13891              :       break;
   13892       185240 :     case GTU:
   13893              :       /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
   13894              :          Those same assemblers have the same but opposite lossage on cmov.  */
   13895       185240 :       if (mode == CCmode)
   13896       185302 :         suffix = fp ? "nbe" : "a";
   13897              :       else
   13898            0 :         gcc_unreachable ();
   13899              :       break;
   13900       243921 :     case LT:
   13901       243921 :       switch (mode)
   13902              :         {
   13903              :         case E_CCNOmode:
   13904              :         case E_CCGOCmode:
   13905              :           suffix = "s";
   13906              :           break;
   13907              : 
   13908              :         case E_CCmode:
   13909              :         case E_CCGCmode:
   13910              :         case E_CCGZmode:
   13911      7226679 :           suffix = "l";
   13912              :           break;
   13913              : 
   13914            0 :         default:
   13915            0 :           gcc_unreachable ();
   13916              :         }
   13917              :       break;
   13918       439494 :     case LTU:
   13919       439494 :       if (mode == CCmode || mode == CCGZmode)
   13920              :         suffix = "b";
   13921        25210 :       else if (mode == CCCmode)
   13922        26541 :         suffix = fp ? "b" : "c";
   13923              :       else
   13924            0 :         gcc_unreachable ();
   13925              :       break;
   13926       147306 :     case GE:
   13927       147306 :       switch (mode)
   13928              :         {
   13929              :         case E_CCNOmode:
   13930              :         case E_CCGOCmode:
   13931              :           suffix = "ns";
   13932              :           break;
   13933              : 
   13934              :         case E_CCmode:
   13935              :         case E_CCGCmode:
   13936              :         case E_CCGZmode:
   13937      7226679 :           suffix = "ge";
   13938              :           break;
   13939              : 
   13940            0 :         default:
   13941            0 :           gcc_unreachable ();
   13942              :         }
   13943              :       break;
   13944       197734 :     case GEU:
   13945       197734 :       if (mode == CCmode || mode == CCGZmode)
   13946              :         suffix = "nb";
   13947        10135 :       else if (mode == CCCmode)
   13948        12001 :         suffix = fp ? "nb" : "nc";
   13949              :       else
   13950            0 :         gcc_unreachable ();
   13951              :       break;
   13952       253340 :     case LE:
   13953       253340 :       gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
   13954              :       suffix = "le";
   13955              :       break;
   13956       123806 :     case LEU:
   13957       123806 :       if (mode == CCmode)
   13958              :         suffix = "be";
   13959              :       else
   13960            0 :         gcc_unreachable ();
   13961              :       break;
   13962       235017 :     case UNORDERED:
   13963       235024 :       suffix = fp ? "u" : "p";
   13964              :       break;
   13965         5008 :     case ORDERED:
   13966         5013 :       suffix = fp ? "nu" : "np";
   13967              :       break;
   13968            0 :     default:
   13969            0 :       gcc_unreachable ();
   13970              :     }
   13971      7226679 :   fputs (suffix, file);
   13972      7226679 : }
   13973              : 
   13974              : /* Print the name of register X to FILE based on its machine mode and number.
   13975              :    If CODE is 'w', pretend the mode is HImode.
   13976              :    If CODE is 'b', pretend the mode is QImode.
   13977              :    If CODE is 'k', pretend the mode is SImode.
   13978              :    If CODE is 'q', pretend the mode is DImode.
   13979              :    If CODE is 'x', pretend the mode is V4SFmode.
   13980              :    If CODE is 't', pretend the mode is V8SFmode.
   13981              :    If CODE is 'g', pretend the mode is V16SFmode.
   13982              :    If CODE is 'h', pretend the reg is the 'high' byte register.
   13983              :    If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
   13984              :    If CODE is 'd', duplicate the operand for AVX instruction.
   13985              :    If CODE is 'V', print naked full integer register name without %.
   13986              :  */
   13987              : 
   13988              : void
   13989    124647948 : print_reg (rtx x, int code, FILE *file)
   13990              : {
   13991    124647948 :   const char *reg;
   13992    124647948 :   int msize;
   13993    124647948 :   unsigned int regno;
   13994    124647948 :   bool duplicated;
   13995              : 
   13996    124647948 :   if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
   13997    124645541 :     putc ('%', file);
   13998              : 
   13999    124647948 :   if (x == pc_rtx)
   14000              :     {
   14001      5768168 :       gcc_assert (TARGET_64BIT);
   14002      5768168 :       fputs ("rip", file);
   14003      5768168 :       return;
   14004              :     }
   14005              : 
   14006    118879780 :   if (code == 'y' && STACK_TOP_P (x))
   14007              :     {
   14008       290465 :       fputs ("st(0)", file);
   14009       290465 :       return;
   14010              :     }
   14011              : 
   14012    118589315 :   if (code == 'w')
   14013              :     msize = 2;
   14014              :   else if (code == 'b')
   14015              :     msize = 1;
   14016              :   else if (code == 'k')
   14017              :     msize = 4;
   14018              :   else if (code == 'q')
   14019              :     msize = 8;
   14020              :   else if (code == 'h')
   14021              :     msize = 0;
   14022              :   else if (code == 'x')
   14023              :     msize = 16;
   14024              :   else if (code == 't')
   14025              :     msize = 32;
   14026              :   else if (code == 'g')
   14027              :     msize = 64;
   14028              :   else
   14029    202726574 :     msize = GET_MODE_SIZE (GET_MODE (x));
   14030              : 
   14031    118589315 :   regno = REGNO (x);
   14032              : 
   14033    118589315 :   if (regno == ARG_POINTER_REGNUM
   14034    118589315 :       || regno == FRAME_POINTER_REGNUM
   14035    118589315 :       || regno == FPSR_REG)
   14036              :     {
   14037            0 :       output_operand_lossage
   14038            0 :         ("invalid use of register '%s'", reg_names[regno]);
   14039            0 :       return;
   14040              :     }
   14041    118589315 :   else if (regno == FLAGS_REG)
   14042              :     {
   14043            1 :       output_operand_lossage ("invalid use of asm flag output");
   14044            1 :       return;
   14045              :     }
   14046              : 
   14047    118589314 :   if (code == 'V')
   14048              :     {
   14049            1 :       if (GENERAL_REGNO_P (regno))
   14050            2 :         msize = GET_MODE_SIZE (word_mode);
   14051              :       else
   14052            0 :         error ("%<V%> modifier on non-integer register");
   14053              :     }
   14054              : 
   14055    118589314 :   duplicated = code == 'd' && TARGET_AVX;
   14056              : 
   14057    118589314 :   switch (msize)
   14058              :     {
   14059     78903316 :     case 16:
   14060     78903316 :     case 12:
   14061     78903316 :     case 8:
   14062    147715619 :       if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
   14063            5 :         warning (0, "unsupported size for integer register");
   14064              :       /* FALLTHRU */
   14065    115096622 :     case 4:
   14066    115096622 :       if (LEGACY_INT_REGNO_P (regno))
   14067    124420040 :         putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
   14068              :       /* FALLTHRU */
   14069    115991725 :     case 2:
   14070     22389549 :     normal:
   14071    115991725 :       reg = hi_reg_name[regno];
   14072    115991725 :       break;
   14073      2332865 :     case 1:
   14074      2332865 :       if (regno >= ARRAY_SIZE (qi_reg_name))
   14075       273327 :         goto normal;
   14076      2059538 :       if (!ANY_QI_REGNO_P (regno))
   14077            0 :         error ("unsupported size for integer register");
   14078      2059538 :       reg = qi_reg_name[regno];
   14079      2059538 :       break;
   14080        26407 :     case 0:
   14081        26407 :       if (regno >= ARRAY_SIZE (qi_high_reg_name))
   14082            0 :         goto normal;
   14083        26407 :       reg = qi_high_reg_name[regno];
   14084        26407 :       break;
   14085       511644 :     case 32:
   14086       511644 :     case 64:
   14087       511644 :       if (SSE_REGNO_P (regno))
   14088              :         {
   14089       511644 :           gcc_assert (!duplicated);
   14090       716737 :           putc (msize == 32 ? 'y' : 'z', file);
   14091       511644 :           reg = hi_reg_name[regno] + 1;
   14092       511644 :           break;
   14093              :         }
   14094            0 :       goto normal;
   14095            0 :     default:
   14096            0 :       gcc_unreachable ();
   14097              :     }
   14098              : 
   14099    118589314 :   fputs (reg, file);
   14100              : 
   14101              :   /* Irritatingly, AMD extended registers use
   14102              :      different naming convention: "r%d[bwd]"  */
   14103    118589314 :   if (REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   14104              :     {
   14105     10561082 :       gcc_assert (TARGET_64BIT);
   14106     10561082 :       switch (msize)
   14107              :         {
   14108            0 :           case 0:
   14109            0 :             error ("extended registers have no high halves");
   14110            0 :             break;
   14111       181373 :           case 1:
   14112       181373 :             putc ('b', file);
   14113       181373 :             break;
   14114        30749 :           case 2:
   14115        30749 :             putc ('w', file);
   14116        30749 :             break;
   14117      2530763 :           case 4:
   14118      2530763 :             putc ('d', file);
   14119      2530763 :             break;
   14120              :           case 8:
   14121              :             /* no suffix */
   14122              :             break;
   14123            0 :           default:
   14124            0 :             error ("unsupported operand size for extended register");
   14125            0 :             break;
   14126              :         }
   14127     10561082 :       return;
   14128              :     }
   14129              : 
   14130    108028232 :   if (duplicated)
   14131              :     {
   14132        16864 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14133        16847 :         fprintf (file, ", %%%s", reg);
   14134              :       else
   14135           17 :         fprintf (file, ", %s", reg);
   14136              :     }
   14137              : }
   14138              : 
   14139              : /* Meaning of CODE:
   14140              :    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
   14141              :    C -- print opcode suffix for set/cmov insn.
   14142              :    c -- like C, but print reversed condition
   14143              :    F,f -- likewise, but for floating-point.
   14144              :    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
   14145              :         otherwise nothing
   14146              :    R -- print embedded rounding and sae.
   14147              :    r -- print only sae.
   14148              :    z -- print the opcode suffix for the size of the current operand.
   14149              :    Z -- likewise, with special suffixes for x87 instructions.
   14150              :    * -- print a star (in certain assembler syntax)
   14151              :    A -- print an absolute memory reference.
   14152              :    E -- print address with DImode register names if TARGET_64BIT.
   14153              :    w -- print the operand as if it's a "word" (HImode) even if it isn't.
   14154              :    s -- print a shift double count, followed by the assemblers argument
   14155              :         delimiter.
   14156              :    b -- print the QImode name of the register for the indicated operand.
   14157              :         %b0 would print %al if operands[0] is reg 0.
   14158              :    w --  likewise, print the HImode name of the register.
   14159              :    k --  likewise, print the SImode name of the register.
   14160              :    q --  likewise, print the DImode name of the register.
   14161              :    x --  likewise, print the V4SFmode name of the register.
   14162              :    t --  likewise, print the V8SFmode name of the register.
   14163              :    g --  likewise, print the V16SFmode name of the register.
   14164              :    h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
   14165              :    y -- print "st(0)" instead of "st" as a register.
   14166              :    d -- print duplicated register operand for AVX instruction.
   14167              :    D -- print condition for SSE cmp instruction.
   14168              :    P -- if PIC, print an @PLT suffix.  For -fno-plt, load function
   14169              :         address from GOT.
   14170              :    p -- print raw symbol name.
   14171              :    X -- don't print any sort of PIC '@' suffix for a symbol.
   14172              :    & -- print some in-use local-dynamic symbol name.
   14173              :    H -- print a memory address offset by 8; used for sse high-parts
   14174              :    Y -- print condition for XOP pcom* instruction.
   14175              :    V -- print naked full integer register name without %.
   14176              :    v -- print segment override prefix
   14177              :    + -- print a branch hint as 'cs' or 'ds' prefix
   14178              :    ; -- print a semicolon (after prefixes due to bug in older gas).
   14179              :    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
   14180              :    ^ -- print addr32 prefix if Pmode != word_mode
   14181              :    M -- print addr32 prefix for TARGET_X32 with VSIB address.
   14182              :    ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
   14183              :    N -- print maskz if it's constant 0 operand.
   14184              :    G -- print embedded flag for ccmp/ctest.
   14185              :  */
   14186              : 
   14187              : void
   14188    178745949 : ix86_print_operand (FILE *file, rtx x, int code)
   14189              : {
   14190    178936891 :   if (code)
   14191              :     {
   14192     62678639 :       switch (code)
   14193              :         {
   14194       190938 :         case 'A':
   14195       190938 :           switch (ASSEMBLER_DIALECT)
   14196              :             {
   14197       190938 :             case ASM_ATT:
   14198       190938 :               putc ('*', file);
   14199       190938 :               break;
   14200              : 
   14201            0 :             case ASM_INTEL:
   14202              :               /* Intel syntax. For absolute addresses, registers should not
   14203              :                  be surrounded by braces.  */
   14204            0 :               if (!REG_P (x))
   14205              :                 {
   14206            0 :                   putc ('[', file);
   14207            0 :                   ix86_print_operand (file, x, 0);
   14208            0 :                   putc (']', file);
   14209            0 :                   return;
   14210              :                 }
   14211              :               break;
   14212              : 
   14213            0 :             default:
   14214            0 :               gcc_unreachable ();
   14215              :             }
   14216              : 
   14217       190938 :           ix86_print_operand (file, x, 0);
   14218       190938 :           return;
   14219              : 
   14220      3599845 :         case 'E':
   14221              :           /* Wrap address in an UNSPEC to declare special handling.  */
   14222      3599845 :           if (TARGET_64BIT)
   14223      3114154 :             x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
   14224              : 
   14225      3599845 :           output_address (VOIDmode, x);
   14226      3599845 :           return;
   14227              : 
   14228            0 :         case 'L':
   14229            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14230            0 :             putc ('l', file);
   14231            0 :           return;
   14232              : 
   14233            0 :         case 'W':
   14234            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14235            0 :             putc ('w', file);
   14236            0 :           return;
   14237              : 
   14238            0 :         case 'B':
   14239            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14240            0 :             putc ('b', file);
   14241            0 :           return;
   14242              : 
   14243            0 :         case 'Q':
   14244            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14245            0 :             putc ('l', file);
   14246            0 :           return;
   14247              : 
   14248            0 :         case 'S':
   14249            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14250            0 :             putc ('s', file);
   14251            0 :           return;
   14252              : 
   14253            0 :         case 'T':
   14254            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14255            0 :             putc ('t', file);
   14256            0 :           return;
   14257              : 
   14258              :         case 'O':
   14259              : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   14260              :           if (ASSEMBLER_DIALECT != ASM_ATT)
   14261              :             return;
   14262              : 
   14263              :           switch (GET_MODE_SIZE (GET_MODE (x)))
   14264              :             {
   14265              :             case 2:
   14266              :               putc ('w', file);
   14267              :               break;
   14268              : 
   14269              :             case 4:
   14270              :               putc ('l', file);
   14271              :               break;
   14272              : 
   14273              :             case 8:
   14274              :               putc ('q', file);
   14275              :               break;
   14276              : 
   14277              :             default:
   14278              :               output_operand_lossage ("invalid operand size for operand "
   14279              :                                       "code 'O'");
   14280              :               return;
   14281              :             }
   14282              : 
   14283              :           putc ('.', file);
   14284              : #endif
   14285              :           return;
   14286              : 
   14287        38097 :         case 'z':
   14288        38097 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   14289              :             {
   14290              :               /* Opcodes don't get size suffixes if using Intel opcodes.  */
   14291        38095 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   14292              :                 return;
   14293              : 
   14294        76190 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   14295              :                 {
   14296            6 :                 case 1:
   14297            6 :                   putc ('b', file);
   14298            6 :                   return;
   14299              : 
   14300            6 :                 case 2:
   14301            6 :                   putc ('w', file);
   14302            6 :                   return;
   14303              : 
   14304        37598 :                 case 4:
   14305        37598 :                   putc ('l', file);
   14306        37598 :                   return;
   14307              : 
   14308          485 :                 case 8:
   14309          485 :                   putc ('q', file);
   14310          485 :                   return;
   14311              : 
   14312            0 :                 default:
   14313            0 :                   output_operand_lossage ("invalid operand size for operand "
   14314              :                                           "code 'z'");
   14315            0 :                   return;
   14316              :                 }
   14317              :             }
   14318              : 
   14319            2 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   14320              :             {
   14321            1 :               if (this_is_asm_operands)
   14322            1 :                 warning_for_asm (this_is_asm_operands,
   14323              :                                  "non-integer operand used with operand code %<z%>");
   14324              :               else
   14325            0 :                 warning (0, "non-integer operand used with operand code %<z%>");
   14326              :             }
   14327              :           /* FALLTHRU */
   14328              : 
   14329       386077 :         case 'Z':
   14330              :           /* 387 opcodes don't get size suffixes if using Intel opcodes.  */
   14331       386077 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14332              :             return;
   14333              : 
   14334       386077 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   14335              :             {
   14336        29434 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   14337              :                 {
   14338         3525 :                 case 2:
   14339              : #ifdef HAVE_AS_IX86_FILDS
   14340         3525 :                   putc ('s', file);
   14341              : #endif
   14342         3525 :                   return;
   14343              : 
   14344         3989 :                 case 4:
   14345         3989 :                   putc ('l', file);
   14346         3989 :                   return;
   14347              : 
   14348         7203 :                 case 8:
   14349              : #ifdef HAVE_AS_IX86_FILDQ
   14350         7203 :                   putc ('q', file);
   14351              : #else
   14352              :                   fputs ("ll", file);
   14353              : #endif
   14354         7203 :                   return;
   14355              : 
   14356              :                 default:
   14357              :                   break;
   14358              :                 }
   14359              :             }
   14360       371360 :           else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   14361              :             {
   14362              :               /* 387 opcodes don't get size suffixes
   14363              :                  if the operands are registers.  */
   14364       371358 :               if (STACK_REG_P (x))
   14365              :                 return;
   14366              : 
   14367       691864 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   14368              :                 {
   14369        23577 :                 case 4:
   14370        23577 :                   putc ('s', file);
   14371        23577 :                   return;
   14372              : 
   14373        32884 :                 case 8:
   14374        32884 :                   putc ('l', file);
   14375        32884 :                   return;
   14376              : 
   14377       289469 :                 case 12:
   14378       289469 :                 case 16:
   14379       289469 :                   putc ('t', file);
   14380       289469 :                   return;
   14381              : 
   14382              :                 default:
   14383              :                   break;
   14384              :                 }
   14385              :             }
   14386              :           else
   14387              :             {
   14388            2 :               output_operand_lossage ("invalid operand type used with "
   14389              :                                       "operand code '%c'", code);
   14390            2 :               return;
   14391              :             }
   14392              : 
   14393            2 :           output_operand_lossage ("invalid operand size for operand code '%c'",
   14394              :                                   code);
   14395            2 :           return;
   14396              : 
   14397              :         case 'd':
   14398              :         case 'b':
   14399              :         case 'w':
   14400              :         case 'k':
   14401              :         case 'q':
   14402              :         case 'h':
   14403              :         case 't':
   14404              :         case 'g':
   14405              :         case 'y':
   14406              :         case 'x':
   14407              :         case 'X':
   14408              :         case 'P':
   14409              :         case 'p':
   14410              :         case 'V':
   14411              :           break;
   14412              : 
   14413            0 :         case 's':
   14414            0 :           if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
   14415              :             {
   14416            0 :               ix86_print_operand (file, x, 0);
   14417            0 :               fputs (", ", file);
   14418              :             }
   14419            0 :           return;
   14420              : 
   14421          494 :         case 'Y':
   14422          494 :           switch (GET_CODE (x))
   14423              :             {
   14424          182 :             case NE:
   14425          182 :               fputs ("neq", file);
   14426          182 :               break;
   14427           32 :             case EQ:
   14428           32 :               fputs ("eq", file);
   14429           32 :               break;
   14430           64 :             case GE:
   14431           64 :             case GEU:
   14432           64 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
   14433           64 :               break;
   14434           40 :             case GT:
   14435           40 :             case GTU:
   14436           40 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
   14437           40 :               break;
   14438           64 :             case LE:
   14439           64 :             case LEU:
   14440           64 :               fputs ("le", file);
   14441           64 :               break;
   14442          112 :             case LT:
   14443          112 :             case LTU:
   14444          112 :               fputs ("lt", file);
   14445          112 :               break;
   14446            0 :             case UNORDERED:
   14447            0 :               fputs ("unord", file);
   14448            0 :               break;
   14449            0 :             case ORDERED:
   14450            0 :               fputs ("ord", file);
   14451            0 :               break;
   14452            0 :             case UNEQ:
   14453            0 :               fputs ("ueq", file);
   14454            0 :               break;
   14455            0 :             case UNGE:
   14456            0 :               fputs ("nlt", file);
   14457            0 :               break;
   14458            0 :             case UNGT:
   14459            0 :               fputs ("nle", file);
   14460            0 :               break;
   14461            0 :             case UNLE:
   14462            0 :               fputs ("ule", file);
   14463            0 :               break;
   14464            0 :             case UNLT:
   14465            0 :               fputs ("ult", file);
   14466            0 :               break;
   14467            0 :             case LTGT:
   14468            0 :               fputs ("une", file);
   14469            0 :               break;
   14470            0 :             default:
   14471            0 :               output_operand_lossage ("operand is not a condition code, "
   14472              :                                       "invalid operand code 'Y'");
   14473            0 :               return;
   14474              :             }
   14475          494 :           return;
   14476              : 
   14477        10193 :         case 'D':
   14478              :           /* Little bit of braindamage here.  The SSE compare instructions
   14479              :              does use completely different names for the comparisons that the
   14480              :              fp conditional moves.  */
   14481        10193 :           switch (GET_CODE (x))
   14482              :             {
   14483           15 :             case UNEQ:
   14484           15 :               if (TARGET_AVX)
   14485              :                 {
   14486           15 :                   fputs ("eq_us", file);
   14487           15 :                   break;
   14488              :                 }
   14489              :              /* FALLTHRU */
   14490         5249 :             case EQ:
   14491         5249 :               fputs ("eq", file);
   14492         5249 :               break;
   14493            0 :             case UNLT:
   14494            0 :               if (TARGET_AVX)
   14495              :                 {
   14496            0 :                   fputs ("nge", file);
   14497            0 :                   break;
   14498              :                 }
   14499              :              /* FALLTHRU */
   14500         1728 :             case LT:
   14501         1728 :               fputs ("lt", file);
   14502         1728 :               break;
   14503            0 :             case UNLE:
   14504            0 :               if (TARGET_AVX)
   14505              :                 {
   14506            0 :                   fputs ("ngt", file);
   14507            0 :                   break;
   14508              :                 }
   14509              :              /* FALLTHRU */
   14510          839 :             case LE:
   14511          839 :               fputs ("le", file);
   14512          839 :               break;
   14513          100 :             case UNORDERED:
   14514          100 :               fputs ("unord", file);
   14515          100 :               break;
   14516           12 :             case LTGT:
   14517           12 :               if (TARGET_AVX)
   14518              :                 {
   14519           12 :                   fputs ("neq_oq", file);
   14520           12 :                   break;
   14521              :                 }
   14522              :              /* FALLTHRU */
   14523          915 :             case NE:
   14524          915 :               fputs ("neq", file);
   14525          915 :               break;
   14526            0 :             case GE:
   14527            0 :               if (TARGET_AVX)
   14528              :                 {
   14529            0 :                   fputs ("ge", file);
   14530            0 :                   break;
   14531              :                 }
   14532              :              /* FALLTHRU */
   14533          453 :             case UNGE:
   14534          453 :               fputs ("nlt", file);
   14535          453 :               break;
   14536            0 :             case GT:
   14537            0 :               if (TARGET_AVX)
   14538              :                 {
   14539            0 :                   fputs ("gt", file);
   14540            0 :                   break;
   14541              :                 }
   14542              :              /* FALLTHRU */
   14543          799 :             case UNGT:
   14544          799 :               fputs ("nle", file);
   14545          799 :               break;
   14546           83 :             case ORDERED:
   14547           83 :               fputs ("ord", file);
   14548           83 :               break;
   14549            0 :             default:
   14550            0 :               output_operand_lossage ("operand is not a condition code, "
   14551              :                                       "invalid operand code 'D'");
   14552            0 :               return;
   14553              :             }
   14554        10193 :           return;
   14555              : 
   14556      7226679 :         case 'F':
   14557      7226679 :         case 'f':
   14558              : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   14559              :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14560              :             putc ('.', file);
   14561              :           gcc_fallthrough ();
   14562              : #endif
   14563              : 
   14564      7226679 :         case 'C':
   14565      7226679 :         case 'c':
   14566      7226679 :           if (!COMPARISON_P (x))
   14567              :             {
   14568            0 :               output_operand_lossage ("operand is not a condition code, "
   14569              :                                       "invalid operand code '%c'", code);
   14570            0 :               return;
   14571              :             }
   14572      7226679 :           put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
   14573      7226679 :                               code == 'c' || code == 'f',
   14574      7226679 :                               code == 'F' || code == 'f',
   14575              :                               file);
   14576      7226679 :           return;
   14577              : 
   14578           21 :         case 'G':
   14579           21 :           {
   14580           21 :             int dfv = INTVAL (x);
   14581           21 :             const char *dfv_suffix = ix86_ccmp_dfv_mapping[dfv];
   14582           21 :             fputs (dfv_suffix, file);
   14583              :           }
   14584           21 :           return;
   14585              : 
   14586         1292 :         case 'H':
   14587         1292 :           if (!offsettable_memref_p (x))
   14588              :             {
   14589            1 :               output_operand_lossage ("operand is not an offsettable memory "
   14590              :                                       "reference, invalid operand code 'H'");
   14591            1 :               return;
   14592              :             }
   14593              :           /* It doesn't actually matter what mode we use here, as we're
   14594              :              only going to use this for printing.  */
   14595         1291 :           x = adjust_address_nv (x, DImode, 8);
   14596              :           /* Output 'qword ptr' for intel assembler dialect.  */
   14597         1291 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14598            0 :             code = 'q';
   14599              :           break;
   14600              : 
   14601        75841 :         case 'K':
   14602        75841 :           if (!CONST_INT_P (x))
   14603              :             {
   14604            1 :               output_operand_lossage ("operand is not an integer, invalid "
   14605              :                                       "operand code 'K'");
   14606            1 :               return;
   14607              :             }
   14608              : 
   14609        75840 :           if (INTVAL (x) & IX86_HLE_ACQUIRE)
   14610              : #ifdef HAVE_AS_IX86_HLE
   14611           22 :             fputs ("xacquire ", file);
   14612              : #else
   14613              :             fputs ("\n" ASM_BYTE "0xf2\n\t", file);
   14614              : #endif
   14615        75818 :           else if (INTVAL (x) & IX86_HLE_RELEASE)
   14616              : #ifdef HAVE_AS_IX86_HLE
   14617           24 :             fputs ("xrelease ", file);
   14618              : #else
   14619              :             fputs ("\n" ASM_BYTE "0xf3\n\t", file);
   14620              : #endif
   14621              :           /* We do not want to print value of the operand.  */
   14622        75840 :           return;
   14623              : 
   14624        43023 :         case 'N':
   14625        43023 :           if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
   14626        15508 :             fputs ("{z}", file);
   14627        43023 :           return;
   14628              : 
   14629         4054 :         case 'r':
   14630         4054 :           if (!CONST_INT_P (x) || INTVAL (x) != ROUND_SAE)
   14631              :             {
   14632            2 :               output_operand_lossage ("operand is not a specific integer, "
   14633              :                                       "invalid operand code 'r'");
   14634            2 :               return;
   14635              :             }
   14636              : 
   14637         4052 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14638            1 :             fputs (", ", file);
   14639              : 
   14640         4052 :           fputs ("{sae}", file);
   14641              : 
   14642         4052 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14643         4051 :             fputs (", ", file);
   14644              : 
   14645         4052 :           return;
   14646              : 
   14647         5969 :         case 'R':
   14648         5969 :           if (!CONST_INT_P (x))
   14649              :             {
   14650            1 :               output_operand_lossage ("operand is not an integer, invalid "
   14651              :                                       "operand code 'R'");
   14652            1 :               return;
   14653              :             }
   14654              : 
   14655         5968 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14656            6 :             fputs (", ", file);
   14657              : 
   14658         5968 :           switch (INTVAL (x))
   14659              :             {
   14660         5153 :             case ROUND_NEAREST_INT | ROUND_SAE:
   14661         5153 :               fputs ("{rn-sae}", file);
   14662         5153 :               break;
   14663          637 :             case ROUND_NEG_INF | ROUND_SAE:
   14664          637 :               fputs ("{rd-sae}", file);
   14665          637 :               break;
   14666           56 :             case ROUND_POS_INF | ROUND_SAE:
   14667           56 :               fputs ("{ru-sae}", file);
   14668           56 :               break;
   14669          121 :             case ROUND_ZERO | ROUND_SAE:
   14670          121 :               fputs ("{rz-sae}", file);
   14671          121 :               break;
   14672            1 :             default:
   14673            1 :               output_operand_lossage ("operand is not a specific integer, "
   14674              :                                       "invalid operand code 'R'");
   14675              :             }
   14676              : 
   14677         5968 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14678         5962 :             fputs (", ", file);
   14679              : 
   14680         5968 :           return;
   14681              : 
   14682        10522 :         case 'v':
   14683        10522 :           if (MEM_P (x))
   14684              :             {
   14685        10650 :               switch (MEM_ADDR_SPACE (x))
   14686              :                 {
   14687              :                 case ADDR_SPACE_GENERIC:
   14688              :                   break;
   14689            0 :                 case ADDR_SPACE_SEG_FS:
   14690            0 :                   fputs ("fs ", file);
   14691            0 :                   break;
   14692            0 :                 case ADDR_SPACE_SEG_GS:
   14693            0 :                   fputs ("gs ", file);
   14694            0 :                   break;
   14695            0 :                 default:
   14696            0 :                   gcc_unreachable ();
   14697              :                 }
   14698              :             }
   14699              :           else
   14700            0 :             output_operand_lossage ("operand is not a memory reference, "
   14701              :                                     "invalid operand code 'v'");
   14702        10522 :           return;
   14703              : 
   14704            0 :         case '*':
   14705            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14706            0 :             putc ('*', file);
   14707            0 :           return;
   14708              : 
   14709          206 :         case '&':
   14710          206 :           {
   14711          206 :             const char *name = get_some_local_dynamic_name ();
   14712          206 :             if (name == NULL)
   14713            1 :               output_operand_lossage ("'%%&' used without any "
   14714              :                                       "local dynamic TLS references");
   14715              :             else
   14716          205 :               assemble_name (file, name);
   14717          206 :             return;
   14718              :           }
   14719              : 
   14720      6541565 :         case '+':
   14721      6541565 :           {
   14722      6541565 :             rtx x;
   14723              : 
   14724      6541565 :             if (!optimize
   14725      5110043 :                 || optimize_function_for_size_p (cfun)
   14726     11462631 :                 || (!TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN
   14727      4921066 :                     && !TARGET_BRANCH_PREDICTION_HINTS_TAKEN))
   14728      6541565 :               return;
   14729              : 
   14730            0 :             x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
   14731            0 :             if (x)
   14732              :               {
   14733            0 :                 int pred_val = profile_probability::from_reg_br_prob_note
   14734            0 :                                  (XINT (x, 0)).to_reg_br_prob_base ();
   14735              : 
   14736            0 :                 bool taken = pred_val > REG_BR_PROB_BASE / 2;
   14737              :                 /* We use 3e (DS) prefix for taken branches and
   14738              :                    2e (CS) prefix for not taken branches.  */
   14739            0 :                 if (taken && TARGET_BRANCH_PREDICTION_HINTS_TAKEN)
   14740            0 :                   fputs ("ds ; ", file);
   14741            0 :                 else if (!taken && TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN)
   14742            0 :                   fputs ("cs ; ", file);
   14743              :               }
   14744            0 :             return;
   14745              :           }
   14746              : 
   14747              :         case ';':
   14748              : #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
   14749              :           putc (';', file);
   14750              : #endif
   14751              :           return;
   14752              : 
   14753         3264 :         case '~':
   14754         3264 :           putc (TARGET_AVX2 ? 'i' : 'f', file);
   14755         3264 :           return;
   14756              : 
   14757         1678 :         case 'M':
   14758         1678 :           if (TARGET_X32)
   14759              :             {
   14760              :               /* NB: 32-bit indices in VSIB address are sign-extended
   14761              :                  to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
   14762              :                  sign-extended to 0xfffffffff7fa3010 which is invalid
   14763              :                  address.  Add addr32 prefix if there is no base
   14764              :                  register nor symbol.  */
   14765           40 :               bool ok;
   14766           40 :               struct ix86_address parts;
   14767           40 :               ok = ix86_decompose_address (x, &parts);
   14768           40 :               gcc_assert (ok && parts.index == NULL_RTX);
   14769           40 :               if (parts.base == NULL_RTX
   14770           40 :                   && (parts.disp == NULL_RTX
   14771           34 :                       || !symbolic_operand (parts.disp,
   14772           34 :                                             GET_MODE (parts.disp))))
   14773           34 :                 fputs ("addr32 ", file);
   14774              :             }
   14775         1678 :           return;
   14776              : 
   14777        24172 :         case '^':
   14778        27363 :           if (Pmode != word_mode)
   14779            0 :             fputs ("addr32 ", file);
   14780        24172 :           return;
   14781              : 
   14782     14992351 :         case '!':
   14783     14992351 :           if (ix86_notrack_prefixed_insn_p (current_output_insn))
   14784         3891 :             fputs ("notrack ", file);
   14785     14992351 :           return;
   14786              : 
   14787            1 :         default:
   14788            1 :           output_operand_lossage ("invalid operand code '%c'", code);
   14789              :         }
   14790              :     }
   14791              : 
   14792    145360520 :   if (REG_P (x))
   14793     86656667 :     print_reg (x, code, file);
   14794              : 
   14795     58703853 :   else if (MEM_P (x))
   14796              :     {
   14797     33523108 :       rtx addr = XEXP (x, 0);
   14798              : 
   14799              :       /* No `byte ptr' prefix for call instructions ... */
   14800     33523108 :       if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
   14801              :         {
   14802          313 :           machine_mode mode = GET_MODE (x);
   14803          313 :           const char *size;
   14804              : 
   14805              :           /* Check for explicit size override codes.  */
   14806          313 :           if (code == 'b')
   14807              :             size = "BYTE";
   14808              :           else if (code == 'w')
   14809              :             size = "WORD";
   14810              :           else if (code == 'k')
   14811              :             size = "DWORD";
   14812              :           else if (code == 'q')
   14813              :             size = "QWORD";
   14814              :           else if (code == 'x')
   14815              :             size = "XMMWORD";
   14816              :           else if (code == 't')
   14817              :             size = "YMMWORD";
   14818              :           else if (code == 'g')
   14819              :             size = "ZMMWORD";
   14820          227 :           else if (mode == BLKmode)
   14821              :             /* ... or BLKmode operands, when not overridden.  */
   14822              :             size = NULL;
   14823              :           else
   14824          450 :             switch (GET_MODE_SIZE (mode))
   14825              :               {
   14826              :               case 1: size = "BYTE"; break;
   14827              :               case 2: size = "WORD"; break;
   14828              :               case 4: size = "DWORD"; break;
   14829              :               case 8: size = "QWORD"; break;
   14830              :               case 12: size = "TBYTE"; break;
   14831            7 :               case 16:
   14832            7 :                 if (mode == XFmode)
   14833              :                   size = "TBYTE";
   14834              :                 else
   14835              :                   size = "XMMWORD";
   14836              :                 break;
   14837              :               case 32: size = "YMMWORD"; break;
   14838              :               case 64: size = "ZMMWORD"; break;
   14839            0 :               default:
   14840            0 :                 gcc_unreachable ();
   14841              :               }
   14842              :           if (size)
   14843              :             {
   14844          311 :               fputs (size, file);
   14845          311 :               fputs (" PTR ", file);
   14846              :             }
   14847              :         }
   14848              : 
   14849     33523108 :       if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   14850            0 :         output_operand_lossage ("invalid constraints for operand");
   14851              :       else
   14852     33523108 :         ix86_print_operand_address_as
   14853     34073571 :           (file, addr, MEM_ADDR_SPACE (x), code == 'p' || code == 'P');
   14854              :     }
   14855              : 
   14856     25180745 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == HFmode)
   14857              :     {
   14858          975 :       long l = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   14859          975 :                                REAL_MODE_FORMAT (HFmode));
   14860          975 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14861          975 :         putc ('$', file);
   14862          975 :       fprintf (file, "0x%04x", (unsigned int) l);
   14863          975 :     }
   14864              : 
   14865     25179770 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
   14866              :     {
   14867        21254 :       long l;
   14868              : 
   14869        21254 :       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14870              : 
   14871        21254 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14872        21254 :         putc ('$', file);
   14873              :       /* Sign extend 32bit SFmode immediate to 8 bytes.  */
   14874        21254 :       if (code == 'q')
   14875          327 :         fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
   14876              :                  (unsigned long long) (int) l);
   14877              :       else
   14878        20927 :         fprintf (file, "0x%08x", (unsigned int) l);
   14879              :     }
   14880              : 
   14881     25158516 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == DFmode)
   14882              :     {
   14883         3386 :       long l[2];
   14884              : 
   14885         3386 :       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14886              : 
   14887         3386 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14888         3386 :         putc ('$', file);
   14889         3386 :       fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
   14890         3386 :     }
   14891              : 
   14892              :   /* These float cases don't actually occur as immediate operands.  */
   14893     25155130 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == XFmode)
   14894              :     {
   14895            0 :       char dstr[30];
   14896              : 
   14897            0 :       real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
   14898            0 :       fputs (dstr, file);
   14899            0 :     }
   14900              : 
   14901              :   /* Print bcst_mem_operand.  */
   14902     25155130 :   else if (GET_CODE (x) == VEC_DUPLICATE)
   14903              :     {
   14904          314 :       machine_mode vmode = GET_MODE (x);
   14905              :       /* Must be bcst_memory_operand.  */
   14906          314 :       gcc_assert (bcst_mem_operand (x, vmode));
   14907              : 
   14908          314 :       rtx mem = XEXP (x,0);
   14909          314 :       ix86_print_operand (file, mem, 0);
   14910              : 
   14911          314 :       switch (vmode)
   14912              :         {
   14913           28 :         case E_V2DImode:
   14914           28 :         case E_V2DFmode:
   14915           28 :           fputs ("{1to2}", file);
   14916           28 :           break;
   14917           74 :         case E_V4SImode:
   14918           74 :         case E_V4SFmode:
   14919           74 :         case E_V4DImode:
   14920           74 :         case E_V4DFmode:
   14921           74 :           fputs ("{1to4}", file);
   14922           74 :           break;
   14923           94 :         case E_V8SImode:
   14924           94 :         case E_V8SFmode:
   14925           94 :         case E_V8DFmode:
   14926           94 :         case E_V8DImode:
   14927           94 :         case E_V8HFmode:
   14928           94 :           fputs ("{1to8}", file);
   14929           94 :           break;
   14930          110 :         case E_V16SFmode:
   14931          110 :         case E_V16SImode:
   14932          110 :         case E_V16HFmode:
   14933          110 :           fputs ("{1to16}", file);
   14934          110 :           break;
   14935            8 :         case E_V32HFmode:
   14936            8 :           fputs ("{1to32}", file);
   14937            8 :           break;
   14938            0 :         default:
   14939            0 :           gcc_unreachable ();
   14940              :         }
   14941              :     }
   14942              : 
   14943              :   else
   14944              :     {
   14945              :       /* We have patterns that allow zero sets of memory, for instance.
   14946              :          In 64-bit mode, we should probably support all 8-byte vectors,
   14947              :          since we can in fact encode that into an immediate.  */
   14948     25154816 :       if (CONST_VECTOR_P (x))
   14949              :         {
   14950         3327 :           if (x != CONST0_RTX (GET_MODE (x)))
   14951            2 :             output_operand_lossage ("invalid vector immediate");
   14952         3327 :           x = const0_rtx;
   14953              :         }
   14954              : 
   14955     25154816 :       if (code == 'P')
   14956              :         {
   14957      5994106 :           if (ix86_force_load_from_GOT_p (x, true))
   14958              :             {
   14959              :               /* For inline assembly statement, load function address
   14960              :                  from GOT with 'P' operand modifier to avoid PLT.  */
   14961            4 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   14962              :                                   (TARGET_64BIT
   14963              :                                    ? UNSPEC_GOTPCREL
   14964              :                                    : UNSPEC_GOT));
   14965            4 :               x = gen_rtx_CONST (Pmode, x);
   14966            4 :               x = gen_const_mem (Pmode, x);
   14967            4 :               ix86_print_operand (file, x, 'A');
   14968            4 :               return;
   14969              :             }
   14970              :         }
   14971     19160710 :       else if (code != 'p')
   14972              :         {
   14973     19160601 :           if (CONST_INT_P (x))
   14974              :             {
   14975     15816648 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14976     15816436 :                 putc ('$', file);
   14977              :             }
   14978      3343953 :           else if (GET_CODE (x) == CONST || SYMBOL_REF_P (x)
   14979         9409 :                    || LABEL_REF_P (x))
   14980              :             {
   14981      3343951 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14982      3343927 :                 putc ('$', file);
   14983              :               else
   14984           24 :                 fputs ("OFFSET FLAT:", file);
   14985              :             }
   14986              :         }
   14987     25154812 :       if (CONST_INT_P (x))
   14988     15816734 :         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
   14989      9338078 :       else if (flag_pic || MACHOPIC_INDIRECT)
   14990       524773 :         output_pic_addr_const (file, x, code);
   14991              :       else
   14992      8813305 :         output_addr_const (file, x);
   14993              :     }
   14994              : }
   14995              : 
   14996              : static bool
   14997     21644270 : ix86_print_operand_punct_valid_p (unsigned char code)
   14998              : {
   14999     21644270 :   return (code == '*' || code == '+' || code == '&' || code == ';'
   15000     15016523 :           || code == '~' || code == '^' || code == '!');
   15001              : }
   15002              : 
   15003              : /* Print a memory operand whose address is ADDR.  */
   15004              : 
   15005              : static void
   15006     37125224 : ix86_print_operand_address_as (FILE *file, rtx addr,
   15007              :                                addr_space_t as, bool raw)
   15008              : {
   15009     37125224 :   struct ix86_address parts;
   15010     37125224 :   rtx base, index, disp;
   15011     37125224 :   int scale;
   15012     37125224 :   int ok;
   15013     37125224 :   bool vsib = false;
   15014     37125224 :   int code = 0;
   15015              : 
   15016     37125224 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
   15017              :     {
   15018         1678 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   15019         1678 :       gcc_assert (parts.index == NULL_RTX);
   15020         1678 :       parts.index = XVECEXP (addr, 0, 1);
   15021         1678 :       parts.scale = INTVAL (XVECEXP (addr, 0, 2));
   15022         1678 :       addr = XVECEXP (addr, 0, 0);
   15023         1678 :       vsib = true;
   15024              :     }
   15025     37123546 :   else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
   15026              :     {
   15027      3114154 :       gcc_assert (TARGET_64BIT);
   15028      3114154 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   15029      3114154 :       code = 'q';
   15030              :     }
   15031              :   else
   15032     34009392 :     ok = ix86_decompose_address (addr, &parts);
   15033              : 
   15034     37125224 :   gcc_assert (ok);
   15035              : 
   15036     37125224 :   base = parts.base;
   15037     37125224 :   index = parts.index;
   15038     37125224 :   disp = parts.disp;
   15039     37125224 :   scale = parts.scale;
   15040              : 
   15041     37125224 :   if (ADDR_SPACE_GENERIC_P (as))
   15042     36843173 :     as = parts.seg;
   15043              :   else
   15044       282051 :     gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg));
   15045              : 
   15046     37125224 :   if (!ADDR_SPACE_GENERIC_P (as) && !raw)
   15047              :     {
   15048       282066 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   15049       282064 :         putc ('%', file);
   15050              : 
   15051       282066 :       switch (as)
   15052              :         {
   15053       182327 :         case ADDR_SPACE_SEG_FS:
   15054       182327 :           fputs ("fs:", file);
   15055       182327 :           break;
   15056        99739 :         case ADDR_SPACE_SEG_GS:
   15057        99739 :           fputs ("gs:", file);
   15058        99739 :           break;
   15059            0 :         default:
   15060            0 :           gcc_unreachable ();
   15061              :         }
   15062              :     }
   15063              : 
   15064              :   /* Use one byte shorter RIP relative addressing for 64bit mode.  */
   15065     37125224 :   if (TARGET_64BIT && !base && !index && !raw)
   15066              :     {
   15067      6029922 :       rtx symbol = disp;
   15068              : 
   15069      6029922 :       if (GET_CODE (disp) == CONST
   15070      2183948 :           && GET_CODE (XEXP (disp, 0)) == PLUS
   15071      2098767 :           && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   15072      2098767 :         symbol = XEXP (XEXP (disp, 0), 0);
   15073              : 
   15074      6029922 :       if (LABEL_REF_P (symbol)
   15075      6029922 :           || (SYMBOL_REF_P (symbol)
   15076      5768298 :               && SYMBOL_REF_TLS_MODEL (symbol) == 0))
   15077      5768168 :         base = pc_rtx;
   15078              :     }
   15079              : 
   15080     37125224 :   if (!base && !index)
   15081              :     {
   15082              :       /* Displacement only requires special attention.  */
   15083       601430 :       if (CONST_INT_P (disp))
   15084              :         {
   15085       269435 :           if (ASSEMBLER_DIALECT == ASM_INTEL && ADDR_SPACE_GENERIC_P (as))
   15086            0 :             fputs ("ds:", file);
   15087       269435 :           fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
   15088              :         }
   15089              :       /* Load the external function address via the GOT slot to avoid PLT.  */
   15090       331995 :       else if (GET_CODE (disp) == CONST
   15091       113615 :                && GET_CODE (XEXP (disp, 0)) == UNSPEC
   15092        85418 :                && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
   15093         9626 :                    || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
   15094       407787 :                && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   15095           24 :         output_pic_addr_const (file, disp, 0);
   15096       331971 :       else if (flag_pic)
   15097       114897 :         output_pic_addr_const (file, disp, 0);
   15098              :       else
   15099       217074 :         output_addr_const (file, disp);
   15100              :     }
   15101              :   else
   15102              :     {
   15103              :       /* Print SImode register names to force addr32 prefix.  */
   15104     36523794 :       if (SImode_address_operand (addr, VOIDmode))
   15105              :         {
   15106           51 :           if (flag_checking)
   15107              :             {
   15108           51 :               gcc_assert (TARGET_64BIT);
   15109           51 :               switch (GET_CODE (addr))
   15110              :                 {
   15111            0 :                 case SUBREG:
   15112            0 :                   gcc_assert (GET_MODE (addr) == SImode);
   15113            0 :                   gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
   15114              :                   break;
   15115           51 :                 case ZERO_EXTEND:
   15116           51 :                 case AND:
   15117           51 :                   gcc_assert (GET_MODE (addr) == DImode);
   15118              :                   break;
   15119            0 :                 default:
   15120            0 :                   gcc_unreachable ();
   15121              :                 }
   15122              :             }
   15123           51 :           gcc_assert (!code);
   15124              :           code = 'k';
   15125              :         }
   15126     36523743 :       else if (code == 0
   15127     33411234 :                && TARGET_X32
   15128          539 :                && disp
   15129          448 :                && CONST_INT_P (disp)
   15130          349 :                && INTVAL (disp) < -16*1024*1024)
   15131              :         {
   15132              :           /* X32 runs in 64-bit mode, where displacement, DISP, in
   15133              :              address DISP(%r64), is encoded as 32-bit immediate sign-
   15134              :              extended from 32-bit to 64-bit.  For -0x40000300(%r64),
   15135              :              address is %r64 + 0xffffffffbffffd00.  When %r64 <
   15136              :              0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
   15137              :              which is invalid for x32.  The correct address is %r64
   15138              :              - 0x40000300 == 0xf7ffdd64.  To properly encode
   15139              :              -0x40000300(%r64) for x32, we zero-extend negative
   15140              :              displacement by forcing addr32 prefix which truncates
   15141              :              0xfffffffff7ffdd64 to 0xf7ffdd64.  In theory, we should
   15142              :              zero-extend all negative displacements, including -1(%rsp).
   15143              :              However, for small negative displacements, sign-extension
   15144              :              won't cause overflow.  We only zero-extend negative
   15145              :              displacements if they < -16*1024*1024, which is also used
   15146              :              to check legitimate address displacements for PIC.  */
   15147           51 :           code = 'k';
   15148              :         }
   15149              : 
   15150              :       /* Since the upper 32 bits of RSP are always zero for x32,
   15151              :          we can encode %esp as %rsp to avoid 0x67 prefix if
   15152              :          there is no index register.  */
   15153         1089 :       if (TARGET_X32 && Pmode == SImode
   15154     36524255 :           && !index && base && REG_P (base) && REGNO (base) == SP_REG)
   15155              :         code = 'q';
   15156              : 
   15157     36523794 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   15158              :         {
   15159     36523432 :           if (disp)
   15160              :             {
   15161     32450420 :               if (flag_pic)
   15162      2830003 :                 output_pic_addr_const (file, disp, 0);
   15163     29620417 :               else if (LABEL_REF_P (disp))
   15164         5324 :                 output_asm_label (disp);
   15165              :               else
   15166     29615093 :                 output_addr_const (file, disp);
   15167              :             }
   15168              : 
   15169     36523432 :           putc ('(', file);
   15170     36523432 :           if (base)
   15171     36103299 :             print_reg (base, code, file);
   15172     36523432 :           if (index)
   15173              :             {
   15174      1887567 :               putc (',', file);
   15175      3773504 :               print_reg (index, vsib ? 0 : code, file);
   15176      1887567 :               if (scale != 1 || vsib)
   15177      1026066 :                 fprintf (file, ",%d", scale);
   15178              :             }
   15179     36523432 :           putc (')', file);
   15180              :         }
   15181              :       else
   15182              :         {
   15183          362 :           rtx offset = NULL_RTX;
   15184              : 
   15185          362 :           if (disp)
   15186              :             {
   15187              :               /* Pull out the offset of a symbol; print any symbol itself.  */
   15188          282 :               if (GET_CODE (disp) == CONST
   15189           14 :                   && GET_CODE (XEXP (disp, 0)) == PLUS
   15190           14 :                   && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   15191              :                 {
   15192           14 :                   offset = XEXP (XEXP (disp, 0), 1);
   15193           14 :                   disp = gen_rtx_CONST (VOIDmode,
   15194              :                                         XEXP (XEXP (disp, 0), 0));
   15195              :                 }
   15196              : 
   15197          282 :               if (flag_pic)
   15198            0 :                 output_pic_addr_const (file, disp, 0);
   15199          282 :               else if (LABEL_REF_P (disp))
   15200            0 :                 output_asm_label (disp);
   15201          282 :               else if (CONST_INT_P (disp))
   15202              :                 offset = disp;
   15203              :               else
   15204          115 :                 output_addr_const (file, disp);
   15205              :             }
   15206              : 
   15207          362 :           putc ('[', file);
   15208          362 :           if (base)
   15209              :             {
   15210          325 :               print_reg (base, code, file);
   15211          325 :               if (offset)
   15212              :                 {
   15213          181 :                   if (INTVAL (offset) >= 0)
   15214           20 :                     putc ('+', file);
   15215          181 :                   fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   15216              :                 }
   15217              :             }
   15218           37 :           else if (offset)
   15219            0 :             fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   15220              :           else
   15221           37 :             putc ('0', file);
   15222              : 
   15223          362 :           if (index)
   15224              :             {
   15225           90 :               putc ('+', file);
   15226          132 :               print_reg (index, vsib ? 0 : code, file);
   15227           90 :               if (scale != 1 || vsib)
   15228           88 :                 fprintf (file, "*%d", scale);
   15229              :             }
   15230          362 :           putc (']', file);
   15231              :         }
   15232              :     }
   15233     37125224 : }
   15234              : 
   15235              : static void
   15236      3602117 : ix86_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   15237              : {
   15238      3602117 :   if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   15239            1 :     output_operand_lossage ("invalid constraints for operand");
   15240              :   else
   15241      3602116 :     ix86_print_operand_address_as (file, addr, ADDR_SPACE_GENERIC, false);
   15242      3602117 : }
   15243              : 
   15244              : /* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA.  */
   15245              : 
   15246              : static bool
   15247        15503 : i386_asm_output_addr_const_extra (FILE *file, rtx x)
   15248              : {
   15249        15503 :   rtx op;
   15250              : 
   15251        15503 :   if (GET_CODE (x) != UNSPEC)
   15252              :     return false;
   15253              : 
   15254        15503 :   op = XVECEXP (x, 0, 0);
   15255        15503 :   switch (XINT (x, 1))
   15256              :     {
   15257         1293 :     case UNSPEC_GOTOFF:
   15258         1293 :       output_addr_const (file, op);
   15259         1293 :       fputs ("@gotoff", file);
   15260         1293 :       break;
   15261            0 :     case UNSPEC_GOTTPOFF:
   15262            0 :       output_addr_const (file, op);
   15263              :       /* FIXME: This might be @TPOFF in Sun ld.  */
   15264            0 :       fputs ("@gottpoff", file);
   15265            0 :       break;
   15266            0 :     case UNSPEC_TPOFF:
   15267            0 :       output_addr_const (file, op);
   15268            0 :       fputs ("@tpoff", file);
   15269            0 :       break;
   15270        11113 :     case UNSPEC_NTPOFF:
   15271        11113 :       output_addr_const (file, op);
   15272        11113 :       if (TARGET_64BIT)
   15273        10337 :         fputs ("@tpoff", file);
   15274              :       else
   15275          776 :         fputs ("@ntpoff", file);
   15276              :       break;
   15277            0 :     case UNSPEC_DTPOFF:
   15278            0 :       output_addr_const (file, op);
   15279            0 :       fputs ("@dtpoff", file);
   15280            0 :       break;
   15281         3096 :     case UNSPEC_GOTNTPOFF:
   15282         3096 :       output_addr_const (file, op);
   15283         3096 :       if (TARGET_64BIT)
   15284         3096 :         fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   15285              :                "@gottpoff(%rip)" : "@gottpoff[rip]", file);
   15286              :       else
   15287            0 :         fputs ("@gotntpoff", file);
   15288              :       break;
   15289            1 :     case UNSPEC_INDNTPOFF:
   15290            1 :       output_addr_const (file, op);
   15291            1 :       fputs ("@indntpoff", file);
   15292            1 :       break;
   15293            0 :     case UNSPEC_SECREL32:
   15294            0 :       output_addr_const (file, op);
   15295            0 :       fputs ("@secrel32", file);
   15296            0 :       break;
   15297              : #if TARGET_MACHO
   15298              :     case UNSPEC_MACHOPIC_OFFSET:
   15299              :       output_addr_const (file, op);
   15300              :       putc ('-', file);
   15301              :       machopic_output_function_base_name (file);
   15302              :       break;
   15303              : #endif
   15304              : 
   15305              :     default:
   15306              :       return false;
   15307              :     }
   15308              : 
   15309              :   return true;
   15310              : }
   15311              : 
   15312              : 
   15313              : /* Output code to perform a 387 binary operation in INSN, one of PLUS,
   15314              :    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
   15315              :    is the expression of the binary operation.  The output may either be
   15316              :    emitted here, or returned to the caller, like all output_* functions.
   15317              : 
   15318              :    There is no guarantee that the operands are the same mode, as they
   15319              :    might be within FLOAT or FLOAT_EXTEND expressions.  */
   15320              : 
   15321              : #ifndef SYSV386_COMPAT
   15322              : /* Set to 1 for compatibility with brain-damaged assemblers.  No-one
   15323              :    wants to fix the assemblers because that causes incompatibility
   15324              :    with gcc.  No-one wants to fix gcc because that causes
   15325              :    incompatibility with assemblers...  You can use the option of
   15326              :    -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way.  */
   15327              : #define SYSV386_COMPAT 1
   15328              : #endif
   15329              : 
   15330              : const char *
   15331       606955 : output_387_binary_op (rtx_insn *insn, rtx *operands)
   15332              : {
   15333       606955 :   static char buf[40];
   15334       606955 :   const char *p;
   15335       606955 :   bool is_sse
   15336       606955 :     = (SSE_REG_P (operands[0])
   15337       663098 :        || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]));
   15338              : 
   15339        56143 :   if (is_sse)
   15340              :     p = "%v";
   15341        56143 :   else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
   15342        56136 :            || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
   15343              :     p = "fi";
   15344              :   else
   15345       606955 :     p = "f";
   15346              : 
   15347       606955 :   strcpy (buf, p);
   15348              : 
   15349       606955 :   switch (GET_CODE (operands[3]))
   15350              :     {
   15351              :     case PLUS:
   15352              :       p = "add"; break;
   15353              :     case MINUS:
   15354              :       p = "sub"; break;
   15355        94572 :     case MULT:
   15356        94572 :       p = "mul"; break;
   15357        27472 :     case DIV:
   15358        27472 :       p = "div"; break;
   15359            0 :     default:
   15360            0 :       gcc_unreachable ();
   15361              :     }
   15362              : 
   15363       606955 :   strcat (buf, p);
   15364              : 
   15365       606955 :   if (is_sse)
   15366              :    {
   15367       550812 :      p = GET_MODE (operands[0]) == SFmode ? "ss" : "sd";
   15368       550812 :      strcat (buf, p);
   15369              : 
   15370       550812 :      if (TARGET_AVX)
   15371              :        p = "\t{%2, %1, %0|%0, %1, %2}";
   15372              :      else
   15373       535400 :        p = "\t{%2, %0|%0, %2}";
   15374              : 
   15375       550812 :      strcat (buf, p);
   15376       550812 :      return buf;
   15377              :    }
   15378              : 
   15379              :   /* Even if we do not want to check the inputs, this documents input
   15380              :      constraints.  Which helps in understanding the following code.  */
   15381        56143 :   if (flag_checking)
   15382              :     {
   15383        56142 :       if (STACK_REG_P (operands[0])
   15384        56142 :           && ((REG_P (operands[1])
   15385        54489 :                && REGNO (operands[0]) == REGNO (operands[1])
   15386        50376 :                && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
   15387         5766 :               || (REG_P (operands[2])
   15388         5766 :                   && REGNO (operands[0]) == REGNO (operands[2])
   15389         5766 :                   && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
   15390       112284 :           && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
   15391              :         ; /* ok */
   15392              :       else
   15393            0 :         gcc_unreachable ();
   15394              :     }
   15395              : 
   15396        56143 :   switch (GET_CODE (operands[3]))
   15397              :     {
   15398        41041 :     case MULT:
   15399        41041 :     case PLUS:
   15400        41041 :       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
   15401         2059 :         std::swap (operands[1], operands[2]);
   15402              : 
   15403              :       /* know operands[0] == operands[1].  */
   15404              : 
   15405        41041 :       if (MEM_P (operands[2]))
   15406              :         {
   15407              :           p = "%Z2\t%2";
   15408              :           break;
   15409              :         }
   15410              : 
   15411        36604 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   15412              :         {
   15413        21355 :           if (STACK_TOP_P (operands[0]))
   15414              :             /* How is it that we are storing to a dead operand[2]?
   15415              :                Well, presumably operands[1] is dead too.  We can't
   15416              :                store the result to st(0) as st(0) gets popped on this
   15417              :                instruction.  Instead store to operands[2] (which I
   15418              :                think has to be st(1)).  st(1) will be popped later.
   15419              :                gcc <= 2.8.1 didn't have this check and generated
   15420              :                assembly code that the Unixware assembler rejected.  */
   15421              :             p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
   15422              :           else
   15423              :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   15424              :           break;
   15425              :         }
   15426              : 
   15427        15249 :       if (STACK_TOP_P (operands[0]))
   15428              :         p = "\t{%y2, %0|%0, %y2}";    /* st(0) = st(0) op st(r2) */
   15429              :       else
   15430              :         p = "\t{%2, %0|%0, %2}";      /* st(r1) = st(r1) op st(0) */
   15431              :       break;
   15432              : 
   15433        15102 :     case MINUS:
   15434        15102 :     case DIV:
   15435        15102 :       if (MEM_P (operands[1]))
   15436              :         {
   15437              :           p = "r%Z1\t%1";
   15438              :           break;
   15439              :         }
   15440              : 
   15441        14640 :       if (MEM_P (operands[2]))
   15442              :         {
   15443              :           p = "%Z2\t%2";
   15444              :           break;
   15445              :         }
   15446              : 
   15447        13030 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   15448              :         {
   15449              : #if SYSV386_COMPAT
   15450              :           /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
   15451              :              derived assemblers, confusingly reverse the direction of
   15452              :              the operation for fsub{r} and fdiv{r} when the
   15453              :              destination register is not st(0).  The Intel assembler
   15454              :              doesn't have this brain damage.  Read !SYSV386_COMPAT to
   15455              :              figure out what the hardware really does.  */
   15456         6269 :           if (STACK_TOP_P (operands[0]))
   15457              :             p = "{p\t%0, %2|rp\t%2, %0}";
   15458              :           else
   15459              :             p = "{rp\t%2, %0|p\t%0, %2}";
   15460              : #else
   15461              :           if (STACK_TOP_P (operands[0]))
   15462              :             /* As above for fmul/fadd, we can't store to st(0).  */
   15463              :             p = "rp\t{%0, %2|%2, %0}";        /* st(1) = st(0) op st(1); pop */
   15464              :           else
   15465              :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   15466              : #endif
   15467              :           break;
   15468              :         }
   15469              : 
   15470         6761 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   15471              :         {
   15472              : #if SYSV386_COMPAT
   15473         3146 :           if (STACK_TOP_P (operands[0]))
   15474              :             p = "{rp\t%0, %1|p\t%1, %0}";
   15475              :           else
   15476              :             p = "{p\t%1, %0|rp\t%0, %1}";
   15477              : #else
   15478              :           if (STACK_TOP_P (operands[0]))
   15479              :             p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
   15480              :           else
   15481              :             p = "rp\t{%1, %0|%0, %1}";        /* st(r2) = st(0) op st(r2); pop */
   15482              : #endif
   15483              :           break;
   15484              :         }
   15485              : 
   15486         3615 :       if (STACK_TOP_P (operands[0]))
   15487              :         {
   15488         2737 :           if (STACK_TOP_P (operands[1]))
   15489              :             p = "\t{%y2, %0|%0, %y2}";        /* st(0) = st(0) op st(r2) */
   15490              :           else
   15491              :             p = "r\t{%y1, %0|%0, %y1}";       /* st(0) = st(r1) op st(0) */
   15492              :           break;
   15493              :         }
   15494          878 :       else if (STACK_TOP_P (operands[1]))
   15495              :         {
   15496              : #if SYSV386_COMPAT
   15497              :           p = "{\t%1, %0|r\t%0, %1}";
   15498              : #else
   15499              :           p = "r\t{%1, %0|%0, %1}";   /* st(r2) = st(0) op st(r2) */
   15500              : #endif
   15501              :         }
   15502              :       else
   15503              :         {
   15504              : #if SYSV386_COMPAT
   15505              :           p = "{r\t%2, %0|\t%0, %2}";
   15506              : #else
   15507              :           p = "\t{%2, %0|%0, %2}";    /* st(r1) = st(r1) op st(0) */
   15508              : #endif
   15509              :         }
   15510              :       break;
   15511              : 
   15512            0 :     default:
   15513            0 :       gcc_unreachable ();
   15514              :     }
   15515              : 
   15516        56143 :   strcat (buf, p);
   15517        56143 :   return buf;
   15518              : }
   15519              : 
   15520              : /* Return needed mode for entity in optimize_mode_switching pass.  */
   15521              : 
   15522              : static int
   15523         1656 : ix86_dirflag_mode_needed (rtx_insn *insn)
   15524              : {
   15525         1656 :   if (CALL_P (insn))
   15526              :     {
   15527          339 :       if (cfun->machine->func_type == TYPE_NORMAL)
   15528              :         return X86_DIRFLAG_ANY;
   15529              :       else
   15530              :         /* No need to emit CLD in interrupt handler for TARGET_CLD.  */
   15531          339 :         return TARGET_CLD ? X86_DIRFLAG_ANY : X86_DIRFLAG_RESET;
   15532              :     }
   15533              : 
   15534         1317 :   if (recog_memoized (insn) < 0)
   15535              :     return X86_DIRFLAG_ANY;
   15536              : 
   15537         1315 :   if (get_attr_type (insn) == TYPE_STR)
   15538              :     {
   15539              :       /* Emit cld instruction if stringops are used in the function.  */
   15540            1 :       if (cfun->machine->func_type == TYPE_NORMAL)
   15541            0 :         return TARGET_CLD ? X86_DIRFLAG_RESET : X86_DIRFLAG_ANY;
   15542              :       else
   15543              :         return X86_DIRFLAG_RESET;
   15544              :     }
   15545              : 
   15546              :   return X86_DIRFLAG_ANY;
   15547              : }
   15548              : 
   15549              : /* Check if a 256bit or 512 bit AVX register is referenced inside of EXP.   */
   15550              : 
   15551              : static bool
   15552      2219274 : ix86_check_avx_upper_register (const_rtx exp)
   15553              : {
   15554              :   /* construct_container may return a parallel with expr_list
   15555              :      which contains the real reg and mode  */
   15556      2219274 :   subrtx_iterator::array_type array;
   15557      8497087 :   FOR_EACH_SUBRTX (iter, array, exp, NONCONST)
   15558              :     {
   15559      6438494 :       const_rtx x = *iter;
   15560      2585314 :       if (SSE_REG_P (x)
   15561       834735 :           && !EXT_REX_SSE_REG_P (x)
   15562      8095816 :           && GET_MODE_BITSIZE (GET_MODE (x)) > 128)
   15563       160681 :         return true;
   15564              :     }
   15565              : 
   15566      2058593 :   return false;
   15567      2219274 : }
   15568              : 
   15569              : /* Check if a 256bit or 512bit AVX register is referenced in stores.   */
   15570              : 
   15571              : static void
   15572        51283 : ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
   15573              : {
   15574        51283 :   if (SSE_REG_P (dest)
   15575        12741 :       && !EXT_REX_SSE_REG_P (dest)
   15576        76765 :       && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
   15577              :     {
   15578          754 :       bool *used = (bool *) data;
   15579          754 :       *used = true;
   15580              :     }
   15581        51283 : }
   15582              : 
   15583              : /* Return needed mode for entity in optimize_mode_switching pass.  */
   15584              : 
   15585              : static int
   15586      2071935 : ix86_avx_u128_mode_needed (rtx_insn *insn)
   15587              : {
   15588      2071935 :   if (DEBUG_INSN_P (insn))
   15589              :     return AVX_U128_ANY;
   15590              : 
   15591      2071935 :   if (CALL_P (insn))
   15592              :     {
   15593        49777 :       rtx link;
   15594              : 
   15595              :       /* Needed mode is set to AVX_U128_CLEAN if there are
   15596              :          no 256bit or 512bit modes used in function arguments. */
   15597        49777 :       for (link = CALL_INSN_FUNCTION_USAGE (insn);
   15598       136378 :            link;
   15599        86601 :            link = XEXP (link, 1))
   15600              :         {
   15601        87647 :           if (GET_CODE (XEXP (link, 0)) == USE)
   15602              :             {
   15603        86308 :               rtx arg = XEXP (XEXP (link, 0), 0);
   15604              : 
   15605        86308 :               if (ix86_check_avx_upper_register (arg))
   15606              :                 return AVX_U128_DIRTY;
   15607              :             }
   15608              :         }
   15609              : 
   15610              :       /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit
   15611              :          nor 512bit registers used in the function return register.  */
   15612        48731 :       bool avx_upper_reg_found = false;
   15613        48731 :       note_stores (insn, ix86_check_avx_upper_stores,
   15614              :                    &avx_upper_reg_found);
   15615        48731 :       if (avx_upper_reg_found)
   15616              :         return AVX_U128_DIRTY;
   15617              : 
   15618              :       /* If the function is known to preserve some SSE registers,
   15619              :          RA and previous passes can legitimately rely on that for
   15620              :          modes wider than 256 bits.  It's only safe to issue a
   15621              :          vzeroupper if all SSE registers are clobbered.  */
   15622        48547 :       const function_abi &abi = insn_callee_abi (insn);
   15623        48547 :       if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
   15624              :           /* Should be safe to issue an vzeroupper before sibling_call_p.
   15625              :              Also there not mode_exit for sibling_call, so there could be
   15626              :              missing vzeroupper for that.  */
   15627        48547 :           || !(SIBLING_CALL_P (insn)
   15628        47261 :                || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15629        47261 :                                          abi.mode_clobbers (V4DImode))))
   15630         8425 :         return AVX_U128_ANY;
   15631              : 
   15632        40122 :       return AVX_U128_CLEAN;
   15633              :     }
   15634              : 
   15635      2022158 :   rtx set = single_set (insn);
   15636      2022158 :   if (set)
   15637              :     {
   15638      1949242 :       rtx dest = SET_DEST (set);
   15639      1949242 :       rtx src = SET_SRC (set);
   15640      1467931 :       if (SSE_REG_P (dest)
   15641       553443 :           && !EXT_REX_SSE_REG_P (dest)
   15642      3044556 :           && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
   15643              :         {
   15644              :           /* This is an YMM/ZMM load.  Return AVX_U128_DIRTY if the
   15645              :              source isn't zero.  */
   15646       169055 :           if (standard_sse_constant_p (src, GET_MODE (dest)) != 1)
   15647              :             return AVX_U128_DIRTY;
   15648              :           else
   15649              :             return AVX_U128_ANY;
   15650              :         }
   15651              :       else
   15652              :         {
   15653      1780187 :           if (ix86_check_avx_upper_register (src))
   15654              :             return AVX_U128_DIRTY;
   15655              :         }
   15656              : 
   15657              :       /* This isn't YMM/ZMM load/store.  */
   15658              :       return AVX_U128_ANY;
   15659              :     }
   15660              : 
   15661              :   /* Require DIRTY mode if a 256bit or 512bit AVX register is referenced.
   15662              :      Hardware changes state only when a 256bit register is written to,
   15663              :      but we need to prevent the compiler from moving optimal insertion
   15664              :      point above eventual read from 256bit or 512 bit register.  */
   15665        72916 :   if (ix86_check_avx_upper_register (PATTERN (insn)))
   15666              :     return AVX_U128_DIRTY;
   15667              : 
   15668              :   return AVX_U128_ANY;
   15669              : }
   15670              : 
   15671              : /* Return mode that i387 must be switched into
   15672              :    prior to the execution of insn.  */
   15673              : 
   15674              : static int
   15675       422541 : ix86_i387_mode_needed (int entity, rtx_insn *insn)
   15676              : {
   15677       422541 :   enum attr_i387_cw mode;
   15678              : 
   15679              :   /* The mode UNINITIALIZED is used to store control word after a
   15680              :      function call or ASM pattern.  The mode ANY specify that function
   15681              :      has no requirements on the control word and make no changes in the
   15682              :      bits we are interested in.  */
   15683              : 
   15684       422541 :   if (CALL_P (insn)
   15685       422541 :       || (NONJUMP_INSN_P (insn)
   15686       345848 :           && (asm_noperands (PATTERN (insn)) >= 0
   15687       345795 :               || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
   15688        15025 :     return I387_CW_UNINITIALIZED;
   15689              : 
   15690       407516 :   if (recog_memoized (insn) < 0)
   15691              :     return I387_CW_ANY;
   15692              : 
   15693       406574 :   mode = get_attr_i387_cw (insn);
   15694              : 
   15695       406574 :   switch (entity)
   15696              :     {
   15697            0 :     case I387_ROUNDEVEN:
   15698            0 :       if (mode == I387_CW_ROUNDEVEN)
   15699              :         return mode;
   15700              :       break;
   15701              : 
   15702       401911 :     case I387_TRUNC:
   15703       401911 :       if (mode == I387_CW_TRUNC)
   15704              :         return mode;
   15705              :       break;
   15706              : 
   15707         3628 :     case I387_FLOOR:
   15708         3628 :       if (mode == I387_CW_FLOOR)
   15709              :         return mode;
   15710              :       break;
   15711              : 
   15712         1035 :     case I387_CEIL:
   15713         1035 :       if (mode == I387_CW_CEIL)
   15714              :         return mode;
   15715              :       break;
   15716              : 
   15717            0 :     default:
   15718            0 :       gcc_unreachable ();
   15719              :     }
   15720              : 
   15721              :   return I387_CW_ANY;
   15722              : }
   15723              : 
   15724              : /* Return mode that entity must be switched into
   15725              :    prior to the execution of insn.  */
   15726              : 
   15727              : static int
   15728      2496132 : ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
   15729              : {
   15730      2496132 :   switch (entity)
   15731              :     {
   15732         1656 :     case X86_DIRFLAG:
   15733         1656 :       return ix86_dirflag_mode_needed (insn);
   15734      2071935 :     case AVX_U128:
   15735      2071935 :       return ix86_avx_u128_mode_needed (insn);
   15736       422541 :     case I387_ROUNDEVEN:
   15737       422541 :     case I387_TRUNC:
   15738       422541 :     case I387_FLOOR:
   15739       422541 :     case I387_CEIL:
   15740       422541 :       return ix86_i387_mode_needed (entity, insn);
   15741            0 :     default:
   15742            0 :       gcc_unreachable ();
   15743              :     }
   15744              :   return 0;
   15745              : }
   15746              : 
   15747              : /* Calculate mode of upper 128bit AVX registers after the insn.  */
   15748              : 
   15749              : static int
   15750      2071935 : ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
   15751              : {
   15752      2071935 :   rtx pat = PATTERN (insn);
   15753              : 
   15754      2071935 :   if (vzeroupper_pattern (pat, VOIDmode)
   15755      2071935 :       || vzeroall_pattern (pat, VOIDmode))
   15756          161 :     return AVX_U128_CLEAN;
   15757              : 
   15758              :   /* We know that state is clean after CALL insn if there are no
   15759              :      256bit or 512bit registers used in the function return register. */
   15760      2071774 :   if (CALL_P (insn))
   15761              :     {
   15762        49731 :       bool avx_upper_reg_found = false;
   15763        49731 :       note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found);
   15764              : 
   15765        49731 :       if (avx_upper_reg_found)
   15766              :         return AVX_U128_DIRTY;
   15767              : 
   15768              :       /* If the function doesn't clobber any sse registers or only clobber
   15769              :          128-bit part, Then vzeroupper isn't issued before the function exit.
   15770              :          the status not CLEAN but ANY after the function.  */
   15771        49161 :       const function_abi &abi = insn_callee_abi (insn);
   15772        49161 :       if (!(SIBLING_CALL_P (insn)
   15773        47880 :             || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15774        47880 :                                       abi.mode_clobbers (V4DImode))))
   15775         8721 :         return AVX_U128_ANY;
   15776              : 
   15777        40440 :       return  AVX_U128_CLEAN;
   15778              :     }
   15779              : 
   15780              :   /* Otherwise, return current mode.  Remember that if insn
   15781              :      references AVX 256bit or 512bit registers, the mode was already
   15782              :      changed to DIRTY from MODE_NEEDED.  */
   15783              :   return mode;
   15784              : }
   15785              : 
   15786              : /* Return the mode that an insn results in.  */
   15787              : 
   15788              : static int
   15789      2495287 : ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
   15790              : {
   15791      2495287 :   switch (entity)
   15792              :     {
   15793              :     case X86_DIRFLAG:
   15794              :       return mode;
   15795      2071935 :     case AVX_U128:
   15796      2071935 :       return ix86_avx_u128_mode_after (mode, insn);
   15797              :     case I387_ROUNDEVEN:
   15798              :     case I387_TRUNC:
   15799              :     case I387_FLOOR:
   15800              :     case I387_CEIL:
   15801              :       return mode;
   15802            0 :     default:
   15803            0 :       gcc_unreachable ();
   15804              :     }
   15805              : }
   15806              : 
   15807              : static int
   15808          120 : ix86_dirflag_mode_entry (void)
   15809              : {
   15810              :   /* For TARGET_CLD or in the interrupt handler we can't assume
   15811              :      direction flag state at function entry.  */
   15812          120 :   if (TARGET_CLD
   15813          118 :       || cfun->machine->func_type != TYPE_NORMAL)
   15814          120 :     return X86_DIRFLAG_ANY;
   15815              : 
   15816              :   return X86_DIRFLAG_RESET;
   15817              : }
   15818              : 
   15819              : static int
   15820       123119 : ix86_avx_u128_mode_entry (void)
   15821              : {
   15822       123119 :   tree arg;
   15823              : 
   15824              :   /* Entry mode is set to AVX_U128_DIRTY if there are
   15825              :      256bit or 512bit modes used in function arguments.  */
   15826       310992 :   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
   15827       187873 :        arg = TREE_CHAIN (arg))
   15828              :     {
   15829       221822 :       rtx incoming = DECL_INCOMING_RTL (arg);
   15830              : 
   15831       221822 :       if (incoming && ix86_check_avx_upper_register (incoming))
   15832              :         return AVX_U128_DIRTY;
   15833              :     }
   15834              : 
   15835              :   return AVX_U128_CLEAN;
   15836              : }
   15837              : 
   15838              : /* Return a mode that ENTITY is assumed to be
   15839              :    switched to at function entry.  */
   15840              : 
   15841              : static int
   15842        75894 : ix86_mode_entry (int entity)
   15843              : {
   15844        75894 :   switch (entity)
   15845              :     {
   15846          120 :     case X86_DIRFLAG:
   15847          120 :       return ix86_dirflag_mode_entry ();
   15848        74629 :     case AVX_U128:
   15849        74629 :       return ix86_avx_u128_mode_entry ();
   15850              :     case I387_ROUNDEVEN:
   15851              :     case I387_TRUNC:
   15852              :     case I387_FLOOR:
   15853              :     case I387_CEIL:
   15854              :       return I387_CW_ANY;
   15855            0 :     default:
   15856            0 :       gcc_unreachable ();
   15857              :     }
   15858              : }
   15859              : 
   15860              : static int
   15861        73379 : ix86_avx_u128_mode_exit (void)
   15862              : {
   15863        73379 :   rtx reg = crtl->return_rtx;
   15864              : 
   15865              :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit
   15866              :      or 512 bit modes used in the function return register. */
   15867        73379 :   if (reg && ix86_check_avx_upper_register (reg))
   15868              :     return AVX_U128_DIRTY;
   15869              : 
   15870              :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit or 512bit
   15871              :      modes used in function arguments, otherwise return AVX_U128_CLEAN.
   15872              :    */
   15873        48490 :   return ix86_avx_u128_mode_entry ();
   15874              : }
   15875              : 
   15876              : /* Return a mode that ENTITY is assumed to be
   15877              :    switched to at function exit.  */
   15878              : 
   15879              : static int
   15880        74499 : ix86_mode_exit (int entity)
   15881              : {
   15882        74499 :   switch (entity)
   15883              :     {
   15884              :     case X86_DIRFLAG:
   15885              :       return X86_DIRFLAG_ANY;
   15886        73379 :     case AVX_U128:
   15887        73379 :       return ix86_avx_u128_mode_exit ();
   15888         1086 :     case I387_ROUNDEVEN:
   15889         1086 :     case I387_TRUNC:
   15890         1086 :     case I387_FLOOR:
   15891         1086 :     case I387_CEIL:
   15892         1086 :       return I387_CW_ANY;
   15893            0 :     default:
   15894            0 :       gcc_unreachable ();
   15895              :     }
   15896              : }
   15897              : 
   15898              : static int
   15899      2179091 : ix86_mode_priority (int, int n)
   15900              : {
   15901      2179091 :   return n;
   15902              : }
   15903              : 
   15904              : /* Output code to initialize control word copies used by trunc?f?i and
   15905              :    rounding patterns.  CURRENT_MODE is set to current control word,
   15906              :    while NEW_MODE is set to new control word.  */
   15907              : 
   15908              : static void
   15909         3312 : emit_i387_cw_initialization (int mode)
   15910              : {
   15911         3312 :   rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
   15912         3312 :   rtx new_mode;
   15913              : 
   15914         3312 :   enum ix86_stack_slot slot;
   15915              : 
   15916         3312 :   rtx reg = gen_reg_rtx (HImode);
   15917              : 
   15918         3312 :   emit_insn (gen_x86_fnstcw_1 (stored_mode));
   15919         3312 :   emit_move_insn (reg, copy_rtx (stored_mode));
   15920              : 
   15921         3312 :   switch (mode)
   15922              :     {
   15923            0 :     case I387_CW_ROUNDEVEN:
   15924              :       /* round to nearest */
   15925            0 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15926            0 :       slot = SLOT_CW_ROUNDEVEN;
   15927            0 :       break;
   15928              : 
   15929         3116 :     case I387_CW_TRUNC:
   15930              :       /* round toward zero (truncate) */
   15931         3116 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
   15932         3116 :       slot = SLOT_CW_TRUNC;
   15933         3116 :       break;
   15934              : 
   15935          137 :     case I387_CW_FLOOR:
   15936              :       /* round down toward -oo */
   15937          137 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15938          137 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
   15939          137 :       slot = SLOT_CW_FLOOR;
   15940          137 :       break;
   15941              : 
   15942           59 :     case I387_CW_CEIL:
   15943              :       /* round up toward +oo */
   15944           59 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15945           59 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
   15946           59 :       slot = SLOT_CW_CEIL;
   15947           59 :       break;
   15948              : 
   15949            0 :     default:
   15950            0 :       gcc_unreachable ();
   15951              :     }
   15952              : 
   15953         3312 :   gcc_assert (slot < MAX_386_STACK_LOCALS);
   15954              : 
   15955         3312 :   new_mode = assign_386_stack_local (HImode, slot);
   15956         3312 :   emit_move_insn (new_mode, reg);
   15957         3312 : }
   15958              : 
   15959              : /* Generate one or more insns to set ENTITY to MODE.  */
   15960              : 
   15961              : static void
   15962        52125 : ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
   15963              :                     HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
   15964              : {
   15965        52125 :   switch (entity)
   15966              :     {
   15967          265 :     case X86_DIRFLAG:
   15968          265 :       if (mode == X86_DIRFLAG_RESET)
   15969          265 :         emit_insn (gen_cld ());
   15970              :       break;
   15971        43558 :     case AVX_U128:
   15972        43558 :       if (mode == AVX_U128_CLEAN)
   15973        22252 :         ix86_expand_avx_vzeroupper ();
   15974              :       break;
   15975         8302 :     case I387_ROUNDEVEN:
   15976         8302 :     case I387_TRUNC:
   15977         8302 :     case I387_FLOOR:
   15978         8302 :     case I387_CEIL:
   15979         8302 :       if (mode != I387_CW_ANY
   15980         8302 :           && mode != I387_CW_UNINITIALIZED)
   15981         3312 :         emit_i387_cw_initialization (mode);
   15982              :       break;
   15983            0 :     default:
   15984            0 :       gcc_unreachable ();
   15985              :     }
   15986        52125 : }
   15987              : 
   15988              : /* Output code for INSN to convert a float to a signed int.  OPERANDS
   15989              :    are the insn operands.  The output may be [HSD]Imode and the input
   15990              :    operand may be [SDX]Fmode.  */
   15991              : 
   15992              : const char *
   15993         7456 : output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
   15994              : {
   15995         7456 :   bool stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   15996         7456 :   bool dimode_p = GET_MODE (operands[0]) == DImode;
   15997         7456 :   int round_mode = get_attr_i387_cw (insn);
   15998              : 
   15999         7456 :   static char buf[40];
   16000         7456 :   const char *p;
   16001              : 
   16002              :   /* Jump through a hoop or two for DImode, since the hardware has no
   16003              :      non-popping instruction.  We used to do this a different way, but
   16004              :      that was somewhat fragile and broke with post-reload splitters.  */
   16005         7456 :   if ((dimode_p || fisttp) && !stack_top_dies)
   16006           25 :     output_asm_insn ("fld\t%y1", operands);
   16007              : 
   16008         7456 :   gcc_assert (STACK_TOP_P (operands[1]));
   16009         7456 :   gcc_assert (MEM_P (operands[0]));
   16010         7456 :   gcc_assert (GET_MODE (operands[1]) != TFmode);
   16011              : 
   16012         7456 :   if (fisttp)
   16013              :     return "fisttp%Z0\t%0";
   16014              : 
   16015         7455 :   strcpy (buf, "fist");
   16016              : 
   16017         7455 :   if (round_mode != I387_CW_ANY)
   16018         7411 :     output_asm_insn ("fldcw\t%3", operands);
   16019              : 
   16020         7455 :   p = "p%Z0\t%0";
   16021         7455 :   strcat (buf, p + !(stack_top_dies || dimode_p));
   16022              : 
   16023         7455 :   output_asm_insn (buf, operands);
   16024              : 
   16025         7455 :   if (round_mode != I387_CW_ANY)
   16026         7411 :     output_asm_insn ("fldcw\t%2", operands);
   16027              : 
   16028              :   return "";
   16029              : }
   16030              : 
   16031              : /* Output code for x87 ffreep insn.  The OPNO argument, which may only
   16032              :    have the values zero or one, indicates the ffreep insn's operand
   16033              :    from the OPERANDS array.  */
   16034              : 
   16035              : static const char *
   16036       274567 : output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
   16037              : {
   16038            0 :   if (TARGET_USE_FFREEP)
   16039              : #ifdef HAVE_AS_IX86_FFREEP
   16040            0 :     return opno ? "ffreep\t%y1" : "ffreep\t%y0";
   16041              : #else
   16042              :     {
   16043              :       static char retval[32];
   16044              :       int regno = REGNO (operands[opno]);
   16045              : 
   16046              :       gcc_assert (STACK_REGNO_P (regno));
   16047              : 
   16048              :       regno -= FIRST_STACK_REG;
   16049              : 
   16050              :       snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
   16051              :       return retval;
   16052              :     }
   16053              : #endif
   16054              : 
   16055            0 :   return opno ? "fstp\t%y1" : "fstp\t%y0";
   16056              : }
   16057              : 
   16058              : 
   16059              : /* Output code for INSN to compare OPERANDS.  EFLAGS_P is 1 when fcomi
   16060              :    should be used.  UNORDERED_P is true when fucom should be used.  */
   16061              : 
   16062              : const char *
   16063       108193 : output_fp_compare (rtx_insn *insn, rtx *operands,
   16064              :                    bool eflags_p, bool unordered_p)
   16065              : {
   16066       108193 :   rtx *xops = eflags_p ? &operands[0] : &operands[1];
   16067       108193 :   bool stack_top_dies;
   16068              : 
   16069       108193 :   static char buf[40];
   16070       108193 :   const char *p;
   16071              : 
   16072       108193 :   gcc_assert (STACK_TOP_P (xops[0]));
   16073              : 
   16074       108193 :   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   16075              : 
   16076       108193 :   if (eflags_p)
   16077              :     {
   16078       108193 :       p = unordered_p ? "fucomi" : "fcomi";
   16079       108193 :       strcpy (buf, p);
   16080              : 
   16081       108193 :       p = "p\t{%y1, %0|%0, %y1}";
   16082       108193 :       strcat (buf, p + !stack_top_dies);
   16083              : 
   16084       108193 :       return buf;
   16085              :     }
   16086              : 
   16087            0 :   if (STACK_REG_P (xops[1])
   16088            0 :       && stack_top_dies
   16089            0 :       && find_regno_note (insn, REG_DEAD, FIRST_STACK_REG + 1))
   16090              :     {
   16091            0 :       gcc_assert (REGNO (xops[1]) == FIRST_STACK_REG + 1);
   16092              : 
   16093              :       /* If both the top of the 387 stack die, and the other operand
   16094              :          is also a stack register that dies, then this must be a
   16095              :          `fcompp' float compare.  */
   16096            0 :       p = unordered_p ? "fucompp" : "fcompp";
   16097            0 :       strcpy (buf, p);
   16098              :     }
   16099            0 :   else if (const0_operand (xops[1], VOIDmode))
   16100              :     {
   16101            0 :       gcc_assert (!unordered_p);
   16102            0 :       strcpy (buf, "ftst");
   16103              :     }
   16104              :   else
   16105              :     {
   16106            0 :       if (GET_MODE_CLASS (GET_MODE (xops[1])) == MODE_INT)
   16107              :         {
   16108            0 :           gcc_assert (!unordered_p);
   16109              :           p = "ficom";
   16110              :         }
   16111              :       else
   16112            0 :         p = unordered_p ? "fucom" : "fcom";
   16113              : 
   16114            0 :       strcpy (buf, p);
   16115              : 
   16116            0 :       p = "p%Z2\t%y2";
   16117            0 :       strcat (buf, p + !stack_top_dies);
   16118              :     }
   16119              : 
   16120            0 :   output_asm_insn (buf, operands);
   16121            0 :   return "fnstsw\t%0";
   16122              : }
   16123              : 
   16124              : void
   16125       128769 : ix86_output_addr_vec_elt (FILE *file, int value)
   16126              : {
   16127       128769 :   const char *directive = ASM_LONG;
   16128              : 
   16129              : #ifdef ASM_QUAD
   16130       128769 :   if (TARGET_LP64)
   16131       117030 :     directive = ASM_QUAD;
   16132              : #else
   16133              :   gcc_assert (!TARGET_64BIT);
   16134              : #endif
   16135              : 
   16136       128769 :   fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
   16137       128769 : }
   16138              : 
   16139              : void
   16140        27054 : ix86_output_addr_diff_elt (FILE *file, int value, int rel)
   16141              : {
   16142        27054 :   const char *directive = ASM_LONG;
   16143              : 
   16144              : #ifdef ASM_QUAD
   16145        40527 :   if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
   16146              :     directive = ASM_QUAD;
   16147              : #else
   16148              :   gcc_assert (!TARGET_64BIT);
   16149              : #endif
   16150              :   /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand.  */
   16151        27054 :   if (TARGET_64BIT || TARGET_VXWORKS_VAROFF)
   16152        13473 :     fprintf (file, "%s%s%d-%s%d\n",
   16153              :              directive, LPREFIX, value, LPREFIX, rel);
   16154              : #if TARGET_MACHO
   16155              :   else if (TARGET_MACHO)
   16156              :     {
   16157              :       fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
   16158              :       machopic_output_function_base_name (file);
   16159              :       putc ('\n', file);
   16160              :     }
   16161              : #endif
   16162        13581 :   else if (HAVE_AS_GOTOFF_IN_DATA)
   16163        13581 :     fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
   16164              :   else
   16165              :     asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
   16166              :                  GOT_SYMBOL_NAME, LPREFIX, value);
   16167        27054 : }
   16168              : 
   16169              : #define LEA_MAX_STALL (3)
   16170              : #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
   16171              : 
   16172              : /* Increase given DISTANCE in half-cycles according to
   16173              :    dependencies between PREV and NEXT instructions.
   16174              :    Add 1 half-cycle if there is no dependency and
   16175              :    go to next cycle if there is some dependency.  */
   16176              : 
   16177              : static unsigned int
   16178         2138 : increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
   16179              : {
   16180         2138 :   df_ref def, use;
   16181              : 
   16182         2138 :   if (!prev || !next)
   16183          752 :     return distance + (distance & 1) + 2;
   16184              : 
   16185         1386 :   if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
   16186          228 :     return distance + 1;
   16187              : 
   16188         1920 :   FOR_EACH_INSN_USE (use, next)
   16189         2449 :     FOR_EACH_INSN_DEF (def, prev)
   16190         1687 :       if (!DF_REF_IS_ARTIFICIAL (def)
   16191         1687 :           && DF_REF_REGNO (use) == DF_REF_REGNO (def))
   16192          741 :         return distance + (distance & 1) + 2;
   16193              : 
   16194          417 :   return distance + 1;
   16195              : }
   16196              : 
   16197              : /* Function checks if instruction INSN defines register number
   16198              :    REGNO1 or REGNO2.  */
   16199              : 
   16200              : bool
   16201         2081 : insn_defines_reg (unsigned int regno1, unsigned int regno2,
   16202              :                   rtx_insn *insn)
   16203              : {
   16204         2081 :   df_ref def;
   16205              : 
   16206         3757 :   FOR_EACH_INSN_DEF (def, insn)
   16207         2082 :     if (DF_REF_REG_DEF_P (def)
   16208         2082 :         && !DF_REF_IS_ARTIFICIAL (def)
   16209         2082 :         && (regno1 == DF_REF_REGNO (def)
   16210         1692 :             || regno2 == DF_REF_REGNO (def)))
   16211              :       return true;
   16212              : 
   16213              :   return false;
   16214              : }
   16215              : 
   16216              : /* Function checks if instruction INSN uses register number
   16217              :    REGNO as a part of address expression.  */
   16218              : 
   16219              : static bool
   16220         1189 : insn_uses_reg_mem (unsigned int regno, rtx insn)
   16221              : {
   16222         1189 :   df_ref use;
   16223              : 
   16224         2489 :   FOR_EACH_INSN_USE (use, insn)
   16225         1392 :     if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
   16226              :       return true;
   16227              : 
   16228              :   return false;
   16229              : }
   16230              : 
   16231              : /* Search backward for non-agu definition of register number REGNO1
   16232              :    or register number REGNO2 in basic block starting from instruction
   16233              :    START up to head of basic block or instruction INSN.
   16234              : 
   16235              :    Function puts true value into *FOUND var if definition was found
   16236              :    and false otherwise.
   16237              : 
   16238              :    Distance in half-cycles between START and found instruction or head
   16239              :    of BB is added to DISTANCE and returned.  */
   16240              : 
   16241              : static int
   16242          627 : distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
   16243              :                                rtx_insn *insn, int distance,
   16244              :                                rtx_insn *start, bool *found)
   16245              : {
   16246          627 :   basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
   16247          627 :   rtx_insn *prev = start;
   16248          627 :   rtx_insn *next = NULL;
   16249              : 
   16250          627 :   *found = false;
   16251              : 
   16252          627 :   while (prev
   16253         1865 :          && prev != insn
   16254         1865 :          && distance < LEA_SEARCH_THRESHOLD)
   16255              :     {
   16256         1663 :       if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
   16257              :         {
   16258          949 :           distance = increase_distance (prev, next, distance);
   16259          949 :           if (insn_defines_reg (regno1, regno2, prev))
   16260              :             {
   16261          245 :               if (recog_memoized (prev) < 0
   16262          245 :                   || get_attr_type (prev) != TYPE_LEA)
   16263              :                 {
   16264          201 :                   *found = true;
   16265          201 :                   return distance;
   16266              :                 }
   16267              :             }
   16268              : 
   16269              :           next = prev;
   16270              :         }
   16271         1462 :       if (prev == BB_HEAD (bb))
   16272              :         break;
   16273              : 
   16274         1238 :       prev = PREV_INSN (prev);
   16275              :     }
   16276              : 
   16277              :   return distance;
   16278              : }
   16279              : 
   16280              : /* Search backward for non-agu definition of register number REGNO1
   16281              :    or register number REGNO2 in INSN's basic block until
   16282              :    1. Pass LEA_SEARCH_THRESHOLD instructions, or
   16283              :    2. Reach neighbor BBs boundary, or
   16284              :    3. Reach agu definition.
   16285              :    Returns the distance between the non-agu definition point and INSN.
   16286              :    If no definition point, returns -1.  */
   16287              : 
   16288              : static int
   16289          431 : distance_non_agu_define (unsigned int regno1, unsigned int regno2,
   16290              :                          rtx_insn *insn)
   16291              : {
   16292          431 :   basic_block bb = BLOCK_FOR_INSN (insn);
   16293          431 :   int distance = 0;
   16294          431 :   bool found = false;
   16295              : 
   16296          431 :   if (insn != BB_HEAD (bb))
   16297          431 :     distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
   16298              :                                               distance, PREV_INSN (insn),
   16299              :                                               &found);
   16300              : 
   16301          431 :   if (!found && distance < LEA_SEARCH_THRESHOLD)
   16302              :     {
   16303          168 :       edge e;
   16304          168 :       edge_iterator ei;
   16305          168 :       bool simple_loop = false;
   16306              : 
   16307          338 :       FOR_EACH_EDGE (e, ei, bb->preds)
   16308          207 :         if (e->src == bb)
   16309              :           {
   16310              :             simple_loop = true;
   16311              :             break;
   16312              :           }
   16313              : 
   16314          168 :       if (simple_loop)
   16315           37 :         distance = distance_non_agu_define_in_bb (regno1, regno2,
   16316              :                                                   insn, distance,
   16317           37 :                                                   BB_END (bb), &found);
   16318              :       else
   16319              :         {
   16320          131 :           int shortest_dist = -1;
   16321          131 :           bool found_in_bb = false;
   16322              : 
   16323          290 :           FOR_EACH_EDGE (e, ei, bb->preds)
   16324              :             {
   16325          159 :               int bb_dist
   16326          318 :                 = distance_non_agu_define_in_bb (regno1, regno2,
   16327              :                                                  insn, distance,
   16328          159 :                                                  BB_END (e->src),
   16329              :                                                  &found_in_bb);
   16330          159 :               if (found_in_bb)
   16331              :                 {
   16332           24 :                   if (shortest_dist < 0)
   16333              :                     shortest_dist = bb_dist;
   16334            0 :                   else if (bb_dist > 0)
   16335            0 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   16336              : 
   16337           24 :                   found = true;
   16338              :                 }
   16339              :             }
   16340              : 
   16341          131 :           distance = shortest_dist;
   16342              :         }
   16343              :     }
   16344              : 
   16345          431 :   if (!found)
   16346              :     return -1;
   16347              : 
   16348          201 :   return distance >> 1;
   16349              : }
   16350              : 
   16351              : /* Return the distance in half-cycles between INSN and the next
   16352              :    insn that uses register number REGNO in memory address added
   16353              :    to DISTANCE.  Return -1 if REGNO0 is set.
   16354              : 
   16355              :    Put true value into *FOUND if register usage was found and
   16356              :    false otherwise.
   16357              :    Put true value into *REDEFINED if register redefinition was
   16358              :    found and false otherwise.  */
   16359              : 
   16360              : static int
   16361          770 : distance_agu_use_in_bb (unsigned int regno,
   16362              :                         rtx_insn *insn, int distance, rtx_insn *start,
   16363              :                         bool *found, bool *redefined)
   16364              : {
   16365          770 :   basic_block bb = NULL;
   16366          770 :   rtx_insn *next = start;
   16367          770 :   rtx_insn *prev = NULL;
   16368              : 
   16369          770 :   *found = false;
   16370          770 :   *redefined = false;
   16371              : 
   16372          770 :   if (start != NULL_RTX)
   16373              :     {
   16374          753 :       bb = BLOCK_FOR_INSN (start);
   16375          753 :       if (start != BB_HEAD (bb))
   16376              :         /* If insn and start belong to the same bb, set prev to insn,
   16377              :            so the call to increase_distance will increase the distance
   16378              :            between insns by 1.  */
   16379          414 :         prev = insn;
   16380              :     }
   16381              : 
   16382         2576 :   while (next
   16383         2576 :          && next != insn
   16384         2576 :          && distance < LEA_SEARCH_THRESHOLD)
   16385              :     {
   16386         2387 :       if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
   16387              :         {
   16388         1189 :           distance = increase_distance(prev, next, distance);
   16389         1189 :           if (insn_uses_reg_mem (regno, next))
   16390              :             {
   16391              :               /* Return DISTANCE if OP0 is used in memory
   16392              :                  address in NEXT.  */
   16393           92 :               *found = true;
   16394           92 :               return distance;
   16395              :             }
   16396              : 
   16397         1097 :           if (insn_defines_reg (regno, INVALID_REGNUM, next))
   16398              :             {
   16399              :               /* Return -1 if OP0 is set in NEXT.  */
   16400          156 :               *redefined = true;
   16401          156 :               return -1;
   16402              :             }
   16403              : 
   16404              :           prev = next;
   16405              :         }
   16406              : 
   16407         2139 :       if (next == BB_END (bb))
   16408              :         break;
   16409              : 
   16410         1806 :       next = NEXT_INSN (next);
   16411              :     }
   16412              : 
   16413              :   return distance;
   16414              : }
   16415              : 
   16416              : /* Return the distance between INSN and the next insn that uses
   16417              :    register number REGNO0 in memory address.  Return -1 if no such
   16418              :    a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set.  */
   16419              : 
   16420              : static int
   16421          431 : distance_agu_use (unsigned int regno0, rtx_insn *insn)
   16422              : {
   16423          431 :   basic_block bb = BLOCK_FOR_INSN (insn);
   16424          431 :   int distance = 0;
   16425          431 :   bool found = false;
   16426          431 :   bool redefined = false;
   16427              : 
   16428          431 :   if (insn != BB_END (bb))
   16429          414 :     distance = distance_agu_use_in_bb (regno0, insn, distance,
   16430              :                                        NEXT_INSN (insn),
   16431              :                                        &found, &redefined);
   16432              : 
   16433          431 :   if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
   16434              :     {
   16435          251 :       edge e;
   16436          251 :       edge_iterator ei;
   16437          251 :       bool simple_loop = false;
   16438              : 
   16439          537 :       FOR_EACH_EDGE (e, ei, bb->succs)
   16440          356 :         if (e->dest == bb)
   16441              :           {
   16442              :             simple_loop = true;
   16443              :             break;
   16444              :           }
   16445              : 
   16446          251 :       if (simple_loop)
   16447           70 :         distance = distance_agu_use_in_bb (regno0, insn,
   16448              :                                            distance, BB_HEAD (bb),
   16449              :                                            &found, &redefined);
   16450              :       else
   16451              :         {
   16452          181 :           int shortest_dist = -1;
   16453          181 :           bool found_in_bb = false;
   16454          181 :           bool redefined_in_bb = false;
   16455              : 
   16456          467 :           FOR_EACH_EDGE (e, ei, bb->succs)
   16457              :             {
   16458          286 :               int bb_dist
   16459          572 :                 = distance_agu_use_in_bb (regno0, insn,
   16460          286 :                                           distance, BB_HEAD (e->dest),
   16461              :                                           &found_in_bb, &redefined_in_bb);
   16462          286 :               if (found_in_bb)
   16463              :                 {
   16464           18 :                   if (shortest_dist < 0)
   16465              :                     shortest_dist = bb_dist;
   16466            2 :                   else if (bb_dist > 0)
   16467            2 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   16468              : 
   16469           18 :                   found = true;
   16470              :                 }
   16471              :             }
   16472              : 
   16473          181 :           distance = shortest_dist;
   16474              :         }
   16475              :     }
   16476              : 
   16477          431 :   if (!found || redefined)
   16478              :     return -1;
   16479              : 
   16480           90 :   return distance >> 1;
   16481              : }
   16482              : 
   16483              : /* Define this macro to tune LEA priority vs ADD, it take effect when
   16484              :    there is a dilemma of choosing LEA or ADD
   16485              :    Negative value: ADD is more preferred than LEA
   16486              :    Zero: Neutral
   16487              :    Positive value: LEA is more preferred than ADD.  */
   16488              : #define IX86_LEA_PRIORITY 0
   16489              : 
   16490              : /* Return true if usage of lea INSN has performance advantage
   16491              :    over a sequence of instructions.  Instructions sequence has
   16492              :    SPLIT_COST cycles higher latency than lea latency.  */
   16493              : 
   16494              : static bool
   16495         1601 : ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
   16496              :                       unsigned int regno2, int split_cost, bool has_scale)
   16497              : {
   16498         1601 :   int dist_define, dist_use;
   16499              : 
   16500              :   /* For Atom processors newer than Bonnell, if using a 2-source or
   16501              :      3-source LEA for non-destructive destination purposes, or due to
   16502              :      wanting ability to use SCALE, the use of LEA is justified.  */
   16503         1601 :   if (!TARGET_CPU_P (BONNELL))
   16504              :     {
   16505         1170 :       if (has_scale)
   16506              :         return true;
   16507         1151 :       if (split_cost < 1)
   16508              :         return false;
   16509          406 :       if (regno0 == regno1 || regno0 == regno2)
   16510              :         return false;
   16511              :       return true;
   16512              :     }
   16513              : 
   16514              :   /* Remember recog_data content.  */
   16515          431 :   struct recog_data_d recog_data_save = recog_data;
   16516              : 
   16517          431 :   dist_define = distance_non_agu_define (regno1, regno2, insn);
   16518          431 :   dist_use = distance_agu_use (regno0, insn);
   16519              : 
   16520              :   /* distance_non_agu_define can call get_attr_type which can call
   16521              :      recog_memoized, restore recog_data back to previous content.  */
   16522          431 :   recog_data = recog_data_save;
   16523              : 
   16524          431 :   if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
   16525              :     {
   16526              :       /* If there is no non AGU operand definition, no AGU
   16527              :          operand usage and split cost is 0 then both lea
   16528              :          and non lea variants have same priority.  Currently
   16529              :          we prefer lea for 64 bit code and non lea on 32 bit
   16530              :          code.  */
   16531          233 :       if (dist_use < 0 && split_cost == 0)
   16532           97 :         return TARGET_64BIT || IX86_LEA_PRIORITY;
   16533              :       else
   16534              :         return true;
   16535              :     }
   16536              : 
   16537              :   /* With longer definitions distance lea is more preferable.
   16538              :      Here we change it to take into account splitting cost and
   16539              :      lea priority.  */
   16540          198 :   dist_define += split_cost + IX86_LEA_PRIORITY;
   16541              : 
   16542              :   /* If there is no use in memory address then we just check
   16543              :      that split cost exceeds AGU stall.  */
   16544          198 :   if (dist_use < 0)
   16545          194 :     return dist_define > LEA_MAX_STALL;
   16546              : 
   16547              :   /* If this insn has both backward non-agu dependence and forward
   16548              :      agu dependence, the one with short distance takes effect.  */
   16549            4 :   return dist_define >= dist_use;
   16550              : }
   16551              : 
   16552              : /* Return true if we need to split op0 = op1 + op2 into a sequence of
   16553              :    move and add to avoid AGU stalls.  */
   16554              : 
   16555              : bool
   16556      9159884 : ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
   16557              : {
   16558      9159884 :   unsigned int regno0, regno1, regno2;
   16559              : 
   16560              :   /* Check if we need to optimize.  */
   16561      9159884 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16562      9159100 :     return false;
   16563              : 
   16564          784 :   regno0 = true_regnum (operands[0]);
   16565          784 :   regno1 = true_regnum (operands[1]);
   16566          784 :   regno2 = true_regnum (operands[2]);
   16567              : 
   16568              :   /* We need to split only adds with non destructive
   16569              :      destination operand.  */
   16570          784 :   if (regno0 == regno1 || regno0 == regno2)
   16571              :     return false;
   16572              :   else
   16573          246 :     return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
   16574              : }
   16575              : 
   16576              : /* Return true if we should emit lea instruction instead of mov
   16577              :    instruction.  */
   16578              : 
   16579              : bool
   16580     29850094 : ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
   16581              : {
   16582     29850094 :   unsigned int regno0, regno1;
   16583              : 
   16584              :   /* Check if we need to optimize.  */
   16585     29850094 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16586     29847825 :     return false;
   16587              : 
   16588              :   /* Use lea for reg to reg moves only.  */
   16589         2269 :   if (!REG_P (operands[0]) || !REG_P (operands[1]))
   16590              :     return false;
   16591              : 
   16592          465 :   regno0 = true_regnum (operands[0]);
   16593          465 :   regno1 = true_regnum (operands[1]);
   16594              : 
   16595          465 :   return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
   16596              : }
   16597              : 
   16598              : /* Return true if we need to split lea into a sequence of
   16599              :    instructions to avoid AGU stalls during peephole2. */
   16600              : 
   16601              : bool
   16602     11345331 : ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
   16603              : {
   16604     11345331 :   unsigned int regno0, regno1, regno2;
   16605     11345331 :   int split_cost;
   16606     11345331 :   struct ix86_address parts;
   16607     11345331 :   int ok;
   16608              : 
   16609              :   /* The "at least two components" test below might not catch simple
   16610              :      move or zero extension insns if parts.base is non-NULL and parts.disp
   16611              :      is const0_rtx as the only components in the address, e.g. if the
   16612              :      register is %rbp or %r13.  As this test is much cheaper and moves or
   16613              :      zero extensions are the common case, do this check first.  */
   16614     11345331 :   if (REG_P (operands[1])
   16615     11345331 :       || (SImode_address_operand (operands[1], VOIDmode)
   16616       138900 :           && REG_P (XEXP (operands[1], 0))))
   16617      4153771 :     return false;
   16618              : 
   16619      7191560 :   ok = ix86_decompose_address (operands[1], &parts);
   16620      7191560 :   gcc_assert (ok);
   16621              : 
   16622              :   /* There should be at least two components in the address.  */
   16623      7191560 :   if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
   16624      7191560 :       + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
   16625              :     return false;
   16626              : 
   16627              :   /* We should not split into add if non legitimate pic
   16628              :      operand is used as displacement. */
   16629      2715350 :   if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
   16630              :     return false;
   16631              : 
   16632      2665298 :   regno0 = true_regnum (operands[0]) ;
   16633      2665298 :   regno1 = INVALID_REGNUM;
   16634      2665298 :   regno2 = INVALID_REGNUM;
   16635              : 
   16636      2665298 :   if (parts.base)
   16637      2587878 :     regno1 = true_regnum (parts.base);
   16638      2665298 :   if (parts.index)
   16639       481757 :     regno2 = true_regnum (parts.index);
   16640              : 
   16641              :   /* Use add for a = a + b and a = b + a since it is faster and shorter
   16642              :      than lea for most processors.  For the processors like BONNELL, if
   16643              :      the destination register of LEA holds an actual address which will
   16644              :      be used soon, LEA is better and otherwise ADD is better.  */
   16645      2665298 :   if (!TARGET_CPU_P (BONNELL)
   16646      2665167 :       && parts.scale == 1
   16647      2418238 :       && (!parts.disp || parts.disp == const0_rtx)
   16648       176845 :       && (regno0 == regno1 || regno0 == regno2))
   16649              :     return true;
   16650              : 
   16651              :   /* Split with -Oz if the encoding requires fewer bytes.  */
   16652      2659067 :   if (optimize_size > 1
   16653           27 :       && parts.scale > 1
   16654            4 :       && !parts.base
   16655            4 :       && (!parts.disp || parts.disp == const0_rtx))
   16656              :     return true;
   16657              : 
   16658              :   /* Check we need to optimize.  */
   16659      2659063 :   if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
   16660      2658720 :     return false;
   16661              : 
   16662          343 :   split_cost = 0;
   16663              : 
   16664              :   /* Compute how many cycles we will add to execution time
   16665              :      if split lea into a sequence of instructions.  */
   16666          343 :   if (parts.base || parts.index)
   16667              :     {
   16668              :       /* Have to use mov instruction if non destructive
   16669              :          destination form is used.  */
   16670          343 :       if (regno1 != regno0 && regno2 != regno0)
   16671          268 :         split_cost += 1;
   16672              : 
   16673              :       /* Have to add index to base if both exist.  */
   16674          343 :       if (parts.base && parts.index)
   16675           55 :         split_cost += 1;
   16676              : 
   16677              :       /* Have to use shift and adds if scale is 2 or greater.  */
   16678          343 :       if (parts.scale > 1)
   16679              :         {
   16680           30 :           if (regno0 != regno1)
   16681           24 :             split_cost += 1;
   16682            6 :           else if (regno2 == regno0)
   16683            0 :             split_cost += 4;
   16684              :           else
   16685            6 :             split_cost += parts.scale;
   16686              :         }
   16687              : 
   16688              :       /* Have to use add instruction with immediate if
   16689              :          disp is non zero.  */
   16690          343 :       if (parts.disp && parts.disp != const0_rtx)
   16691          280 :         split_cost += 1;
   16692              : 
   16693              :       /* Subtract the price of lea.  */
   16694          343 :       split_cost -= 1;
   16695              :     }
   16696              : 
   16697          343 :   return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
   16698          343 :                                 parts.scale > 1);
   16699              : }
   16700              : 
   16701              : /* Return true if it is ok to optimize an ADD operation to LEA
   16702              :    operation to avoid flag register consumation.  For most processors,
   16703              :    ADD is faster than LEA.  For the processors like BONNELL, if the
   16704              :    destination register of LEA holds an actual address which will be
   16705              :    used soon, LEA is better and otherwise ADD is better.  */
   16706              : 
   16707              : bool
   16708      9221132 : ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
   16709              : {
   16710      9221132 :   unsigned int regno0 = true_regnum (operands[0]);
   16711      9221132 :   unsigned int regno1 = true_regnum (operands[1]);
   16712      9221132 :   unsigned int regno2 = true_regnum (operands[2]);
   16713              : 
   16714              :   /* If a = b + c, (a!=b && a!=c), must use lea form. */
   16715      9221132 :   if (regno0 != regno1 && regno0 != regno2)
   16716              :     return true;
   16717              : 
   16718      7163677 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16719      7163130 :     return false;
   16720              : 
   16721          547 :   return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
   16722              : }
   16723              : 
   16724              : /* Return true if destination reg of SET_BODY is shift count of
   16725              :    USE_BODY.  */
   16726              : 
   16727              : static bool
   16728           83 : ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
   16729              : {
   16730           83 :   rtx set_dest;
   16731           83 :   rtx shift_rtx;
   16732           83 :   int i;
   16733              : 
   16734              :   /* Retrieve destination of SET_BODY.  */
   16735           83 :   switch (GET_CODE (set_body))
   16736              :     {
   16737           67 :     case SET:
   16738           67 :       set_dest = SET_DEST (set_body);
   16739           67 :       if (!set_dest || !REG_P (set_dest))
   16740              :         return false;
   16741           66 :       break;
   16742            8 :     case PARALLEL:
   16743           24 :       for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
   16744           16 :         if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
   16745              :                                           use_body))
   16746              :           return true;
   16747              :       /* FALLTHROUGH */
   16748              :     default:
   16749              :       return false;
   16750              :     }
   16751              : 
   16752              :   /* Retrieve shift count of USE_BODY.  */
   16753           66 :   switch (GET_CODE (use_body))
   16754              :     {
   16755           22 :     case SET:
   16756           22 :       shift_rtx = XEXP (use_body, 1);
   16757           22 :       break;
   16758           22 :     case PARALLEL:
   16759           66 :       for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
   16760           44 :         if (ix86_dep_by_shift_count_body (set_body,
   16761           44 :                                           XVECEXP (use_body, 0, i)))
   16762              :           return true;
   16763              :       /* FALLTHROUGH */
   16764              :     default:
   16765              :       return false;
   16766              :     }
   16767              : 
   16768           22 :   if (shift_rtx
   16769           22 :       && (GET_CODE (shift_rtx) == ASHIFT
   16770           21 :           || GET_CODE (shift_rtx) == LSHIFTRT
   16771            5 :           || GET_CODE (shift_rtx) == ASHIFTRT
   16772            0 :           || GET_CODE (shift_rtx) == ROTATE
   16773            0 :           || GET_CODE (shift_rtx) == ROTATERT))
   16774              :     {
   16775           22 :       rtx shift_count = XEXP (shift_rtx, 1);
   16776              : 
   16777              :       /* Return true if shift count is dest of SET_BODY.  */
   16778           22 :       if (REG_P (shift_count))
   16779              :         {
   16780              :           /* Add check since it can be invoked before register
   16781              :              allocation in pre-reload schedule.  */
   16782            0 :           if (reload_completed
   16783            0 :               && true_regnum (set_dest) == true_regnum (shift_count))
   16784              :             return true;
   16785            0 :           else if (REGNO(set_dest) == REGNO(shift_count))
   16786              :             return true;
   16787              :         }
   16788              :     }
   16789              : 
   16790              :   return false;
   16791              : }
   16792              : 
   16793              : /* Return true if destination reg of SET_INSN is shift count of
   16794              :    USE_INSN.  */
   16795              : 
   16796              : bool
   16797           23 : ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
   16798              : {
   16799           23 :   return ix86_dep_by_shift_count_body (PATTERN (set_insn),
   16800           23 :                                        PATTERN (use_insn));
   16801              : }
   16802              : 
   16803              : /* Return TRUE if the operands to a vec_interleave_{high,low}v2df
   16804              :    are ok, keeping in mind the possible movddup alternative.  */
   16805              : 
   16806              : bool
   16807        94590 : ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
   16808              : {
   16809        94590 :   if (MEM_P (operands[0]))
   16810         2055 :     return rtx_equal_p (operands[0], operands[1 + high]);
   16811        92535 :   if (MEM_P (operands[1]) && MEM_P (operands[2]))
   16812         1050 :     return false;
   16813              :   return true;
   16814              : }
   16815              : 
   16816              : /* A subroutine of ix86_build_signbit_mask.  If VECT is true,
   16817              :    then replicate the value for all elements of the vector
   16818              :    register.  */
   16819              : 
   16820              : rtx
   16821        76063 : ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
   16822              : {
   16823        76063 :   int i, n_elt;
   16824        76063 :   rtvec v;
   16825        76063 :   machine_mode scalar_mode;
   16826              : 
   16827        76063 :   switch (mode)
   16828              :     {
   16829         1323 :     case E_V64QImode:
   16830         1323 :     case E_V32QImode:
   16831         1323 :     case E_V16QImode:
   16832         1323 :     case E_V32HImode:
   16833         1323 :     case E_V16HImode:
   16834         1323 :     case E_V8HImode:
   16835         1323 :     case E_V16SImode:
   16836         1323 :     case E_V8SImode:
   16837         1323 :     case E_V4SImode:
   16838         1323 :     case E_V2SImode:
   16839         1323 :     case E_V8DImode:
   16840         1323 :     case E_V4DImode:
   16841         1323 :     case E_V2DImode:
   16842         1323 :       gcc_assert (vect);
   16843              :       /* FALLTHRU */
   16844        76063 :     case E_V2HFmode:
   16845        76063 :     case E_V4HFmode:
   16846        76063 :     case E_V8HFmode:
   16847        76063 :     case E_V16HFmode:
   16848        76063 :     case E_V32HFmode:
   16849        76063 :     case E_V16SFmode:
   16850        76063 :     case E_V8SFmode:
   16851        76063 :     case E_V4SFmode:
   16852        76063 :     case E_V2SFmode:
   16853        76063 :     case E_V8DFmode:
   16854        76063 :     case E_V4DFmode:
   16855        76063 :     case E_V2DFmode:
   16856        76063 :     case E_V32BFmode:
   16857        76063 :     case E_V16BFmode:
   16858        76063 :     case E_V8BFmode:
   16859        76063 :     case E_V4BFmode:
   16860        76063 :     case E_V2BFmode:
   16861        76063 :       n_elt = GET_MODE_NUNITS (mode);
   16862        76063 :       v = rtvec_alloc (n_elt);
   16863        76063 :       scalar_mode = GET_MODE_INNER (mode);
   16864              : 
   16865        76063 :       RTVEC_ELT (v, 0) = value;
   16866              : 
   16867       235600 :       for (i = 1; i < n_elt; ++i)
   16868       159537 :         RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
   16869              : 
   16870        76063 :       return gen_rtx_CONST_VECTOR (mode, v);
   16871              : 
   16872            0 :     default:
   16873            0 :       gcc_unreachable ();
   16874              :     }
   16875              : }
   16876              : 
   16877              : /* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
   16878              :    and ix86_expand_int_vcond.  Create a mask for the sign bit in MODE
   16879              :    for an SSE register.  If VECT is true, then replicate the mask for
   16880              :    all elements of the vector register.  If INVERT is true, then create
   16881              :    a mask excluding the sign bit.  */
   16882              : 
   16883              : rtx
   16884        77809 : ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
   16885              : {
   16886        77809 :   machine_mode vec_mode, imode;
   16887        77809 :   wide_int w;
   16888        77809 :   rtx mask, v;
   16889              : 
   16890        77809 :   switch (mode)
   16891              :     {
   16892              :     case E_V2HFmode:
   16893              :     case E_V4HFmode:
   16894              :     case E_V8HFmode:
   16895              :     case E_V16HFmode:
   16896              :     case E_V32HFmode:
   16897              :     case E_V32BFmode:
   16898              :     case E_V16BFmode:
   16899              :     case E_V8BFmode:
   16900              :     case E_V4BFmode:
   16901              :     case E_V2BFmode:
   16902              :       vec_mode = mode;
   16903              :       imode = HImode;
   16904              :       break;
   16905              : 
   16906        34713 :     case E_V16SImode:
   16907        34713 :     case E_V16SFmode:
   16908        34713 :     case E_V8SImode:
   16909        34713 :     case E_V4SImode:
   16910        34713 :     case E_V8SFmode:
   16911        34713 :     case E_V4SFmode:
   16912        34713 :     case E_V2SFmode:
   16913        34713 :     case E_V2SImode:
   16914        34713 :       vec_mode = mode;
   16915        34713 :       imode = SImode;
   16916        34713 :       break;
   16917              : 
   16918        39830 :     case E_V8DImode:
   16919        39830 :     case E_V4DImode:
   16920        39830 :     case E_V2DImode:
   16921        39830 :     case E_V8DFmode:
   16922        39830 :     case E_V4DFmode:
   16923        39830 :     case E_V2DFmode:
   16924        39830 :       vec_mode = mode;
   16925        39830 :       imode = DImode;
   16926        39830 :       break;
   16927              : 
   16928         2765 :     case E_TImode:
   16929         2765 :     case E_TFmode:
   16930         2765 :       vec_mode = VOIDmode;
   16931         2765 :       imode = TImode;
   16932         2765 :       break;
   16933              : 
   16934            0 :     default:
   16935            0 :       gcc_unreachable ();
   16936              :     }
   16937              : 
   16938        77809 :   machine_mode inner_mode = GET_MODE_INNER (mode);
   16939       155618 :   w = wi::set_bit_in_zero (GET_MODE_BITSIZE (inner_mode) - 1,
   16940       155618 :                            GET_MODE_BITSIZE (inner_mode));
   16941        77809 :   if (invert)
   16942        41310 :     w = wi::bit_not (w);
   16943              : 
   16944              :   /* Force this value into the low part of a fp vector constant.  */
   16945        77809 :   mask = immed_wide_int_const (w, imode);
   16946        77809 :   mask = gen_lowpart (inner_mode, mask);
   16947              : 
   16948        77809 :   if (vec_mode == VOIDmode)
   16949         2765 :     return force_reg (inner_mode, mask);
   16950              : 
   16951        75044 :   v = ix86_build_const_vector (vec_mode, vect, mask);
   16952        75044 :   return force_reg (vec_mode, v);
   16953        77809 : }
   16954              : 
   16955              : /* Return HOST_WIDE_INT for const vector OP in MODE.  */
   16956              : 
   16957              : HOST_WIDE_INT
   16958       137254 : ix86_convert_const_vector_to_integer (rtx op, machine_mode mode)
   16959              : {
   16960       290737 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   16961            0 :     gcc_unreachable ();
   16962              : 
   16963       137254 :   int nunits = GET_MODE_NUNITS (mode);
   16964       274508 :   wide_int val = wi::zero (GET_MODE_BITSIZE (mode));
   16965       137254 :   machine_mode innermode = GET_MODE_INNER (mode);
   16966       137254 :   unsigned int innermode_bits = GET_MODE_BITSIZE (innermode);
   16967              : 
   16968       137254 :   switch (mode)
   16969              :     {
   16970              :     case E_V2QImode:
   16971              :     case E_V4QImode:
   16972              :     case E_V2HImode:
   16973              :     case E_V8QImode:
   16974              :     case E_V4HImode:
   16975              :     case E_V2SImode:
   16976       469709 :       for (int i = 0; i < nunits; ++i)
   16977              :         {
   16978       337652 :           int v = INTVAL (XVECEXP (op, 0, i));
   16979       337652 :           wide_int wv = wi::shwi (v, innermode_bits);
   16980       337652 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16981       337652 :         }
   16982              :       break;
   16983           88 :     case E_V1SImode:
   16984           88 :     case E_V1DImode:
   16985           88 :       op = CONST_VECTOR_ELT (op, 0);
   16986           88 :       return INTVAL (op);
   16987              :     case E_V2HFmode:
   16988              :     case E_V2BFmode:
   16989              :     case E_V4HFmode:
   16990              :     case E_V4BFmode:
   16991              :     case E_V2SFmode:
   16992        15373 :       for (int i = 0; i < nunits; ++i)
   16993              :         {
   16994        10264 :           rtx x = XVECEXP (op, 0, i);
   16995        10264 :           int v = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   16996        10264 :                                   REAL_MODE_FORMAT (innermode));
   16997        10264 :           wide_int wv = wi::shwi (v, innermode_bits);
   16998        10264 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16999        10264 :         }
   17000              :       break;
   17001            0 :     default:
   17002            0 :       gcc_unreachable ();
   17003              :     }
   17004              : 
   17005       137166 :   return val.to_shwi ();
   17006       137254 : }
   17007              : 
   17008           32 : int ix86_get_flags_cc (rtx_code code)
   17009              : {
   17010           32 :   switch (code)
   17011              :     {
   17012              :       case NE: return X86_CCNE;
   17013              :       case EQ: return X86_CCE;
   17014              :       case GE: return X86_CCNL;
   17015              :       case GT: return X86_CCNLE;
   17016              :       case LE: return X86_CCLE;
   17017              :       case LT: return X86_CCL;
   17018              :       case GEU: return X86_CCNB;
   17019              :       case GTU: return X86_CCNBE;
   17020              :       case LEU: return X86_CCBE;
   17021              :       case LTU: return X86_CCB;
   17022              :       default: return -1;
   17023              :     }
   17024              : }
   17025              : 
   17026              : /* Return TRUE or FALSE depending on whether the first SET in INSN
   17027              :    has source and destination with matching CC modes, and that the
   17028              :    CC mode is at least as constrained as REQ_MODE.  */
   17029              : 
   17030              : bool
   17031     54468672 : ix86_match_ccmode (rtx insn, machine_mode req_mode)
   17032              : {
   17033     54468672 :   rtx set;
   17034     54468672 :   machine_mode set_mode;
   17035              : 
   17036     54468672 :   set = PATTERN (insn);
   17037     54468672 :   if (GET_CODE (set) == PARALLEL)
   17038       527432 :     set = XVECEXP (set, 0, 0);
   17039     54468672 :   gcc_assert (GET_CODE (set) == SET);
   17040     54468672 :   gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
   17041              : 
   17042     54468672 :   set_mode = GET_MODE (SET_DEST (set));
   17043     54468672 :   switch (set_mode)
   17044              :     {
   17045      1425154 :     case E_CCNOmode:
   17046      1425154 :       if (req_mode != CCNOmode
   17047       102077 :           && (req_mode != CCmode
   17048            0 :               || XEXP (SET_SRC (set), 1) != const0_rtx))
   17049              :         return false;
   17050              :       break;
   17051      5859211 :     case E_CCmode:
   17052      5859211 :       if (req_mode == CCGCmode)
   17053              :         return false;
   17054              :       /* FALLTHRU */
   17055      9579167 :     case E_CCGCmode:
   17056      9579167 :       if (req_mode == CCGOCmode || req_mode == CCNOmode)
   17057              :         return false;
   17058              :       /* FALLTHRU */
   17059     10692182 :     case E_CCGOCmode:
   17060     10692182 :       if (req_mode == CCZmode)
   17061              :         return false;
   17062              :       /* FALLTHRU */
   17063              :     case E_CCZmode:
   17064              :       break;
   17065              : 
   17066            0 :     case E_CCGZmode:
   17067              : 
   17068            0 :     case E_CCAmode:
   17069            0 :     case E_CCCmode:
   17070            0 :     case E_CCOmode:
   17071            0 :     case E_CCPmode:
   17072            0 :     case E_CCSmode:
   17073            0 :       if (set_mode != req_mode)
   17074              :         return false;
   17075              :       break;
   17076              : 
   17077            0 :     default:
   17078            0 :       gcc_unreachable ();
   17079              :     }
   17080              : 
   17081     54357751 :   return GET_MODE (SET_SRC (set)) == set_mode;
   17082              : }
   17083              : 
   17084              : machine_mode
   17085     13799755 : ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
   17086              : {
   17087     13799755 :   machine_mode mode = GET_MODE (op0);
   17088              : 
   17089     13799755 :   if (SCALAR_FLOAT_MODE_P (mode))
   17090              :     {
   17091       145574 :       gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
   17092              :       return CCFPmode;
   17093              :     }
   17094              : 
   17095     13654181 :   switch (code)
   17096              :     {
   17097              :       /* Only zero flag is needed.  */
   17098              :     case EQ:                    /* ZF=0 */
   17099              :     case NE:                    /* ZF!=0 */
   17100              :       return CCZmode;
   17101              :       /* Codes needing carry flag.  */
   17102       968770 :     case GEU:                   /* CF=0 */
   17103       968770 :     case LTU:                   /* CF=1 */
   17104       968770 :       rtx geu;
   17105              :       /* Detect overflow checks.  They need just the carry flag.  */
   17106       968770 :       if (GET_CODE (op0) == PLUS
   17107       968770 :           && (rtx_equal_p (op1, XEXP (op0, 0))
   17108       106402 :               || rtx_equal_p (op1, XEXP (op0, 1))))
   17109        17593 :         return CCCmode;
   17110              :       /* Similarly for *setcc_qi_addqi3_cconly_overflow_1_* patterns.
   17111              :          Match LTU of op0
   17112              :          (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   17113              :          and op1
   17114              :          (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
   17115              :          where CC_CCC is either CC or CCC.  */
   17116       951177 :       else if (code == LTU
   17117       345568 :                && GET_CODE (op0) == NEG
   17118           18 :                && GET_CODE (geu = XEXP (op0, 0)) == GEU
   17119            0 :                && REG_P (XEXP (geu, 0))
   17120            0 :                && (GET_MODE (XEXP (geu, 0)) == CCCmode
   17121            0 :                    || GET_MODE (XEXP (geu, 0)) == CCmode)
   17122            0 :                && REGNO (XEXP (geu, 0)) == FLAGS_REG
   17123            0 :                && XEXP (geu, 1) == const0_rtx
   17124            0 :                && GET_CODE (op1) == LTU
   17125            0 :                && REG_P (XEXP (op1, 0))
   17126            0 :                && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   17127            0 :                && REGNO (XEXP (op1, 0)) == FLAGS_REG
   17128       951177 :                && XEXP (op1, 1) == const0_rtx)
   17129              :         return CCCmode;
   17130              :       /* Similarly for *x86_cmc pattern.
   17131              :          Match LTU of op0 (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   17132              :          and op1 (geu:QI (reg:CCC FLAGS_REG) (const_int 0)).
   17133              :          It is sufficient to test that the operand modes are CCCmode.  */
   17134       951177 :       else if (code == LTU
   17135       345568 :                && GET_CODE (op0) == NEG
   17136           18 :                && GET_CODE (XEXP (op0, 0)) == LTU
   17137            0 :                && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   17138            0 :                && GET_CODE (op1) == GEU
   17139            0 :                && GET_MODE (XEXP (op1, 0)) == CCCmode)
   17140              :         return CCCmode;
   17141              :       /* Similarly for the comparison of addcarry/subborrow pattern.  */
   17142       345568 :       else if (code == LTU
   17143       345568 :                && GET_CODE (op0) == ZERO_EXTEND
   17144        15583 :                && GET_CODE (op1) == PLUS
   17145        11179 :                && ix86_carry_flag_operator (XEXP (op1, 0), VOIDmode)
   17146        11179 :                && GET_CODE (XEXP (op1, 1)) == ZERO_EXTEND)
   17147              :         return CCCmode;
   17148              :       else
   17149       939998 :         return CCmode;
   17150              :     case GTU:                   /* CF=0 & ZF=0 */
   17151              :     case LEU:                   /* CF=1 | ZF=1 */
   17152              :       return CCmode;
   17153              :       /* Codes possibly doable only with sign flag when
   17154              :          comparing against zero.  */
   17155       827741 :     case GE:                    /* SF=OF   or   SF=0 */
   17156       827741 :     case LT:                    /* SF<>OF  or   SF=1 */
   17157       827741 :       if (op1 == const0_rtx)
   17158              :         return CCGOCmode;
   17159              :       else
   17160              :         /* For other cases Carry flag is not required.  */
   17161       450363 :         return CCGCmode;
   17162              :       /* Codes doable only with sign flag when comparing
   17163              :          against zero, but we miss jump instruction for it
   17164              :          so we need to use relational tests against overflow
   17165              :          that thus needs to be zero.  */
   17166       926318 :     case GT:                    /* ZF=0 & SF=OF */
   17167       926318 :     case LE:                    /* ZF=1 | SF<>OF */
   17168       926318 :       if (op1 == const0_rtx)
   17169              :         return CCNOmode;
   17170              :       else
   17171       620320 :         return CCGCmode;
   17172              :     default:
   17173              :       /* CCmode should be used in all other cases.  */
   17174              :       return CCmode;
   17175              :     }
   17176              : }
   17177              : 
   17178              : /* Return TRUE or FALSE depending on whether the ptest instruction
   17179              :    INSN has source and destination with suitable matching CC modes.  */
   17180              : 
   17181              : bool
   17182        91273 : ix86_match_ptest_ccmode (rtx insn)
   17183              : {
   17184        91273 :   rtx set, src;
   17185        91273 :   machine_mode set_mode;
   17186              : 
   17187        91273 :   set = PATTERN (insn);
   17188        91273 :   gcc_assert (GET_CODE (set) == SET);
   17189        91273 :   src = SET_SRC (set);
   17190        91273 :   gcc_assert (GET_CODE (src) == UNSPEC
   17191              :               && XINT (src, 1) == UNSPEC_PTEST);
   17192              : 
   17193        91273 :   set_mode = GET_MODE (src);
   17194        91273 :   if (set_mode != CCZmode
   17195              :       && set_mode != CCCmode
   17196              :       && set_mode != CCmode)
   17197              :     return false;
   17198        91273 :   return GET_MODE (SET_DEST (set)) == set_mode;
   17199              : }
   17200              : 
   17201              : /* Return the fixed registers used for condition codes.  */
   17202              : 
   17203              : static bool
   17204     18854128 : ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
   17205              : {
   17206     18854128 :   *p1 = FLAGS_REG;
   17207     18854128 :   *p2 = INVALID_REGNUM;
   17208     18854128 :   return true;
   17209              : }
   17210              : 
   17211              : /* If two condition code modes are compatible, return a condition code
   17212              :    mode which is compatible with both.  Otherwise, return
   17213              :    VOIDmode.  */
   17214              : 
   17215              : static machine_mode
   17216        31565 : ix86_cc_modes_compatible (machine_mode m1, machine_mode m2)
   17217              : {
   17218        31565 :   if (m1 == m2)
   17219              :     return m1;
   17220              : 
   17221        30418 :   if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
   17222              :     return VOIDmode;
   17223              : 
   17224        30418 :   if ((m1 == CCGCmode && m2 == CCGOCmode)
   17225        30418 :       || (m1 == CCGOCmode && m2 == CCGCmode))
   17226              :     return CCGCmode;
   17227              : 
   17228        30418 :   if ((m1 == CCNOmode && m2 == CCGOCmode)
   17229        30238 :       || (m1 == CCGOCmode && m2 == CCNOmode))
   17230              :     return CCNOmode;
   17231              : 
   17232        30126 :   if (m1 == CCZmode
   17233        16457 :       && (m2 == CCGCmode || m2 == CCGOCmode || m2 == CCNOmode))
   17234              :     return m2;
   17235        17581 :   else if (m2 == CCZmode
   17236        13413 :            && (m1 == CCGCmode || m1 == CCGOCmode || m1 == CCNOmode))
   17237              :     return m1;
   17238              : 
   17239         7407 :   switch (m1)
   17240              :     {
   17241            0 :     default:
   17242            0 :       gcc_unreachable ();
   17243              : 
   17244         7407 :     case E_CCmode:
   17245         7407 :     case E_CCGCmode:
   17246         7407 :     case E_CCGOCmode:
   17247         7407 :     case E_CCNOmode:
   17248         7407 :     case E_CCAmode:
   17249         7407 :     case E_CCCmode:
   17250         7407 :     case E_CCOmode:
   17251         7407 :     case E_CCPmode:
   17252         7407 :     case E_CCSmode:
   17253         7407 :     case E_CCZmode:
   17254         7407 :       switch (m2)
   17255              :         {
   17256              :         default:
   17257              :           return VOIDmode;
   17258              : 
   17259              :         case E_CCmode:
   17260              :         case E_CCGCmode:
   17261              :         case E_CCGOCmode:
   17262              :         case E_CCNOmode:
   17263              :         case E_CCAmode:
   17264              :         case E_CCCmode:
   17265              :         case E_CCOmode:
   17266              :         case E_CCPmode:
   17267              :         case E_CCSmode:
   17268              :         case E_CCZmode:
   17269              :           return CCmode;
   17270              :         }
   17271              : 
   17272              :     case E_CCFPmode:
   17273              :       /* These are only compatible with themselves, which we already
   17274              :          checked above.  */
   17275              :       return VOIDmode;
   17276              :     }
   17277              : }
   17278              : 
   17279              : /* Return strategy to use for floating-point.  We assume that fcomi is always
   17280              :    preferable where available, since that is also true when looking at size
   17281              :    (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test).  */
   17282              : 
   17283              : enum ix86_fpcmp_strategy
   17284      5595185 : ix86_fp_comparison_strategy (enum rtx_code)
   17285              : {
   17286              :   /* Do fcomi/sahf based test when profitable.  */
   17287              : 
   17288      5595185 :   if (TARGET_CMOVE)
   17289              :     return IX86_FPCMP_COMI;
   17290              : 
   17291            0 :   if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
   17292            0 :     return IX86_FPCMP_SAHF;
   17293              : 
   17294              :   return IX86_FPCMP_ARITH;
   17295              : }
   17296              : 
   17297              : /* Convert comparison codes we use to represent FP comparison to integer
   17298              :    code that will result in proper branch.  Return UNKNOWN if no such code
   17299              :    is available.  */
   17300              : 
   17301              : enum rtx_code
   17302       592764 : ix86_fp_compare_code_to_integer (enum rtx_code code)
   17303              : {
   17304       592764 :   switch (code)
   17305              :     {
   17306              :     case GT:
   17307              :       return GTU;
   17308        18315 :     case GE:
   17309        18315 :       return GEU;
   17310              :     case ORDERED:
   17311              :     case UNORDERED:
   17312              :       return code;
   17313       119746 :     case UNEQ:
   17314       119746 :       return EQ;
   17315        21423 :     case UNLT:
   17316        21423 :       return LTU;
   17317        32268 :     case UNLE:
   17318        32268 :       return LEU;
   17319       114157 :     case LTGT:
   17320       114157 :       return NE;
   17321          695 :     case EQ:
   17322          695 :     case NE:
   17323          695 :       if (TARGET_AVX10_2)
   17324              :         return code;
   17325              :       /* FALLTHRU.  */
   17326          265 :     default:
   17327          265 :       return UNKNOWN;
   17328              :     }
   17329              : }
   17330              : 
   17331              : /* Zero extend possibly SImode EXP to Pmode register.  */
   17332              : rtx
   17333        37873 : ix86_zero_extend_to_Pmode (rtx exp)
   17334              : {
   17335        49719 :   return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
   17336              : }
   17337              : 
   17338              : /* Return true if the function is called via PLT.   */
   17339              : 
   17340              : bool
   17341       985975 : ix86_call_use_plt_p (rtx call_op)
   17342              : {
   17343       985975 :   if (SYMBOL_REF_LOCAL_P (call_op))
   17344              :     {
   17345       196682 :       if (SYMBOL_REF_DECL (call_op)
   17346       196682 :           && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
   17347              :         {
   17348              :           /* NB: All ifunc functions must be called via PLT.  */
   17349       113454 :           cgraph_node *node
   17350       113454 :             = cgraph_node::get (SYMBOL_REF_DECL (call_op));
   17351       113454 :           if (node && node->ifunc_resolver)
   17352              :             return true;
   17353              :         }
   17354       196662 :       return false;
   17355              :     }
   17356              :   return true;
   17357              : }
   17358              : 
   17359              : /* Implement TARGET_IFUNC_REF_LOCAL_OK.  If this hook returns true,
   17360              :    the PLT entry will be used as the function address for local IFUNC
   17361              :    functions.  When the PIC register is needed for PLT call, indirect
   17362              :    call via the PLT entry will fail since the PIC register may not be
   17363              :    set up properly for indirect call.  In this case, we should return
   17364              :    false.  */
   17365              : 
   17366              : static bool
   17367    788129723 : ix86_ifunc_ref_local_ok (void)
   17368              : {
   17369    788129723 :   return !flag_pic || (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC);
   17370              : }
   17371              : 
   17372              : /* Return true if the function being called was marked with attribute
   17373              :    "noplt" or using -fno-plt and we are compiling for non-PIC.  We need
   17374              :    to handle the non-PIC case in the backend because there is no easy
   17375              :    interface for the front-end to force non-PLT calls to use the GOT.
   17376              :    This is currently used only with 64-bit or 32-bit GOT32X ELF targets
   17377              :    to call the function marked "noplt" indirectly.  */
   17378              : 
   17379              : bool
   17380      5978296 : ix86_nopic_noplt_attribute_p (rtx call_op)
   17381              : {
   17382      5491019 :   if (flag_pic || ix86_cmodel == CM_LARGE
   17383              :       || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
   17384              :       || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
   17385     11469315 :       || SYMBOL_REF_LOCAL_P (call_op))
   17386              :     return false;
   17387              : 
   17388      3830845 :   tree symbol_decl = SYMBOL_REF_DECL (call_op);
   17389              : 
   17390      3830845 :   if (!flag_plt
   17391      3830845 :       || (symbol_decl != NULL_TREE
   17392      3830813 :           && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl))))
   17393           34 :     return true;
   17394              : 
   17395              :   return false;
   17396              : }
   17397              : 
   17398              : /* Helper to output the jmp/call.  */
   17399              : static void
   17400           33 : ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno)
   17401              : {
   17402           33 :   if (thunk_name != NULL)
   17403              :     {
   17404           22 :       if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   17405            1 :           && ix86_indirect_branch_cs_prefix)
   17406            1 :         fprintf (asm_out_file, "\tcs\n");
   17407           22 :       fprintf (asm_out_file, "\tjmp\t");
   17408           22 :       assemble_name (asm_out_file, thunk_name);
   17409           22 :       putc ('\n', asm_out_file);
   17410           22 :       if ((ix86_harden_sls & harden_sls_indirect_jmp))
   17411            2 :         fputs ("\tint3\n", asm_out_file);
   17412              :     }
   17413              :   else
   17414           11 :     output_indirect_thunk (regno);
   17415           33 : }
   17416              : 
   17417              : /* Output indirect branch via a call and return thunk.  CALL_OP is a
   17418              :    register which contains the branch target.  XASM is the assembly
   17419              :    template for CALL_OP.  Branch is a tail call if SIBCALL_P is true.
   17420              :    A normal call is converted to:
   17421              : 
   17422              :         call __x86_indirect_thunk_reg
   17423              : 
   17424              :    and a tail call is converted to:
   17425              : 
   17426              :         jmp __x86_indirect_thunk_reg
   17427              :  */
   17428              : 
   17429              : static void
   17430           50 : ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
   17431              : {
   17432           50 :   char thunk_name_buf[32];
   17433           50 :   char *thunk_name;
   17434           50 :   enum indirect_thunk_prefix need_prefix
   17435           50 :     = indirect_thunk_need_prefix (current_output_insn);
   17436           50 :   int regno = REGNO (call_op);
   17437              : 
   17438           50 :   if (cfun->machine->indirect_branch_type
   17439           50 :       != indirect_branch_thunk_inline)
   17440              :     {
   17441           39 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   17442           16 :         SET_HARD_REG_BIT (indirect_thunks_used, regno);
   17443              : 
   17444           39 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   17445           39 :       thunk_name = thunk_name_buf;
   17446              :     }
   17447              :   else
   17448              :     thunk_name = NULL;
   17449              : 
   17450           50 :   if (sibcall_p)
   17451           27 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17452              :   else
   17453              :     {
   17454           23 :       if (thunk_name != NULL)
   17455              :         {
   17456           17 :           if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
   17457            1 :               && ix86_indirect_branch_cs_prefix)
   17458            1 :             fprintf (asm_out_file, "\tcs\n");
   17459           17 :           fprintf (asm_out_file, "\tcall\t");
   17460           17 :           assemble_name (asm_out_file, thunk_name);
   17461           17 :           putc ('\n', asm_out_file);
   17462           17 :           return;
   17463              :         }
   17464              : 
   17465            6 :       char indirectlabel1[32];
   17466            6 :       char indirectlabel2[32];
   17467              : 
   17468            6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   17469              :                                    INDIRECT_LABEL,
   17470              :                                    indirectlabelno++);
   17471            6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   17472              :                                    INDIRECT_LABEL,
   17473              :                                    indirectlabelno++);
   17474              : 
   17475              :       /* Jump.  */
   17476            6 :       fputs ("\tjmp\t", asm_out_file);
   17477            6 :       assemble_name_raw (asm_out_file, indirectlabel2);
   17478            6 :       fputc ('\n', asm_out_file);
   17479              : 
   17480            6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   17481              : 
   17482            6 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17483              : 
   17484            6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   17485              : 
   17486              :       /* Call.  */
   17487            6 :       fputs ("\tcall\t", asm_out_file);
   17488            6 :       assemble_name_raw (asm_out_file, indirectlabel1);
   17489            6 :       fputc ('\n', asm_out_file);
   17490              :     }
   17491              : }
   17492              : 
   17493              : /* Output indirect branch via a call and return thunk.  CALL_OP is
   17494              :    the branch target.  XASM is the assembly template for CALL_OP.
   17495              :    Branch is a tail call if SIBCALL_P is true.  A normal call is
   17496              :    converted to:
   17497              : 
   17498              :         jmp L2
   17499              :    L1:
   17500              :         push CALL_OP
   17501              :         jmp __x86_indirect_thunk
   17502              :    L2:
   17503              :         call L1
   17504              : 
   17505              :    and a tail call is converted to:
   17506              : 
   17507              :         push CALL_OP
   17508              :         jmp __x86_indirect_thunk
   17509              :  */
   17510              : 
   17511              : static void
   17512            0 : ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
   17513              :                                       bool sibcall_p)
   17514              : {
   17515            0 :   char thunk_name_buf[32];
   17516            0 :   char *thunk_name;
   17517            0 :   char push_buf[64];
   17518            0 :   enum indirect_thunk_prefix need_prefix
   17519            0 :     = indirect_thunk_need_prefix (current_output_insn);
   17520            0 :   int regno = -1;
   17521              : 
   17522            0 :   if (cfun->machine->indirect_branch_type
   17523            0 :       != indirect_branch_thunk_inline)
   17524              :     {
   17525            0 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   17526            0 :         indirect_thunk_needed = true;
   17527            0 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   17528            0 :       thunk_name = thunk_name_buf;
   17529              :     }
   17530              :   else
   17531              :     thunk_name = NULL;
   17532              : 
   17533            0 :   snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
   17534            0 :             TARGET_64BIT ? 'q' : 'l', xasm);
   17535              : 
   17536            0 :   if (sibcall_p)
   17537              :     {
   17538            0 :       output_asm_insn (push_buf, &call_op);
   17539            0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17540              :     }
   17541              :   else
   17542              :     {
   17543            0 :       char indirectlabel1[32];
   17544            0 :       char indirectlabel2[32];
   17545              : 
   17546            0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   17547              :                                    INDIRECT_LABEL,
   17548              :                                    indirectlabelno++);
   17549            0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   17550              :                                    INDIRECT_LABEL,
   17551              :                                    indirectlabelno++);
   17552              : 
   17553              :       /* Jump.  */
   17554            0 :       fputs ("\tjmp\t", asm_out_file);
   17555            0 :       assemble_name_raw (asm_out_file, indirectlabel2);
   17556            0 :       fputc ('\n', asm_out_file);
   17557              : 
   17558            0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   17559              : 
   17560              :       /* An external function may be called via GOT, instead of PLT.  */
   17561            0 :       if (MEM_P (call_op))
   17562              :         {
   17563            0 :           struct ix86_address parts;
   17564            0 :           rtx addr = XEXP (call_op, 0);
   17565            0 :           if (ix86_decompose_address (addr, &parts)
   17566            0 :               && parts.base == stack_pointer_rtx)
   17567              :             {
   17568              :               /* Since call will adjust stack by -UNITS_PER_WORD,
   17569              :                  we must convert "disp(stack, index, scale)" to
   17570              :                  "disp+UNITS_PER_WORD(stack, index, scale)".  */
   17571            0 :               if (parts.index)
   17572              :                 {
   17573            0 :                   addr = gen_rtx_MULT (Pmode, parts.index,
   17574              :                                        GEN_INT (parts.scale));
   17575            0 :                   addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   17576              :                                        addr);
   17577              :                 }
   17578              :               else
   17579              :                 addr = stack_pointer_rtx;
   17580              : 
   17581            0 :               rtx disp;
   17582            0 :               if (parts.disp != NULL_RTX)
   17583            0 :                 disp = plus_constant (Pmode, parts.disp,
   17584            0 :                                       UNITS_PER_WORD);
   17585              :               else
   17586            0 :                 disp = GEN_INT (UNITS_PER_WORD);
   17587              : 
   17588            0 :               addr = gen_rtx_PLUS (Pmode, addr, disp);
   17589            0 :               call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
   17590              :             }
   17591              :         }
   17592              : 
   17593            0 :       output_asm_insn (push_buf, &call_op);
   17594              : 
   17595            0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17596              : 
   17597            0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   17598              : 
   17599              :       /* Call.  */
   17600            0 :       fputs ("\tcall\t", asm_out_file);
   17601            0 :       assemble_name_raw (asm_out_file, indirectlabel1);
   17602            0 :       fputc ('\n', asm_out_file);
   17603              :     }
   17604            0 : }
   17605              : 
   17606              : /* Output indirect branch via a call and return thunk.  CALL_OP is
   17607              :    the branch target.  XASM is the assembly template for CALL_OP.
   17608              :    Branch is a tail call if SIBCALL_P is true.   */
   17609              : 
   17610              : static void
   17611           50 : ix86_output_indirect_branch (rtx call_op, const char *xasm,
   17612              :                              bool sibcall_p)
   17613              : {
   17614           50 :   if (REG_P (call_op))
   17615           50 :     ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
   17616              :   else
   17617            0 :     ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
   17618           50 : }
   17619              : 
   17620              : /* Output indirect jump.  CALL_OP is the jump target.  */
   17621              : 
   17622              : const char *
   17623         7836 : ix86_output_indirect_jmp (rtx call_op)
   17624              : {
   17625         7836 :   if (cfun->machine->indirect_branch_type != indirect_branch_keep)
   17626              :     {
   17627              :       /* We can't have red-zone since "call" in the indirect thunk
   17628              :          pushes the return address onto stack, destroying red-zone.  */
   17629            4 :       if (ix86_red_zone_used)
   17630            0 :         gcc_unreachable ();
   17631              : 
   17632            4 :       ix86_output_indirect_branch (call_op, "%0", true);
   17633              :     }
   17634              :   else
   17635         7832 :     output_asm_insn ("%!jmp\t%A0", &call_op);
   17636         7836 :   return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
   17637              : }
   17638              : 
   17639              : /* Output return instrumentation for current function if needed.  */
   17640              : 
   17641              : static void
   17642      1723420 : output_return_instrumentation (void)
   17643              : {
   17644      1723420 :   if (ix86_instrument_return != instrument_return_none
   17645            6 :       && flag_fentry
   17646      1723426 :       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
   17647              :     {
   17648            5 :       if (ix86_flag_record_return)
   17649            5 :         fprintf (asm_out_file, "1:\n");
   17650            5 :       switch (ix86_instrument_return)
   17651              :         {
   17652            2 :         case instrument_return_call:
   17653            2 :           fprintf (asm_out_file, "\tcall\t__return__\n");
   17654            2 :           break;
   17655            3 :         case instrument_return_nop5:
   17656              :           /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1)  */
   17657            3 :           fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   17658            3 :           break;
   17659              :         case instrument_return_none:
   17660              :           break;
   17661              :         }
   17662              : 
   17663            5 :       if (ix86_flag_record_return)
   17664              :         {
   17665            5 :           fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
   17666            5 :           fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   17667            5 :           fprintf (asm_out_file, "\t.previous\n");
   17668              :         }
   17669              :     }
   17670      1723420 : }
   17671              : 
   17672              : /* Output function return.  CALL_OP is the jump target.  Add a REP
   17673              :    prefix to RET if LONG_P is true and function return is kept.  */
   17674              : 
   17675              : const char *
   17676      1594702 : ix86_output_function_return (bool long_p)
   17677              : {
   17678      1594702 :   output_return_instrumentation ();
   17679              : 
   17680      1594702 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17681              :     {
   17682           17 :       char thunk_name[32];
   17683           17 :       enum indirect_thunk_prefix need_prefix
   17684           17 :         = indirect_thunk_need_prefix (current_output_insn);
   17685              : 
   17686           17 :       if (cfun->machine->function_return_type
   17687           17 :           != indirect_branch_thunk_inline)
   17688              :         {
   17689           12 :           bool need_thunk = (cfun->machine->function_return_type
   17690              :                              == indirect_branch_thunk);
   17691           12 :           indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
   17692              :                                true);
   17693           12 :           indirect_return_needed |= need_thunk;
   17694           12 :           fprintf (asm_out_file, "\tjmp\t");
   17695           12 :           assemble_name (asm_out_file, thunk_name);
   17696           12 :           putc ('\n', asm_out_file);
   17697              :         }
   17698              :       else
   17699            5 :         output_indirect_thunk (INVALID_REGNUM);
   17700              : 
   17701           17 :       return "";
   17702              :     }
   17703              : 
   17704      3188882 :   output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr);
   17705      1594685 :   return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
   17706              : }
   17707              : 
   17708              : /* Output indirect function return.  RET_OP is the function return
   17709              :    target.  */
   17710              : 
   17711              : const char *
   17712           17 : ix86_output_indirect_function_return (rtx ret_op)
   17713              : {
   17714           17 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17715              :     {
   17716            0 :       char thunk_name[32];
   17717            0 :       enum indirect_thunk_prefix need_prefix
   17718            0 :         = indirect_thunk_need_prefix (current_output_insn);
   17719            0 :       unsigned int regno = REGNO (ret_op);
   17720            0 :       gcc_assert (regno == CX_REG);
   17721              : 
   17722            0 :       if (cfun->machine->function_return_type
   17723            0 :           != indirect_branch_thunk_inline)
   17724              :         {
   17725            0 :           bool need_thunk = (cfun->machine->function_return_type
   17726              :                              == indirect_branch_thunk);
   17727            0 :           indirect_thunk_name (thunk_name, regno, need_prefix, true);
   17728              : 
   17729            0 :           if (need_thunk)
   17730              :             {
   17731            0 :               indirect_return_via_cx = true;
   17732            0 :               SET_HARD_REG_BIT (indirect_thunks_used, CX_REG);
   17733              :             }
   17734            0 :           fprintf (asm_out_file, "\tjmp\t");
   17735            0 :           assemble_name (asm_out_file, thunk_name);
   17736            0 :           putc ('\n', asm_out_file);
   17737              :         }
   17738              :       else
   17739            0 :         output_indirect_thunk (regno);
   17740              :     }
   17741              :   else
   17742              :     {
   17743           17 :       output_asm_insn ("%!jmp\t%A0", &ret_op);
   17744           17 :       if (ix86_harden_sls & harden_sls_indirect_jmp)
   17745            1 :         fputs ("\tint3\n", asm_out_file);
   17746              :     }
   17747           17 :   return "";
   17748              : }
   17749              : 
   17750              : /* Output the assembly for a call instruction.  */
   17751              : 
   17752              : const char *
   17753      6160405 : ix86_output_call_insn (rtx_insn *insn, rtx call_op)
   17754              : {
   17755      6160405 :   bool direct_p = constant_call_address_operand (call_op, VOIDmode);
   17756      6160405 :   bool output_indirect_p
   17757              :     = (!TARGET_SEH
   17758      6160405 :        && cfun->machine->indirect_branch_type != indirect_branch_keep);
   17759      6160405 :   bool seh_nop_p = false;
   17760      6160405 :   const char *xasm;
   17761              : 
   17762      6160405 :   if (SIBLING_CALL_P (insn))
   17763              :     {
   17764       128718 :       output_return_instrumentation ();
   17765       128718 :       if (direct_p)
   17766              :         {
   17767       119045 :           if (ix86_nopic_noplt_attribute_p (call_op))
   17768              :             {
   17769            4 :               direct_p = false;
   17770            4 :               if (TARGET_64BIT)
   17771              :                 {
   17772            4 :                   if (output_indirect_p)
   17773              :                     xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17774              :                   else
   17775            4 :                     xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17776              :                 }
   17777              :               else
   17778              :                 {
   17779            0 :                   if (output_indirect_p)
   17780              :                     xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17781              :                   else
   17782            0 :                     xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17783              :                 }
   17784              :             }
   17785              :           else
   17786              :             xasm = "%!jmp\t%P0";
   17787              :         }
   17788              :       /* SEH epilogue detection requires the indirect branch case
   17789              :          to include REX.W.  */
   17790         9673 :       else if (TARGET_SEH)
   17791              :         xasm = "%!rex.W jmp\t%A0";
   17792              :       else
   17793              :         {
   17794         9673 :           if (output_indirect_p)
   17795              :             xasm = "%0";
   17796              :           else
   17797         9650 :             xasm = "%!jmp\t%A0";
   17798              :         }
   17799              : 
   17800       128718 :       if (output_indirect_p && !direct_p)
   17801           23 :         ix86_output_indirect_branch (call_op, xasm, true);
   17802              :       else
   17803              :         {
   17804       128695 :           output_asm_insn (xasm, &call_op);
   17805       128695 :           if (!direct_p
   17806         9654 :               && (ix86_harden_sls & harden_sls_indirect_jmp))
   17807              :             return "int3";
   17808              :         }
   17809       128717 :       return "";
   17810              :     }
   17811              : 
   17812              :   /* SEH unwinding can require an extra nop to be emitted in several
   17813              :      circumstances.  Determine if we have one of those.  */
   17814      6031687 :   if (TARGET_SEH)
   17815              :     {
   17816              :       rtx_insn *i;
   17817              : 
   17818              :       for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
   17819              :         {
   17820              :           /* Prevent a catch region from being adjacent to a jump that would
   17821              :              be interpreted as an epilogue sequence by the unwinder.  */
   17822              :           if (JUMP_P(i) && CROSSING_JUMP_P (i))
   17823              :             {
   17824              :               seh_nop_p = true;
   17825              :               break;
   17826              :             }
   17827              : 
   17828              :           /* If we get to another real insn, we don't need the nop.  */
   17829              :           if (INSN_P (i))
   17830              :             break;
   17831              : 
   17832              :           /* If we get to the epilogue note, prevent a catch region from
   17833              :              being adjacent to the standard epilogue sequence.  Note that,
   17834              :              if non-call exceptions are enabled, we already did it during
   17835              :              epilogue expansion, or else, if the insn can throw internally,
   17836              :              we already did it during the reorg pass.  */
   17837              :           if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
   17838              :               && !flag_non_call_exceptions
   17839              :               && !can_throw_internal (insn))
   17840              :             {
   17841              :               seh_nop_p = true;
   17842              :               break;
   17843              :             }
   17844              :         }
   17845              : 
   17846              :       /* If we didn't find a real insn following the call, prevent the
   17847              :          unwinder from looking into the next function.  */
   17848              :       if (i == NULL)
   17849              :         seh_nop_p = true;
   17850              :     }
   17851              : 
   17852      6031687 :   if (direct_p)
   17853              :     {
   17854      5858229 :       if (ix86_nopic_noplt_attribute_p (call_op))
   17855              :         {
   17856            6 :           direct_p = false;
   17857            6 :           if (TARGET_64BIT)
   17858              :             {
   17859            6 :               if (output_indirect_p)
   17860              :                 xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17861              :               else
   17862            6 :                 xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17863              :             }
   17864              :           else
   17865              :             {
   17866            0 :               if (output_indirect_p)
   17867              :                 xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17868              :               else
   17869            0 :                 xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17870              :             }
   17871              :         }
   17872              :       else
   17873              :         xasm = "%!call\t%P0";
   17874              :     }
   17875              :   else
   17876              :     {
   17877       173458 :       if (output_indirect_p)
   17878              :         xasm = "%0";
   17879              :       else
   17880       173435 :         xasm = "%!call\t%A0";
   17881              :     }
   17882              : 
   17883      6031687 :   if (output_indirect_p && !direct_p)
   17884           23 :     ix86_output_indirect_branch (call_op, xasm, false);
   17885              :   else
   17886      6031664 :     output_asm_insn (xasm, &call_op);
   17887              : 
   17888              :   if (seh_nop_p)
   17889              :     return "nop";
   17890              : 
   17891              :   return "";
   17892              : }
   17893              : 
   17894              : /* Return a MEM corresponding to a stack slot with mode MODE.
   17895              :    Allocate a new slot if necessary.
   17896              : 
   17897              :    The RTL for a function can have several slots available: N is
   17898              :    which slot to use.  */
   17899              : 
   17900              : rtx
   17901        22440 : assign_386_stack_local (machine_mode mode, enum ix86_stack_slot n)
   17902              : {
   17903        22440 :   struct stack_local_entry *s;
   17904              : 
   17905        22440 :   gcc_assert (n < MAX_386_STACK_LOCALS);
   17906              : 
   17907        33838 :   for (s = ix86_stack_locals; s; s = s->next)
   17908        31235 :     if (s->mode == mode && s->n == n)
   17909        19837 :       return validize_mem (copy_rtx (s->rtl));
   17910              : 
   17911         2603 :   int align = 0;
   17912              :   /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
   17913              :      alignment with -m32 -mpreferred-stack-boundary=2.  */
   17914         2603 :   if (mode == DImode
   17915          329 :       && !TARGET_64BIT
   17916          329 :       && n == SLOT_FLOATxFDI_387
   17917         2932 :       && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
   17918              :     align = 32;
   17919         2603 :   s = ggc_alloc<stack_local_entry> ();
   17920         2603 :   s->n = n;
   17921         2603 :   s->mode = mode;
   17922         5206 :   s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
   17923              : 
   17924         2603 :   s->next = ix86_stack_locals;
   17925         2603 :   ix86_stack_locals = s;
   17926         2603 :   return validize_mem (copy_rtx (s->rtl));
   17927              : }
   17928              : 
   17929              : static void
   17930      1493935 : ix86_instantiate_decls (void)
   17931              : {
   17932      1493935 :   struct stack_local_entry *s;
   17933              : 
   17934      1493935 :   for (s = ix86_stack_locals; s; s = s->next)
   17935            0 :     if (s->rtl != NULL_RTX)
   17936            0 :       instantiate_decl_rtl (s->rtl);
   17937      1493935 : }
   17938              : 
   17939              : /* Check whether x86 address PARTS is a pc-relative address.  */
   17940              : 
   17941              : bool
   17942     26869346 : ix86_rip_relative_addr_p (struct ix86_address *parts)
   17943              : {
   17944     26869346 :   rtx base, index, disp;
   17945              : 
   17946     26869346 :   base = parts->base;
   17947     26869346 :   index = parts->index;
   17948     26869346 :   disp = parts->disp;
   17949              : 
   17950     26869346 :   if (disp && !base && !index)
   17951              :     {
   17952     25082763 :       if (TARGET_64BIT)
   17953              :         {
   17954     23417842 :           rtx symbol = disp;
   17955              : 
   17956     23417842 :           if (GET_CODE (disp) == CONST)
   17957      7063009 :             symbol = XEXP (disp, 0);
   17958     23417842 :           if (GET_CODE (symbol) == PLUS
   17959      6547925 :               && CONST_INT_P (XEXP (symbol, 1)))
   17960      6547925 :             symbol = XEXP (symbol, 0);
   17961              : 
   17962     23417842 :           if (LABEL_REF_P (symbol)
   17963     23410604 :               || (SYMBOL_REF_P (symbol)
   17964     22144168 :                   && SYMBOL_REF_TLS_MODEL (symbol) == 0)
   17965     24684278 :               || (GET_CODE (symbol) == UNSPEC
   17966       533943 :                   && (XINT (symbol, 1) == UNSPEC_GOTPCREL
   17967              :                       || XINT (symbol, 1) == UNSPEC_PCREL
   17968              :                       || XINT (symbol, 1) == UNSPEC_GOTNTPOFF)))
   17969     22657836 :             return true;
   17970              :         }
   17971              :     }
   17972              :   return false;
   17973              : }
   17974              : 
   17975              : /* Calculate the length of the memory address in the instruction encoding.
   17976              :    Includes addr32 prefix, does not include the one-byte modrm, opcode,
   17977              :    or other prefixes.  We never generate addr32 prefix for LEA insn.  */
   17978              : 
   17979              : int
   17980    275088234 : memory_address_length (rtx addr, bool lea)
   17981              : {
   17982    275088234 :   struct ix86_address parts;
   17983    275088234 :   rtx base, index, disp;
   17984    275088234 :   int len;
   17985    275088234 :   int ok;
   17986              : 
   17987    275088234 :   if (GET_CODE (addr) == PRE_DEC
   17988    266492826 :       || GET_CODE (addr) == POST_INC
   17989    261953029 :       || GET_CODE (addr) == PRE_MODIFY
   17990    261953029 :       || GET_CODE (addr) == POST_MODIFY)
   17991              :     return 0;
   17992              : 
   17993    261953029 :   ok = ix86_decompose_address (addr, &parts);
   17994    261953029 :   gcc_assert (ok);
   17995              : 
   17996    261953029 :   len = (parts.seg == ADDR_SPACE_GENERIC) ? 0 : 1;
   17997              : 
   17998              :   /*  If this is not LEA instruction, add the length of addr32 prefix.  */
   17999    223397926 :   if (TARGET_64BIT && !lea
   18000    459284371 :       && (SImode_address_operand (addr, VOIDmode)
   18001    197331105 :           || (parts.base && GET_MODE (parts.base) == SImode)
   18002    197320511 :           || (parts.index && GET_MODE (parts.index) == SImode)))
   18003        10831 :     len++;
   18004              : 
   18005    261953029 :   base = parts.base;
   18006    261953029 :   index = parts.index;
   18007    261953029 :   disp = parts.disp;
   18008              : 
   18009    261953029 :   if (base && SUBREG_P (base))
   18010            2 :     base = SUBREG_REG (base);
   18011    261953029 :   if (index && SUBREG_P (index))
   18012            0 :     index = SUBREG_REG (index);
   18013              : 
   18014    261953029 :   gcc_assert (base == NULL_RTX || REG_P (base));
   18015    261953029 :   gcc_assert (index == NULL_RTX || REG_P (index));
   18016              : 
   18017              :   /* Rule of thumb:
   18018              :        - esp as the base always wants an index,
   18019              :        - ebp as the base always wants a displacement,
   18020              :        - r12 as the base always wants an index,
   18021              :        - r13 as the base always wants a displacement.  */
   18022              : 
   18023              :   /* Register Indirect.  */
   18024    261953029 :   if (base && !index && !disp)
   18025              :     {
   18026              :       /* esp (for its index) and ebp (for its displacement) need
   18027              :          the two-byte modrm form.  Similarly for r12 and r13 in 64-bit
   18028              :          code.  */
   18029     17081861 :       if (base == arg_pointer_rtx
   18030     17081861 :           || base == frame_pointer_rtx
   18031     17081861 :           || REGNO (base) == SP_REG
   18032     10186972 :           || REGNO (base) == BP_REG
   18033     10186972 :           || REGNO (base) == R12_REG
   18034     26794598 :           || REGNO (base) == R13_REG)
   18035      7369124 :         len++;
   18036              :     }
   18037              : 
   18038              :   /* Direct Addressing.  In 64-bit mode mod 00 r/m 5
   18039              :      is not disp32, but disp32(%rip), so for disp32
   18040              :      SIB byte is needed, unless print_operand_address
   18041              :      optimizes it into disp32(%rip) or (%rip) is implied
   18042              :      by UNSPEC.  */
   18043    244871168 :   else if (disp && !base && !index)
   18044              :     {
   18045     24104027 :       len += 4;
   18046     24104027 :       if (!ix86_rip_relative_addr_p (&parts))
   18047      1852241 :         len++;
   18048              :     }
   18049              :   else
   18050              :     {
   18051              :       /* Find the length of the displacement constant.  */
   18052    220767141 :       if (disp)
   18053              :         {
   18054    216790774 :           if (base && satisfies_constraint_K (disp))
   18055    125572970 :             len += 1;
   18056              :           else
   18057     91217804 :             len += 4;
   18058              :         }
   18059              :       /* ebp always wants a displacement.  Similarly r13.  */
   18060      3976367 :       else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
   18061        10643 :         len++;
   18062              : 
   18063              :       /* An index requires the two-byte modrm form....  */
   18064    220767141 :       if (index
   18065              :           /* ...like esp (or r12), which always wants an index.  */
   18066    210504917 :           || base == arg_pointer_rtx
   18067    210504917 :           || base == frame_pointer_rtx
   18068    431272058 :           || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
   18069    158616521 :         len++;
   18070              :     }
   18071              : 
   18072              :   return len;
   18073              : }
   18074              : 
   18075              : /* Compute default value for "length_immediate" attribute.  When SHORTFORM
   18076              :    is set, expect that insn have 8bit immediate alternative.  */
   18077              : int
   18078    322328635 : ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
   18079              : {
   18080    322328635 :   int len = 0;
   18081    322328635 :   int i;
   18082    322328635 :   extract_insn_cached (insn);
   18083   1005789436 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   18084    683460801 :     if (CONSTANT_P (recog_data.operand[i]))
   18085              :       {
   18086    142020586 :         enum attr_mode mode = get_attr_mode (insn);
   18087              : 
   18088    142020586 :         gcc_assert (!len);
   18089    142020586 :         if (shortform && CONST_INT_P (recog_data.operand[i]))
   18090              :           {
   18091     38241076 :             HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
   18092     38241076 :             switch (mode)
   18093              :               {
   18094      1431590 :               case MODE_QI:
   18095      1431590 :                 len = 1;
   18096      1431590 :                 continue;
   18097       435459 :               case MODE_HI:
   18098       435459 :                 ival = trunc_int_for_mode (ival, HImode);
   18099       435459 :                 break;
   18100     16053418 :               case MODE_SI:
   18101     16053418 :                 ival = trunc_int_for_mode (ival, SImode);
   18102     16053418 :                 break;
   18103              :               default:
   18104              :                 break;
   18105              :               }
   18106     36809486 :             if (IN_RANGE (ival, -128, 127))
   18107              :               {
   18108     32669499 :                 len = 1;
   18109     32669499 :                 continue;
   18110              :               }
   18111              :           }
   18112    107919497 :         switch (mode)
   18113              :           {
   18114              :           case MODE_QI:
   18115              :             len = 1;
   18116              :             break;
   18117              :           case MODE_HI:
   18118    683460801 :             len = 2;
   18119              :             break;
   18120              :           case MODE_SI:
   18121    102547381 :             len = 4;
   18122              :             break;
   18123              :           /* Immediates for DImode instructions are encoded
   18124              :              as 32bit sign extended values.  */
   18125              :           case MODE_DI:
   18126    102547381 :             len = 4;
   18127              :             break;
   18128            0 :           default:
   18129            0 :             fatal_insn ("unknown insn mode", insn);
   18130              :         }
   18131              :       }
   18132    322328635 :   return len;
   18133              : }
   18134              : 
   18135              : /* Compute default value for "length_address" attribute.  */
   18136              : int
   18137    452380851 : ix86_attr_length_address_default (rtx_insn *insn)
   18138              : {
   18139    452380851 :   int i;
   18140              : 
   18141    452380851 :   if (get_attr_type (insn) == TYPE_LEA)
   18142              :     {
   18143     28815552 :       rtx set = PATTERN (insn), addr;
   18144              : 
   18145     28815552 :       if (GET_CODE (set) == PARALLEL)
   18146        86839 :         set = XVECEXP (set, 0, 0);
   18147              : 
   18148     28815552 :       gcc_assert (GET_CODE (set) == SET);
   18149              : 
   18150     28815552 :       addr = SET_SRC (set);
   18151              : 
   18152     28815552 :       return memory_address_length (addr, true);
   18153              :     }
   18154              : 
   18155    423565299 :   extract_insn_cached (insn);
   18156    974985997 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   18157              :     {
   18158    797407653 :       rtx op = recog_data.operand[i];
   18159    797407653 :       if (MEM_P (op))
   18160              :         {
   18161    246267471 :           constrain_operands_cached (insn, reload_completed);
   18162    246267471 :           if (which_alternative != -1)
   18163              :             {
   18164    246267471 :               const char *constraints = recog_data.constraints[i];
   18165    246267471 :               int alt = which_alternative;
   18166              : 
   18167    390656443 :               while (*constraints == '=' || *constraints == '+')
   18168    144388972 :                 constraints++;
   18169   1119615919 :               while (alt-- > 0)
   18170   2142574383 :                 while (*constraints++ != ',')
   18171              :                   ;
   18172              :               /* Skip ignored operands.  */
   18173    246267471 :               if (*constraints == 'X')
   18174       280516 :                 continue;
   18175              :             }
   18176              : 
   18177    245986955 :           int len = memory_address_length (XEXP (op, 0), false);
   18178              : 
   18179              :           /* Account for segment prefix for non-default addr spaces.  */
   18180    258779622 :           if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)))
   18181       784294 :             len++;
   18182              : 
   18183    245986955 :           return len;
   18184              :         }
   18185              :     }
   18186              :   return 0;
   18187              : }
   18188              : 
   18189              : /* Compute default value for "length_vex" attribute. It includes
   18190              :    2 or 3 byte VEX prefix and 1 opcode byte.  */
   18191              : 
   18192              : int
   18193      5064385 : ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
   18194              :                               bool has_vex_w)
   18195              : {
   18196      5064385 :   int i, reg_only = 2 + 1;
   18197      5064385 :   bool has_mem = false;
   18198              : 
   18199              :   /* Only 0f opcode can use 2 byte VEX prefix and  VEX W bit uses 3
   18200              :      byte VEX prefix.  */
   18201      5064385 :   if (!has_0f_opcode || has_vex_w)
   18202              :     return 3 + 1;
   18203              : 
   18204              :  /* We can always use 2 byte VEX prefix in 32bit.  */
   18205      4632407 :   if (!TARGET_64BIT)
   18206              :     return 2 + 1;
   18207              : 
   18208      3562139 :   extract_insn_cached (insn);
   18209              : 
   18210     11194997 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   18211      7924399 :     if (REG_P (recog_data.operand[i]))
   18212              :       {
   18213              :         /* REX.W bit uses 3 byte VEX prefix.
   18214              :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   18215      5225777 :         if (GET_MODE (recog_data.operand[i]) == DImode
   18216      5225777 :             && GENERAL_REG_P (recog_data.operand[i]))
   18217              :           return 3 + 1;
   18218              : 
   18219              :         /* REX.B bit requires 3-byte VEX. Right here we don't know which
   18220              :            operand will be encoded using VEX.B, so be conservative.
   18221              :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   18222      5213394 :         if (REX_INT_REGNO_P (recog_data.operand[i])
   18223      5213394 :             || REX2_INT_REGNO_P (recog_data.operand[i])
   18224      5213394 :             || REX_SSE_REGNO_P (recog_data.operand[i]))
   18225            0 :           reg_only = 3 + 1;
   18226              :       }
   18227      2698622 :     else if (MEM_P (recog_data.operand[i]))
   18228              :       {
   18229              :         /* REX2.X or REX2.B bits use 3 byte VEX prefix.  */
   18230      2061195 :         if (x86_extended_rex2reg_mentioned_p (recog_data.operand[i]))
   18231              :           return 4;
   18232              : 
   18233              :         /* REX.X or REX.B bits use 3 byte VEX prefix.  */
   18234      2060954 :         if (x86_extended_reg_mentioned_p (recog_data.operand[i]))
   18235              :           return 3 + 1;
   18236              : 
   18237              :         has_mem = true;
   18238              :       }
   18239              : 
   18240      3270598 :   return has_mem ? 2 + 1 : reg_only;
   18241              : }
   18242              : 
   18243              : 
   18244              : static bool
   18245              : ix86_class_likely_spilled_p (reg_class_t);
   18246              : 
   18247              : /* Returns true if lhs of insn is HW function argument register and set up
   18248              :    is_spilled to true if it is likely spilled HW register.  */
   18249              : static bool
   18250         1149 : insn_is_function_arg (rtx insn, bool* is_spilled)
   18251              : {
   18252         1149 :   rtx dst;
   18253              : 
   18254         1149 :   if (!NONDEBUG_INSN_P (insn))
   18255              :     return false;
   18256              :   /* Call instructions are not movable, ignore it.  */
   18257         1149 :   if (CALL_P (insn))
   18258              :     return false;
   18259         1075 :   insn = PATTERN (insn);
   18260         1075 :   if (GET_CODE (insn) == PARALLEL)
   18261           73 :     insn = XVECEXP (insn, 0, 0);
   18262         1075 :   if (GET_CODE (insn) != SET)
   18263              :     return false;
   18264         1075 :   dst = SET_DEST (insn);
   18265          979 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   18266         1948 :       && ix86_function_arg_regno_p (REGNO (dst)))
   18267              :     {
   18268              :       /* Is it likely spilled HW register?  */
   18269          873 :       if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
   18270          873 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
   18271          829 :         *is_spilled = true;
   18272          873 :       return true;
   18273              :     }
   18274              :   return false;
   18275              : }
   18276              : 
   18277              : /* Add output dependencies for chain of function adjacent arguments if only
   18278              :    there is a move to likely spilled HW register.  Return first argument
   18279              :    if at least one dependence was added or NULL otherwise.  */
   18280              : static rtx_insn *
   18281          415 : add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
   18282              : {
   18283          415 :   rtx_insn *insn;
   18284          415 :   rtx_insn *last = call;
   18285          415 :   rtx_insn *first_arg = NULL;
   18286          415 :   bool is_spilled = false;
   18287              : 
   18288          415 :   head = PREV_INSN (head);
   18289              : 
   18290              :   /* Find nearest to call argument passing instruction.  */
   18291          415 :   while (true)
   18292              :     {
   18293          415 :       last = PREV_INSN (last);
   18294          415 :       if (last == head)
   18295              :         return NULL;
   18296          415 :       if (!NONDEBUG_INSN_P (last))
   18297            0 :         continue;
   18298          415 :       if (insn_is_function_arg (last, &is_spilled))
   18299              :         break;
   18300              :       return NULL;
   18301              :     }
   18302              : 
   18303              :   first_arg = last;
   18304         1054 :   while (true)
   18305              :     {
   18306         1054 :       insn = PREV_INSN (last);
   18307         1054 :       if (!INSN_P (insn))
   18308              :         break;
   18309          956 :       if (insn == head)
   18310              :         break;
   18311          915 :       if (!NONDEBUG_INSN_P (insn))
   18312              :         {
   18313          181 :           last = insn;
   18314          181 :           continue;
   18315              :         }
   18316          734 :       if (insn_is_function_arg (insn, &is_spilled))
   18317              :         {
   18318              :           /* Add output dependence between two function arguments if chain
   18319              :              of output arguments contains likely spilled HW registers.  */
   18320          466 :           if (is_spilled)
   18321          466 :             add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   18322              :           first_arg = last = insn;
   18323              :         }
   18324              :       else
   18325              :         break;
   18326              :     }
   18327          407 :   if (!is_spilled)
   18328              :     return NULL;
   18329              :   return first_arg;
   18330              : }
   18331              : 
   18332              : /* Add output or anti dependency from insn to first_arg to restrict its code
   18333              :    motion.  */
   18334              : static void
   18335         2335 : avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
   18336              : {
   18337         2335 :   rtx set;
   18338         2335 :   rtx tmp;
   18339              : 
   18340         2335 :   set = single_set (insn);
   18341         2335 :   if (!set)
   18342              :     return;
   18343         1451 :   tmp = SET_DEST (set);
   18344         1451 :   if (REG_P (tmp))
   18345              :     {
   18346              :       /* Add output dependency to the first function argument.  */
   18347         1256 :       add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   18348         1256 :       return;
   18349              :     }
   18350              :   /* Add anti dependency.  */
   18351          195 :   add_dependence (first_arg, insn, REG_DEP_ANTI);
   18352              : }
   18353              : 
   18354              : /* Avoid cross block motion of function argument through adding dependency
   18355              :    from the first non-jump instruction in bb.  */
   18356              : static void
   18357           68 : add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
   18358              : {
   18359           68 :   rtx_insn *insn = BB_END (bb);
   18360              : 
   18361          134 :   while (insn)
   18362              :     {
   18363          134 :       if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
   18364              :         {
   18365           67 :           rtx set = single_set (insn);
   18366           67 :           if (set)
   18367              :             {
   18368           67 :               avoid_func_arg_motion (arg, insn);
   18369           67 :               return;
   18370              :             }
   18371              :         }
   18372           67 :       if (insn == BB_HEAD (bb))
   18373              :         return;
   18374           66 :       insn = PREV_INSN (insn);
   18375              :     }
   18376              : }
   18377              : 
   18378              : /* Hook for pre-reload schedule - avoid motion of function arguments
   18379              :    passed in likely spilled HW registers.  */
   18380              : static void
   18381     10350569 : ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
   18382              : {
   18383     10350569 :   rtx_insn *insn;
   18384     10350569 :   rtx_insn *first_arg = NULL;
   18385     10350569 :   if (reload_completed)
   18386              :     return;
   18387         2262 :   while (head != tail && DEBUG_INSN_P (head))
   18388          766 :     head = NEXT_INSN (head);
   18389        10999 :   for (insn = tail; insn != head; insn = PREV_INSN (insn))
   18390         9639 :     if (INSN_P (insn) && CALL_P (insn))
   18391              :       {
   18392          415 :         first_arg = add_parameter_dependencies (insn, head);
   18393          415 :         if (first_arg)
   18394              :           {
   18395              :             /* Add dependee for first argument to predecessors if only
   18396              :                region contains more than one block.  */
   18397          407 :             basic_block bb =  BLOCK_FOR_INSN (insn);
   18398          407 :             int rgn = CONTAINING_RGN (bb->index);
   18399          407 :             int nr_blks = RGN_NR_BLOCKS (rgn);
   18400              :             /* Skip trivial regions and region head blocks that can have
   18401              :                predecessors outside of region.  */
   18402          407 :             if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
   18403              :               {
   18404           67 :                 edge e;
   18405           67 :                 edge_iterator ei;
   18406              : 
   18407              :                 /* Regions are SCCs with the exception of selective
   18408              :                    scheduling with pipelining of outer blocks enabled.
   18409              :                    So also check that immediate predecessors of a non-head
   18410              :                    block are in the same region.  */
   18411          137 :                 FOR_EACH_EDGE (e, ei, bb->preds)
   18412              :                   {
   18413              :                     /* Avoid creating of loop-carried dependencies through
   18414              :                        using topological ordering in the region.  */
   18415           70 :                     if (rgn == CONTAINING_RGN (e->src->index)
   18416           69 :                         && BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
   18417           68 :                       add_dependee_for_func_arg (first_arg, e->src);
   18418              :                   }
   18419              :               }
   18420          407 :             insn = first_arg;
   18421          407 :             if (insn == head)
   18422              :               break;
   18423              :           }
   18424              :       }
   18425         9224 :     else if (first_arg)
   18426         2268 :       avoid_func_arg_motion (first_arg, insn);
   18427              : }
   18428              : 
   18429              : /* Hook for pre-reload schedule - set priority of moves from likely spilled
   18430              :    HW registers to maximum, to schedule them at soon as possible. These are
   18431              :    moves from function argument registers at the top of the function entry
   18432              :    and moves from function return value registers after call.  */
   18433              : static int
   18434    110871692 : ix86_adjust_priority (rtx_insn *insn, int priority)
   18435              : {
   18436    110871692 :   rtx set;
   18437              : 
   18438    110871692 :   if (reload_completed)
   18439              :     return priority;
   18440              : 
   18441        14711 :   if (!NONDEBUG_INSN_P (insn))
   18442              :     return priority;
   18443              : 
   18444        12653 :   set = single_set (insn);
   18445        12653 :   if (set)
   18446              :     {
   18447        12047 :       rtx tmp = SET_SRC (set);
   18448        12047 :       if (REG_P (tmp)
   18449         2537 :           && HARD_REGISTER_P (tmp)
   18450          501 :           && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
   18451        12047 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
   18452          450 :         return current_sched_info->sched_max_insns_priority;
   18453              :     }
   18454              : 
   18455              :   return priority;
   18456              : }
   18457              : 
   18458              : /* Prepare for scheduling pass.  */
   18459              : static void
   18460       970494 : ix86_sched_init_global (FILE *, int, int)
   18461              : {
   18462              :   /* Install scheduling hooks for current CPU.  Some of these hooks are used
   18463              :      in time-critical parts of the scheduler, so we only set them up when
   18464              :      they are actually used.  */
   18465       970494 :   switch (ix86_tune)
   18466              :     {
   18467       923886 :     case PROCESSOR_CORE2:
   18468       923886 :     case PROCESSOR_NEHALEM:
   18469       923886 :     case PROCESSOR_SANDYBRIDGE:
   18470       923886 :     case PROCESSOR_HASWELL:
   18471       923886 :     case PROCESSOR_TREMONT:
   18472       923886 :     case PROCESSOR_ALDERLAKE:
   18473       923886 :     case PROCESSOR_GENERIC:
   18474              :       /* Do not perform multipass scheduling for pre-reload schedule
   18475              :          to save compile time.  */
   18476       923886 :       if (reload_completed)
   18477              :         {
   18478       923399 :           ix86_core2i7_init_hooks ();
   18479       923399 :           break;
   18480              :         }
   18481              :       /* Fall through.  */
   18482        47095 :     default:
   18483        47095 :       targetm.sched.dfa_post_advance_cycle = NULL;
   18484        47095 :       targetm.sched.first_cycle_multipass_init = NULL;
   18485        47095 :       targetm.sched.first_cycle_multipass_begin = NULL;
   18486        47095 :       targetm.sched.first_cycle_multipass_issue = NULL;
   18487        47095 :       targetm.sched.first_cycle_multipass_backtrack = NULL;
   18488        47095 :       targetm.sched.first_cycle_multipass_end = NULL;
   18489        47095 :       targetm.sched.first_cycle_multipass_fini = NULL;
   18490        47095 :       break;
   18491              :     }
   18492       970494 : }
   18493              : 
   18494              : 
   18495              : /* Implement TARGET_STATIC_RTX_ALIGNMENT.  */
   18496              : 
   18497              : static HOST_WIDE_INT
   18498       730904 : ix86_static_rtx_alignment (machine_mode mode)
   18499              : {
   18500       730904 :   if (mode == DFmode)
   18501              :     return 64;
   18502              :   if (ALIGN_MODE_128 (mode))
   18503       158242 :     return MAX (128, GET_MODE_ALIGNMENT (mode));
   18504       486758 :   return GET_MODE_ALIGNMENT (mode);
   18505              : }
   18506              : 
   18507              : /* Implement TARGET_CONSTANT_ALIGNMENT.  */
   18508              : 
   18509              : static HOST_WIDE_INT
   18510      6811209 : ix86_constant_alignment (const_tree exp, HOST_WIDE_INT align)
   18511              : {
   18512      6811209 :   if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
   18513              :       || TREE_CODE (exp) == INTEGER_CST)
   18514              :     {
   18515       371861 :       machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   18516       371861 :       HOST_WIDE_INT mode_align = ix86_static_rtx_alignment (mode);
   18517       371861 :       return MAX (mode_align, align);
   18518              :     }
   18519      6296803 :   else if (!optimize_size && TREE_CODE (exp) == STRING_CST
   18520      9456130 :            && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
   18521              :     return BITS_PER_WORD;
   18522              : 
   18523              :   return align;
   18524              : }
   18525              : 
   18526              : /* Implement TARGET_EMPTY_RECORD_P.  */
   18527              : 
   18528              : static bool
   18529   1497983039 : ix86_is_empty_record (const_tree type)
   18530              : {
   18531   1497983039 :   if (!TARGET_64BIT)
   18532              :     return false;
   18533   1466729504 :   return default_is_empty_record (type);
   18534              : }
   18535              : 
   18536              : /* Implement TARGET_WARN_PARAMETER_PASSING_ABI.  */
   18537              : 
   18538              : static void
   18539     15435898 : ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
   18540              : {
   18541     15435898 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   18542              : 
   18543     15435898 :   if (!cum->warn_empty)
   18544              :     return;
   18545              : 
   18546     13174863 :   if (!TYPE_EMPTY_P (type))
   18547              :     return;
   18548              : 
   18549              :   /* Don't warn if the function isn't visible outside of the TU.  */
   18550        15224 :   if (cum->decl && !TREE_PUBLIC (cum->decl))
   18551              :     return;
   18552              : 
   18553        13740 :   tree decl = cum->decl;
   18554        13740 :   if (!decl)
   18555              :     /* If we don't know the target, look at the current TU.  */
   18556           39 :     decl = current_function_decl;
   18557              : 
   18558        13740 :   const_tree ctx = get_ultimate_context (decl);
   18559        13740 :   if (ctx == NULL_TREE
   18560        27446 :       || !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
   18561              :     return;
   18562              : 
   18563              :   /* If the actual size of the type is zero, then there is no change
   18564              :      in how objects of this size are passed.  */
   18565           72 :   if (int_size_in_bytes (type) == 0)
   18566              :     return;
   18567              : 
   18568           66 :   warning (OPT_Wabi, "empty class %qT parameter passing ABI "
   18569              :            "changes in %<-fabi-version=12%> (GCC 8)", type);
   18570              : 
   18571              :   /* Only warn once.  */
   18572           66 :   cum->warn_empty = false;
   18573              : }
   18574              : 
   18575              : /* This hook returns name of multilib ABI.  */
   18576              : 
   18577              : static const char *
   18578      3451359 : ix86_get_multilib_abi_name (void)
   18579              : {
   18580      3451359 :   if (!(TARGET_64BIT_P (ix86_isa_flags)))
   18581              :     return "i386";
   18582      3407187 :   else if (TARGET_X32_P (ix86_isa_flags))
   18583              :     return "x32";
   18584              :   else
   18585      3407187 :     return "x86_64";
   18586              : }
   18587              : 
   18588              : /* Compute the alignment for a variable for Intel MCU psABI.  TYPE is
   18589              :    the data type, and ALIGN is the alignment that the object would
   18590              :    ordinarily have.  */
   18591              : 
   18592              : static int
   18593            0 : iamcu_alignment (tree type, int align)
   18594              : {
   18595            0 :   machine_mode mode;
   18596              : 
   18597            0 :   if (align < 32 || TYPE_USER_ALIGN (type))
   18598              :     return align;
   18599              : 
   18600              :   /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4
   18601              :      bytes.  */
   18602            0 :   type = strip_array_types (type);
   18603            0 :   if (TYPE_ATOMIC (type))
   18604              :     return align;
   18605              : 
   18606            0 :   mode = TYPE_MODE (type);
   18607            0 :   switch (GET_MODE_CLASS (mode))
   18608              :     {
   18609              :     case MODE_INT:
   18610              :     case MODE_COMPLEX_INT:
   18611              :     case MODE_COMPLEX_FLOAT:
   18612              :     case MODE_FLOAT:
   18613              :     case MODE_DECIMAL_FLOAT:
   18614              :       return 32;
   18615              :     default:
   18616              :       return align;
   18617              :     }
   18618              : }
   18619              : 
   18620              : /* Compute the alignment for a static variable.
   18621              :    TYPE is the data type, and ALIGN is the alignment that
   18622              :    the object would ordinarily have.  The value of this function is used
   18623              :    instead of that alignment to align the object.  */
   18624              : 
   18625              : int
   18626     12100865 : ix86_data_alignment (tree type, unsigned int align, bool opt)
   18627              : {
   18628              :   /* GCC 4.8 and earlier used to incorrectly assume this alignment even
   18629              :      for symbols from other compilation units or symbols that don't need
   18630              :      to bind locally.  In order to preserve some ABI compatibility with
   18631              :      those compilers, ensure we don't decrease alignment from what we
   18632              :      used to assume.  */
   18633              : 
   18634     12100865 :   unsigned int max_align_compat = MIN (256, MAX_OFILE_ALIGNMENT);
   18635              : 
   18636              :   /* A data structure, equal or greater than the size of a cache line
   18637              :      (64 bytes in the Pentium 4 and other recent Intel processors, including
   18638              :      processors based on Intel Core microarchitecture) should be aligned
   18639              :      so that its base address is a multiple of a cache line size.  */
   18640              : 
   18641     24201730 :   unsigned int max_align
   18642     12100865 :     = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
   18643              : 
   18644     14690849 :   if (max_align < BITS_PER_WORD)
   18645            0 :     max_align = BITS_PER_WORD;
   18646              : 
   18647     12100865 :   switch (ix86_align_data_type)
   18648              :     {
   18649     12100865 :     case ix86_align_data_type_abi: opt = false; break;
   18650     12100845 :     case ix86_align_data_type_compat: max_align = BITS_PER_WORD; break;
   18651              :     case ix86_align_data_type_cacheline: break;
   18652              :     }
   18653              : 
   18654     12100865 :   if (TARGET_IAMCU)
   18655            0 :     align = iamcu_alignment (type, align);
   18656              : 
   18657     12100865 :   if (opt
   18658      5816988 :       && AGGREGATE_TYPE_P (type)
   18659      3731042 :       && TYPE_SIZE (type)
   18660     15831855 :       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
   18661              :     {
   18662      6760439 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align_compat)
   18663      3730990 :           && align < max_align_compat)
   18664       701541 :         align = max_align_compat;
   18665      7398616 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align)
   18666      3730990 :           && align < max_align)
   18667        63364 :         align = max_align;
   18668              :     }
   18669              : 
   18670              :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18671              :      to 16byte boundary.  */
   18672     12100865 :   if (TARGET_64BIT)
   18673              :     {
   18674      4988126 :       if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
   18675      3284669 :           && TYPE_SIZE (type)
   18676      3284607 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18677     10953866 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18678     11575900 :           && align < 128)
   18679       622034 :         return 128;
   18680              :     }
   18681              : 
   18682     11478831 :   if (!opt)
   18683      6087151 :     return align;
   18684              : 
   18685      5391680 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18686              :     {
   18687      1107554 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18688              :         return 64;
   18689      1107554 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18690              :         return 128;
   18691              :     }
   18692      4284126 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18693              :     {
   18694              : 
   18695        13003 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18696              :         return 64;
   18697        13003 :       if ((TYPE_MODE (type) == XCmode
   18698        13003 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18699              :         return 128;
   18700              :     }
   18701      4271123 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18702      4271123 :            && TYPE_FIELDS (type))
   18703              :     {
   18704      2196421 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18705              :         return 64;
   18706      2196421 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18707              :         return 128;
   18708              :     }
   18709      2074702 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18710              :            || TREE_CODE (type) == INTEGER_TYPE)
   18711              :     {
   18712      1923401 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18713              :         return 64;
   18714      1923401 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18715              :         return 128;
   18716              :     }
   18717              : 
   18718      5391565 :   return align;
   18719              : }
   18720              : 
   18721              : /* Implement TARGET_LOWER_LOCAL_DECL_ALIGNMENT.  */
   18722              : static void
   18723     32648666 : ix86_lower_local_decl_alignment (tree decl)
   18724              : {
   18725     32648666 :   unsigned int new_align = ix86_local_alignment (decl, VOIDmode,
   18726     32648666 :                                                  DECL_ALIGN (decl), true);
   18727     32648666 :   if (new_align < DECL_ALIGN (decl))
   18728            0 :     SET_DECL_ALIGN (decl, new_align);
   18729     32648666 : }
   18730              : 
   18731              : /* Compute the alignment for a local variable or a stack slot.  EXP is
   18732              :    the data type or decl itself, MODE is the widest mode available and
   18733              :    ALIGN is the alignment that the object would ordinarily have.  The
   18734              :    value of this macro is used instead of that alignment to align the
   18735              :    object.  */
   18736              : 
   18737              : unsigned int
   18738     50449332 : ix86_local_alignment (tree exp, machine_mode mode,
   18739              :                       unsigned int align, bool may_lower)
   18740              : {
   18741     50449332 :   tree type, decl;
   18742              : 
   18743     50449332 :   if (exp && DECL_P (exp))
   18744              :     {
   18745     48264171 :       type = TREE_TYPE (exp);
   18746     48264171 :       decl = exp;
   18747              :     }
   18748              :   else
   18749              :     {
   18750              :       type = exp;
   18751              :       decl = NULL;
   18752              :     }
   18753              : 
   18754              :   /* Don't do dynamic stack realignment for long long objects with
   18755              :      -mpreferred-stack-boundary=2.  */
   18756     50449332 :   if (may_lower
   18757     32648666 :       && !TARGET_64BIT
   18758       249703 :       && align == 64
   18759        38968 :       && ix86_preferred_stack_boundary < 64
   18760            0 :       && (mode == DImode || (type && TYPE_MODE (type) == DImode))
   18761            0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18762            0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18763     50449332 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18764              :     align = 32;
   18765              : 
   18766              :   /* If TYPE is NULL, we are allocating a stack slot for caller-save
   18767              :      register in MODE.  We will return the largest alignment of XF
   18768              :      and DF.  */
   18769     50449332 :   if (!type)
   18770              :     {
   18771      1430565 :       if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
   18772         1513 :         align = GET_MODE_ALIGNMENT (DFmode);
   18773      1430565 :       return align;
   18774              :     }
   18775              : 
   18776              :   /* Don't increase alignment for Intel MCU psABI.  */
   18777     49018767 :   if (TARGET_IAMCU)
   18778              :     return align;
   18779              : 
   18780              :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18781              :      to 16byte boundary.  Exact wording is:
   18782              : 
   18783              :      An array uses the same alignment as its elements, except that a local or
   18784              :      global array variable of length at least 16 bytes or
   18785              :      a C99 variable-length array variable always has alignment of at least 16 bytes.
   18786              : 
   18787              :      This was added to allow use of aligned SSE instructions at arrays.  This
   18788              :      rule is meant for static storage (where compiler cannot do the analysis
   18789              :      by itself).  We follow it for automatic variables only when convenient.
   18790              :      We fully control everything in the function compiled and functions from
   18791              :      other unit cannot rely on the alignment.
   18792              : 
   18793              :      Exclude va_list type.  It is the common case of local array where
   18794              :      we cannot benefit from the alignment.
   18795              : 
   18796              :      TODO: Probably one should optimize for size only when var is not escaping.  */
   18797     46182898 :   if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
   18798     94843898 :       && TARGET_SSE)
   18799              :     {
   18800     45785407 :       if (AGGREGATE_TYPE_P (type)
   18801      9797276 :           && (va_list_type_node == NULL_TREE
   18802      9797276 :               || (TYPE_MAIN_VARIANT (type)
   18803      9797276 :                   != TYPE_MAIN_VARIANT (va_list_type_node)))
   18804      9697827 :           && TYPE_SIZE (type)
   18805      9697827 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18806     46898566 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18807     52917634 :           && align < 128)
   18808      6019068 :         return 128;
   18809              :     }
   18810     42999699 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18811              :     {
   18812       807144 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18813              :         return 64;
   18814       807144 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18815              :         return 128;
   18816              :     }
   18817     42192555 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18818              :     {
   18819       159882 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18820              :         return 64;
   18821       159882 :       if ((TYPE_MODE (type) == XCmode
   18822       159882 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18823              :         return 128;
   18824              :     }
   18825     42032673 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18826     42032673 :            && TYPE_FIELDS (type))
   18827              :     {
   18828      4947636 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18829              :         return 64;
   18830      4944531 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18831              :         return 128;
   18832              :     }
   18833     37085037 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18834              :            || TREE_CODE (type) == INTEGER_TYPE)
   18835              :     {
   18836              : 
   18837     30520899 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18838              :         return 64;
   18839     30520899 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18840              :         return 128;
   18841              :     }
   18842              :   return align;
   18843              : }
   18844              : 
   18845              : /* Compute the minimum required alignment for dynamic stack realignment
   18846              :    purposes for a local variable, parameter or a stack slot.  EXP is
   18847              :    the data type or decl itself, MODE is its mode and ALIGN is the
   18848              :    alignment that the object would ordinarily have.  */
   18849              : 
   18850              : unsigned int
   18851     48687269 : ix86_minimum_alignment (tree exp, machine_mode mode,
   18852              :                         unsigned int align)
   18853              : {
   18854     48687269 :   tree type, decl;
   18855              : 
   18856     48687269 :   if (exp && DECL_P (exp))
   18857              :     {
   18858     15485770 :       type = TREE_TYPE (exp);
   18859     15485770 :       decl = exp;
   18860              :     }
   18861              :   else
   18862              :     {
   18863              :       type = exp;
   18864              :       decl = NULL;
   18865              :     }
   18866              : 
   18867     48687269 :   if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
   18868              :     return align;
   18869              : 
   18870              :   /* Don't do dynamic stack realignment for long long objects with
   18871              :      -mpreferred-stack-boundary=2.  */
   18872            0 :   if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
   18873            0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18874            0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18875            0 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18876              :     {
   18877            0 :       gcc_checking_assert (!TARGET_STV);
   18878              :       return 32;
   18879              :     }
   18880              : 
   18881              :   return align;
   18882              : }
   18883              : 
   18884              : /* Find a location for the static chain incoming to a nested function.
   18885              :    This is a register, unless all free registers are used by arguments.  */
   18886              : 
   18887              : static rtx
   18888       270260 : ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
   18889              : {
   18890       270260 :   unsigned regno;
   18891              : 
   18892       270260 :   if (TARGET_64BIT)
   18893              :     {
   18894              :       /* We always use R10 in 64-bit mode.  */
   18895              :       regno = R10_REG;
   18896              :     }
   18897              :   else
   18898              :     {
   18899        88353 :       const_tree fntype, fndecl;
   18900        88353 :       unsigned int ccvt;
   18901              : 
   18902              :       /* By default in 32-bit mode we use ECX to pass the static chain.  */
   18903        88353 :       regno = CX_REG;
   18904              : 
   18905        88353 :       if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
   18906              :         {
   18907        78379 :           fntype = TREE_TYPE (fndecl_or_type);
   18908        78379 :           fndecl = fndecl_or_type;
   18909              :         }
   18910              :       else
   18911              :         {
   18912              :           fntype = fndecl_or_type;
   18913              :           fndecl = NULL;
   18914              :         }
   18915              : 
   18916        88353 :       ccvt = ix86_get_callcvt (fntype);
   18917        88353 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   18918              :         {
   18919              :           /* Fastcall functions use ecx/edx for arguments, which leaves
   18920              :              us with EAX for the static chain.
   18921              :              Thiscall functions use ecx for arguments, which also
   18922              :              leaves us with EAX for the static chain.  */
   18923              :           regno = AX_REG;
   18924              :         }
   18925        88353 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   18926              :         {
   18927              :           /* Thiscall functions use ecx for arguments, which leaves
   18928              :              us with EAX and EDX for the static chain.
   18929              :              We are using for abi-compatibility EAX.  */
   18930              :           regno = AX_REG;
   18931              :         }
   18932        88353 :       else if (ix86_function_regparm (fntype, fndecl) == 3)
   18933              :         {
   18934              :           /* For regparm 3, we have no free call-clobbered registers in
   18935              :              which to store the static chain.  In order to implement this,
   18936              :              we have the trampoline push the static chain to the stack.
   18937              :              However, we can't push a value below the return address when
   18938              :              we call the nested function directly, so we have to use an
   18939              :              alternate entry point.  For this we use ESI, and have the
   18940              :              alternate entry point push ESI, so that things appear the
   18941              :              same once we're executing the nested function.  */
   18942            0 :           if (incoming_p)
   18943              :             {
   18944            0 :               if (fndecl == current_function_decl
   18945            0 :                   && !ix86_static_chain_on_stack)
   18946              :                 {
   18947            0 :                   gcc_assert (!reload_completed);
   18948            0 :                   ix86_static_chain_on_stack = true;
   18949              :                 }
   18950            0 :               return gen_frame_mem (SImode,
   18951            0 :                                     plus_constant (Pmode,
   18952              :                                                    arg_pointer_rtx, -8));
   18953              :             }
   18954              :           regno = SI_REG;
   18955              :         }
   18956              :     }
   18957              : 
   18958       358626 :   return gen_rtx_REG (Pmode, regno);
   18959              : }
   18960              : 
   18961              : /* Emit RTL insns to initialize the variable parts of a trampoline.
   18962              :    FNDECL is the decl of the target address; M_TRAMP is a MEM for
   18963              :    the trampoline, and CHAIN_VALUE is an RTX for the static chain
   18964              :    to be passed to the target function.  */
   18965              : 
   18966              : static void
   18967          306 : ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   18968              : {
   18969          306 :   rtx mem, fnaddr;
   18970          306 :   int opcode;
   18971          306 :   int offset = 0;
   18972          306 :   bool need_endbr = (flag_cf_protection & CF_BRANCH);
   18973              : 
   18974          306 :   fnaddr = XEXP (DECL_RTL (fndecl), 0);
   18975              : 
   18976          306 :   if (TARGET_64BIT)
   18977              :     {
   18978          306 :       int size;
   18979              : 
   18980          306 :       if (need_endbr)
   18981              :         {
   18982              :           /* Insert ENDBR64.  */
   18983            1 :           mem = adjust_address (m_tramp, SImode, offset);
   18984            1 :           emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
   18985            1 :           offset += 4;
   18986              :         }
   18987              : 
   18988              :       /* Load the function address to r11.  Try to load address using
   18989              :          the shorter movl instead of movabs.  We may want to support
   18990              :          movq for kernel mode, but kernel does not use trampolines at
   18991              :          the moment.  FNADDR is a 32bit address and may not be in
   18992              :          DImode when ptr_mode == SImode.  Always use movl in this
   18993              :          case.  */
   18994          306 :       if (ptr_mode == SImode
   18995          306 :           || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
   18996              :         {
   18997          274 :           fnaddr = copy_addr_to_reg (fnaddr);
   18998              : 
   18999          274 :           mem = adjust_address (m_tramp, HImode, offset);
   19000          274 :           emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
   19001              : 
   19002          274 :           mem = adjust_address (m_tramp, SImode, offset + 2);
   19003          274 :           emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
   19004          274 :           offset += 6;
   19005              :         }
   19006              :       else
   19007              :         {
   19008           32 :           mem = adjust_address (m_tramp, HImode, offset);
   19009           32 :           emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
   19010              : 
   19011           32 :           mem = adjust_address (m_tramp, DImode, offset + 2);
   19012           32 :           emit_move_insn (mem, fnaddr);
   19013           32 :           offset += 10;
   19014              :         }
   19015              : 
   19016              :       /* Load static chain using movabs to r10.  Use the shorter movl
   19017              :          instead of movabs when ptr_mode == SImode.  */
   19018          306 :       if (ptr_mode == SImode)
   19019              :         {
   19020              :           opcode = 0xba41;
   19021              :           size = 6;
   19022              :         }
   19023              :       else
   19024              :         {
   19025          306 :           opcode = 0xba49;
   19026          306 :           size = 10;
   19027              :         }
   19028              : 
   19029          306 :       mem = adjust_address (m_tramp, HImode, offset);
   19030          306 :       emit_move_insn (mem, gen_int_mode (opcode, HImode));
   19031              : 
   19032          306 :       mem = adjust_address (m_tramp, ptr_mode, offset + 2);
   19033          306 :       emit_move_insn (mem, chain_value);
   19034          306 :       offset += size;
   19035              : 
   19036              :       /* Jump to r11; the last (unused) byte is a nop, only there to
   19037              :          pad the write out to a single 32-bit store.  */
   19038          306 :       mem = adjust_address (m_tramp, SImode, offset);
   19039          306 :       emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
   19040          306 :       offset += 4;
   19041              :     }
   19042              :   else
   19043              :     {
   19044            0 :       rtx disp, chain;
   19045              : 
   19046              :       /* Depending on the static chain location, either load a register
   19047              :          with a constant, or push the constant to the stack.  All of the
   19048              :          instructions are the same size.  */
   19049            0 :       chain = ix86_static_chain (fndecl, true);
   19050            0 :       if (REG_P (chain))
   19051              :         {
   19052            0 :           switch (REGNO (chain))
   19053              :             {
   19054              :             case AX_REG:
   19055              :               opcode = 0xb8; break;
   19056            0 :             case CX_REG:
   19057            0 :               opcode = 0xb9; break;
   19058            0 :             default:
   19059            0 :               gcc_unreachable ();
   19060              :             }
   19061              :         }
   19062              :       else
   19063              :         opcode = 0x68;
   19064              : 
   19065            0 :       if (need_endbr)
   19066              :         {
   19067              :           /* Insert ENDBR32.  */
   19068            0 :           mem = adjust_address (m_tramp, SImode, offset);
   19069            0 :           emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
   19070            0 :           offset += 4;
   19071              :         }
   19072              : 
   19073            0 :       mem = adjust_address (m_tramp, QImode, offset);
   19074            0 :       emit_move_insn (mem, gen_int_mode (opcode, QImode));
   19075              : 
   19076            0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   19077            0 :       emit_move_insn (mem, chain_value);
   19078            0 :       offset += 5;
   19079              : 
   19080            0 :       mem = adjust_address (m_tramp, QImode, offset);
   19081            0 :       emit_move_insn (mem, gen_int_mode (0xe9, QImode));
   19082              : 
   19083            0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   19084              : 
   19085              :       /* Compute offset from the end of the jmp to the target function.
   19086              :          In the case in which the trampoline stores the static chain on
   19087              :          the stack, we need to skip the first insn which pushes the
   19088              :          (call-saved) register static chain; this push is 1 byte.  */
   19089            0 :       offset += 5;
   19090            0 :       int skip = MEM_P (chain) ? 1 : 0;
   19091              :       /* Skip ENDBR32 at the entry of the target function.  */
   19092            0 :       if (need_endbr
   19093            0 :           && !cgraph_node::get (fndecl)->only_called_directly_p ())
   19094            0 :         skip += 4;
   19095            0 :       disp = expand_binop (SImode, sub_optab, fnaddr,
   19096            0 :                            plus_constant (Pmode, XEXP (m_tramp, 0),
   19097            0 :                                           offset - skip),
   19098              :                            NULL_RTX, 1, OPTAB_DIRECT);
   19099            0 :       emit_move_insn (mem, disp);
   19100              :     }
   19101              : 
   19102          306 :   gcc_assert (offset <= TRAMPOLINE_SIZE);
   19103              : 
   19104              : #ifdef HAVE_ENABLE_EXECUTE_STACK
   19105              : #ifdef CHECK_EXECUTE_STACK_ENABLED
   19106              :   if (CHECK_EXECUTE_STACK_ENABLED)
   19107              : #endif
   19108              :   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
   19109              :                      LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
   19110              : #endif
   19111          306 : }
   19112              : 
   19113              : static bool
   19114     61617551 : ix86_allocate_stack_slots_for_args (void)
   19115              : {
   19116              :   /* Naked functions should not allocate stack slots for arguments.  */
   19117     61617551 :   return !ix86_function_naked (current_function_decl);
   19118              : }
   19119              : 
   19120              : static bool
   19121     39602034 : ix86_warn_func_return (tree decl)
   19122              : {
   19123              :   /* Naked functions are implemented entirely in assembly, including the
   19124              :      return sequence, so suppress warnings about this.  */
   19125     39602034 :   return !ix86_function_naked (decl);
   19126              : }
   19127              : 
   19128              : /* Return the shift count of a vector by scalar shift builtin second argument
   19129              :    ARG1.  */
   19130              : static tree
   19131        14142 : ix86_vector_shift_count (tree arg1)
   19132              : {
   19133        14142 :   if (tree_fits_uhwi_p (arg1))
   19134              :     return arg1;
   19135         8316 :   else if (TREE_CODE (arg1) == VECTOR_CST && CHAR_BIT == 8)
   19136              :     {
   19137              :       /* The count argument is weird, passed in as various 128-bit
   19138              :          (or 64-bit) vectors, the low 64 bits from it are the count.  */
   19139          162 :       unsigned char buf[16];
   19140          162 :       int len = native_encode_expr (arg1, buf, 16);
   19141          162 :       if (len == 0)
   19142          162 :         return NULL_TREE;
   19143          162 :       tree t = native_interpret_expr (uint64_type_node, buf, len);
   19144          162 :       if (t && tree_fits_uhwi_p (t))
   19145              :         return t;
   19146              :     }
   19147              :   return NULL_TREE;
   19148              : }
   19149              : 
   19150              : /* Return true if arg_mask is all ones, ELEMS is elements number of
   19151              :    corresponding vector.  */
   19152              : static bool
   19153        25042 : ix86_masked_all_ones (unsigned HOST_WIDE_INT elems, tree arg_mask)
   19154              : {
   19155        25042 :   if (TREE_CODE (arg_mask) != INTEGER_CST)
   19156              :     return false;
   19157              : 
   19158         7462 :   unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg_mask);
   19159         7462 :   if (elems == HOST_BITS_PER_WIDE_INT)
   19160           33 :     return  mask == HOST_WIDE_INT_M1U;
   19161         7429 :   if ((mask | (HOST_WIDE_INT_M1U << elems)) != HOST_WIDE_INT_M1U)
   19162         2681 :     return false;
   19163              : 
   19164              :   return true;
   19165              : }
   19166              : 
   19167              : static tree
   19168     68331744 : ix86_fold_builtin (tree fndecl, int n_args,
   19169              :                    tree *args, bool ignore ATTRIBUTE_UNUSED)
   19170              : {
   19171     68331744 :   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
   19172              :     {
   19173     68331744 :       enum ix86_builtins fn_code
   19174     68331744 :         = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   19175     68331744 :       enum rtx_code rcode;
   19176     68331744 :       bool is_vshift;
   19177     68331744 :       enum tree_code tcode;
   19178     68331744 :       bool is_scalar;
   19179     68331744 :       unsigned HOST_WIDE_INT mask;
   19180              : 
   19181     68331744 :       switch (fn_code)
   19182              :         {
   19183         8966 :         case IX86_BUILTIN_CPU_IS:
   19184         8966 :         case IX86_BUILTIN_CPU_SUPPORTS:
   19185         8966 :           gcc_assert (n_args == 1);
   19186         8966 :           return fold_builtin_cpu (fndecl, args);
   19187              : 
   19188        26005 :         case IX86_BUILTIN_NANQ:
   19189        26005 :         case IX86_BUILTIN_NANSQ:
   19190        26005 :           {
   19191        26005 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19192        26005 :             const char *str = c_getstr (*args);
   19193        26005 :             int quiet = fn_code == IX86_BUILTIN_NANQ;
   19194        26005 :             REAL_VALUE_TYPE real;
   19195              : 
   19196        26005 :             if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
   19197        26005 :               return build_real (type, real);
   19198            0 :             return NULL_TREE;
   19199              :           }
   19200              : 
   19201          108 :         case IX86_BUILTIN_INFQ:
   19202          108 :         case IX86_BUILTIN_HUGE_VALQ:
   19203          108 :           {
   19204          108 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19205          108 :             REAL_VALUE_TYPE inf;
   19206          108 :             real_inf (&inf);
   19207          108 :             return build_real (type, inf);
   19208              :           }
   19209              : 
   19210        62501 :         case IX86_BUILTIN_TZCNT16:
   19211        62501 :         case IX86_BUILTIN_CTZS:
   19212        62501 :         case IX86_BUILTIN_TZCNT32:
   19213        62501 :         case IX86_BUILTIN_TZCNT64:
   19214        62501 :           gcc_assert (n_args == 1);
   19215        62501 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   19216              :             {
   19217           45 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19218           45 :               tree arg = args[0];
   19219           45 :               if (fn_code == IX86_BUILTIN_TZCNT16
   19220           45 :                   || fn_code == IX86_BUILTIN_CTZS)
   19221            3 :                 arg = fold_convert (short_unsigned_type_node, arg);
   19222           45 :               if (integer_zerop (arg))
   19223            6 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   19224              :               else
   19225           39 :                 return fold_const_call (CFN_CTZ, type, arg);
   19226              :             }
   19227              :           break;
   19228              : 
   19229        52043 :         case IX86_BUILTIN_LZCNT16:
   19230        52043 :         case IX86_BUILTIN_CLZS:
   19231        52043 :         case IX86_BUILTIN_LZCNT32:
   19232        52043 :         case IX86_BUILTIN_LZCNT64:
   19233        52043 :           gcc_assert (n_args == 1);
   19234        52043 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   19235              :             {
   19236           54 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19237           54 :               tree arg = args[0];
   19238           54 :               if (fn_code == IX86_BUILTIN_LZCNT16
   19239           54 :                   || fn_code == IX86_BUILTIN_CLZS)
   19240           18 :                 arg = fold_convert (short_unsigned_type_node, arg);
   19241           54 :               if (integer_zerop (arg))
   19242            3 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   19243              :               else
   19244           51 :                 return fold_const_call (CFN_CLZ, type, arg);
   19245              :             }
   19246              :           break;
   19247              : 
   19248        61289 :         case IX86_BUILTIN_BEXTR32:
   19249        61289 :         case IX86_BUILTIN_BEXTR64:
   19250        61289 :         case IX86_BUILTIN_BEXTRI32:
   19251        61289 :         case IX86_BUILTIN_BEXTRI64:
   19252        61289 :           gcc_assert (n_args == 2);
   19253        61289 :           if (tree_fits_uhwi_p (args[1]))
   19254              :             {
   19255          152 :               unsigned HOST_WIDE_INT res = 0;
   19256          152 :               unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
   19257          152 :               unsigned int start = tree_to_uhwi (args[1]);
   19258          152 :               unsigned int len = (start & 0xff00) >> 8;
   19259          152 :               tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
   19260          152 :               start &= 0xff;
   19261          152 :               if (start >= prec || len == 0)
   19262          111 :                 return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
   19263              :                                          args[0]);
   19264           41 :               else if (!tree_fits_uhwi_p (args[0]))
   19265              :                 break;
   19266              :               else
   19267           24 :                 res = tree_to_uhwi (args[0]) >> start;
   19268           24 :               if (len > prec)
   19269              :                 len = prec;
   19270           24 :               if (len < HOST_BITS_PER_WIDE_INT)
   19271           15 :                 res &= (HOST_WIDE_INT_1U << len) - 1;
   19272           24 :               return build_int_cstu (lhs_type, res);
   19273              :             }
   19274              :           break;
   19275              : 
   19276        21044 :         case IX86_BUILTIN_BZHI32:
   19277        21044 :         case IX86_BUILTIN_BZHI64:
   19278        21044 :           gcc_assert (n_args == 2);
   19279        21044 :           if (tree_fits_uhwi_p (args[1]))
   19280              :             {
   19281          190 :               unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
   19282          190 :               tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
   19283          190 :               if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
   19284              :                 return args[0];
   19285          190 :               if (idx == 0)
   19286           52 :                 return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
   19287              :                                          args[0]);
   19288          138 :               if (!tree_fits_uhwi_p (args[0]))
   19289              :                 break;
   19290           12 :               unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
   19291           12 :               res &= ~(HOST_WIDE_INT_M1U << idx);
   19292           12 :               return build_int_cstu (lhs_type, res);
   19293              :             }
   19294              :           break;
   19295              : 
   19296        20810 :         case IX86_BUILTIN_PDEP32:
   19297        20810 :         case IX86_BUILTIN_PDEP64:
   19298        20810 :           gcc_assert (n_args == 2);
   19299        20810 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   19300              :             {
   19301           46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   19302           46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   19303           46 :               unsigned HOST_WIDE_INT res = 0;
   19304           46 :               unsigned HOST_WIDE_INT m, k = 1;
   19305         2990 :               for (m = 1; m; m <<= 1)
   19306         2944 :                 if ((mask & m) != 0)
   19307              :                   {
   19308         1440 :                     if ((src & k) != 0)
   19309          789 :                       res |= m;
   19310         1440 :                     k <<= 1;
   19311              :                   }
   19312           46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   19313              :             }
   19314              :           break;
   19315              : 
   19316        20812 :         case IX86_BUILTIN_PEXT32:
   19317        20812 :         case IX86_BUILTIN_PEXT64:
   19318        20812 :           gcc_assert (n_args == 2);
   19319        20812 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   19320              :             {
   19321           46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   19322           46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   19323           46 :               unsigned HOST_WIDE_INT res = 0;
   19324           46 :               unsigned HOST_WIDE_INT m, k = 1;
   19325         2990 :               for (m = 1; m; m <<= 1)
   19326         2944 :                 if ((mask & m) != 0)
   19327              :                   {
   19328         2016 :                     if ((src & m) != 0)
   19329         1063 :                       res |= k;
   19330         2016 :                     k <<= 1;
   19331              :                   }
   19332           46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   19333              :             }
   19334              :           break;
   19335              : 
   19336       127062 :         case IX86_BUILTIN_MOVMSKPS:
   19337       127062 :         case IX86_BUILTIN_PMOVMSKB:
   19338       127062 :         case IX86_BUILTIN_MOVMSKPD:
   19339       127062 :         case IX86_BUILTIN_PMOVMSKB128:
   19340       127062 :         case IX86_BUILTIN_MOVMSKPD256:
   19341       127062 :         case IX86_BUILTIN_MOVMSKPS256:
   19342       127062 :         case IX86_BUILTIN_PMOVMSKB256:
   19343       127062 :           gcc_assert (n_args == 1);
   19344       127062 :           if (TREE_CODE (args[0]) == VECTOR_CST)
   19345              :             {
   19346              :               HOST_WIDE_INT res = 0;
   19347         3213 :               for (unsigned i = 0; i < VECTOR_CST_NELTS (args[0]); ++i)
   19348              :                 {
   19349         2620 :                   tree e = VECTOR_CST_ELT (args[0], i);
   19350         2620 :                   if (TREE_CODE (e) == INTEGER_CST && !TREE_OVERFLOW (e))
   19351              :                     {
   19352         1168 :                       if (wi::neg_p (wi::to_wide (e)))
   19353         1119 :                         res |= HOST_WIDE_INT_1 << i;
   19354              :                     }
   19355         1452 :                   else if (TREE_CODE (e) == REAL_CST && !TREE_OVERFLOW (e))
   19356              :                     {
   19357         1452 :                       if (TREE_REAL_CST (e).sign)
   19358         1215 :                         res |= HOST_WIDE_INT_1 << i;
   19359              :                     }
   19360              :                   else
   19361              :                     return NULL_TREE;
   19362              :                 }
   19363          593 :               return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
   19364              :             }
   19365              :           break;
   19366              : 
   19367       660338 :         case IX86_BUILTIN_PSLLD:
   19368       660338 :         case IX86_BUILTIN_PSLLD128:
   19369       660338 :         case IX86_BUILTIN_PSLLD128_MASK:
   19370       660338 :         case IX86_BUILTIN_PSLLD256:
   19371       660338 :         case IX86_BUILTIN_PSLLD256_MASK:
   19372       660338 :         case IX86_BUILTIN_PSLLD512:
   19373       660338 :         case IX86_BUILTIN_PSLLDI:
   19374       660338 :         case IX86_BUILTIN_PSLLDI128:
   19375       660338 :         case IX86_BUILTIN_PSLLDI128_MASK:
   19376       660338 :         case IX86_BUILTIN_PSLLDI256:
   19377       660338 :         case IX86_BUILTIN_PSLLDI256_MASK:
   19378       660338 :         case IX86_BUILTIN_PSLLDI512:
   19379       660338 :         case IX86_BUILTIN_PSLLQ:
   19380       660338 :         case IX86_BUILTIN_PSLLQ128:
   19381       660338 :         case IX86_BUILTIN_PSLLQ128_MASK:
   19382       660338 :         case IX86_BUILTIN_PSLLQ256:
   19383       660338 :         case IX86_BUILTIN_PSLLQ256_MASK:
   19384       660338 :         case IX86_BUILTIN_PSLLQ512:
   19385       660338 :         case IX86_BUILTIN_PSLLQI:
   19386       660338 :         case IX86_BUILTIN_PSLLQI128:
   19387       660338 :         case IX86_BUILTIN_PSLLQI128_MASK:
   19388       660338 :         case IX86_BUILTIN_PSLLQI256:
   19389       660338 :         case IX86_BUILTIN_PSLLQI256_MASK:
   19390       660338 :         case IX86_BUILTIN_PSLLQI512:
   19391       660338 :         case IX86_BUILTIN_PSLLW:
   19392       660338 :         case IX86_BUILTIN_PSLLW128:
   19393       660338 :         case IX86_BUILTIN_PSLLW128_MASK:
   19394       660338 :         case IX86_BUILTIN_PSLLW256:
   19395       660338 :         case IX86_BUILTIN_PSLLW256_MASK:
   19396       660338 :         case IX86_BUILTIN_PSLLW512_MASK:
   19397       660338 :         case IX86_BUILTIN_PSLLWI:
   19398       660338 :         case IX86_BUILTIN_PSLLWI128:
   19399       660338 :         case IX86_BUILTIN_PSLLWI128_MASK:
   19400       660338 :         case IX86_BUILTIN_PSLLWI256:
   19401       660338 :         case IX86_BUILTIN_PSLLWI256_MASK:
   19402       660338 :         case IX86_BUILTIN_PSLLWI512_MASK:
   19403       660338 :           rcode = ASHIFT;
   19404       660338 :           is_vshift = false;
   19405       660338 :           goto do_shift;
   19406       601973 :         case IX86_BUILTIN_PSRAD:
   19407       601973 :         case IX86_BUILTIN_PSRAD128:
   19408       601973 :         case IX86_BUILTIN_PSRAD128_MASK:
   19409       601973 :         case IX86_BUILTIN_PSRAD256:
   19410       601973 :         case IX86_BUILTIN_PSRAD256_MASK:
   19411       601973 :         case IX86_BUILTIN_PSRAD512:
   19412       601973 :         case IX86_BUILTIN_PSRADI:
   19413       601973 :         case IX86_BUILTIN_PSRADI128:
   19414       601973 :         case IX86_BUILTIN_PSRADI128_MASK:
   19415       601973 :         case IX86_BUILTIN_PSRADI256:
   19416       601973 :         case IX86_BUILTIN_PSRADI256_MASK:
   19417       601973 :         case IX86_BUILTIN_PSRADI512:
   19418       601973 :         case IX86_BUILTIN_PSRAQ128_MASK:
   19419       601973 :         case IX86_BUILTIN_PSRAQ256_MASK:
   19420       601973 :         case IX86_BUILTIN_PSRAQ512:
   19421       601973 :         case IX86_BUILTIN_PSRAQI128_MASK:
   19422       601973 :         case IX86_BUILTIN_PSRAQI256_MASK:
   19423       601973 :         case IX86_BUILTIN_PSRAQI512:
   19424       601973 :         case IX86_BUILTIN_PSRAW:
   19425       601973 :         case IX86_BUILTIN_PSRAW128:
   19426       601973 :         case IX86_BUILTIN_PSRAW128_MASK:
   19427       601973 :         case IX86_BUILTIN_PSRAW256:
   19428       601973 :         case IX86_BUILTIN_PSRAW256_MASK:
   19429       601973 :         case IX86_BUILTIN_PSRAW512:
   19430       601973 :         case IX86_BUILTIN_PSRAWI:
   19431       601973 :         case IX86_BUILTIN_PSRAWI128:
   19432       601973 :         case IX86_BUILTIN_PSRAWI128_MASK:
   19433       601973 :         case IX86_BUILTIN_PSRAWI256:
   19434       601973 :         case IX86_BUILTIN_PSRAWI256_MASK:
   19435       601973 :         case IX86_BUILTIN_PSRAWI512:
   19436       601973 :           rcode = ASHIFTRT;
   19437       601973 :           is_vshift = false;
   19438       601973 :           goto do_shift;
   19439       634257 :         case IX86_BUILTIN_PSRLD:
   19440       634257 :         case IX86_BUILTIN_PSRLD128:
   19441       634257 :         case IX86_BUILTIN_PSRLD128_MASK:
   19442       634257 :         case IX86_BUILTIN_PSRLD256:
   19443       634257 :         case IX86_BUILTIN_PSRLD256_MASK:
   19444       634257 :         case IX86_BUILTIN_PSRLD512:
   19445       634257 :         case IX86_BUILTIN_PSRLDI:
   19446       634257 :         case IX86_BUILTIN_PSRLDI128:
   19447       634257 :         case IX86_BUILTIN_PSRLDI128_MASK:
   19448       634257 :         case IX86_BUILTIN_PSRLDI256:
   19449       634257 :         case IX86_BUILTIN_PSRLDI256_MASK:
   19450       634257 :         case IX86_BUILTIN_PSRLDI512:
   19451       634257 :         case IX86_BUILTIN_PSRLQ:
   19452       634257 :         case IX86_BUILTIN_PSRLQ128:
   19453       634257 :         case IX86_BUILTIN_PSRLQ128_MASK:
   19454       634257 :         case IX86_BUILTIN_PSRLQ256:
   19455       634257 :         case IX86_BUILTIN_PSRLQ256_MASK:
   19456       634257 :         case IX86_BUILTIN_PSRLQ512:
   19457       634257 :         case IX86_BUILTIN_PSRLQI:
   19458       634257 :         case IX86_BUILTIN_PSRLQI128:
   19459       634257 :         case IX86_BUILTIN_PSRLQI128_MASK:
   19460       634257 :         case IX86_BUILTIN_PSRLQI256:
   19461       634257 :         case IX86_BUILTIN_PSRLQI256_MASK:
   19462       634257 :         case IX86_BUILTIN_PSRLQI512:
   19463       634257 :         case IX86_BUILTIN_PSRLW:
   19464       634257 :         case IX86_BUILTIN_PSRLW128:
   19465       634257 :         case IX86_BUILTIN_PSRLW128_MASK:
   19466       634257 :         case IX86_BUILTIN_PSRLW256:
   19467       634257 :         case IX86_BUILTIN_PSRLW256_MASK:
   19468       634257 :         case IX86_BUILTIN_PSRLW512:
   19469       634257 :         case IX86_BUILTIN_PSRLWI:
   19470       634257 :         case IX86_BUILTIN_PSRLWI128:
   19471       634257 :         case IX86_BUILTIN_PSRLWI128_MASK:
   19472       634257 :         case IX86_BUILTIN_PSRLWI256:
   19473       634257 :         case IX86_BUILTIN_PSRLWI256_MASK:
   19474       634257 :         case IX86_BUILTIN_PSRLWI512:
   19475       634257 :           rcode = LSHIFTRT;
   19476       634257 :           is_vshift = false;
   19477       634257 :           goto do_shift;
   19478       276266 :         case IX86_BUILTIN_PSLLVV16HI:
   19479       276266 :         case IX86_BUILTIN_PSLLVV16SI:
   19480       276266 :         case IX86_BUILTIN_PSLLVV2DI:
   19481       276266 :         case IX86_BUILTIN_PSLLVV2DI_MASK:
   19482       276266 :         case IX86_BUILTIN_PSLLVV32HI:
   19483       276266 :         case IX86_BUILTIN_PSLLVV4DI:
   19484       276266 :         case IX86_BUILTIN_PSLLVV4DI_MASK:
   19485       276266 :         case IX86_BUILTIN_PSLLVV4SI:
   19486       276266 :         case IX86_BUILTIN_PSLLVV4SI_MASK:
   19487       276266 :         case IX86_BUILTIN_PSLLVV8DI:
   19488       276266 :         case IX86_BUILTIN_PSLLVV8HI:
   19489       276266 :         case IX86_BUILTIN_PSLLVV8SI:
   19490       276266 :         case IX86_BUILTIN_PSLLVV8SI_MASK:
   19491       276266 :           rcode = ASHIFT;
   19492       276266 :           is_vshift = true;
   19493       276266 :           goto do_shift;
   19494       275847 :         case IX86_BUILTIN_PSRAVQ128:
   19495       275847 :         case IX86_BUILTIN_PSRAVQ256:
   19496       275847 :         case IX86_BUILTIN_PSRAVV16HI:
   19497       275847 :         case IX86_BUILTIN_PSRAVV16SI:
   19498       275847 :         case IX86_BUILTIN_PSRAVV32HI:
   19499       275847 :         case IX86_BUILTIN_PSRAVV4SI:
   19500       275847 :         case IX86_BUILTIN_PSRAVV4SI_MASK:
   19501       275847 :         case IX86_BUILTIN_PSRAVV8DI:
   19502       275847 :         case IX86_BUILTIN_PSRAVV8HI:
   19503       275847 :         case IX86_BUILTIN_PSRAVV8SI:
   19504       275847 :         case IX86_BUILTIN_PSRAVV8SI_MASK:
   19505       275847 :           rcode = ASHIFTRT;
   19506       275847 :           is_vshift = true;
   19507       275847 :           goto do_shift;
   19508       276257 :         case IX86_BUILTIN_PSRLVV16HI:
   19509       276257 :         case IX86_BUILTIN_PSRLVV16SI:
   19510       276257 :         case IX86_BUILTIN_PSRLVV2DI:
   19511       276257 :         case IX86_BUILTIN_PSRLVV2DI_MASK:
   19512       276257 :         case IX86_BUILTIN_PSRLVV32HI:
   19513       276257 :         case IX86_BUILTIN_PSRLVV4DI:
   19514       276257 :         case IX86_BUILTIN_PSRLVV4DI_MASK:
   19515       276257 :         case IX86_BUILTIN_PSRLVV4SI:
   19516       276257 :         case IX86_BUILTIN_PSRLVV4SI_MASK:
   19517       276257 :         case IX86_BUILTIN_PSRLVV8DI:
   19518       276257 :         case IX86_BUILTIN_PSRLVV8HI:
   19519       276257 :         case IX86_BUILTIN_PSRLVV8SI:
   19520       276257 :         case IX86_BUILTIN_PSRLVV8SI_MASK:
   19521       276257 :           rcode = LSHIFTRT;
   19522       276257 :           is_vshift = true;
   19523       276257 :           goto do_shift;
   19524              : 
   19525      2724938 :         do_shift:
   19526      2724938 :           gcc_assert (n_args >= 2);
   19527      2724938 :           if (TREE_CODE (args[0]) != VECTOR_CST)
   19528              :             break;
   19529          927 :           mask = HOST_WIDE_INT_M1U;
   19530          927 :           if (n_args > 2)
   19531              :             {
   19532              :               /* This is masked shift.  */
   19533          678 :               if (!tree_fits_uhwi_p (args[n_args - 1])
   19534          678 :                   || TREE_SIDE_EFFECTS (args[n_args - 2]))
   19535              :                 break;
   19536          678 :               mask = tree_to_uhwi (args[n_args - 1]);
   19537          678 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19538          678 :               mask |= HOST_WIDE_INT_M1U << elems;
   19539          678 :               if (mask != HOST_WIDE_INT_M1U
   19540          567 :                   && TREE_CODE (args[n_args - 2]) != VECTOR_CST)
   19541              :                 break;
   19542          633 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   19543              :                 return args[n_args - 2];
   19544              :             }
   19545          879 :           if (is_vshift && TREE_CODE (args[1]) != VECTOR_CST)
   19546              :             break;
   19547          879 :           if (tree tem = (is_vshift ? integer_one_node
   19548          879 :                           : ix86_vector_shift_count (args[1])))
   19549              :             {
   19550          558 :               unsigned HOST_WIDE_INT count = tree_to_uhwi (tem);
   19551          558 :               unsigned HOST_WIDE_INT prec
   19552          558 :                 = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (args[0])));
   19553          558 :               if (count == 0 && mask == HOST_WIDE_INT_M1U)
   19554              :                 return args[0];
   19555          558 :               if (count >= prec)
   19556              :                 {
   19557           72 :                   if (rcode == ASHIFTRT)
   19558           27 :                     count = prec - 1;
   19559           45 :                   else if (mask == HOST_WIDE_INT_M1U)
   19560            3 :                     return build_zero_cst (TREE_TYPE (args[0]));
   19561              :                 }
   19562          555 :               tree countt = NULL_TREE;
   19563          555 :               if (!is_vshift)
   19564              :                 {
   19565          377 :                   if (count >= prec)
   19566           42 :                     countt = integer_zero_node;
   19567              :                   else
   19568          335 :                     countt = build_int_cst (integer_type_node, count);
   19569              :                 }
   19570          555 :               tree_vector_builder builder;
   19571          555 :               if (mask != HOST_WIDE_INT_M1U || is_vshift)
   19572          392 :                 builder.new_vector (TREE_TYPE (args[0]),
   19573          784 :                                     TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0])),
   19574              :                                     1);
   19575              :               else
   19576          163 :                 builder.new_unary_operation (TREE_TYPE (args[0]), args[0],
   19577              :                                              false);
   19578          555 :               unsigned int cnt = builder.encoded_nelts ();
   19579         5967 :               for (unsigned int i = 0; i < cnt; ++i)
   19580              :                 {
   19581         5412 :                   tree elt = VECTOR_CST_ELT (args[0], i);
   19582         5412 :                   if (TREE_CODE (elt) != INTEGER_CST || TREE_OVERFLOW (elt))
   19583            0 :                     return NULL_TREE;
   19584         5412 :                   tree type = TREE_TYPE (elt);
   19585         5412 :                   if (rcode == LSHIFTRT)
   19586         2040 :                     elt = fold_convert (unsigned_type_for (type), elt);
   19587         5412 :                   if (is_vshift)
   19588              :                     {
   19589         1846 :                       countt = VECTOR_CST_ELT (args[1], i);
   19590         1846 :                       if (TREE_CODE (countt) != INTEGER_CST
   19591         1846 :                           || TREE_OVERFLOW (countt))
   19592              :                         return NULL_TREE;
   19593         1846 :                       if (wi::neg_p (wi::to_wide (countt))
   19594         3610 :                           || wi::to_widest (countt) >= prec)
   19595              :                         {
   19596          325 :                           if (rcode == ASHIFTRT)
   19597          108 :                             countt = build_int_cst (TREE_TYPE (countt),
   19598          108 :                                                     prec - 1);
   19599              :                           else
   19600              :                             {
   19601          217 :                               elt = build_zero_cst (TREE_TYPE (elt));
   19602          217 :                               countt = build_zero_cst (TREE_TYPE (countt));
   19603              :                             }
   19604              :                         }
   19605              :                     }
   19606         3566 :                   else if (count >= prec)
   19607          504 :                     elt = build_zero_cst (TREE_TYPE (elt));
   19608         8950 :                   elt = const_binop (rcode == ASHIFT
   19609              :                                      ? LSHIFT_EXPR : RSHIFT_EXPR,
   19610         5412 :                                      TREE_TYPE (elt), elt, countt);
   19611         5412 :                   if (!elt || TREE_CODE (elt) != INTEGER_CST)
   19612              :                     return NULL_TREE;
   19613         5412 :                   if (rcode == LSHIFTRT)
   19614         2040 :                     elt = fold_convert (type, elt);
   19615         5412 :                   if ((mask & (HOST_WIDE_INT_1U << i)) == 0)
   19616              :                     {
   19617         1566 :                       elt = VECTOR_CST_ELT (args[n_args - 2], i);
   19618         1566 :                       if (TREE_CODE (elt) != INTEGER_CST
   19619         1566 :                           || TREE_OVERFLOW (elt))
   19620              :                         return NULL_TREE;
   19621              :                     }
   19622         5412 :                   builder.quick_push (elt);
   19623              :                 }
   19624          555 :               return builder.build ();
   19625          555 :             }
   19626              :           break;
   19627              : 
   19628        32748 :         case IX86_BUILTIN_MINSS:
   19629        32748 :         case IX86_BUILTIN_MINSH_MASK:
   19630        32748 :           tcode = LT_EXPR;
   19631        32748 :           is_scalar = true;
   19632        32748 :           goto do_minmax;
   19633              : 
   19634        32748 :         case IX86_BUILTIN_MAXSS:
   19635        32748 :         case IX86_BUILTIN_MAXSH_MASK:
   19636        32748 :           tcode = GT_EXPR;
   19637        32748 :           is_scalar = true;
   19638        32748 :           goto do_minmax;
   19639              : 
   19640       350995 :         case IX86_BUILTIN_MINPS:
   19641       350995 :         case IX86_BUILTIN_MINPD:
   19642       350995 :         case IX86_BUILTIN_MINPS256:
   19643       350995 :         case IX86_BUILTIN_MINPD256:
   19644       350995 :         case IX86_BUILTIN_MINPS512:
   19645       350995 :         case IX86_BUILTIN_MINPD512:
   19646       350995 :         case IX86_BUILTIN_MINPS128_MASK:
   19647       350995 :         case IX86_BUILTIN_MINPD128_MASK:
   19648       350995 :         case IX86_BUILTIN_MINPS256_MASK:
   19649       350995 :         case IX86_BUILTIN_MINPD256_MASK:
   19650       350995 :         case IX86_BUILTIN_MINPH128_MASK:
   19651       350995 :         case IX86_BUILTIN_MINPH256_MASK:
   19652       350995 :         case IX86_BUILTIN_MINPH512_MASK:
   19653       350995 :           tcode = LT_EXPR;
   19654       350995 :           is_scalar = false;
   19655       350995 :           goto do_minmax;
   19656              : 
   19657              :         case IX86_BUILTIN_MAXPS:
   19658              :         case IX86_BUILTIN_MAXPD:
   19659              :         case IX86_BUILTIN_MAXPS256:
   19660              :         case IX86_BUILTIN_MAXPD256:
   19661              :         case IX86_BUILTIN_MAXPS512:
   19662              :         case IX86_BUILTIN_MAXPD512:
   19663              :         case IX86_BUILTIN_MAXPS128_MASK:
   19664              :         case IX86_BUILTIN_MAXPD128_MASK:
   19665              :         case IX86_BUILTIN_MAXPS256_MASK:
   19666              :         case IX86_BUILTIN_MAXPD256_MASK:
   19667              :         case IX86_BUILTIN_MAXPH128_MASK:
   19668              :         case IX86_BUILTIN_MAXPH256_MASK:
   19669              :         case IX86_BUILTIN_MAXPH512_MASK:
   19670              :           tcode = GT_EXPR;
   19671              :           is_scalar = false;
   19672       767506 :         do_minmax:
   19673       767506 :           gcc_assert (n_args >= 2);
   19674       767506 :           if (TREE_CODE (args[0]) != VECTOR_CST
   19675           76 :               || TREE_CODE (args[1]) != VECTOR_CST)
   19676              :             break;
   19677           76 :           mask = HOST_WIDE_INT_M1U;
   19678           76 :           if (n_args > 2)
   19679              :             {
   19680           36 :               gcc_assert (n_args >= 4);
   19681              :               /* This is masked minmax.  */
   19682           36 :               if (TREE_CODE (args[3]) != INTEGER_CST
   19683           36 :                   || TREE_SIDE_EFFECTS (args[2]))
   19684              :                 break;
   19685           36 :               mask = TREE_INT_CST_LOW (args[3]);
   19686           36 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19687           36 :               mask |= HOST_WIDE_INT_M1U << elems;
   19688           36 :               if (mask != HOST_WIDE_INT_M1U
   19689           32 :                   && TREE_CODE (args[2]) != VECTOR_CST)
   19690              :                 break;
   19691           36 :               if (n_args >= 5)
   19692              :                 {
   19693           20 :                   if (!tree_fits_uhwi_p (args[4]))
   19694              :                     break;
   19695           20 :                   if (tree_to_uhwi (args[4]) != 4
   19696            0 :                       && tree_to_uhwi (args[4]) != 8)
   19697              :                     break;
   19698              :                 }
   19699           36 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   19700              :                 return args[2];
   19701              :             }
   19702              :           /* Punt on NaNs, unless exceptions are disabled.  */
   19703           76 :           if (HONOR_NANS (args[0])
   19704           76 :               && (n_args < 5 || tree_to_uhwi (args[4]) != 8))
   19705          184 :             for (int i = 0; i < 2; ++i)
   19706              :               {
   19707          134 :                 unsigned count = vector_cst_encoded_nelts (args[i]);
   19708          957 :                 for (unsigned j = 0; j < count; ++j)
   19709          849 :                   if (tree_expr_nan_p (VECTOR_CST_ENCODED_ELT (args[i], j)))
   19710              :                     return NULL_TREE;
   19711              :               }
   19712           50 :           {
   19713           50 :             tree res = const_binop (tcode,
   19714           50 :                                     truth_type_for (TREE_TYPE (args[0])),
   19715              :                                     args[0], args[1]);
   19716           50 :             if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19717              :               break;
   19718           50 :             res = fold_ternary (VEC_COND_EXPR, TREE_TYPE (args[0]), res,
   19719              :                                 args[0], args[1]);
   19720           50 :             if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19721              :               break;
   19722           50 :             if (mask != HOST_WIDE_INT_M1U)
   19723              :               {
   19724           32 :                 unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19725           32 :                 vec_perm_builder sel (nelts, nelts, 1);
   19726          328 :                 for (unsigned int i = 0; i < nelts; i++)
   19727          296 :                   if (mask & (HOST_WIDE_INT_1U << i))
   19728          160 :                     sel.quick_push (i);
   19729              :                   else
   19730          136 :                     sel.quick_push (nelts + i);
   19731           32 :                 vec_perm_indices indices (sel, 2, nelts);
   19732           32 :                 res = fold_vec_perm (TREE_TYPE (args[0]), res, args[2],
   19733              :                                      indices);
   19734           32 :                 if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19735              :                   break;
   19736           32 :               }
   19737           50 :             if (is_scalar)
   19738              :               {
   19739           10 :                 unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19740           10 :                 vec_perm_builder sel (nelts, nelts, 1);
   19741           10 :                 sel.quick_push (0);
   19742           40 :                 for (unsigned int i = 1; i < nelts; i++)
   19743           30 :                   sel.quick_push (nelts + i);
   19744           10 :                 vec_perm_indices indices (sel, 2, nelts);
   19745           10 :                 res = fold_vec_perm (TREE_TYPE (args[0]), res, args[0],
   19746              :                                      indices);
   19747           10 :                 if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19748              :                   break;
   19749           10 :               }
   19750           50 :             return res;
   19751              :           }
   19752              : 
   19753              :         default:
   19754              :           break;
   19755              :         }
   19756              :     }
   19757              : 
   19758              : #ifdef SUBTARGET_FOLD_BUILTIN
   19759              :   return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
   19760              : #endif
   19761              : 
   19762              :   return NULL_TREE;
   19763              : }
   19764              : 
   19765              : /* Fold a MD builtin (use ix86_fold_builtin for folding into
   19766              :    constant) in GIMPLE.  */
   19767              : 
   19768              : bool
   19769      1154467 : ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   19770              : {
   19771      1154467 :   gimple *stmt = gsi_stmt (*gsi), *g;
   19772      1154467 :   gimple_seq stmts = NULL;
   19773      1154467 :   tree fndecl = gimple_call_fndecl (stmt);
   19774      1154467 :   gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
   19775      1154467 :   int n_args = gimple_call_num_args (stmt);
   19776      1154467 :   enum ix86_builtins fn_code
   19777      1154467 :     = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   19778      1154467 :   tree decl = NULL_TREE;
   19779      1154467 :   tree arg0, arg1, arg2;
   19780      1154467 :   enum rtx_code rcode;
   19781      1154467 :   enum tree_code tcode;
   19782      1154467 :   unsigned HOST_WIDE_INT count;
   19783      1154467 :   bool is_vshift;
   19784      1154467 :   unsigned HOST_WIDE_INT elems;
   19785      1154467 :   location_t loc;
   19786              : 
   19787              :   /* Don't fold when there's isa mismatch.  */
   19788      1154467 :   if (!ix86_check_builtin_isa_match (fn_code, NULL, NULL))
   19789              :     return false;
   19790              : 
   19791      1154340 :   switch (fn_code)
   19792              :     {
   19793          288 :     case IX86_BUILTIN_TZCNT32:
   19794          288 :       decl = builtin_decl_implicit (BUILT_IN_CTZ);
   19795          288 :       goto fold_tzcnt_lzcnt;
   19796              : 
   19797          237 :     case IX86_BUILTIN_TZCNT64:
   19798          237 :       decl = builtin_decl_implicit (BUILT_IN_CTZLL);
   19799          237 :       goto fold_tzcnt_lzcnt;
   19800              : 
   19801          215 :     case IX86_BUILTIN_LZCNT32:
   19802          215 :       decl = builtin_decl_implicit (BUILT_IN_CLZ);
   19803          215 :       goto fold_tzcnt_lzcnt;
   19804              : 
   19805          224 :     case IX86_BUILTIN_LZCNT64:
   19806          224 :       decl = builtin_decl_implicit (BUILT_IN_CLZLL);
   19807          224 :       goto fold_tzcnt_lzcnt;
   19808              : 
   19809          964 :     fold_tzcnt_lzcnt:
   19810          964 :       gcc_assert (n_args == 1);
   19811          964 :       arg0 = gimple_call_arg (stmt, 0);
   19812          964 :       if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
   19813              :         {
   19814          799 :           int prec = TYPE_PRECISION (TREE_TYPE (arg0));
   19815              :           /* If arg0 is provably non-zero, optimize into generic
   19816              :              __builtin_c[tl]z{,ll} function the middle-end handles
   19817              :              better.  */
   19818          799 :           if (!expr_not_equal_to (arg0, wi::zero (prec)))
   19819              :             return false;
   19820              : 
   19821            9 :           loc = gimple_location (stmt);
   19822            9 :           g = gimple_build_call (decl, 1, arg0);
   19823            9 :           gimple_set_location (g, loc);
   19824            9 :           tree lhs = make_ssa_name (integer_type_node);
   19825            9 :           gimple_call_set_lhs (g, lhs);
   19826            9 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
   19827            9 :           g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
   19828            9 :           gimple_set_location (g, loc);
   19829            9 :           gsi_replace (gsi, g, false);
   19830            9 :           return true;
   19831              :         }
   19832              :       break;
   19833              : 
   19834          489 :     case IX86_BUILTIN_BZHI32:
   19835          489 :     case IX86_BUILTIN_BZHI64:
   19836          489 :       gcc_assert (n_args == 2);
   19837          489 :       arg1 = gimple_call_arg (stmt, 1);
   19838          489 :       if (tree_fits_uhwi_p (arg1) && gimple_call_lhs (stmt))
   19839              :         {
   19840          195 :           unsigned int idx = tree_to_uhwi (arg1) & 0xff;
   19841          195 :           arg0 = gimple_call_arg (stmt, 0);
   19842          195 :           if (idx < TYPE_PRECISION (TREE_TYPE (arg0)))
   19843              :             break;
   19844           31 :           loc = gimple_location (stmt);
   19845           31 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19846           31 :           gimple_set_location (g, loc);
   19847           31 :           gsi_replace (gsi, g, false);
   19848           31 :           return true;
   19849              :         }
   19850              :       break;
   19851              : 
   19852          502 :     case IX86_BUILTIN_PDEP32:
   19853          502 :     case IX86_BUILTIN_PDEP64:
   19854          502 :     case IX86_BUILTIN_PEXT32:
   19855          502 :     case IX86_BUILTIN_PEXT64:
   19856          502 :       gcc_assert (n_args == 2);
   19857          502 :       arg1 = gimple_call_arg (stmt, 1);
   19858          502 :       if (integer_all_onesp (arg1) && gimple_call_lhs (stmt))
   19859              :         {
   19860            4 :           loc = gimple_location (stmt);
   19861            4 :           arg0 = gimple_call_arg (stmt, 0);
   19862            4 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19863            4 :           gimple_set_location (g, loc);
   19864            4 :           gsi_replace (gsi, g, false);
   19865            4 :           return true;
   19866              :         }
   19867              :       break;
   19868              : 
   19869          145 :     case IX86_BUILTIN_PBLENDVB256:
   19870          145 :     case IX86_BUILTIN_BLENDVPS256:
   19871          145 :     case IX86_BUILTIN_BLENDVPD256:
   19872              :       /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
   19873              :          to scalar operations and not combined back.  */
   19874          145 :       if (!TARGET_AVX2)
   19875              :         break;
   19876              : 
   19877              :       /* FALLTHRU.  */
   19878          112 :     case IX86_BUILTIN_BLENDVPD:
   19879              :       /* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
   19880              :          w/o sse4.2, it's veclowered to scalar operations and
   19881              :          not combined back.  */
   19882          112 :       if (!TARGET_SSE4_2)
   19883              :         break;
   19884              :       /* FALLTHRU.  */
   19885          166 :     case IX86_BUILTIN_PBLENDVB128:
   19886          166 :     case IX86_BUILTIN_BLENDVPS:
   19887          166 :       gcc_assert (n_args == 3);
   19888          166 :       arg0 = gimple_call_arg (stmt, 0);
   19889          166 :       arg1 = gimple_call_arg (stmt, 1);
   19890          166 :       arg2 = gimple_call_arg (stmt, 2);
   19891          166 :       if (gimple_call_lhs (stmt))
   19892              :         {
   19893          166 :           loc = gimple_location (stmt);
   19894          166 :           tree type = TREE_TYPE (arg2);
   19895          166 :           if (VECTOR_FLOAT_TYPE_P (type))
   19896              :             {
   19897           73 :               tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
   19898           73 :                 ? intSI_type_node : intDI_type_node;
   19899           73 :               type = get_same_sized_vectype (itype, type);
   19900              :             }
   19901              :           else
   19902           93 :             type = signed_type_for (type);
   19903          166 :           arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
   19904          166 :           tree zero_vec = build_zero_cst (type);
   19905          166 :           tree cmp_type = truth_type_for (type);
   19906          166 :           tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
   19907          166 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19908          166 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19909              :                                    VEC_COND_EXPR, cmp,
   19910              :                                    arg1, arg0);
   19911          166 :           gimple_set_location (g, loc);
   19912          166 :           gsi_replace (gsi, g, false);
   19913              :         }
   19914              :       else
   19915            0 :         gsi_replace (gsi, gimple_build_nop (), false);
   19916              :       return true;
   19917              : 
   19918              : 
   19919           16 :     case IX86_BUILTIN_PCMPEQB128:
   19920           16 :     case IX86_BUILTIN_PCMPEQW128:
   19921           16 :     case IX86_BUILTIN_PCMPEQD128:
   19922           16 :     case IX86_BUILTIN_PCMPEQQ:
   19923           16 :     case IX86_BUILTIN_PCMPEQB256:
   19924           16 :     case IX86_BUILTIN_PCMPEQW256:
   19925           16 :     case IX86_BUILTIN_PCMPEQD256:
   19926           16 :     case IX86_BUILTIN_PCMPEQQ256:
   19927           16 :       tcode = EQ_EXPR;
   19928           16 :       goto do_cmp;
   19929              : 
   19930              :     case IX86_BUILTIN_PCMPGTB128:
   19931              :     case IX86_BUILTIN_PCMPGTW128:
   19932              :     case IX86_BUILTIN_PCMPGTD128:
   19933              :     case IX86_BUILTIN_PCMPGTQ:
   19934              :     case IX86_BUILTIN_PCMPGTB256:
   19935              :     case IX86_BUILTIN_PCMPGTW256:
   19936              :     case IX86_BUILTIN_PCMPGTD256:
   19937              :     case IX86_BUILTIN_PCMPGTQ256:
   19938              :       tcode = GT_EXPR;
   19939              : 
   19940           33 :     do_cmp:
   19941           33 :       gcc_assert (n_args == 2);
   19942           33 :       arg0 = gimple_call_arg (stmt, 0);
   19943           33 :       arg1 = gimple_call_arg (stmt, 1);
   19944           33 :       if (gimple_call_lhs (stmt))
   19945              :         {
   19946           32 :           loc = gimple_location (stmt);
   19947           32 :           tree type = TREE_TYPE (arg0);
   19948           32 :           tree zero_vec = build_zero_cst (type);
   19949           32 :           tree minus_one_vec = build_minus_one_cst (type);
   19950           32 :           tree cmp_type = truth_type_for (type);
   19951           32 :           tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1);
   19952           32 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19953           32 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19954              :                                    VEC_COND_EXPR, cmp,
   19955              :                                    minus_one_vec, zero_vec);
   19956           32 :           gimple_set_location (g, loc);
   19957           32 :           gsi_replace (gsi, g, false);
   19958              :         }
   19959              :       else
   19960            1 :         gsi_replace (gsi, gimple_build_nop (), false);
   19961              :       return true;
   19962              : 
   19963         9297 :     case IX86_BUILTIN_PSLLD:
   19964         9297 :     case IX86_BUILTIN_PSLLD128:
   19965         9297 :     case IX86_BUILTIN_PSLLD128_MASK:
   19966         9297 :     case IX86_BUILTIN_PSLLD256:
   19967         9297 :     case IX86_BUILTIN_PSLLD256_MASK:
   19968         9297 :     case IX86_BUILTIN_PSLLD512:
   19969         9297 :     case IX86_BUILTIN_PSLLDI:
   19970         9297 :     case IX86_BUILTIN_PSLLDI128:
   19971         9297 :     case IX86_BUILTIN_PSLLDI128_MASK:
   19972         9297 :     case IX86_BUILTIN_PSLLDI256:
   19973         9297 :     case IX86_BUILTIN_PSLLDI256_MASK:
   19974         9297 :     case IX86_BUILTIN_PSLLDI512:
   19975         9297 :     case IX86_BUILTIN_PSLLQ:
   19976         9297 :     case IX86_BUILTIN_PSLLQ128:
   19977         9297 :     case IX86_BUILTIN_PSLLQ128_MASK:
   19978         9297 :     case IX86_BUILTIN_PSLLQ256:
   19979         9297 :     case IX86_BUILTIN_PSLLQ256_MASK:
   19980         9297 :     case IX86_BUILTIN_PSLLQ512:
   19981         9297 :     case IX86_BUILTIN_PSLLQI:
   19982         9297 :     case IX86_BUILTIN_PSLLQI128:
   19983         9297 :     case IX86_BUILTIN_PSLLQI128_MASK:
   19984         9297 :     case IX86_BUILTIN_PSLLQI256:
   19985         9297 :     case IX86_BUILTIN_PSLLQI256_MASK:
   19986         9297 :     case IX86_BUILTIN_PSLLQI512:
   19987         9297 :     case IX86_BUILTIN_PSLLW:
   19988         9297 :     case IX86_BUILTIN_PSLLW128:
   19989         9297 :     case IX86_BUILTIN_PSLLW128_MASK:
   19990         9297 :     case IX86_BUILTIN_PSLLW256:
   19991         9297 :     case IX86_BUILTIN_PSLLW256_MASK:
   19992         9297 :     case IX86_BUILTIN_PSLLW512_MASK:
   19993         9297 :     case IX86_BUILTIN_PSLLWI:
   19994         9297 :     case IX86_BUILTIN_PSLLWI128:
   19995         9297 :     case IX86_BUILTIN_PSLLWI128_MASK:
   19996         9297 :     case IX86_BUILTIN_PSLLWI256:
   19997         9297 :     case IX86_BUILTIN_PSLLWI256_MASK:
   19998         9297 :     case IX86_BUILTIN_PSLLWI512_MASK:
   19999         9297 :       rcode = ASHIFT;
   20000         9297 :       is_vshift = false;
   20001         9297 :       goto do_shift;
   20002         6495 :     case IX86_BUILTIN_PSRAD:
   20003         6495 :     case IX86_BUILTIN_PSRAD128:
   20004         6495 :     case IX86_BUILTIN_PSRAD128_MASK:
   20005         6495 :     case IX86_BUILTIN_PSRAD256:
   20006         6495 :     case IX86_BUILTIN_PSRAD256_MASK:
   20007         6495 :     case IX86_BUILTIN_PSRAD512:
   20008         6495 :     case IX86_BUILTIN_PSRADI:
   20009         6495 :     case IX86_BUILTIN_PSRADI128:
   20010         6495 :     case IX86_BUILTIN_PSRADI128_MASK:
   20011         6495 :     case IX86_BUILTIN_PSRADI256:
   20012         6495 :     case IX86_BUILTIN_PSRADI256_MASK:
   20013         6495 :     case IX86_BUILTIN_PSRADI512:
   20014         6495 :     case IX86_BUILTIN_PSRAQ128_MASK:
   20015         6495 :     case IX86_BUILTIN_PSRAQ256_MASK:
   20016         6495 :     case IX86_BUILTIN_PSRAQ512:
   20017         6495 :     case IX86_BUILTIN_PSRAQI128_MASK:
   20018         6495 :     case IX86_BUILTIN_PSRAQI256_MASK:
   20019         6495 :     case IX86_BUILTIN_PSRAQI512:
   20020         6495 :     case IX86_BUILTIN_PSRAW:
   20021         6495 :     case IX86_BUILTIN_PSRAW128:
   20022         6495 :     case IX86_BUILTIN_PSRAW128_MASK:
   20023         6495 :     case IX86_BUILTIN_PSRAW256:
   20024         6495 :     case IX86_BUILTIN_PSRAW256_MASK:
   20025         6495 :     case IX86_BUILTIN_PSRAW512:
   20026         6495 :     case IX86_BUILTIN_PSRAWI:
   20027         6495 :     case IX86_BUILTIN_PSRAWI128:
   20028         6495 :     case IX86_BUILTIN_PSRAWI128_MASK:
   20029         6495 :     case IX86_BUILTIN_PSRAWI256:
   20030         6495 :     case IX86_BUILTIN_PSRAWI256_MASK:
   20031         6495 :     case IX86_BUILTIN_PSRAWI512:
   20032         6495 :       rcode = ASHIFTRT;
   20033         6495 :       is_vshift = false;
   20034         6495 :       goto do_shift;
   20035         7960 :     case IX86_BUILTIN_PSRLD:
   20036         7960 :     case IX86_BUILTIN_PSRLD128:
   20037         7960 :     case IX86_BUILTIN_PSRLD128_MASK:
   20038         7960 :     case IX86_BUILTIN_PSRLD256:
   20039         7960 :     case IX86_BUILTIN_PSRLD256_MASK:
   20040         7960 :     case IX86_BUILTIN_PSRLD512:
   20041         7960 :     case IX86_BUILTIN_PSRLDI:
   20042         7960 :     case IX86_BUILTIN_PSRLDI128:
   20043         7960 :     case IX86_BUILTIN_PSRLDI128_MASK:
   20044         7960 :     case IX86_BUILTIN_PSRLDI256:
   20045         7960 :     case IX86_BUILTIN_PSRLDI256_MASK:
   20046         7960 :     case IX86_BUILTIN_PSRLDI512:
   20047         7960 :     case IX86_BUILTIN_PSRLQ:
   20048         7960 :     case IX86_BUILTIN_PSRLQ128:
   20049         7960 :     case IX86_BUILTIN_PSRLQ128_MASK:
   20050         7960 :     case IX86_BUILTIN_PSRLQ256:
   20051         7960 :     case IX86_BUILTIN_PSRLQ256_MASK:
   20052         7960 :     case IX86_BUILTIN_PSRLQ512:
   20053         7960 :     case IX86_BUILTIN_PSRLQI:
   20054         7960 :     case IX86_BUILTIN_PSRLQI128:
   20055         7960 :     case IX86_BUILTIN_PSRLQI128_MASK:
   20056         7960 :     case IX86_BUILTIN_PSRLQI256:
   20057         7960 :     case IX86_BUILTIN_PSRLQI256_MASK:
   20058         7960 :     case IX86_BUILTIN_PSRLQI512:
   20059         7960 :     case IX86_BUILTIN_PSRLW:
   20060         7960 :     case IX86_BUILTIN_PSRLW128:
   20061         7960 :     case IX86_BUILTIN_PSRLW128_MASK:
   20062         7960 :     case IX86_BUILTIN_PSRLW256:
   20063         7960 :     case IX86_BUILTIN_PSRLW256_MASK:
   20064         7960 :     case IX86_BUILTIN_PSRLW512:
   20065         7960 :     case IX86_BUILTIN_PSRLWI:
   20066         7960 :     case IX86_BUILTIN_PSRLWI128:
   20067         7960 :     case IX86_BUILTIN_PSRLWI128_MASK:
   20068         7960 :     case IX86_BUILTIN_PSRLWI256:
   20069         7960 :     case IX86_BUILTIN_PSRLWI256_MASK:
   20070         7960 :     case IX86_BUILTIN_PSRLWI512:
   20071         7960 :       rcode = LSHIFTRT;
   20072         7960 :       is_vshift = false;
   20073         7960 :       goto do_shift;
   20074         2384 :     case IX86_BUILTIN_PSLLVV16HI:
   20075         2384 :     case IX86_BUILTIN_PSLLVV16SI:
   20076         2384 :     case IX86_BUILTIN_PSLLVV2DI:
   20077         2384 :     case IX86_BUILTIN_PSLLVV2DI_MASK:
   20078         2384 :     case IX86_BUILTIN_PSLLVV32HI:
   20079         2384 :     case IX86_BUILTIN_PSLLVV4DI:
   20080         2384 :     case IX86_BUILTIN_PSLLVV4DI_MASK:
   20081         2384 :     case IX86_BUILTIN_PSLLVV4SI:
   20082         2384 :     case IX86_BUILTIN_PSLLVV4SI_MASK:
   20083         2384 :     case IX86_BUILTIN_PSLLVV8DI:
   20084         2384 :     case IX86_BUILTIN_PSLLVV8HI:
   20085         2384 :     case IX86_BUILTIN_PSLLVV8SI:
   20086         2384 :     case IX86_BUILTIN_PSLLVV8SI_MASK:
   20087         2384 :       rcode = ASHIFT;
   20088         2384 :       is_vshift = true;
   20089         2384 :       goto do_shift;
   20090         2341 :     case IX86_BUILTIN_PSRAVQ128:
   20091         2341 :     case IX86_BUILTIN_PSRAVQ256:
   20092         2341 :     case IX86_BUILTIN_PSRAVV16HI:
   20093         2341 :     case IX86_BUILTIN_PSRAVV16SI:
   20094         2341 :     case IX86_BUILTIN_PSRAVV32HI:
   20095         2341 :     case IX86_BUILTIN_PSRAVV4SI:
   20096         2341 :     case IX86_BUILTIN_PSRAVV4SI_MASK:
   20097         2341 :     case IX86_BUILTIN_PSRAVV8DI:
   20098         2341 :     case IX86_BUILTIN_PSRAVV8HI:
   20099         2341 :     case IX86_BUILTIN_PSRAVV8SI:
   20100         2341 :     case IX86_BUILTIN_PSRAVV8SI_MASK:
   20101         2341 :       rcode = ASHIFTRT;
   20102         2341 :       is_vshift = true;
   20103         2341 :       goto do_shift;
   20104         2380 :     case IX86_BUILTIN_PSRLVV16HI:
   20105         2380 :     case IX86_BUILTIN_PSRLVV16SI:
   20106         2380 :     case IX86_BUILTIN_PSRLVV2DI:
   20107         2380 :     case IX86_BUILTIN_PSRLVV2DI_MASK:
   20108         2380 :     case IX86_BUILTIN_PSRLVV32HI:
   20109         2380 :     case IX86_BUILTIN_PSRLVV4DI:
   20110         2380 :     case IX86_BUILTIN_PSRLVV4DI_MASK:
   20111         2380 :     case IX86_BUILTIN_PSRLVV4SI:
   20112         2380 :     case IX86_BUILTIN_PSRLVV4SI_MASK:
   20113         2380 :     case IX86_BUILTIN_PSRLVV8DI:
   20114         2380 :     case IX86_BUILTIN_PSRLVV8HI:
   20115         2380 :     case IX86_BUILTIN_PSRLVV8SI:
   20116         2380 :     case IX86_BUILTIN_PSRLVV8SI_MASK:
   20117         2380 :       rcode = LSHIFTRT;
   20118         2380 :       is_vshift = true;
   20119         2380 :       goto do_shift;
   20120              : 
   20121        30857 :     do_shift:
   20122        30857 :       gcc_assert (n_args >= 2);
   20123        30857 :       if (!gimple_call_lhs (stmt))
   20124              :         {
   20125            1 :           gsi_replace (gsi, gimple_build_nop (), false);
   20126            1 :           return true;
   20127              :         }
   20128        30856 :       arg0 = gimple_call_arg (stmt, 0);
   20129        30856 :       arg1 = gimple_call_arg (stmt, 1);
   20130        30856 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20131              :       /* For masked shift, only optimize if the mask is all ones.  */
   20132        30856 :       if (n_args > 2
   20133        30856 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   20134              :         break;
   20135        16081 :       if (is_vshift)
   20136              :         {
   20137         2640 :           if (TREE_CODE (arg1) != VECTOR_CST)
   20138              :             break;
   20139           69 :           count = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0)));
   20140           69 :           if (integer_zerop (arg1))
   20141           27 :             count = 0;
   20142           42 :           else if (rcode == ASHIFTRT)
   20143              :             break;
   20144              :           else
   20145          230 :             for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg1); ++i)
   20146              :               {
   20147          212 :                 tree elt = VECTOR_CST_ELT (arg1, i);
   20148          212 :                 if (!wi::neg_p (wi::to_wide (elt))
   20149          375 :                     && wi::to_widest (elt) < count)
   20150           16 :                   return false;
   20151              :               }
   20152              :         }
   20153              :       else
   20154              :         {
   20155        13441 :           arg1 = ix86_vector_shift_count (arg1);
   20156        13441 :           if (!arg1)
   20157              :             break;
   20158         5608 :           count = tree_to_uhwi (arg1);
   20159              :         }
   20160         5653 :       if (count == 0)
   20161              :         {
   20162              :           /* Just return the first argument for shift by 0.  */
   20163           93 :           loc = gimple_location (stmt);
   20164           93 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   20165           93 :           gimple_set_location (g, loc);
   20166           93 :           gsi_replace (gsi, g, false);
   20167           93 :           return true;
   20168              :         }
   20169         5560 :       if (rcode != ASHIFTRT
   20170         5560 :           && count >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0))))
   20171              :         {
   20172              :           /* For shift counts equal or greater than precision, except for
   20173              :              arithmetic right shift the result is zero.  */
   20174           78 :           loc = gimple_location (stmt);
   20175           78 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   20176           78 :                                    build_zero_cst (TREE_TYPE (arg0)));
   20177           78 :           gimple_set_location (g, loc);
   20178           78 :           gsi_replace (gsi, g, false);
   20179           78 :           return true;
   20180              :         }
   20181              :       break;
   20182              : 
   20183          531 :     case IX86_BUILTIN_SHUFPD512:
   20184          531 :     case IX86_BUILTIN_SHUFPS512:
   20185          531 :     case IX86_BUILTIN_SHUFPD:
   20186          531 :     case IX86_BUILTIN_SHUFPD256:
   20187          531 :     case IX86_BUILTIN_SHUFPS:
   20188          531 :     case IX86_BUILTIN_SHUFPS256:
   20189          531 :       arg0 = gimple_call_arg (stmt, 0);
   20190          531 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20191              :       /* This is masked shuffle.  Only optimize if the mask is all ones.  */
   20192          531 :       if (n_args > 3
   20193          895 :           && !ix86_masked_all_ones (elems,
   20194          364 :                                     gimple_call_arg (stmt, n_args - 1)))
   20195              :         break;
   20196          203 :       arg2 = gimple_call_arg (stmt, 2);
   20197          203 :       if (TREE_CODE (arg2) == INTEGER_CST && gimple_call_lhs (stmt))
   20198              :         {
   20199          146 :           unsigned HOST_WIDE_INT shuffle_mask = TREE_INT_CST_LOW (arg2);
   20200              :           /* Check valid imm, refer to gcc.target/i386/testimm-10.c.  */
   20201          146 :           if (shuffle_mask > 255)
   20202              :             return false;
   20203              : 
   20204          144 :           machine_mode imode = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (arg0)));
   20205          144 :           loc = gimple_location (stmt);
   20206          144 :           tree itype = (imode == E_DFmode
   20207          144 :                         ? long_long_integer_type_node : integer_type_node);
   20208          144 :           tree vtype = build_vector_type (itype, elems);
   20209          144 :           tree_vector_builder elts (vtype, elems, 1);
   20210              : 
   20211              : 
   20212              :           /* Transform integer shuffle_mask to vector perm_mask which
   20213              :              is used by vec_perm_expr, refer to shuflp[sd]256/512 in sse.md.  */
   20214          840 :           for (unsigned i = 0; i != elems; i++)
   20215              :             {
   20216          696 :               unsigned sel_idx;
   20217              :               /* Imm[1:0](if VL > 128, then use Imm[3:2],Imm[5:4],Imm[7:6])
   20218              :                  provide 2 select controls for each element of the
   20219              :                  destination.  */
   20220          696 :               if (imode == E_DFmode)
   20221          240 :                 sel_idx = (i & 1) * elems + (i & ~1)
   20222          240 :                           + ((shuffle_mask >> i) & 1);
   20223              :               else
   20224              :                 {
   20225              :                   /* Imm[7:0](if VL > 128, also use Imm[7:0]) provide 4 select
   20226              :                      controls for each element of the destination.  */
   20227          456 :                   unsigned j = i % 4;
   20228          456 :                   sel_idx = ((i >> 1) & 1) * elems + (i & ~3)
   20229          456 :                             + ((shuffle_mask >> 2 * j) & 3);
   20230              :                 }
   20231          696 :               elts.quick_push (build_int_cst (itype, sel_idx));
   20232              :             }
   20233              : 
   20234          144 :           tree perm_mask = elts.build ();
   20235          144 :           arg1 = gimple_call_arg (stmt, 1);
   20236          144 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   20237              :                                    VEC_PERM_EXPR,
   20238              :                                    arg0, arg1, perm_mask);
   20239          144 :           gimple_set_location (g, loc);
   20240          144 :           gsi_replace (gsi, g, false);
   20241          144 :           return true;
   20242          144 :         }
   20243              :       // Do not error yet, the constant could be propagated later?
   20244              :       break;
   20245              : 
   20246           48 :     case IX86_BUILTIN_PABSB:
   20247           48 :     case IX86_BUILTIN_PABSW:
   20248           48 :     case IX86_BUILTIN_PABSD:
   20249              :       /* 64-bit vector abs<mode>2 is only supported under TARGET_MMX_WITH_SSE.  */
   20250           48 :       if (!TARGET_MMX_WITH_SSE)
   20251              :         break;
   20252              :       /* FALLTHRU.  */
   20253         2190 :     case IX86_BUILTIN_PABSB128:
   20254         2190 :     case IX86_BUILTIN_PABSB256:
   20255         2190 :     case IX86_BUILTIN_PABSB512:
   20256         2190 :     case IX86_BUILTIN_PABSW128:
   20257         2190 :     case IX86_BUILTIN_PABSW256:
   20258         2190 :     case IX86_BUILTIN_PABSW512:
   20259         2190 :     case IX86_BUILTIN_PABSD128:
   20260         2190 :     case IX86_BUILTIN_PABSD256:
   20261         2190 :     case IX86_BUILTIN_PABSD512:
   20262         2190 :     case IX86_BUILTIN_PABSQ128:
   20263         2190 :     case IX86_BUILTIN_PABSQ256:
   20264         2190 :     case IX86_BUILTIN_PABSQ512:
   20265         2190 :     case IX86_BUILTIN_PABSB128_MASK:
   20266         2190 :     case IX86_BUILTIN_PABSB256_MASK:
   20267         2190 :     case IX86_BUILTIN_PABSW128_MASK:
   20268         2190 :     case IX86_BUILTIN_PABSW256_MASK:
   20269         2190 :     case IX86_BUILTIN_PABSD128_MASK:
   20270         2190 :     case IX86_BUILTIN_PABSD256_MASK:
   20271         2190 :       gcc_assert (n_args >= 1);
   20272         2190 :       if (!gimple_call_lhs (stmt))
   20273              :         {
   20274            1 :           gsi_replace (gsi, gimple_build_nop (), false);
   20275            1 :           return true;
   20276              :         }
   20277         2189 :       arg0 = gimple_call_arg (stmt, 0);
   20278         2189 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20279              :       /* For masked ABS, only optimize if the mask is all ones.  */
   20280         2189 :       if (n_args > 1
   20281         2189 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   20282              :         break;
   20283          229 :       {
   20284          229 :         tree utype, ures, vce;
   20285          229 :         utype = unsigned_type_for (TREE_TYPE (arg0));
   20286              :         /* PABSB/W/D/Q store the unsigned result in dst, use ABSU_EXPR
   20287              :            instead of ABS_EXPR to handle overflow case(TYPE_MIN).  */
   20288          229 :         ures = gimple_build (&stmts, ABSU_EXPR, utype, arg0);
   20289          229 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   20290          229 :         loc = gimple_location (stmt);
   20291          229 :         vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg0), ures);
   20292          229 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   20293              :                                  VIEW_CONVERT_EXPR, vce);
   20294          229 :         gsi_replace (gsi, g, false);
   20295              :       }
   20296          229 :       return true;
   20297              : 
   20298         2225 :     case IX86_BUILTIN_MINPS:
   20299         2225 :     case IX86_BUILTIN_MINPD:
   20300         2225 :     case IX86_BUILTIN_MINPS256:
   20301         2225 :     case IX86_BUILTIN_MINPD256:
   20302         2225 :     case IX86_BUILTIN_MINPS512:
   20303         2225 :     case IX86_BUILTIN_MINPD512:
   20304         2225 :     case IX86_BUILTIN_MINPS128_MASK:
   20305         2225 :     case IX86_BUILTIN_MINPD128_MASK:
   20306         2225 :     case IX86_BUILTIN_MINPS256_MASK:
   20307         2225 :     case IX86_BUILTIN_MINPD256_MASK:
   20308         2225 :     case IX86_BUILTIN_MINPH128_MASK:
   20309         2225 :     case IX86_BUILTIN_MINPH256_MASK:
   20310         2225 :     case IX86_BUILTIN_MINPH512_MASK:
   20311         2225 :       tcode = LT_EXPR;
   20312         2225 :       goto do_minmax;
   20313              : 
   20314              :     case IX86_BUILTIN_MAXPS:
   20315              :     case IX86_BUILTIN_MAXPD:
   20316              :     case IX86_BUILTIN_MAXPS256:
   20317              :     case IX86_BUILTIN_MAXPD256:
   20318              :     case IX86_BUILTIN_MAXPS512:
   20319              :     case IX86_BUILTIN_MAXPD512:
   20320              :     case IX86_BUILTIN_MAXPS128_MASK:
   20321              :     case IX86_BUILTIN_MAXPD128_MASK:
   20322              :     case IX86_BUILTIN_MAXPS256_MASK:
   20323              :     case IX86_BUILTIN_MAXPD256_MASK:
   20324              :     case IX86_BUILTIN_MAXPH128_MASK:
   20325              :     case IX86_BUILTIN_MAXPH256_MASK:
   20326              :     case IX86_BUILTIN_MAXPH512_MASK:
   20327              :       tcode = GT_EXPR;
   20328         4435 :     do_minmax:
   20329         4435 :       gcc_assert (n_args >= 2);
   20330              :       /* Without SSE4.1 we often aren't able to pattern match it back to the
   20331              :          desired instruction.  */
   20332         4435 :       if (!gimple_call_lhs (stmt) || !optimize || !TARGET_SSE4_1)
   20333              :         break;
   20334         3865 :       arg0 = gimple_call_arg (stmt, 0);
   20335         3865 :       arg1 = gimple_call_arg (stmt, 1);
   20336         3865 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20337              :       /* For masked minmax, only optimize if the mask is all ones.  */
   20338         3865 :       if (n_args > 2
   20339         3865 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, 3)))
   20340              :         break;
   20341          647 :       if (n_args >= 5)
   20342              :         {
   20343          436 :           tree arg4 = gimple_call_arg (stmt, 4);
   20344          436 :           if (!tree_fits_uhwi_p (arg4))
   20345              :             break;
   20346          424 :           if (tree_to_uhwi (arg4) == 4)
   20347              :             /* Ok.  */;
   20348          416 :           else if (tree_to_uhwi (arg4) != 8)
   20349              :             /* Invalid round argument.  */
   20350              :             break;
   20351          416 :           else if (HONOR_NANS (arg0))
   20352              :             /* Lowering to comparison would raise exceptions which
   20353              :                shouldn't be raised.  */
   20354              :             break;
   20355              :         }
   20356          219 :       {
   20357          219 :         tree type = truth_type_for (TREE_TYPE (arg0));
   20358          219 :         tree cmpres = gimple_build (&stmts, tcode, type, arg0, arg1);
   20359          219 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   20360          219 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   20361              :                                  VEC_COND_EXPR, cmpres, arg0, arg1);
   20362          219 :         gsi_replace (gsi, g, false);
   20363              :       }
   20364          219 :       return true;
   20365              : 
   20366              :     default:
   20367              :       break;
   20368              :     }
   20369              : 
   20370              :   return false;
   20371              : }
   20372              : 
   20373              : /* Handler for an SVML-style interface to
   20374              :    a library with vectorized intrinsics.  */
   20375              : 
   20376              : tree
   20377           10 : ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
   20378              : {
   20379           10 :   char name[20];
   20380           10 :   tree fntype, new_fndecl, args;
   20381           10 :   unsigned arity;
   20382           10 :   const char *bname;
   20383           10 :   machine_mode el_mode, in_mode;
   20384           10 :   int n, in_n;
   20385              : 
   20386              :   /* The SVML is suitable for unsafe math only.  */
   20387           10 :   if (!flag_unsafe_math_optimizations)
   20388              :     return NULL_TREE;
   20389              : 
   20390           10 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   20391           10 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   20392           10 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   20393           10 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   20394           10 :   if (el_mode != in_mode
   20395           10 :       || n != in_n)
   20396              :     return NULL_TREE;
   20397              : 
   20398           10 :   switch (fn)
   20399              :     {
   20400           10 :     CASE_CFN_EXP:
   20401           10 :     CASE_CFN_LOG:
   20402           10 :     CASE_CFN_LOG10:
   20403           10 :     CASE_CFN_POW:
   20404           10 :     CASE_CFN_TANH:
   20405           10 :     CASE_CFN_TAN:
   20406           10 :     CASE_CFN_ATAN:
   20407           10 :     CASE_CFN_ATAN2:
   20408           10 :     CASE_CFN_ATANH:
   20409           10 :     CASE_CFN_CBRT:
   20410           10 :     CASE_CFN_SINH:
   20411           10 :     CASE_CFN_SIN:
   20412           10 :     CASE_CFN_ASINH:
   20413           10 :     CASE_CFN_ASIN:
   20414           10 :     CASE_CFN_COSH:
   20415           10 :     CASE_CFN_COS:
   20416           10 :     CASE_CFN_ACOSH:
   20417           10 :     CASE_CFN_ACOS:
   20418           10 :       if ((el_mode != DFmode || n != 2)
   20419            8 :           && (el_mode != SFmode || n != 4))
   20420              :         return NULL_TREE;
   20421            6 :       break;
   20422              : 
   20423              :     default:
   20424              :       return NULL_TREE;
   20425              :     }
   20426              : 
   20427            6 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20428              :                                  ? double_type_node : float_type_node, fn);
   20429            6 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20430              : 
   20431            6 :   if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
   20432            2 :     strcpy (name, "vmlsLn4");
   20433            4 :   else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
   20434            0 :     strcpy (name, "vmldLn2");
   20435            4 :   else if (n == 4)
   20436              :     {
   20437            2 :       sprintf (name, "vmls%s", bname+10);
   20438            2 :       name[strlen (name)-1] = '4';
   20439              :     }
   20440              :   else
   20441            2 :     sprintf (name, "vmld%s2", bname+10);
   20442              : 
   20443              :   /* Convert to uppercase. */
   20444            6 :   name[4] &= ~0x20;
   20445              : 
   20446            6 :   arity = 0;
   20447            6 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20448            0 :     arity++;
   20449              : 
   20450            6 :   if (arity == 1)
   20451            0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20452              :   else
   20453            6 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20454              : 
   20455              :   /* Build a function declaration for the vectorized function.  */
   20456            6 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20457              :                            FUNCTION_DECL, get_identifier (name), fntype);
   20458            6 :   TREE_PUBLIC (new_fndecl) = 1;
   20459            6 :   DECL_EXTERNAL (new_fndecl) = 1;
   20460            6 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   20461            6 :   TREE_READONLY (new_fndecl) = 1;
   20462              : 
   20463            6 :   return new_fndecl;
   20464              : }
   20465              : 
   20466              : /* Handler for an ACML-style interface to
   20467              :    a library with vectorized intrinsics.  */
   20468              : 
   20469              : tree
   20470            3 : ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
   20471              : {
   20472            3 :   char name[20] = "__vr.._";
   20473            3 :   tree fntype, new_fndecl, args;
   20474            3 :   unsigned arity;
   20475            3 :   const char *bname;
   20476            3 :   machine_mode el_mode, in_mode;
   20477            3 :   int n, in_n;
   20478              : 
   20479              :   /* The ACML is 64bits only and suitable for unsafe math only as
   20480              :      it does not correctly support parts of IEEE with the required
   20481              :      precision such as denormals.  */
   20482            3 :   if (!TARGET_64BIT
   20483            3 :       || !flag_unsafe_math_optimizations)
   20484              :     return NULL_TREE;
   20485              : 
   20486            3 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   20487            3 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   20488            3 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   20489            3 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   20490            3 :   if (el_mode != in_mode
   20491            3 :       || n != in_n)
   20492              :     return NULL_TREE;
   20493              : 
   20494            3 :   switch (fn)
   20495              :     {
   20496            3 :     CASE_CFN_SIN:
   20497            3 :     CASE_CFN_COS:
   20498            3 :     CASE_CFN_EXP:
   20499            3 :     CASE_CFN_LOG:
   20500            3 :     CASE_CFN_LOG2:
   20501            3 :     CASE_CFN_LOG10:
   20502            3 :       if (el_mode == DFmode && n == 2)
   20503              :         {
   20504            3 :           name[4] = 'd';
   20505            3 :           name[5] = '2';
   20506              :         }
   20507            0 :       else if (el_mode == SFmode && n == 4)
   20508              :         {
   20509            0 :           name[4] = 's';
   20510            0 :           name[5] = '4';
   20511              :         }
   20512              :       else
   20513              :         return NULL_TREE;
   20514            3 :       break;
   20515              : 
   20516              :     default:
   20517              :       return NULL_TREE;
   20518              :     }
   20519              : 
   20520            3 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20521              :                                  ? double_type_node : float_type_node, fn);
   20522            3 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20523            3 :   sprintf (name + 7, "%s", bname+10);
   20524              : 
   20525            3 :   arity = 0;
   20526            3 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20527            0 :     arity++;
   20528              : 
   20529            3 :   if (arity == 1)
   20530            0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20531              :   else
   20532            3 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20533              : 
   20534              :   /* Build a function declaration for the vectorized function.  */
   20535            3 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20536              :                            FUNCTION_DECL, get_identifier (name), fntype);
   20537            3 :   TREE_PUBLIC (new_fndecl) = 1;
   20538            3 :   DECL_EXTERNAL (new_fndecl) = 1;
   20539            3 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   20540            3 :   TREE_READONLY (new_fndecl) = 1;
   20541              : 
   20542            3 :   return new_fndecl;
   20543              : }
   20544              : 
   20545              : /* Handler for an AOCL-LibM-style interface to
   20546              :    a library with vectorized intrinsics.  */
   20547              : 
   20548              : tree
   20549          386 : ix86_veclibabi_aocl (combined_fn fn, tree type_out, tree type_in)
   20550              : {
   20551          386 :   char name[20] = "amd_vr";
   20552          386 :   int name_len = 6;
   20553          386 :   tree fntype, new_fndecl, args;
   20554          386 :   unsigned arity;
   20555          386 :   const char *bname;
   20556          386 :   machine_mode el_mode, in_mode;
   20557          386 :   int n, in_n;
   20558              : 
   20559              :   /* AOCL-LibM is 64bits only.  It is also only suitable for unsafe math only
   20560              :      as it trades off some accuracy for increased performance.  */
   20561          386 :   if (!TARGET_64BIT
   20562          386 :       || !flag_unsafe_math_optimizations)
   20563              :     return NULL_TREE;
   20564              : 
   20565          386 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   20566          386 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   20567          386 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   20568          386 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   20569          386 :   if (el_mode != in_mode
   20570          386 :       || n != in_n)
   20571              :     return NULL_TREE;
   20572              : 
   20573          386 :   gcc_checking_assert (n > 0);
   20574              : 
   20575              :   /* Decide whether there exists a function for the combination of FN, the mode
   20576              :      and the vector width.  Return early if it doesn't.  */
   20577              : 
   20578          386 :   if (el_mode != DFmode && el_mode != SFmode)
   20579              :     return NULL_TREE;
   20580              : 
   20581              :   /* Supported vector widths for given FN and single/double precision.  Zeros
   20582              :      are used to fill out unused positions in the arrays.  */
   20583          386 :   static const int supported_n[][2][3] = {
   20584              :   /*   Single prec. ,  Double prec.  */
   20585              :     { { 16,  0,  0 }, {  2,  4,  8 } }, /* TAN.  */
   20586              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* EXP.  */
   20587              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* EXP2.  */
   20588              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* LOG.  */
   20589              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* LOG2.  */
   20590              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* COS.  */
   20591              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* SIN.  */
   20592              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* POW.  */
   20593              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* ERF.  */
   20594              :     { {  4,  8, 16 }, {  2,  8,  0 } }, /* ATAN.  */
   20595              :     { {  4,  8, 16 }, {  2,  0,  0 } }, /* LOG10.  */
   20596              :     { {  4,  0,  0 }, {  2,  0,  0 } }, /* EXP10.  */
   20597              :     { {  4,  0,  0 }, {  2,  0,  0 } }, /* LOG1P.  */
   20598              :     { {  4,  8, 16 }, {  8,  0,  0 } }, /* ASIN.  */
   20599              :     { {  4, 16,  0 }, {  0,  0,  0 } }, /* ACOS.  */
   20600              :     { {  4,  8, 16 }, {  0,  0,  0 } }, /* TANH.  */
   20601              :     { {  4,  0,  0 }, {  0,  0,  0 } }, /* EXPM1.  */
   20602              :     { {  4,  8,  0 }, {  0,  0,  0 } }, /* COSH.  */
   20603              :   };
   20604              : 
   20605              :   /* We cannot simply index the supported_n array with FN since multiple FNs
   20606              :      may correspond to a single operation (see the definitions of these
   20607              :      CASE_CFN_* macros).  */
   20608          386 :   int i;
   20609          386 :   switch (fn)
   20610              :     {
   20611              :     CASE_CFN_TAN   :  i = 0; break;
   20612           28 :     CASE_CFN_EXP   :  i = 1; break;
   20613           28 :     CASE_CFN_EXP2  :  i = 2; break;
   20614           28 :     CASE_CFN_LOG   :  i = 3; break;
   20615           28 :     CASE_CFN_LOG2  :  i = 4; break;
   20616           28 :     CASE_CFN_COS   :  i = 5; break;
   20617           28 :     CASE_CFN_SIN   :  i = 6; break;
   20618           28 :     CASE_CFN_POW   :  i = 7; break;
   20619           28 :     CASE_CFN_ERF   :  i = 8; break;
   20620           25 :     CASE_CFN_ATAN  :  i = 9; break;
   20621           20 :     CASE_CFN_LOG10 : i = 10; break;
   20622           10 :     CASE_CFN_EXP10 : i = 11; break;
   20623           10 :     CASE_CFN_LOG1P : i = 12; break;
   20624           24 :     CASE_CFN_ASIN  : i = 13; break;
   20625           14 :     CASE_CFN_ACOS  : i = 14; break;
   20626           18 :     CASE_CFN_TANH  : i = 15; break;
   20627            9 :     CASE_CFN_EXPM1 : i = 16; break;
   20628           14 :     CASE_CFN_COSH  : i = 17; break;
   20629              :     default: return NULL_TREE;
   20630              :     }
   20631              : 
   20632          386 :   int j = el_mode == DFmode;
   20633          386 :   bool n_is_supported = false;
   20634          976 :   for (unsigned k = 0; k < 3; k++)
   20635          857 :     if (supported_n[i][j][k] == n)
   20636              :       {
   20637              :         n_is_supported = true;
   20638              :         break;
   20639              :       }
   20640          386 :   if (!n_is_supported)
   20641              :     return NULL_TREE;
   20642              : 
   20643              :   /* Append the precision and the vector width to the function name we are
   20644              :      constructing.  */
   20645          267 :   name[name_len++] = el_mode == DFmode ? 'd' : 's';
   20646          267 :   switch (n)
   20647              :     {
   20648          214 :       case 2:
   20649          214 :       case 4:
   20650          214 :       case 8:
   20651          214 :         name[name_len++] = '0' + n;
   20652          214 :         break;
   20653           53 :       case 16:
   20654           53 :         name[name_len++] = '1';
   20655           53 :         name[name_len++] = '6';
   20656           53 :         break;
   20657            0 :       default:
   20658            0 :         gcc_unreachable ();
   20659              :     }
   20660          267 :   name[name_len++] = '_';
   20661              : 
   20662              :   /* Append the operation name (steal it from the name of a builtin).  */
   20663          267 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20664              :                                  ? double_type_node : float_type_node, fn);
   20665          267 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20666          267 :   sprintf (name + name_len, "%s", bname + 10);
   20667              : 
   20668          267 :   arity = 0;
   20669          267 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20670            0 :     arity++;
   20671              : 
   20672          267 :   if (arity == 1)
   20673            0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20674              :   else
   20675          267 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20676              : 
   20677              :   /* Build a function declaration for the vectorized function.  */
   20678          267 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20679              :                            FUNCTION_DECL, get_identifier (name), fntype);
   20680          267 :   TREE_PUBLIC (new_fndecl) = 1;
   20681          267 :   DECL_EXTERNAL (new_fndecl) = 1;
   20682          267 :   TREE_READONLY (new_fndecl) = 1;
   20683              : 
   20684          267 :   return new_fndecl;
   20685              : }
   20686              : 
   20687              : /* Returns a decl of a function that implements scatter store with
   20688              :    register type VECTYPE and index type INDEX_TYPE and SCALE.
   20689              :    Return NULL_TREE if it is not available.  */
   20690              : 
   20691              : static tree
   20692       133037 : ix86_vectorize_builtin_scatter (const_tree vectype,
   20693              :                                 const_tree index_type, int scale)
   20694              : {
   20695       133037 :   bool si;
   20696       133037 :   enum ix86_builtins code;
   20697              : 
   20698       133037 :   if (!TARGET_AVX512F)
   20699              :     return NULL_TREE;
   20700              : 
   20701         4193 :   if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 2u)
   20702         7367 :       ? !TARGET_USE_SCATTER_2PARTS
   20703         7367 :       : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
   20704         3174 :          ? !TARGET_USE_SCATTER_4PARTS
   20705         2057 :          : !TARGET_USE_SCATTER_8PARTS))
   20706              :     return NULL_TREE;
   20707              : 
   20708         4193 :   if ((TREE_CODE (index_type) != INTEGER_TYPE
   20709          463 :        && !POINTER_TYPE_P (index_type))
   20710         4656 :       || (TYPE_MODE (index_type) != SImode
   20711         1777 :           && TYPE_MODE (index_type) != DImode))
   20712            0 :     return NULL_TREE;
   20713              : 
   20714         4423 :   if (TYPE_PRECISION (index_type) > POINTER_SIZE)
   20715              :     return NULL_TREE;
   20716              : 
   20717              :   /* v*scatter* insn sign extends index to pointer mode.  */
   20718         4193 :   if (TYPE_PRECISION (index_type) < POINTER_SIZE
   20719         4193 :       && TYPE_UNSIGNED (index_type))
   20720              :     return NULL_TREE;
   20721              : 
   20722              :   /* Scale can be 1, 2, 4 or 8.  */
   20723         4193 :   if (scale <= 0
   20724         4193 :       || scale > 8
   20725         4177 :       || (scale & (scale - 1)) != 0)
   20726              :     return NULL_TREE;
   20727              : 
   20728         4177 :   si = TYPE_MODE (index_type) == SImode;
   20729         4177 :   switch (TYPE_MODE (vectype))
   20730              :     {
   20731          169 :     case E_V8DFmode:
   20732          169 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DF : IX86_BUILTIN_SCATTERDIV8DF;
   20733              :       break;
   20734          104 :     case E_V8DImode:
   20735          104 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DI : IX86_BUILTIN_SCATTERDIV8DI;
   20736              :       break;
   20737          177 :     case E_V16SFmode:
   20738          177 :       code = si ? IX86_BUILTIN_SCATTERSIV16SF : IX86_BUILTIN_SCATTERALTDIV16SF;
   20739              :       break;
   20740          257 :     case E_V16SImode:
   20741          257 :       code = si ? IX86_BUILTIN_SCATTERSIV16SI : IX86_BUILTIN_SCATTERALTDIV16SI;
   20742              :       break;
   20743          206 :     case E_V4DFmode:
   20744          206 :       if (TARGET_AVX512VL)
   20745           34 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DF : IX86_BUILTIN_SCATTERDIV4DF;
   20746              :       else
   20747              :         return NULL_TREE;
   20748              :       break;
   20749          142 :     case E_V4DImode:
   20750          142 :       if (TARGET_AVX512VL)
   20751           34 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DI : IX86_BUILTIN_SCATTERDIV4DI;
   20752              :       else
   20753              :         return NULL_TREE;
   20754              :       break;
   20755          248 :     case E_V8SFmode:
   20756          248 :       if (TARGET_AVX512VL)
   20757           40 :         code = si ? IX86_BUILTIN_SCATTERSIV8SF : IX86_BUILTIN_SCATTERALTDIV8SF;
   20758              :       else
   20759              :         return NULL_TREE;
   20760              :       break;
   20761          268 :     case E_V8SImode:
   20762          268 :       if (TARGET_AVX512VL)
   20763           82 :         code = si ? IX86_BUILTIN_SCATTERSIV8SI : IX86_BUILTIN_SCATTERALTDIV8SI;
   20764              :       else
   20765              :         return NULL_TREE;
   20766              :       break;
   20767          251 :     case E_V2DFmode:
   20768          251 :       if (TARGET_AVX512VL)
   20769           94 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DF : IX86_BUILTIN_SCATTERDIV2DF;
   20770              :       else
   20771              :         return NULL_TREE;
   20772              :       break;
   20773          196 :     case E_V2DImode:
   20774          196 :       if (TARGET_AVX512VL)
   20775           94 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DI : IX86_BUILTIN_SCATTERDIV2DI;
   20776              :       else
   20777              :         return NULL_TREE;
   20778              :       break;
   20779          301 :     case E_V4SFmode:
   20780          301 :       if (TARGET_AVX512VL)
   20781           96 :         code = si ? IX86_BUILTIN_SCATTERSIV4SF : IX86_BUILTIN_SCATTERALTDIV4SF;
   20782              :       else
   20783              :         return NULL_TREE;
   20784              :       break;
   20785          324 :     case E_V4SImode:
   20786          324 :       if (TARGET_AVX512VL)
   20787          138 :         code = si ? IX86_BUILTIN_SCATTERSIV4SI : IX86_BUILTIN_SCATTERALTDIV4SI;
   20788              :       else
   20789              :         return NULL_TREE;
   20790              :       break;
   20791              :     default:
   20792              :       return NULL_TREE;
   20793              :     }
   20794              : 
   20795         1319 :   return get_ix86_builtin (code);
   20796              : }
   20797              : 
   20798              : /* Return true if it is safe to use the rsqrt optabs to optimize
   20799              :    1.0/sqrt.  */
   20800              : 
   20801              : static bool
   20802           66 : use_rsqrt_p (machine_mode mode)
   20803              : {
   20804           66 :   return ((mode == HFmode
   20805           42 :            || (TARGET_SSE && TARGET_SSE_MATH))
   20806           66 :           && flag_finite_math_only
   20807           65 :           && !flag_trapping_math
   20808          119 :           && flag_unsafe_math_optimizations);
   20809              : }
   20810              : 
   20811              : /* Helper for avx_vpermilps256_operand et al.  This is also used by
   20812              :    the expansion functions to turn the parallel back into a mask.
   20813              :    The return value is 0 for no match and the imm8+1 for a match.  */
   20814              : 
   20815              : int
   20816        64196 : avx_vpermilp_parallel (rtx par, machine_mode mode)
   20817              : {
   20818        64196 :   unsigned i, nelt = GET_MODE_NUNITS (mode);
   20819        64196 :   unsigned mask = 0;
   20820        64196 :   unsigned char ipar[16] = {};  /* Silence -Wuninitialized warning.  */
   20821              : 
   20822        64196 :   if (XVECLEN (par, 0) != (int) nelt)
   20823              :     return 0;
   20824              : 
   20825              :   /* Validate that all of the elements are constants, and not totally
   20826              :      out of range.  Copy the data into an integral array to make the
   20827              :      subsequent checks easier.  */
   20828       312544 :   for (i = 0; i < nelt; ++i)
   20829              :     {
   20830       248348 :       rtx er = XVECEXP (par, 0, i);
   20831       248348 :       unsigned HOST_WIDE_INT ei;
   20832              : 
   20833       248348 :       if (!CONST_INT_P (er))
   20834              :         return 0;
   20835       248348 :       ei = INTVAL (er);
   20836       248348 :       if (ei >= nelt)
   20837              :         return 0;
   20838       248348 :       ipar[i] = ei;
   20839              :     }
   20840              : 
   20841        64196 :   switch (mode)
   20842              :     {
   20843              :     case E_V8DFmode:
   20844              :     case E_V8DImode:
   20845              :       /* In the 512-bit DFmode case, we can only move elements within
   20846              :          a 128-bit lane.  First fill the second part of the mask,
   20847              :          then fallthru.  */
   20848         4762 :       for (i = 4; i < 6; ++i)
   20849              :         {
   20850         3305 :           if (!IN_RANGE (ipar[i], 4, 5))
   20851              :             return 0;
   20852         3080 :           mask |= (ipar[i] - 4) << i;
   20853              :         }
   20854         3519 :       for (i = 6; i < 8; ++i)
   20855              :         {
   20856         2488 :           if (!IN_RANGE (ipar[i], 6, 7))
   20857              :             return 0;
   20858         2062 :           mask |= (ipar[i] - 6) << i;
   20859              :         }
   20860              :       /* FALLTHRU */
   20861              : 
   20862              :     case E_V4DFmode:
   20863              :     case E_V4DImode:
   20864              :       /* In the 256-bit DFmode case, we can only move elements within
   20865              :          a 128-bit lane.  */
   20866        46320 :       for (i = 0; i < 2; ++i)
   20867              :         {
   20868        38943 :           if (!IN_RANGE (ipar[i], 0, 1))
   20869              :             return 0;
   20870        25966 :           mask |= ipar[i] << i;
   20871              :         }
   20872        19441 :       for (i = 2; i < 4; ++i)
   20873              :         {
   20874        13414 :           if (!IN_RANGE (ipar[i], 2, 3))
   20875              :             return 0;
   20876        12064 :           mask |= (ipar[i] - 2) << i;
   20877              :         }
   20878              :       break;
   20879              : 
   20880              :     case E_V16SFmode:
   20881              :     case E_V16SImode:
   20882              :       /* In 512 bit SFmode case, permutation in the upper 256 bits
   20883              :          must mirror the permutation in the lower 256-bits.  */
   20884         3652 :       for (i = 0; i < 8; ++i)
   20885         3256 :         if (ipar[i] + 8 != ipar[i + 8])
   20886              :           return 0;
   20887              :       /* FALLTHRU */
   20888              : 
   20889              :     case E_V8SFmode:
   20890              :     case E_V8SImode:
   20891              :       /* In 256 bit SFmode case, we have full freedom of
   20892              :          movement within the low 128-bit lane, but the high 128-bit
   20893              :          lane must mirror the exact same pattern.  */
   20894        33640 :       for (i = 0; i < 4; ++i)
   20895        28529 :         if (ipar[i] + 4 != ipar[i + 4])
   20896              :           return 0;
   20897              :       nelt = 4;
   20898              :       /* FALLTHRU */
   20899              : 
   20900        38550 :     case E_V2DFmode:
   20901        38550 :     case E_V2DImode:
   20902        38550 :     case E_V4SFmode:
   20903        38550 :     case E_V4SImode:
   20904              :       /* In the 128-bit case, we've full freedom in the placement of
   20905              :          the elements from the source operand.  */
   20906       134722 :       for (i = 0; i < nelt; ++i)
   20907        96172 :         mask |= ipar[i] << (i * (nelt / 2));
   20908              :       break;
   20909              : 
   20910            0 :     default:
   20911            0 :       gcc_unreachable ();
   20912              :     }
   20913              : 
   20914              :   /* Make sure success has a non-zero value by adding one.  */
   20915        44577 :   return mask + 1;
   20916              : }
   20917              : 
   20918              : /* Helper for avx_vperm2f128_v4df_operand et al.  This is also used by
   20919              :    the expansion functions to turn the parallel back into a mask.
   20920              :    The return value is 0 for no match and the imm8+1 for a match.  */
   20921              : 
   20922              : int
   20923        42818 : avx_vperm2f128_parallel (rtx par, machine_mode mode)
   20924              : {
   20925        42818 :   unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
   20926        42818 :   unsigned mask = 0;
   20927        42818 :   unsigned char ipar[8] = {};  /* Silence -Wuninitialized warning.  */
   20928              : 
   20929        42818 :   if (XVECLEN (par, 0) != (int) nelt)
   20930              :     return 0;
   20931              : 
   20932              :   /* Validate that all of the elements are constants, and not totally
   20933              :      out of range.  Copy the data into an integral array to make the
   20934              :      subsequent checks easier.  */
   20935       344490 :   for (i = 0; i < nelt; ++i)
   20936              :     {
   20937       301672 :       rtx er = XVECEXP (par, 0, i);
   20938       301672 :       unsigned HOST_WIDE_INT ei;
   20939              : 
   20940       301672 :       if (!CONST_INT_P (er))
   20941              :         return 0;
   20942       301672 :       ei = INTVAL (er);
   20943       301672 :       if (ei >= 2 * nelt)
   20944              :         return 0;
   20945       301672 :       ipar[i] = ei;
   20946              :     }
   20947              : 
   20948              :   /* Validate that the halves of the permute are halves.  */
   20949        82729 :   for (i = 0; i < nelt2 - 1; ++i)
   20950        66550 :     if (ipar[i] + 1 != ipar[i + 1])
   20951              :       return 0;
   20952        51152 :   for (i = nelt2; i < nelt - 1; ++i)
   20953        35625 :     if (ipar[i] + 1 != ipar[i + 1])
   20954              :       return 0;
   20955              : 
   20956              :   /* Reconstruct the mask.  */
   20957        46485 :   for (i = 0; i < 2; ++i)
   20958              :     {
   20959        31008 :       unsigned e = ipar[i * nelt2];
   20960        31008 :       if (e % nelt2)
   20961              :         return 0;
   20962        30958 :       e /= nelt2;
   20963        30958 :       mask |= e << (i * 4);
   20964              :     }
   20965              : 
   20966              :   /* Make sure success has a non-zero value by adding one.  */
   20967        15477 :   return mask + 1;
   20968              : }
   20969              : 
   20970              : /* Return a mask of VPTERNLOG operands that do not affect output.  */
   20971              : 
   20972              : int
   20973         2431 : vpternlog_redundant_operand_mask (rtx pternlog_imm)
   20974              : {
   20975         2431 :   int mask = 0;
   20976         2431 :   int imm8 = INTVAL (pternlog_imm);
   20977              : 
   20978         2431 :   if (((imm8 >> 4) & 0x0F) == (imm8 & 0x0F))
   20979            6 :     mask |= 1;
   20980         2431 :   if (((imm8 >> 2) & 0x33) == (imm8 & 0x33))
   20981            6 :     mask |= 2;
   20982         2431 :   if (((imm8 >> 1) & 0x55) == (imm8 & 0x55))
   20983          155 :     mask |= 4;
   20984              : 
   20985         2431 :   return mask;
   20986              : }
   20987              : 
   20988              : /* Eliminate false dependencies on operands that do not affect output
   20989              :    by substituting other operands of a VPTERNLOG.  */
   20990              : 
   20991              : void
   20992           81 : substitute_vpternlog_operands (rtx *operands)
   20993              : {
   20994           81 :   int mask = vpternlog_redundant_operand_mask (operands[4]);
   20995              : 
   20996           81 :   if (mask & 1) /* The first operand is redundant.  */
   20997            2 :     operands[1] = operands[2];
   20998              : 
   20999           81 :   if (mask & 2) /* The second operand is redundant.  */
   21000            2 :     operands[2] = operands[1];
   21001              : 
   21002           81 :   if (mask & 4) /* The third operand is redundant.  */
   21003           77 :     operands[3] = operands[1];
   21004            4 :   else if (REG_P (operands[3]))
   21005              :     {
   21006            0 :       if (mask & 1)
   21007            0 :         operands[1] = operands[3];
   21008            0 :       if (mask & 2)
   21009            0 :         operands[2] = operands[3];
   21010              :     }
   21011           81 : }
   21012              : 
   21013              : /* Return a register priority for hard reg REGNO.  */
   21014              : static int
   21015     59519954 : ix86_register_priority (int hard_regno)
   21016              : {
   21017              :   /* ebp and r13 as the base always wants a displacement, r12 as the
   21018              :      base always wants an index.  So discourage their usage in an
   21019              :      address.  */
   21020     59519954 :   if (hard_regno == R12_REG || hard_regno == R13_REG)
   21021              :     return 0;
   21022     54917803 :   if (hard_regno == BP_REG)
   21023              :     return 1;
   21024              :   /* New x86-64 int registers result in bigger code size.  Discourage them.  */
   21025     52984800 :   if (REX_INT_REGNO_P (hard_regno))
   21026              :     return 2;
   21027     36065613 :   if (REX2_INT_REGNO_P (hard_regno))
   21028              :     return 2;
   21029              :   /* New x86-64 SSE registers result in bigger code size.  Discourage them.  */
   21030     36063091 :   if (REX_SSE_REGNO_P (hard_regno))
   21031              :     return 2;
   21032     29776884 :   if (EXT_REX_SSE_REGNO_P (hard_regno))
   21033              :     return 1;
   21034              :   /* Usage of AX register results in smaller code.  Prefer it.  */
   21035     29499828 :   if (hard_regno == AX_REG)
   21036      3917602 :     return 4;
   21037              :   return 3;
   21038              : }
   21039              : 
   21040              : /* Implement TARGET_PREFERRED_RELOAD_CLASS.
   21041              : 
   21042              :    Put float CONST_DOUBLE in the constant pool instead of fp regs.
   21043              :    QImode must go into class Q_REGS.
   21044              :    Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
   21045              :    movdf to do mem-to-mem moves through integer regs.  */
   21046              : 
   21047              : static reg_class_t
   21048    553889752 : ix86_preferred_reload_class (rtx x, reg_class_t regclass)
   21049              : {
   21050    553889752 :   machine_mode mode = GET_MODE (x);
   21051              : 
   21052              :   /* We're only allowed to return a subclass of CLASS.  Many of the
   21053              :      following checks fail for NO_REGS, so eliminate that early.  */
   21054    553889752 :   if (regclass == NO_REGS)
   21055              :     return NO_REGS;
   21056              : 
   21057              :   /* All classes can load zeros.  */
   21058    553015067 :   if (x == CONST0_RTX (mode))
   21059              :     return regclass;
   21060              : 
   21061              :   /* Force constants into memory if we are loading a (nonzero) constant into
   21062              :      an MMX, SSE or MASK register.  This is because there are no MMX/SSE/MASK
   21063              :      instructions to load from a constant.  */
   21064    527839508 :   if (CONSTANT_P (x)
   21065    527839508 :       && (MAYBE_MMX_CLASS_P (regclass)
   21066    153975018 :           || MAYBE_SSE_CLASS_P (regclass)
   21067    123317332 :           || MAYBE_MASK_CLASS_P (regclass)))
   21068     30791199 :     return NO_REGS;
   21069              : 
   21070              :   /* Floating-point constants need more complex checks.  */
   21071    497048309 :   if (CONST_DOUBLE_P (x))
   21072              :     {
   21073              :       /* General regs can load everything.  */
   21074       311108 :       if (INTEGER_CLASS_P (regclass))
   21075              :         return regclass;
   21076              : 
   21077              :       /* Floats can load 0 and 1 plus some others.  Note that we eliminated
   21078              :          zero above.  We only want to wind up preferring 80387 registers if
   21079              :          we plan on doing computation with them.  */
   21080       183343 :       if (IS_STACK_MODE (mode)
   21081       241831 :           && standard_80387_constant_p (x) > 0)
   21082              :         {
   21083              :           /* Limit class to FP regs.  */
   21084        40476 :           if (FLOAT_CLASS_P (regclass))
   21085              :             return FLOAT_REGS;
   21086              :         }
   21087              : 
   21088       142867 :       return NO_REGS;
   21089              :     }
   21090              : 
   21091              :   /* Prefer SSE if we can use them for math.  Also allow integer regs
   21092              :      when moves between register units are cheap.  */
   21093    496737201 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   21094              :     {
   21095     31176825 :       if (TARGET_INTER_UNIT_MOVES_FROM_VEC
   21096     31161912 :           && TARGET_INTER_UNIT_MOVES_TO_VEC
   21097     93491383 :           && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
   21098     31019796 :         return INT_SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   21099              :       else
   21100       157029 :         return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   21101              :     }
   21102              : 
   21103              :   /* Generally when we see PLUS here, it's the function invariant
   21104              :      (plus soft-fp const_int).  Which can only be computed into general
   21105              :      regs.  */
   21106    465560376 :   if (GET_CODE (x) == PLUS)
   21107      2024181 :     return INTEGER_CLASS_P (regclass) ? regclass : NO_REGS;
   21108              : 
   21109              :   /* QImode constants are easy to load, but non-constant QImode data
   21110              :      must go into Q_REGS or ALL_MASK_REGS.  */
   21111    463536195 :   if (GET_MODE (x) == QImode && !CONSTANT_P (x))
   21112              :     {
   21113     24786422 :       if (Q_CLASS_P (regclass))
   21114              :         return regclass;
   21115     20021387 :       else if (reg_class_subset_p (Q_REGS, regclass))
   21116              :         return Q_REGS;
   21117        55309 :       else if (MASK_CLASS_P (regclass))
   21118              :         return regclass;
   21119              :       else
   21120              :         return NO_REGS;
   21121              :     }
   21122              : 
   21123              :   return regclass;
   21124              : }
   21125              : 
   21126              : /* Discourage putting floating-point values in SSE registers unless
   21127              :    SSE math is being used, and likewise for the 387 registers.  */
   21128              : static reg_class_t
   21129     75524541 : ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
   21130              : {
   21131              :   /* Restrict the output reload class to the register bank that we are doing
   21132              :      math on.  If we would like not to return a subset of CLASS, reject this
   21133              :      alternative: if reload cannot do this, it will still use its choice.  */
   21134     75524541 :   machine_mode mode = GET_MODE (x);
   21135     75524541 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   21136      7248581 :     return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
   21137              : 
   21138     68275960 :   if (IS_STACK_MODE (mode))
   21139       212178 :     return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
   21140              : 
   21141              :   return regclass;
   21142              : }
   21143              : 
   21144              : static reg_class_t
   21145    390538725 : ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
   21146              :                        machine_mode mode, secondary_reload_info *sri)
   21147              : {
   21148              :   /* Double-word spills from general registers to non-offsettable memory
   21149              :      references (zero-extended addresses) require special handling.  */
   21150    390538725 :   if (TARGET_64BIT
   21151    337546292 :       && MEM_P (x)
   21152    182434198 :       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
   21153     18518743 :       && INTEGER_CLASS_P (rclass)
   21154    393250519 :       && !offsettable_memref_p (x))
   21155              :     {
   21156      2465252 :       sri->icode = (in_p
   21157      1232626 :                     ? CODE_FOR_reload_noff_load
   21158              :                     : CODE_FOR_reload_noff_store);
   21159              :       /* Add the cost of moving address to a temporary.  */
   21160      1232626 :       sri->extra_cost = 1;
   21161              : 
   21162      1232626 :       return NO_REGS;
   21163              :     }
   21164              : 
   21165              :   /* QImode spills from non-QI registers require
   21166              :      intermediate register on 32bit targets.  */
   21167    389306099 :   if (mode == QImode
   21168    389306099 :       && ((!TARGET_64BIT && !in_p
   21169       587374 :            && INTEGER_CLASS_P (rclass)
   21170       587334 :            && MAYBE_NON_Q_CLASS_P (rclass))
   21171     22437186 :           || (!TARGET_AVX512DQ
   21172     22228754 :               && MAYBE_MASK_CLASS_P (rclass))))
   21173              :     {
   21174         6555 :       int regno = true_regnum (x);
   21175              : 
   21176              :       /* Return Q_REGS if the operand is in memory.  */
   21177         6555 :       if (regno == -1)
   21178              :         return Q_REGS;
   21179              : 
   21180              :       return NO_REGS;
   21181              :     }
   21182              : 
   21183              :   /* Require movement to gpr, and then store to memory.  */
   21184    389299544 :   if ((mode == HFmode || mode == HImode || mode == V2QImode
   21185              :        || mode == BFmode)
   21186      4140911 :       && !TARGET_SSE4_1
   21187      3549200 :       && SSE_CLASS_P (rclass)
   21188       284722 :       && !in_p && MEM_P (x))
   21189              :     {
   21190       173852 :       sri->extra_cost = 1;
   21191       173852 :       return GENERAL_REGS;
   21192              :     }
   21193              : 
   21194              :   /* This condition handles corner case where an expression involving
   21195              :      pointers gets vectorized.  We're trying to use the address of a
   21196              :      stack slot as a vector initializer.
   21197              : 
   21198              :      (set (reg:V2DI 74 [ vect_cst_.2 ])
   21199              :           (vec_duplicate:V2DI (reg/f:DI 20 frame)))
   21200              : 
   21201              :      Eventually frame gets turned into sp+offset like this:
   21202              : 
   21203              :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21204              :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   21205              :                                        (const_int 392 [0x188]))))
   21206              : 
   21207              :      That later gets turned into:
   21208              : 
   21209              :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21210              :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   21211              :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
   21212              : 
   21213              :      We'll have the following reload recorded:
   21214              : 
   21215              :      Reload 0: reload_in (DI) =
   21216              :            (plus:DI (reg/f:DI 7 sp)
   21217              :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
   21218              :      reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21219              :      SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
   21220              :      reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
   21221              :      reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21222              :      reload_reg_rtx: (reg:V2DI 22 xmm1)
   21223              : 
   21224              :      Which isn't going to work since SSE instructions can't handle scalar
   21225              :      additions.  Returning GENERAL_REGS forces the addition into integer
   21226              :      register and reload can handle subsequent reloads without problems.  */
   21227              : 
   21228    223730059 :   if (in_p && GET_CODE (x) == PLUS
   21229            2 :       && SSE_CLASS_P (rclass)
   21230    389125692 :       && SCALAR_INT_MODE_P (mode))
   21231              :     return GENERAL_REGS;
   21232              : 
   21233              :   return NO_REGS;
   21234              : }
   21235              : 
   21236              : /* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
   21237              : 
   21238              : static bool
   21239    725194690 : ix86_class_likely_spilled_p (reg_class_t rclass)
   21240              : {
   21241    715020763 :   switch (rclass)
   21242              :     {
   21243              :       case AREG:
   21244              :       case DREG:
   21245              :       case CREG:
   21246              :       case BREG:
   21247              :       case AD_REGS:
   21248              :       case SIREG:
   21249              :       case DIREG:
   21250              :       case SSE_FIRST_REG:
   21251              :       case FP_TOP_REG:
   21252              :       case FP_SECOND_REG:
   21253              :         return true;
   21254              : 
   21255    693022554 :       default:
   21256    693022554 :         break;
   21257              :     }
   21258              : 
   21259    693022554 :   return false;
   21260              : }
   21261              : 
   21262              : /* Implement TARGET_CALLEE_SAVE_COST.  */
   21263              : 
   21264              : static int
   21265     82410772 : ix86_callee_save_cost (spill_cost_type, unsigned int hard_regno, machine_mode,
   21266              :                        unsigned int, int mem_cost, const HARD_REG_SET &, bool)
   21267              : {
   21268              :   /* Account for the fact that push and pop are shorter and do their
   21269              :      own allocation and deallocation.  */
   21270     82410772 :   if (GENERAL_REGNO_P (hard_regno))
   21271              :     {
   21272              :       /* push is 1 byte while typical spill is 4-5 bytes.
   21273              :          ??? We probably should adjust size costs accordingly.
   21274              :          Costs are relative to reg-reg move that has 2 bytes for 32bit
   21275              :          and 3 bytes otherwise.  Be sure that no cost table sets cost
   21276              :          to 2, so we end up with 0.  */
   21277     82400582 :       if (mem_cost <= 2 || optimize_function_for_size_p (cfun))
   21278      3585956 :         return 1;
   21279     78814626 :       return mem_cost - 2;
   21280              :     }
   21281              :   return mem_cost;
   21282              : }
   21283              : 
   21284              : /* Return true if a set of DST by the expression SRC should be allowed.
   21285              :    This prevents complex sets of likely_spilled hard regs before split1.  */
   21286              : 
   21287              : bool
   21288    614282848 : ix86_hardreg_mov_ok (rtx dst, rtx src)
   21289              : {
   21290              :   /* Avoid complex sets of likely_spilled hard registers before reload.  */
   21291    508739774 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   21292    297395609 :       && !REG_P (src) && !MEM_P (src)
   21293     97554981 :       && !(VECTOR_MODE_P (GET_MODE (dst))
   21294     97554981 :            ? standard_sse_constant_p (src, GET_MODE (dst))
   21295     48538562 :            : x86_64_immediate_operand (src, GET_MODE (dst)))
   21296     10173927 :       && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
   21297    623215110 :       && ix86_pre_reload_split ())
   21298              :     return false;
   21299              :   return true;
   21300              : }
   21301              : 
   21302              : /* If we are copying between registers from different register sets
   21303              :    (e.g. FP and integer), we may need a memory location.
   21304              : 
   21305              :    The function can't work reliably when one of the CLASSES is a class
   21306              :    containing registers from multiple sets.  We avoid this by never combining
   21307              :    different sets in a single alternative in the machine description.
   21308              :    Ensure that this constraint holds to avoid unexpected surprises.
   21309              : 
   21310              :    When STRICT is false, we are being called from REGISTER_MOVE_COST,
   21311              :    so do not enforce these sanity checks.
   21312              : 
   21313              :    To optimize register_move_cost performance, define inline variant.  */
   21314              : 
   21315              : static inline bool
   21316   5735133493 : inline_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   21317              :                                 reg_class_t class2, int strict)
   21318              : {
   21319   5735133493 :   if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
   21320              :     return false;
   21321              : 
   21322   5702668891 :   if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
   21323   4859755271 :       || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
   21324   4150061630 :       || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
   21325   3959620155 :       || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
   21326   3779394272 :       || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
   21327   3779394272 :       || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
   21328   3779394272 :       || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
   21329   9310320143 :       || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
   21330              :     {
   21331   2258669682 :       gcc_assert (!strict || lra_in_progress);
   21332              :       return true;
   21333              :     }
   21334              : 
   21335   3443999209 :   if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
   21336              :     return true;
   21337              : 
   21338              :   /* ??? This is a lie.  We do have moves between mmx/general, and for
   21339              :      mmx/sse2.  But by saying we need secondary memory we discourage the
   21340              :      register allocator from using the mmx registers unless needed.  */
   21341   3293472879 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   21342              :     return true;
   21343              : 
   21344              :   /* Between mask and general, we have moves no larger than word size.  */
   21345   3196059354 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   21346              :     {
   21347      2612214 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2))
   21348      3411939 :           || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21349       193123 :         return true;
   21350              :     }
   21351              : 
   21352   3195866231 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   21353              :     {
   21354              :       /* SSE1 doesn't have any direct moves from other classes.  */
   21355    694495400 :       if (!TARGET_SSE2)
   21356              :         return true;
   21357              : 
   21358    692303996 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)))
   21359              :         return true;
   21360              : 
   21361              :       /* If the target says that inter-unit moves are more expensive
   21362              :          than moving through memory, then don't generate them.  */
   21363   1038050562 :       if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC)
   21364   1037564718 :           || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC))
   21365      1321114 :         return true;
   21366              : 
   21367              :       /* With SSE4.1, *mov{ti,di}_internal supports moves between
   21368              :          SSE_REGS and GENERAL_REGS using pinsr{q,d} or pextr{q,d}.  */
   21369    690982882 :       if (TARGET_SSE4_1
   21370     36644205 :           && (TARGET_64BIT ? mode == TImode : mode == DImode))
   21371              :         return false;
   21372              : 
   21373    689394537 :       int msize = GET_MODE_SIZE (mode);
   21374              : 
   21375              :       /* Between SSE and general, we have moves no larger than word size.  */
   21376    705775816 :       if (msize > UNITS_PER_WORD)
   21377              :         return true;
   21378              : 
   21379              :       /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
   21380              :          Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16.  */
   21381    596408068 :       int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
   21382              : 
   21383    596408068 :       if (msize < minsize)
   21384              :         return true;
   21385              :     }
   21386              : 
   21387              :   return false;
   21388              : }
   21389              : 
   21390              : /* Implement TARGET_SECONDARY_MEMORY_NEEDED.  */
   21391              : 
   21392              : static bool
   21393     72170173 : ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   21394              :                               reg_class_t class2)
   21395              : {
   21396     72170173 :   return inline_secondary_memory_needed (mode, class1, class2, true);
   21397              : }
   21398              : 
   21399              : /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
   21400              : 
   21401              :    get_secondary_mem widens integral modes to BITS_PER_WORD.
   21402              :    There is no need to emit full 64 bit move on 64 bit targets
   21403              :    for integral modes that can be moved using 32 bit move.  */
   21404              : 
   21405              : static machine_mode
   21406        13059 : ix86_secondary_memory_needed_mode (machine_mode mode)
   21407              : {
   21408        26118 :   if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
   21409           19 :     return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
   21410              :   return mode;
   21411              : }
   21412              : 
   21413              : /* Implement the TARGET_CLASS_MAX_NREGS hook.
   21414              : 
   21415              :    On the 80386, this is the size of MODE in words,
   21416              :    except in the FP regs, where a single reg is always enough.  */
   21417              : 
   21418              : static unsigned char
   21419   5766384688 : ix86_class_max_nregs (reg_class_t rclass, machine_mode mode)
   21420              : {
   21421   5766384688 :   if (MAYBE_INTEGER_CLASS_P (rclass))
   21422              :     {
   21423   3885289280 :       if (mode == XFmode)
   21424    145997999 :         return (TARGET_64BIT ? 2 : 3);
   21425   3739291281 :       else if (mode == XCmode)
   21426    145997624 :         return (TARGET_64BIT ? 4 : 6);
   21427              :       else
   21428   7292357270 :         return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21429              :     }
   21430              :   else
   21431              :     {
   21432   1881095408 :       if (COMPLEX_MODE_P (mode))
   21433              :         return 2;
   21434              :       else
   21435   1605141309 :         return 1;
   21436              :     }
   21437              : }
   21438              : 
   21439              : /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
   21440              : 
   21441              : static bool
   21442     41332483 : ix86_can_change_mode_class (machine_mode from, machine_mode to,
   21443              :                             reg_class_t regclass)
   21444              : {
   21445     41332483 :   if (from == to)
   21446              :     return true;
   21447              : 
   21448              :   /* x87 registers can't do subreg at all, as all values are reformatted
   21449              :      to extended precision.
   21450              : 
   21451              :      ??? middle-end queries mode changes for ALL_REGS and this makes
   21452              :      vec_series_lowpart_p to always return false.  We probably should
   21453              :      restrict this to modes supported by i387 and check if it is enabled.  */
   21454     39848583 :   if (MAYBE_FLOAT_CLASS_P (regclass))
   21455              :     return false;
   21456              : 
   21457     35062085 :   if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
   21458              :     {
   21459              :       /* Vector registers do not support QI or HImode loads.  If we don't
   21460              :          disallow a change to these modes, reload will assume it's ok to
   21461              :          drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
   21462              :          the vec_dupv4hi pattern.
   21463              :          NB: SSE2 can load 16bit data to sse register via pinsrw.  */
   21464     16793165 :       int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
   21465     16793165 :       if (GET_MODE_SIZE (from) < mov_size
   21466     33586016 :           || GET_MODE_SIZE (to) < mov_size)
   21467              :         return false;
   21468              :     }
   21469              : 
   21470              :   return true;
   21471              : }
   21472              : 
   21473              : /* Return index of MODE in the sse load/store tables.  */
   21474              : 
   21475              : static inline int
   21476    780689862 : sse_store_index (machine_mode mode)
   21477              : {
   21478              :   /* NB: Use SFmode cost for HFmode instead of adding HFmode load/store
   21479              :      costs to processor_costs, which requires changes to all entries in
   21480              :      processor cost table.  */
   21481    780689862 :   if (mode == E_HFmode)
   21482    138359338 :     mode = E_SFmode;
   21483              : 
   21484   1561379724 :   switch (GET_MODE_SIZE (mode))
   21485              :     {
   21486              :     case 4:
   21487              :       return 0;
   21488              :     case 8:
   21489              :       return 1;
   21490              :     case 16:
   21491              :       return 2;
   21492              :     case 32:
   21493              :       return 3;
   21494              :     case 64:
   21495              :       return 4;
   21496              :     default:
   21497              :       return -1;
   21498              :     }
   21499              : }
   21500              : 
   21501              : /* Return the cost of moving data of mode M between a
   21502              :    register and memory.  A value of 2 is the default; this cost is
   21503              :    relative to those in `REGISTER_MOVE_COST'.
   21504              : 
   21505              :    This function is used extensively by register_move_cost that is used to
   21506              :    build tables at startup.  Make it inline in this case.
   21507              :    When IN is 2, return maximum of in and out move cost.
   21508              : 
   21509              :    If moving between registers and memory is more expensive than
   21510              :    between two registers, you should define this macro to express the
   21511              :    relative cost.
   21512              : 
   21513              :    Model also increased moving costs of QImode registers in non
   21514              :    Q_REGS classes.
   21515              :  */
   21516              : static inline int
   21517   6978568990 : inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
   21518              : {
   21519   6978568990 :   int cost;
   21520              : 
   21521   6978568990 :   if (FLOAT_CLASS_P (regclass))
   21522              :     {
   21523    356439293 :       int index;
   21524    356439293 :       switch (mode)
   21525              :         {
   21526              :           case E_SFmode:
   21527              :             index = 0;
   21528              :             break;
   21529              :           case E_DFmode:
   21530              :             index = 1;
   21531              :             break;
   21532              :           case E_XFmode:
   21533              :             index = 2;
   21534              :             break;
   21535              :           default:
   21536              :             return 100;
   21537              :         }
   21538    106548725 :       if (in == 2)
   21539    102568157 :         return MAX (ix86_cost->hard_register.fp_load [index],
   21540              :                     ix86_cost->hard_register.fp_store [index]);
   21541      3980568 :       return in ? ix86_cost->hard_register.fp_load [index]
   21542      3980568 :                 : ix86_cost->hard_register.fp_store [index];
   21543              :     }
   21544   6622129697 :   if (SSE_CLASS_P (regclass))
   21545              :     {
   21546    650372704 :       int index = sse_store_index (mode);
   21547    650372704 :       if (index == -1)
   21548              :         return 100;
   21549    565610953 :       if (in == 2)
   21550    400705524 :         return MAX (ix86_cost->hard_register.sse_load [index],
   21551              :                     ix86_cost->hard_register.sse_store [index]);
   21552    164905429 :       return in ? ix86_cost->hard_register.sse_load [index]
   21553    164905429 :                 : ix86_cost->hard_register.sse_store [index];
   21554              :     }
   21555   5971756993 :   if (MASK_CLASS_P (regclass))
   21556              :     {
   21557    109287603 :       int index;
   21558    218575206 :       switch (GET_MODE_SIZE (mode))
   21559              :         {
   21560              :         case 1:
   21561              :           index = 0;
   21562              :           break;
   21563      9014229 :         case 2:
   21564      9014229 :           index = 1;
   21565      9014229 :           break;
   21566              :         /* DImode loads and stores assumed to cost the same as SImode.  */
   21567     40559118 :         case 4:
   21568     40559118 :         case 8:
   21569     40559118 :           index = 2;
   21570     40559118 :           break;
   21571              :         default:
   21572              :           return 100;
   21573              :         }
   21574              : 
   21575     53183155 :       if (in == 2)
   21576       585187 :         return MAX (ix86_cost->hard_register.mask_load[index],
   21577              :                     ix86_cost->hard_register.mask_store[index]);
   21578     52597968 :       return in ? ix86_cost->hard_register.mask_load[2]
   21579     52597968 :                 : ix86_cost->hard_register.mask_store[2];
   21580              :     }
   21581   5862469390 :   if (MMX_CLASS_P (regclass))
   21582              :     {
   21583    174029132 :       int index;
   21584    348058264 :       switch (GET_MODE_SIZE (mode))
   21585              :         {
   21586              :           case 4:
   21587              :             index = 0;
   21588              :             break;
   21589    102136548 :           case 8:
   21590    102136548 :             index = 1;
   21591    102136548 :             break;
   21592              :           default:
   21593              :             return 100;
   21594              :         }
   21595    139840484 :       if (in == 2)
   21596    119677926 :         return MAX (ix86_cost->hard_register.mmx_load [index],
   21597              :                     ix86_cost->hard_register.mmx_store [index]);
   21598     20162558 :       return in ? ix86_cost->hard_register.mmx_load [index]
   21599     20162558 :                 : ix86_cost->hard_register.mmx_store [index];
   21600              :     }
   21601  11376880516 :   switch (GET_MODE_SIZE (mode))
   21602              :     {
   21603    125928078 :       case 1:
   21604    125928078 :         if (Q_CLASS_P (regclass) || TARGET_64BIT)
   21605              :           {
   21606    123297829 :             if (!in)
   21607     19778812 :               return ix86_cost->hard_register.int_store[0];
   21608    103519017 :             if (TARGET_PARTIAL_REG_DEPENDENCY
   21609    103519017 :                 && optimize_function_for_speed_p (cfun))
   21610     96549220 :               cost = ix86_cost->hard_register.movzbl_load;
   21611              :             else
   21612      6969797 :               cost = ix86_cost->hard_register.int_load[0];
   21613    103519017 :             if (in == 2)
   21614     83712210 :               return MAX (cost, ix86_cost->hard_register.int_store[0]);
   21615              :             return cost;
   21616              :           }
   21617              :         else
   21618              :           {
   21619      2630249 :            if (in == 2)
   21620      1862690 :              return MAX (ix86_cost->hard_register.movzbl_load,
   21621              :                          ix86_cost->hard_register.int_store[0] + 4);
   21622       767559 :            if (in)
   21623       383835 :              return ix86_cost->hard_register.movzbl_load;
   21624              :            else
   21625       383724 :              return ix86_cost->hard_register.int_store[0] + 4;
   21626              :           }
   21627    649948098 :         break;
   21628    649948098 :       case 2:
   21629    649948098 :         {
   21630    649948098 :           int cost;
   21631    649948098 :           if (in == 2)
   21632    549114901 :             cost = MAX (ix86_cost->hard_register.int_load[1],
   21633              :                         ix86_cost->hard_register.int_store[1]);
   21634              :           else
   21635    100833197 :             cost = in ? ix86_cost->hard_register.int_load[1]
   21636              :                       : ix86_cost->hard_register.int_store[1];
   21637              : 
   21638    649948098 :           if (mode == E_HFmode)
   21639              :             {
   21640              :               /* Prefer SSE over GPR for HFmode.  */
   21641    125940554 :               int sse_cost;
   21642    125940554 :               int index = sse_store_index (mode);
   21643    125940554 :               if (in == 2)
   21644    115859176 :                 sse_cost = MAX (ix86_cost->hard_register.sse_load[index],
   21645              :                                 ix86_cost->hard_register.sse_store[index]);
   21646              :               else
   21647     20162756 :                 sse_cost = (in
   21648     10081378 :                             ? ix86_cost->hard_register.sse_load [index]
   21649              :                             : ix86_cost->hard_register.sse_store [index]);
   21650    125940554 :               if (sse_cost >= cost)
   21651    125940554 :                 cost = sse_cost + 1;
   21652              :             }
   21653              :           return cost;
   21654              :         }
   21655   4912564082 :       default:
   21656   4912564082 :         if (in == 2)
   21657   3803245284 :           cost = MAX (ix86_cost->hard_register.int_load[2],
   21658              :                       ix86_cost->hard_register.int_store[2]);
   21659   1109318798 :         else if (in)
   21660    554849058 :           cost = ix86_cost->hard_register.int_load[2];
   21661              :         else
   21662    554469740 :           cost = ix86_cost->hard_register.int_store[2];
   21663              :         /* Multiply with the number of GPR moves needed.  */
   21664   9944149825 :         return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21665              :     }
   21666              : }
   21667              : 
   21668              : static int
   21669   1794242602 : ix86_memory_move_cost (machine_mode mode, reg_class_t regclass, bool in)
   21670              : {
   21671   2691037138 :   return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
   21672              : }
   21673              : 
   21674              : 
   21675              : /* Return the cost of moving data from a register in class CLASS1 to
   21676              :    one in class CLASS2.
   21677              : 
   21678              :    It is not required that the cost always equal 2 when FROM is the same as TO;
   21679              :    on some machines it is expensive to move between registers if they are not
   21680              :    general registers.  */
   21681              : 
   21682              : static int
   21683   5662963320 : ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
   21684              :                          reg_class_t class2_i)
   21685              : {
   21686   5662963320 :   enum reg_class class1 = (enum reg_class) class1_i;
   21687   5662963320 :   enum reg_class class2 = (enum reg_class) class2_i;
   21688              : 
   21689              :   /* In case we require secondary memory, compute cost of the store followed
   21690              :      by load.  In order to avoid bad register allocation choices, we need
   21691              :      for this to be *at least* as high as the symmetric MEMORY_MOVE_COST.  */
   21692              : 
   21693   5662963320 :   if (inline_secondary_memory_needed (mode, class1, class2, false))
   21694              :     {
   21695   2592163194 :       int cost = 1;
   21696              : 
   21697   2592163194 :       cost += inline_memory_move_cost (mode, class1, 2);
   21698   2592163194 :       cost += inline_memory_move_cost (mode, class2, 2);
   21699              : 
   21700              :       /* In case of copying from general_purpose_register we may emit multiple
   21701              :          stores followed by single load causing memory size mismatch stall.
   21702              :          Count this as arbitrarily high cost of 20.  */
   21703   5184326388 :       if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD
   21704    775940591 :           && TARGET_MEMORY_MISMATCH_STALL
   21705   4144044376 :           && targetm.class_max_nregs (class1, mode)
   21706    775940591 :              > targetm.class_max_nregs (class2, mode))
   21707    147627669 :         cost += 20;
   21708              : 
   21709              :       /* In the case of FP/MMX moves, the registers actually overlap, and we
   21710              :          have to switch modes in order to treat them differently.  */
   21711     59838999 :       if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
   21712   2642578399 :           || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
   21713     18847588 :         cost += 20;
   21714              : 
   21715   2592163194 :       return cost;
   21716              :     }
   21717              : 
   21718              :   /* Moves between MMX and non-MMX units require secondary memory.  */
   21719   3070800126 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   21720            0 :     gcc_unreachable ();
   21721              : 
   21722   3070800126 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   21723    588192716 :     return (SSE_CLASS_P (class1)
   21724    588192716 :             ? ix86_cost->hard_register.sse_to_integer
   21725    588192716 :             : ix86_cost->hard_register.integer_to_sse);
   21726              : 
   21727              :   /* Moves between mask register and GPR.  */
   21728   2482607410 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   21729              :     {
   21730      1056274 :       return (MASK_CLASS_P (class1)
   21731      1056274 :               ? ix86_cost->hard_register.mask_to_integer
   21732      1056274 :               : ix86_cost->hard_register.integer_to_mask);
   21733              :     }
   21734              :   /* Moving between mask registers.  */
   21735   2481551136 :   if (MASK_CLASS_P (class1) && MASK_CLASS_P (class2))
   21736       101327 :     return ix86_cost->hard_register.mask_move;
   21737              : 
   21738   2481449809 :   if (MAYBE_FLOAT_CLASS_P (class1))
   21739     11913696 :     return ix86_cost->hard_register.fp_move;
   21740   2469536113 :   if (MAYBE_SSE_CLASS_P (class1))
   21741              :     {
   21742    231792092 :       if (GET_MODE_BITSIZE (mode) <= 128)
   21743    113427659 :         return ix86_cost->hard_register.xmm_move;
   21744      4936774 :       if (GET_MODE_BITSIZE (mode) <= 256)
   21745      1568427 :         return ix86_cost->hard_register.ymm_move;
   21746       899960 :       return ix86_cost->hard_register.zmm_move;
   21747              :     }
   21748   2353640067 :   if (MAYBE_MMX_CLASS_P (class1))
   21749      2191635 :     return ix86_cost->hard_register.mmx_move;
   21750              :   return 2;
   21751              : }
   21752              : 
   21753              : /* Implement TARGET_HARD_REGNO_NREGS.  This is ordinarily the length in
   21754              :    words of a value of mode MODE but can be less for certain modes in
   21755              :    special long registers.
   21756              : 
   21757              :    Actually there are no two word move instructions for consecutive
   21758              :    registers.  And only registers 0-3 may have mov byte instructions
   21759              :    applied to them.  */
   21760              : 
   21761              : static unsigned int
   21762   8883261296 : ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
   21763              : {
   21764   8883261296 :   if (GENERAL_REGNO_P (regno))
   21765              :     {
   21766   3089830016 :       if (mode == XFmode)
   21767     25393824 :         return TARGET_64BIT ? 2 : 3;
   21768   3064912032 :       if (mode == XCmode)
   21769     25393824 :         return TARGET_64BIT ? 4 : 6;
   21770   6138040576 :       return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21771              :     }
   21772   5793431280 :   if (COMPLEX_MODE_P (mode))
   21773              :     return 2;
   21774              :   /* Register pair for mask registers.  */
   21775   5045891760 :   if (mode == P2QImode || mode == P2HImode)
   21776     93442440 :     return 2;
   21777              : 
   21778              :   return 1;
   21779              : }
   21780              : 
   21781              : /* Implement REGMODE_NATURAL_SIZE(MODE).  */
   21782              : unsigned int
   21783    114826619 : ix86_regmode_natural_size (machine_mode mode)
   21784              : {
   21785    114826619 :   if (mode == P2HImode || mode == P2QImode)
   21786         2462 :     return GET_MODE_SIZE (mode) / 2;
   21787    114825388 :   return UNITS_PER_WORD;
   21788              : }
   21789              : 
   21790              : /* Implement TARGET_HARD_REGNO_MODE_OK.  */
   21791              : 
   21792              : static bool
   21793  52441177903 : ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   21794              : {
   21795              :   /* Flags and only flags can only hold CCmode values.  */
   21796  52441177903 :   if (CC_REGNO_P (regno))
   21797    414277204 :     return GET_MODE_CLASS (mode) == MODE_CC;
   21798  52026900699 :   if (GET_MODE_CLASS (mode) == MODE_CC
   21799              :       || GET_MODE_CLASS (mode) == MODE_RANDOM)
   21800              :     return false;
   21801  46696101832 :   if (STACK_REGNO_P (regno))
   21802   4545917514 :     return VALID_FP_MODE_P (mode);
   21803  42150184318 :   if (MASK_REGNO_P (regno))
   21804              :     {
   21805              :       /* Register pair only starts at even register number.  */
   21806   3542787009 :       if ((mode == P2QImode || mode == P2HImode))
   21807     48836558 :         return MASK_PAIR_REGNO_P(regno);
   21808              : 
   21809    987908435 :       return ((TARGET_AVX512F && VALID_MASK_REG_MODE (mode))
   21810   4461755861 :               || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
   21811              :     }
   21812              : 
   21813  38607397309 :   if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
   21814              :     return false;
   21815              : 
   21816  37664262791 :   if (SSE_REGNO_P (regno))
   21817              :     {
   21818              :       /* We implement the move patterns for all vector modes into and
   21819              :          out of SSE registers, even when no operation instructions
   21820              :          are available.  */
   21821              : 
   21822              :       /* For AVX-512 we allow, regardless of regno:
   21823              :           - XI mode
   21824              :           - any of 512-bit wide vector mode
   21825              :           - any scalar mode.  */
   21826  16297107504 :       if (TARGET_AVX512F
   21827              :           && ((VALID_AVX512F_REG_OR_XI_MODE (mode))
   21828              :               || VALID_AVX512F_SCALAR_MODE (mode)))
   21829              :         return true;
   21830              : 
   21831              :       /* TODO check for QI/HI scalars.  */
   21832              :       /* AVX512VL allows sse regs16+ for 128/256 bit modes.  */
   21833  15615793997 :       if (TARGET_AVX512VL
   21834   1738101979 :           && (VALID_AVX256_REG_OR_OI_MODE (mode)
   21835   1527444541 :               || VALID_AVX512VL_128_REG_MODE (mode)))
   21836              :         return true;
   21837              : 
   21838              :       /* xmm16-xmm31 are only available for AVX-512.  */
   21839  15172628089 :       if (EXT_REX_SSE_REGNO_P (regno))
   21840              :         return false;
   21841              : 
   21842              :       /* OImode and AVX modes are available only when AVX is enabled.  */
   21843   8795830017 :       return ((TARGET_AVX
   21844   1892505800 :                && VALID_AVX256_REG_OR_OI_MODE (mode))
   21845              :               || VALID_SSE_REG_MODE (mode)
   21846              :               || VALID_SSE2_REG_MODE (mode)
   21847              :               || VALID_MMX_REG_MODE (mode)
   21848   8795830017 :               || VALID_MMX_REG_MODE_3DNOW (mode));
   21849              :     }
   21850  21367155287 :   if (MMX_REGNO_P (regno))
   21851              :     {
   21852              :       /* We implement the move patterns for 3DNOW modes even in MMX mode,
   21853              :          so if the register is available at all, then we can move data of
   21854              :          the given mode into or out of it.  */
   21855   3784699516 :       return (VALID_MMX_REG_MODE (mode)
   21856              :               || VALID_MMX_REG_MODE_3DNOW (mode));
   21857              :     }
   21858              : 
   21859  17582455771 :   if (mode == QImode)
   21860              :     {
   21861              :       /* Take care for QImode values - they can be in non-QI regs,
   21862              :          but then they do cause partial register stalls.  */
   21863    200810735 :       if (ANY_QI_REGNO_P (regno))
   21864              :         return true;
   21865     13847564 :       if (!TARGET_PARTIAL_REG_STALL)
   21866              :         return true;
   21867              :       /* LRA checks if the hard register is OK for the given mode.
   21868              :          QImode values can live in non-QI regs, so we allow all
   21869              :          registers here.  */
   21870           19 :       if (lra_in_progress)
   21871              :        return true;
   21872           19 :       return !can_create_pseudo_p ();
   21873              :     }
   21874              :   /* We handle both integer and floats in the general purpose registers.  */
   21875  17381645036 :   else if (VALID_INT_MODE_P (mode)
   21876  12696194401 :            || VALID_FP_MODE_P (mode))
   21877              :     return true;
   21878              :   /* Lots of MMX code casts 8 byte vector modes to DImode.  If we then go
   21879              :      on to use that value in smaller contexts, this can easily force a
   21880              :      pseudo to be allocated to GENERAL_REGS.  Since this is no worse than
   21881              :      supporting DImode, allow it.  */
   21882  11670799719 :   else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
   21883              :     return true;
   21884              : 
   21885              :   return false;
   21886              : }
   21887              : 
   21888              : /* Initialize function_abis[ABI_ID] with the set of register clobbers
   21889              :    in FULL_REG_CLOBBERS, adjusting for rules that apply to all ABIs.  */
   21890              : 
   21891              : static void
   21892          762 : ix86_initialize_abi (unsigned int abi_id, HARD_REG_SET full_reg_clobbers)
   21893              : {
   21894              :   /* The general rule is that fixed registers should be marked as
   21895              :      call-clobbered.  This includes global registers, inaccessible
   21896              :      registers, the flags register, and the FPSR.
   21897              : 
   21898              :      Handle the exceptions below.  */
   21899          762 :   full_reg_clobbers |= fixed_reg_set;
   21900              : 
   21901              :   /* Every ABI (even preserve_none) preserves EBP/RBP.  */
   21902          762 :   CLEAR_HARD_REG_BIT (full_reg_clobbers, HARD_FRAME_POINTER_REGNUM);
   21903              : 
   21904              :   /* Treat GCC's internal frame-related registers as call-preserved.  */
   21905          762 :   CLEAR_HARD_REG_BIT (full_reg_clobbers, FRAME_POINTER_REGNUM);
   21906          762 :   CLEAR_HARD_REG_BIT (full_reg_clobbers, ARG_POINTER_REGNUM);
   21907              : 
   21908              :   /* MMX registers aren't preserved.  */
   21909          762 :   if (TARGET_MMX)
   21910          762 :     full_reg_clobbers |= reg_class_contents[MMX_REGS];
   21911              : 
   21912              :   /* X87 registers aren't preserved.  */
   21913          762 :   if (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)
   21914          762 :     full_reg_clobbers |= reg_class_contents[FLOAT_REGS];
   21915              : 
   21916          762 :   function_abis[abi_id].initialize (abi_id, full_reg_clobbers);
   21917          762 : }
   21918              : 
   21919              : /* Return the descriptor of no_callee_saved_registers function type.
   21920              :    None of the enabled registers are preserved, except for the common
   21921              :    rules applied by ix86_initialize_abi.  */
   21922              : 
   21923              : static const predefined_function_abi &
   21924         3088 : ix86_no_callee_saved_abi (void)
   21925              : {
   21926         3088 :   auto &no_callee_saved_abi = function_abis[ABI_NO_CALLEE_SAVED];
   21927         3088 :   if (!no_callee_saved_abi.initialized_p ())
   21928           98 :     ix86_initialize_abi (ABI_NO_CALLEE_SAVED, accessible_reg_set);
   21929         3088 :   return no_callee_saved_abi;
   21930              : }
   21931              : 
   21932              : /* Return the descriptor of the no_caller_saved_registers function type
   21933              :    with ABI identifier ABI_ID.  All registers are preserved, except for:
   21934              : 
   21935              :    - the return registers, which are enumerated in ABI_ID.
   21936              : 
   21937              :    - the common rules applied by ix86_initialize_abi.  */
   21938              : 
   21939              : static const predefined_function_abi &
   21940         3705 : ix86_no_caller_saved_abi (unsigned int abi_id)
   21941              : {
   21942         3705 :   auto &abi = function_abis[abi_id];
   21943         3705 :   if (!abi.initialized_p ())
   21944              :     {
   21945          172 :       HARD_REG_SET full_reg_clobbers = {};
   21946              : 
   21947          172 :       switch (abi_id)
   21948              :         {
   21949              :         case ABI_NO_CALLER_SAVED_RETURN_VOID:
   21950              :           break;
   21951              : 
   21952            1 :         case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
   21953            1 :           SET_HARD_REG_BIT (full_reg_clobbers, DX_REG);
   21954              :           /* Fall through.  */
   21955            9 :         case ABI_NO_CALLER_SAVED_RETURN_AX:
   21956            9 :           SET_HARD_REG_BIT (full_reg_clobbers, AX_REG);
   21957            9 :           break;
   21958              : 
   21959            2 :         case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
   21960            2 :           SET_HARD_REG_BIT (full_reg_clobbers, AX_REG);
   21961            2 :           SET_HARD_REG_BIT (full_reg_clobbers, XMM0_REG);
   21962            2 :           break;
   21963              : 
   21964            1 :         case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
   21965            1 :           SET_HARD_REG_BIT (full_reg_clobbers, XMM1_REG);
   21966              :           /* Fall through.  */
   21967            2 :         case ABI_NO_CALLER_SAVED_RETURN_XMM0:
   21968            2 :           SET_HARD_REG_BIT (full_reg_clobbers, XMM0_REG);
   21969            2 :           break;
   21970              : 
   21971            0 :         default:
   21972            0 :           gcc_unreachable ();
   21973              :         }
   21974              : 
   21975          172 :       ix86_initialize_abi (abi_id, full_reg_clobbers);
   21976              :     }
   21977         3705 :   return abi;
   21978              : }
   21979              : 
   21980              : /* Return the descriptor of the standard function ABI type.  If
   21981              :    ABI_TYPE == ABI_ALTERNATE, return the function alternate ABI type.  */
   21982              : 
   21983              : static const predefined_function_abi &
   21984      1597203 : ix86_standard_abi (int abi_type)
   21985              : {
   21986      1597203 :   static const char ix86_call_used_regs[] = CALL_USED_REGISTERS;
   21987      1597203 :   auto &standard_abi = function_abis[abi_type];
   21988      1597203 :   if (!standard_abi.initialized_p ())
   21989              :     {
   21990          492 :       HARD_REG_SET full_reg_clobbers = {};
   21991              : 
   21992              :       /* Add all registers that are clobbered by the call.  NB: If the
   21993              :          current ABI is SYSV_ABI, the alternate ABI is MS_ABI.   */
   21994         1007 :       bool is_64bit_ms_abi = (TARGET_64BIT
   21995          492 :                               && ix86_abi == (abi_type == ABI_ALTERNATE
   21996          492 :                                               ? SYSV_ABI : MS_ABI));
   21997           23 :       char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi);
   21998        45756 :       for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   21999        45264 :         if (ix86_call_used_regs[i] == 1
   22000         8856 :             || (ix86_call_used_regs[i] & c_mask))
   22001        36684 :           SET_HARD_REG_BIT (full_reg_clobbers, i);
   22002              : 
   22003          492 :       ix86_initialize_abi (abi_type, full_reg_clobbers);
   22004              :     }
   22005      1597203 :   return standard_abi;
   22006              : }
   22007              : 
   22008              : /* Return the descriptor of the function alternate ABI type.  */
   22009              : 
   22010              : static const predefined_function_abi &
   22011      1597203 : ix86_alternate_abi (void)
   22012              : {
   22013           12 :   return ix86_standard_abi (ABI_ALTERNATE);
   22014              : }
   22015              : 
   22016              : /* Return the function ABI ID based on FNTYPE.  */
   22017              : 
   22018              : static int
   22019    410293238 : ix86_function_abi_id (const_tree fntype)
   22020              : {
   22021    410293238 :   auto call_saved_registers = ix86_fntype_call_saved_registers (fntype);
   22022    410293238 :   if (call_saved_registers == TYPE_PRESERVE_NONE
   22023    410293238 :       || call_saved_registers == TYPE_NO_CALLEE_SAVED_REGISTERS)
   22024              :     return ABI_NO_CALLEE_SAVED;
   22025              : 
   22026    410290150 :   if (call_saved_registers == TYPE_NO_CALLER_SAVED_REGISTERS)
   22027              :     {
   22028         3705 :       tree type = TREE_TYPE (fntype);
   22029         3705 :       if (VOID_TYPE_P (type))
   22030              :         return ABI_NO_CALLER_SAVED_RETURN_VOID;
   22031              :       /* AX register contains the address of the return value location
   22032              :          passed in by the caller.  */
   22033         2256 :       else if (ix86_return_in_memory (type, fntype))
   22034              :         return ABI_NO_CALLER_SAVED_RETURN_AX;
   22035         2197 :       rtx ret = ix86_function_value (type, fntype, false);
   22036         2197 :       unsigned int nregs;
   22037         2197 :       if (REG_P (ret))
   22038              :         {
   22039         2016 :           unsigned int regno = REGNO (ret);
   22040         2016 :           if (STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
   22041              :             return ABI_NO_CALLER_SAVED_RETURN_VOID;
   22042              :           else
   22043         2016 :             switch (regno)
   22044              :               {
   22045         1947 :               case AX_REG:
   22046         1947 :                 nregs = REG_NREGS (ret);
   22047         1947 :                 if (nregs == 1)
   22048              :                   return ABI_NO_CALLER_SAVED_RETURN_AX;
   22049           71 :                 else if (nregs == 2)
   22050              :                   return ABI_NO_CALLER_SAVED_RETURN_AX_DX;
   22051            0 :                 gcc_unreachable ();
   22052              :               case XMM0_REG:
   22053              :                 return ABI_NO_CALLER_SAVED_RETURN_XMM0;
   22054            0 :               default:
   22055            0 :                 gcc_unreachable ();
   22056              :               }
   22057              :         }
   22058          181 :       else if (GET_CODE (ret) == PARALLEL && XVECLEN (ret, 0) == 2)
   22059              :         {
   22060          181 :           rtx x0 = XVECEXP (ret, 0, 0);
   22061          181 :           rtx x1 = XVECEXP (ret, 0, 1);
   22062          181 :           if (GET_CODE (x0) == EXPR_LIST
   22063          181 :               && GET_CODE (x1) == EXPR_LIST)
   22064              :             {
   22065          181 :               x0 = XEXP (x0, 0);
   22066          181 :               x1 = XEXP (x1, 0);
   22067          181 :               if (REG_P (x0) && REGNO (x0) == AX_REG)
   22068              :                 {
   22069           59 :                   if (REG_P (x1) && REGNO (x1) == XMM0_REG)
   22070              :                     return ABI_NO_CALLER_SAVED_RETURN_AX_XMM0;
   22071              :                 }
   22072          122 :               if (REG_P (x0) && REGNO (x0) == XMM0_REG && REG_P (x1))
   22073              :                 {
   22074          122 :                   if (REGNO (x1) == AX_REG)
   22075              :                     return ABI_NO_CALLER_SAVED_RETURN_AX_XMM0;
   22076           64 :                   else if (REGNO (x1) == XMM1_REG)
   22077              :                     return ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1;
   22078              :                 }
   22079              :             }
   22080              : 
   22081            0 :           gcc_unreachable ();
   22082              :         }
   22083              :     }
   22084              : 
   22085              :   /* NB: This must be the last since other attributes change the
   22086              :      function ABI.  */
   22087    410286445 :   if (ix86_function_type_abi (fntype) != ix86_abi)
   22088      1597191 :     return ABI_ALTERNATE;
   22089              : 
   22090              :   return ABI_DEFAULT;
   22091              : }
   22092              : 
   22093              : /* Implement TARGET_FNTYPE_ABI.  */
   22094              : 
   22095              : static const predefined_function_abi &
   22096    410293238 : ix86_fntype_abi (const_tree fntype)
   22097              : {
   22098    410293238 :   unsigned int abi_id = ix86_function_abi_id (fntype);
   22099    410293238 :   switch (abi_id)
   22100              :     {
   22101    408689254 :     case ABI_DEFAULT:
   22102    408689254 :       return default_function_abi;
   22103              : 
   22104      1597191 :     case ABI_ALTERNATE:
   22105      1597191 :       return ix86_alternate_abi ();
   22106              : 
   22107         3088 :     case ABI_NO_CALLEE_SAVED:
   22108         3088 :       return ix86_no_callee_saved_abi ();
   22109              : 
   22110         3705 :     case ABI_NO_CALLER_SAVED_RETURN_VOID:
   22111         3705 :     case ABI_NO_CALLER_SAVED_RETURN_AX:
   22112         3705 :     case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
   22113         3705 :     case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
   22114         3705 :     case ABI_NO_CALLER_SAVED_RETURN_XMM0:
   22115         3705 :     case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
   22116         3705 :       return ix86_no_caller_saved_abi (abi_id);
   22117              : 
   22118            0 :     default:
   22119            0 :       gcc_unreachable ();
   22120              :     }
   22121              : 
   22122              :   return default_function_abi;
   22123              : }
   22124              : 
   22125              : /* Initialize function_abis with corresponding abi_id,
   22126              :    currently only handle vzeroupper.  */
   22127              : void
   22128        22304 : ix86_initialize_callee_abi (unsigned int abi_id)
   22129              : {
   22130        22304 :   gcc_assert (abi_id == ABI_VZEROUPPER);
   22131        22304 :   predefined_function_abi &vzeroupper_abi = function_abis[abi_id];
   22132        22304 :   if (!vzeroupper_abi.initialized_p ())
   22133              :     {
   22134              :       HARD_REG_SET full_reg_clobbers;
   22135         4317 :       CLEAR_HARD_REG_SET (full_reg_clobbers);
   22136         4317 :       vzeroupper_abi.initialize (ABI_VZEROUPPER, full_reg_clobbers);
   22137              :     }
   22138        22304 : }
   22139              : 
   22140              : void
   22141        22304 : ix86_expand_avx_vzeroupper (void)
   22142              : {
   22143              :   /* Initialize vzeroupper_abi here.  */
   22144        22304 :   ix86_initialize_callee_abi (ABI_VZEROUPPER);
   22145        22304 :   rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
   22146        22304 :   CALL_INSN_ABI_ID (insn) = ABI_VZEROUPPER;
   22147              :   /* Return false for non-local goto in can_nonlocal_goto.  */
   22148        22304 :   make_reg_eh_region_note (insn, 0, INT_MIN);
   22149              :   /* Flag used for call_insn indicates it's a fake call.  */
   22150        22304 :   RTX_FLAG (insn, used) = 1;
   22151        22304 : }
   22152              : 
   22153              : 
   22154              : /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  The only ABI that
   22155              :    saves SSE registers across calls is Win64 (thus no need to check the
   22156              :    current ABI here), and with AVX enabled Win64 only guarantees that
   22157              :    the low 16 bytes are saved.  */
   22158              : 
   22159              : static bool
   22160   1903337341 : ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
   22161              :                                      machine_mode mode)
   22162              : {
   22163   1903337341 :   switch (abi_id)
   22164              :     {
   22165     31230681 :     case ABI_VZEROUPPER:
   22166              :       /* Special ABI for vzeroupper which only clobbers higher part of
   22167              :          SSE registers.  */
   22168     31230681 :       return (GET_MODE_SIZE (mode) > 16
   22169     31230681 :               && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
   22170      4784802 :                   || LEGACY_SSE_REGNO_P (regno)));
   22171              : 
   22172   1871602090 :     case ABI_DEFAULT:
   22173   1871602090 :     case ABI_ALTERNATE:
   22174   1871602090 :     case ABI_NO_CALLEE_SAVED:
   22175   1871602090 :       break;
   22176              : 
   22177              :     case ABI_NO_CALLER_SAVED_RETURN_VOID:
   22178              :     case ABI_NO_CALLER_SAVED_RETURN_AX:
   22179              :     case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
   22180              :       /* These ABIs don't clobber SSE registers.  */
   22181              :       return false;
   22182              : 
   22183              :     case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
   22184              :     case ABI_NO_CALLER_SAVED_RETURN_XMM0:
   22185              :     case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
   22186              :       /* These ABIs return some values in SSE registers and preserve
   22187              :          the rest.  The return value registers (XMM0 and possibly XMM1)
   22188              :          are fully rather than partially call-clobbered.  */
   22189              :       return false;
   22190              : 
   22191            0 :     default:
   22192            0 :       gcc_unreachable ();
   22193              :     }
   22194              : 
   22195   2462278610 :   return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
   22196              : }
   22197              : 
   22198              : /* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a
   22199              :    tieable integer mode.  */
   22200              : 
   22201              : static bool
   22202     53952716 : ix86_tieable_integer_mode_p (machine_mode mode)
   22203              : {
   22204     53952716 :   switch (mode)
   22205              :     {
   22206              :     case E_HImode:
   22207              :     case E_SImode:
   22208              :       return true;
   22209              : 
   22210      5374939 :     case E_QImode:
   22211      5374939 :       return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
   22212              : 
   22213     10713224 :     case E_DImode:
   22214     10713224 :       return TARGET_64BIT;
   22215              : 
   22216              :     default:
   22217              :       return false;
   22218              :     }
   22219              : }
   22220              : 
   22221              : /* Implement TARGET_MODES_TIEABLE_P.
   22222              : 
   22223              :    Return true if MODE1 is accessible in a register that can hold MODE2
   22224              :    without copying.  That is, all register classes that can hold MODE2
   22225              :    can also hold MODE1.  */
   22226              : 
   22227              : static bool
   22228     34840210 : ix86_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   22229              : {
   22230     34840210 :   if (mode1 == mode2)
   22231              :     return true;
   22232              : 
   22233     34752847 :   if (ix86_tieable_integer_mode_p (mode1)
   22234     34752847 :       && ix86_tieable_integer_mode_p (mode2))
   22235              :     return true;
   22236              : 
   22237              :   /* MODE2 being XFmode implies fp stack or general regs, which means we
   22238              :      can tie any smaller floating point modes to it.  Note that we do not
   22239              :      tie this with TFmode.  */
   22240     25360455 :   if (mode2 == XFmode)
   22241         4314 :     return mode1 == SFmode || mode1 == DFmode;
   22242              : 
   22243              :   /* MODE2 being DFmode implies fp stack, general or sse regs, which means
   22244              :      that we can tie it with SFmode.  */
   22245     25356141 :   if (mode2 == DFmode)
   22246       250259 :     return mode1 == SFmode;
   22247              : 
   22248              :   /* If MODE2 is only appropriate for an SSE register, then tie with
   22249              :      any vector modes or scalar floating point modes acceptable to SSE
   22250              :      registers, excluding scalar integer modes with SUBREG:
   22251              :         (subreg:QI (reg:TI 99) 0))
   22252              :         (subreg:HI (reg:TI 99) 0))
   22253              :         (subreg:SI (reg:TI 99) 0))
   22254              :         (subreg:DI (reg:TI 99) 0))
   22255              :      to avoid unnecessary move from SSE register to integer register.
   22256              :    */
   22257     25105882 :   if (GET_MODE_SIZE (mode2) >= 16
   22258     38987410 :       && (GET_MODE_SIZE (mode1) == GET_MODE_SIZE (mode2)
   22259     13701493 :           || ((VECTOR_MODE_P (mode1) || SCALAR_FLOAT_MODE_P (mode1))
   22260       512530 :               && GET_MODE_SIZE (mode1) <= GET_MODE_SIZE (mode2)))
   22261     31153269 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   22262      5607284 :     return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1);
   22263              : 
   22264              :   /* If MODE2 is appropriate for an MMX register, then tie
   22265              :      with any other mode acceptable to MMX registers.  */
   22266     19498598 :   if (GET_MODE_SIZE (mode2) == 8
   22267     19498598 :       && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
   22268      3327403 :     return (GET_MODE_SIZE (mode1) == 8
   22269      3327403 :             && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
   22270              : 
   22271              :   /* SCmode and DImode can be tied.  */
   22272     16171195 :   if ((mode1 == E_SCmode && mode2 == E_DImode)
   22273     16171195 :       || (mode1 == E_DImode && mode2 == E_SCmode))
   22274          108 :     return TARGET_64BIT;
   22275              : 
   22276              :   /* [SD]Cmode and V2[SD]Fmode modes can be tied.  */
   22277     16171087 :   if ((mode1 == E_SCmode && mode2 == E_V2SFmode)
   22278     16171087 :       || (mode1 == E_V2SFmode && mode2 == E_SCmode)
   22279     16171087 :       || (mode1 == E_DCmode && mode2 == E_V2DFmode)
   22280     16171087 :       || (mode1 == E_V2DFmode && mode2 == E_DCmode))
   22281            0 :     return true;
   22282              : 
   22283              :   return false;
   22284              : }
   22285              : 
   22286              : /* Return the cost of moving between two registers of mode MODE.  */
   22287              : 
   22288              : static int
   22289     29690254 : ix86_set_reg_reg_cost (machine_mode mode)
   22290              : {
   22291     29690254 :   unsigned int units = UNITS_PER_WORD;
   22292              : 
   22293     29690254 :   switch (GET_MODE_CLASS (mode))
   22294              :     {
   22295              :     default:
   22296              :       break;
   22297              : 
   22298              :     case MODE_CC:
   22299     29690254 :       units = GET_MODE_SIZE (CCmode);
   22300              :       break;
   22301              : 
   22302      1166133 :     case MODE_FLOAT:
   22303      1166133 :       if ((TARGET_SSE && mode == TFmode)
   22304       675566 :           || (TARGET_80387 && mode == XFmode)
   22305       213010 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
   22306       143734 :           || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
   22307      2300734 :         units = GET_MODE_SIZE (mode);
   22308              :       break;
   22309              : 
   22310      1326216 :     case MODE_COMPLEX_FLOAT:
   22311      1326216 :       if ((TARGET_SSE && mode == TCmode)
   22312       889090 :           || (TARGET_80387 && mode == XCmode)
   22313       451842 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
   22314        14560 :           || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
   22315      2645884 :         units = GET_MODE_SIZE (mode);
   22316              :       break;
   22317              : 
   22318     18979377 :     case MODE_VECTOR_INT:
   22319     18979377 :     case MODE_VECTOR_FLOAT:
   22320     18979377 :       if ((TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
   22321     18883667 :           || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   22322     18712247 :           || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   22323     16045611 :           || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   22324     14720980 :           || ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   22325     14675212 :               && VALID_MMX_REG_MODE (mode)))
   22326      8624688 :         units = GET_MODE_SIZE (mode);
   22327              :     }
   22328              : 
   22329              :   /* Return the cost of moving between two registers of mode MODE,
   22330              :      assuming that the move will be in pieces of at most UNITS bytes.  */
   22331     29690254 :   return COSTS_N_INSNS (CEIL (GET_MODE_SIZE (mode), units));
   22332              : }
   22333              : 
   22334              : /* Return cost of vector operation in MODE given that scalar version has
   22335              :    COST.  */
   22336              : 
   22337              : static int
   22338   2873411586 : ix86_vec_cost (machine_mode mode, int cost)
   22339              : {
   22340   2873411586 :   if (!VECTOR_MODE_P (mode))
   22341              :     return cost;
   22342              : 
   22343   2873171211 :   if (GET_MODE_BITSIZE (mode) == 128
   22344   2873171211 :       && TARGET_SSE_SPLIT_REGS)
   22345      2862350 :     return cost * GET_MODE_BITSIZE (mode) / 64;
   22346   2871740036 :   else if (GET_MODE_BITSIZE (mode) > 128
   22347   2871740036 :       && TARGET_AVX256_SPLIT_REGS)
   22348      1674608 :     return cost * GET_MODE_BITSIZE (mode) / 128;
   22349   2870902732 :   else if (GET_MODE_BITSIZE (mode) > 256
   22350   2870902732 :       && TARGET_AVX512_SPLIT_REGS)
   22351       305596 :     return cost * GET_MODE_BITSIZE (mode) / 256;
   22352              :   return cost;
   22353              : }
   22354              : 
   22355              : /* Return cost of vec_widen_<s>mult_hi/lo_<mode>,
   22356              :    vec_widen_<s>mul_hi/lo_<mode> is only available for VI124_AVX2.  */
   22357              : static int
   22358         1221 : ix86_widen_mult_cost (const struct processor_costs *cost,
   22359              :                       enum machine_mode mode, bool uns_p)
   22360              : {
   22361         1221 :   gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
   22362         1221 :   int extra_cost = 0;
   22363         1221 :   int basic_cost = 0;
   22364         1221 :   switch (mode)
   22365              :     {
   22366          130 :     case V8HImode:
   22367          130 :     case V16HImode:
   22368          130 :       if (!uns_p || mode == V16HImode)
   22369           55 :         extra_cost = cost->sse_op * 2;
   22370          130 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   22371          130 :       break;
   22372          219 :     case V4SImode:
   22373          219 :     case V8SImode:
   22374              :       /* pmulhw/pmullw can be used.  */
   22375          219 :       basic_cost = cost->mulss * 2 + cost->sse_op * 2;
   22376          219 :       break;
   22377          804 :     case V2DImode:
   22378              :       /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
   22379              :          require extra 4 mul, 4 add, 4 cmp and 2 shift.  */
   22380          804 :       if (!TARGET_SSE4_1 && !uns_p)
   22381          488 :         extra_cost = (cost->mulss + cost->sse_op + cost->sse_op) * 4
   22382          488 :                       + cost->sse_op * 2;
   22383              :       /* Fallthru.  */
   22384          860 :     case V4DImode:
   22385          860 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   22386          860 :       break;
   22387              :     default:
   22388              :       /* Not implemented.  */
   22389              :       return 100;
   22390              :     }
   22391         1209 :   return ix86_vec_cost (mode, basic_cost + extra_cost);
   22392              : }
   22393              : 
   22394              : /* Return cost of multiplication in MODE.  */
   22395              : 
   22396              : static int
   22397   1226179246 : ix86_multiplication_cost (const struct processor_costs *cost,
   22398              :                           enum machine_mode mode)
   22399              : {
   22400   1226179246 :   machine_mode inner_mode = mode;
   22401   1226179246 :   if (VECTOR_MODE_P (mode))
   22402   1225145607 :     inner_mode = GET_MODE_INNER (mode);
   22403              : 
   22404   1226179246 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22405       755145 :     return inner_mode == DFmode ? cost->mulsd : cost->mulss;
   22406   1225424101 :   else if (X87_FLOAT_MODE_P (mode))
   22407       166485 :     return cost->fmul;
   22408   1225257616 :   else if (FLOAT_MODE_P (mode))
   22409       241756 :     return  ix86_vec_cost (mode,
   22410       241756 :                            inner_mode == DFmode ? cost->mulsd : cost->mulss);
   22411   1225015860 :   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22412              :     {
   22413   1224928025 :       int nmults, nops;
   22414              :       /* Cost of reading the memory.  */
   22415   1224928025 :       int extra;
   22416              : 
   22417   1224928025 :       switch (mode)
   22418              :         {
   22419     19289754 :         case V4QImode:
   22420     19289754 :         case V8QImode:
   22421              :           /* Partial V*QImode is emulated with 4-6 insns.  */
   22422     19289754 :           nmults = 1;
   22423     19289754 :           nops = 3;
   22424     19289754 :           extra = 0;
   22425              : 
   22426     19289754 :           if (TARGET_AVX512BW && TARGET_AVX512VL)
   22427              :             ;
   22428     19176928 :           else if (TARGET_AVX2)
   22429              :             nops += 2;
   22430     18672836 :           else if (TARGET_XOP)
   22431        10040 :             extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22432              :           else
   22433              :             {
   22434     18662796 :               nops += 1;
   22435     18662796 :               extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22436              :             }
   22437     19289754 :           goto do_qimode;
   22438              : 
   22439      9645360 :         case V16QImode:
   22440              :           /* V*QImode is emulated with 4-11 insns.  */
   22441      9645360 :           nmults = 1;
   22442      9645360 :           nops = 3;
   22443      9645360 :           extra = 0;
   22444              : 
   22445      9645360 :           if (TARGET_AVX2 && !TARGET_PREFER_AVX128)
   22446              :             {
   22447       306247 :               if (!(TARGET_AVX512BW && TARGET_AVX512VL))
   22448       250120 :                 nops += 3;
   22449              :             }
   22450      9339113 :           else if (TARGET_XOP)
   22451              :             {
   22452         5464 :               nmults += 1;
   22453         5464 :               nops += 2;
   22454         5464 :               extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22455              :             }
   22456              :           else
   22457              :             {
   22458      9333649 :               nmults += 1;
   22459      9333649 :               nops += 4;
   22460      9333649 :               extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22461              :             }
   22462      9645360 :           goto do_qimode;
   22463              : 
   22464      9643732 :         case V32QImode:
   22465      9643732 :           nmults = 1;
   22466      9643732 :           nops = 3;
   22467      9643732 :           extra = 0;
   22468              : 
   22469      9643732 :           if (!TARGET_AVX512BW || TARGET_PREFER_AVX256)
   22470              :             {
   22471      9560208 :               nmults += 1;
   22472      9560208 :               nops += 4;
   22473              :               /* 2 loads, so no division by 2.  */
   22474      9560208 :               extra += COSTS_N_INSNS (cost->sse_load[3]);
   22475              :             }
   22476      9643732 :           goto do_qimode;
   22477              : 
   22478      9643253 :         case V64QImode:
   22479      9643253 :           nmults = 2;
   22480      9643253 :           nops = 9;
   22481              :           /* 2 loads of each size, so no division by 2.  */
   22482      9643253 :           extra = COSTS_N_INSNS (cost->sse_load[3] + cost->sse_load[4]);
   22483              : 
   22484     48222099 :         do_qimode:
   22485     48222099 :           return ix86_vec_cost (mode, cost->mulss * nmults
   22486     48222099 :                                 + cost->sse_op * nops) + extra;
   22487              : 
   22488     41241292 :         case V4SImode:
   22489              :           /* pmulld is used in this case. No emulation is needed.  */
   22490     41241292 :           if (TARGET_SSE4_1)
   22491      2242404 :             goto do_native;
   22492              :           /* V4SImode is emulated with 7 insns.  */
   22493              :           else
   22494     38998888 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 5);
   22495              : 
   22496    166693886 :         case V2DImode:
   22497    166693886 :         case V4DImode:
   22498              :           /* vpmullq is used in this case. No emulation is needed.  */
   22499    166693886 :           if (TARGET_AVX512DQ && TARGET_AVX512VL)
   22500       628707 :             goto do_native;
   22501              :           /* V*DImode is emulated with 6-8 insns.  */
   22502    166065179 :           else if (TARGET_XOP && mode == V2DImode)
   22503        55100 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 4);
   22504              :           /* FALLTHRU */
   22505    249293653 :         case V8DImode:
   22506              :           /* vpmullq is used in this case. No emulation is needed.  */
   22507    249293653 :           if (TARGET_AVX512DQ && mode == V8DImode)
   22508       405930 :             goto do_native;
   22509              :           else
   22510    248887723 :             return ix86_vec_cost (mode, cost->mulss * 3 + cost->sse_op * 5);
   22511              : 
   22512    888764215 :         default:
   22513    888764215 :         do_native:
   22514    888764215 :           return ix86_vec_cost (mode, cost->mulss);
   22515              :         }
   22516              :     }
   22517              :   else
   22518       175662 :     return (cost->mult_init[MODE_INDEX (mode)] + cost->mult_bit * 7);
   22519              : }
   22520              : 
   22521              : /* Return cost of multiplication in MODE.  */
   22522              : 
   22523              : static int
   22524     74209814 : ix86_division_cost (const struct processor_costs *cost,
   22525              :                           enum machine_mode mode)
   22526              : {
   22527     74209814 :   machine_mode inner_mode = mode;
   22528     74209814 :   if (VECTOR_MODE_P (mode))
   22529     54371057 :     inner_mode = GET_MODE_INNER (mode);
   22530              : 
   22531     74209814 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22532       242794 :     return inner_mode == DFmode ? cost->divsd : cost->divss;
   22533     73967020 :   else if (X87_FLOAT_MODE_P (mode))
   22534        46719 :     return cost->fdiv;
   22535     73920301 :   else if (FLOAT_MODE_P (mode))
   22536        22226 :     return ix86_vec_cost (mode,
   22537        22226 :                           inner_mode == DFmode ? cost->divsd : cost->divss);
   22538              :   else
   22539     82926004 :     return cost->divide[MODE_INDEX (mode)];
   22540              : }
   22541              : 
   22542              : /* Return cost of shift in MODE.
   22543              :    If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
   22544              :    AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE
   22545              :    if op1 is a result of subreg.
   22546              : 
   22547              :    SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored.  */
   22548              : 
   22549              : static int
   22550    787382654 : ix86_shift_rotate_cost (const struct processor_costs *cost,
   22551              :                         enum rtx_code code,
   22552              :                         enum machine_mode mode, bool constant_op1,
   22553              :                         HOST_WIDE_INT op1_val,
   22554              :                         bool and_in_op1,
   22555              :                         bool shift_and_truncate,
   22556              :                         bool *skip_op0, bool *skip_op1)
   22557              : {
   22558    787382654 :   if (skip_op0)
   22559    787295944 :     *skip_op0 = *skip_op1 = false;
   22560              : 
   22561    787382654 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22562              :     {
   22563    404360045 :       int count;
   22564              :       /* Cost of reading the memory.  */
   22565    404360045 :       int extra;
   22566              : 
   22567    404360045 :       switch (mode)
   22568              :         {
   22569      6137657 :         case V4QImode:
   22570      6137657 :         case V8QImode:
   22571      6137657 :           if (TARGET_AVX2)
   22572              :             /* Use vpbroadcast.  */
   22573       196355 :             extra = cost->sse_op;
   22574              :           else
   22575      5941302 :             extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22576              : 
   22577      6137657 :           if (constant_op1)
   22578              :             {
   22579      6137627 :               if (code == ASHIFTRT)
   22580              :                 {
   22581          190 :                   count = 4;
   22582          190 :                   extra *= 2;
   22583              :                 }
   22584              :               else
   22585              :                 count = 2;
   22586              :             }
   22587           30 :           else if (TARGET_AVX512BW && TARGET_AVX512VL)
   22588           30 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   22589            0 :           else if (TARGET_SSE4_1)
   22590              :             count = 5;
   22591            0 :           else if (code == ASHIFTRT)
   22592              :             count = 6;
   22593              :           else
   22594            0 :             count = 5;
   22595      6137627 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   22596              : 
   22597      3072004 :         case V16QImode:
   22598      3072004 :           if (TARGET_XOP)
   22599              :             {
   22600              :               /* For XOP we use vpshab, which requires a broadcast of the
   22601              :                  value to the variable shift insn.  For constants this
   22602              :                  means a V16Q const in mem; even when we can perform the
   22603              :                  shift with one insn set the cost to prefer paddb.  */
   22604         3573 :               if (constant_op1)
   22605              :                 {
   22606         2614 :                   extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22607         2614 :                   return ix86_vec_cost (mode, cost->sse_op) + extra;
   22608              :                 }
   22609              :               else
   22610              :                 {
   22611          959 :                   count = (code == ASHIFT) ? 3 : 4;
   22612          959 :                   return ix86_vec_cost (mode, cost->sse_op * count);
   22613              :                 }
   22614              :             }
   22615              :           /* FALLTHRU */
   22616      6136954 :         case V32QImode:
   22617      6136954 :           if (TARGET_GFNI && constant_op1)
   22618              :             {
   22619              :               /* Use vgf2p8affine.  One extra load for the mask, but in a loop
   22620              :                  with enough registers it will be moved out.  So for now don't
   22621              :                  account the constant mask load.  This is not quite right
   22622              :                  for non loop vectorization.  */
   22623        12074 :               extra = 0;
   22624        12074 :               return ix86_vec_cost (mode, cost->sse_op) + extra;
   22625              :             }
   22626      6124880 :           if (TARGET_AVX2)
   22627              :             /* Use vpbroadcast.  */
   22628       189078 :             extra = cost->sse_op;
   22629              :           else
   22630      5935802 :             extra = COSTS_N_INSNS (mode == V16QImode
   22631              :                                    ? cost->sse_load[2]
   22632      5935802 :                                    : cost->sse_load[3]) / 2;
   22633              : 
   22634      6124880 :           if (constant_op1)
   22635              :             {
   22636      6124656 :               if (code == ASHIFTRT)
   22637              :                 {
   22638          269 :                   count = 4;
   22639          269 :                   extra *= 2;
   22640              :                 }
   22641              :               else
   22642              :                 count = 2;
   22643              :             }
   22644          224 :           else if (TARGET_AVX512BW
   22645           76 :                    && ((mode == V32QImode && !TARGET_PREFER_AVX256)
   22646           38 :                        || (mode == V16QImode && TARGET_AVX512VL
   22647           38 :                            && !TARGET_PREFER_AVX128)))
   22648           76 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   22649          148 :           else if (TARGET_AVX2
   22650            0 :                    && mode == V16QImode && !TARGET_PREFER_AVX128)
   22651              :             count = 6;
   22652          148 :           else if (TARGET_SSE4_1)
   22653              :             count = 9;
   22654          148 :           else if (code == ASHIFTRT)
   22655              :             count = 10;
   22656              :           else
   22657           76 :             count = 9;
   22658      6124804 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   22659              : 
   22660      3068772 :         case V64QImode:
   22661              :           /* Ignore the mask load for GF2P8AFFINEQB.  */
   22662      3068772 :           extra = 0;
   22663      3068772 :           return ix86_vec_cost (mode, cost->sse_op) + extra;
   22664              : 
   22665     55322234 :         case V2DImode:
   22666     55322234 :         case V4DImode:
   22667              :           /* V*DImode arithmetic right shift is emulated.  */
   22668     55322234 :           if (code == ASHIFTRT && !TARGET_AVX512VL)
   22669              :             {
   22670         1532 :               if (constant_op1)
   22671              :                 {
   22672          771 :                   if (op1_val == 63)
   22673          500 :                     count = TARGET_SSE4_2 ? 1 : 2;
   22674          570 :                   else if (TARGET_XOP)
   22675              :                     count = 2;
   22676          271 :                   else if (TARGET_SSE4_1)
   22677              :                     count = 3;
   22678              :                   else
   22679          291 :                     count = 4;
   22680              :                 }
   22681          761 :               else if (TARGET_XOP)
   22682              :                 count = 3;
   22683           96 :               else if (TARGET_SSE4_2)
   22684              :                 count = 4;
   22685              :               else
   22686         1532 :                 count = 5;
   22687              : 
   22688         1532 :               return ix86_vec_cost (mode, cost->sse_op * count);
   22689              :             }
   22690              :           /* FALLTHRU */
   22691    389011557 :         default:
   22692    389011557 :           return ix86_vec_cost (mode, cost->sse_op);
   22693              :         }
   22694              :     }
   22695              : 
   22696    774749071 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22697              :     {
   22698    195895266 :       if (constant_op1)
   22699              :         {
   22700    195860504 :           if (op1_val > 32)
   22701    139162454 :             return cost->shift_const + COSTS_N_INSNS (2);
   22702              :           else
   22703     56698050 :             return cost->shift_const * 2;
   22704              :         }
   22705              :       else
   22706              :         {
   22707        34762 :           if (and_in_op1)
   22708           63 :             return cost->shift_var * 2;
   22709              :           else
   22710        34699 :             return cost->shift_var * 6 + COSTS_N_INSNS (2);
   22711              :         }
   22712              :     }
   22713              :   else
   22714              :     {
   22715    187127343 :       if (constant_op1)
   22716    186360639 :         return cost->shift_const;
   22717       766704 :       else if (shift_and_truncate)
   22718              :         {
   22719        23554 :           if (skip_op0)
   22720        23554 :             *skip_op0 = *skip_op1 = true;
   22721              :           /* Return the cost after shift-and truncation.  */
   22722        23554 :           return cost->shift_var;
   22723              :         }
   22724              :       else
   22725       743150 :         return cost->shift_var;
   22726              :     }
   22727              : }
   22728              : 
   22729              : static int
   22730    150960124 : ix86_insn_cost (rtx_insn *insn, bool speed)
   22731              : {
   22732    150960124 :   int insn_cost = 0;
   22733              :   /* Add extra cost to avoid post_reload late_combine revert
   22734              :      the optimization did in pass_rpad.  */
   22735    150960124 :   if (reload_completed
   22736      4585319 :       && ix86_rpad_gate ()
   22737       251500 :       && recog_memoized (insn) >= 0
   22738    151211353 :       && get_attr_avx_partial_xmm_update (insn)
   22739              :       == AVX_PARTIAL_XMM_UPDATE_TRUE)
   22740              :     insn_cost += COSTS_N_INSNS (3);
   22741              : 
   22742    150960124 :   rtx pat = PATTERN (insn);
   22743              :   /* A USE of a memory is more expensive than a use of a REG.
   22744              :      For example *<absneg>mode2_1's use of a signbit mask.  */
   22745    150960124 :   if (GET_CODE (pat) == PARALLEL)
   22746              :     {
   22747     47215490 :       for (int i = 0; i < XVECLEN (pat, 0); i++)
   22748              :         {
   22749     31716122 :           rtx x = XVECEXP (pat, 0, i);
   22750     31716122 :           if (GET_CODE (x) == USE && MEM_P (XEXP (x, 0)))
   22751        63694 :             insn_cost += !speed ? COSTS_N_BYTES (4)
   22752        29878 :                                 : TARGET_64BIT ? COSTS_N_INSNS (1) + 1
   22753              :                                                : COSTS_N_INSNS (3) + 1;
   22754              :         }
   22755              :     }
   22756              :   /* Cost *h{add,sub}<mode>[_low] directly as pattern cost for the
   22757              :      variants with outer vec_concat are artificially low.  */
   22758    150960124 :   if (INSN_CODE (insn) >= 0
   22759    150960124 :       && get_attr_cost_special (insn) == COST_SPECIAL_HADDSUB)
   22760          632 :     return insn_cost + ix86_vec_cost (GET_MODE (pat),
   22761          316 :                                       (speed ? ix86_tune_cost
   22762          316 :                                        : &ix86_size_cost)->addss);
   22763              : 
   22764    150959808 :   return insn_cost + pattern_cost (pat, speed);
   22765              : }
   22766              : 
   22767              : /* Return cost of SSE/AVX FP->FP conversion (extensions and truncates).  */
   22768              : 
   22769              : static int
   22770       765629 : vec_fp_conversion_cost (const struct processor_costs *cost, int size)
   22771              : {
   22772       765629 :   if (size < 128)
   22773       760399 :     return cost->cvtss2sd;
   22774         5230 :   else if (size < 256)
   22775              :     {
   22776         2445 :       if (TARGET_SSE_SPLIT_REGS)
   22777            0 :         return cost->cvtss2sd * size / 64;
   22778         2445 :       return cost->cvtss2sd;
   22779              :     }
   22780         2785 :   if (size < 512)
   22781         1483 :     return cost->vcvtps2pd256;
   22782              :   else
   22783         1302 :     return cost->vcvtps2pd512;
   22784              : }
   22785              : 
   22786              : /* Return true of X is UNSPEC with UNSPEC_PCMP or UNSPEC_UNSIGNED_PCMP.  */
   22787              : 
   22788              : static bool
   22789       274991 : unspec_pcmp_p (rtx x)
   22790              : {
   22791       274991 :   return GET_CODE (x) == UNSPEC
   22792       274991 :          && (XINT (x, 1) == UNSPEC_PCMP || XINT (x, 1) == UNSPEC_UNSIGNED_PCMP);
   22793              : }
   22794              : 
   22795              : /* Compute a (partial) cost for rtx X.  Return true if the complete
   22796              :    cost has been computed, and false if subexpressions should be
   22797              :    scanned.  In either case, *TOTAL contains the cost result.  */
   22798              : 
   22799              : static bool
   22800   7816587976 : ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
   22801              :                 int *total, bool speed)
   22802              : {
   22803   7816587976 :   rtx mask;
   22804   7816587976 :   enum rtx_code code = GET_CODE (x);
   22805   7816587976 :   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
   22806   4183563142 :   const struct processor_costs *cost
   22807   7816587976 :     = speed ? ix86_tune_cost : &ix86_size_cost;
   22808   7816587976 :   int src_cost;
   22809              : 
   22810              :   /* Handling different vternlog variants.  */
   22811   7816587976 :   if ((GET_MODE_SIZE (mode) == 64
   22812   7816587976 :        ? TARGET_AVX512F
   22813   6614420634 :        : (TARGET_AVX512VL
   22814   6551494870 :           || (TARGET_AVX512F && !TARGET_PREFER_AVX256)))
   22815    177900506 :       && GET_MODE_SIZE (mode) >= 16
   22816    120798714 :       && outer_code_i == SET
   22817   7863257044 :       && ternlog_operand (x, mode))
   22818              :     {
   22819        33644 :       rtx args[3];
   22820              : 
   22821        33644 :       args[0] = NULL_RTX;
   22822        33644 :       args[1] = NULL_RTX;
   22823        33644 :       args[2] = NULL_RTX;
   22824        33644 :       int idx = ix86_ternlog_idx (x, args);
   22825        33644 :       gcc_assert (idx >= 0);
   22826              : 
   22827        33644 :       *total = cost->sse_op;
   22828       134576 :       for (int i = 0; i != 3; i++)
   22829       100932 :         if (args[i])
   22830        71162 :           *total += rtx_cost (args[i], GET_MODE (args[i]), UNSPEC, i, speed);
   22831        33644 :       return true;
   22832              :     }
   22833              : 
   22834              : 
   22835   7816554332 :   switch (code)
   22836              :     {
   22837     48233762 :     case SET:
   22838     48233762 :       if (register_operand (SET_DEST (x), VOIDmode)
   22839     48233762 :           && register_operand (SET_SRC (x), VOIDmode))
   22840              :         {
   22841     29690254 :           *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
   22842     29690254 :           return true;
   22843              :         }
   22844              : 
   22845     18543508 :       if (register_operand (SET_SRC (x), VOIDmode))
   22846              :         /* Avoid potentially incorrect high cost from rtx_costs
   22847              :            for non-tieable SUBREGs.  */
   22848              :         src_cost = 0;
   22849              :       else
   22850              :         {
   22851     15724041 :           src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed);
   22852              : 
   22853     15724041 :           if (CONSTANT_P (SET_SRC (x)))
   22854              :             /* Constant costs assume a base value of COSTS_N_INSNS (1) and add
   22855              :                a small value, possibly zero for cheap constants.  */
   22856      7117765 :             src_cost += COSTS_N_INSNS (1);
   22857              :         }
   22858              : 
   22859     18543508 :       *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed);
   22860     18543508 :       return true;
   22861              : 
   22862   2878086508 :     case CONST_INT:
   22863   2878086508 :     case CONST:
   22864   2878086508 :     case LABEL_REF:
   22865   2878086508 :     case SYMBOL_REF:
   22866   2878086508 :       if (x86_64_immediate_operand (x, VOIDmode))
   22867   2263286580 :         *total = 0;
   22868    614799928 :       else if (TARGET_64BIT && x86_64_zext_immediate_operand (x, VOIDmode))
   22869              :         /* Consider the zext constants slightly more expensive, as they
   22870              :            can't appear in most instructions.  */
   22871     28464446 :         *total = 1;
   22872              :       else
   22873              :         /* movabsq is slightly more expensive than a simple instruction. */
   22874    586335482 :         *total = COSTS_N_INSNS (1) + 1;
   22875              :       return true;
   22876              : 
   22877      7612868 :     case CONST_DOUBLE:
   22878      7612868 :       if (IS_STACK_MODE (mode))
   22879      1295581 :         switch (standard_80387_constant_p (x))
   22880              :           {
   22881              :           case -1:
   22882              :           case 0:
   22883              :             break;
   22884       277231 :           case 1: /* 0.0 */
   22885       277231 :             *total = 1;
   22886       277231 :             return true;
   22887       468133 :           default: /* Other constants */
   22888       468133 :             *total = 2;
   22889       468133 :             return true;
   22890              :           }
   22891              :       /* FALLTHRU */
   22892              : 
   22893     14850013 :     case CONST_VECTOR:
   22894     14850013 :       switch (standard_sse_constant_p (x, mode))
   22895              :         {
   22896              :         case 0:
   22897              :           break;
   22898      4316784 :         case 1:  /* 0: xor eliminates false dependency */
   22899      4316784 :           *total = 0;
   22900      4316784 :           return true;
   22901       211334 :         default: /* -1: cmp contains false dependency */
   22902       211334 :           *total = 1;
   22903       211334 :           return true;
   22904              :         }
   22905              :       /* FALLTHRU */
   22906              : 
   22907     11332741 :     case CONST_WIDE_INT:
   22908              :       /* Fall back to (MEM (SYMBOL_REF)), since that's where
   22909              :          it'll probably end up.  Add a penalty for size.  */
   22910     22665482 :       *total = (COSTS_N_INSNS (1)
   22911     22437664 :                 + (!TARGET_64BIT && flag_pic)
   22912     22665482 :                 + (GET_MODE_SIZE (mode) <= 4
   22913     19859009 :                    ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
   22914     11332741 :       return true;
   22915              : 
   22916     22854985 :     case ZERO_EXTEND:
   22917              :       /* The zero extensions is often completely free on x86_64, so make
   22918              :          it as cheap as possible.  */
   22919     22854985 :       if (TARGET_64BIT && mode == DImode
   22920      4940232 :           && GET_MODE (XEXP (x, 0)) == SImode)
   22921      3009539 :         *total = 1;
   22922     19845446 :       else if (TARGET_ZERO_EXTEND_WITH_AND)
   22923            0 :         *total = cost->add;
   22924              :       else
   22925     19845446 :         *total = cost->movzx;
   22926              :       return false;
   22927              : 
   22928      2798073 :     case SIGN_EXTEND:
   22929      2798073 :       *total = cost->movsx;
   22930      2798073 :       return false;
   22931              : 
   22932    647632573 :     case ASHIFT:
   22933    647632573 :       if (SCALAR_INT_MODE_P (mode)
   22934    250238364 :           && GET_MODE_SIZE (mode) < UNITS_PER_WORD
   22935    691425896 :           && CONST_INT_P (XEXP (x, 1)))
   22936              :         {
   22937     43604779 :           HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   22938     43604779 :           if (value == 1)
   22939              :             {
   22940      2515787 :               *total = cost->add;
   22941      2515787 :               return false;
   22942              :             }
   22943     41088992 :           if ((value == 2 || value == 3)
   22944      4618388 :               && cost->lea <= cost->shift_const)
   22945              :             {
   22946      2180400 :               *total = cost->lea;
   22947      2180400 :               return false;
   22948              :             }
   22949              :         }
   22950              :       /* FALLTHRU */
   22951              : 
   22952    787295944 :     case ROTATE:
   22953    787295944 :     case ASHIFTRT:
   22954    787295944 :     case LSHIFTRT:
   22955    787295944 :     case ROTATERT:
   22956    787295944 :       bool skip_op0, skip_op1;
   22957    787295944 :       *total = ix86_shift_rotate_cost (cost, code, mode,
   22958    787295944 :                                        CONSTANT_P (XEXP (x, 1)),
   22959              :                                        CONST_INT_P (XEXP (x, 1))
   22960              :                                          ? INTVAL (XEXP (x, 1)) : -1,
   22961              :                                        GET_CODE (XEXP (x, 1)) == AND,
   22962    787295944 :                                        SUBREG_P (XEXP (x, 1))
   22963    787295944 :                                        && GET_CODE (XEXP (XEXP (x, 1),
   22964              :                                                           0)) == AND,
   22965              :                                        &skip_op0, &skip_op1);
   22966    787295944 :       if (skip_op0 || skip_op1)
   22967              :         {
   22968        23554 :           if (!skip_op0)
   22969            0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   22970        23554 :           if (!skip_op1)
   22971            0 :             *total += rtx_cost (XEXP (x, 1), mode, code, 0, speed);
   22972        23554 :           return true;
   22973              :         }
   22974              :       return false;
   22975              : 
   22976       229793 :     case FMA:
   22977       229793 :       {
   22978       229793 :         rtx sub;
   22979              : 
   22980       229793 :         gcc_assert (FLOAT_MODE_P (mode));
   22981       229793 :         gcc_assert (TARGET_FMA || TARGET_FMA4 || TARGET_AVX512F);
   22982              : 
   22983       459586 :         *total = ix86_vec_cost (mode,
   22984       229793 :                                 GET_MODE_INNER (mode) == SFmode
   22985              :                                 ? cost->fmass : cost->fmasd);
   22986       229793 :         *total += rtx_cost (XEXP (x, 1), mode, FMA, 1, speed);
   22987              : 
   22988              :         /* Negate in op0 or op2 is free: FMS, FNMA, FNMS.  */
   22989       229793 :         sub = XEXP (x, 0);
   22990       229793 :         if (GET_CODE (sub) == NEG)
   22991        51481 :           sub = XEXP (sub, 0);
   22992       229793 :         *total += rtx_cost (sub, mode, FMA, 0, speed);
   22993              : 
   22994       229793 :         sub = XEXP (x, 2);
   22995       229793 :         if (GET_CODE (sub) == NEG)
   22996        40537 :           sub = XEXP (sub, 0);
   22997       229793 :         *total += rtx_cost (sub, mode, FMA, 2, speed);
   22998       229793 :         return true;
   22999              :       }
   23000              : 
   23001   1786058958 :     case MULT:
   23002   1786058958 :       if (!FLOAT_MODE_P (mode) && !VECTOR_MODE_P (mode))
   23003              :         {
   23004    560143616 :           rtx op0 = XEXP (x, 0);
   23005    560143616 :           rtx op1 = XEXP (x, 1);
   23006    560143616 :           int nbits;
   23007    560143616 :           if (CONST_INT_P (XEXP (x, 1)))
   23008              :             {
   23009    541581165 :               unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   23010   1098976384 :               for (nbits = 0; value != 0; value &= value - 1)
   23011    557395219 :                 nbits++;
   23012              :             }
   23013              :           else
   23014              :             /* This is arbitrary.  */
   23015              :             nbits = 7;
   23016              : 
   23017              :           /* Compute costs correctly for widening multiplication.  */
   23018    560143616 :           if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
   23019    565757701 :               && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
   23020      5614085 :                  == GET_MODE_SIZE (mode))
   23021              :             {
   23022      5600624 :               int is_mulwiden = 0;
   23023      5600624 :               machine_mode inner_mode = GET_MODE (op0);
   23024              : 
   23025      5600624 :               if (GET_CODE (op0) == GET_CODE (op1))
   23026      5499808 :                 is_mulwiden = 1, op1 = XEXP (op1, 0);
   23027       100816 :               else if (CONST_INT_P (op1))
   23028              :                 {
   23029        90755 :                   if (GET_CODE (op0) == SIGN_EXTEND)
   23030        40383 :                     is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
   23031        40383 :                                   == INTVAL (op1);
   23032              :                   else
   23033        50372 :                     is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
   23034              :                 }
   23035              : 
   23036      5590563 :               if (is_mulwiden)
   23037      5590563 :                 op0 = XEXP (op0, 0), mode = GET_MODE (op0);
   23038              :             }
   23039              : 
   23040    560143616 :           int mult_init;
   23041              :           // Double word multiplication requires 3 mults and 2 adds.
   23042   1135985362 :           if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23043              :             {
   23044    337074597 :               mult_init = 3 * cost->mult_init[MODE_INDEX (word_mode)]
   23045    337074597 :                           + 2 * cost->add;
   23046    337074597 :               nbits *= 3;
   23047              :             }
   23048    384774638 :           else mult_init = cost->mult_init[MODE_INDEX (mode)];
   23049              : 
   23050   1120287232 :           *total = (mult_init
   23051    560143616 :                     + nbits * cost->mult_bit
   23052    560143616 :                     + rtx_cost (op0, mode, outer_code, opno, speed)
   23053    560143616 :                     + rtx_cost (op1, mode, outer_code, opno, speed));
   23054              : 
   23055    560143616 :           return true;
   23056              :         }
   23057   1225915342 :       *total = ix86_multiplication_cost (cost, mode);
   23058   1225915342 :       return false;
   23059              : 
   23060     74194408 :     case DIV:
   23061     74194408 :     case UDIV:
   23062     74194408 :     case MOD:
   23063     74194408 :     case UMOD:
   23064     74194408 :       *total = ix86_division_cost (cost, mode);
   23065     74194408 :       return false;
   23066              : 
   23067    698426759 :     case PLUS:
   23068    698426759 :       if (GET_MODE_CLASS (mode) == MODE_INT
   23069    956414884 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   23070              :         {
   23071    143141347 :           if (GET_CODE (XEXP (x, 0)) == PLUS
   23072      3434093 :               && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   23073       816308 :               && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
   23074       816283 :               && CONSTANT_P (XEXP (x, 1)))
   23075              :             {
   23076       816226 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
   23077       816226 :               if (val == 2 || val == 4 || val == 8)
   23078              :                 {
   23079       816122 :                   *total = cost->lea;
   23080       816122 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   23081              :                                       outer_code, opno, speed);
   23082       816122 :                   *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0), mode,
   23083              :                                       outer_code, opno, speed);
   23084       816122 :                   *total += rtx_cost (XEXP (x, 1), mode,
   23085              :                                       outer_code, opno, speed);
   23086       816122 :                   return true;
   23087              :                 }
   23088              :             }
   23089    142325121 :           else if (GET_CODE (XEXP (x, 0)) == MULT
   23090     53132569 :                    && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   23091              :             {
   23092     53068063 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
   23093     53068063 :               if (val == 2 || val == 4 || val == 8)
   23094              :                 {
   23095      8064631 :                   *total = cost->lea;
   23096      8064631 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23097              :                                       outer_code, opno, speed);
   23098      8064631 :                   *total += rtx_cost (XEXP (x, 1), mode,
   23099              :                                       outer_code, opno, speed);
   23100      8064631 :                   return true;
   23101              :                 }
   23102              :             }
   23103     89257058 :           else if (GET_CODE (XEXP (x, 0)) == PLUS)
   23104              :             {
   23105      2617867 :               rtx op = XEXP (XEXP (x, 0), 0);
   23106              : 
   23107              :               /* Add with carry, ignore the cost of adding a carry flag.  */
   23108      2617867 :               if (ix86_carry_flag_operator (op, mode)
   23109      2617867 :                   || ix86_carry_flag_unset_operator (op, mode))
   23110        69649 :                 *total = cost->add;
   23111              :               else
   23112              :                 {
   23113      2548218 :                   *total = cost->lea;
   23114      2548218 :                   *total += rtx_cost (op, mode,
   23115              :                                       outer_code, opno, speed);
   23116              :                 }
   23117              : 
   23118      2617867 :               *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   23119              :                                   outer_code, opno, speed);
   23120      2617867 :               *total += rtx_cost (XEXP (x, 1), mode,
   23121              :                                   outer_code, opno, speed);
   23122      2617867 :               return true;
   23123              :             }
   23124              :         }
   23125              :       /* FALLTHRU */
   23126              : 
   23127   1863704692 :     case MINUS:
   23128              :       /* Subtract with borrow, ignore the cost of subtracting a carry flag.  */
   23129   1863704692 :       if (GET_MODE_CLASS (mode) == MODE_INT
   23130    525849171 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
   23131    237462929 :           && GET_CODE (XEXP (x, 0)) == MINUS
   23132   1863743677 :           && (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode)
   23133        15621 :               || ix86_carry_flag_unset_operator (XEXP (XEXP (x, 0), 1), mode)))
   23134              :         {
   23135        23364 :           *total = cost->add;
   23136        23364 :           *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23137              :                               outer_code, opno, speed);
   23138        23364 :           *total += rtx_cost (XEXP (x, 1), mode,
   23139              :                               outer_code, opno, speed);
   23140        23364 :           return true;
   23141              :         }
   23142              : 
   23143   1863681328 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23144      2416367 :         *total = cost->addss;
   23145   1861264961 :       else if (X87_FLOAT_MODE_P (mode))
   23146       224315 :         *total = cost->fadd;
   23147   1861040646 :       else if (FLOAT_MODE_P (mode))
   23148       453678 :         *total = ix86_vec_cost (mode, cost->addss);
   23149   1860586968 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23150   1225730410 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23151   1309067141 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23152    336053593 :         *total = cost->add * 2;
   23153              :       else
   23154    298802965 :         *total = cost->add;
   23155              :       return false;
   23156              : 
   23157      4049996 :     case IOR:
   23158      4049996 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23159      3794955 :           || SSE_FLOAT_MODE_P (mode))
   23160              :         {
   23161              :           /* (ior (not ...) ...) can be a single insn in AVX512.  */
   23162         2935 :           if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
   23163       264861 :               && (GET_MODE_SIZE (mode) == 64
   23164            0 :                   || (TARGET_AVX512VL
   23165            0 :                       && (GET_MODE_SIZE (mode) == 32
   23166            0 :                           || GET_MODE_SIZE (mode) == 16))))
   23167              :             {
   23168            0 :               rtx right = GET_CODE (XEXP (x, 1)) != NOT
   23169            0 :                           ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
   23170              : 
   23171            0 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23172            0 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23173              :                                    outer_code, opno, speed)
   23174            0 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   23175            0 :               return true;
   23176              :             }
   23177       264861 :           *total = ix86_vec_cost (mode, cost->sse_op);
   23178       264861 :         }
   23179      3785135 :       else if (TARGET_64BIT
   23180      3491117 :                && mode == TImode
   23181      1718765 :                && GET_CODE (XEXP (x, 0)) == ASHIFT
   23182       259251 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
   23183       257252 :                && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == DImode
   23184       257252 :                && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   23185       257252 :                && INTVAL (XEXP (XEXP (x, 0), 1)) == 64
   23186       257252 :                && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
   23187       234758 :                && GET_MODE (XEXP (XEXP (x, 1), 0)) == DImode)
   23188              :         {
   23189              :           /* *concatditi3 is cheap.  */
   23190       234758 :           rtx op0 = XEXP (XEXP (XEXP (x, 0), 0), 0);
   23191       234758 :           rtx op1 = XEXP (XEXP (x, 1), 0);
   23192         1576 :           *total = (SUBREG_P (op0) && GET_MODE (SUBREG_REG (op0)) == DFmode)
   23193       234758 :                    ? COSTS_N_INSNS (1)    /* movq.  */
   23194       233182 :                    : set_src_cost (op0, DImode, speed);
   23195         2538 :           *total += (SUBREG_P (op1) && GET_MODE (SUBREG_REG (op1)) == DFmode)
   23196       234758 :                     ? COSTS_N_INSNS (1)    /* movq.  */
   23197       232233 :                     : set_src_cost (op1, DImode, speed);
   23198       234758 :           return true;
   23199              :         }
   23200      3550377 :       else if (TARGET_64BIT
   23201      3256359 :                && mode == TImode
   23202      1484007 :                && GET_CODE (XEXP (x, 0)) == AND
   23203      1423323 :                && REG_P (XEXP (XEXP (x, 0), 0))
   23204      1418026 :                && CONST_WIDE_INT_P (XEXP (XEXP (x, 0), 1))
   23205      1415283 :                && CONST_WIDE_INT_NUNITS (XEXP (XEXP (x, 0), 1)) == 2
   23206      1415283 :                && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 0) == -1
   23207       923337 :                && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 1) == 0
   23208       923337 :                && GET_CODE (XEXP (x, 1)) == ASHIFT
   23209       921088 :                && GET_CODE (XEXP (XEXP (x, 1), 0)) == ZERO_EXTEND
   23210       921088 :                && GET_MODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == DImode
   23211       921088 :                && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   23212      4471465 :                && INTVAL (XEXP (XEXP (x, 1), 1)) == 64)
   23213              :         {
   23214              :           /* *insvti_highpart is cheap.  */
   23215       921088 :           rtx op = XEXP (XEXP (XEXP (x, 1), 0), 0);
   23216       921088 :           *total = COSTS_N_INSNS (1) + 1;
   23217         1538 :           *total += (SUBREG_P (op) && GET_MODE (SUBREG_REG (op)) == DFmode)
   23218       921088 :                     ? COSTS_N_INSNS (1)    /* movq.  */
   23219       920048 :                     : set_src_cost (op, DImode, speed);
   23220       921088 :           return true;
   23221              :         }
   23222      5552596 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23223       756068 :         *total = cost->add * 2;
   23224              :       else
   23225      1873221 :         *total = cost->add;
   23226              :       return false;
   23227              : 
   23228       601254 :     case XOR:
   23229       601254 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23230       444289 :           || SSE_FLOAT_MODE_P (mode))
   23231       156965 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23232       949005 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23233        17339 :         *total = cost->add * 2;
   23234              :       else
   23235       426950 :         *total = cost->add;
   23236              :       return false;
   23237              : 
   23238      6511604 :     case AND:
   23239      6511604 :       if (address_no_seg_operand (x, mode))
   23240              :         {
   23241        13915 :           *total = cost->lea;
   23242        13915 :           return true;
   23243              :         }
   23244      6497689 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23245      6057690 :                || SSE_FLOAT_MODE_P (mode))
   23246              :         {
   23247              :           /* pandn is a single instruction.  */
   23248       473893 :           if (GET_CODE (XEXP (x, 0)) == NOT)
   23249              :             {
   23250        59972 :               rtx right = XEXP (x, 1);
   23251              : 
   23252              :               /* (and (not ...) (not ...)) can be a single insn in AVX512.  */
   23253          158 :               if (GET_CODE (right) == NOT && TARGET_AVX512F
   23254        59972 :                   && (GET_MODE_SIZE (mode) == 64
   23255            0 :                       || (TARGET_AVX512VL
   23256            0 :                           && (GET_MODE_SIZE (mode) == 32
   23257            0 :                               || GET_MODE_SIZE (mode) == 16))))
   23258            0 :                 right = XEXP (right, 0);
   23259              : 
   23260        59972 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23261        59972 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23262              :                                    outer_code, opno, speed)
   23263        59972 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   23264        59972 :               return true;
   23265              :             }
   23266       413921 :           else if (GET_CODE (XEXP (x, 1)) == NOT)
   23267              :             {
   23268         2678 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23269         2678 :                        + rtx_cost (XEXP (x, 0), mode,
   23270              :                                    outer_code, opno, speed)
   23271         2678 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   23272              :                                    outer_code, opno, speed);
   23273         2678 :               return true;
   23274              :             }
   23275       411243 :           *total = ix86_vec_cost (mode, cost->sse_op);
   23276       411243 :         }
   23277     12758483 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23278              :         {
   23279      1144500 :           if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   23280              :             {
   23281         1670 :               *total = cost->add * 2
   23282          835 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23283              :                                    outer_code, opno, speed)
   23284          835 :                        + rtx_cost (XEXP (x, 1), mode,
   23285              :                                    outer_code, opno, speed);
   23286          835 :               return true;
   23287              :             }
   23288      1143665 :           else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT)
   23289              :             {
   23290            0 :               *total = cost->add * 2
   23291            0 :                        + rtx_cost (XEXP (x, 0), mode,
   23292              :                                    outer_code, opno, speed)
   23293            0 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   23294              :                                    outer_code, opno, speed);
   23295            0 :               return true;
   23296              :             }
   23297      1143665 :           *total = cost->add * 2;
   23298              :         }
   23299      4879296 :       else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   23300              :         {
   23301         7410 :           *total = cost->add
   23302         3705 :                    + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23303              :                                outer_code, opno, speed)
   23304         3705 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23305         3705 :           return true;
   23306              :         }
   23307      4875591 :       else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT)
   23308              :         {
   23309          112 :           *total = cost->add
   23310           56 :                    + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   23311           56 :                    + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   23312              :                                outer_code, opno, speed);
   23313           56 :           return true;
   23314              :         }
   23315              :       else
   23316      4875535 :         *total = cost->add;
   23317              :       return false;
   23318              : 
   23319       547618 :     case NOT:
   23320       547618 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23321              :         {
   23322              :           /* (not (xor ...)) can be a single insn in AVX512.  */
   23323            0 :           if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
   23324        22231 :               && (GET_MODE_SIZE (mode) == 64
   23325            0 :                   || (TARGET_AVX512VL
   23326            0 :                       && (GET_MODE_SIZE (mode) == 32
   23327            0 :                           || GET_MODE_SIZE (mode) == 16))))
   23328              :             {
   23329            0 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23330            0 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23331              :                                    outer_code, opno, speed)
   23332            0 :                        + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   23333              :                                    outer_code, opno, speed);
   23334            0 :               return true;
   23335              :             }
   23336              : 
   23337              :           // vnot is pxor -1.
   23338        22231 :           *total = ix86_vec_cost (mode, cost->sse_op) + 1;
   23339              :         }
   23340      1196803 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23341        46214 :         *total = cost->add * 2;
   23342              :       else
   23343       479173 :         *total = cost->add;
   23344              :       return false;
   23345              : 
   23346     18574124 :     case NEG:
   23347     18574124 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23348        53614 :         *total = cost->sse_op;
   23349     18520510 :       else if (X87_FLOAT_MODE_P (mode))
   23350        15420 :         *total = cost->fchs;
   23351     18505090 :       else if (FLOAT_MODE_P (mode))
   23352        27424 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23353     18477666 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23354     13601367 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23355      9904649 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23356      1791190 :         *total = cost->add * 3;
   23357              :       else
   23358      3085109 :         *total = cost->add;
   23359              :       return false;
   23360              : 
   23361     54642510 :     case COMPARE:
   23362     54642510 :       rtx op0, op1;
   23363     54642510 :       op0 = XEXP (x, 0);
   23364     54642510 :       op1 = XEXP (x, 1);
   23365     54642510 :       if (GET_CODE (op0) == ZERO_EXTRACT
   23366       108312 :           && XEXP (op0, 1) == const1_rtx
   23367        92153 :           && CONST_INT_P (XEXP (op0, 2))
   23368        92117 :           && op1 == const0_rtx)
   23369              :         {
   23370              :           /* This kind of construct is implemented using test[bwl].
   23371              :              Treat it as if we had an AND.  */
   23372        92117 :           mode = GET_MODE (XEXP (op0, 0));
   23373       184234 :           *total = (cost->add
   23374        92117 :                     + rtx_cost (XEXP (op0, 0), mode, outer_code,
   23375              :                                 opno, speed)
   23376        92117 :                     + rtx_cost (const1_rtx, mode, outer_code, opno, speed));
   23377        92117 :           return true;
   23378              :         }
   23379              : 
   23380     54550393 :       if (GET_CODE (op0) == PLUS && rtx_equal_p (XEXP (op0, 0), op1))
   23381              :         {
   23382              :           /* This is an overflow detection, count it as a normal compare.  */
   23383       145087 :           *total = rtx_cost (op0, GET_MODE (op0), COMPARE, 0, speed);
   23384       145087 :           return true;
   23385              :         }
   23386              : 
   23387     54405306 :       rtx geu;
   23388              :       /* Match x
   23389              :          (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   23390              :                       (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))  */
   23391     54405306 :       if (mode == CCCmode
   23392       296822 :           && GET_CODE (op0) == NEG
   23393         8129 :           && GET_CODE (geu = XEXP (op0, 0)) == GEU
   23394         8126 :           && REG_P (XEXP (geu, 0))
   23395         8126 :           && (GET_MODE (XEXP (geu, 0)) == CCCmode
   23396          761 :               || GET_MODE (XEXP (geu, 0)) == CCmode)
   23397         8126 :           && REGNO (XEXP (geu, 0)) == FLAGS_REG
   23398         8126 :           && XEXP (geu, 1) == const0_rtx
   23399         8126 :           && GET_CODE (op1) == LTU
   23400         8126 :           && REG_P (XEXP (op1, 0))
   23401         8126 :           && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   23402         8126 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   23403     54413432 :           && XEXP (op1, 1) == const0_rtx)
   23404              :         {
   23405              :           /* This is *setcc_qi_addqi3_cconly_overflow_1_* patterns, a nop.  */
   23406         8126 :           *total = 0;
   23407         8126 :           return true;
   23408              :         }
   23409              :       /* Match x
   23410              :          (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   23411              :                       (geu:QI (reg:CCC FLAGS_REG) (const_int 0)))  */
   23412     54397180 :       if (mode == CCCmode
   23413       288696 :           && GET_CODE (op0) == NEG
   23414            3 :           && GET_CODE (XEXP (op0, 0)) == LTU
   23415            3 :           && REG_P (XEXP (XEXP (op0, 0), 0))
   23416            3 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   23417            3 :           && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
   23418            3 :           && XEXP (XEXP (op0, 0), 1) == const0_rtx
   23419            3 :           && GET_CODE (op1) == GEU
   23420            3 :           && REG_P (XEXP (op1, 0))
   23421            3 :           && GET_MODE (XEXP (op1, 0)) == CCCmode
   23422            3 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   23423     54397183 :           && XEXP (op1, 1) == const0_rtx)
   23424              :         {
   23425              :           /* This is *x86_cmc.  */
   23426            3 :           if (!speed)
   23427            0 :             *total = COSTS_N_BYTES (1);
   23428            3 :           else if (TARGET_SLOW_STC)
   23429            0 :             *total = COSTS_N_INSNS (2);
   23430              :           else
   23431            3 :             *total = COSTS_N_INSNS (1);
   23432            3 :           return true;
   23433              :         }
   23434              : 
   23435     54397177 :       if (SCALAR_INT_MODE_P (GET_MODE (op0))
   23436    113223723 :           && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
   23437              :         {
   23438       761506 :           if (op1 == const0_rtx)
   23439       219018 :             *total = cost->add
   23440       109509 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed);
   23441              :           else
   23442      1303994 :             *total = 3*cost->add
   23443       651997 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed)
   23444       651997 :                      + rtx_cost (op1, GET_MODE (op0), outer_code, opno, speed);
   23445       761506 :           return true;
   23446              :         }
   23447              : 
   23448              :       /* The embedded comparison operand is completely free.  */
   23449     53635671 :       if (!general_operand (op0, GET_MODE (op0)) && op1 == const0_rtx)
   23450       364994 :         *total = 0;
   23451              : 
   23452              :       return false;
   23453              : 
   23454      1380242 :     case FLOAT_EXTEND:
   23455              :       /* x87 represents all values extended to 80bit.  */
   23456      1380242 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23457       669776 :         *total = 0;
   23458              :       else
   23459      1420932 :         *total = vec_fp_conversion_cost (cost, GET_MODE_BITSIZE (mode));
   23460              :       return false;
   23461              : 
   23462        86024 :     case FLOAT_TRUNCATE:
   23463        86024 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23464        58189 :         *total = cost->fadd;
   23465              :       else
   23466        55670 :         *total = vec_fp_conversion_cost (cost, GET_MODE_BITSIZE (mode));
   23467              :       return false;
   23468       687654 :     case FLOAT:
   23469       687654 :     case UNSIGNED_FLOAT:
   23470       687654 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23471              :         /* TODO: We do not have cost tables for x87.  */
   23472        95262 :         *total = cost->fadd;
   23473       592392 :       else if (VECTOR_MODE_P (mode))
   23474            0 :         *total = ix86_vec_cost (mode, cost->cvtpi2ps);
   23475              :       else
   23476       592392 :         *total = cost->cvtsi2ss;
   23477              :       return false;
   23478              : 
   23479       285233 :     case FIX:
   23480       285233 :     case UNSIGNED_FIX:
   23481       285233 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23482              :         /* TODO: We do not have cost tables for x87.  */
   23483       285233 :         *total = cost->fadd;
   23484            0 :       else if (VECTOR_MODE_P (mode))
   23485            0 :         *total = ix86_vec_cost (mode, cost->cvtps2pi);
   23486              :       else
   23487            0 :         *total = cost->cvtss2si;
   23488              :       return false;
   23489              : 
   23490       419026 :     case ABS:
   23491              :       /* SSE requires memory load for the constant operand. It may make
   23492              :          sense to account for this.  Of course the constant operand may or
   23493              :          may not be reused. */
   23494       419026 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23495       297858 :         *total = cost->sse_op;
   23496       121168 :       else if (X87_FLOAT_MODE_P (mode))
   23497        36901 :         *total = cost->fabs;
   23498        84267 :       else if (FLOAT_MODE_P (mode))
   23499        33418 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23500        50849 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23501         6657 :         *total = cost->sse_op;
   23502              :       return false;
   23503              : 
   23504        28906 :     case SQRT:
   23505        28906 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23506        18479 :         *total = mode == SFmode ? cost->sqrtss : cost->sqrtsd;
   23507        10427 :       else if (X87_FLOAT_MODE_P (mode))
   23508         4385 :         *total = cost->fsqrt;
   23509         6042 :       else if (FLOAT_MODE_P (mode))
   23510         6042 :         *total = ix86_vec_cost (mode,
   23511              :                                 mode == SFmode ? cost->sqrtss : cost->sqrtsd);
   23512              :       return false;
   23513              : 
   23514      4024982 :     case UNSPEC:
   23515      4024982 :       switch (XINT (x, 1))
   23516              :         {
   23517       126567 :         case UNSPEC_TP:
   23518       126567 :           *total = 0;
   23519       126567 :           break;
   23520              : 
   23521         5210 :         case UNSPEC_VTERNLOG:
   23522         5210 :           *total = cost->sse_op;
   23523         5210 :           if (!REG_P (XVECEXP (x, 0, 0)))
   23524          720 :             *total += rtx_cost (XVECEXP (x, 0, 0), mode, code, 0, speed);
   23525         5210 :           if (!REG_P (XVECEXP (x, 0, 1)))
   23526          694 :             *total += rtx_cost (XVECEXP (x, 0, 1), mode, code, 1, speed);
   23527         5210 :           if (!REG_P (XVECEXP (x, 0, 2)))
   23528          733 :             *total += rtx_cost (XVECEXP (x, 0, 2), mode, code, 2, speed);
   23529              :           return true;
   23530              : 
   23531        94814 :         case UNSPEC_PTEST:
   23532        94814 :           {
   23533        94814 :             *total = cost->sse_op;
   23534        94814 :             rtx test_op0 = XVECEXP (x, 0, 0);
   23535        94814 :             if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
   23536              :               return false;
   23537        94166 :             if (GET_CODE (test_op0) == AND)
   23538              :               {
   23539           23 :                 rtx and_op0 = XEXP (test_op0, 0);
   23540           23 :                 if (GET_CODE (and_op0) == NOT)
   23541            0 :                   and_op0 = XEXP (and_op0, 0);
   23542           23 :                 *total += rtx_cost (and_op0, GET_MODE (and_op0),
   23543              :                                     AND, 0, speed)
   23544           23 :                           + rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
   23545              :                                       AND, 1, speed);
   23546              :              }
   23547              :             else
   23548        94143 :               *total = rtx_cost (test_op0, GET_MODE (test_op0),
   23549              :                                  UNSPEC, 0, speed);
   23550              :           }
   23551              :           return true;
   23552              : 
   23553        20663 :         case UNSPEC_BLENDV:
   23554        20663 :           *total = cost->sse_op;
   23555        20663 :           if (!REG_P (XVECEXP (x, 0, 0)))
   23556         8658 :             *total += rtx_cost (XVECEXP (x, 0, 0), mode, code, 0, speed);
   23557        20663 :           if (!REG_P (XVECEXP (x, 0, 1)))
   23558        10127 :             *total += rtx_cost (XVECEXP (x, 0, 1), mode, code, 1, speed);
   23559        20663 :           if (!REG_P (XVECEXP (x, 0, 2)))
   23560              :             {
   23561        13123 :               rtx cond = XVECEXP (x, 0, 2);
   23562        13123 :               if ((GET_CODE (cond) == LT || GET_CODE (cond) == GT)
   23563          773 :                   && CONST_VECTOR_P (XEXP (cond, 1)))
   23564              :                 {
   23565              :                   /* avx2_blendvpd256_gt and friends.  */
   23566          153 :                   if (!REG_P (XEXP (cond, 0)))
   23567           70 :                     *total += rtx_cost (XEXP (cond, 0), mode, code, 2, speed);
   23568              :                 }
   23569              :               else
   23570        12970 :                 *total += rtx_cost (cond, mode, code, 2, speed);
   23571              :             }
   23572              :           return true;
   23573              : 
   23574        57925 :         case UNSPEC_MOVMSK:
   23575        57925 :           *total = cost->sse_op;
   23576        57925 :           return true;
   23577              : 
   23578              :         default:
   23579              :           break;
   23580              :         }
   23581              :       return false;
   23582              : 
   23583      2093506 :     case VEC_CONCAT:
   23584              :       /* ??? Assume all of these vector manipulation patterns are
   23585              :          recognizable.  In which case they all pretty much have the
   23586              :          same cost.
   23587              :          ??? We should still recruse when computing cost.  */
   23588      2093506 :      *total = cost->sse_op;
   23589      2093506 :      return true;
   23590              : 
   23591      2573319 :     case VEC_SELECT:
   23592              :      /* Special case extracting lower part from the vector.
   23593              :         This by itself needs to code and most of SSE/AVX instructions have
   23594              :         packed and single forms where the single form may be represented
   23595              :         by such VEC_SELECT.
   23596              : 
   23597              :         Use cost 1 (despite the fact that functionally equivalent SUBREG has
   23598              :         cost 0).  Making VEC_SELECT completely free, for example instructs CSE
   23599              :         to forward propagate VEC_SELECT into
   23600              : 
   23601              :            (set (reg eax) (reg src))
   23602              : 
   23603              :         which then prevents fwprop and combining. See i.e.
   23604              :         gcc.target/i386/pr91103-1.c.
   23605              : 
   23606              :         ??? rtvec_series_p test should be, for valid patterns, equivalent to
   23607              :         vec_series_lowpart_p but is not, since the latter calls
   23608              :         can_cange_mode_class on ALL_REGS and this return false since x87 does
   23609              :         not support subregs at all.  */
   23610      2573319 :      if (rtvec_series_p (XVEC (XEXP (x, 1), 0), 0))
   23611       810321 :        *total = rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
   23612       810321 :                           outer_code, opno, speed) + 1;
   23613              :      else
   23614              :        /* ??? We should still recruse when computing cost.  */
   23615      1762998 :        *total = cost->sse_op;
   23616              :      return true;
   23617              : 
   23618      1251169 :     case VEC_DUPLICATE:
   23619      2502338 :       *total = rtx_cost (XEXP (x, 0),
   23620      1251169 :                          GET_MODE (XEXP (x, 0)),
   23621              :                          VEC_DUPLICATE, 0, speed);
   23622              :       /* It's broadcast instruction, not embedded broadcasting.  */
   23623      1251169 :       if (outer_code == SET)
   23624      1199256 :         *total += cost->sse_op;
   23625              : 
   23626              :      return true;
   23627              : 
   23628       730418 :     case VEC_MERGE:
   23629       730418 :       mask = XEXP (x, 2);
   23630              :       /* Scalar versions of SSE instructions may be represented as:
   23631              : 
   23632              :          (vec_merge (vec_duplicate (operation ....))
   23633              :                      (register or memory)
   23634              :                      (const_int 1))
   23635              : 
   23636              :          In this case vec_merge and vec_duplicate is for free.
   23637              :          Just recurse into operation and second operand.  */
   23638       730418 :       if (mask == const1_rtx
   23639       217230 :           && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)
   23640              :         {
   23641        79406 :           *total = rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23642              :                              outer_code, opno, speed)
   23643        79406 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23644        79406 :           return true;
   23645              :         }
   23646              :       /* This is masked instruction, assume the same cost,
   23647              :          as nonmasked variant.  */
   23648       651012 :       else if (TARGET_AVX512F
   23649       651012 :                && (register_operand (mask, GET_MODE (mask))
   23650              :                    /* Redunduant clean up of high bits for kmask with VL=2/4
   23651              :                       .i.e (vec_merge op0, op1, (and op3 15)).  */
   23652       118917 :                    || (GET_CODE (mask) == AND
   23653          411 :                        && register_operand (XEXP (mask, 0), GET_MODE (mask))
   23654          411 :                        && CONST_INT_P (XEXP (mask, 1))
   23655          411 :                        && ((INTVAL (XEXP (mask, 1)) == 3
   23656          131 :                             && GET_MODE_NUNITS (mode) == 2)
   23657          280 :                            || (INTVAL (XEXP (mask, 1)) == 15
   23658          280 :                                && GET_MODE_NUNITS (mode) == 4)))))
   23659              :         {
   23660       373771 :           *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   23661       373771 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23662       373771 :           return true;
   23663              :         }
   23664              :       /* Combination of the two above:
   23665              : 
   23666              :          (vec_merge (vec_merge (vec_duplicate (operation ...))
   23667              :                        (register or memory)
   23668              :                        (reg:QI mask))
   23669              :                     (register or memory)
   23670              :                     (const_int 1))
   23671              : 
   23672              :          i.e. avx512fp16_vcvtss2sh_mask.  */
   23673       277241 :       else if (TARGET_AVX512F
   23674       118506 :                && mask == const1_rtx
   23675        45931 :                && GET_CODE (XEXP (x, 0)) == VEC_MERGE
   23676        27126 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == VEC_DUPLICATE
   23677       279503 :                && register_operand (XEXP (XEXP (x, 0), 2),
   23678         2262 :                                     GET_MODE (XEXP (XEXP (x, 0), 2))))
   23679              :         {
   23680         2250 :           *total = rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
   23681              :                              mode, outer_code, opno, speed)
   23682         2250 :                    + rtx_cost (XEXP (XEXP (x, 0), 1),
   23683              :                                mode, outer_code, opno, speed)
   23684         2250 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23685         2250 :           return true;
   23686              :         }
   23687              :       /* vcmp.  */
   23688       274991 :       else if (unspec_pcmp_p (mask)
   23689       274991 :                || (GET_CODE (mask) == NOT
   23690            0 :                    && unspec_pcmp_p (XEXP (mask, 0))))
   23691              :         {
   23692         1950 :           rtx uns = GET_CODE (mask) == NOT ? XEXP (mask, 0) : mask;
   23693         1950 :           rtx unsop0 = XVECEXP (uns, 0, 0);
   23694              :           /* Make (subreg:V4SI (not:V16QI (reg:V16QI ..)) 0)
   23695              :              cost the same as register.
   23696              :              This is used by avx_cmp<mode>3_ltint_not.  */
   23697         1950 :           if (SUBREG_P (unsop0))
   23698          417 :             unsop0 = XEXP (unsop0, 0);
   23699         1950 :           if (GET_CODE (unsop0) == NOT)
   23700           18 :             unsop0 = XEXP (unsop0, 0);
   23701         1950 :           *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   23702         1950 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed)
   23703         1950 :                    + rtx_cost (unsop0, mode, UNSPEC, opno, speed)
   23704         1950 :                    + rtx_cost (XVECEXP (uns, 0, 1), mode, UNSPEC, opno, speed)
   23705         1950 :                    + cost->sse_op;
   23706         1950 :           return true;
   23707              :         }
   23708              :       else
   23709       273041 :         *total = cost->sse_op;
   23710       273041 :       return false;
   23711              : 
   23712    107955585 :     case MEM:
   23713              :       /* CONST_VECTOR_DUPLICATE_P in constant_pool is just broadcast.
   23714              :          or variants in ix86_vector_duplicate_simode_const.  */
   23715              : 
   23716    107955585 :       if (GET_MODE_SIZE (mode) >= 16
   23717     17737969 :           && VECTOR_MODE_P (mode)
   23718     11603616 :           && SYMBOL_REF_P (XEXP (x, 0))
   23719      2284821 :           && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))
   23720    110012648 :           && ix86_broadcast_from_constant (mode, x))
   23721              :         {
   23722       524979 :           *total = COSTS_N_INSNS (2) + speed;
   23723       524979 :           return true;
   23724              :         }
   23725              : 
   23726              :       /* An insn that accesses memory is slightly more expensive
   23727              :          than one that does not.  */
   23728    107430606 :       if (speed)
   23729              :         {
   23730     96131955 :           *total += 1;
   23731     96131955 :           rtx addr = XEXP (x, 0);
   23732              :           /* For MEM, rtx_cost iterates each subrtx, and adds up the costs,
   23733              :              so for MEM (reg) and MEM (reg + 4), the former costs 5,
   23734              :              the latter costs 9, it is not accurate for x86. Ideally
   23735              :              address_cost should be used, but it reduce cost too much.
   23736              :              So current solution is make constant disp as cheap as possible.  */
   23737     96131955 :           if (GET_CODE (addr) == PLUS
   23738     78192435 :               && x86_64_immediate_operand (XEXP (addr, 1), Pmode)
   23739              :               /* Only handle (reg + disp) since other forms of addr are mostly LEA,
   23740              :                  there's no additional cost for the plus of disp.  */
   23741    168871920 :               && register_operand (XEXP (addr, 0), Pmode))
   23742              :             {
   23743     56879672 :               *total += 1;
   23744     69742323 :               *total += rtx_cost (XEXP (addr, 0), Pmode, PLUS, 0, speed);
   23745     56879672 :               return true;
   23746              :             }
   23747              :         }
   23748              : 
   23749              :       return false;
   23750              : 
   23751        51667 :     case ZERO_EXTRACT:
   23752        51667 :       if (XEXP (x, 1) == const1_rtx
   23753        11387 :           && GET_CODE (XEXP (x, 2)) == ZERO_EXTEND
   23754            0 :           && GET_MODE (XEXP (x, 2)) == SImode
   23755            0 :           && GET_MODE (XEXP (XEXP (x, 2), 0)) == QImode)
   23756              :         {
   23757              :           /* Ignore cost of zero extension and masking of last argument.  */
   23758            0 :           *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23759            0 :           *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23760            0 :           *total += rtx_cost (XEXP (XEXP (x, 2), 0), mode, code, 2, speed);
   23761            0 :           return true;
   23762              :         }
   23763              :       return false;
   23764              : 
   23765     29416058 :     case IF_THEN_ELSE:
   23766     29416058 :       if (TARGET_XOP
   23767        25035 :           && VECTOR_MODE_P (mode)
   23768     29421449 :           && (GET_MODE_SIZE (mode) == 16 || GET_MODE_SIZE (mode) == 32))
   23769              :         {
   23770              :           /* vpcmov.  */
   23771         4823 :           *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (6);
   23772         4823 :           if (!REG_P (XEXP (x, 0)))
   23773         4663 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23774         4823 :           if (!REG_P (XEXP (x, 1)))
   23775         4630 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23776         4823 :           if (!REG_P (XEXP (x, 2)))
   23777         4632 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   23778         4823 :           return true;
   23779              :         }
   23780            0 :       else if (TARGET_CMOVE
   23781     29411235 :                && SCALAR_INT_MODE_P (mode)
   23782     31816272 :                && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   23783              :         {
   23784              :           /* cmov.  */
   23785      2208087 :           *total = COSTS_N_INSNS (1);
   23786      2208087 :           if (!COMPARISON_P (XEXP (x, 0)) && !REG_P (XEXP (x, 0)))
   23787            0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23788      2208087 :           if (!REG_P (XEXP (x, 1)))
   23789       119472 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23790      2208087 :           if (!REG_P (XEXP (x, 2)))
   23791       719467 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   23792      2208087 :           return true;
   23793              :         }
   23794              :       return false;
   23795              : 
   23796     18331050 :     case EQ:
   23797     18331050 :     case GT:
   23798     18331050 :     case GTU:
   23799     18331050 :     case LT:
   23800     18331050 :     case LTU:
   23801     18331050 :       if (TARGET_SSE2
   23802     18327850 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23803     18712250 :           && GET_MODE_SIZE (mode) >= 8)
   23804              :         {
   23805              :           /* vpcmpeq */
   23806       373548 :           *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
   23807       373548 :           if (!REG_P (XEXP (x, 0)))
   23808        74846 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23809       373548 :           if (!REG_P (XEXP (x, 1)))
   23810       141906 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23811       373548 :           return true;
   23812              :         }
   23813     17957502 :       if (TARGET_XOP
   23814        12168 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23815     17957610 :           && GET_MODE_SIZE (mode) <= 16)
   23816              :         {
   23817              :           /* vpcomeq */
   23818          108 :           *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (6);
   23819          108 :           if (!REG_P (XEXP (x, 0)))
   23820            0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23821          108 :           if (!REG_P (XEXP (x, 1)))
   23822            0 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23823          108 :           return true;
   23824              :         }
   23825              :       return false;
   23826              : 
   23827     16369459 :     case NE:
   23828     16369459 :     case GE:
   23829     16369459 :     case GEU:
   23830     16369459 :       if (TARGET_XOP
   23831        21924 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23832     16376241 :           && GET_MODE_SIZE (mode) <= 16)
   23833              :         {
   23834              :           /* vpcomneq */
   23835         6782 :           *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (6);
   23836         6782 :           if (!REG_P (XEXP (x, 0)))
   23837         1405 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23838         6782 :           if (!REG_P (XEXP (x, 1)))
   23839         5734 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23840         6782 :           return true;
   23841              :         }
   23842     16362677 :       if (TARGET_SSE2
   23843     16360541 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23844     16365989 :           && GET_MODE_SIZE (mode) >= 8)
   23845              :         {
   23846         3347 :           if (TARGET_AVX512F && GET_MODE_SIZE (mode) >= 16)
   23847              :             /* vpcmpeq + vpternlog */
   23848           51 :             *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (11);
   23849              :           else
   23850              :             /* vpcmpeq + pxor + vpcmpeq */
   23851         3392 :             *total = speed ? COSTS_N_INSNS (3) : COSTS_N_BYTES (12);
   23852         3288 :           if (!REG_P (XEXP (x, 0)))
   23853          342 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23854         3288 :           if (!REG_P (XEXP (x, 1)))
   23855           45 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23856         3288 :           return true;
   23857              :         }
   23858              :       return false;
   23859              : 
   23860              :     default:
   23861              :       return false;
   23862              :     }
   23863              : }
   23864              : 
   23865              : #if TARGET_MACHO
   23866              : 
   23867              : static int current_machopic_label_num;
   23868              : 
   23869              : /* Given a symbol name and its associated stub, write out the
   23870              :    definition of the stub.  */
   23871              : 
   23872              : void
   23873              : machopic_output_stub (FILE *file, const char *symb, const char *stub)
   23874              : {
   23875              :   unsigned int length;
   23876              :   char *binder_name, *symbol_name, lazy_ptr_name[32];
   23877              :   int label = ++current_machopic_label_num;
   23878              : 
   23879              :   /* For 64-bit we shouldn't get here.  */
   23880              :   gcc_assert (!TARGET_64BIT);
   23881              : 
   23882              :   /* Lose our funky encoding stuff so it doesn't contaminate the stub.  */
   23883              :   symb = targetm.strip_name_encoding (symb);
   23884              : 
   23885              :   length = strlen (stub);
   23886              :   binder_name = XALLOCAVEC (char, length + 32);
   23887              :   GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
   23888              : 
   23889              :   length = strlen (symb);
   23890              :   symbol_name = XALLOCAVEC (char, length + 32);
   23891              :   GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
   23892              : 
   23893              :   sprintf (lazy_ptr_name, "L%d$lz", label);
   23894              : 
   23895              :   if (MACHOPIC_ATT_STUB)
   23896              :     switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
   23897              :   else if (MACHOPIC_PURE)
   23898              :     switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
   23899              :   else
   23900              :     switch_to_section (darwin_sections[machopic_symbol_stub_section]);
   23901              : 
   23902              :   fprintf (file, "%s:\n", stub);
   23903              :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   23904              : 
   23905              :   if (MACHOPIC_ATT_STUB)
   23906              :     {
   23907              :       fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
   23908              :     }
   23909              :   else if (MACHOPIC_PURE)
   23910              :     {
   23911              :       /* PIC stub.  */
   23912              :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   23913              :       rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
   23914              :       output_set_got (tmp, NULL_RTX);   /* "CALL ___<cpu>.get_pc_thunk.cx".  */
   23915              :       fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
   23916              :                label, lazy_ptr_name, label);
   23917              :       fprintf (file, "\tjmp\t*%%ecx\n");
   23918              :     }
   23919              :   else
   23920              :     fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
   23921              : 
   23922              :   /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
   23923              :      it needs no stub-binding-helper.  */
   23924              :   if (MACHOPIC_ATT_STUB)
   23925              :     return;
   23926              : 
   23927              :   fprintf (file, "%s:\n", binder_name);
   23928              : 
   23929              :   if (MACHOPIC_PURE)
   23930              :     {
   23931              :       fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
   23932              :       fprintf (file, "\tpushl\t%%ecx\n");
   23933              :     }
   23934              :   else
   23935              :     fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
   23936              : 
   23937              :   fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
   23938              : 
   23939              :   /* N.B. Keep the correspondence of these
   23940              :      'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
   23941              :      old-pic/new-pic/non-pic stubs; altering this will break
   23942              :      compatibility with existing dylibs.  */
   23943              :   if (MACHOPIC_PURE)
   23944              :     {
   23945              :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   23946              :       switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
   23947              :     }
   23948              :   else
   23949              :     /* 16-byte -mdynamic-no-pic stub.  */
   23950              :     switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
   23951              : 
   23952              :   fprintf (file, "%s:\n", lazy_ptr_name);
   23953              :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   23954              :   fprintf (file, ASM_LONG "%s\n", binder_name);
   23955              : }
   23956              : #endif /* TARGET_MACHO */
   23957              : 
   23958              : /* Order the registers for register allocator.  */
   23959              : 
   23960              : void
   23961       219158 : x86_order_regs_for_local_alloc (void)
   23962              : {
   23963       219158 :    int pos = 0;
   23964       219158 :    int i;
   23965              : 
   23966              :    /* First allocate the local general purpose registers.  */
   23967     20381694 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   23968     20162536 :      if (GENERAL_REGNO_P (i) && default_function_abi.clobbers_full_reg_p (i))
   23969      5490190 :        reg_alloc_order [pos++] = i;
   23970              : 
   23971              :    /* Global general purpose registers.  */
   23972     20381694 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   23973     20162536 :      if (GENERAL_REGNO_P (i) && !default_function_abi.clobbers_full_reg_p (i))
   23974      1522866 :        reg_alloc_order [pos++] = i;
   23975              : 
   23976              :    /* x87 registers come first in case we are doing FP math
   23977              :       using them.  */
   23978       219158 :    if (!TARGET_SSE_MATH)
   23979        56367 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   23980        50104 :        reg_alloc_order [pos++] = i;
   23981              : 
   23982              :    /* SSE registers.  */
   23983      1972422 :    for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
   23984      1753264 :      reg_alloc_order [pos++] = i;
   23985      1972422 :    for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
   23986      1753264 :      reg_alloc_order [pos++] = i;
   23987              : 
   23988              :    /* Extended REX SSE registers.  */
   23989      3725686 :    for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
   23990      3506528 :      reg_alloc_order [pos++] = i;
   23991              : 
   23992              :    /* Mask register.  */
   23993      1972422 :    for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
   23994      1753264 :      reg_alloc_order [pos++] = i;
   23995              : 
   23996              :    /* x87 registers.  */
   23997       219158 :    if (TARGET_SSE_MATH)
   23998      1916055 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   23999      1703160 :        reg_alloc_order [pos++] = i;
   24000              : 
   24001      1972422 :    for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
   24002      1753264 :      reg_alloc_order [pos++] = i;
   24003              : 
   24004              :    /* Initialize the rest of array as we do not allocate some registers
   24005              :       at all.  */
   24006      1095790 :    while (pos < FIRST_PSEUDO_REGISTER)
   24007       876632 :      reg_alloc_order [pos++] = 0;
   24008       219158 : }
   24009              : 
   24010              : static bool
   24011    254083935 : ix86_ms_bitfield_layout_p (const_tree record_type)
   24012              : {
   24013    254083935 :   return ((TARGET_MS_BITFIELD_LAYOUT
   24014          215 :            && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
   24015    254083935 :           || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
   24016              : }
   24017              : 
   24018              : /* Returns an expression indicating where the this parameter is
   24019              :    located on entry to the FUNCTION.  */
   24020              : 
   24021              : static rtx
   24022         1770 : x86_this_parameter (tree function)
   24023              : {
   24024         1770 :   tree type = TREE_TYPE (function);
   24025         1770 :   bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
   24026         1770 :   int nregs;
   24027              : 
   24028         1770 :   if (TARGET_64BIT)
   24029              :     {
   24030         1768 :       const int *parm_regs;
   24031              : 
   24032         1768 :       if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type)))
   24033              :         parm_regs = x86_64_preserve_none_int_parameter_registers;
   24034         1768 :       else if (ix86_function_type_abi (type) == MS_ABI)
   24035              :         parm_regs = x86_64_ms_abi_int_parameter_registers;
   24036              :       else
   24037         1768 :         parm_regs = x86_64_int_parameter_registers;
   24038         1768 :       return gen_rtx_REG (Pmode, parm_regs[aggr]);
   24039              :     }
   24040              : 
   24041            2 :   nregs = ix86_function_regparm (type, function);
   24042              : 
   24043            2 :   if (nregs > 0 && !stdarg_p (type))
   24044              :     {
   24045            0 :       int regno;
   24046            0 :       unsigned int ccvt = ix86_get_callcvt (type);
   24047              : 
   24048            0 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   24049            0 :         regno = aggr ? DX_REG : CX_REG;
   24050            0 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   24051              :         {
   24052            0 :           regno = CX_REG;
   24053            0 :           if (aggr)
   24054            0 :             return gen_rtx_MEM (SImode,
   24055            0 :                                 plus_constant (Pmode, stack_pointer_rtx, 4));
   24056              :         }
   24057              :       else
   24058              :         {
   24059            0 :           regno = AX_REG;
   24060            0 :           if (aggr)
   24061              :             {
   24062            0 :               regno = DX_REG;
   24063            0 :               if (nregs == 1)
   24064            0 :                 return gen_rtx_MEM (SImode,
   24065            0 :                                     plus_constant (Pmode,
   24066              :                                                    stack_pointer_rtx, 4));
   24067              :             }
   24068              :         }
   24069            0 :       return gen_rtx_REG (SImode, regno);
   24070              :     }
   24071              : 
   24072            4 :   return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
   24073            4 :                                              aggr ? 8 : 4));
   24074              : }
   24075              : 
   24076              : /* Determine whether x86_output_mi_thunk can succeed.  */
   24077              : 
   24078              : static bool
   24079         4926 : x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   24080              :                          const_tree function)
   24081              : {
   24082              :   /* 64-bit can handle anything.  */
   24083         4926 :   if (TARGET_64BIT)
   24084              :     return true;
   24085              : 
   24086              :   /* For 32-bit, everything's fine if we have one free register.  */
   24087           76 :   if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
   24088              :     return true;
   24089              : 
   24090              :   /* Need a free register for vcall_offset.  */
   24091            0 :   if (vcall_offset)
   24092              :     return false;
   24093              : 
   24094              :   /* Need a free register for GOT references.  */
   24095            0 :   if (flag_pic && !targetm.binds_local_p (function))
   24096              :     return false;
   24097              : 
   24098              :   /* Otherwise ok.  */
   24099              :   return true;
   24100              : }
   24101              : 
   24102              : /* Output the assembler code for a thunk function.  THUNK_DECL is the
   24103              :    declaration for the thunk function itself, FUNCTION is the decl for
   24104              :    the target function.  DELTA is an immediate constant offset to be
   24105              :    added to THIS.  If VCALL_OFFSET is nonzero, the word at
   24106              :    *(*this + vcall_offset) should be added to THIS.  */
   24107              : 
   24108              : static void
   24109         1770 : x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
   24110              :                      HOST_WIDE_INT vcall_offset, tree function)
   24111              : {
   24112         1770 :   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   24113         1770 :   rtx this_param = x86_this_parameter (function);
   24114         1770 :   rtx this_reg, tmp, fnaddr;
   24115         1770 :   unsigned int tmp_regno;
   24116         1770 :   rtx_insn *insn;
   24117         1770 :   int saved_flag_force_indirect_call = flag_force_indirect_call;
   24118              : 
   24119         1770 :   if (TARGET_64BIT)
   24120              :     tmp_regno = R10_REG;
   24121              :   else
   24122              :     {
   24123            2 :       unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
   24124            2 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   24125              :         tmp_regno = AX_REG;
   24126            2 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   24127              :         tmp_regno = DX_REG;
   24128              :       else
   24129            2 :         tmp_regno = CX_REG;
   24130              : 
   24131            2 :       if (flag_pic)
   24132            2 :   flag_force_indirect_call = 0;
   24133              :     }
   24134              : 
   24135         1770 :   emit_note (NOTE_INSN_PROLOGUE_END);
   24136              : 
   24137              :   /* CET is enabled, insert EB instruction.  */
   24138         1770 :   if ((flag_cf_protection & CF_BRANCH))
   24139           20 :     emit_insn (gen_nop_endbr ());
   24140              : 
   24141              :   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
   24142              :      pull it in now and let DELTA benefit.  */
   24143         1770 :   if (REG_P (this_param))
   24144              :     this_reg = this_param;
   24145            2 :   else if (vcall_offset)
   24146              :     {
   24147              :       /* Put the this parameter into %eax.  */
   24148            2 :       this_reg = gen_rtx_REG (Pmode, AX_REG);
   24149            1 :       emit_move_insn (this_reg, this_param);
   24150              :     }
   24151              :   else
   24152              :     this_reg = NULL_RTX;
   24153              : 
   24154              :   /* Adjust the this parameter by a fixed constant.  */
   24155         1770 :   if (delta)
   24156              :     {
   24157          831 :       rtx delta_rtx = GEN_INT (delta);
   24158          831 :       rtx delta_dst = this_reg ? this_reg : this_param;
   24159              : 
   24160          831 :       if (TARGET_64BIT)
   24161              :         {
   24162          830 :           if (!x86_64_general_operand (delta_rtx, Pmode))
   24163              :             {
   24164            0 :               tmp = gen_rtx_REG (Pmode, tmp_regno);
   24165            0 :               emit_move_insn (tmp, delta_rtx);
   24166            0 :               delta_rtx = tmp;
   24167              :             }
   24168              :         }
   24169              : 
   24170          832 :       ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
   24171              :     }
   24172              : 
   24173              :   /* Adjust the this parameter by a value stored in the vtable.  */
   24174         1770 :   if (vcall_offset)
   24175              :     {
   24176          990 :       rtx vcall_addr, vcall_mem, this_mem;
   24177              : 
   24178          991 :       tmp = gen_rtx_REG (Pmode, tmp_regno);
   24179              : 
   24180          990 :       this_mem = gen_rtx_MEM (ptr_mode, this_reg);
   24181          991 :       if (Pmode != ptr_mode)
   24182            0 :         this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
   24183          990 :       emit_move_insn (tmp, this_mem);
   24184              : 
   24185              :       /* Adjust the this parameter.  */
   24186          991 :       vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
   24187          990 :       if (TARGET_64BIT
   24188          990 :           && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
   24189              :         {
   24190            0 :           rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
   24191            0 :           emit_move_insn (tmp2, GEN_INT (vcall_offset));
   24192            0 :           vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
   24193              :         }
   24194              : 
   24195          990 :       vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
   24196          991 :       if (Pmode != ptr_mode)
   24197            0 :         emit_insn (gen_addsi_1_zext (this_reg,
   24198              :                                      gen_rtx_REG (ptr_mode,
   24199              :                                                   REGNO (this_reg)),
   24200              :                                      vcall_mem));
   24201              :       else
   24202          990 :         ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
   24203              :     }
   24204              : 
   24205              :   /* If necessary, drop THIS back to its stack slot.  */
   24206         1770 :   if (this_reg && this_reg != this_param)
   24207            1 :     emit_move_insn (this_param, this_reg);
   24208              : 
   24209         1770 :   fnaddr = XEXP (DECL_RTL (function), 0);
   24210         1770 :   if (TARGET_64BIT)
   24211              :     {
   24212           25 :       if (!flag_pic || targetm.binds_local_p (function)
   24213         1793 :           || TARGET_PECOFF)
   24214              :         ;
   24215              :       else
   24216              :         {
   24217            0 :           tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
   24218            0 :           tmp = gen_rtx_CONST (Pmode, tmp);
   24219            0 :           fnaddr = gen_const_mem (Pmode, tmp);
   24220              :         }
   24221              :     }
   24222              :   else
   24223              :     {
   24224            2 :       if (!flag_pic || targetm.binds_local_p (function))
   24225              :         ;
   24226              : #if TARGET_MACHO
   24227              :       else if (TARGET_MACHO)
   24228              :         {
   24229              :           fnaddr = machopic_indirect_call_target (DECL_RTL (function));
   24230              :           fnaddr = XEXP (fnaddr, 0);
   24231              :         }
   24232              : #endif /* TARGET_MACHO */
   24233              :       else
   24234              :         {
   24235            0 :           tmp = gen_rtx_REG (Pmode, CX_REG);
   24236            0 :           output_set_got (tmp, NULL_RTX);
   24237              : 
   24238            0 :           fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
   24239            0 :           fnaddr = gen_rtx_CONST (Pmode, fnaddr);
   24240            0 :           fnaddr = gen_rtx_PLUS (Pmode, tmp, fnaddr);
   24241            0 :           fnaddr = gen_const_mem (Pmode, fnaddr);
   24242              :         }
   24243              :     }
   24244              : 
   24245              :   /* Our sibling call patterns do not allow memories, because we have no
   24246              :      predicate that can distinguish between frame and non-frame memory.
   24247              :      For our purposes here, we can get away with (ab)using a jump pattern,
   24248              :      because we're going to do no optimization.  */
   24249         1770 :   if (MEM_P (fnaddr))
   24250              :     {
   24251            0 :       if (sibcall_insn_operand (fnaddr, word_mode))
   24252              :         {
   24253            0 :           fnaddr = XEXP (DECL_RTL (function), 0);
   24254            0 :           tmp = gen_rtx_MEM (QImode, fnaddr);
   24255            0 :           tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   24256            0 :           tmp = emit_call_insn (tmp);
   24257            0 :           SIBLING_CALL_P (tmp) = 1;
   24258              :         }
   24259              :       else
   24260            0 :         emit_jump_insn (gen_indirect_jump (fnaddr));
   24261              :     }
   24262              :   else
   24263              :     {
   24264         1770 :       if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
   24265              :         {
   24266              :           // CM_LARGE_PIC always uses pseudo PIC register which is
   24267              :           // uninitialized.  Since FUNCTION is local and calling it
   24268              :           // doesn't go through PLT, we use scratch register %r11 as
   24269              :           // PIC register and initialize it here.
   24270            3 :           pic_offset_table_rtx = gen_rtx_REG (Pmode, R11_REG);
   24271            3 :           ix86_init_large_pic_reg (tmp_regno);
   24272            3 :           fnaddr = legitimize_pic_address (fnaddr,
   24273            3 :                                            gen_rtx_REG (Pmode, tmp_regno));
   24274              :         }
   24275              : 
   24276         1770 :       if (!sibcall_insn_operand (fnaddr, word_mode))
   24277              :         {
   24278            9 :           tmp = gen_rtx_REG (word_mode, tmp_regno);
   24279            9 :           if (GET_MODE (fnaddr) != word_mode)
   24280            0 :             fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
   24281            9 :           emit_move_insn (tmp, fnaddr);
   24282            9 :           fnaddr = tmp;
   24283              :         }
   24284              : 
   24285         1770 :       tmp = gen_rtx_MEM (QImode, fnaddr);
   24286         1770 :       tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   24287         1770 :       tmp = emit_call_insn (tmp);
   24288         1770 :       SIBLING_CALL_P (tmp) = 1;
   24289              :     }
   24290         1770 :   emit_barrier ();
   24291              : 
   24292              :   /* Emit just enough of rest_of_compilation to get the insns emitted.  */
   24293         1770 :   insn = get_insns ();
   24294         1770 :   shorten_branches (insn);
   24295         1770 :   assemble_start_function (thunk_fndecl, fnname);
   24296         1770 :   final_start_function (insn, file, 1);
   24297         1770 :   final (insn, file, 1);
   24298         1770 :   final_end_function ();
   24299         1770 :   assemble_end_function (thunk_fndecl, fnname);
   24300              : 
   24301         1770 :   flag_force_indirect_call = saved_flag_force_indirect_call;
   24302         1770 : }
   24303              : 
   24304              : static void
   24305       277837 : x86_file_start (void)
   24306              : {
   24307       277837 :   default_file_start ();
   24308       277837 :   if (TARGET_16BIT)
   24309            6 :     fputs ("\t.code16gcc\n", asm_out_file);
   24310              : #if TARGET_MACHO
   24311              :   darwin_file_start ();
   24312              : #endif
   24313       277837 :   if (X86_FILE_START_VERSION_DIRECTIVE)
   24314              :     fputs ("\t.version\t\"01.01\"\n", asm_out_file);
   24315       277837 :   if (X86_FILE_START_FLTUSED)
   24316              :     fputs ("\t.global\t__fltused\n", asm_out_file);
   24317       277837 :   if (ix86_asm_dialect == ASM_INTEL)
   24318           66 :     fputs ("\t.intel_syntax noprefix\n", asm_out_file);
   24319       277837 : }
   24320              : 
   24321              : int
   24322    105553418 : x86_field_alignment (tree type, int computed)
   24323              : {
   24324    105553418 :   machine_mode mode;
   24325              : 
   24326    105553418 :   if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
   24327              :     return computed;
   24328      9127689 :   if (TARGET_IAMCU)
   24329            0 :     return iamcu_alignment (type, computed);
   24330      9127689 :   type = strip_array_types (type);
   24331      9127689 :   mode = TYPE_MODE (type);
   24332      9127689 :   if (mode == DFmode || mode == DCmode
   24333      9021723 :       || GET_MODE_CLASS (mode) == MODE_INT
   24334      3019945 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
   24335              :     {
   24336      6107744 :       if (TYPE_ATOMIC (type) && computed > 32)
   24337              :         {
   24338            0 :           static bool warned;
   24339              : 
   24340            0 :           if (!warned && warn_psabi)
   24341              :             {
   24342            0 :               const char *url
   24343              :                 = CHANGES_ROOT_URL "gcc-11/changes.html#ia32_atomic";
   24344              : 
   24345            0 :               warned = true;
   24346            0 :               inform (input_location, "the alignment of %<_Atomic %T%> "
   24347              :                                       "fields changed in %{GCC 11.1%}",
   24348            0 :                       TYPE_MAIN_VARIANT (type), url);
   24349              :             }
   24350              :         }
   24351              :       else
   24352      6107744 :       return MIN (32, computed);
   24353              :     }
   24354              :   return computed;
   24355              : }
   24356              : 
   24357              : /* Print call to TARGET to FILE.  */
   24358              : 
   24359              : static void
   24360          375 : x86_print_call_or_nop (FILE *file, const char *target,
   24361              :                        const char *label)
   24362              : {
   24363          375 :   if (flag_nop_mcount || !strcmp (target, "nop"))
   24364              :     {
   24365            9 :       if (TARGET_16BIT)
   24366              :         /* 3 byte no-op: lea 0(%si), %si */
   24367            1 :         fprintf (file, "%s" ASM_BYTE "0x8d, 0x74, 0x00\n", label);
   24368              :       else
   24369              :         /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
   24370            8 :         fprintf (file, "%s" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n",
   24371              :                  label);
   24372              :     }
   24373          366 :   else if (!TARGET_PECOFF && flag_pic)
   24374              :     {
   24375            8 :       gcc_assert (flag_plt);
   24376              : 
   24377            8 :       fprintf (file, "%s\tcall\t%s@PLT\n", label, target);
   24378              :     }
   24379              :   else
   24380          358 :     fprintf (file, "%s\tcall\t%s\n", label, target);
   24381          375 : }
   24382              : 
   24383              : static bool
   24384          395 : current_fentry_name (const char **name)
   24385              : {
   24386          395 :   tree attr = lookup_attribute ("fentry_name",
   24387          395 :                                 DECL_ATTRIBUTES (current_function_decl));
   24388          395 :   if (!attr)
   24389              :     return false;
   24390            2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   24391            2 :   return true;
   24392              : }
   24393              : 
   24394              : static bool
   24395           16 : current_fentry_section (const char **name)
   24396              : {
   24397           16 :   tree attr = lookup_attribute ("fentry_section",
   24398           16 :                                 DECL_ATTRIBUTES (current_function_decl));
   24399           16 :   if (!attr)
   24400              :     return false;
   24401            2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   24402            2 :   return true;
   24403              : }
   24404              : 
   24405              : /* Return a caller-saved register which isn't live or a callee-saved
   24406              :    register which has been saved on stack in the prologue at entry for
   24407              :    profile.  */
   24408              : 
   24409              : static int
   24410           17 : x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
   24411              : {
   24412              :   /* Use %r10 if the profiler is emitted before the prologue or it isn't
   24413              :      used by DRAP.  */
   24414           17 :   if (ix86_profile_before_prologue ()
   24415            4 :       || !crtl->drap_reg
   24416           17 :       || REGNO (crtl->drap_reg) != R10_REG)
   24417              :     return R10_REG;
   24418              : 
   24419              :   /* The profiler is emitted after the prologue.  If there is a
   24420              :      caller-saved register which isn't live or a callee-saved
   24421              :      register saved on stack in the prologue, use it.  */
   24422              : 
   24423            0 :   bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
   24424              : 
   24425            0 :   int i;
   24426            0 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   24427            0 :     if (GENERAL_REGNO_P (i)
   24428            0 :         && i != R10_REG
   24429              : #ifdef NO_PROFILE_COUNTERS
   24430            0 :         && (r11_ok || i != R11_REG)
   24431              : #else
   24432              :         && i != R11_REG
   24433              : #endif
   24434            0 :         && TEST_HARD_REG_BIT (accessible_reg_set, i)
   24435            0 :         && (ix86_save_reg (i, true, true)
   24436            0 :             || (crtl->abi->clobbers_full_reg_p (i)
   24437            0 :                 && !fixed_regs[i]
   24438            0 :                 && !REGNO_REG_SET_P (reg_live, i))))
   24439            0 :       return i;
   24440              : 
   24441            0 :   sorry ("no register available for profiling %<-mcmodel=large%s%>",
   24442            0 :          ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
   24443              : 
   24444            0 :   return R10_REG;
   24445              : }
   24446              : 
   24447              : /* Output assembler code to FILE to increment profiler label # LABELNO
   24448              :    for profiling a function entry.  */
   24449              : void
   24450          395 : x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   24451              : {
   24452          395 :   if (cfun->machine->insn_queued_at_entrance)
   24453              :     {
   24454            7 :       if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
   24455            6 :         fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
   24456            7 :       unsigned int patch_area_size
   24457            7 :         = crtl->patch_area_size - crtl->patch_area_entry;
   24458            7 :       if (patch_area_size)
   24459            2 :         ix86_output_patchable_area (patch_area_size,
   24460              :                                     crtl->patch_area_entry == 0);
   24461              :     }
   24462              : 
   24463          395 :   const char *mcount_name = MCOUNT_NAME;
   24464              : 
   24465          395 :   bool fentry_section_p
   24466          395 :     = (flag_record_mcount
   24467          775 :        || lookup_attribute ("fentry_section",
   24468          380 :                             DECL_ATTRIBUTES (current_function_decl)));
   24469              : 
   24470              :   const char *label = fentry_section_p ? "1:" : "";
   24471              : 
   24472          395 :   if (current_fentry_name (&mcount_name))
   24473              :     ;
   24474          393 :   else if (fentry_name)
   24475            1 :     mcount_name = fentry_name;
   24476          392 :   else if (flag_fentry)
   24477          380 :     mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
   24478              : 
   24479          395 :   if (TARGET_64BIT)
   24480              :     {
   24481              : #ifndef NO_PROFILE_COUNTERS
   24482              :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   24483              :         fprintf (file, "\tlea\tr11, %sP%d[rip]\n", LPREFIX, labelno);
   24484              :       else
   24485              :         fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
   24486              : #endif
   24487              : 
   24488          394 :       int scratch;
   24489          394 :       const char *reg;
   24490          394 :       char legacy_reg[4] = { 0 };
   24491              : 
   24492          394 :       if (!TARGET_PECOFF)
   24493              :         {
   24494          394 :           switch (ix86_cmodel)
   24495              :             {
   24496            7 :             case CM_LARGE:
   24497            7 :               scratch = x86_64_select_profile_regnum (true);
   24498            7 :               reg = hi_reg_name[scratch];
   24499            7 :               if (LEGACY_INT_REGNO_P (scratch))
   24500              :                 {
   24501            0 :                   legacy_reg[0] = 'r';
   24502            0 :                   legacy_reg[1] = reg[0];
   24503            0 :                   legacy_reg[2] = reg[1];
   24504            0 :                   reg = legacy_reg;
   24505              :                 }
   24506            7 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   24507            1 :                 fprintf (file, "%s\tmovabs\t%s, OFFSET FLAT:%s\n"
   24508              :                                "\tcall\t%s\n", label, reg, mcount_name,
   24509              :                                reg);
   24510              :               else
   24511            6 :                 fprintf (file, "%s\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n",
   24512              :                          label, mcount_name, reg, reg);
   24513              :               break;
   24514           10 :             case CM_LARGE_PIC:
   24515              : #ifdef NO_PROFILE_COUNTERS
   24516           10 :               scratch = x86_64_select_profile_regnum (false);
   24517           10 :               reg = hi_reg_name[scratch];
   24518           10 :               if (LEGACY_INT_REGNO_P (scratch))
   24519              :                 {
   24520            0 :                   legacy_reg[0] = 'r';
   24521            0 :                   legacy_reg[1] = reg[0];
   24522            0 :                   legacy_reg[2] = reg[1];
   24523            0 :                   reg = legacy_reg;
   24524              :                 }
   24525           10 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   24526              :                 {
   24527            1 :                   fprintf (file, "1:movabs\tr11, "
   24528              :                                  "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
   24529            1 :                   fprintf (file, "\tlea\t%s, 1b[rip]\n", reg);
   24530            1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   24531            1 :                   fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
   24532              :                            mcount_name);
   24533            1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   24534            1 :                   fprintf (file, "\tcall\t%s\n", reg);
   24535            1 :                   break;
   24536              :                 }
   24537            9 :               fprintf (file,
   24538              :                        "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
   24539            9 :               fprintf (file, "\tleaq\t1b(%%rip), %%%s\n", reg);
   24540            9 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   24541            9 :               fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
   24542            9 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   24543            9 :               fprintf (file, "\tcall\t*%%%s\n", reg);
   24544              : #else
   24545              :               sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
   24546              : #endif
   24547            9 :               break;
   24548           12 :             case CM_SMALL_PIC:
   24549           12 :             case CM_MEDIUM_PIC:
   24550           12 :               if (!flag_plt)
   24551              :                 {
   24552            3 :                   if (ASSEMBLER_DIALECT == ASM_INTEL)
   24553            0 :                     fprintf (file, "%s\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n",
   24554              :                              label, mcount_name);
   24555              :                   else
   24556            3 :                     fprintf (file, "%s\tcall\t*%s@GOTPCREL(%%rip)\n",
   24557              :                              label, mcount_name);
   24558              :                   break;
   24559              :                 }
   24560              :               /* fall through */
   24561          374 :             default:
   24562          374 :               x86_print_call_or_nop (file, mcount_name, label);
   24563          374 :               break;
   24564              :             }
   24565              :         }
   24566              :       else
   24567              :         x86_print_call_or_nop (file, mcount_name, label);
   24568              :     }
   24569            1 :   else if (flag_pic)
   24570              :     {
   24571              : #ifndef NO_PROFILE_COUNTERS
   24572              :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   24573              :         fprintf (file,
   24574              :                  "\tlea\t" PROFILE_COUNT_REGISTER ", %sP%d@GOTOFF[ebx]\n",
   24575              :                  LPREFIX, labelno);
   24576              :       else
   24577              :         fprintf (file,
   24578              :                  "\tleal\t%sP%d@GOTOFF(%%ebx), %%" PROFILE_COUNT_REGISTER "\n",
   24579              :                  LPREFIX, labelno);
   24580              : #endif
   24581            0 :       if (flag_plt)
   24582            0 :         x86_print_call_or_nop (file, mcount_name, label);
   24583            0 :       else if (ASSEMBLER_DIALECT == ASM_INTEL)
   24584            0 :         fprintf (file, "%s\tcall\t[DWORD PTR %s@GOT[ebx]]\n",
   24585              :                  label, mcount_name);
   24586              :       else
   24587            0 :         fprintf (file, "%s\tcall\t*%s@GOT(%%ebx)\n",
   24588              :                  label, mcount_name);
   24589              :     }
   24590              :   else
   24591              :     {
   24592              : #ifndef NO_PROFILE_COUNTERS
   24593              :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   24594              :         fprintf (file,
   24595              :                  "\tmov\t" PROFILE_COUNT_REGISTER ", OFFSET FLAT:%sP%d\n",
   24596              :                  LPREFIX, labelno);
   24597              :       else
   24598              :         fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n",
   24599              :                  LPREFIX, labelno);
   24600              : #endif
   24601            1 :       x86_print_call_or_nop (file, mcount_name, label);
   24602              :     }
   24603              : 
   24604          395 :   if (fentry_section_p)
   24605              :     {
   24606           16 :       const char *sname = "__mcount_loc";
   24607              : 
   24608           16 :       if (current_fentry_section (&sname))
   24609              :         ;
   24610           14 :       else if (fentry_section)
   24611            1 :         sname = fentry_section;
   24612              : 
   24613           16 :       fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
   24614           16 :       fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   24615           16 :       fprintf (file, "\t.previous\n");
   24616              :     }
   24617          395 : }
   24618              : 
   24619              : /* We don't have exact information about the insn sizes, but we may assume
   24620              :    quite safely that we are informed about all 1 byte insns and memory
   24621              :    address sizes.  This is enough to eliminate unnecessary padding in
   24622              :    99% of cases.  */
   24623              : 
   24624              : int
   24625    390837486 : ix86_min_insn_size (rtx_insn *insn)
   24626              : {
   24627    390837486 :   int l = 0, len;
   24628              : 
   24629    390837486 :   if (!INSN_P (insn) || !active_insn_p (insn))
   24630       500713 :     return 0;
   24631              : 
   24632              :   /* Discard alignments we've emit and jump instructions.  */
   24633    390336773 :   if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
   24634    390336773 :       && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
   24635              :     return 0;
   24636              : 
   24637              :   /* Important case - calls are always 5 bytes.
   24638              :      It is common to have many calls in the row.  */
   24639    390336769 :   if (CALL_P (insn)
   24640      9219655 :       && symbolic_reference_mentioned_p (PATTERN (insn))
   24641    399224170 :       && !SIBLING_CALL_P (insn))
   24642              :     return 5;
   24643    381685411 :   len = get_attr_length (insn);
   24644    381685411 :   if (len <= 1)
   24645              :     return 1;
   24646              : 
   24647              :   /* For normal instructions we rely on get_attr_length being exact,
   24648              :      with a few exceptions.  */
   24649    373034817 :   if (!JUMP_P (insn))
   24650              :     {
   24651    367595839 :       enum attr_type type = get_attr_type (insn);
   24652              : 
   24653    367595839 :       switch (type)
   24654              :         {
   24655        96077 :         case TYPE_MULTI:
   24656        96077 :           if (GET_CODE (PATTERN (insn)) == ASM_INPUT
   24657        96077 :               || asm_noperands (PATTERN (insn)) >= 0)
   24658          527 :             return 0;
   24659              :           break;
   24660              :         case TYPE_OTHER:
   24661              :         case TYPE_FCMP:
   24662              :           break;
   24663              :         default:
   24664              :           /* Otherwise trust get_attr_length.  */
   24665              :           return len;
   24666              :         }
   24667              : 
   24668       476158 :       l = get_attr_length_address (insn);
   24669       476158 :       if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
   24670              :         l = 4;
   24671              :     }
   24672       385654 :   if (l)
   24673        90504 :     return 1+l;
   24674              :   else
   24675      5824632 :     return 2;
   24676              : }
   24677              : 
   24678              : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   24679              : 
   24680              : /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
   24681              :    window.  */
   24682              : 
   24683              : static void
   24684        45472 : ix86_avoid_jump_mispredicts (void)
   24685              : {
   24686        45472 :   rtx_insn *insn, *start = get_insns ();
   24687        45472 :   int nbytes = 0, njumps = 0;
   24688        45472 :   bool isjump = false;
   24689              : 
   24690              :   /* Look for all minimal intervals of instructions containing 4 jumps.
   24691              :      The intervals are bounded by START and INSN.  NBYTES is the total
   24692              :      size of instructions in the interval including INSN and not including
   24693              :      START.  When the NBYTES is smaller than 16 bytes, it is possible
   24694              :      that the end of START and INSN ends up in the same 16byte page.
   24695              : 
   24696              :      The smallest offset in the page INSN can start is the case where START
   24697              :      ends on the offset 0.  Offset of INSN is then NBYTES - sizeof (INSN).
   24698              :      We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
   24699              : 
   24700              :      Don't consider asm goto as jump, while it can contain a jump, it doesn't
   24701              :      have to, control transfer to label(s) can be performed through other
   24702              :      means, and also we estimate minimum length of all asm stmts as 0.  */
   24703       701057 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   24704              :     {
   24705       655585 :       int min_size;
   24706              : 
   24707       655585 :       if (LABEL_P (insn))
   24708              :         {
   24709          956 :           align_flags alignment = label_to_alignment (insn);
   24710          956 :           int align = alignment.levels[0].log;
   24711          956 :           int max_skip = alignment.levels[0].maxskip;
   24712              : 
   24713          956 :           if (max_skip > 15)
   24714              :             max_skip = 15;
   24715              :           /* If align > 3, only up to 16 - max_skip - 1 bytes can be
   24716              :              already in the current 16 byte page, because otherwise
   24717              :              ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
   24718              :              bytes to reach 16 byte boundary.  */
   24719          956 :           if (align <= 0
   24720          313 :               || (align <= 3 && max_skip != (1 << align) - 1))
   24721          956 :             max_skip = 0;
   24722          956 :           if (dump_file)
   24723            0 :             fprintf (dump_file, "Label %i with max_skip %i\n",
   24724            0 :                      INSN_UID (insn), max_skip);
   24725          956 :           if (max_skip)
   24726              :             {
   24727         6120 :               while (nbytes + max_skip >= 16)
   24728              :                 {
   24729         5807 :                   start = NEXT_INSN (start);
   24730          295 :                   if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   24731         5824 :                       || CALL_P (start))
   24732          335 :                     njumps--, isjump = true;
   24733              :                   else
   24734              :                     isjump = false;
   24735         5807 :                   nbytes -= ix86_min_insn_size (start);
   24736              :                 }
   24737              :             }
   24738          956 :           continue;
   24739          956 :         }
   24740              : 
   24741       654629 :       min_size = ix86_min_insn_size (insn);
   24742       654629 :       nbytes += min_size;
   24743       654629 :       if (dump_file)
   24744            0 :         fprintf (dump_file, "Insn %i estimated to %i bytes\n",
   24745            0 :                  INSN_UID (insn), min_size);
   24746        46596 :       if ((JUMP_P (insn) && asm_noperands (PATTERN (insn)) < 0)
   24747       654649 :           || CALL_P (insn))
   24748        47609 :         njumps++;
   24749              :       else
   24750       607020 :         continue;
   24751              : 
   24752        55969 :       while (njumps > 3)
   24753              :         {
   24754         8360 :           start = NEXT_INSN (start);
   24755          527 :           if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   24756         8360 :               || CALL_P (start))
   24757         1227 :             njumps--, isjump = true;
   24758              :           else
   24759              :             isjump = false;
   24760         8360 :           nbytes -= ix86_min_insn_size (start);
   24761              :         }
   24762        47609 :       gcc_assert (njumps >= 0);
   24763        47609 :       if (dump_file)
   24764            0 :         fprintf (dump_file, "Interval %i to %i has %i bytes\n",
   24765            0 :                  INSN_UID (start), INSN_UID (insn), nbytes);
   24766              : 
   24767        47609 :       if (njumps == 3 && isjump && nbytes < 16)
   24768              :         {
   24769           36 :           int padsize = 15 - nbytes + ix86_min_insn_size (insn);
   24770              : 
   24771           36 :           if (dump_file)
   24772            0 :             fprintf (dump_file, "Padding insn %i by %i bytes!\n",
   24773            0 :                      INSN_UID (insn), padsize);
   24774           36 :           emit_insn_before (gen_max_skip_align (GEN_INT (4), GEN_INT (padsize)), insn);
   24775              :         }
   24776              :     }
   24777        45472 : }
   24778              : #endif
   24779              : 
   24780              : /* AMD Athlon works faster
   24781              :    when RET is not destination of conditional jump or directly preceded
   24782              :    by other jump instruction.  We avoid the penalty by inserting NOP just
   24783              :    before the RET instructions in such cases.  */
   24784              : static void
   24785        45192 : ix86_pad_returns (void)
   24786              : {
   24787        45192 :   edge e;
   24788        45192 :   edge_iterator ei;
   24789              : 
   24790        90409 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   24791              :     {
   24792        45217 :       basic_block bb = e->src;
   24793        45217 :       rtx_insn *ret = BB_END (bb);
   24794        45217 :       rtx_insn *prev;
   24795        45217 :       bool replace = false;
   24796              : 
   24797        45207 :       if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
   24798        90424 :           || optimize_bb_for_size_p (bb))
   24799           23 :         continue;
   24800       179989 :       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
   24801       134377 :         if (active_insn_p (prev) || LABEL_P (prev))
   24802              :           break;
   24803        45194 :       if (prev && LABEL_P (prev))
   24804              :         {
   24805           43 :           edge e;
   24806           43 :           edge_iterator ei;
   24807              : 
   24808           56 :           FOR_EACH_EDGE (e, ei, bb->preds)
   24809          146 :             if (EDGE_FREQUENCY (e) && e->src->index >= 0
   24810           97 :                 && !(e->flags & EDGE_FALLTHRU))
   24811              :               {
   24812              :                 replace = true;
   24813              :                 break;
   24814              :               }
   24815              :         }
   24816           43 :       if (!replace)
   24817              :         {
   24818        45158 :           prev = prev_active_insn (ret);
   24819        45158 :           if (prev
   24820        45158 :               && ((JUMP_P (prev) && any_condjump_p (prev))
   24821        44723 :                   || CALL_P (prev)))
   24822              :             replace = true;
   24823              :           /* Empty functions get branch mispredict even when
   24824              :              the jump destination is not visible to us.  */
   24825        45158 :           if (!prev && !optimize_function_for_size_p (cfun))
   24826              :             replace = true;
   24827              :         }
   24828        44740 :       if (replace)
   24829              :         {
   24830          488 :           emit_jump_insn_before (gen_simple_return_internal_long (), ret);
   24831          488 :           delete_insn (ret);
   24832              :         }
   24833              :     }
   24834        45192 : }
   24835              : 
   24836              : /* Count the minimum number of instructions in BB.  Return 4 if the
   24837              :    number of instructions >= 4.  */
   24838              : 
   24839              : static int
   24840           42 : ix86_count_insn_bb (basic_block bb)
   24841              : {
   24842           42 :   rtx_insn *insn;
   24843           42 :   int insn_count = 0;
   24844              : 
   24845              :   /* Count number of instructions in this block.  Return 4 if the number
   24846              :      of instructions >= 4.  */
   24847          296 :   FOR_BB_INSNS (bb, insn)
   24848              :     {
   24849              :       /* Only happen in exit blocks.  */
   24850          290 :       if (JUMP_P (insn)
   24851          290 :           && ANY_RETURN_P (PATTERN (insn)))
   24852              :         break;
   24853              : 
   24854          266 :       if (NONDEBUG_INSN_P (insn)
   24855          102 :           && GET_CODE (PATTERN (insn)) != USE
   24856          350 :           && GET_CODE (PATTERN (insn)) != CLOBBER)
   24857              :         {
   24858           84 :           insn_count++;
   24859           84 :           if (insn_count >= 4)
   24860              :             return insn_count;
   24861              :         }
   24862              :     }
   24863              : 
   24864              :   return insn_count;
   24865              : }
   24866              : 
   24867              : 
   24868              : /* Count the minimum number of instructions in code path in BB.
   24869              :    Return 4 if the number of instructions >= 4.  */
   24870              : 
   24871              : static int
   24872           62 : ix86_count_insn (basic_block bb)
   24873              : {
   24874           62 :   edge e;
   24875           62 :   edge_iterator ei;
   24876           62 :   int min_prev_count;
   24877              : 
   24878              :   /* Only bother counting instructions along paths with no
   24879              :      more than 2 basic blocks between entry and exit.  Given
   24880              :      that BB has an edge to exit, determine if a predecessor
   24881              :      of BB has an edge from entry.  If so, compute the number
   24882              :      of instructions in the predecessor block.  If there
   24883              :      happen to be multiple such blocks, compute the minimum.  */
   24884           62 :   min_prev_count = 4;
   24885          145 :   FOR_EACH_EDGE (e, ei, bb->preds)
   24886              :     {
   24887          109 :       edge prev_e;
   24888          109 :       edge_iterator prev_ei;
   24889              : 
   24890          109 :       if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   24891              :         {
   24892           26 :           min_prev_count = 0;
   24893           26 :           break;
   24894              :         }
   24895          182 :       FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
   24896              :         {
   24897          109 :           if (prev_e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   24898              :             {
   24899           10 :               int count = ix86_count_insn_bb (e->src);
   24900           10 :               if (count < min_prev_count)
   24901           83 :                 min_prev_count = count;
   24902              :               break;
   24903              :             }
   24904              :         }
   24905              :     }
   24906              : 
   24907           62 :   if (min_prev_count < 4)
   24908           32 :     min_prev_count += ix86_count_insn_bb (bb);
   24909              : 
   24910           62 :   return min_prev_count;
   24911              : }
   24912              : 
   24913              : /* Pad short function to 4 instructions.   */
   24914              : 
   24915              : static void
   24916           63 : ix86_pad_short_function (void)
   24917              : {
   24918           63 :   edge e;
   24919           63 :   edge_iterator ei;
   24920              : 
   24921          128 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   24922              :     {
   24923           65 :       rtx_insn *ret = BB_END (e->src);
   24924           65 :       if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
   24925              :         {
   24926           62 :           int insn_count = ix86_count_insn (e->src);
   24927              : 
   24928              :           /* Pad short function.  */
   24929           62 :           if (insn_count < 4)
   24930              :             {
   24931              :               rtx_insn *insn = ret;
   24932              : 
   24933              :               /* Find epilogue.  */
   24934              :               while (insn
   24935           60 :                      && (!NOTE_P (insn)
   24936           26 :                          || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
   24937           37 :                 insn = PREV_INSN (insn);
   24938              : 
   24939           23 :               if (!insn)
   24940            0 :                 insn = ret;
   24941              : 
   24942              :               /* Two NOPs count as one instruction.  */
   24943           23 :               insn_count = 2 * (4 - insn_count);
   24944           23 :               emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
   24945              :             }
   24946              :         }
   24947              :     }
   24948           63 : }
   24949              : 
   24950              : /* Fix up a Windows system unwinder issue.  If an EH region falls through into
   24951              :    the epilogue, the Windows system unwinder will apply epilogue logic and
   24952              :    produce incorrect offsets.  This can be avoided by adding a nop between
   24953              :    the last insn that can throw and the first insn of the epilogue.  */
   24954              : 
   24955              : static void
   24956            0 : ix86_seh_fixup_eh_fallthru (void)
   24957              : {
   24958            0 :   edge e;
   24959            0 :   edge_iterator ei;
   24960              : 
   24961            0 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   24962              :     {
   24963            0 :       rtx_insn *insn, *next;
   24964              : 
   24965              :       /* Find the beginning of the epilogue.  */
   24966            0 :       for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
   24967            0 :         if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
   24968              :           break;
   24969            0 :       if (insn == NULL)
   24970            0 :         continue;
   24971              : 
   24972              :       /* We only care about preceding insns that can throw.  */
   24973            0 :       insn = prev_active_insn (insn);
   24974            0 :       if (insn == NULL || !can_throw_internal (insn))
   24975            0 :         continue;
   24976              : 
   24977              :       /* Do not separate calls from their debug information.  */
   24978            0 :       for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next))
   24979            0 :         if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION)
   24980            0 :           insn = next;
   24981              :         else
   24982              :           break;
   24983              : 
   24984            0 :       emit_insn_after (gen_nops (const1_rtx), insn);
   24985              :     }
   24986            0 : }
   24987              : /* Split vector load from parm_decl to elemental loads to avoid STLF
   24988              :    stalls.  */
   24989              : static void
   24990       983238 : ix86_split_stlf_stall_load ()
   24991              : {
   24992       983238 :   rtx_insn* insn, *start = get_insns ();
   24993       983238 :   unsigned window = 0;
   24994              : 
   24995     27138202 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   24996              :     {
   24997     27137361 :       if (!NONDEBUG_INSN_P (insn))
   24998     15366847 :         continue;
   24999     11770514 :       window++;
   25000              :       /* Insert 64 vaddps %xmm18, %xmm19, %xmm20(no dependence between each
   25001              :          other, just emulate for pipeline) before stalled load, stlf stall
   25002              :          case is as fast as no stall cases on CLX.
   25003              :          Since CFG is freed before machine_reorg, just do a rough
   25004              :          calculation of the window according to the layout.  */
   25005     11770514 :       if (window > (unsigned) x86_stlf_window_ninsns)
   25006              :         return;
   25007              : 
   25008     11752283 :       if (any_uncondjump_p (insn)
   25009     11716252 :           || ANY_RETURN_P (PATTERN (insn))
   25010     23089649 :           || CALL_P (insn))
   25011              :         return;
   25012              : 
   25013     10788117 :       rtx set = single_set (insn);
   25014     10788117 :       if (!set)
   25015       439316 :         continue;
   25016     10348801 :       rtx src = SET_SRC (set);
   25017     20697244 :       if (!MEM_P (src)
   25018              :           /* Only handle V2DFmode load since it doesn't need any scratch
   25019              :              register.  */
   25020      1472794 :           || GET_MODE (src) != E_V2DFmode
   25021         5662 :           || !MEM_EXPR (src)
   25022     10352907 :           || TREE_CODE (get_base_address (MEM_EXPR (src))) != PARM_DECL)
   25023     10348443 :         continue;
   25024              : 
   25025          358 :       rtx zero = CONST0_RTX (V2DFmode);
   25026          358 :       rtx dest = SET_DEST (set);
   25027          358 :       rtx m = adjust_address (src, DFmode, 0);
   25028          358 :       rtx loadlpd = gen_sse2_loadlpd (dest, zero, m);
   25029          358 :       emit_insn_before (loadlpd, insn);
   25030          358 :       m = adjust_address (src, DFmode, 8);
   25031          358 :       rtx loadhpd = gen_sse2_loadhpd (dest, dest, m);
   25032          358 :       if (dump_file && (dump_flags & TDF_DETAILS))
   25033              :         {
   25034            0 :           fputs ("Due to potential STLF stall, split instruction:\n",
   25035              :                  dump_file);
   25036            0 :           print_rtl_single (dump_file, insn);
   25037            0 :           fputs ("To:\n", dump_file);
   25038            0 :           print_rtl_single (dump_file, loadlpd);
   25039            0 :           print_rtl_single (dump_file, loadhpd);
   25040              :         }
   25041          358 :       PATTERN (insn) = loadhpd;
   25042          358 :       INSN_CODE (insn) = -1;
   25043          358 :       gcc_assert (recog_memoized (insn) != -1);
   25044              :     }
   25045              : }
   25046              : 
   25047              : /* Implement machine specific optimizations.  We implement padding of returns
   25048              :    for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window.  */
   25049              : static void
   25050      1493941 : ix86_reorg (void)
   25051              : {
   25052              :   /* We are freeing block_for_insn in the toplev to keep compatibility
   25053              :      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   25054      1493941 :   compute_bb_for_insn ();
   25055              : 
   25056      1493941 :   if (TARGET_SEH && current_function_has_exception_handlers ())
   25057              :     ix86_seh_fixup_eh_fallthru ();
   25058              : 
   25059      1493941 :   if (optimize && optimize_function_for_speed_p (cfun))
   25060              :     {
   25061       985561 :       if (TARGET_SSE2)
   25062       983238 :         ix86_split_stlf_stall_load ();
   25063       985561 :       if (TARGET_PAD_SHORT_FUNCTION)
   25064           63 :         ix86_pad_short_function ();
   25065       985498 :       else if (TARGET_PAD_RETURNS)
   25066        45192 :         ix86_pad_returns ();
   25067              : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   25068       985561 :       if (TARGET_FOUR_JUMP_LIMIT)
   25069        45472 :         ix86_avoid_jump_mispredicts ();
   25070              : #endif
   25071              :     }
   25072      1493941 : }
   25073              : 
   25074              : /* Return nonzero when QImode register that must be represented via REX prefix
   25075              :    is used.  */
   25076              : bool
   25077      8720149 : x86_extended_QIreg_mentioned_p (rtx_insn *insn)
   25078              : {
   25079      8720149 :   int i;
   25080      8720149 :   extract_insn_cached (insn);
   25081     33047129 :   for (i = 0; i < recog_data.n_operands; i++)
   25082      4696962 :     if (GENERAL_REG_P (recog_data.operand[i])
   25083     21834818 :         && !QI_REGNO_P (REGNO (recog_data.operand[i])))
   25084              :        return true;
   25085              :   return false;
   25086              : }
   25087              : 
   25088              : /* Return true when INSN mentions register that must be encoded using REX
   25089              :    prefix.  */
   25090              : bool
   25091    199774093 : x86_extended_reg_mentioned_p (rtx insn)
   25092              : {
   25093    199774093 :   subrtx_iterator::array_type array;
   25094   1044690843 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   25095              :     {
   25096    893549284 :       const_rtx x = *iter;
   25097    893549284 :       if (REG_P (x)
   25098    893549284 :           && (REX_INT_REGNO_P (REGNO (x)) || REX_SSE_REGNO_P (REGNO (x))
   25099    257544522 :               || REX2_INT_REGNO_P (REGNO (x))))
   25100     48632534 :         return true;
   25101              :     }
   25102    151141559 :   return false;
   25103    199774093 : }
   25104              : 
   25105              : /* Return true when INSN mentions register that must be encoded using REX2
   25106              :    prefix.  */
   25107              : bool
   25108      2064731 : x86_extended_rex2reg_mentioned_p (rtx insn)
   25109              : {
   25110      2064731 :   subrtx_iterator::array_type array;
   25111      9590436 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   25112              :     {
   25113      7526362 :       const_rtx x = *iter;
   25114      7526362 :       if (REG_P (x) && REX2_INT_REGNO_P (REGNO (x)))
   25115          657 :         return true;
   25116              :     }
   25117      2064074 :   return false;
   25118      2064731 : }
   25119              : 
   25120              : /* Return true when rtx operands mentions register that must be encoded using
   25121              :    evex prefix.  */
   25122              : bool
   25123           10 : x86_evex_reg_mentioned_p (rtx operands[], int nops)
   25124              : {
   25125           10 :   int i;
   25126           28 :   for (i = 0; i < nops; i++)
   25127           22 :     if (EXT_REX_SSE_REG_P (operands[i])
   25128           40 :         || x86_extended_rex2reg_mentioned_p (operands[i]))
   25129            4 :       return true;
   25130              :   return false;
   25131              : }
   25132              : 
   25133              : /* If profitable, negate (without causing overflow) integer constant
   25134              :    of mode MODE at location LOC.  Return true in this case.  */
   25135              : bool
   25136      5931978 : x86_maybe_negate_const_int (rtx *loc, machine_mode mode)
   25137              : {
   25138      5931978 :   HOST_WIDE_INT val;
   25139              : 
   25140      5931978 :   if (!CONST_INT_P (*loc))
   25141              :     return false;
   25142              : 
   25143      5005332 :   switch (mode)
   25144              :     {
   25145      2862974 :     case E_DImode:
   25146              :       /* DImode x86_64 constants must fit in 32 bits.  */
   25147      2862974 :       gcc_assert (x86_64_immediate_operand (*loc, mode));
   25148              : 
   25149              :       mode = SImode;
   25150              :       break;
   25151              : 
   25152              :     case E_SImode:
   25153              :     case E_HImode:
   25154              :     case E_QImode:
   25155              :       break;
   25156              : 
   25157            0 :     default:
   25158            0 :       gcc_unreachable ();
   25159              :     }
   25160              : 
   25161              :   /* Avoid overflows.  */
   25162      5005332 :   if (mode_signbit_p (mode, *loc))
   25163              :     return false;
   25164              : 
   25165      5004858 :   val = INTVAL (*loc);
   25166              : 
   25167              :   /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
   25168              :      Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
   25169      5004858 :   if ((val < 0 && val != -128)
   25170      3291272 :       || val == 128)
   25171              :     {
   25172      1725097 :       *loc = GEN_INT (-val);
   25173      1725097 :       return true;
   25174              :     }
   25175              : 
   25176              :   return false;
   25177              : }
   25178              : 
   25179              : /* Generate an unsigned DImode/SImode to FP conversion.  This is the same code
   25180              :    optabs would emit if we didn't have TFmode patterns.  */
   25181              : 
   25182              : void
   25183         4585 : x86_emit_floatuns (rtx operands[2])
   25184              : {
   25185         4585 :   rtx_code_label *neglab, *donelab;
   25186         4585 :   rtx i0, i1, f0, in, out;
   25187         4585 :   machine_mode mode, inmode;
   25188              : 
   25189         4585 :   inmode = GET_MODE (operands[1]);
   25190         4585 :   gcc_assert (inmode == SImode || inmode == DImode);
   25191              : 
   25192         4585 :   out = operands[0];
   25193         4585 :   in = force_reg (inmode, operands[1]);
   25194         4585 :   mode = GET_MODE (out);
   25195         4585 :   neglab = gen_label_rtx ();
   25196         4585 :   donelab = gen_label_rtx ();
   25197         4585 :   f0 = gen_reg_rtx (mode);
   25198              : 
   25199         4585 :   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
   25200              : 
   25201         4585 :   expand_float (out, in, 0);
   25202              : 
   25203         4585 :   emit_jump_insn (gen_jump (donelab));
   25204         4585 :   emit_barrier ();
   25205              : 
   25206         4585 :   emit_label (neglab);
   25207              : 
   25208         4585 :   i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
   25209              :                             1, OPTAB_DIRECT);
   25210         4585 :   i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
   25211              :                             1, OPTAB_DIRECT);
   25212         4585 :   i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
   25213              : 
   25214         4585 :   expand_float (f0, i0, 0);
   25215              : 
   25216         4585 :   emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
   25217              : 
   25218         4585 :   emit_label (donelab);
   25219         4585 : }
   25220              : 
   25221              : /* Return the diagnostic message string if conversion from FROMTYPE to
   25222              :    TOTYPE is not allowed, NULL otherwise.  */
   25223              : 
   25224              : static const char *
   25225   1110940074 : ix86_invalid_conversion (const_tree fromtype, const_tree totype)
   25226              : {
   25227   1110940074 :   machine_mode from_mode = element_mode (fromtype);
   25228   1110940074 :   machine_mode to_mode = element_mode (totype);
   25229              : 
   25230   1110940074 :   if (!TARGET_SSE2 && from_mode != to_mode)
   25231              :     {
   25232              :       /* Do no allow conversions to/from BFmode/HFmode scalar types
   25233              :          when TARGET_SSE2 is not available.  */
   25234       468442 :       if (from_mode == BFmode)
   25235              :         return N_("invalid conversion from type %<__bf16%> "
   25236              :                   "without option %<-msse2%>");
   25237       468441 :       if (from_mode == HFmode)
   25238              :         return N_("invalid conversion from type %<_Float16%> "
   25239              :                   "without option %<-msse2%>");
   25240       468441 :       if (to_mode == BFmode)
   25241              :         return N_("invalid conversion to type %<__bf16%> "
   25242              :                   "without option %<-msse2%>");
   25243       468441 :       if (to_mode == HFmode)
   25244              :         return N_("invalid conversion to type %<_Float16%> "
   25245              :                   "without option %<-msse2%>");
   25246              :     }
   25247              : 
   25248              :   /* Warn for silent implicit conversion between __bf16 and short,
   25249              :      since __bfloat16 is refined as real __bf16 instead of short
   25250              :      since GCC13.  */
   25251   1110940072 :   if (element_mode (fromtype) != element_mode (totype)
   25252   1110940072 :       && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
   25253              :     {
   25254              :       /* Warn for silent implicit conversion where user may expect
   25255              :          a bitcast.  */
   25256      7794044 :       if ((TYPE_MODE (fromtype) == BFmode
   25257          279 :            && TYPE_MODE (totype) == HImode)
   25258      7794322 :           || (TYPE_MODE (totype) == BFmode
   25259          423 :               && TYPE_MODE (fromtype) == HImode))
   25260            1 :         warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
   25261              :                 "to real %<__bf16%> since GCC 13.1, be careful of "
   25262              :                  "implicit conversion between %<__bf16%> and %<short%>; "
   25263              :                  "an explicit bitcast may be needed here");
   25264              :     }
   25265              : 
   25266              :   /* Conversion allowed.  */
   25267              :   return NULL;
   25268              : }
   25269              : 
   25270              : /* Return the diagnostic message string if the unary operation OP is
   25271              :    not permitted on TYPE, NULL otherwise.  */
   25272              : 
   25273              : static const char *
   25274     92367153 : ix86_invalid_unary_op (int op, const_tree type)
   25275              : {
   25276     92367153 :   machine_mode mmode = element_mode (type);
   25277              :   /* Reject all single-operand operations on BFmode/HFmode except for &
   25278              :      when TARGET_SSE2 is not available.  */
   25279     92367153 :   if (!TARGET_SSE2 && op != ADDR_EXPR)
   25280              :     {
   25281       111212 :       if (mmode == BFmode)
   25282              :         return N_("operation not permitted on type %<__bf16%> "
   25283              :                   "without option %<-msse2%>");
   25284       111212 :       if (mmode == HFmode)
   25285            0 :         return N_("operation not permitted on type %<_Float16%> "
   25286              :                   "without option %<-msse2%>");
   25287              :     }
   25288              : 
   25289              :   /* Operation allowed.  */
   25290              :   return NULL;
   25291              : }
   25292              : 
   25293              : /* Return the diagnostic message string if the binary operation OP is
   25294              :    not permitted on TYPE1 and TYPE2, NULL otherwise.  */
   25295              : 
   25296              : static const char *
   25297    167576333 : ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
   25298              :                         const_tree type2)
   25299              : {
   25300    167576333 :   machine_mode type1_mode = element_mode (type1);
   25301    167576333 :   machine_mode type2_mode = element_mode (type2);
   25302              :   /* Reject all 2-operand operations on BFmode or HFmode
   25303              :      when TARGET_SSE2 is not available.  */
   25304    167576333 :   if (!TARGET_SSE2)
   25305              :     {
   25306      1009932 :       if (type1_mode == BFmode || type2_mode == BFmode)
   25307              :         return N_("operation not permitted on type %<__bf16%> "
   25308              :                   "without option %<-msse2%>");
   25309              : 
   25310      1009932 :       if (type1_mode == HFmode || type2_mode == HFmode)
   25311            0 :         return N_("operation not permitted on type %<_Float16%> "
   25312              :                   "without option %<-msse2%>");
   25313              :     }
   25314              : 
   25315              :   /* Operation allowed.  */
   25316              :   return NULL;
   25317              : }
   25318              : 
   25319              : 
   25320              : /* Target hook for scalar_mode_supported_p.  */
   25321              : static bool
   25322      4659157 : ix86_scalar_mode_supported_p (scalar_mode mode)
   25323              : {
   25324      4659157 :   if (DECIMAL_FLOAT_MODE_P (mode))
   25325       642450 :     return default_decimal_float_supported_p ();
   25326      4016707 :   else if (mode == TFmode)
   25327              :     return true;
   25328      3688747 :   else if (mode == HFmode || mode == BFmode)
   25329              :     return true;
   25330              :   else
   25331      3034810 :     return default_scalar_mode_supported_p (mode);
   25332              : }
   25333              : 
   25334              : /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE
   25335              :    if MODE is HFmode, and punt to the generic implementation otherwise.  */
   25336              : 
   25337              : static bool
   25338      2252486 : ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode)
   25339              : {
   25340              :   /* NB: Always return TRUE for HFmode so that the _Float16 type will
   25341              :      be defined by the C front-end for AVX512FP16 intrinsics.  We will
   25342              :      issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't
   25343              :      enabled.  */
   25344      1925993 :   return ((mode == HFmode || mode == BFmode)
   25345      3851986 :           ? true
   25346      1599500 :           : default_libgcc_floating_mode_supported_p (mode));
   25347              : }
   25348              : 
   25349              : /* Implements target hook vector_mode_supported_p.  */
   25350              : static bool
   25351   1382422119 : ix86_vector_mode_supported_p (machine_mode mode)
   25352              : {
   25353              :   /* For ia32, scalar TImode isn't supported and so V1TImode shouldn't be
   25354              :      either.  */
   25355   1520827807 :   if (!TARGET_64BIT && GET_MODE_INNER (mode) == TImode)
   25356              :     return false;
   25357   1382421915 :   if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   25358              :     return true;
   25359   1162784582 :   if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   25360              :     return true;
   25361    517584274 :   if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   25362              :     return true;
   25363    376527591 :   if (TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
   25364              :     return true;
   25365    242000568 :   if ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   25366    241938696 :       && VALID_MMX_REG_MODE (mode))
   25367              :     return true;
   25368     35980419 :   if ((TARGET_3DNOW || TARGET_MMX_WITH_SSE)
   25369     35335699 :       && VALID_MMX_REG_MODE_3DNOW (mode))
   25370              :     return true;
   25371     22835301 :   if (mode == V2QImode)
   25372        24855 :     return true;
   25373              :   return false;
   25374              : }
   25375              : 
   25376              : /* Target hook for c_mode_for_suffix.  */
   25377              : static machine_mode
   25378       198365 : ix86_c_mode_for_suffix (char suffix)
   25379              : {
   25380       198365 :   if (suffix == 'q')
   25381              :     return TFmode;
   25382           37 :   if (suffix == 'w')
   25383              :     return XFmode;
   25384              : 
   25385            0 :   return VOIDmode;
   25386              : }
   25387              : 
   25388              : /* Helper function to map common constraints to non-EGPR ones.
   25389              :    All related constraints have h prefix, and h plus Upper letter
   25390              :    means the constraint is strictly EGPR enabled, while h plus
   25391              :    lower letter indicates the constraint is strictly gpr16 only.
   25392              : 
   25393              :    Specially for "g" constraint, split it to rmi as there is
   25394              :    no corresponding general constraint define for backend.
   25395              : 
   25396              :    Here is the full list to map constraints that may involve
   25397              :    gpr to h prefixed.
   25398              : 
   25399              :    "g" -> "jrjmi"
   25400              :    "r" -> "jr"
   25401              :    "m" -> "jm"
   25402              :    "<" -> "j<"
   25403              :    ">" -> "j>"
   25404              :    "o" -> "jo"
   25405              :    "V" -> "jV"
   25406              :    "p" -> "jp"
   25407              :    "Bm" -> "ja"
   25408              : */
   25409              : 
   25410           64 : static void map_egpr_constraints (vec<const char *> &constraints)
   25411              : {
   25412           74 :   for (size_t i = 0; i < constraints.length(); i++)
   25413              :     {
   25414           10 :       const char *cur = constraints[i];
   25415              : 
   25416           10 :       if (startswith (cur, "=@cc"))
   25417            0 :         continue;
   25418              : 
   25419           10 :       int len = strlen (cur);
   25420           10 :       auto_vec<char> buf;
   25421              : 
   25422           24 :       for (int j = 0; j < len; j++)
   25423              :         {
   25424           14 :           switch (cur[j])
   25425              :             {
   25426            2 :             case 'g':
   25427            2 :               buf.safe_push ('j');
   25428            2 :               buf.safe_push ('r');
   25429            2 :               buf.safe_push ('j');
   25430            2 :               buf.safe_push ('m');
   25431            2 :               buf.safe_push ('i');
   25432            2 :               break;
   25433            8 :             case 'r':
   25434            8 :             case 'm':
   25435            8 :             case '<':
   25436            8 :             case '>':
   25437            8 :             case 'o':
   25438            8 :             case 'V':
   25439            8 :             case 'p':
   25440            8 :               buf.safe_push ('j');
   25441            8 :               buf.safe_push (cur[j]);
   25442            8 :               break;
   25443            0 :             case 'B':
   25444            0 :               if (cur[j + 1] == 'm')
   25445              :                 {
   25446            0 :                   buf.safe_push ('j');
   25447            0 :                   buf.safe_push ('a');
   25448            0 :                   j++;
   25449              :                 }
   25450              :               else
   25451              :                 {
   25452            0 :                   buf.safe_push (cur[j]);
   25453            0 :                   buf.safe_push (cur[j + 1]);
   25454            0 :                   j++;
   25455              :                 }
   25456              :               break;
   25457            0 :             case 'T':
   25458            0 :             case 'Y':
   25459            0 :             case 'W':
   25460            0 :             case 'j':
   25461            0 :               buf.safe_push (cur[j]);
   25462            0 :               buf.safe_push (cur[j + 1]);
   25463            0 :               j++;
   25464            0 :               break;
   25465            0 :             case '{':
   25466            0 :               do
   25467              :                 {
   25468            0 :                   buf.safe_push (cur[j]);
   25469            0 :                 } while (cur[j++] != '}');
   25470              :               break;
   25471            4 :             default:
   25472            4 :               buf.safe_push (cur[j]);
   25473            4 :               break;
   25474              :             }
   25475              :         }
   25476           10 :       buf.safe_push ('\0');
   25477           20 :       constraints[i] = xstrdup (buf.address ());
   25478           10 :     }
   25479           64 : }
   25480              : 
   25481              : /* Worker function for TARGET_MD_ASM_ADJUST.
   25482              : 
   25483              :    We implement asm flag outputs, and maintain source compatibility
   25484              :    with the old cc0-based compiler.  */
   25485              : 
   25486              : static rtx_insn *
   25487       109904 : ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
   25488              :                     vec<machine_mode> & /*input_modes*/,
   25489              :                     vec<const char *> &constraints, vec<rtx> &/*uses*/,
   25490              :                     vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
   25491              :                     location_t loc)
   25492              : {
   25493       109904 :   bool saw_asm_flag = false;
   25494              : 
   25495       109904 :   start_sequence ();
   25496              : 
   25497       109904 :   if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
   25498           64 :     map_egpr_constraints (constraints);
   25499              : 
   25500       298760 :   for (unsigned i = 0, n = outputs.length (); i < n; ++i)
   25501              :     {
   25502        79779 :       const char *con = constraints[i];
   25503        79779 :       if (!startswith (con, "=@cc"))
   25504        79691 :         continue;
   25505           88 :       con += 4;
   25506           88 :       if (strchr (con, ',') != NULL)
   25507              :         {
   25508            1 :           error_at (loc, "alternatives not allowed in %<asm%> flag output");
   25509            1 :           continue;
   25510              :         }
   25511              : 
   25512           87 :       bool invert = false;
   25513           87 :       if (con[0] == 'n')
   25514           19 :         invert = true, con++;
   25515              : 
   25516           87 :       machine_mode mode = CCmode;
   25517           87 :       rtx_code code = UNKNOWN;
   25518              : 
   25519           87 :       switch (con[0])
   25520              :         {
   25521           15 :         case 'a':
   25522           15 :           if (con[1] == 0)
   25523              :             mode = CCAmode, code = EQ;
   25524            4 :           else if (con[1] == 'e' && con[2] == 0)
   25525              :             mode = CCCmode, code = NE;
   25526              :           break;
   25527           11 :         case 'b':
   25528           11 :           if (con[1] == 0)
   25529              :             mode = CCCmode, code = EQ;
   25530            6 :           else if (con[1] == 'e' && con[2] == 0)
   25531              :             mode = CCAmode, code = NE;
   25532              :           break;
   25533           14 :         case 'c':
   25534           14 :           if (con[1] == 0)
   25535              :             mode = CCCmode, code = EQ;
   25536              :           break;
   25537            8 :         case 'e':
   25538            8 :           if (con[1] == 0)
   25539              :             mode = CCZmode, code = EQ;
   25540              :           break;
   25541           11 :         case 'g':
   25542           11 :           if (con[1] == 0)
   25543              :             mode = CCGCmode, code = GT;
   25544            5 :           else if (con[1] == 'e' && con[2] == 0)
   25545              :             mode = CCGCmode, code = GE;
   25546              :           break;
   25547           10 :         case 'l':
   25548           10 :           if (con[1] == 0)
   25549              :             mode = CCGCmode, code = LT;
   25550            5 :           else if (con[1] == 'e' && con[2] == 0)
   25551              :             mode = CCGCmode, code = LE;
   25552              :           break;
   25553            4 :         case 'o':
   25554            4 :           if (con[1] == 0)
   25555              :             mode = CCOmode, code = EQ;
   25556              :           break;
   25557            4 :         case 'p':
   25558            4 :           if (con[1] == 0)
   25559              :             mode = CCPmode, code = EQ;
   25560              :           break;
   25561            4 :         case 's':
   25562            4 :           if (con[1] == 0)
   25563              :             mode = CCSmode, code = EQ;
   25564              :           break;
   25565            6 :         case 'z':
   25566            6 :           if (con[1] == 0)
   25567              :             mode = CCZmode, code = EQ;
   25568              :           break;
   25569              :         }
   25570            1 :       if (code == UNKNOWN)
   25571              :         {
   25572            1 :           error_at (loc, "unknown %<asm%> flag output %qs", constraints[i]);
   25573            1 :           continue;
   25574              :         }
   25575           86 :       if (invert)
   25576           19 :         code = reverse_condition (code);
   25577              : 
   25578           86 :       rtx dest = outputs[i];
   25579           86 :       if (!saw_asm_flag)
   25580              :         {
   25581              :           /* This is the first asm flag output.  Here we put the flags
   25582              :              register in as the real output and adjust the condition to
   25583              :              allow it.  */
   25584           75 :           constraints[i] = "=Bf";
   25585           75 :           outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG);
   25586           75 :           saw_asm_flag = true;
   25587              :         }
   25588              :       else
   25589              :         {
   25590              :           /* We don't need the flags register as output twice.  */
   25591           11 :           constraints[i] = "=X";
   25592           11 :           outputs[i] = gen_rtx_SCRATCH (SImode);
   25593              :         }
   25594              : 
   25595           86 :       rtx x = gen_rtx_REG (mode, FLAGS_REG);
   25596           86 :       x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx);
   25597              : 
   25598           86 :       machine_mode dest_mode = GET_MODE (dest);
   25599           86 :       if (!SCALAR_INT_MODE_P (dest_mode))
   25600              :         {
   25601            3 :           error_at (loc, "invalid type for %<asm%> flag output");
   25602            3 :           continue;
   25603              :         }
   25604              : 
   25605           83 :       if (dest_mode == QImode)
   25606           73 :         emit_insn (gen_rtx_SET (dest, x));
   25607              :       else
   25608              :         {
   25609           10 :           rtx reg = gen_reg_rtx (QImode);
   25610           10 :           emit_insn (gen_rtx_SET (reg, x));
   25611              : 
   25612           10 :           reg = convert_to_mode (dest_mode, reg, 1);
   25613           10 :           emit_move_insn (dest, reg);
   25614              :         }
   25615              :     }
   25616              : 
   25617       109904 :   rtx_insn *seq = end_sequence ();
   25618              : 
   25619       109904 :   if (saw_asm_flag)
   25620              :     return seq;
   25621              :   else
   25622              :     {
   25623              :       /* If we had no asm flag outputs, clobber the flags.  */
   25624       109829 :       clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG));
   25625       109829 :       SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG);
   25626       109829 :       return NULL;
   25627              :     }
   25628              : }
   25629              : 
   25630              : /* Implements target vector targetm.asm.encode_section_info.  */
   25631              : 
   25632              : static void ATTRIBUTE_UNUSED
   25633     10000453 : ix86_encode_section_info (tree decl, rtx rtl, int first)
   25634              : {
   25635     10000453 :   default_encode_section_info (decl, rtl, first);
   25636              : 
   25637     10000453 :   if (ix86_in_large_data_p (decl))
   25638           32 :     SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
   25639     10000453 : }
   25640              : 
   25641              : /* Worker function for REVERSE_CONDITION.  */
   25642              : 
   25643              : enum rtx_code
   25644     32028255 : ix86_reverse_condition (enum rtx_code code, machine_mode mode)
   25645              : {
   25646     32028255 :   return (mode == CCFPmode
   25647     32028255 :           ? reverse_condition_maybe_unordered (code)
   25648     27599963 :           : reverse_condition (code));
   25649              : }
   25650              : 
   25651              : /* Output code to perform an x87 FP register move, from OPERANDS[1]
   25652              :    to OPERANDS[0].  */
   25653              : 
   25654              : const char *
   25655       653003 : output_387_reg_move (rtx_insn *insn, rtx *operands)
   25656              : {
   25657       653003 :   if (REG_P (operands[0]))
   25658              :     {
   25659       547000 :       if (REG_P (operands[1])
   25660       547000 :           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   25661              :         {
   25662       292486 :           if (REGNO (operands[0]) == FIRST_STACK_REG)
   25663       274567 :             return output_387_ffreep (operands, 0);
   25664              :           return "fstp\t%y0";
   25665              :         }
   25666       254514 :       if (STACK_TOP_P (operands[0]))
   25667       254514 :         return "fld%Z1\t%y1";
   25668              :       return "fst\t%y0";
   25669              :     }
   25670       106003 :   else if (MEM_P (operands[0]))
   25671              :     {
   25672       106003 :       gcc_assert (REG_P (operands[1]));
   25673       106003 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   25674              :         return "fstp%Z0\t%y0";
   25675              :       else
   25676              :         {
   25677              :           /* There is no non-popping store to memory for XFmode.
   25678              :              So if we need one, follow the store with a load.  */
   25679         6258 :           if (GET_MODE (operands[0]) == XFmode)
   25680              :             return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
   25681              :           else
   25682         1921 :             return "fst%Z0\t%y0";
   25683              :         }
   25684              :     }
   25685              :   else
   25686            0 :     gcc_unreachable();
   25687              : }
   25688              : #ifdef TARGET_SOLARIS
   25689              : /* Solaris implementation of TARGET_ASM_NAMED_SECTION.  */
   25690              : 
   25691              : static void
   25692              : i386_solaris_elf_named_section (const char *name, unsigned int flags,
   25693              :                                 tree decl)
   25694              : {
   25695              :   /* With Binutils 2.15, the "@unwind" marker must be specified on
   25696              :      every occurrence of the ".eh_frame" section, not just the first
   25697              :      one.  */
   25698              :   if (TARGET_64BIT
   25699              :       && strcmp (name, ".eh_frame") == 0)
   25700              :     {
   25701              :       fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
   25702              :                flags & SECTION_WRITE ? "aw" : "a");
   25703              :       return;
   25704              :     }
   25705              : 
   25706              : #if HAVE_SOLARIS_AS
   25707              :   if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
   25708              :     {
   25709              :       solaris_elf_asm_comdat_section (name, flags, decl);
   25710              :       return;
   25711              :     }
   25712              : 
   25713              :   /* Solaris/x86 as uses the same syntax for the SHF_EXCLUDE flags as the
   25714              :      SPARC assembler.  One cannot mix single-letter flags and #exclude, so
   25715              :      only emit the latter here.  */
   25716              :   if (flags & SECTION_EXCLUDE)
   25717              :     {
   25718              :       fprintf (asm_out_file, "\t.section\t%s,#exclude\n", name);
   25719              :       return;
   25720              :     }
   25721              : #endif
   25722              : 
   25723              :   default_elf_asm_named_section (name, flags, decl);
   25724              : }
   25725              : #endif /* TARGET_SOLARIS */
   25726              : 
   25727              : /* Return the mangling of TYPE if it is an extended fundamental type.  */
   25728              : 
   25729              : static const char *
   25730   1084487097 : ix86_mangle_type (const_tree type)
   25731              : {
   25732   1084487097 :   type = TYPE_MAIN_VARIANT (type);
   25733              : 
   25734   1084487097 :   if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
   25735              :       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
   25736              :     return NULL;
   25737              : 
   25738    588390499 :   if (type == float128_type_node || type == float64x_type_node)
   25739              :     return NULL;
   25740              : 
   25741    587603200 :   switch (TYPE_MODE (type))
   25742              :     {
   25743              :     case E_BFmode:
   25744              :       return "DF16b";
   25745       459409 :     case E_HFmode:
   25746              :       /* _Float16 is "DF16_".
   25747              :          Align with clang's decision in https://reviews.llvm.org/D33719. */
   25748       459409 :       return "DF16_";
   25749       681659 :     case E_TFmode:
   25750              :       /* __float128 is "g".  */
   25751       681659 :       return "g";
   25752      8081689 :     case E_XFmode:
   25753              :       /* "long double" or __float80 is "e".  */
   25754      8081689 :       return "e";
   25755              :     default:
   25756              :       return NULL;
   25757              :     }
   25758              : }
   25759              : 
   25760              : /* Create C++ tinfo symbols for only conditionally available fundamental
   25761              :    types.  */
   25762              : 
   25763              : static void
   25764            5 : ix86_emit_support_tinfos (emit_support_tinfos_callback callback)
   25765              : {
   25766            5 :   extern tree ix86_float16_type_node;
   25767            5 :   extern tree ix86_bf16_type_node;
   25768              : 
   25769            5 :   if (!TARGET_SSE2)
   25770              :     {
   25771            0 :       if (!float16_type_node)
   25772            0 :         float16_type_node = ix86_float16_type_node;
   25773            0 :       if (!bfloat16_type_node)
   25774            0 :         bfloat16_type_node = ix86_bf16_type_node;
   25775            0 :       callback (float16_type_node);
   25776            0 :       callback (bfloat16_type_node);
   25777            0 :       float16_type_node = NULL_TREE;
   25778            0 :       bfloat16_type_node = NULL_TREE;
   25779              :     }
   25780            5 : }
   25781              : 
   25782              : static GTY(()) tree ix86_tls_stack_chk_guard_decl;
   25783              : 
   25784              : static tree
   25785          338 : ix86_stack_protect_guard (void)
   25786              : {
   25787          338 :   if (TARGET_SSP_TLS_GUARD)
   25788              :     {
   25789          263 :       tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
   25790          263 :       int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg);
   25791          263 :       tree type = build_qualified_type (type_node, qual);
   25792          263 :       tree t;
   25793              : 
   25794          263 :       if (OPTION_SET_P (ix86_stack_protector_guard_symbol_str))
   25795              :         {
   25796            1 :           t = ix86_tls_stack_chk_guard_decl;
   25797              : 
   25798            1 :           if (t == NULL)
   25799              :             {
   25800            1 :               rtx x;
   25801              : 
   25802            1 :               t = build_decl
   25803            1 :                 (UNKNOWN_LOCATION, VAR_DECL,
   25804              :                  get_identifier (ix86_stack_protector_guard_symbol_str),
   25805              :                  type);
   25806            1 :               TREE_STATIC (t) = 1;
   25807            1 :               TREE_PUBLIC (t) = 1;
   25808            1 :               DECL_EXTERNAL (t) = 1;
   25809            1 :               TREE_USED (t) = 1;
   25810            1 :               TREE_THIS_VOLATILE (t) = 1;
   25811            1 :               DECL_ARTIFICIAL (t) = 1;
   25812            1 :               DECL_IGNORED_P (t) = 1;
   25813              : 
   25814              :               /* Do not share RTL as the declaration is visible outside of
   25815              :                  current function.  */
   25816            1 :               x = DECL_RTL (t);
   25817            1 :               RTX_FLAG (x, used) = 1;
   25818              : 
   25819            1 :               ix86_tls_stack_chk_guard_decl = t;
   25820              :             }
   25821              :         }
   25822              :       else
   25823              :         {
   25824          262 :           tree asptrtype = build_pointer_type (type);
   25825              : 
   25826          262 :           t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset);
   25827          262 :           t = build2 (MEM_REF, asptrtype, t,
   25828              :                       build_int_cst (asptrtype, 0));
   25829          262 :           TREE_THIS_VOLATILE (t) = 1;
   25830              :         }
   25831              : 
   25832          263 :       return t;
   25833              :     }
   25834              : 
   25835           75 :   return default_stack_protect_guard ();
   25836              : }
   25837              : 
   25838              : /* Implement TARGET_STACK_PROTECT_GUARD_SYMBOL_P.  */
   25839              : 
   25840              : static bool
   25841       207986 : ix86_stack_protect_guard_symbol_p (void)
   25842              : {
   25843       207986 :   return TARGET_SSP_GLOBAL_GUARD;
   25844              : }
   25845              : 
   25846              : static bool
   25847          930 : ix86_stack_protect_runtime_enabled_p (void)
   25848              : {
   25849              :   /* Naked functions should not enable stack protector.  */
   25850          930 :   return !ix86_function_naked (current_function_decl);
   25851              : }
   25852              : 
   25853              : /* For 32-bit code we can save PIC register setup by using
   25854              :    __stack_chk_fail_local hidden function instead of calling
   25855              :    __stack_chk_fail directly.  64-bit code doesn't need to setup any PIC
   25856              :    register, so it is better to call __stack_chk_fail directly.  */
   25857              : 
   25858              : static tree ATTRIBUTE_UNUSED
   25859          331 : ix86_stack_protect_fail (void)
   25860              : {
   25861          331 :   return TARGET_64BIT
   25862          331 :          ? default_external_stack_protect_fail ()
   25863            1 :          : default_hidden_stack_protect_fail ();
   25864              : }
   25865              : 
   25866              : /* Select a format to encode pointers in exception handling data.  CODE
   25867              :    is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
   25868              :    true if the symbol may be affected by dynamic relocations.
   25869              : 
   25870              :    ??? All x86 object file formats are capable of representing this.
   25871              :    After all, the relocation needed is the same as for the call insn.
   25872              :    Whether or not a particular assembler allows us to enter such, I
   25873              :    guess we'll have to see.  */
   25874              : 
   25875              : int
   25876       800244 : asm_preferred_eh_data_format (int code, int global)
   25877              : {
   25878              :   /* PE-COFF is effectively always -fPIC because of the .reloc section.  */
   25879       800244 :   if (flag_pic || TARGET_PECOFF || !ix86_direct_extern_access)
   25880              :     {
   25881        38421 :       int type = DW_EH_PE_sdata8;
   25882        38421 :       if (ptr_mode == SImode
   25883        24442 :           || ix86_cmodel == CM_SMALL_PIC
   25884        38507 :           || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
   25885              :         type = DW_EH_PE_sdata4;
   25886        53858 :       return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
   25887              :     }
   25888              : 
   25889       761823 :   if (ix86_cmodel == CM_SMALL
   25890        18670 :       || (ix86_cmodel == CM_MEDIUM && code))
   25891       743166 :     return DW_EH_PE_udata4;
   25892              : 
   25893              :   return DW_EH_PE_absptr;
   25894              : }
   25895              : 
   25896              : /* Cost of constructing or destructing a vector in VECMODE from/to elements
   25897              :    of ELMODE.  */
   25898              : static int
   25899       783658 : ix86_vector_cd_cost (machine_mode vecmode, machine_mode elmode)
   25900              : {
   25901      1567316 :   if (GET_MODE_BITSIZE (vecmode) < 128)
   25902       543084 :     return ((GET_MODE_BITSIZE (vecmode) / GET_MODE_BITSIZE (elmode) - 1)
   25903       271542 :             * ix86_cost->sse_op);
   25904              : 
   25905       512116 :   int n = GET_MODE_BITSIZE (vecmode) / 128;
   25906       512116 :   int cost = 0;
   25907              :   /* Element inserts/extracts into/from N SSE vectors, the possible
   25908              :      GPR <-> XMM moves have to be accounted for elsewhere.  */
   25909      1024232 :   if (GET_MODE_BITSIZE (elmode) < 128)
   25910      1022986 :     cost += n * (128 / GET_MODE_BITSIZE (elmode) - 1) * ix86_cost->sse_op;
   25911       512116 :   if (GET_MODE_BITSIZE (vecmode) >= 256
   25912       521858 :       && GET_MODE_BITSIZE (elmode) < 256)
   25913              :     /* N/2 vinserti128/vextracti128 for SSE <-> AVX256.  */
   25914         9742 :     cost += n * ix86_vec_cost (V32QImode, ix86_cost->sse_op) / 2;
   25915      1024232 :   if (GET_MODE_BITSIZE (vecmode) == 512)
   25916              :     /* One vinserti64x4/vextracti64x4 for AVX256 <-> AVX512.  */
   25917         1968 :     cost += ix86_vec_cost (vecmode, ix86_cost->sse_op);
   25918              :   return cost;
   25919              : }
   25920              : 
   25921              : /* Worker for ix86_builtin_vectorization_cost and the fallback calls
   25922              :    from ix86_vector_costs::add_stmt_cost.  */
   25923              : static int
   25924     15608553 : ix86_default_vector_cost (enum vect_cost_for_stmt type_of_cost,
   25925              :                           machine_mode mode)
   25926              : {
   25927     15608553 :   bool fp = FLOAT_MODE_P (mode);
   25928     15608553 :   int index;
   25929     15608553 :   switch (type_of_cost)
   25930              :     {
   25931      1858382 :       case scalar_stmt:
   25932      1858382 :         return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
   25933              : 
   25934      1859087 :       case scalar_load:
   25935              :         /* load/store costs are relative to register move which is 2. Recompute
   25936              :            it to COSTS_N_INSNS so everything have same base.  */
   25937      3718174 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_load[0]
   25938      1859087 :                               : ix86_cost->int_load [2]) / 2;
   25939              : 
   25940      4007184 :       case scalar_store:
   25941      8014368 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_store[0]
   25942      4007184 :                               : ix86_cost->int_store [2]) / 2;
   25943              : 
   25944      1119843 :       case vector_stmt:
   25945      2239686 :         return ix86_vec_cost (mode,
   25946      2239686 :                               fp ? ix86_cost->addss : ix86_cost->sse_op);
   25947              : 
   25948      2000676 :       case vector_load:
   25949      2000676 :         index = sse_store_index (mode);
   25950              :         /* See PR82713 - we may end up being called on non-vector type.  */
   25951      2000676 :         if (index < 0)
   25952       102116 :           index = 2;
   25953      2000676 :         return COSTS_N_INSNS (ix86_cost->sse_load[index]) / 2;
   25954              : 
   25955       997284 :       case vector_store:
   25956       997284 :         index = sse_store_index (mode);
   25957              :         /* See PR82713 - we may end up being called on non-vector type.  */
   25958       997284 :         if (index < 0)
   25959        92657 :           index = 2;
   25960       997284 :         return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
   25961              : 
   25962       874628 :       case vec_to_scalar:
   25963       874628 :       case scalar_to_vec:
   25964       874628 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   25965              : 
   25966              :       /* We should have separate costs for unaligned loads and gather/scatter.
   25967              :          Do that incrementally.  */
   25968       526886 :       case unaligned_load:
   25969       526886 :         index = sse_store_index (mode);
   25970              :         /* See PR82713 - we may end up being called on non-vector type.  */
   25971       526886 :         if (index < 0)
   25972         3337 :           index = 2;
   25973       526886 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_load[index]) / 2;
   25974              : 
   25975       850787 :       case unaligned_store:
   25976       850787 :         index = sse_store_index (mode);
   25977              :         /* See PR82713 - we may end up being called on non-vector type.  */
   25978       850787 :         if (index < 0)
   25979        17250 :           index = 2;
   25980       850787 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_store[index]) / 2;
   25981              : 
   25982            0 :       case vector_gather_load:
   25983            0 :         return ix86_vec_cost (mode,
   25984            0 :                               COSTS_N_INSNS
   25985              :                                  (ix86_cost->gather_static
   25986              :                                   + ix86_cost->gather_per_elt
   25987            0 :                                     * GET_MODE_NUNITS (mode)) / 2);
   25988              : 
   25989            0 :       case vector_scatter_store:
   25990            0 :         return ix86_vec_cost (mode,
   25991            0 :                               COSTS_N_INSNS
   25992              :                                  (ix86_cost->scatter_static
   25993              :                                   + ix86_cost->scatter_per_elt
   25994            0 :                                     * GET_MODE_NUNITS (mode)) / 2);
   25995              : 
   25996       364109 :       case cond_branch_taken:
   25997       364109 :         return ix86_cost->cond_taken_branch_cost;
   25998              : 
   25999         8614 :       case cond_branch_not_taken:
   26000         8614 :         return ix86_cost->cond_not_taken_branch_cost;
   26001              : 
   26002       299585 :       case vec_perm:
   26003       299585 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   26004              : 
   26005        90305 :       case vec_promote_demote:
   26006        90305 :         if (fp)
   26007        11739 :           return vec_fp_conversion_cost (ix86_tune_cost, mode);
   26008        78566 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   26009              : 
   26010       751183 :       case vec_construct:
   26011       751183 :       case vec_deconstruct:
   26012      1502366 :         return ix86_vector_cd_cost (mode, GET_MODE_INNER (mode));
   26013              : 
   26014            0 :       default:
   26015            0 :         gcc_unreachable ();
   26016              :     }
   26017              : }
   26018              : 
   26019              : /* Implement targetm.vectorize.builtin_vectorization_cost.  */
   26020              : static int
   26021      9314298 : ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
   26022              :                                  tree vectype, int)
   26023              : {
   26024      9314298 :   machine_mode mode = TImode;
   26025      9314298 :   if (vectype != NULL)
   26026      5846576 :     mode = TYPE_MODE (vectype);
   26027      9314298 :   return ix86_default_vector_cost (type_of_cost, mode);
   26028              : }
   26029              : 
   26030              : 
   26031              : /* This function returns the calling abi specific va_list type node.
   26032              :    It returns  the FNDECL specific va_list type.  */
   26033              : 
   26034              : static tree
   26035        47729 : ix86_fn_abi_va_list (tree fndecl)
   26036              : {
   26037        47729 :   if (!TARGET_64BIT)
   26038          726 :     return va_list_type_node;
   26039        47003 :   gcc_assert (fndecl != NULL_TREE);
   26040              : 
   26041        47003 :   if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
   26042        12880 :     return ms_va_list_type_node;
   26043              :   else
   26044        34123 :     return sysv_va_list_type_node;
   26045              : }
   26046              : 
   26047              : /* Returns the canonical va_list type specified by TYPE. If there
   26048              :    is no valid TYPE provided, it return NULL_TREE.  */
   26049              : 
   26050              : static tree
   26051       247454 : ix86_canonical_va_list_type (tree type)
   26052              : {
   26053       247454 :   if (TARGET_64BIT)
   26054              :     {
   26055       246952 :       if (lookup_attribute ("ms_abi va_list", TYPE_ATTRIBUTES (type)))
   26056         5948 :         return ms_va_list_type_node;
   26057              : 
   26058       241004 :       if ((TREE_CODE (type) == ARRAY_TYPE
   26059        50138 :            && integer_zerop (array_type_nelts_minus_one (type)))
   26060       241004 :           || POINTER_TYPE_P (type))
   26061              :         {
   26062       188964 :           tree elem_type = TREE_TYPE (type);
   26063       188964 :           if (TREE_CODE (elem_type) == RECORD_TYPE
   26064       340996 :               && lookup_attribute ("sysv_abi va_list",
   26065       152032 :                                    TYPE_ATTRIBUTES (elem_type)))
   26066       152032 :             return sysv_va_list_type_node;
   26067              :         }
   26068              : 
   26069        88972 :       return NULL_TREE;
   26070              :     }
   26071              : 
   26072          502 :   return std_canonical_va_list_type (type);
   26073              : }
   26074              : 
   26075              : /* Iterate through the target-specific builtin types for va_list.
   26076              :    IDX denotes the iterator, *PTREE is set to the result type of
   26077              :    the va_list builtin, and *PNAME to its internal type.
   26078              :    Returns zero if there is no element for this index, otherwise
   26079              :    IDX should be increased upon the next call.
   26080              :    Note, do not iterate a base builtin's name like __builtin_va_list.
   26081              :    Used from c_common_nodes_and_builtins.  */
   26082              : 
   26083              : static int
   26084       630576 : ix86_enum_va_list (int idx, const char **pname, tree *ptree)
   26085              : {
   26086       630576 :   if (TARGET_64BIT)
   26087              :     {
   26088       625200 :       switch (idx)
   26089              :         {
   26090              :         default:
   26091              :           break;
   26092              : 
   26093       208400 :         case 0:
   26094       208400 :           *ptree = ms_va_list_type_node;
   26095       208400 :           *pname = "__builtin_ms_va_list";
   26096       208400 :           return 1;
   26097              : 
   26098       208400 :         case 1:
   26099       208400 :           *ptree = sysv_va_list_type_node;
   26100       208400 :           *pname = "__builtin_sysv_va_list";
   26101       208400 :           return 1;
   26102              :         }
   26103              :     }
   26104              : 
   26105              :   return 0;
   26106              : }
   26107              : 
   26108              : #undef TARGET_SCHED_DISPATCH
   26109              : #define TARGET_SCHED_DISPATCH ix86_bd_has_dispatch
   26110              : #undef TARGET_SCHED_DISPATCH_DO
   26111              : #define TARGET_SCHED_DISPATCH_DO ix86_bd_do_dispatch
   26112              : #undef TARGET_SCHED_REASSOCIATION_WIDTH
   26113              : #define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
   26114              : #undef TARGET_SCHED_REORDER
   26115              : #define TARGET_SCHED_REORDER ix86_atom_sched_reorder
   26116              : #undef TARGET_SCHED_ADJUST_PRIORITY
   26117              : #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
   26118              : #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
   26119              : #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
   26120              :   ix86_dependencies_evaluation_hook
   26121              : 
   26122              : 
   26123              : /* Implementation of reassociation_width target hook used by
   26124              :    reassoc phase to identify parallelism level in reassociated
   26125              :    tree.  Statements tree_code is passed in OPC.  Arguments type
   26126              :    is passed in MODE.  */
   26127              : 
   26128              : static int
   26129        28951 : ix86_reassociation_width (tree_code op, machine_mode mode)
   26130              : {
   26131        28951 :   int width = 1;
   26132              :   /* Vector part.  */
   26133        28951 :   if (VECTOR_MODE_P (mode))
   26134              :     {
   26135         8745 :       int div = 1;
   26136         8745 :       if (INTEGRAL_MODE_P (mode))
   26137         2824 :         width = ix86_cost->reassoc_vec_int;
   26138         5921 :       else if (FLOAT_MODE_P (mode))
   26139         5921 :         width = ix86_cost->reassoc_vec_fp;
   26140              : 
   26141         8745 :       if (width == 1)
   26142              :         return 1;
   26143              : 
   26144              :       /* Znver1-4 Integer vector instructions execute in FP unit
   26145              :          and can execute 3 additions and one multiplication per cycle.  */
   26146         8740 :       if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2
   26147         8740 :            || ix86_tune == PROCESSOR_ZNVER3 || ix86_tune == PROCESSOR_ZNVER4
   26148         8740 :            || ix86_tune == PROCESSOR_C86_4G_M4
   26149         8740 :            || ix86_tune == PROCESSOR_C86_4G_M6
   26150         8740 :            || ix86_tune == PROCESSOR_C86_4G_M7
   26151         8738 :            || ix86_tune == PROCESSOR_C86_4G_M8)
   26152            2 :           && INTEGRAL_MODE_P (mode) && op != PLUS_EXPR && op != MINUS_EXPR)
   26153              :         return 1;
   26154              :       /* Znver5 can do 2 integer multiplications per cycle with latency
   26155              :          of 3.  */
   26156         8740 :       if ((ix86_tune == PROCESSOR_ZNVER5 || ix86_tune == PROCESSOR_ZNVER6)
   26157            0 :           && INTEGRAL_MODE_P (mode) && op != PLUS_EXPR && op != MINUS_EXPR)
   26158         8740 :         width = 6;
   26159              : 
   26160              :       /* Account for targets that splits wide vectors into multiple parts.  */
   26161         8742 :       if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 256)
   26162            0 :         div = GET_MODE_BITSIZE (mode) / 256;
   26163         8740 :       else if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 128)
   26164            0 :         div = GET_MODE_BITSIZE (mode) / 128;
   26165         8740 :       else if (TARGET_SSE_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 64)
   26166            0 :         div = GET_MODE_BITSIZE (mode) / 64;
   26167         8740 :       width = (width + div - 1) / div;
   26168         8740 :     }
   26169              :   /* Scalar part.  */
   26170              :   else if (INTEGRAL_MODE_P (mode))
   26171        14602 :     width = ix86_cost->reassoc_int;
   26172              :   else if (FLOAT_MODE_P (mode))
   26173         5604 :     width = ix86_cost->reassoc_fp;
   26174              : 
   26175              :   /* Avoid using too many registers in 32bit mode.  */
   26176        28946 :   if (!TARGET_64BIT && width > 2)
   26177        28951 :     width = 2;
   26178              :   return width;
   26179              : }
   26180              : 
   26181              : /* ??? No autovectorization into MMX or 3DNOW until we can reliably
   26182              :    place emms and femms instructions.  */
   26183              : 
   26184              : static machine_mode
   26185      5334994 : ix86_preferred_simd_mode (scalar_mode mode)
   26186              : {
   26187      5334994 :   if (!TARGET_SSE)
   26188          873 :     return word_mode;
   26189              : 
   26190      5334121 :   switch (mode)
   26191              :     {
   26192       432748 :     case E_QImode:
   26193       432748 :       if (TARGET_AVX512BW && !TARGET_PREFER_AVX256)
   26194              :         return V64QImode;
   26195       420202 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26196              :         return V32QImode;
   26197              :       else
   26198       400527 :         return V16QImode;
   26199              : 
   26200       210029 :     case E_HImode:
   26201       210029 :       if (TARGET_AVX512BW && !TARGET_PREFER_AVX256)
   26202              :         return V32HImode;
   26203       199505 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26204              :         return V16HImode;
   26205              :       else
   26206       183501 :         return V8HImode;
   26207              : 
   26208      1584712 :     case E_SImode:
   26209      1584712 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26210              :         return V16SImode;
   26211      1517065 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26212              :         return V8SImode;
   26213              :       else
   26214      1363976 :         return V4SImode;
   26215              : 
   26216      1930400 :     case E_DImode:
   26217      1930400 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26218              :         return V8DImode;
   26219      1526247 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26220              :         return V4DImode;
   26221              :       else
   26222      1464194 :         return V2DImode;
   26223              : 
   26224       144909 :     case E_HFmode:
   26225       144909 :       if (TARGET_AVX512FP16)
   26226              :         {
   26227       141978 :           if (TARGET_AVX512VL)
   26228              :             {
   26229        69102 :               if (TARGET_PREFER_AVX128)
   26230              :                 return V8HFmode;
   26231        68880 :               else if (TARGET_PREFER_AVX256)
   26232              :                 return V16HFmode;
   26233              :             }
   26234       139646 :           return V32HFmode;
   26235              :         }
   26236         2931 :       return word_mode;
   26237              : 
   26238        62952 :     case E_BFmode:
   26239        62952 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26240              :         return V32BFmode;
   26241        26492 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26242              :         return V16BFmode;
   26243              :       else
   26244        13489 :         return V8BFmode;
   26245              : 
   26246       629769 :     case E_SFmode:
   26247       629769 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26248              :         return V16SFmode;
   26249       429091 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26250              :         return V8SFmode;
   26251              :       else
   26252       362483 :         return V4SFmode;
   26253              : 
   26254       299696 :     case E_DFmode:
   26255       299696 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26256              :         return V8DFmode;
   26257       178442 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26258              :         return V4DFmode;
   26259       124921 :       else if (TARGET_SSE2)
   26260              :         return V2DFmode;
   26261              :       /* FALLTHRU */
   26262              : 
   26263        38962 :     default:
   26264        38962 :       return word_mode;
   26265              :     }
   26266              : }
   26267              : 
   26268              : /* If AVX is enabled then try vectorizing with both 256bit and 128bit
   26269              :    vectors.  If AVX512F is enabled then try vectorizing with 512bit,
   26270              :    256bit and 128bit vectors.  */
   26271              : 
   26272              : static unsigned int
   26273      2215508 : ix86_autovectorize_vector_modes (vector_modes *modes, bool all)
   26274              : {
   26275      2215508 :   if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26276              :     {
   26277        74942 :       modes->safe_push (V64QImode);
   26278        74942 :       modes->safe_push (V32QImode);
   26279        74942 :       modes->safe_push (V16QImode);
   26280              :     }
   26281      2140566 :   else if (TARGET_AVX512F && all)
   26282              :     {
   26283          574 :       modes->safe_push (V32QImode);
   26284          574 :       modes->safe_push (V16QImode);
   26285          574 :       modes->safe_push (V64QImode);
   26286              :     }
   26287      2139992 :   else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26288              :     {
   26289        28734 :       modes->safe_push (V32QImode);
   26290        28734 :       modes->safe_push (V16QImode);
   26291              :     }
   26292      2111258 :   else if (TARGET_AVX && all)
   26293              :     {
   26294           24 :       modes->safe_push (V16QImode);
   26295           24 :       modes->safe_push (V32QImode);
   26296              :     }
   26297      2111234 :   else if (TARGET_SSE2)
   26298      2108946 :     modes->safe_push (V16QImode);
   26299              : 
   26300      2215508 :   if (TARGET_MMX_WITH_SSE)
   26301      1818722 :     modes->safe_push (V8QImode);
   26302              : 
   26303      2215508 :   if (TARGET_SSE2)
   26304      2213220 :     modes->safe_push (V4QImode);
   26305              : 
   26306      2215508 :   return ix86_vect_compare_costs ? VECT_COMPARE_COSTS : 0;
   26307              : }
   26308              : 
   26309              : /* Implementation of targetm.vectorize.get_mask_mode.  */
   26310              : 
   26311              : static opt_machine_mode
   26312      3593869 : ix86_get_mask_mode (machine_mode data_mode)
   26313              : {
   26314      3593869 :   unsigned vector_size = GET_MODE_SIZE (data_mode);
   26315      3593869 :   unsigned nunits = GET_MODE_NUNITS (data_mode);
   26316      3593869 :   unsigned elem_size = vector_size / nunits;
   26317              : 
   26318              :   /* Scalar mask case.  */
   26319       484748 :   if ((TARGET_AVX512F && vector_size == 64)
   26320      3477280 :       || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
   26321              :       /* AVX512FP16 only supports vector comparison
   26322              :          to kmask for _Float16.  */
   26323      3301229 :       || (TARGET_AVX512VL && TARGET_AVX512FP16
   26324        18432 :           && GET_MODE_INNER (data_mode) == E_HFmode)
   26325      6899858 :       || (TARGET_AVX10_2 && GET_MODE_INNER (data_mode) == E_BFmode))
   26326              :     {
   26327       295664 :       if (elem_size == 4
   26328       295664 :           || elem_size == 8
   26329       136171 :           || (TARGET_AVX512BW && (elem_size == 1 || elem_size == 2)))
   26330       264418 :         return smallest_int_mode_for_size (nunits).require ();
   26331              :     }
   26332              : 
   26333      3329451 :   scalar_int_mode elem_mode
   26334      3329451 :     = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT).require ();
   26335              : 
   26336      3329451 :   gcc_assert (elem_size * nunits == vector_size);
   26337              : 
   26338      3329451 :   return mode_for_vector (elem_mode, nunits);
   26339              : }
   26340              : 
   26341              : 
   26342              : 
   26343              : /* Return class of registers which could be used for pseudo of MODE
   26344              :    and of class RCLASS for spilling instead of memory.  Return NO_REGS
   26345              :    if it is not possible or non-profitable.  */
   26346              : 
   26347              : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   26348              : 
   26349              : static reg_class_t
   26350   6298877477 : ix86_spill_class (reg_class_t rclass, machine_mode mode)
   26351              : {
   26352   6298877477 :   if (0 && TARGET_GENERAL_REGS_SSE_SPILL
   26353              :       && TARGET_SSE2
   26354              :       && TARGET_INTER_UNIT_MOVES_TO_VEC
   26355              :       && TARGET_INTER_UNIT_MOVES_FROM_VEC
   26356              :       && (mode == SImode || (TARGET_64BIT && mode == DImode))
   26357              :       && INTEGER_CLASS_P (rclass))
   26358              :     return ALL_SSE_REGS;
   26359   6298877477 :   return NO_REGS;
   26360              : }
   26361              : 
   26362              : /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  Like the default implementation,
   26363              :    but returns a lower bound.  */
   26364              : 
   26365              : static unsigned int
   26366      1873971 : ix86_max_noce_ifcvt_seq_cost (edge e)
   26367              : {
   26368      1873971 :   bool predictable_p = predictable_edge_p (e);
   26369      1873971 :   if (predictable_p)
   26370              :     {
   26371       147766 :       if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
   26372            8 :         return param_max_rtl_if_conversion_predictable_cost;
   26373              :     }
   26374              :   else
   26375              :     {
   26376      1726205 :       if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
   26377           73 :         return param_max_rtl_if_conversion_unpredictable_cost;
   26378              :     }
   26379              : 
   26380              :   /* For modern machines with deeper pipeline, the penalty for branch
   26381              :      misprediction could be higher than before to reset the pipeline
   26382              :      slots. Add parameter br_mispredict_scale as a factor to describe
   26383              :      the impact of resetting the pipeline.  */
   26384              : 
   26385      1873890 :   return BRANCH_COST (true, predictable_p)
   26386      1873890 :          * ix86_tune_cost->br_mispredict_scale;
   26387              : }
   26388              : 
   26389              : /* Return true if SEQ is a good candidate as a replacement for the
   26390              :    if-convertible sequence described in IF_INFO.  */
   26391              : 
   26392              : static bool
   26393       178332 : ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
   26394              : {
   26395       178332 :   if (TARGET_ONE_IF_CONV_INSN && if_info->speed_p)
   26396              :     {
   26397              :       int cmov_cnt = 0;
   26398              :       /* Punt if SEQ contains more than one CMOV or FCMOV instruction.
   26399              :          Maybe we should allow even more conditional moves as long as they
   26400              :          are used far enough not to stall the CPU, or also consider
   26401              :          IF_INFO->TEST_BB succ edge probabilities.  */
   26402          336 :       for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
   26403              :         {
   26404          280 :           rtx set = single_set (insn);
   26405          280 :           if (!set)
   26406            0 :             continue;
   26407          280 :           if (GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
   26408          238 :             continue;
   26409           42 :           rtx src = SET_SRC (set);
   26410           42 :           machine_mode mode = GET_MODE (src);
   26411           42 :           if (GET_MODE_CLASS (mode) != MODE_INT
   26412            0 :               && GET_MODE_CLASS (mode) != MODE_FLOAT)
   26413            0 :             continue;
   26414           42 :           if ((!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
   26415           41 :               || (!REG_P (XEXP (src, 2)) && !MEM_P (XEXP (src, 2))))
   26416            1 :             continue;
   26417              :           /* insn is CMOV or FCMOV.  */
   26418           41 :           if (++cmov_cnt > 1)
   26419              :             return false;
   26420              :         }
   26421              :     }
   26422              : 
   26423              :   /* W/o TARGET_SSE4_1, it takes 3 instructions (pand, pandn and por)
   26424              :      for movdfcc/movsfcc, and could possibly fail cost comparison.
   26425              :      Increase branch cost will hurt performance for other modes, so
   26426              :      specially add some preference for floating point ifcvt.  */
   26427       178324 :   if (!TARGET_SSE4_1 && if_info->x
   26428       141540 :       && GET_MODE_CLASS (GET_MODE (if_info->x)) == MODE_FLOAT
   26429        17976 :       && if_info->speed_p)
   26430              :     {
   26431        10938 :       unsigned cost = seq_cost (seq, true);
   26432              : 
   26433        10938 :       if (cost <= if_info->original_cost)
   26434              :         return true;
   26435              : 
   26436         9734 :       return cost <= (if_info->max_seq_cost + COSTS_N_INSNS (2));
   26437              :     }
   26438              : 
   26439       167386 :   return default_noce_conversion_profitable_p (seq, if_info);
   26440              : }
   26441              : 
   26442              : /* x86-specific vector costs.  */
   26443              : class ix86_vector_costs : public vector_costs
   26444              : {
   26445              : public:
   26446              :   ix86_vector_costs (vec_info *, bool);
   26447              : 
   26448              :   unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
   26449              :                               stmt_vec_info stmt_info, slp_tree node,
   26450              :                               tree vectype, int misalign,
   26451              :                               vect_cost_model_location where) override;
   26452              :   void finish_cost (const vector_costs *) override;
   26453              :   bool better_main_loop_than_p (const vector_costs *) const override;
   26454              :   bool better_epilogue_loop_than_p (const vector_costs *other,
   26455              :                                     loop_vec_info main_loop) const override;
   26456              : 
   26457              : private:
   26458              : 
   26459              :   bool better_fold_left_reduc_than_p (const vector_costs *) const;
   26460              :   /* Estimate register pressure of the vectorized code.  */
   26461              :   void ix86_vect_estimate_reg_pressure ();
   26462              :   /* Number of GENERAL_REGS/SSE_REGS used in the vectorizer, it's used for
   26463              :      estimation of register pressure.
   26464              :      ??? Currently it's only used by vec_construct/scalar_to_vec
   26465              :      where we know it's not loaded from memory.  */
   26466              :   unsigned m_num_gpr_needed[3];
   26467              :   unsigned m_num_sse_needed[3];
   26468              :   /* Number of 256-bit vector permutation.  */
   26469              :   unsigned m_num_avx256_vec_perm[3];
   26470              :   /* Number of 512-bit vector permutation.  */
   26471              :   unsigned m_num_avx512_vec_perm[3];
   26472              :   /* Number of reductions for FMA/DOT_PROD_EXPR/SAD_EXPR  */
   26473              :   unsigned m_num_reduc[X86_REDUC_LAST];
   26474              :   /* Don't do unroll if m_prefer_unroll is false, default is true.  */
   26475              :   bool m_prefer_unroll;
   26476              :   /* Scalar lanes in fold-left reductions.  */
   26477              :   unsigned int m_num_fold_left_reduc_lanes;
   26478              : };
   26479              : 
   26480      2193092 : ix86_vector_costs::ix86_vector_costs (vec_info* vinfo, bool costing_for_scalar)
   26481              :   : vector_costs (vinfo, costing_for_scalar),
   26482      2193092 :     m_num_gpr_needed (),
   26483      2193092 :     m_num_sse_needed (),
   26484      2193092 :     m_num_avx256_vec_perm (),
   26485      2193092 :     m_num_avx512_vec_perm (),
   26486      2193092 :     m_num_reduc (),
   26487      2193092 :     m_prefer_unroll (true),
   26488      2193092 :     m_num_fold_left_reduc_lanes (0)
   26489      2193092 : {}
   26490              : 
   26491              : /* Implement targetm.vectorize.create_costs.  */
   26492              : 
   26493              : static vector_costs *
   26494      2193092 : ix86_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
   26495              : {
   26496      2193092 :   return new ix86_vector_costs (vinfo, costing_for_scalar);
   26497              : }
   26498              : 
   26499              : /* Return true if a vec_perm should be counted as a cross-lane vector
   26500              :    permutation for a vector with NUNITS elements.  */
   26501              : static bool
   26502         5336 : ix86_count_cross_lane_perm_p (vec_info *vinfo, slp_tree node, unsigned nunits)
   26503              : {
   26504              :   /* TODO: For loop vectorization with no SLP load-permutation
   26505              :      information, conservatively treat these perms as cross-lane.
   26506              :      Repeated-index cases such as {0, 0, 0, 0} are emitted as
   26507              :      separate vec_perm_exprs for each index, so we cannot reliably
   26508              :      separate false positives from real cross-lane shuffles yet.  */
   26509         5336 :   if (!node
   26510         5327 :       || !SLP_TREE_LOAD_PERMUTATION (node).exists ()
   26511         9616 :       || !is_a<bb_vec_info> (vinfo))
   26512              :     return true;
   26513              : 
   26514           41 :   unsigned half = nunits / 2;
   26515           41 :   bool allsame = true;
   26516           41 :   unsigned first = SLP_TREE_LOAD_PERMUTATION (node)[0];
   26517           41 :   bool cross_lane_p = false;
   26518              : 
   26519          217 :   for (unsigned i = 0; i != SLP_TREE_LANES (node); i++)
   26520              :     {
   26521          215 :       unsigned tmp = SLP_TREE_LOAD_PERMUTATION (node)[i];
   26522              :       /* allsame is just a broadcast.  */
   26523          215 :       if (tmp != first)
   26524          106 :         allsame = false;
   26525              : 
   26526              :       /* The load permutation can cover multiple vectors, so compare
   26527              :          source and destination lanes modulo NUNITS.  */
   26528          215 :       tmp = tmp & (nunits - 1);
   26529          215 :       unsigned index = i & (nunits - 1);
   26530          215 :       if ((index < half && tmp >= half) || (index >= half && tmp < half))
   26531           67 :         cross_lane_p = true;
   26532              : 
   26533          215 :       if (!allsame && cross_lane_p)
   26534              :         return true;
   26535              :     }
   26536              : 
   26537              :   return false;
   26538              : }
   26539              : 
   26540              : unsigned
   26541      7845192 : ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
   26542              :                                   stmt_vec_info stmt_info, slp_tree node,
   26543              :                                   tree vectype, int,
   26544              :                                   vect_cost_model_location where)
   26545              : {
   26546      7845192 :   unsigned retval = 0;
   26547      7845192 :   bool scalar_p
   26548              :     = (kind == scalar_stmt || kind == scalar_load || kind == scalar_store);
   26549      7845192 :   int stmt_cost = - 1;
   26550              : 
   26551      7845192 :   bool fp = false;
   26552      7845192 :   machine_mode mode = scalar_p ? SImode : TImode;
   26553              : 
   26554      7845192 :   if (vectype != NULL)
   26555              :     {
   26556      3576507 :       fp = FLOAT_TYPE_P (vectype);
   26557      3576507 :       mode = TYPE_MODE (vectype);
   26558      3576507 :       if (scalar_p)
   26559       283929 :         mode = TYPE_MODE (TREE_TYPE (vectype));
   26560              :     }
   26561              :   /* When we are costing a scalar stmt use the scalar stmt to get at the
   26562              :      type of the operation.  */
   26563      4268685 :   else if (scalar_p && stmt_info)
   26564      4185081 :     if (tree lhs = gimple_get_lhs (stmt_info->stmt))
   26565              :       {
   26566      4003492 :         fp = FLOAT_TYPE_P (TREE_TYPE (lhs));
   26567      4003492 :         mode = TYPE_MODE (TREE_TYPE (lhs));
   26568              :       }
   26569              : 
   26570      7845192 :   if ((kind == vector_stmt || kind == scalar_stmt)
   26571      2134546 :       && stmt_info
   26572      9970499 :       && stmt_info->stmt && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
   26573              :     {
   26574      1706458 :       tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
   26575              :       /*machine_mode inner_mode = mode;
   26576              :       if (VECTOR_MODE_P (mode))
   26577              :         inner_mode = GET_MODE_INNER (mode);*/
   26578              : 
   26579      1706458 :       switch (subcode)
   26580              :         {
   26581       679608 :         case PLUS_EXPR:
   26582       679608 :         case POINTER_PLUS_EXPR:
   26583       679608 :         case MINUS_EXPR:
   26584       679608 :           if (kind == scalar_stmt)
   26585              :             {
   26586       424548 :               if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26587        99039 :                 stmt_cost = ix86_cost->addss;
   26588       325509 :               else if (X87_FLOAT_MODE_P (mode))
   26589          139 :                 stmt_cost = ix86_cost->fadd;
   26590              :               else
   26591       325370 :                 stmt_cost = ix86_cost->add;
   26592              :             }
   26593              :           else
   26594       255060 :             stmt_cost = ix86_vec_cost (mode, fp ? ix86_cost->addss
   26595              :                                        : ix86_cost->sse_op);
   26596              :           break;
   26597              : 
   26598       263842 :         case MULT_EXPR:
   26599              :           /* For MULT_HIGHPART_EXPR, x86 only supports pmulhw,
   26600              :              take it as MULT_EXPR.  */
   26601       263842 :         case MULT_HIGHPART_EXPR:
   26602       263842 :           stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   26603       263842 :           break;
   26604              :           /* There's no direct instruction for WIDEN_MULT_EXPR,
   26605              :              take emulation into account.  */
   26606         1221 :         case WIDEN_MULT_EXPR:
   26607         2442 :           stmt_cost = ix86_widen_mult_cost (ix86_cost, mode,
   26608         1221 :                                             TYPE_UNSIGNED (vectype));
   26609         1221 :           break;
   26610              : 
   26611        11305 :         case NEGATE_EXPR:
   26612        11305 :           if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26613         3564 :             stmt_cost = ix86_cost->sse_op;
   26614         7741 :           else if (X87_FLOAT_MODE_P (mode))
   26615            0 :             stmt_cost = ix86_cost->fchs;
   26616         7741 :           else if (VECTOR_MODE_P (mode))
   26617         3839 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26618              :           else
   26619         3902 :             stmt_cost = ix86_cost->add;
   26620              :           break;
   26621        15406 :         case TRUNC_DIV_EXPR:
   26622        15406 :         case CEIL_DIV_EXPR:
   26623        15406 :         case FLOOR_DIV_EXPR:
   26624        15406 :         case ROUND_DIV_EXPR:
   26625        15406 :         case TRUNC_MOD_EXPR:
   26626        15406 :         case CEIL_MOD_EXPR:
   26627        15406 :         case FLOOR_MOD_EXPR:
   26628        15406 :         case RDIV_EXPR:
   26629        15406 :         case ROUND_MOD_EXPR:
   26630        15406 :         case EXACT_DIV_EXPR:
   26631        15406 :           stmt_cost = ix86_division_cost (ix86_cost, mode);
   26632        15406 :           break;
   26633              : 
   26634        86710 :         case RSHIFT_EXPR:
   26635        86710 :         case LSHIFT_EXPR:
   26636        86710 :         case LROTATE_EXPR:
   26637        86710 :         case RROTATE_EXPR:
   26638        86710 :           {
   26639        86710 :             tree op1 = gimple_assign_rhs1 (stmt_info->stmt);
   26640        86710 :             tree op2 = gimple_assign_rhs2 (stmt_info->stmt);
   26641        86710 :             stmt_cost = ix86_shift_rotate_cost
   26642        86710 :                            (ix86_cost,
   26643              :                             (subcode == RSHIFT_EXPR
   26644        46117 :                              && !TYPE_UNSIGNED (TREE_TYPE (op1)))
   26645              :                             ? ASHIFTRT : LSHIFTRT, mode,
   26646        86710 :                             TREE_CODE (op2) == INTEGER_CST,
   26647        86710 :                             cst_and_fits_in_hwi (op2)
   26648        55202 :                             ? int_cst_value (op2) : -1,
   26649              :                             false, false, NULL, NULL);
   26650              :           }
   26651        86710 :           break;
   26652       104461 :         case NOP_EXPR:
   26653              :           /* Only sign-conversions are free.  */
   26654       104461 :           if (tree_nop_conversion_p
   26655       104461 :                 (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt)),
   26656       104461 :                  TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))))
   26657              :             stmt_cost = 0;
   26658       104461 :           else if (fp)
   26659        10461 :             stmt_cost = vec_fp_conversion_cost
   26660        10461 :                           (ix86_tune_cost, GET_MODE_BITSIZE (mode));
   26661              :           break;
   26662              : 
   26663        23369 :         case FLOAT_EXPR:
   26664        23369 :             if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26665        17552 :               stmt_cost = ix86_cost->cvtsi2ss;
   26666         5817 :             else if (X87_FLOAT_MODE_P (mode))
   26667              :               /* TODO: We do not have cost tables for x87.  */
   26668           50 :               stmt_cost = ix86_cost->fadd;
   26669              :             else
   26670         5767 :               stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtpi2ps);
   26671              :             break;
   26672              : 
   26673         2409 :         case FIX_TRUNC_EXPR:
   26674         2409 :             if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26675            0 :               stmt_cost = ix86_cost->cvtss2si;
   26676         2409 :             else if (X87_FLOAT_MODE_P (mode))
   26677              :               /* TODO: We do not have cost tables for x87.  */
   26678            0 :               stmt_cost = ix86_cost->fadd;
   26679              :             else
   26680         2409 :               stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtps2pi);
   26681              :             break;
   26682              : 
   26683        56497 :         case COND_EXPR:
   26684        56497 :           {
   26685              :             /* SSE2 conditinal move sequence is:
   26686              :                  pcmpgtd %xmm5, %xmm0 (accounted separately)
   26687              :                  pand    %xmm0, %xmm2
   26688              :                  pandn   %xmm1, %xmm0
   26689              :                  por     %xmm2, %xmm0
   26690              :                while SSE4 uses cmp + blend
   26691              :                and AVX512 masked moves.
   26692              : 
   26693              :                The condition is accounted separately since we usually have
   26694              :                  p = a < b
   26695              :                  c = p ? x : y
   26696              :                and we will account first statement as setcc.  Exception is when
   26697              :                p is loaded from memory as bool and then we will not account
   26698              :                the compare, but there is no way to check for this.  */
   26699              : 
   26700        56497 :             int ninsns = TARGET_SSE4_1 ? 1 : 3;
   26701              : 
   26702              :             /* If one of parameters is 0 or -1 the sequence will be simplified:
   26703              :                (if_true & mask) | (if_false & ~mask) -> if_true & mask  */
   26704        23700 :             if (ninsns > 1
   26705        23700 :                 && (zerop (gimple_assign_rhs2 (stmt_info->stmt))
   26706        23344 :                     || zerop (gimple_assign_rhs3 (stmt_info->stmt))
   26707        13223 :                     || integer_minus_onep
   26708        13223 :                         (gimple_assign_rhs2 (stmt_info->stmt))
   26709        12930 :                     || integer_minus_onep
   26710        12930 :                         (gimple_assign_rhs3 (stmt_info->stmt))))
   26711              :               ninsns = 1;
   26712              : 
   26713        56497 :             if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26714         5062 :               stmt_cost = ninsns * ix86_cost->sse_op;
   26715        51435 :             else if (X87_FLOAT_MODE_P (mode))
   26716              :               /* x87 requires conditional branch.  We don't have cost for
   26717              :                  that.  */
   26718              :               ;
   26719        51426 :             else if (VECTOR_MODE_P (mode))
   26720        21631 :               stmt_cost = ix86_vec_cost (mode, ninsns * ix86_cost->sse_op);
   26721              :             else
   26722              :               /* compare (accounted separately) + cmov.  */
   26723        29795 :               stmt_cost = ix86_cost->add;
   26724              :           }
   26725              :           break;
   26726              : 
   26727        37427 :         case MIN_EXPR:
   26728        37427 :         case MAX_EXPR:
   26729        37427 :           if (fp)
   26730              :             {
   26731         1507 :               if (X87_FLOAT_MODE_P (mode)
   26732          533 :                   && !SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26733              :                 /* x87 requires conditional branch.  We don't have cost for
   26734              :                    that.  */
   26735              :                 ;
   26736              :               else
   26737              :                 /* minss  */
   26738         1507 :                 stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26739              :             }
   26740              :           else
   26741              :             {
   26742        35920 :               if (VECTOR_MODE_P (mode))
   26743              :                 {
   26744        10493 :                   stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26745              :                   /* vpmin was introduced in SSE3.
   26746              :                      SSE2 needs pcmpgtd + pand + pandn + pxor.
   26747              :                      If one of parameters is 0 or -1 the sequence is simplified
   26748              :                      to pcmpgtd + pand.  */
   26749        10493 :                   if (!TARGET_SSSE3)
   26750              :                     {
   26751         8534 :                       if (zerop (gimple_assign_rhs2 (stmt_info->stmt))
   26752        15297 :                           || integer_minus_onep
   26753         6763 :                                 (gimple_assign_rhs2 (stmt_info->stmt)))
   26754         1771 :                         stmt_cost *= 2;
   26755              :                       else
   26756         6763 :                         stmt_cost *= 4;
   26757              :                     }
   26758              :                 }
   26759              :               else
   26760              :                 /* cmp + cmov.  */
   26761        25427 :                 stmt_cost = ix86_cost->add * 2;
   26762              :             }
   26763              :           break;
   26764              : 
   26765         1951 :         case ABS_EXPR:
   26766         1951 :         case ABSU_EXPR:
   26767         1951 :           if (fp)
   26768              :             {
   26769         1090 :               if (X87_FLOAT_MODE_P (mode)
   26770          583 :                   && !SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26771              :                 /* fabs.  */
   26772            0 :                 stmt_cost = ix86_cost->fabs;
   26773              :               else
   26774              :                 /* andss of sign bit.  */
   26775         1090 :                 stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26776              :             }
   26777              :           else
   26778              :             {
   26779          861 :               if (VECTOR_MODE_P (mode))
   26780              :                 {
   26781          114 :                   stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26782              :                   /* vabs was introduced in SSE3.
   26783              :                      SSE3 uses psrat + pxor + psub.  */
   26784          114 :                   if (!TARGET_SSSE3)
   26785           84 :                     stmt_cost *= 3;
   26786              :                 }
   26787              :               else
   26788              :                 /* neg + cmov.  */
   26789          747 :                 stmt_cost = ix86_cost->add * 2;
   26790              :             }
   26791              :           break;
   26792              : 
   26793       164032 :         case BIT_IOR_EXPR:
   26794       164032 :         case BIT_XOR_EXPR:
   26795       164032 :         case BIT_AND_EXPR:
   26796       164032 :         case BIT_NOT_EXPR:
   26797       164032 :           gcc_assert (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode)
   26798              :                       && !X87_FLOAT_MODE_P (mode));
   26799       164032 :           if (VECTOR_MODE_P (mode))
   26800        56478 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26801              :           else
   26802       107554 :             stmt_cost = ix86_cost->add;
   26803              :           break;
   26804              : 
   26805       258220 :         default:
   26806       258220 :           if (TREE_CODE_CLASS (subcode) == tcc_comparison)
   26807              :             {
   26808       100295 :               tree op_type;
   26809       100295 :               if (kind == vector_stmt)
   26810        32718 :                 op_type = SLP_TREE_VECTYPE (SLP_TREE_CHILDREN (node)[0]);
   26811              :               else
   26812        67577 :                 op_type = vect_comparison_type (stmt_info);
   26813       100295 :               mode = TYPE_MODE (op_type);
   26814              : 
   26815       100295 :               if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26816              :                 /* CMPccS? insructions are cheap, so use sse_op.  While they
   26817              :                    produce a mask which may need to be turned to 0/1 by and,
   26818              :                    expect that this will be optimized away in a common case.  */
   26819         8439 :                 stmt_cost = ix86_cost->sse_op;
   26820        91856 :               else if (X87_FLOAT_MODE_P (mode))
   26821              :                 /* fcmp + setcc.  */
   26822           32 :                 stmt_cost = ix86_cost->fadd + ix86_cost->add;
   26823        91824 :               else if (VECTOR_MODE_P (mode))
   26824        32661 :                 stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26825              :               else
   26826              :                 /* setcc.  */
   26827        59163 :                 stmt_cost = ix86_cost->add;
   26828              :               break;
   26829              :             }
   26830              :           break;
   26831              :         }
   26832              :     }
   26833              : 
   26834              :   /* Record number of load/store/gather/scatter in vectorized body.  */
   26835      7845192 :   if (where == vect_body && !m_costing_for_scalar)
   26836              :     {
   26837      2082481 :       int scale = 1;
   26838      2082481 :       if (vectype
   26839      4150191 :           && ((GET_MODE_SIZE (TYPE_MODE (vectype)) == 64
   26840        59962 :               && TARGET_AVX512_SPLIT_REGS)
   26841      4135118 :               || (GET_MODE_SIZE (TYPE_MODE (vectype)) == 32
   26842       118743 :                   && TARGET_AVX256_SPLIT_REGS)))
   26843              :         scale = 2;
   26844              : 
   26845      2082481 :       switch (kind)
   26846              :         {
   26847              :           /* Emulated gather/scatter or any scalarization.  */
   26848       117855 :         case scalar_load:
   26849       117855 :         case scalar_stmt:
   26850       117855 :         case scalar_store:
   26851       117855 :         case vector_gather_load:
   26852       117855 :         case vector_scatter_store:
   26853       117855 :           m_prefer_unroll = false;
   26854       117855 :           break;
   26855              : 
   26856       648771 :         case vector_stmt:
   26857       648771 :         case vec_to_scalar:
   26858              :           /* Count number of reduction FMA and "real" DOT_PROD_EXPR,
   26859              :              unroll in the vectorizer will enable partial sum.  */
   26860       648771 :           if (stmt_info
   26861       648742 :               && vect_is_reduction (stmt_info)
   26862       718274 :               && stmt_info->stmt)
   26863              :             {
   26864              :               /* Handle __builtin_fma.  */
   26865        69503 :               if (gimple_call_combined_fn (stmt_info->stmt) == CFN_FMA)
   26866              :                 {
   26867           11 :                   m_num_reduc[X86_REDUC_FMA] += count * scale;
   26868           11 :                   break;
   26869              :                 }
   26870              : 
   26871        69492 :               if (!is_gimple_assign (stmt_info->stmt))
   26872              :                 break;
   26873              : 
   26874        66726 :               tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
   26875        66726 :               machine_mode inner_mode = GET_MODE_INNER (mode);
   26876        66726 :               tree rhs1, rhs2;
   26877        66726 :               bool native_vnni_p = true;
   26878        66726 :               gimple* def;
   26879        66726 :               machine_mode mode_rhs;
   26880        66726 :               switch (subcode)
   26881              :                 {
   26882        49816 :                 case PLUS_EXPR:
   26883        49816 :                 case MINUS_EXPR:
   26884        49816 :                   if (!fp || !flag_associative_math
   26885        26417 :                       || flag_fp_contract_mode != FP_CONTRACT_FAST)
   26886              :                     break;
   26887              : 
   26888              :                   /* FMA condition for different modes.  */
   26889        26417 :                   if (((inner_mode == DFmode || inner_mode == SFmode)
   26890        26387 :                        && !TARGET_FMA && !TARGET_AVX512VL)
   26891         8624 :                       || (inner_mode == HFmode && !TARGET_AVX512FP16)
   26892         8624 :                       || (inner_mode == BFmode && !TARGET_AVX10_2))
   26893              :                     break;
   26894              : 
   26895              :                   /* MULT_EXPR + PLUS_EXPR/MINUS_EXPR is transformed
   26896              :                      to FMA/FNMA after vectorization.  */
   26897         8624 :                   rhs1 = gimple_assign_rhs1 (stmt_info->stmt);
   26898         8624 :                   rhs2 = gimple_assign_rhs2 (stmt_info->stmt);
   26899         8624 :                   if (subcode == PLUS_EXPR
   26900         6771 :                       && TREE_CODE (rhs1) == SSA_NAME
   26901         6771 :                       && (def = SSA_NAME_DEF_STMT (rhs1), true)
   26902         6771 :                       && is_gimple_assign (def)
   26903        12029 :                       && gimple_assign_rhs_code (def) == MULT_EXPR)
   26904         1992 :                     m_num_reduc[X86_REDUC_FMA] += count * scale;
   26905         6632 :                   else if (TREE_CODE (rhs2) == SSA_NAME
   26906         6632 :                            && (def = SSA_NAME_DEF_STMT (rhs2), true)
   26907         6632 :                            && is_gimple_assign (def)
   26908        13175 :                            && gimple_assign_rhs_code (def) == MULT_EXPR)
   26909         6537 :                     m_num_reduc[X86_REDUC_FMA] += count * scale;
   26910              :                   break;
   26911              : 
   26912              :                   /* Vectorizer lane_reducing_op_p supports DOT_PROX_EXPR,
   26913              :                      WIDEN_SUM_EXPR and SAD_EXPR, x86 backend only supports
   26914              :                      SAD_EXPR (usad{v16qi,v32qi,v64qi}) and DOT_PROD_EXPR.  */
   26915          616 :                 case DOT_PROD_EXPR:
   26916          616 :                   rhs1 = gimple_assign_rhs1 (stmt_info->stmt);
   26917          616 :                   mode_rhs = TYPE_MODE (TREE_TYPE (rhs1));
   26918          616 :                   if (mode_rhs == QImode)
   26919              :                     {
   26920          343 :                       rhs2 = gimple_assign_rhs2 (stmt_info->stmt);
   26921          343 :                       signop signop1_p = TYPE_SIGN (TREE_TYPE (rhs1));
   26922          343 :                       signop signop2_p = TYPE_SIGN (TREE_TYPE (rhs2));
   26923              : 
   26924              :                       /* vpdpbusd.  */
   26925          343 :                       if (signop1_p != signop2_p)
   26926           85 :                         native_vnni_p
   26927           85 :                           = (GET_MODE_SIZE (mode) == 64
   26928           85 :                              ? TARGET_AVX512VNNI
   26929           28 :                              : ((TARGET_AVX512VNNI && TARGET_AVX512VL)
   26930           85 :                                 || TARGET_AVXVNNI));
   26931              :                       else
   26932              :                         /* vpdpbssd.  */
   26933          258 :                         native_vnni_p
   26934          274 :                           = (GET_MODE_SIZE (mode) == 64
   26935          258 :                              ? TARGET_AVX10_2
   26936          242 :                              : (TARGET_AVXVNNIINT8 || TARGET_AVX10_2));
   26937              :                     }
   26938          616 :                   m_num_reduc[X86_REDUC_DOT_PROD] += count * scale;
   26939              : 
   26940              :                   /* Dislike to do unroll and partial sum for
   26941              :                      emulated DOT_PROD_EXPR.  */
   26942          616 :                   if (!native_vnni_p)
   26943          159 :                     m_num_reduc[X86_REDUC_DOT_PROD] += 3 * count;
   26944              :                   break;
   26945              : 
   26946          106 :                 case SAD_EXPR:
   26947          106 :                   m_num_reduc[X86_REDUC_SAD] += count * scale;
   26948          106 :                   break;
   26949              : 
   26950              :                 default:
   26951              :                   break;
   26952              :                 }
   26953              :             }
   26954              : 
   26955              :         default:
   26956              :           break;
   26957              :         }
   26958              :     }
   26959              : 
   26960              : 
   26961      7845192 :   combined_fn cfn;
   26962      7845192 :   if ((kind == vector_stmt || kind == scalar_stmt)
   26963      2134546 :       && stmt_info
   26964      2125307 :       && stmt_info->stmt
   26965      9970499 :       && is_gimple_call (stmt_info->stmt))
   26966              :     {
   26967        26479 :       tree fndecl = gimple_call_fndecl (stmt_info->stmt);
   26968        26479 :       cgraph_node *node;
   26969        26479 :       if ((fndecl
   26970         5465 :            && (node = cgraph_node::get (fndecl))
   26971         5432 :            && node->simd_clones)
   26972        30939 :           || gimple_call_internal_p (stmt_info->stmt, IFN_MASK_CALL))
   26973         2460 :         stmt_cost = 10 * ix86_vec_cost (mode,
   26974         1230 :                                         mode == SFmode ? ix86_cost->fmass
   26975              :                                         : ix86_cost->fmasd);
   26976        25249 :       else if ((cfn = gimple_call_combined_fn (stmt_info->stmt)) != CFN_LAST)
   26977        23879 :         switch (cfn)
   26978              :           {
   26979          107 :           case CFN_FMA:
   26980          107 :             stmt_cost = ix86_vec_cost (mode,
   26981          107 :                                        mode == SFmode ? ix86_cost->fmass
   26982              :                                        : ix86_cost->fmasd);
   26983          107 :             break;
   26984           62 :           case CFN_MULH:
   26985           62 :             stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   26986           62 :             break;
   26987              :           default:
   26988              :             break;
   26989              :           }
   26990              :     }
   26991              : 
   26992      7845192 :   if (kind == vec_promote_demote)
   26993              :     {
   26994        62539 :       int outer_size
   26995              :         = tree_to_uhwi
   26996        62539 :             (TYPE_SIZE
   26997        62539 :                 (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt))));
   26998        62539 :       int inner_size
   26999              :         = tree_to_uhwi
   27000        62539 :             (TYPE_SIZE
   27001        62539 :                 (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))));
   27002        62539 :       bool inner_fp = FLOAT_TYPE_P
   27003              :                         (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt)));
   27004              : 
   27005         5638 :       if (fp && inner_fp)
   27006         5128 :         stmt_cost = vec_fp_conversion_cost
   27007         5128 :                           (ix86_tune_cost, GET_MODE_BITSIZE (mode));
   27008        57411 :       else if (fp && !inner_fp)
   27009         6153 :         stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtpi2ps);
   27010        51258 :       else if (!fp && inner_fp)
   27011          510 :         stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtps2pi);
   27012              :       else
   27013        50748 :         stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   27014              :       /* VEC_PACK_TRUNC_EXPR and similar demote operations: If outer size is
   27015              :          greater than inner size we will end up doing two conversions and
   27016              :          packing them.  We always pack pairs; if the size difference is greater
   27017              :          it is split into multiple demote operations.  */
   27018        62539 :       if (inner_size > outer_size)
   27019        23798 :         stmt_cost = stmt_cost * 2
   27020        23798 :                     + ix86_vec_cost (mode, ix86_cost->sse_op);
   27021              :     }
   27022              : 
   27023              :   /* If we do elementwise loads into a vector then we are bound by
   27024              :      latency and execution resources for the many scalar loads
   27025              :      (AGU and load ports).  Try to account for this by scaling the
   27026              :      construction cost by the number of elements involved.  */
   27027      7845192 :   if ((kind == vec_construct || kind == vec_deconstruct)
   27028      7845192 :       && ((node
   27029       334785 :            && (((SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_ELEMENTWISE
   27030       346056 :                  || SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_STRIDED_SLP)
   27031        42508 :                 && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF
   27032              :                                         (SLP_TREE_REPRESENTATIVE (node))))
   27033              :                     != INTEGER_CST))
   27034        22805 :                || mat_gather_scatter_p (SLP_TREE_MEMORY_ACCESS_TYPE (node))))))
   27035              :     {
   27036        32475 :       auto lsdata = static_cast<vect_load_store_data *> (node->data);
   27037        32475 :       tree ls_type = lsdata->ls_type ? lsdata->ls_type : vectype;
   27038        32475 :       tree ls_eltype
   27039        32475 :         = lsdata->ls_eltype ? lsdata->ls_eltype : TREE_TYPE (ls_type);
   27040        32475 :       stmt_cost = ix86_vector_cd_cost (TYPE_MODE (ls_type),
   27041        32475 :                                        TYPE_MODE (ls_eltype));
   27042        32475 :       stmt_cost *= (GET_MODE_BITSIZE (TYPE_MODE (ls_type))
   27043        64950 :                     / GET_MODE_BITSIZE (TYPE_MODE (ls_eltype)) + 1);
   27044              :     }
   27045      7812717 :   else if ((kind == vec_construct || kind == scalar_to_vec)
   27046       517886 :            && node
   27047       484681 :            && SLP_TREE_DEF_TYPE (node) == vect_external_def)
   27048              :     {
   27049       340188 :       stmt_cost = ix86_default_vector_cost (kind, mode);
   27050       340188 :       unsigned i;
   27051       340188 :       tree op;
   27052      1447301 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   27053       766925 :         if (TREE_CODE (op) == SSA_NAME)
   27054       539694 :           TREE_VISITED (op) = 0;
   27055      1107113 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   27056              :         {
   27057       766925 :           if (TREE_CODE (op) != SSA_NAME
   27058       539694 :               || TREE_VISITED (op))
   27059       265283 :             continue;
   27060       501642 :           TREE_VISITED (op) = 1;
   27061       501642 :           gimple *def = SSA_NAME_DEF_STMT (op);
   27062       501642 :           tree tem;
   27063              :           /* Look through a conversion.  */
   27064       501642 :           if (is_gimple_assign (def)
   27065       281377 :               && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
   27066        32446 :               && ((tem = gimple_assign_rhs1 (def)), true)
   27067       534088 :               && TREE_CODE (tem) == SSA_NAME)
   27068        32233 :             def = SSA_NAME_DEF_STMT (tem);
   27069              :           /* When the component is loaded from memory without sign-
   27070              :              or zero-extension we can move it to a vector register and/or
   27071              :              insert it via vpinsr with a memory operand.  */
   27072       501642 :           if (gimple_assign_load_p (def)
   27073       142994 :               && tree_nop_conversion_p (TREE_TYPE (op),
   27074       142994 :                                         TREE_TYPE (gimple_assign_lhs (def)))
   27075       776788 :               && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op))) > 1
   27076         6327 :                   || TARGET_SSE4_1))
   27077              :             ;
   27078              :           /* When the component is extracted from a vector it is already
   27079              :              in a vector register.  */
   27080       369305 :           else if (is_gimple_assign (def)
   27081       143782 :                    && gimple_assign_rhs_code (def) == BIT_FIELD_REF
   27082       372166 :                    && VECTOR_TYPE_P (TREE_TYPE
   27083              :                                 (TREE_OPERAND (gimple_assign_rhs1 (def), 0))))
   27084              :             ;
   27085              :           else
   27086              :             {
   27087       366876 :               if (fp)
   27088              :                 {
   27089              :                   /* Scalar FP values residing in x87 registers need to be
   27090              :                      spilled and reloaded.  */
   27091        16818 :                   auto mode2 = TYPE_MODE (TREE_TYPE (op));
   27092        16818 :                   if (IS_STACK_MODE (mode2))
   27093              :                     {
   27094          971 :                       int cost
   27095              :                         = (ix86_cost->hard_register.fp_store[mode2 == SFmode
   27096          971 :                                                              ? 0 : 1]
   27097          971 :                            + ix86_cost->sse_load[sse_store_index (mode2)]);
   27098          971 :                       stmt_cost += COSTS_N_INSNS (cost) / 2;
   27099              :                     }
   27100        16818 :                   m_num_sse_needed[where]++;
   27101              :                 }
   27102              :               else
   27103              :                 {
   27104       350058 :                   m_num_gpr_needed[where]++;
   27105              : 
   27106       350058 :                   stmt_cost += COSTS_N_INSNS (ix86_cost->integer_to_sse) / 2;
   27107              :                 }
   27108              :             }
   27109              :         }
   27110      1107113 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   27111       766925 :         if (TREE_CODE (op) == SSA_NAME)
   27112       539694 :           TREE_VISITED (op) = 0;
   27113              :     }
   27114      7845192 :   if (stmt_cost == -1)
   27115      5954067 :     stmt_cost = ix86_default_vector_cost (kind, mode);
   27116              : 
   27117              :   /* BIT_FIELD_REF <vect_**, 64, 0> with count 0 costs 0 in body.  */
   27118      7845192 :   if (kind == vec_perm && vectype && count != 0)
   27119              :     {
   27120       123353 :       unsigned vec_size = GET_MODE_SIZE (TYPE_MODE (vectype));
   27121       123353 :       unsigned nunits = TYPE_VECTOR_SUBPARTS (vectype);
   27122       123353 :       unsigned *num_vec_perm = NULL;
   27123              : 
   27124       123353 :       if (vec_size == 32)
   27125         4138 :         num_vec_perm = m_num_avx256_vec_perm;
   27126       119215 :       else if (vec_size == 64)
   27127         1198 :         num_vec_perm = m_num_avx512_vec_perm;
   27128              : 
   27129         5336 :       if (num_vec_perm && ix86_count_cross_lane_perm_p (m_vinfo, node, nunits))
   27130              :         {
   27131         5334 :           num_vec_perm[where] += count;
   27132         5334 :           if (dump_file && (dump_flags & TDF_DETAILS))
   27133              :             {
   27134          346 :               fprintf (dump_file,
   27135              :                        "Detected avx%u cross-lane permutation: ", vec_size * 8);
   27136          346 :               if (stmt_info)
   27137          343 :                 print_gimple_expr (dump_file, stmt_info->stmt, 0, TDF_SLIM);
   27138          346 :               fprintf (dump_file, " \n");
   27139              :             }
   27140              :         }
   27141              :     }
   27142              : 
   27143              :   /* Penalize DFmode vector operations for Bonnell.  */
   27144      7845192 :   if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
   27145      7845277 :       && vectype && GET_MODE_INNER (TYPE_MODE (vectype)) == DFmode)
   27146           12 :     stmt_cost *= 5;  /* FIXME: The value here is arbitrary.  */
   27147              : 
   27148              :   /* Statements in an inner loop relative to the loop being
   27149              :      vectorized are weighted more heavily.  The value here is
   27150              :      arbitrary and could potentially be improved with analysis.  */
   27151      7845192 :   retval = adjust_cost_for_freq (stmt_info, where, count * stmt_cost);
   27152              : 
   27153              :   /* We need to multiply all vector stmt cost by 1.7 (estimated cost)
   27154              :      for Silvermont as it has out of order integer pipeline and can execute
   27155              :      2 scalar instruction per tick, but has in order SIMD pipeline.  */
   27156      7845192 :   if ((TARGET_CPU_P (SILVERMONT) || TARGET_CPU_P (GOLDMONT)
   27157      7845192 :        || TARGET_CPU_P (GOLDMONT_PLUS) || TARGET_CPU_P (INTEL))
   27158         2551 :       && stmt_info && stmt_info->stmt)
   27159              :     {
   27160         2189 :       tree lhs_op = gimple_get_lhs (stmt_info->stmt);
   27161         2189 :       if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE)
   27162         1657 :         retval = (retval * 17) / 10;
   27163              :     }
   27164              : 
   27165      7845192 :   m_costs[where] += retval;
   27166              : 
   27167      7845192 :   return retval;
   27168              : }
   27169              : 
   27170              : void
   27171      1887649 : ix86_vector_costs::ix86_vect_estimate_reg_pressure ()
   27172              : {
   27173      1887649 :   unsigned gpr_spill_cost = COSTS_N_INSNS (ix86_cost->int_store [2]) / 2;
   27174      1887649 :   unsigned sse_spill_cost = COSTS_N_INSNS (ix86_cost->sse_store[0]) / 2;
   27175              : 
   27176              :   /* Any better way to have target available fp registers, currently use SSE_REGS.  */
   27177      1887649 :   unsigned target_avail_sse = TARGET_64BIT ? (TARGET_AVX512F ? 32 : 16) : 8;
   27178      7550596 :   for (unsigned i = 0; i != 3; i++)
   27179              :     {
   27180      5662947 :       if (m_num_gpr_needed[i] > target_avail_regs)
   27181          924 :         m_costs[i] += gpr_spill_cost * (m_num_gpr_needed[i] - target_avail_regs);
   27182              :       /* Only measure sse registers pressure.  */
   27183      5662947 :       if (TARGET_SSE && (m_num_sse_needed[i] > target_avail_sse))
   27184          100 :         m_costs[i] += sse_spill_cost * (m_num_sse_needed[i] - target_avail_sse);
   27185              :     }
   27186      1887649 : }
   27187              : 
   27188              : void
   27189      1887649 : ix86_vector_costs::finish_cost (const vector_costs *scalar_costs)
   27190              : {
   27191      1887649 :   loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
   27192       497017 :   if (loop_vinfo && !m_costing_for_scalar)
   27193              :     {
   27194       125492 :       unsigned int vf = vect_vf_for_cost (loop_vinfo);
   27195       547371 :       for (auto inst : LOOP_VINFO_SLP_INSTANCES (loop_vinfo))
   27196       170895 :         if ((SLP_INSTANCE_KIND (inst) == slp_inst_kind_reduc_group
   27197       170895 :              || SLP_INSTANCE_KIND (inst) == slp_inst_kind_reduc_chain)
   27198       170895 :             && (vect_reduc_type (loop_vinfo, SLP_INSTANCE_TREE (inst))
   27199              :                 == FOLD_LEFT_REDUCTION))
   27200         3901 :           m_num_fold_left_reduc_lanes
   27201         3901 :             += vf * SLP_TREE_LANES (SLP_INSTANCE_TREE (inst));
   27202              : 
   27203       125492 :       if (m_num_fold_left_reduc_lanes && dump_enabled_p ())
   27204           19 :         dump_printf_loc (MSG_NOTE, vect_location,
   27205              :                          "in-order FP reduction lanes: %u\n",
   27206              :                          m_num_fold_left_reduc_lanes);
   27207              : 
   27208              :       /* We are currently not asking the vectorizer to compare costs
   27209              :          between different vector mode sizes.  When using predication
   27210              :          that will end up always choosing the preferred mode size even
   27211              :          if there's a smaller mode covering all lanes.  Test for this
   27212              :          situation and artificially reject the larger mode attempt.
   27213              :          ???  We currently lack masked ops for sub-SSE sized modes,
   27214              :          so we could restrict this rejection to AVX and AVX512 modes
   27215              :          but error on the safe side for now.  */
   27216       125492 :       if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
   27217           29 :           && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27218           17 :           && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   27219       125503 :           && (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())
   27220           22 :               > ceil_log2 (LOOP_VINFO_INT_NITERS (loop_vinfo))))
   27221            8 :         m_costs[vect_body] = INT_MAX;
   27222              : 
   27223              :       /* We'd like to avoid using masking if there's an in-order reduction
   27224              :          to vectorize because that will also perform in-order adds of
   27225              :          masked elements (as neutral value, of course) here, but there
   27226              :          is currently no way to indicate to try un-masked with the same
   27227              :          mode.  */
   27228              : 
   27229       125492 :       bool any_reduc_p = false;
   27230       498501 :       for (int i = 0; i != X86_REDUC_LAST; i++)
   27231       374310 :         if (m_num_reduc[i])
   27232              :           {
   27233              :             any_reduc_p = true;
   27234              :             break;
   27235              :           }
   27236              : 
   27237       125492 :       if (any_reduc_p
   27238              :           /* Not much gain for loop with gather and scatter.  */
   27239         1301 :           && m_prefer_unroll
   27240         1144 :           && !LOOP_VINFO_EPILOGUE_P (loop_vinfo))
   27241              :         {
   27242         1826 :           unsigned unroll_factor
   27243          913 :             = OPTION_SET_P (ix86_vect_unroll_limit)
   27244          913 :             ? ix86_vect_unroll_limit
   27245          913 :             : ix86_cost->vect_unroll_limit;
   27246              : 
   27247          913 :           if (unroll_factor > 1)
   27248              :             {
   27249         3652 :               for (int i = 0 ; i != X86_REDUC_LAST; i++)
   27250              :                 {
   27251         2739 :                   if (m_num_reduc[i])
   27252              :                     {
   27253          913 :                       unsigned tmp = CEIL (ix86_cost->reduc_lat_mult_thr[i],
   27254              :                                            m_num_reduc[i]);
   27255         2739 :                       unroll_factor = MIN (unroll_factor, tmp);
   27256              :                     }
   27257              :                 }
   27258              : 
   27259         1826 :               m_suggested_unroll_factor  = 1 << ceil_log2 (unroll_factor);
   27260              :             }
   27261              :         }
   27262              : 
   27263              :     }
   27264              : 
   27265      1887649 :   ix86_vect_estimate_reg_pressure ();
   27266              : 
   27267      7550596 :   for (int i = 0; i != 3; i++)
   27268      5662947 :     if (m_num_avx256_vec_perm[i]
   27269          522 :         && TARGET_AVX256_AVOID_VEC_PERM)
   27270            7 :       m_costs[i] = INT_MAX;
   27271              : 
   27272      7550596 :   for (int i = 0; i != 3; i++)
   27273      5662947 :     if (m_num_avx512_vec_perm[i] && TARGET_AVX512_AVOID_VEC_PERM)
   27274            5 :       m_costs[i] = INT_MAX;
   27275              : 
   27276              :   /* When X86_TUNE_AVX512_TWO_EPILOGUES is enabled arrange for both
   27277              :      a AVX2 and a SSE epilogue for AVX512 vectorized loops.  */
   27278      1887649 :   if (loop_vinfo
   27279       497017 :       && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27280        43386 :       && GET_MODE_SIZE (loop_vinfo->vector_mode) == 32
   27281      1888403 :       && ix86_tune_features[X86_TUNE_AVX512_TWO_EPILOGUES])
   27282           25 :     m_suggested_epilogue_mode = V16QImode;
   27283              :   /* When a 128bit SSE vectorized epilogue still has a VF of 16 or larger
   27284              :      enable a 64bit SSE epilogue.  */
   27285      1887649 :   if (loop_vinfo
   27286       497017 :       && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27287        43386 :       && GET_MODE_SIZE (loop_vinfo->vector_mode) == 16
   27288      1890154 :       && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () >= 16)
   27289           95 :     m_suggested_epilogue_mode = V8QImode;
   27290              : 
   27291              :   /* When X86_TUNE_AVX512_MASKED_EPILOGUES is enabled try to use
   27292              :      a masked epilogue if that doesn't seem detrimental.  */
   27293      1887649 :   if (loop_vinfo
   27294       497017 :       && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27295       475324 :       && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () > 2
   27296              :       /* Avoid a masked epilog if cascaded epilogues eventually get us
   27297              :          to one with VF 1 as that means no scalar epilog at all.  */
   27298        76312 :       && !((GET_MODE_SIZE (loop_vinfo->vector_mode)
   27299        76312 :             / LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () == 16)
   27300           34 :            && ix86_tune_features[X86_TUNE_AVX512_TWO_EPILOGUES])
   27301        76311 :       && ix86_tune_features[X86_TUNE_AVX512_MASKED_EPILOGUES]
   27302      1887833 :       && !OPTION_SET_P (param_vect_partial_vector_usage))
   27303              :     {
   27304          166 :       bool avoid = false;
   27305          166 :       if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   27306          129 :           && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) >= 0)
   27307              :         {
   27308          129 :           unsigned int peel_niter
   27309              :             = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo);
   27310          129 :           if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
   27311            0 :             peel_niter += 1;
   27312              :           /* When we know the number of scalar iterations of the epilogue,
   27313              :              avoid masking when a single vector epilog iteration handles
   27314              :              it in full.  */
   27315          129 :           if (pow2p_hwi ((LOOP_VINFO_INT_NITERS (loop_vinfo) - peel_niter)
   27316          129 :                          % LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ()))
   27317              :             avoid = true;
   27318              :         }
   27319          164 :       if (!avoid && loop_outer (loop_outer (LOOP_VINFO_LOOP (loop_vinfo))))
   27320           14 :         for (auto ddr : LOOP_VINFO_DDRS (loop_vinfo))
   27321              :           {
   27322            4 :             if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
   27323              :               ;
   27324            4 :             else if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
   27325              :               ;
   27326              :             else
   27327              :               {
   27328            2 :                 int loop_depth
   27329            4 :                     = index_in_loop_nest (LOOP_VINFO_LOOP (loop_vinfo)->num,
   27330            2 :                                           DDR_LOOP_NEST (ddr));
   27331            4 :                 if (DDR_NUM_DIST_VECTS (ddr) == 1
   27332            2 :                     && DDR_DIST_VECTS (ddr)[0][loop_depth] == 0)
   27333              :                   {
   27334              :                     /* Avoid the case when there's an outer loop that might
   27335              :                        traverse a multi-dimensional array with the inner
   27336              :                        loop just executing the masked epilogue with a
   27337              :                        read-write where the next outer iteration might
   27338              :                        read from the masked part of the previous write,
   27339              :                        'n' filling half a vector.
   27340              :                          for (j = 0; j < m; ++j)
   27341              :                            for (i = 0; i < n; ++i)
   27342              :                              a[j][i] = c * a[j][i];  */
   27343              :                     avoid = true;
   27344              :                     break;
   27345              :                   }
   27346              :               }
   27347              :           }
   27348              :       /* Avoid using masking if there's an in-order reduction
   27349              :          to vectorize because that will also perform in-order adds of
   27350              :          masked elements (as neutral value, of course).  */
   27351          166 :       if (!avoid)
   27352              :         {
   27353          655 :           for (auto inst : LOOP_VINFO_SLP_INSTANCES (loop_vinfo))
   27354          173 :             if (SLP_INSTANCE_KIND (inst) == slp_inst_kind_reduc_group
   27355          173 :                 && (vect_reduc_type (loop_vinfo, SLP_INSTANCE_TREE (inst))
   27356              :                     == FOLD_LEFT_REDUCTION))
   27357              :               {
   27358              :                 avoid = true;
   27359              :                 break;
   27360              :               }
   27361              :         }
   27362          162 :       if (!avoid)
   27363              :         {
   27364          158 :           m_suggested_epilogue_mode = loop_vinfo->vector_mode;
   27365          158 :           m_masked_epilogue = 1;
   27366              :         }
   27367              :     }
   27368              : 
   27369      1887649 :   vector_costs::finish_cost (scalar_costs);
   27370      1887649 : }
   27371              : 
   27372              : /* Return true if THIS has a shorter fold-left reduction chain than OTHER.  */
   27373              : 
   27374              : bool
   27375        32570 : ix86_vector_costs::better_fold_left_reduc_than_p
   27376              :   (const vector_costs *other) const
   27377              : {
   27378        32570 :   auto other_costs = static_cast<const ix86_vector_costs *> (other);
   27379        32570 :   if (m_num_fold_left_reduc_lanes >= other_costs->m_num_fold_left_reduc_lanes)
   27380              :     return false;
   27381              : 
   27382              :   /* Do not let emulated sub-SSE modes win on this alone.  */
   27383          316 :   loop_vec_info loop_vinfo = as_a<loop_vec_info> (m_vinfo);
   27384          632 :   return known_ge (GET_MODE_SIZE (loop_vinfo->vector_mode), 16);
   27385              : }
   27386              : 
   27387              : /* Return true if THIS should be preferred over OTHER as main vector loop.  */
   27388              : 
   27389              : bool
   27390        31088 : ix86_vector_costs::better_main_loop_than_p (const vector_costs *other) const
   27391              : {
   27392        31088 :   loop_vec_info this_loop_vinfo = as_a<loop_vec_info> (this->vinfo ());
   27393        31088 :   loop_vec_info other_loop_vinfo = as_a<loop_vec_info> (other->vinfo ());
   27394              : 
   27395        31088 :   if (better_fold_left_reduc_than_p (other))
   27396              :     return true;
   27397              : 
   27398              :   /* If the other loop is masked it does not need an epilog.  Prefer that
   27399              :      if the current loop cannot be vectorized fully with a vector
   27400              :      epilogs with at most one scalar iteration left.  */
   27401        21119 :   if (LOOP_VINFO_NITERS_KNOWN_P (this_loop_vinfo)
   27402        21119 :       && LOOP_VINFO_USING_PARTIAL_VECTORS_P (other_loop_vinfo)
   27403            4 :       && known_gt (LOOP_VINFO_VECT_FACTOR (other_loop_vinfo),
   27404              :                    LOOP_VINFO_INT_NITERS (this_loop_vinfo))
   27405        31057 :       && (popcount_hwi (LOOP_VINFO_INT_NITERS (this_loop_vinfo) & ~1)
   27406            4 :           > (param_vect_epilogues_nomask != 0)))
   27407              :     return false;
   27408              : 
   27409        31049 :   return vector_costs::better_main_loop_than_p (other);
   27410              : }
   27411              : 
   27412              : /* Return true if THIS should be preferred over OTHER as epilog vector
   27413              :    loop when vectorizing MAIN_LOOP.  */
   27414              : 
   27415              : bool
   27416         1482 : ix86_vector_costs::better_epilogue_loop_than_p (const vector_costs *other,
   27417              :                                                 loop_vec_info main_loop) const
   27418              : {
   27419         1482 :   loop_vec_info this_loop_info = as_a <loop_vec_info> (this->vinfo ());
   27420              : 
   27421         1482 :   if (better_fold_left_reduc_than_p (other))
   27422              :     return true;
   27423              : 
   27424              :   /* The x86 target allows for multiple vector epilogues, if THIS is
   27425              :      the suggested epilog mode of OTHER then keep the latter unless
   27426              :      THIS has a VF of one which means no further epilog needed.  */
   27427         1482 :   int tem;
   27428         1482 :   if (known_gt (LOOP_VINFO_VECT_FACTOR (this_loop_info), 1U)
   27429         1482 :       && (GET_MODE_SIZE (other->suggested_epilogue_mode (tem))
   27430         2940 :           == GET_MODE_SIZE (this_loop_info->vector_mode)))
   27431              :     return false;
   27432         1409 :   return vector_costs::better_epilogue_loop_than_p (other, main_loop);
   27433              : }
   27434              : 
   27435              : /* Validate target specific memory model bits in VAL. */
   27436              : 
   27437              : static unsigned HOST_WIDE_INT
   27438       412280 : ix86_memmodel_check (unsigned HOST_WIDE_INT val)
   27439              : {
   27440       412280 :   enum memmodel model = memmodel_from_int (val);
   27441       412280 :   bool strong;
   27442              : 
   27443       412280 :   if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
   27444              :                                       |MEMMODEL_MASK)
   27445       412276 :       || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
   27446              :     {
   27447            4 :       warning (OPT_Winvalid_memory_model,
   27448              :                "unknown architecture specific memory model");
   27449            4 :       return MEMMODEL_SEQ_CST;
   27450              :     }
   27451       412276 :   strong = (is_mm_acq_rel (model) || is_mm_seq_cst (model));
   27452       412276 :   if (val & IX86_HLE_ACQUIRE && !(is_mm_acquire (model) || strong))
   27453              :     {
   27454            0 :       warning (OPT_Winvalid_memory_model,
   27455              :               "%<HLE_ACQUIRE%> not used with %<ACQUIRE%> or stronger "
   27456              :                "memory model");
   27457            0 :       return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
   27458              :     }
   27459       412276 :   if (val & IX86_HLE_RELEASE && !(is_mm_release (model) || strong))
   27460              :     {
   27461            0 :       warning (OPT_Winvalid_memory_model,
   27462              :               "%<HLE_RELEASE%> not used with %<RELEASE%> or stronger "
   27463              :                "memory model");
   27464            0 :       return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
   27465              :     }
   27466              :   return val;
   27467              : }
   27468              : 
   27469              : /* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
   27470              :    CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
   27471              :    CLONEI->simdlen.  Return 0 if SIMD clones shouldn't be emitted,
   27472              :    or number of vecsize_mangle variants that should be emitted.  */
   27473              : 
   27474              : static int
   27475         7689 : ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
   27476              :                                              struct cgraph_simd_clone *clonei,
   27477              :                                              tree base_type, int num,
   27478              :                                              bool explicit_p)
   27479              : {
   27480         7689 :   int ret = 1;
   27481              : 
   27482         7689 :   if (clonei->simdlen
   27483         7689 :       && (clonei->simdlen < 2
   27484         1321 :           || clonei->simdlen > 1024
   27485         1321 :           || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
   27486              :     {
   27487            0 :       if (explicit_p)
   27488            0 :         warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27489              :                     "unsupported simdlen %wd", clonei->simdlen.to_constant ());
   27490            0 :       return 0;
   27491              :     }
   27492              : 
   27493         7689 :   tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
   27494         7689 :   if (TREE_CODE (ret_type) != VOID_TYPE)
   27495         6897 :     switch (TYPE_MODE (ret_type))
   27496              :       {
   27497         6897 :       case E_QImode:
   27498         6897 :       case E_HImode:
   27499         6897 :       case E_SImode:
   27500         6897 :       case E_DImode:
   27501         6897 :       case E_SFmode:
   27502         6897 :       case E_DFmode:
   27503              :       /* case E_SCmode: */
   27504              :       /* case E_DCmode: */
   27505         6897 :         if (!AGGREGATE_TYPE_P (ret_type))
   27506              :           break;
   27507              :         /* FALLTHRU */
   27508            2 :       default:
   27509            2 :         if (explicit_p)
   27510            2 :           warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27511              :                       "unsupported return type %qT for simd", ret_type);
   27512            2 :         return 0;
   27513              :       }
   27514              : 
   27515         7687 :   tree t;
   27516         7687 :   int i;
   27517         7687 :   tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
   27518         7687 :   bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
   27519              : 
   27520         7687 :   for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
   27521        20654 :        t && t != void_list_node; t = TREE_CHAIN (t), i++)
   27522              :     {
   27523        16918 :       tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
   27524        12972 :       switch (TYPE_MODE (arg_type))
   27525              :         {
   27526        12953 :         case E_QImode:
   27527        12953 :         case E_HImode:
   27528        12953 :         case E_SImode:
   27529        12953 :         case E_DImode:
   27530        12953 :         case E_SFmode:
   27531        12953 :         case E_DFmode:
   27532              :         /* case E_SCmode: */
   27533              :         /* case E_DCmode: */
   27534        12953 :           if (!AGGREGATE_TYPE_P (arg_type))
   27535              :             break;
   27536              :           /* FALLTHRU */
   27537           41 :         default:
   27538           41 :           if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
   27539              :             break;
   27540            5 :           if (explicit_p)
   27541            5 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27542              :                         "unsupported argument type %qT for simd", arg_type);
   27543              :           return 0;
   27544              :         }
   27545              :     }
   27546              : 
   27547         7682 :   if (!TREE_PUBLIC (node->decl) || !explicit_p)
   27548              :     {
   27549              :       /* If the function isn't exported, we can pick up just one ISA
   27550              :          for the clones.  */
   27551          114 :       if (TARGET_AVX512F)
   27552            0 :         clonei->vecsize_mangle = 'e';
   27553          114 :       else if (TARGET_AVX2)
   27554            1 :         clonei->vecsize_mangle = 'd';
   27555          113 :       else if (TARGET_AVX)
   27556           88 :         clonei->vecsize_mangle = 'c';
   27557              :       else
   27558           25 :         clonei->vecsize_mangle = 'b';
   27559              :       ret = 1;
   27560              :     }
   27561              :   else
   27562              :     {
   27563         7568 :       clonei->vecsize_mangle = "bcde"[num];
   27564         7568 :       ret = 4;
   27565              :     }
   27566         7682 :   clonei->mask_mode = VOIDmode;
   27567         7682 :   switch (clonei->vecsize_mangle)
   27568              :     {
   27569         1917 :     case 'b':
   27570         1917 :       clonei->vecsize_int = 128;
   27571         1917 :       clonei->vecsize_float = 128;
   27572         1917 :       break;
   27573         1980 :     case 'c':
   27574         1980 :       clonei->vecsize_int = 128;
   27575         1980 :       clonei->vecsize_float = 256;
   27576         1980 :       break;
   27577         1893 :     case 'd':
   27578         1893 :       clonei->vecsize_int = 256;
   27579         1893 :       clonei->vecsize_float = 256;
   27580         1893 :       break;
   27581         1892 :     case 'e':
   27582         1892 :       clonei->vecsize_int = 512;
   27583         1892 :       clonei->vecsize_float = 512;
   27584         1892 :       if (TYPE_MODE (base_type) == QImode)
   27585           19 :         clonei->mask_mode = DImode;
   27586              :       else
   27587         1873 :         clonei->mask_mode = SImode;
   27588              :       break;
   27589              :     }
   27590         7682 :   if (clonei->simdlen == 0)
   27591              :     {
   27592         6361 :       if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
   27593         3297 :         clonei->simdlen = clonei->vecsize_int;
   27594              :       else
   27595         3064 :         clonei->simdlen = clonei->vecsize_float;
   27596         6361 :       clonei->simdlen = clonei->simdlen
   27597        12722 :                         / GET_MODE_BITSIZE (TYPE_MODE (base_type));
   27598              :     }
   27599         1321 :   else if (clonei->simdlen > 16)
   27600              :     {
   27601              :       /* For compatibility with ICC, use the same upper bounds
   27602              :          for simdlen.  In particular, for CTYPE below, use the return type,
   27603              :          unless the function returns void, in that case use the characteristic
   27604              :          type.  If it is possible for given SIMDLEN to pass CTYPE value
   27605              :          in registers (8 [XYZ]MM* regs for 32-bit code, 16 [XYZ]MM* regs
   27606              :          for 64-bit code), accept that SIMDLEN, otherwise warn and don't
   27607              :          emit corresponding clone.  */
   27608           12 :       tree ctype = ret_type;
   27609           12 :       if (VOID_TYPE_P (ret_type))
   27610            0 :         ctype = base_type;
   27611           24 :       int cnt = GET_MODE_BITSIZE (TYPE_MODE (ctype)) * clonei->simdlen;
   27612           12 :       if (SCALAR_INT_MODE_P (TYPE_MODE (ctype)))
   27613            8 :         cnt /= clonei->vecsize_int;
   27614              :       else
   27615            4 :         cnt /= clonei->vecsize_float;
   27616           12 :       if (cnt > (TARGET_64BIT ? 16 : 8))
   27617              :         {
   27618            0 :           if (explicit_p)
   27619            0 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27620              :                         "unsupported simdlen %wd",
   27621              :                         clonei->simdlen.to_constant ());
   27622            0 :           return 0;
   27623              :         }
   27624              :       }
   27625              :   return ret;
   27626              : }
   27627              : 
   27628              : /* If SIMD clone NODE can't be used in a vectorized loop
   27629              :    in current function, return -1, otherwise return a badness of using it
   27630              :    (0 if it is most desirable from vecsize_mangle point of view, 1
   27631              :    slightly less desirable, etc.).  */
   27632              : 
   27633              : static int
   27634         1764 : ix86_simd_clone_usable (struct cgraph_node *node, machine_mode)
   27635              : {
   27636         1764 :   switch (node->simdclone->vecsize_mangle)
   27637              :     {
   27638          626 :     case 'b':
   27639          626 :       if (!TARGET_SSE2)
   27640              :         return -1;
   27641          626 :       if (!TARGET_AVX)
   27642              :         return 0;
   27643          525 :       return TARGET_AVX512F ? 3 : TARGET_AVX2 ? 2 : 1;
   27644          628 :     case 'c':
   27645          628 :       if (!TARGET_AVX)
   27646              :         return -1;
   27647          583 :       return TARGET_AVX512F ? 2 : TARGET_AVX2 ? 1 : 0;
   27648          322 :     case 'd':
   27649          322 :       if (!TARGET_AVX2)
   27650              :         return -1;
   27651          117 :       return TARGET_AVX512F ? 1 : 0;
   27652          188 :     case 'e':
   27653          188 :       if (!TARGET_AVX512F)
   27654          130 :         return -1;
   27655              :       return 0;
   27656            0 :     default:
   27657            0 :       gcc_unreachable ();
   27658              :     }
   27659              : }
   27660              : 
   27661              : /* This function adjusts the unroll factor based on
   27662              :    the hardware capabilities. For ex, bdver3 has
   27663              :    a loop buffer which makes unrolling of smaller
   27664              :    loops less important. This function decides the
   27665              :    unroll factor using number of memory references
   27666              :    (value 32 is used) as a heuristic. */
   27667              : 
   27668              : static unsigned
   27669       795490 : ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
   27670              : {
   27671       795490 :   basic_block *bbs;
   27672       795490 :   rtx_insn *insn;
   27673       795490 :   unsigned i;
   27674       795490 :   unsigned mem_count = 0;
   27675              : 
   27676              :   /* Unroll small size loop when unroll factor is not explicitly
   27677              :      specified.  */
   27678       795490 :   if (ix86_unroll_only_small_loops && !loop->unroll)
   27679              :     {
   27680       751658 :       if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
   27681        72684 :         return MIN (nunroll, ix86_cost->small_unroll_factor);
   27682              :       else
   27683              :         return 1;
   27684              :     }
   27685              : 
   27686        43832 :   if (!TARGET_ADJUST_UNROLL)
   27687              :      return nunroll;
   27688              : 
   27689              :   /* Count the number of memory references within the loop body.
   27690              :      This value determines the unrolling factor for bdver3 and bdver4
   27691              :      architectures. */
   27692            8 :   subrtx_iterator::array_type array;
   27693            8 :   bbs = get_loop_body (loop);
   27694           24 :   for (i = 0; i < loop->num_nodes; i++)
   27695          120 :     FOR_BB_INSNS (bbs[i], insn)
   27696          104 :       if (NONDEBUG_INSN_P (insn))
   27697          588 :         FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   27698          516 :           if (const_rtx x = *iter)
   27699          516 :             if (MEM_P (x))
   27700              :               {
   27701           28 :                 machine_mode mode = GET_MODE (x);
   27702           56 :                 unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
   27703           28 :                 if (n_words > 4)
   27704            0 :                   mem_count += 2;
   27705              :                 else
   27706           28 :                   mem_count += 1;
   27707              :               }
   27708            8 :   free (bbs);
   27709              : 
   27710            8 :   if (mem_count && mem_count <=32)
   27711            8 :     return MIN (nunroll, 32 / mem_count);
   27712              : 
   27713              :   return nunroll;
   27714            8 : }
   27715              : 
   27716              : 
   27717              : /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P.  */
   27718              : 
   27719              : static bool
   27720       426476 : ix86_float_exceptions_rounding_supported_p (void)
   27721              : {
   27722              :   /* For x87 floating point with standard excess precision handling,
   27723              :      there is no adddf3 pattern (since x87 floating point only has
   27724              :      XFmode operations) so the default hook implementation gets this
   27725              :      wrong.  */
   27726       426476 :   return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
   27727              : }
   27728              : 
   27729              : /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
   27730              : 
   27731              : static void
   27732         7054 : ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   27733              : {
   27734         7054 :   if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
   27735              :     return;
   27736         7054 :   tree exceptions_var = create_tmp_var_raw (integer_type_node);
   27737         7054 :   if (TARGET_80387)
   27738              :     {
   27739         7054 :       tree fenv_index_type = build_index_type (size_int (6));
   27740         7054 :       tree fenv_type = build_array_type (unsigned_type_node, fenv_index_type);
   27741         7054 :       tree fenv_var = create_tmp_var_raw (fenv_type);
   27742         7054 :       TREE_ADDRESSABLE (fenv_var) = 1;
   27743         7054 :       tree fenv_ptr = build_pointer_type (fenv_type);
   27744         7054 :       tree fenv_addr = build1 (ADDR_EXPR, fenv_ptr, fenv_var);
   27745         7054 :       fenv_addr = fold_convert (ptr_type_node, fenv_addr);
   27746         7054 :       tree fnstenv = get_ix86_builtin (IX86_BUILTIN_FNSTENV);
   27747         7054 :       tree fldenv = get_ix86_builtin (IX86_BUILTIN_FLDENV);
   27748         7054 :       tree fnstsw = get_ix86_builtin (IX86_BUILTIN_FNSTSW);
   27749         7054 :       tree fnclex = get_ix86_builtin (IX86_BUILTIN_FNCLEX);
   27750         7054 :       tree hold_fnstenv = build_call_expr (fnstenv, 1, fenv_addr);
   27751         7054 :       tree hold_fnclex = build_call_expr (fnclex, 0);
   27752         7054 :       fenv_var = build4 (TARGET_EXPR, fenv_type, fenv_var, hold_fnstenv,
   27753              :                          NULL_TREE, NULL_TREE);
   27754         7054 :       *hold = build2 (COMPOUND_EXPR, void_type_node, fenv_var,
   27755              :                       hold_fnclex);
   27756         7054 :       *clear = build_call_expr (fnclex, 0);
   27757         7054 :       tree sw_var = create_tmp_var_raw (short_unsigned_type_node);
   27758         7054 :       tree fnstsw_call = build_call_expr (fnstsw, 0);
   27759         7054 :       tree sw_mod = build4 (TARGET_EXPR, short_unsigned_type_node, sw_var,
   27760              :                             fnstsw_call, NULL_TREE, NULL_TREE);
   27761         7054 :       tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
   27762         7054 :       tree update_mod = build4 (TARGET_EXPR, integer_type_node,
   27763              :                                 exceptions_var, exceptions_x87,
   27764              :                                 NULL_TREE, NULL_TREE);
   27765         7054 :       *update = build2 (COMPOUND_EXPR, integer_type_node,
   27766              :                         sw_mod, update_mod);
   27767         7054 :       tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
   27768         7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
   27769              :     }
   27770         7054 :   if (TARGET_SSE && TARGET_SSE_MATH)
   27771              :     {
   27772         7054 :       tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
   27773         7054 :       tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
   27774         7054 :       tree stmxcsr = get_ix86_builtin (IX86_BUILTIN_STMXCSR);
   27775         7054 :       tree ldmxcsr = get_ix86_builtin (IX86_BUILTIN_LDMXCSR);
   27776         7054 :       tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
   27777         7054 :       tree hold_assign_orig = build4 (TARGET_EXPR, unsigned_type_node,
   27778              :                                       mxcsr_orig_var, stmxcsr_hold_call,
   27779              :                                       NULL_TREE, NULL_TREE);
   27780         7054 :       tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
   27781              :                                   mxcsr_orig_var,
   27782              :                                   build_int_cst (unsigned_type_node, 0x1f80));
   27783         7054 :       hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
   27784              :                              build_int_cst (unsigned_type_node, 0xffffffc0));
   27785         7054 :       tree hold_assign_mod = build4 (TARGET_EXPR, unsigned_type_node,
   27786              :                                      mxcsr_mod_var, hold_mod_val,
   27787              :                                      NULL_TREE, NULL_TREE);
   27788         7054 :       tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   27789         7054 :       tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
   27790              :                               hold_assign_orig, hold_assign_mod);
   27791         7054 :       hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
   27792              :                          ldmxcsr_hold_call);
   27793         7054 :       if (*hold)
   27794         7054 :         *hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
   27795              :       else
   27796            0 :         *hold = hold_all;
   27797         7054 :       tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   27798         7054 :       if (*clear)
   27799         7054 :         *clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
   27800              :                          ldmxcsr_clear_call);
   27801              :       else
   27802            0 :         *clear = ldmxcsr_clear_call;
   27803         7054 :       tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
   27804         7054 :       tree exceptions_sse = fold_convert (integer_type_node,
   27805              :                                           stxmcsr_update_call);
   27806         7054 :       if (*update)
   27807              :         {
   27808         7054 :           tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
   27809              :                                         exceptions_var, exceptions_sse);
   27810         7054 :           tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
   27811              :                                            exceptions_var, exceptions_mod);
   27812         7054 :           *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
   27813              :                             exceptions_assign);
   27814              :         }
   27815              :       else
   27816            0 :         *update = build4 (TARGET_EXPR, integer_type_node, exceptions_var,
   27817              :                           exceptions_sse, NULL_TREE, NULL_TREE);
   27818         7054 :       tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
   27819         7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   27820              :                         ldmxcsr_update_call);
   27821              :     }
   27822         7054 :   tree atomic_feraiseexcept
   27823         7054 :     = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
   27824         7054 :   tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
   27825              :                                                     1, exceptions_var);
   27826         7054 :   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   27827              :                     atomic_feraiseexcept_call);
   27828              : }
   27829              : 
   27830              : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   27831              : /* For i386, common symbol is local only for non-PIE binaries.  For
   27832              :    x86-64, common symbol is local only for non-PIE binaries or linker
   27833              :    supports copy reloc in PIE binaries.   */
   27834              : 
   27835              : static bool
   27836    791667468 : ix86_binds_local_p (const_tree exp)
   27837              : {
   27838    791667468 :   bool direct_extern_access
   27839    791667468 :     = (ix86_direct_extern_access
   27840   1579803270 :        && !(VAR_OR_FUNCTION_DECL_P (exp)
   27841    788135802 :             && lookup_attribute ("nodirect_extern_access",
   27842    788135802 :                                  DECL_ATTRIBUTES (exp))));
   27843    791667468 :   if (!direct_extern_access)
   27844         1233 :     ix86_has_no_direct_extern_access = true;
   27845    791667468 :   return default_binds_local_p_3 (exp, flag_shlib != 0, true,
   27846              :                                   direct_extern_access,
   27847              :                                   (direct_extern_access
   27848    791666235 :                                    && (!flag_pic
   27849    132924541 :                                        || (TARGET_64BIT
   27850    791667468 :                                            && HAVE_LD_PIE_COPYRELOC != 0))));
   27851              : }
   27852              : 
   27853              : /* If flag_pic or ix86_direct_extern_access is false, then neither
   27854              :    local nor global relocs should be placed in readonly memory.  */
   27855              : 
   27856              : static int
   27857      5158374 : ix86_reloc_rw_mask (void)
   27858              : {
   27859      5158374 :   return (flag_pic || !ix86_direct_extern_access) ? 3 : 0;
   27860              : }
   27861              : #endif
   27862              : 
   27863              : /* Return true iff ADDR can be used as a symbolic base address.  */
   27864              : 
   27865              : static bool
   27866         3011 : symbolic_base_address_p (rtx addr)
   27867              : {
   27868            0 :   if (SYMBOL_REF_P (addr))
   27869              :     return true;
   27870              : 
   27871         2987 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
   27872            0 :     return true;
   27873              : 
   27874              :   return false;
   27875              : }
   27876              : 
   27877              : /* Return true iff ADDR can be used as a base address.  */
   27878              : 
   27879              : static bool
   27880         4590 : base_address_p (rtx addr)
   27881              : {
   27882            0 :   if (REG_P (addr))
   27883              :     return true;
   27884              : 
   27885         2857 :   if (symbolic_base_address_p (addr))
   27886            0 :     return true;
   27887              : 
   27888              :   return false;
   27889              : }
   27890              : 
   27891              : /* If MEM is in the form of [(base+symbase)+offset], extract the three
   27892              :    parts of address and set to BASE, SYMBASE and OFFSET, otherwise
   27893              :    return false.  */
   27894              : 
   27895              : static bool
   27896         2957 : extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
   27897              : {
   27898         2957 :   rtx addr;
   27899              : 
   27900         2957 :   gcc_assert (MEM_P (mem));
   27901              : 
   27902         2957 :   addr = XEXP (mem, 0);
   27903              : 
   27904         2957 :   if (GET_CODE (addr) == CONST)
   27905           10 :     addr = XEXP (addr, 0);
   27906              : 
   27907         2957 :   if (base_address_p (addr))
   27908              :     {
   27909         1324 :       *base = addr;
   27910         1324 :       *symbase = const0_rtx;
   27911         1324 :       *offset = const0_rtx;
   27912         1324 :       return true;
   27913              :     }
   27914              : 
   27915         1633 :   if (GET_CODE (addr) == PLUS
   27916         1633 :       && base_address_p (XEXP (addr, 0)))
   27917              :     {
   27918          433 :       rtx addend = XEXP (addr, 1);
   27919              : 
   27920          433 :       if (GET_CODE (addend) == CONST)
   27921            0 :         addend = XEXP (addend, 0);
   27922              : 
   27923          433 :       if (CONST_INT_P (addend))
   27924              :         {
   27925          279 :           *base = XEXP (addr, 0);
   27926          279 :           *symbase = const0_rtx;
   27927          279 :           *offset = addend;
   27928          279 :           return true;
   27929              :         }
   27930              : 
   27931              :       /* Also accept REG + symbolic ref, with or without a CONST_INT
   27932              :          offset.  */
   27933          154 :       if (REG_P (XEXP (addr, 0)))
   27934              :         {
   27935          154 :           if (symbolic_base_address_p (addend))
   27936              :             {
   27937            0 :               *base = XEXP (addr, 0);
   27938            0 :               *symbase = addend;
   27939            0 :               *offset = const0_rtx;
   27940            0 :               return true;
   27941              :             }
   27942              : 
   27943          154 :           if (GET_CODE (addend) == PLUS
   27944            0 :               && symbolic_base_address_p (XEXP (addend, 0))
   27945          154 :               && CONST_INT_P (XEXP (addend, 1)))
   27946              :             {
   27947            0 :               *base = XEXP (addr, 0);
   27948            0 :               *symbase = XEXP (addend, 0);
   27949            0 :               *offset = XEXP (addend, 1);
   27950            0 :               return true;
   27951              :             }
   27952              :         }
   27953              :     }
   27954              : 
   27955              :   return false;
   27956              : }
   27957              : 
   27958              : /* Given OPERANDS of consecutive load/store, check if we can merge
   27959              :    them into move multiple.  LOAD is true if they are load instructions.
   27960              :    MODE is the mode of memory operands.  */
   27961              : 
   27962              : bool
   27963         1626 : ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
   27964              :                                     machine_mode mode)
   27965              : {
   27966         1626 :   HOST_WIDE_INT offval_1, offval_2, msize;
   27967         1626 :   rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
   27968              :     symbase_1, symbase_2, offset_1, offset_2;
   27969              : 
   27970         1626 :   if (load)
   27971              :     {
   27972         1328 :       mem_1 = operands[1];
   27973         1328 :       mem_2 = operands[3];
   27974         1328 :       reg_1 = operands[0];
   27975         1328 :       reg_2 = operands[2];
   27976              :     }
   27977              :   else
   27978              :     {
   27979          298 :       mem_1 = operands[0];
   27980          298 :       mem_2 = operands[2];
   27981          298 :       reg_1 = operands[1];
   27982          298 :       reg_2 = operands[3];
   27983              :     }
   27984              : 
   27985         1626 :   gcc_assert (REG_P (reg_1) && REG_P (reg_2));
   27986              : 
   27987         1626 :   if (REGNO (reg_1) != REGNO (reg_2))
   27988              :     return false;
   27989              : 
   27990              :   /* Check if the addresses are in the form of [base+offset].  */
   27991         1622 :   if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
   27992              :     return false;
   27993         1335 :   if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
   27994              :     return false;
   27995              : 
   27996              :   /* Check if the bases are the same.  */
   27997          268 :   if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))
   27998          121 :     return false;
   27999              : 
   28000          147 :   offval_1 = INTVAL (offset_1);
   28001          147 :   offval_2 = INTVAL (offset_2);
   28002          147 :   msize = GET_MODE_SIZE (mode);
   28003              :   /* Check if mem_1 is adjacent to mem_2 and mem_1 has lower address.  */
   28004          147 :   if (offval_1 + msize != offval_2)
   28005              :     return false;
   28006              : 
   28007              :   return true;
   28008              : }
   28009              : 
   28010              : /* Implement the TARGET_OPTAB_SUPPORTED_P hook.  */
   28011              : 
   28012              : static bool
   28013       348661 : ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
   28014              :                         optimization_type opt_type)
   28015              : {
   28016       348661 :   switch (op)
   28017              :     {
   28018          231 :     case asin_optab:
   28019          231 :     case acos_optab:
   28020          231 :     case log1p_optab:
   28021          231 :     case exp_optab:
   28022          231 :     case exp10_optab:
   28023          231 :     case exp2_optab:
   28024          231 :     case expm1_optab:
   28025          231 :     case ldexp_optab:
   28026          231 :     case scalb_optab:
   28027          231 :     case round_optab:
   28028          231 :     case lround_optab:
   28029          231 :       return opt_type == OPTIMIZE_FOR_SPEED;
   28030              : 
   28031          286 :     case rint_optab:
   28032          286 :       if (SSE_FLOAT_MODE_P (mode1)
   28033          139 :           && TARGET_SSE_MATH
   28034          127 :           && !flag_trapping_math
   28035           21 :           && !TARGET_SSE4_1
   28036              :           && mode1 != HFmode)
   28037           21 :         return opt_type == OPTIMIZE_FOR_SPEED;
   28038              :       return true;
   28039              : 
   28040         1971 :     case floor_optab:
   28041         1971 :     case ceil_optab:
   28042         1971 :     case btrunc_optab:
   28043         1971 :       if ((SSE_FLOAT_MODE_P (mode1)
   28044         1581 :            && TARGET_SSE_MATH
   28045         1514 :            && TARGET_SSE4_1)
   28046         1904 :           || mode1 == HFmode)
   28047              :         return true;
   28048         1835 :       return opt_type == OPTIMIZE_FOR_SPEED;
   28049              : 
   28050           66 :     case rsqrt_optab:
   28051           66 :       return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1);
   28052              : 
   28053              :     default:
   28054              :       return true;
   28055              :     }
   28056              : }
   28057              : 
   28058              : /* Address space support.
   28059              : 
   28060              :    This is not "far pointers" in the 16-bit sense, but an easy way
   28061              :    to use %fs and %gs segment prefixes.  Therefore:
   28062              : 
   28063              :     (a) All address spaces have the same modes,
   28064              :     (b) All address spaces have the same address forms,
   28065              :     (c) While %fs and %gs are technically subsets of the generic
   28066              :         address space, they are probably not subsets of each other.
   28067              :     (d) Since we have no access to the segment base register values
   28068              :         without resorting to a system call, we cannot convert a
   28069              :         non-default address space to a default address space.
   28070              :         Therefore we do not claim %fs or %gs are subsets of generic.
   28071              : 
   28072              :    Therefore we can (mostly) use the default hooks.  */
   28073              : 
   28074              : /* All use of segmentation is assumed to make address 0 valid.  */
   28075              : 
   28076              : static bool
   28077     69380922 : ix86_addr_space_zero_address_valid (addr_space_t as)
   28078              : {
   28079     69380922 :   return as != ADDR_SPACE_GENERIC;
   28080              : }
   28081              : 
   28082              : static void
   28083       778684 : ix86_init_libfuncs (void)
   28084              : {
   28085       778684 :   if (TARGET_64BIT)
   28086              :     {
   28087       763814 :       set_optab_libfunc (sdivmod_optab, TImode, "__divmodti4");
   28088       763814 :       set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4");
   28089              :     }
   28090              :   else
   28091              :     {
   28092        14870 :       set_optab_libfunc (sdivmod_optab, DImode, "__divmoddi4");
   28093        14870 :       set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
   28094              :     }
   28095              : 
   28096              : #if TARGET_MACHO
   28097              :   darwin_rename_builtins ();
   28098              : #endif
   28099       778684 : }
   28100              : 
   28101              : /* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
   28102              :    FPU, assume that the fpcw is set to extended precision; when using
   28103              :    only SSE, rounding is correct; when using both SSE and the FPU,
   28104              :    the rounding precision is indeterminate, since either may be chosen
   28105              :    apparently at random.  */
   28106              : 
   28107              : static enum flt_eval_method
   28108     91092438 : ix86_get_excess_precision (enum excess_precision_type type)
   28109              : {
   28110     91092438 :   switch (type)
   28111              :     {
   28112     86999065 :       case EXCESS_PRECISION_TYPE_FAST:
   28113              :         /* The fastest type to promote to will always be the native type,
   28114              :            whether that occurs with implicit excess precision or
   28115              :            otherwise.  */
   28116     86999065 :         return TARGET_AVX512FP16
   28117     86999065 :                ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
   28118     86999065 :                : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   28119      4092629 :       case EXCESS_PRECISION_TYPE_STANDARD:
   28120      4092629 :       case EXCESS_PRECISION_TYPE_IMPLICIT:
   28121              :         /* Otherwise, the excess precision we want when we are
   28122              :            in a standards compliant mode, and the implicit precision we
   28123              :            provide would be identical were it not for the unpredictable
   28124              :            cases.  */
   28125      4092629 :         if (TARGET_AVX512FP16 && TARGET_SSE_MATH)
   28126              :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   28127      4086851 :         else if (!TARGET_80387)
   28128              :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   28129      4080719 :         else if (!TARGET_MIX_SSE_I387)
   28130              :           {
   28131      4080547 :             if (!(TARGET_SSE && TARGET_SSE_MATH))
   28132              :               return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
   28133      3091915 :             else if (TARGET_SSE2)
   28134              :               return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   28135              :           }
   28136              : 
   28137              :         /* If we are in standards compliant mode, but we know we will
   28138              :            calculate in unpredictable precision, return
   28139              :            FLT_EVAL_METHOD_FLOAT.  There is no reason to introduce explicit
   28140              :            excess precision if the target can't guarantee it will honor
   28141              :            it.  */
   28142          320 :         return (type == EXCESS_PRECISION_TYPE_STANDARD
   28143          320 :                 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
   28144              :                 : FLT_EVAL_METHOD_UNPREDICTABLE);
   28145          744 :       case EXCESS_PRECISION_TYPE_FLOAT16:
   28146          744 :         if (TARGET_80387
   28147          738 :             && !(TARGET_SSE_MATH && TARGET_SSE))
   28148            4 :           error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
   28149              :         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   28150            0 :       default:
   28151            0 :         gcc_unreachable ();
   28152              :     }
   28153              : 
   28154              :   return FLT_EVAL_METHOD_UNPREDICTABLE;
   28155              : }
   28156              : 
   28157              : /* Return true if _BitInt(N) is supported and fill its details into *INFO.  */
   28158              : bool
   28159       362558 : ix86_bitint_type_info (int n, struct bitint_info *info)
   28160              : {
   28161       362558 :   if (n <= 8)
   28162        11256 :     info->limb_mode = QImode;
   28163       351302 :   else if (n <= 16)
   28164         2558 :     info->limb_mode = HImode;
   28165       348744 :   else if (n <= 32 || (!TARGET_64BIT && n > 64))
   28166        47257 :     info->limb_mode = SImode;
   28167              :   else
   28168       301487 :     info->limb_mode = DImode;
   28169       362558 :   info->abi_limb_mode = info->limb_mode;
   28170       362558 :   info->big_endian = false;
   28171       362558 :   info->extended = bitint_ext_undef;
   28172       362558 :   return true;
   28173              : }
   28174              : 
   28175              : /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return DFmode, TFmode
   28176              :    or XFmode for TI_LONG_DOUBLE_TYPE which is for long double type,
   28177              :    based on long double bits, go with the default one for the others.  */
   28178              : 
   28179              : static machine_mode
   28180      3722960 : ix86_c_mode_for_floating_type (enum tree_index ti)
   28181              : {
   28182      3722960 :   if (ti == TI_LONG_DOUBLE_TYPE)
   28183       620986 :     return (TARGET_LONG_DOUBLE_64 ? DFmode
   28184       620954 :                                   : (TARGET_LONG_DOUBLE_128 ? TFmode : XFmode));
   28185      3101974 :   return default_mode_for_floating_type (ti);
   28186              : }
   28187              : 
   28188              : /* Returns modified FUNCTION_TYPE for cdtor callabi.  */
   28189              : tree
   28190        14713 : ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype)
   28191              : {
   28192        14713 :   if (TARGET_64BIT
   28193           71 :       || TARGET_RTD
   28194        14784 :       || ix86_function_type_abi (fntype) != MS_ABI)
   28195        14713 :     return fntype;
   28196              :   /* For 32-bit MS ABI add thiscall attribute.  */
   28197            0 :   tree attribs = tree_cons (get_identifier ("thiscall"), NULL_TREE,
   28198            0 :                             TYPE_ATTRIBUTES (fntype));
   28199            0 :   return build_type_attribute_variant (fntype, attribs);
   28200              : }
   28201              : 
   28202              : /* Implement PUSH_ROUNDING.  On 386, we have pushw instruction that
   28203              :    decrements by exactly 2 no matter what the position was, there is no pushb.
   28204              : 
   28205              :    But as CIE data alignment factor on this arch is -4 for 32bit targets
   28206              :    and -8 for 64bit targets, we need to make sure all stack pointer adjustments
   28207              :    are in multiple of 4 for 32bit targets and 8 for 64bit targets.  */
   28208              : 
   28209              : poly_int64
   28210    263040658 : ix86_push_rounding (poly_int64 bytes)
   28211              : {
   28212    338597931 :   return ROUND_UP (bytes, UNITS_PER_WORD);
   28213              : }
   28214              : 
   28215              : /* Use 8 bits metadata start from bit48 for LAM_U48,
   28216              :    6 bits metadata start from bit57 for LAM_U57.  */
   28217              : #define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48             \
   28218              :                            ? 48                                 \
   28219              :                            : (ix86_lam_type == lam_u57 ? 57 : 0))
   28220              : #define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48          \
   28221              :                               ? 8                               \
   28222              :                               : (ix86_lam_type == lam_u57 ? 6 : 0))
   28223              : 
   28224              : /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES.  */
   28225              : bool
   28226      6303938 : ix86_memtag_can_tag_addresses ()
   28227              : {
   28228      6303938 :   return ix86_lam_type != lam_none && TARGET_LP64;
   28229              : }
   28230              : 
   28231              : /* Implement TARGET_MEMTAG_TAG_BITSIZE.  */
   28232              : unsigned char
   28233          450 : ix86_memtag_tag_bitsize ()
   28234              : {
   28235          450 :   return IX86_HWASAN_TAG_SIZE;
   28236              : }
   28237              : 
   28238              : /* Implement TARGET_MEMTAG_SET_TAG.  */
   28239              : rtx
   28240          106 : ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
   28241              : {
   28242              :   /* default_memtag_insert_random_tag may
   28243              :      generate tag with value more than 6 bits.  */
   28244          106 :   if (ix86_lam_type == lam_u57)
   28245              :     {
   28246          106 :       unsigned HOST_WIDE_INT and_imm
   28247              :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   28248              : 
   28249          106 :       emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
   28250              :     }
   28251          106 :   tag = expand_simple_binop (Pmode, ASHIFT, tag,
   28252          106 :                              GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
   28253              :                              /* unsignedp = */1, OPTAB_WIDEN);
   28254          106 :   rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
   28255              :                                  /* unsignedp = */1, OPTAB_DIRECT);
   28256          106 :   return ret;
   28257              : }
   28258              : 
   28259              : /* Implement TARGET_MEMTAG_EXTRACT_TAG.  */
   28260              : rtx
   28261          180 : ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
   28262              : {
   28263          180 :   rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
   28264          180 :                                  GEN_INT (IX86_HWASAN_SHIFT), target,
   28265              :                                  /* unsignedp = */0,
   28266              :                                  OPTAB_DIRECT);
   28267          180 :   rtx ret = gen_reg_rtx (QImode);
   28268              :   /* Mask off bit63 when LAM_U57.  */
   28269          180 :   if (ix86_lam_type == lam_u57)
   28270              :     {
   28271          180 :       unsigned HOST_WIDE_INT and_imm
   28272              :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   28273          180 :       emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
   28274          180 :                              gen_int_mode (and_imm, QImode)));
   28275              :     }
   28276              :   else
   28277            0 :     emit_move_insn (ret, gen_lowpart (QImode, tag));
   28278          180 :   return ret;
   28279              : }
   28280              : 
   28281              : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER.  */
   28282              : rtx
   28283          114 : ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
   28284              : {
   28285              :   /* Leave bit63 alone.  */
   28286          114 :   rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
   28287          114 :                                 + (HOST_WIDE_INT_1U << 63) - 1),
   28288          114 :                                Pmode);
   28289          114 :   rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
   28290              :                                            tag_mask, target, true,
   28291              :                                            OPTAB_DIRECT);
   28292          114 :   gcc_assert (untagged_base);
   28293          114 :   return untagged_base;
   28294              : }
   28295              : 
   28296              : /* Implement TARGET_MEMTAG_ADD_TAG.  */
   28297              : rtx
   28298           90 : ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
   28299              : {
   28300           90 :   rtx base_tag = gen_reg_rtx (QImode);
   28301           90 :   rtx base_addr = gen_reg_rtx (Pmode);
   28302           90 :   rtx tagged_addr = gen_reg_rtx (Pmode);
   28303           90 :   rtx new_tag = gen_reg_rtx (QImode);
   28304          180 :   unsigned HOST_WIDE_INT and_imm
   28305           90 :     = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
   28306              : 
   28307              :   /* When there's "overflow" in tag adding,
   28308              :      need to mask the most significant bit off.  */
   28309           90 :   emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
   28310           90 :   emit_move_insn (base_addr,
   28311              :                   ix86_memtag_untagged_pointer (base, NULL_RTX));
   28312           90 :   emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
   28313           90 :   emit_move_insn (new_tag, base_tag);
   28314           90 :   emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
   28315           90 :   emit_move_insn (tagged_addr,
   28316              :                   ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
   28317           90 :   return plus_constant (Pmode, tagged_addr, offset);
   28318              : }
   28319              : 
   28320              : /* Implement TARGET_HAVE_CCMP.  */
   28321              : static bool
   28322      8293988 : ix86_have_ccmp ()
   28323              : {
   28324      8293988 :   return (bool) TARGET_APX_CCMP;
   28325              : }
   28326              : 
   28327              : /* Implement TARGET_MODE_CAN_TRANSFER_BITS.  */
   28328              : static bool
   28329      4774932 : ix86_mode_can_transfer_bits (machine_mode mode)
   28330              : {
   28331      4774932 :   if (GET_MODE_CLASS (mode) == MODE_FLOAT
   28332      4723634 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
   28333       124162 :     switch (GET_MODE_INNER (mode))
   28334              :       {
   28335        56411 :       case E_SFmode:
   28336        56411 :       case E_DFmode:
   28337              :         /* These suffer from normalization upon load when not using SSE.  */
   28338        56411 :         return !(ix86_fpmath & FPMATH_387);
   28339              :       default:
   28340              :         return true;
   28341              :       }
   28342              : 
   28343              :   return true;
   28344              : }
   28345              : 
   28346              : /* Implement TARGET_REDZONE_CLOBBER.  */
   28347              : static rtx
   28348            2 : ix86_redzone_clobber ()
   28349              : {
   28350            2 :   cfun->machine->asm_redzone_clobber_seen = true;
   28351            2 :   if (ix86_using_red_zone ())
   28352              :     {
   28353            2 :       rtx base = plus_constant (Pmode, stack_pointer_rtx, -RED_ZONE_SIZE);
   28354            2 :       rtx mem = gen_rtx_MEM (BLKmode, base);
   28355            2 :       set_mem_size (mem, RED_ZONE_SIZE);
   28356            2 :       return mem;
   28357              :     }
   28358              :   return NULL_RTX;
   28359              : }
   28360              : 
   28361              : /* Target-specific selftests.  */
   28362              : 
   28363              : #if CHECKING_P
   28364              : 
   28365              : namespace selftest {
   28366              : 
   28367              : /* Verify that hard regs are dumped as expected (in compact mode).  */
   28368              : 
   28369              : static void
   28370            4 : ix86_test_dumping_hard_regs ()
   28371              : {
   28372            4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI ax)", gen_raw_REG (SImode, 0));
   28373            4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI dx)", gen_raw_REG (SImode, 1));
   28374            4 : }
   28375              : 
   28376              : /* Test dumping an insn with repeated references to the same SCRATCH,
   28377              :    to verify the rtx_reuse code.  */
   28378              : 
   28379              : static void
   28380            4 : ix86_test_dumping_memory_blockage ()
   28381              : {
   28382            4 :   set_new_first_and_last_insn (NULL, NULL);
   28383              : 
   28384            4 :   rtx pat = gen_memory_blockage ();
   28385            4 :   rtx_reuse_manager r;
   28386            4 :   r.preprocess (pat);
   28387              : 
   28388              :   /* Verify that the repeated references to the SCRATCH show use
   28389              :      reuse IDS.  The first should be prefixed with a reuse ID,
   28390              :      and the second should be dumped as a "reuse_rtx" of that ID.
   28391              :      The expected string assumes Pmode == DImode.  */
   28392            4 :   if (Pmode == DImode)
   28393            4 :     ASSERT_RTL_DUMP_EQ_WITH_REUSE
   28394              :       ("(cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0  A8])\n"
   28395              :        "        (unspec:BLK [\n"
   28396              :        "                (mem/v:BLK (reuse_rtx 0) [0  A8])\n"
   28397              :        "            ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r);
   28398            4 : }
   28399              : 
   28400              : /* Verify loading an RTL dump; specifically a dump of copying
   28401              :    a param on x86_64 from a hard reg into the frame.
   28402              :    This test is target-specific since the dump contains target-specific
   28403              :    hard reg names.  */
   28404              : 
   28405              : static void
   28406            4 : ix86_test_loading_dump_fragment_1 ()
   28407              : {
   28408            4 :   rtl_dump_test t (SELFTEST_LOCATION,
   28409            4 :                    locate_file ("x86_64/copy-hard-reg-into-frame.rtl"));
   28410              : 
   28411            4 :   rtx_insn *insn = get_insn_by_uid (1);
   28412              : 
   28413              :   /* The block structure and indentation here is purely for
   28414              :      readability; it mirrors the structure of the rtx.  */
   28415            4 :   tree mem_expr;
   28416            4 :   {
   28417            4 :     rtx pat = PATTERN (insn);
   28418            4 :     ASSERT_EQ (SET, GET_CODE (pat));
   28419            4 :     {
   28420            4 :       rtx dest = SET_DEST (pat);
   28421            4 :       ASSERT_EQ (MEM, GET_CODE (dest));
   28422              :       /* Verify the "/c" was parsed.  */
   28423            4 :       ASSERT_TRUE (RTX_FLAG (dest, call));
   28424            4 :       ASSERT_EQ (SImode, GET_MODE (dest));
   28425            4 :       {
   28426            4 :         rtx addr = XEXP (dest, 0);
   28427            4 :         ASSERT_EQ (PLUS, GET_CODE (addr));
   28428            4 :         ASSERT_EQ (DImode, GET_MODE (addr));
   28429            4 :         {
   28430            4 :           rtx lhs = XEXP (addr, 0);
   28431              :           /* Verify that the "frame" REG was consolidated.  */
   28432            4 :           ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs);
   28433              :         }
   28434            4 :         {
   28435            4 :           rtx rhs = XEXP (addr, 1);
   28436            4 :           ASSERT_EQ (CONST_INT, GET_CODE (rhs));
   28437            4 :           ASSERT_EQ (-4, INTVAL (rhs));
   28438              :         }
   28439              :       }
   28440              :       /* Verify the "[1 i+0 S4 A32]" was parsed.  */
   28441            4 :       ASSERT_EQ (1, MEM_ALIAS_SET (dest));
   28442              :       /* "i" should have been handled by synthesizing a global int
   28443              :          variable named "i".  */
   28444            4 :       mem_expr = MEM_EXPR (dest);
   28445            4 :       ASSERT_NE (mem_expr, NULL);
   28446            4 :       ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr));
   28447            4 :       ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr));
   28448            4 :       ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr)));
   28449            4 :       ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr)));
   28450              :       /* "+0".  */
   28451            4 :       ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest));
   28452            4 :       ASSERT_EQ (0, MEM_OFFSET (dest));
   28453              :       /* "S4".  */
   28454            4 :       ASSERT_EQ (4, MEM_SIZE (dest));
   28455              :       /* "A32.  */
   28456            4 :       ASSERT_EQ (32, MEM_ALIGN (dest));
   28457              :     }
   28458            4 :     {
   28459            4 :       rtx src = SET_SRC (pat);
   28460            4 :       ASSERT_EQ (REG, GET_CODE (src));
   28461            4 :       ASSERT_EQ (SImode, GET_MODE (src));
   28462            4 :       ASSERT_EQ (5, REGNO (src));
   28463            4 :       tree reg_expr = REG_EXPR (src);
   28464              :       /* "i" here should point to the same var as for the MEM_EXPR.  */
   28465            4 :       ASSERT_EQ (reg_expr, mem_expr);
   28466              :     }
   28467              :   }
   28468            4 : }
   28469              : 
   28470              : /* Verify that the RTL loader copes with a call_insn dump.
   28471              :    This test is target-specific since the dump contains a target-specific
   28472              :    hard reg name.  */
   28473              : 
   28474              : static void
   28475            4 : ix86_test_loading_call_insn ()
   28476              : {
   28477              :   /* The test dump includes register "xmm0", where requires TARGET_SSE
   28478              :      to exist.  */
   28479            4 :   if (!TARGET_SSE)
   28480            0 :     return;
   28481              : 
   28482            4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl"));
   28483              : 
   28484            4 :   rtx_insn *insn = get_insns ();
   28485            4 :   ASSERT_EQ (CALL_INSN, GET_CODE (insn));
   28486              : 
   28487              :   /* "/j".  */
   28488            4 :   ASSERT_TRUE (RTX_FLAG (insn, jump));
   28489              : 
   28490            4 :   rtx pat = PATTERN (insn);
   28491            4 :   ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat)));
   28492              : 
   28493              :   /* Verify REG_NOTES.  */
   28494            4 :   {
   28495              :     /* "(expr_list:REG_CALL_DECL".   */
   28496            4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn)));
   28497            4 :     rtx_expr_list *note0 = as_a <rtx_expr_list *> (REG_NOTES (insn));
   28498            4 :     ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0));
   28499              : 
   28500              :     /* "(expr_list:REG_EH_REGION (const_int 0 [0])".  */
   28501            4 :     rtx_expr_list *note1 = note0->next ();
   28502            4 :     ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1));
   28503              : 
   28504            4 :     ASSERT_EQ (NULL, note1->next ());
   28505              :   }
   28506              : 
   28507              :   /* Verify CALL_INSN_FUNCTION_USAGE.  */
   28508            4 :   {
   28509              :     /* "(expr_list:DF (use (reg:DF 21 xmm0))".  */
   28510            4 :     rtx_expr_list *usage
   28511            4 :       = as_a <rtx_expr_list *> (CALL_INSN_FUNCTION_USAGE (insn));
   28512            4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (usage));
   28513            4 :     ASSERT_EQ (DFmode, GET_MODE (usage));
   28514            4 :     ASSERT_EQ (USE, GET_CODE (usage->element ()));
   28515            4 :     ASSERT_EQ (NULL, usage->next ());
   28516              :   }
   28517            4 : }
   28518              : 
   28519              : /* Verify that the RTL loader copes a dump from print_rtx_function.
   28520              :    This test is target-specific since the dump contains target-specific
   28521              :    hard reg names.  */
   28522              : 
   28523              : static void
   28524            4 : ix86_test_loading_full_dump ()
   28525              : {
   28526            4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl"));
   28527              : 
   28528            4 :   ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   28529              : 
   28530            4 :   rtx_insn *insn_1 = get_insn_by_uid (1);
   28531            4 :   ASSERT_EQ (NOTE, GET_CODE (insn_1));
   28532              : 
   28533            4 :   rtx_insn *insn_7 = get_insn_by_uid (7);
   28534            4 :   ASSERT_EQ (INSN, GET_CODE (insn_7));
   28535            4 :   ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7)));
   28536              : 
   28537            4 :   rtx_insn *insn_15 = get_insn_by_uid (15);
   28538            4 :   ASSERT_EQ (INSN, GET_CODE (insn_15));
   28539            4 :   ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15)));
   28540              : 
   28541              :   /* Verify crtl->return_rtx.  */
   28542            4 :   ASSERT_EQ (REG, GET_CODE (crtl->return_rtx));
   28543            4 :   ASSERT_EQ (0, REGNO (crtl->return_rtx));
   28544            4 :   ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
   28545            4 : }
   28546              : 
   28547              : /* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns.
   28548              :    In particular, verify that it correctly loads the 2nd operand.
   28549              :    This test is target-specific since these are machine-specific
   28550              :    operands (and enums).  */
   28551              : 
   28552              : static void
   28553            4 : ix86_test_loading_unspec ()
   28554              : {
   28555            4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl"));
   28556              : 
   28557            4 :   ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   28558              : 
   28559            4 :   ASSERT_TRUE (cfun);
   28560              : 
   28561              :   /* Test of an UNSPEC.  */
   28562            4 :    rtx_insn *insn = get_insns ();
   28563            4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   28564            4 :   rtx set = single_set (insn);
   28565            4 :   ASSERT_NE (NULL, set);
   28566            4 :   rtx dst = SET_DEST (set);
   28567            4 :   ASSERT_EQ (MEM, GET_CODE (dst));
   28568            4 :   rtx src = SET_SRC (set);
   28569            4 :   ASSERT_EQ (UNSPEC, GET_CODE (src));
   28570            4 :   ASSERT_EQ (BLKmode, GET_MODE (src));
   28571            4 :   ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1));
   28572              : 
   28573            4 :   rtx v0 = XVECEXP (src, 0, 0);
   28574              : 
   28575              :   /* Verify that the two uses of the first SCRATCH have pointer
   28576              :      equality.  */
   28577            4 :   rtx scratch_a = XEXP (dst, 0);
   28578            4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_a));
   28579              : 
   28580            4 :   rtx scratch_b = XEXP (v0, 0);
   28581            4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_b));
   28582              : 
   28583            4 :   ASSERT_EQ (scratch_a, scratch_b);
   28584              : 
   28585              :   /* Verify that the two mems are thus treated as equal.  */
   28586            4 :   ASSERT_TRUE (rtx_equal_p (dst, v0));
   28587              : 
   28588              :   /* Verify that the insn is recognized.  */
   28589            4 :   ASSERT_NE(-1, recog_memoized (insn));
   28590              : 
   28591              :   /* Test of an UNSPEC_VOLATILE, which has its own enum values.  */
   28592            4 :   insn = NEXT_INSN (insn);
   28593            4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   28594              : 
   28595            4 :   set = single_set (insn);
   28596            4 :   ASSERT_NE (NULL, set);
   28597              : 
   28598            4 :   src = SET_SRC (set);
   28599            4 :   ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src));
   28600            4 :   ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1));
   28601            4 : }
   28602              : 
   28603              : /* Run all target-specific selftests.  */
   28604              : 
   28605              : static void
   28606            4 : ix86_run_selftests (void)
   28607              : {
   28608            4 :   ix86_test_dumping_hard_regs ();
   28609            4 :   ix86_test_dumping_memory_blockage ();
   28610              : 
   28611              :   /* Various tests of loading RTL dumps, here because they contain
   28612              :      ix86-isms (e.g. names of hard regs).  */
   28613            4 :   ix86_test_loading_dump_fragment_1 ();
   28614            4 :   ix86_test_loading_call_insn ();
   28615            4 :   ix86_test_loading_full_dump ();
   28616            4 :   ix86_test_loading_unspec ();
   28617            4 : }
   28618              : 
   28619              : } // namespace selftest
   28620              : 
   28621              : #endif /* CHECKING_P */
   28622              : 
   28623              : static const scoped_attribute_specs *const ix86_attribute_table[] =
   28624              : {
   28625              :   &ix86_gnu_attribute_table
   28626              : };
   28627              : 
   28628              : /* Initialize the GCC target structure.  */
   28629              : #undef TARGET_RETURN_IN_MEMORY
   28630              : #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
   28631              : 
   28632              : #undef TARGET_LEGITIMIZE_ADDRESS
   28633              : #define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
   28634              : 
   28635              : #undef TARGET_ATTRIBUTE_TABLE
   28636              : #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
   28637              : #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
   28638              : #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
   28639              : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   28640              : #  undef TARGET_MERGE_DECL_ATTRIBUTES
   28641              : #  define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
   28642              : #endif
   28643              : 
   28644              : #undef TARGET_INVALID_CONVERSION
   28645              : #define TARGET_INVALID_CONVERSION ix86_invalid_conversion
   28646              : 
   28647              : #undef TARGET_INVALID_UNARY_OP
   28648              : #define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op
   28649              : 
   28650              : #undef TARGET_INVALID_BINARY_OP
   28651              : #define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op
   28652              : 
   28653              : #undef TARGET_COMP_TYPE_ATTRIBUTES
   28654              : #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
   28655              : 
   28656              : #undef TARGET_INIT_BUILTINS
   28657              : #define TARGET_INIT_BUILTINS ix86_init_builtins
   28658              : #undef TARGET_BUILTIN_DECL
   28659              : #define TARGET_BUILTIN_DECL ix86_builtin_decl
   28660              : #undef TARGET_EXPAND_BUILTIN
   28661              : #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
   28662              : 
   28663              : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
   28664              : #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
   28665              :   ix86_builtin_vectorized_function
   28666              : 
   28667              : #undef TARGET_VECTORIZE_BUILTIN_GATHER
   28668              : #define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
   28669              : 
   28670              : #undef TARGET_VECTORIZE_BUILTIN_SCATTER
   28671              : #define TARGET_VECTORIZE_BUILTIN_SCATTER ix86_vectorize_builtin_scatter
   28672              : 
   28673              : #undef TARGET_BUILTIN_RECIPROCAL
   28674              : #define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
   28675              : 
   28676              : #undef TARGET_ASM_FUNCTION_EPILOGUE
   28677              : #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
   28678              : 
   28679              : #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
   28680              : #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
   28681              :   ix86_print_patchable_function_entry
   28682              : 
   28683              : #undef TARGET_ENCODE_SECTION_INFO
   28684              : #ifndef SUBTARGET_ENCODE_SECTION_INFO
   28685              : #define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
   28686              : #else
   28687              : #define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
   28688              : #endif
   28689              : 
   28690              : #undef TARGET_ASM_OPEN_PAREN
   28691              : #define TARGET_ASM_OPEN_PAREN ""
   28692              : #undef TARGET_ASM_CLOSE_PAREN
   28693              : #define TARGET_ASM_CLOSE_PAREN ""
   28694              : 
   28695              : #undef TARGET_ASM_BYTE_OP
   28696              : #define TARGET_ASM_BYTE_OP ASM_BYTE
   28697              : 
   28698              : #undef TARGET_ASM_ALIGNED_HI_OP
   28699              : #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
   28700              : #undef TARGET_ASM_ALIGNED_SI_OP
   28701              : #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
   28702              : #ifdef ASM_QUAD
   28703              : #undef TARGET_ASM_ALIGNED_DI_OP
   28704              : #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
   28705              : #endif
   28706              : 
   28707              : #undef TARGET_PROFILE_BEFORE_PROLOGUE
   28708              : #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
   28709              : 
   28710              : #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
   28711              : #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
   28712              : 
   28713              : #undef TARGET_ASM_UNALIGNED_HI_OP
   28714              : #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
   28715              : #undef TARGET_ASM_UNALIGNED_SI_OP
   28716              : #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
   28717              : #undef TARGET_ASM_UNALIGNED_DI_OP
   28718              : #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
   28719              : 
   28720              : #undef TARGET_PRINT_OPERAND
   28721              : #define TARGET_PRINT_OPERAND ix86_print_operand
   28722              : #undef TARGET_PRINT_OPERAND_ADDRESS
   28723              : #define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
   28724              : #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   28725              : #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
   28726              : #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
   28727              : #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
   28728              : 
   28729              : #undef TARGET_SCHED_INIT_GLOBAL
   28730              : #define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
   28731              : #undef TARGET_SCHED_ADJUST_COST
   28732              : #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
   28733              : #undef TARGET_SCHED_ISSUE_RATE
   28734              : #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
   28735              : #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
   28736              : #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   28737              :   ia32_multipass_dfa_lookahead
   28738              : #undef TARGET_SCHED_MACRO_FUSION_P
   28739              : #define TARGET_SCHED_MACRO_FUSION_P ix86_macro_fusion_p
   28740              : #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
   28741              : #define TARGET_SCHED_MACRO_FUSION_PAIR_P ix86_macro_fusion_pair_p
   28742              : 
   28743              : #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   28744              : #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
   28745              : 
   28746              : #undef TARGET_MEMMODEL_CHECK
   28747              : #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
   28748              : 
   28749              : #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
   28750              : #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
   28751              : 
   28752              : #ifdef HAVE_AS_TLS
   28753              : #undef TARGET_HAVE_TLS
   28754              : #define TARGET_HAVE_TLS true
   28755              : #endif
   28756              : #undef TARGET_CANNOT_FORCE_CONST_MEM
   28757              : #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
   28758              : #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
   28759              : #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
   28760              : 
   28761              : #undef TARGET_DELEGITIMIZE_ADDRESS
   28762              : #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
   28763              : 
   28764              : #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
   28765              : #define TARGET_CONST_NOT_OK_FOR_DEBUG_P ix86_const_not_ok_for_debug_p
   28766              : 
   28767              : #undef TARGET_MS_BITFIELD_LAYOUT_P
   28768              : #define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
   28769              : 
   28770              : #if TARGET_MACHO
   28771              : #undef TARGET_BINDS_LOCAL_P
   28772              : #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
   28773              : #else
   28774              : #undef TARGET_BINDS_LOCAL_P
   28775              : #define TARGET_BINDS_LOCAL_P ix86_binds_local_p
   28776              : #endif
   28777              : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   28778              : #undef TARGET_BINDS_LOCAL_P
   28779              : #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
   28780              : #endif
   28781              : 
   28782              : #undef TARGET_ASM_OUTPUT_MI_THUNK
   28783              : #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
   28784              : #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   28785              : #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
   28786              : 
   28787              : #undef TARGET_ASM_FILE_START
   28788              : #define TARGET_ASM_FILE_START x86_file_start
   28789              : 
   28790              : #undef TARGET_OPTION_OVERRIDE
   28791              : #define TARGET_OPTION_OVERRIDE ix86_option_override
   28792              : 
   28793              : #undef TARGET_REGISTER_MOVE_COST
   28794              : #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
   28795              : #undef TARGET_MEMORY_MOVE_COST
   28796              : #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
   28797              : #undef TARGET_RTX_COSTS
   28798              : #define TARGET_RTX_COSTS ix86_rtx_costs
   28799              : #undef TARGET_INSN_COST
   28800              : #define TARGET_INSN_COST ix86_insn_cost
   28801              : #undef TARGET_ADDRESS_COST
   28802              : #define TARGET_ADDRESS_COST ix86_address_cost
   28803              : 
   28804              : #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
   28805              : #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
   28806              :   ix86_use_by_pieces_infrastructure_p
   28807              : 
   28808              : #undef TARGET_OVERLAP_OP_BY_PIECES_P
   28809              : #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true
   28810              : 
   28811              : #undef TARGET_FLAGS_REGNUM
   28812              : #define TARGET_FLAGS_REGNUM FLAGS_REG
   28813              : #undef TARGET_FIXED_CONDITION_CODE_REGS
   28814              : #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
   28815              : #undef TARGET_CC_MODES_COMPATIBLE
   28816              : #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
   28817              : 
   28818              : #undef TARGET_MACHINE_DEPENDENT_REORG
   28819              : #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
   28820              : 
   28821              : #undef TARGET_BUILD_BUILTIN_VA_LIST
   28822              : #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
   28823              : 
   28824              : #undef TARGET_FOLD_BUILTIN
   28825              : #define TARGET_FOLD_BUILTIN ix86_fold_builtin
   28826              : 
   28827              : #undef TARGET_GIMPLE_FOLD_BUILTIN
   28828              : #define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
   28829              : 
   28830              : #undef TARGET_COMPARE_VERSION_PRIORITY
   28831              : #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
   28832              : 
   28833              : #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
   28834              : #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
   28835              :   ix86_generate_version_dispatcher_body
   28836              : 
   28837              : #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
   28838              : #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
   28839              :   ix86_get_function_versions_dispatcher
   28840              : 
   28841              : #undef TARGET_ENUM_VA_LIST_P
   28842              : #define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
   28843              : 
   28844              : #undef TARGET_FN_ABI_VA_LIST
   28845              : #define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
   28846              : 
   28847              : #undef TARGET_CANONICAL_VA_LIST_TYPE
   28848              : #define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
   28849              : 
   28850              : #undef TARGET_EXPAND_BUILTIN_VA_START
   28851              : #define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
   28852              : 
   28853              : #undef TARGET_MD_ASM_ADJUST
   28854              : #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
   28855              : 
   28856              : #undef TARGET_C_EXCESS_PRECISION
   28857              : #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
   28858              : #undef TARGET_C_BITINT_TYPE_INFO
   28859              : #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
   28860              : #undef TARGET_C_MODE_FOR_FLOATING_TYPE
   28861              : #define TARGET_C_MODE_FOR_FLOATING_TYPE ix86_c_mode_for_floating_type
   28862              : #undef TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE
   28863              : #define TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE ix86_cxx_adjust_cdtor_callabi_fntype
   28864              : #undef TARGET_PROMOTE_PROTOTYPES
   28865              : #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
   28866              : #undef TARGET_PUSH_ARGUMENT
   28867              : #define TARGET_PUSH_ARGUMENT ix86_push_argument
   28868              : #undef TARGET_SETUP_INCOMING_VARARGS
   28869              : #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
   28870              : #undef TARGET_MUST_PASS_IN_STACK
   28871              : #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
   28872              : #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
   28873              : #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args
   28874              : #undef TARGET_FUNCTION_ARG_ADVANCE
   28875              : #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
   28876              : #undef TARGET_FUNCTION_ARG
   28877              : #define TARGET_FUNCTION_ARG ix86_function_arg
   28878              : #undef TARGET_INIT_PIC_REG
   28879              : #define TARGET_INIT_PIC_REG ix86_init_pic_reg
   28880              : #undef TARGET_USE_PSEUDO_PIC_REG
   28881              : #define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
   28882              : #undef TARGET_FUNCTION_ARG_BOUNDARY
   28883              : #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
   28884              : #undef TARGET_PASS_BY_REFERENCE
   28885              : #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
   28886              : #undef TARGET_INTERNAL_ARG_POINTER
   28887              : #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
   28888              : #undef TARGET_UPDATE_STACK_BOUNDARY
   28889              : #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
   28890              : #undef TARGET_GET_DRAP_RTX
   28891              : #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
   28892              : #undef TARGET_STRICT_ARGUMENT_NAMING
   28893              : #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   28894              : #undef TARGET_STATIC_CHAIN
   28895              : #define TARGET_STATIC_CHAIN ix86_static_chain
   28896              : #undef TARGET_TRAMPOLINE_INIT
   28897              : #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
   28898              : #undef TARGET_RETURN_POPS_ARGS
   28899              : #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
   28900              : 
   28901              : #undef TARGET_WARN_FUNC_RETURN
   28902              : #define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
   28903              : 
   28904              : #undef TARGET_LEGITIMATE_COMBINED_INSN
   28905              : #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
   28906              : 
   28907              : #undef TARGET_ASAN_SHADOW_OFFSET
   28908              : #define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
   28909              : 
   28910              : #undef TARGET_GIMPLIFY_VA_ARG_EXPR
   28911              : #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
   28912              : 
   28913              : #undef TARGET_SCALAR_MODE_SUPPORTED_P
   28914              : #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
   28915              : 
   28916              : #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
   28917              : #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
   28918              : ix86_libgcc_floating_mode_supported_p
   28919              : 
   28920              : #undef TARGET_VECTOR_MODE_SUPPORTED_P
   28921              : #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
   28922              : 
   28923              : #undef TARGET_C_MODE_FOR_SUFFIX
   28924              : #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
   28925              : 
   28926              : #ifdef HAVE_AS_TLS
   28927              : #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
   28928              : #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
   28929              : #endif
   28930              : 
   28931              : #ifdef SUBTARGET_INSERT_ATTRIBUTES
   28932              : #undef TARGET_INSERT_ATTRIBUTES
   28933              : #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
   28934              : #endif
   28935              : 
   28936              : #undef TARGET_MANGLE_TYPE
   28937              : #define TARGET_MANGLE_TYPE ix86_mangle_type
   28938              : 
   28939              : #undef TARGET_EMIT_SUPPORT_TINFOS
   28940              : #define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos
   28941              : 
   28942              : #undef TARGET_STACK_PROTECT_GUARD
   28943              : #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard
   28944              : 
   28945              : #undef TARGET_STACK_PROTECT_GUARD_SYMBOL_P
   28946              : #define TARGET_STACK_PROTECT_GUARD_SYMBOL_P \
   28947              :   ix86_stack_protect_guard_symbol_p
   28948              : 
   28949              : #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
   28950              : #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \
   28951              :   ix86_stack_protect_runtime_enabled_p
   28952              : 
   28953              : #if !TARGET_MACHO
   28954              : #undef TARGET_STACK_PROTECT_FAIL
   28955              : #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
   28956              : #endif
   28957              : 
   28958              : #undef TARGET_FUNCTION_VALUE
   28959              : #define TARGET_FUNCTION_VALUE ix86_function_value
   28960              : 
   28961              : #undef TARGET_FUNCTION_VALUE_REGNO_P
   28962              : #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
   28963              : 
   28964              : #undef TARGET_ZERO_CALL_USED_REGS
   28965              : #define TARGET_ZERO_CALL_USED_REGS ix86_zero_call_used_regs
   28966              : 
   28967              : #undef TARGET_PROMOTE_FUNCTION_MODE
   28968              : #define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
   28969              : 
   28970              : #undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
   28971              : #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
   28972              : 
   28973              : #undef TARGET_MEMBER_TYPE_FORCES_BLK
   28974              : #define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
   28975              : 
   28976              : #undef TARGET_INSTANTIATE_DECLS
   28977              : #define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
   28978              : 
   28979              : #undef TARGET_SECONDARY_RELOAD
   28980              : #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
   28981              : #undef TARGET_SECONDARY_MEMORY_NEEDED
   28982              : #define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed
   28983              : #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
   28984              : #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
   28985              : 
   28986              : #undef TARGET_CLASS_MAX_NREGS
   28987              : #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
   28988              : 
   28989              : #undef TARGET_PREFERRED_RELOAD_CLASS
   28990              : #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
   28991              : #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
   28992              : #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
   28993              : /* When this hook returns true for MODE, the compiler allows
   28994              :    registers explicitly used in the rtl to be used as spill registers
   28995              :    but prevents the compiler from extending the lifetime of these
   28996              :    registers.  */
   28997              : #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
   28998              : #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
   28999              : #undef TARGET_CLASS_LIKELY_SPILLED_P
   29000              : #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
   29001              : #undef TARGET_CALLEE_SAVE_COST
   29002              : #define TARGET_CALLEE_SAVE_COST ix86_callee_save_cost
   29003              : 
   29004              : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
   29005              : #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
   29006              :   ix86_builtin_vectorization_cost
   29007              : #undef TARGET_VECTORIZE_VEC_PERM_CONST
   29008              : #define TARGET_VECTORIZE_VEC_PERM_CONST ix86_vectorize_vec_perm_const
   29009              : #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
   29010              : #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
   29011              :   ix86_preferred_simd_mode
   29012              : #undef TARGET_VECTORIZE_SPLIT_REDUCTION
   29013              : #define TARGET_VECTORIZE_SPLIT_REDUCTION \
   29014              :   ix86_split_reduction
   29015              : #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
   29016              : #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
   29017              :   ix86_autovectorize_vector_modes
   29018              : #undef TARGET_VECTORIZE_GET_MASK_MODE
   29019              : #define TARGET_VECTORIZE_GET_MASK_MODE ix86_get_mask_mode
   29020              : #undef TARGET_VECTORIZE_CREATE_COSTS
   29021              : #define TARGET_VECTORIZE_CREATE_COSTS ix86_vectorize_create_costs
   29022              : 
   29023              : #undef TARGET_SET_CURRENT_FUNCTION
   29024              : #define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
   29025              : 
   29026              : #undef TARGET_OPTION_VALID_ATTRIBUTE_P
   29027              : #define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
   29028              : 
   29029              : #undef TARGET_OPTION_SAVE
   29030              : #define TARGET_OPTION_SAVE ix86_function_specific_save
   29031              : 
   29032              : #undef TARGET_OPTION_RESTORE
   29033              : #define TARGET_OPTION_RESTORE ix86_function_specific_restore
   29034              : 
   29035              : #undef TARGET_OPTION_POST_STREAM_IN
   29036              : #define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
   29037              : 
   29038              : #undef TARGET_OPTION_PRINT
   29039              : #define TARGET_OPTION_PRINT ix86_function_specific_print
   29040              : 
   29041              : #undef TARGET_CAN_INLINE_P
   29042              : #define TARGET_CAN_INLINE_P ix86_can_inline_p
   29043              : 
   29044              : #undef TARGET_LEGITIMATE_ADDRESS_P
   29045              : #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
   29046              : 
   29047              : #undef TARGET_REGISTER_PRIORITY
   29048              : #define TARGET_REGISTER_PRIORITY ix86_register_priority
   29049              : 
   29050              : #undef TARGET_REGISTER_USAGE_LEVELING_P
   29051              : #define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
   29052              : 
   29053              : #undef TARGET_LEGITIMATE_CONSTANT_P
   29054              : #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
   29055              : 
   29056              : #undef TARGET_COMPUTE_FRAME_LAYOUT
   29057              : #define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
   29058              : 
   29059              : #undef TARGET_FRAME_POINTER_REQUIRED
   29060              : #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
   29061              : 
   29062              : #undef TARGET_CAN_ELIMINATE
   29063              : #define TARGET_CAN_ELIMINATE ix86_can_eliminate
   29064              : 
   29065              : #undef TARGET_EXTRA_LIVE_ON_ENTRY
   29066              : #define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
   29067              : 
   29068              : #undef TARGET_ASM_CODE_END
   29069              : #define TARGET_ASM_CODE_END ix86_code_end
   29070              : 
   29071              : #undef TARGET_CONDITIONAL_REGISTER_USAGE
   29072              : #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
   29073              : 
   29074              : #undef TARGET_CANONICALIZE_COMPARISON
   29075              : #define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison
   29076              : 
   29077              : #undef TARGET_LOOP_UNROLL_ADJUST
   29078              : #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust
   29079              : 
   29080              : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   29081              : #undef TARGET_SPILL_CLASS
   29082              : #define TARGET_SPILL_CLASS ix86_spill_class
   29083              : 
   29084              : #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
   29085              : #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
   29086              :   ix86_simd_clone_compute_vecsize_and_simdlen
   29087              : 
   29088              : #undef TARGET_SIMD_CLONE_ADJUST
   29089              : #define TARGET_SIMD_CLONE_ADJUST ix86_simd_clone_adjust
   29090              : 
   29091              : #undef TARGET_SIMD_CLONE_USABLE
   29092              : #define TARGET_SIMD_CLONE_USABLE ix86_simd_clone_usable
   29093              : 
   29094              : #undef TARGET_OMP_DEVICE_KIND_ARCH_ISA
   29095              : #define TARGET_OMP_DEVICE_KIND_ARCH_ISA ix86_omp_device_kind_arch_isa
   29096              : 
   29097              : #undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
   29098              : #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
   29099              :   ix86_float_exceptions_rounding_supported_p
   29100              : 
   29101              : #undef TARGET_MODE_EMIT
   29102              : #define TARGET_MODE_EMIT ix86_emit_mode_set
   29103              : 
   29104              : #undef TARGET_MODE_NEEDED
   29105              : #define TARGET_MODE_NEEDED ix86_mode_needed
   29106              : 
   29107              : #undef TARGET_MODE_AFTER
   29108              : #define TARGET_MODE_AFTER ix86_mode_after
   29109              : 
   29110              : #undef TARGET_MODE_ENTRY
   29111              : #define TARGET_MODE_ENTRY ix86_mode_entry
   29112              : 
   29113              : #undef TARGET_MODE_EXIT
   29114              : #define TARGET_MODE_EXIT ix86_mode_exit
   29115              : 
   29116              : #undef TARGET_MODE_PRIORITY
   29117              : #define TARGET_MODE_PRIORITY ix86_mode_priority
   29118              : 
   29119              : #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
   29120              : #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
   29121              : 
   29122              : #undef TARGET_OFFLOAD_OPTIONS
   29123              : #define TARGET_OFFLOAD_OPTIONS \
   29124              :   ix86_offload_options
   29125              : 
   29126              : #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
   29127              : #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
   29128              : 
   29129              : #undef TARGET_OPTAB_SUPPORTED_P
   29130              : #define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
   29131              : 
   29132              : #undef TARGET_HARD_REGNO_SCRATCH_OK
   29133              : #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok
   29134              : 
   29135              : #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
   29136              : #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST
   29137              : 
   29138              : #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
   29139              : #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid
   29140              : 
   29141              : #undef TARGET_INIT_LIBFUNCS
   29142              : #define TARGET_INIT_LIBFUNCS ix86_init_libfuncs
   29143              : 
   29144              : #undef TARGET_EXPAND_DIVMOD_LIBFUNC
   29145              : #define TARGET_EXPAND_DIVMOD_LIBFUNC ix86_expand_divmod_libfunc
   29146              : 
   29147              : #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
   29148              : #define TARGET_MAX_NOCE_IFCVT_SEQ_COST ix86_max_noce_ifcvt_seq_cost
   29149              : 
   29150              : #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
   29151              : #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
   29152              : 
   29153              : #undef TARGET_HARD_REGNO_NREGS
   29154              : #define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
   29155              : #undef TARGET_HARD_REGNO_MODE_OK
   29156              : #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
   29157              : 
   29158              : #undef TARGET_MODES_TIEABLE_P
   29159              : #define TARGET_MODES_TIEABLE_P ix86_modes_tieable_p
   29160              : 
   29161              : #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
   29162              : #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
   29163              :   ix86_hard_regno_call_part_clobbered
   29164              : 
   29165              : #undef TARGET_FNTYPE_ABI
   29166              : #define TARGET_FNTYPE_ABI ix86_fntype_abi
   29167              : 
   29168              : #undef TARGET_CAN_CHANGE_MODE_CLASS
   29169              : #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
   29170              : 
   29171              : #undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT
   29172              : #define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment
   29173              : 
   29174              : #undef TARGET_STATIC_RTX_ALIGNMENT
   29175              : #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
   29176              : #undef TARGET_CONSTANT_ALIGNMENT
   29177              : #define TARGET_CONSTANT_ALIGNMENT ix86_constant_alignment
   29178              : 
   29179              : #undef TARGET_EMPTY_RECORD_P
   29180              : #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
   29181              : 
   29182              : #undef TARGET_WARN_PARAMETER_PASSING_ABI
   29183              : #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
   29184              : 
   29185              : #undef TARGET_GET_MULTILIB_ABI_NAME
   29186              : #define TARGET_GET_MULTILIB_ABI_NAME \
   29187              :   ix86_get_multilib_abi_name
   29188              : 
   29189              : #undef TARGET_IFUNC_REF_LOCAL_OK
   29190              : #define TARGET_IFUNC_REF_LOCAL_OK ix86_ifunc_ref_local_ok
   29191              : 
   29192              : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   29193              : # undef TARGET_ASM_RELOC_RW_MASK
   29194              : # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
   29195              : #endif
   29196              : 
   29197              : #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
   29198              : #define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
   29199              : 
   29200              : #undef TARGET_MEMTAG_ADD_TAG
   29201              : #define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
   29202              : 
   29203              : #undef TARGET_MEMTAG_SET_TAG
   29204              : #define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
   29205              : 
   29206              : #undef TARGET_MEMTAG_EXTRACT_TAG
   29207              : #define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
   29208              : 
   29209              : #undef TARGET_MEMTAG_UNTAGGED_POINTER
   29210              : #define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
   29211              : 
   29212              : #undef TARGET_MEMTAG_TAG_BITSIZE
   29213              : #define TARGET_MEMTAG_TAG_BITSIZE ix86_memtag_tag_bitsize
   29214              : 
   29215              : #undef TARGET_GEN_CCMP_FIRST
   29216              : #define TARGET_GEN_CCMP_FIRST ix86_gen_ccmp_first
   29217              : 
   29218              : #undef TARGET_GEN_CCMP_NEXT
   29219              : #define TARGET_GEN_CCMP_NEXT ix86_gen_ccmp_next
   29220              : 
   29221              : #undef TARGET_HAVE_CCMP
   29222              : #define TARGET_HAVE_CCMP ix86_have_ccmp
   29223              : 
   29224              : #undef TARGET_MODE_CAN_TRANSFER_BITS
   29225              : #define TARGET_MODE_CAN_TRANSFER_BITS ix86_mode_can_transfer_bits
   29226              : 
   29227              : #undef TARGET_REDZONE_CLOBBER
   29228              : #define TARGET_REDZONE_CLOBBER ix86_redzone_clobber
   29229              : 
   29230              : static bool
   29231        95857 : ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
   29232              : {
   29233              : #ifdef OPTION_GLIBC
   29234        95857 :   if (OPTION_GLIBC)
   29235        95857 :     return (built_in_function)fcode == BUILT_IN_MEMPCPY;
   29236              :   else
   29237              :     return false;
   29238              : #else
   29239              :   return false;
   29240              : #endif
   29241              : }
   29242              : 
   29243              : #undef TARGET_LIBC_HAS_FAST_FUNCTION
   29244              : #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function
   29245              : 
   29246              : static unsigned
   29247        76397 : ix86_libm_function_max_error (unsigned cfn, machine_mode mode,
   29248              :                               bool boundary_p)
   29249              : {
   29250              : #ifdef OPTION_GLIBC
   29251        76397 :   bool glibc_p = OPTION_GLIBC;
   29252              : #else
   29253              :   bool glibc_p = false;
   29254              : #endif
   29255        76397 :   if (glibc_p)
   29256              :     {
   29257              :       /* If __FAST_MATH__ is defined, glibc provides libmvec.  */
   29258        76397 :       unsigned int libmvec_ret = 0;
   29259        76397 :       if (!flag_trapping_math
   29260         8274 :           && flag_unsafe_math_optimizations
   29261         3364 :           && flag_finite_math_only
   29262         3338 :           && !flag_signed_zeros
   29263         3338 :           && !flag_errno_math)
   29264         3338 :         switch (cfn)
   29265              :           {
   29266         1388 :           CASE_CFN_COS:
   29267         1388 :           CASE_CFN_COS_FN:
   29268         1388 :           CASE_CFN_SIN:
   29269         1388 :           CASE_CFN_SIN_FN:
   29270         1388 :             if (!boundary_p)
   29271              :               {
   29272              :                 /* With non-default rounding modes, libmvec provides
   29273              :                    complete garbage in results.  E.g.
   29274              :                    _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD
   29275              :                    returns 0.00333309174f rather than 1.40129846e-45f.  */
   29276          583 :                 if (flag_rounding_math)
   29277              :                   return ~0U;
   29278              :                 /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
   29279              :                    claims libmvec maximum error is 4ulps.
   29280              :                    My own random testing indicates 2ulps for SFmode and
   29281              :                    0.5ulps for DFmode, but let's go with the 4ulps.  */
   29282              :                 libmvec_ret = 4;
   29283              :               }
   29284              :             break;
   29285              :           default:
   29286              :             break;
   29287              :           }
   29288        76397 :       unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode,
   29289              :                                                               boundary_p);
   29290        76397 :       return MAX (ret, libmvec_ret);
   29291              :     }
   29292            0 :   return default_libm_function_max_error (cfn, mode, boundary_p);
   29293              : }
   29294              : 
   29295              : #undef TARGET_LIBM_FUNCTION_MAX_ERROR
   29296              : #define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error
   29297              : 
   29298              : #if TARGET_MACHO
   29299              : static bool
   29300              : ix86_cannot_copy_insn_p (rtx_insn *insn)
   29301              : {
   29302              :   if (TARGET_64BIT)
   29303              :     return false;
   29304              : 
   29305              :   rtx set = single_set (insn);
   29306              :   if (set)
   29307              :     {
   29308              :       rtx src = SET_SRC (set);
   29309              :       if (GET_CODE (src) == UNSPEC
   29310              :           && XINT (src, 1) == UNSPEC_SET_GOT)
   29311              :         return true;
   29312              :     }
   29313              :   return false;
   29314              : }
   29315              : 
   29316              : #undef TARGET_CANNOT_COPY_INSN_P
   29317              : #define TARGET_CANNOT_COPY_INSN_P ix86_cannot_copy_insn_p
   29318              : 
   29319              : #endif
   29320              : 
   29321              : #if CHECKING_P
   29322              : #undef TARGET_RUN_TARGET_SELFTESTS
   29323              : #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
   29324              : #endif /* #if CHECKING_P */
   29325              : 
   29326              : #undef TARGET_DOCUMENTATION_NAME
   29327              : #define TARGET_DOCUMENTATION_NAME "x86"
   29328              : 
   29329              : /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS.  */
   29330              : sbitmap
   29331       742256 : ix86_get_separate_components (void)
   29332              : {
   29333       742256 :   HOST_WIDE_INT offset, to_allocate;
   29334       742256 :   sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
   29335       742256 :   bitmap_clear (components);
   29336       742256 :   struct machine_function *m = cfun->machine;
   29337              : 
   29338       742256 :   offset = m->frame.stack_pointer_offset;
   29339       742256 :   to_allocate = offset - m->frame.sse_reg_save_offset;
   29340              : 
   29341              :   /* Shrink wrap separate uses MOV, which means APX PPX cannot be used.
   29342              :      Experiments show that APX PPX can speed up the prologue.  If the function
   29343              :      does not exit early during actual execution, then using APX PPX is faster.
   29344              :      If the function always exits early during actual execution, then shrink
   29345              :      wrap separate reduces the number of MOV (PUSH/POP) instructions actually
   29346              :      executed, thus speeding up execution.
   29347              :      foo:
   29348              :           movl    $1, %eax
   29349              :           testq   %rdi, %rdi
   29350              :           jne.L60
   29351              :           ret   ---> early return.
   29352              :     .L60:
   29353              :           subq    $88, %rsp     ---> belong to prologue.
   29354              :           xorl    %eax, %eax
   29355              :           movq    %rbx, 40 (%rsp) ---> belong to prologue.
   29356              :           movq    8 (%rdi), %rbx
   29357              :           movq    %rbp, 48 (%rsp) ---> belong to prologue.
   29358              :           movq    %rdi, %rbp
   29359              :           testq   %rbx, %rbx
   29360              :           jne.L61
   29361              :           movq    40 (%rsp), %rbx
   29362              :           movq    48 (%rsp), %rbp
   29363              :           addq    $88, %rsp
   29364              :           ret
   29365              :      .L61:
   29366              :           movq    %r12, 56 (%rsp) ---> belong to prologue.
   29367              :           movq    %r13, 64 (%rsp) ---> belong to prologue.
   29368              :           movq    %r14, 72 (%rsp) ---> belong to prologue.
   29369              :      ... ...
   29370              : 
   29371              :      Disable shrink wrap separate when PPX is enabled.  */
   29372       742256 :   if ((TARGET_APX_PPX && !crtl->calls_eh_return)
   29373       741782 :       || cfun->machine->func_type != TYPE_NORMAL
   29374              :       || TARGET_SEH
   29375       741684 :       || crtl->stack_realign_needed
   29376       732518 :       || m->call_ms2sysv)
   29377              :     return components;
   29378              : 
   29379              :   /* Since shrink wrapping separate uses MOV instead of PUSH/POP.
   29380              :      Disable shrink wrap separate when MOV is prohibited.  */
   29381       730596 :   if (save_regs_using_push_pop (to_allocate))
   29382              :     return components;
   29383              : 
   29384     33041226 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29385     32685944 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
   29386              :       {
   29387              :         /* Skip registers with large offsets, where a pseudo may be needed.  */
   29388       612291 :         if (IN_RANGE (offset, -0x8000, 0x7fff))
   29389       611169 :           bitmap_set_bit (components, regno);
   29390       658355 :         offset += UNITS_PER_WORD;
   29391              :       }
   29392              : 
   29393              :   /* Don't mess with the following registers.  */
   29394       355282 :   if (frame_pointer_needed)
   29395         6399 :     bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);
   29396              : 
   29397       355282 :   if (crtl->drap_reg)
   29398          138 :     bitmap_clear_bit (components, REGNO (crtl->drap_reg));
   29399              : 
   29400       355282 :   if (pic_offset_table_rtx)
   29401        29982 :     bitmap_clear_bit (components, REAL_PIC_OFFSET_TABLE_REGNUM);
   29402              : 
   29403              :   return components;
   29404              : }
   29405              : 
   29406              : /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB.  */
   29407              : sbitmap
   29408      9479271 : ix86_components_for_bb (basic_block bb)
   29409              : {
   29410      9479271 :   bitmap in = DF_LIVE_IN (bb);
   29411      9479271 :   bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
   29412      9479271 :   bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;
   29413              : 
   29414      9479271 :   sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
   29415      9479271 :   bitmap_clear (components);
   29416              : 
   29417      9479271 :   function_abi_aggregator callee_abis;
   29418      9479271 :   rtx_insn *insn;
   29419    112732620 :   FOR_BB_INSNS (bb, insn)
   29420    103253349 :     if (CALL_P (insn))
   29421      3120844 :       callee_abis.note_callee_abi (insn_callee_abi (insn));
   29422      9479271 :   HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
   29423              : 
   29424              :   /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets.  */
   29425    881572203 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29426    872092932 :     if (!fixed_regs[regno]
   29427    872092932 :         && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
   29428    443004650 :             || bitmap_bit_p (in, regno)
   29429    417113116 :             || bitmap_bit_p (gen, regno)
   29430    404383183 :             || bitmap_bit_p (kill, regno)))
   29431     38938230 :       bitmap_set_bit (components, regno);
   29432              : 
   29433      9479271 :   return components;
   29434              : }
   29435              : 
   29436              : /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS.  */
   29437              : void
   29438       474883 : ix86_disqualify_components (sbitmap, edge, sbitmap, bool)
   29439              : {
   29440              :   /* Nothing to do for x86.  */
   29441       474883 : }
   29442              : 
   29443              : /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS.  */
   29444              : void
   29445       162682 : ix86_emit_prologue_components (sbitmap components)
   29446              : {
   29447       162682 :   HOST_WIDE_INT cfa_offset;
   29448       162682 :   struct machine_function *m = cfun->machine;
   29449              : 
   29450       162682 :   cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
   29451       162682 :                - m->frame.stack_pointer_offset;
   29452     15129426 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29453     14966744 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
   29454              :       {
   29455       741034 :         if (bitmap_bit_p (components, regno))
   29456       193114 :           ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
   29457       790593 :         cfa_offset -= UNITS_PER_WORD;
   29458              :       }
   29459       162682 : }
   29460              : 
   29461              : /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS.  */
   29462              : void
   29463       146569 : ix86_emit_epilogue_components (sbitmap components)
   29464              : {
   29465       146569 :   HOST_WIDE_INT cfa_offset;
   29466       146569 :   struct machine_function *m = cfun->machine;
   29467       146569 :   cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
   29468       146569 :                - m->frame.stack_pointer_offset;
   29469              : 
   29470     13630917 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29471     13484348 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
   29472              :       {
   29473       669388 :         if (bitmap_bit_p (components, regno))
   29474              :           {
   29475       258243 :             rtx reg = gen_rtx_REG (word_mode, regno);
   29476       258243 :             rtx mem;
   29477       258243 :             rtx_insn *insn;
   29478              : 
   29479       258243 :             mem = choose_baseaddr (cfa_offset, NULL);
   29480       258243 :             mem = gen_frame_mem (word_mode, mem);
   29481       258243 :             insn = emit_move_insn (reg, mem);
   29482              : 
   29483       258243 :             RTX_FRAME_RELATED_P (insn) = 1;
   29484       258243 :             add_reg_note (insn, REG_CFA_RESTORE, reg);
   29485              :           }
   29486       724885 :         cfa_offset -= UNITS_PER_WORD;
   29487              :       }
   29488       146569 : }
   29489              : 
   29490              : /* Implement TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS.  */
   29491              : void
   29492        44244 : ix86_set_handled_components (sbitmap components)
   29493              : {
   29494      4114692 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29495      4070448 :     if (bitmap_bit_p (components, regno))
   29496              :       {
   29497       105752 :         cfun->machine->reg_is_wrapped_separately[regno] = true;
   29498       105752 :         cfun->machine->use_fast_prologue_epilogue = true;
   29499       105752 :         cfun->machine->frame.save_regs_using_mov = true;
   29500              :       }
   29501        44244 : }
   29502              : 
   29503              : #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
   29504              : #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS ix86_get_separate_components
   29505              : #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
   29506              : #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB ix86_components_for_bb
   29507              : #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
   29508              : #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS ix86_disqualify_components
   29509              : #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
   29510              : #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
   29511              :   ix86_emit_prologue_components
   29512              : #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
   29513              : #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
   29514              :   ix86_emit_epilogue_components
   29515              : #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
   29516              : #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS ix86_set_handled_components
   29517              : 
   29518              : struct gcc_target targetm = TARGET_INITIALIZER;
   29519              : 
   29520              : #include "gt-i386.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.