LCOV - code coverage report
Current view: top level - gcc/config/i386 - i386.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.4 % 13184 11792
Test Date: 2026-10-03 16:17:38 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 "internal-fn.h"
      73              : #include "tree-vectorizer.h"
      74              : #include "shrink-wrap.h"
      75              : #include "builtins.h"
      76              : #include "rtl-iter.h"
      77              : #include "tree-iterator.h"
      78              : #include "dbgcnt.h"
      79              : #include "case-cfn-macros.h"
      80              : #include "dojump.h"
      81              : #include "fold-const-call.h"
      82              : #include "tree-vrp.h"
      83              : #include "tree-ssanames.h"
      84              : #include "selftest.h"
      85              : #include "selftest-rtl.h"
      86              : #include "print-rtl.h"
      87              : #include "intl.h"
      88              : #include "ifcvt.h"
      89              : #include "symbol-summary.h"
      90              : #include "sreal.h"
      91              : #include "ipa-cp.h"
      92              : #include "ipa-prop.h"
      93              : #include "ipa-fnsummary.h"
      94              : #include "wide-int-bitmask.h"
      95              : #include "tree-vector-builder.h"
      96              : #include "debug.h"
      97              : #include "dwarf2out.h"
      98              : #include "i386-options.h"
      99              : #include "i386-builtins.h"
     100              : #include "i386-expand.h"
     101              : #include "i386-features.h"
     102              : #include "function-abi.h"
     103              : #include "rtl-error.h"
     104              : #include "gimple-pretty-print.h"
     105              : 
     106              : /* This file should be included last.  */
     107              : #include "target-def.h"
     108              : 
     109              : static void ix86_print_operand_address_as (FILE *, rtx, addr_space_t, bool);
     110              : static void ix86_emit_restore_reg_using_pop (rtx, bool = false);
     111              : static const predefined_function_abi & ix86_alternate_abi (void);
     112              : 
     113              : 
     114              : #ifndef CHECK_STACK_LIMIT
     115              : #define CHECK_STACK_LIMIT (-1)
     116              : #endif
     117              : 
     118              : /* Return index of given mode in mult and division cost tables.  */
     119              : #define MODE_INDEX(mode)                                        \
     120              :   ((mode) == QImode ? 0                                         \
     121              :    : (mode) == HImode ? 1                                       \
     122              :    : (mode) == SImode ? 2                                       \
     123              :    : (mode) == DImode ? 3                                       \
     124              :    : 4)
     125              : 
     126              : 
     127              : /* Set by -mtune.  */
     128              : const struct processor_costs *ix86_tune_cost = NULL;
     129              : 
     130              : /* Set by -mtune or -Os.  */
     131              : const struct processor_costs *ix86_cost = NULL;
     132              : 
     133              : /* In case the average insn count for single function invocation is
     134              :    lower than this constant, emit fast (but longer) prologue and
     135              :    epilogue code.  */
     136              : #define FAST_PROLOGUE_INSN_COUNT 20
     137              : 
     138              : /* Names for 8 (low), 8 (high), and 16-bit registers, respectively.  */
     139              : static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
     140              : static const char *const qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
     141              : static const char *const hi_reg_name[] = HI_REGISTER_NAMES;
     142              : 
     143              : /* Array of the smallest class containing reg number REGNO, indexed by
     144              :    REGNO.  Used by REGNO_REG_CLASS in i386.h.  */
     145              : 
     146              : enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
     147              : {
     148              :   /* ax, dx, cx, bx */
     149              :   AREG, DREG, CREG, BREG,
     150              :   /* si, di, bp, sp */
     151              :   SIREG, DIREG, NON_Q_REGS, NON_Q_REGS,
     152              :   /* FP registers */
     153              :   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
     154              :   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
     155              :   /* arg pointer, flags, fpsr, frame */
     156              :   NON_Q_REGS, NO_REGS, NO_REGS, NON_Q_REGS,
     157              :   /* SSE registers */
     158              :   SSE_FIRST_REG, SSE_REGS, SSE_REGS, SSE_REGS,
     159              :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     160              :   /* MMX registers */
     161              :   MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
     162              :   MMX_REGS, MMX_REGS, MMX_REGS, MMX_REGS,
     163              :   /* REX registers */
     164              :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     165              :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     166              :   /* SSE REX registers */
     167              :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     168              :   SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
     169              :   /* AVX-512 SSE registers */
     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              :   ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS, ALL_SSE_REGS,
     174              :   /* Mask registers.  */
     175              :   ALL_MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
     176              :   MASK_REGS, MASK_REGS, MASK_REGS, MASK_REGS,
     177              :   /* REX2 registers */
     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              :   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
     182              :   /* TMM fake register placeholder */
     183              :   NO_REGS,
     184              :   /* Block Scale register */
     185              :   NO_REGS,
     186              : };
     187              : 
     188              : /* The "default" register map used in 32bit mode.  */
     189              : 
     190              : unsigned int const debugger_register_map[FIRST_PSEUDO_REGISTER] =
     191              : {
     192              :   /* general regs */
     193              :   0, 2, 1, 3, 6, 7, 4, 5,
     194              :   /* fp regs */
     195              :   12, 13, 14, 15, 16, 17, 18, 19,
     196              :   /* arg, flags, fpsr, frame */
     197              :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     198              :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     199              :   /* SSE */
     200              :   21, 22, 23, 24, 25, 26, 27, 28,
     201              :   /* MMX */
     202              :   29, 30, 31, 32, 33, 34, 35, 36,
     203              :   /* extended integer registers */
     204              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     205              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     206              :   /* extended sse registers */
     207              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     208              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     209              :   /* AVX-512 registers 16-23 */
     210              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     211              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     212              :   /* AVX-512 registers 24-31 */
     213              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     214              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     215              :   /* Mask registers */
     216              :   93, 94, 95, 96, 97, 98, 99, 100,
     217              :   /* APX r16-r31 */
     218              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     219              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     220              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     221              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     222              :   /* TMM fake register placeholder */
     223              :   INVALID_REGNUM,
     224              :   /* Block Scale register */
     225              :   INVALID_REGNUM,
     226              : };
     227              : 
     228              : /* The "default" register map used in 64bit mode.  */
     229              : 
     230              : unsigned int const debugger64_register_map[FIRST_PSEUDO_REGISTER] =
     231              : {
     232              :   /* general regs */
     233              :   0, 1, 2, 3, 4, 5, 6, 7,
     234              :   /* fp regs */
     235              :   33, 34, 35, 36, 37, 38, 39, 40,
     236              :   /* arg, flags, fpsr, frame */
     237              :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     238              :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     239              :   /* SSE */
     240              :   17, 18, 19, 20, 21, 22, 23, 24,
     241              :   /* MMX */
     242              :   41, 42, 43, 44, 45, 46, 47, 48,
     243              :   /* extended integer registers */
     244              :   8, 9, 10, 11, 12, 13, 14, 15,
     245              :   /* extended SSE registers */
     246              :   25, 26, 27, 28, 29, 30, 31, 32,
     247              :   /* AVX-512 registers 16-23 */
     248              :   67, 68, 69, 70, 71, 72, 73, 74,
     249              :   /* AVX-512 registers 24-31 */
     250              :   75, 76, 77, 78, 79, 80, 81, 82,
     251              :   /* Mask registers */
     252              :   118, 119, 120, 121, 122, 123, 124, 125,
     253              :   /* rex2 extend integer registers */
     254              :   130, 131, 132, 133, 134, 135, 136, 137,
     255              :   138, 139, 140, 141, 142, 143, 144, 145,
     256              :   /* tmm fake register placeholder */
     257              :   IGNORED_DWARF_REGNUM,
     258              :   /* block scale register */
     259              :   IGNORED_DWARF_REGNUM,
     260              : };
     261              : 
     262              : /* Define the register numbers to be used in Dwarf debugging information.
     263              :    The SVR4 reference port C compiler uses the following register numbers
     264              :    in its Dwarf output code:
     265              :         0 for %eax (gcc regno = 0)
     266              :         1 for %ecx (gcc regno = 2)
     267              :         2 for %edx (gcc regno = 1)
     268              :         3 for %ebx (gcc regno = 3)
     269              :         4 for %esp (gcc regno = 7)
     270              :         5 for %ebp (gcc regno = 6)
     271              :         6 for %esi (gcc regno = 4)
     272              :         7 for %edi (gcc regno = 5)
     273              :    The following three DWARF register numbers are never generated by
     274              :    the SVR4 C compiler or by the GNU compilers, but SDB on x86/svr4
     275              :    believed these numbers have these meanings.
     276              :         8  for %eip    (no gcc equivalent)
     277              :         9  for %eflags (gcc regno = 17)
     278              :         10 for %trapno (no gcc equivalent)
     279              :    It is not at all clear how we should number the FP stack registers
     280              :    for the x86 architecture.  If the version of SDB on x86/svr4 were
     281              :    a bit less brain dead with respect to floating-point then we would
     282              :    have a precedent to follow with respect to DWARF register numbers
     283              :    for x86 FP registers, but the SDB on x86/svr4 was so completely
     284              :    broken with respect to FP registers that it is hardly worth thinking
     285              :    of it as something to strive for compatibility with.
     286              :    The version of x86/svr4 SDB I had does (partially)
     287              :    seem to believe that DWARF register number 11 is associated with
     288              :    the x86 register %st(0), but that's about all.  Higher DWARF
     289              :    register numbers don't seem to be associated with anything in
     290              :    particular, and even for DWARF regno 11, SDB only seemed to under-
     291              :    stand that it should say that a variable lives in %st(0) (when
     292              :    asked via an `=' command) if we said it was in DWARF regno 11,
     293              :    but SDB still printed garbage when asked for the value of the
     294              :    variable in question (via a `/' command).
     295              :    (Also note that the labels SDB printed for various FP stack regs
     296              :    when doing an `x' command were all wrong.)
     297              :    Note that these problems generally don't affect the native SVR4
     298              :    C compiler because it doesn't allow the use of -O with -g and
     299              :    because when it is *not* optimizing, it allocates a memory
     300              :    location for each floating-point variable, and the memory
     301              :    location is what gets described in the DWARF AT_location
     302              :    attribute for the variable in question.
     303              :    Regardless of the severe mental illness of the x86/svr4 SDB, we
     304              :    do something sensible here and we use the following DWARF
     305              :    register numbers.  Note that these are all stack-top-relative
     306              :    numbers.
     307              :         11 for %st(0) (gcc regno = 8)
     308              :         12 for %st(1) (gcc regno = 9)
     309              :         13 for %st(2) (gcc regno = 10)
     310              :         14 for %st(3) (gcc regno = 11)
     311              :         15 for %st(4) (gcc regno = 12)
     312              :         16 for %st(5) (gcc regno = 13)
     313              :         17 for %st(6) (gcc regno = 14)
     314              :         18 for %st(7) (gcc regno = 15)
     315              : */
     316              : unsigned int const svr4_debugger_register_map[FIRST_PSEUDO_REGISTER] =
     317              : {
     318              :   /* general regs */
     319              :   0, 2, 1, 3, 6, 7, 5, 4,
     320              :   /* fp regs */
     321              :   11, 12, 13, 14, 15, 16, 17, 18,
     322              :   /* arg, flags, fpsr, frame */
     323              :   IGNORED_DWARF_REGNUM, 9,
     324              :   IGNORED_DWARF_REGNUM, IGNORED_DWARF_REGNUM,
     325              :   /* SSE registers */
     326              :   21, 22, 23, 24, 25, 26, 27, 28,
     327              :   /* MMX registers */
     328              :   29, 30, 31, 32, 33, 34, 35, 36,
     329              :   /* extended integer registers */
     330              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     331              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     332              :   /* extended sse registers */
     333              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     334              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     335              :   /* AVX-512 registers 16-23 */
     336              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     337              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     338              :   /* AVX-512 registers 24-31 */
     339              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     340              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     341              :   /* Mask registers */
     342              :   93, 94, 95, 96, 97, 98, 99, 100,
     343              :   /* APX r16-r31 */
     344              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     345              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     346              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     347              :   INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM, INVALID_REGNUM,
     348              :   /* TMM fake register placeholder */
     349              :   INVALID_REGNUM,
     350              :   /* Block Scale register */
     351              :   INVALID_REGNUM,
     352              : };
     353              : 
     354              : /* Define parameter passing and return registers.  */
     355              : 
     356              : static int const x86_64_int_parameter_registers[6] =
     357              : {
     358              :   DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG
     359              : };
     360              : 
     361              : static int const x86_64_ms_abi_int_parameter_registers[4] =
     362              : {
     363              :   CX_REG, DX_REG, R8_REG, R9_REG
     364              : };
     365              : 
     366              : /* Similar as Clang's preserve_none function parameter passing.
     367              :    NB: Use DI_REG and SI_REG, see ix86_function_arg_regno_p.  */
     368              : 
     369              : static int const x86_64_preserve_none_int_parameter_registers[6] =
     370              : {
     371              :   R12_REG, R13_REG, R14_REG, R15_REG, DI_REG, SI_REG
     372              : };
     373              : 
     374              : static int const x86_64_int_return_registers[2] =
     375              : {
     376              :   AX_REG, DX_REG
     377              : };
     378              : 
     379              : /* Define the structure for the machine field in struct function.  */
     380              : 
     381              : struct GTY(()) stack_local_entry {
     382              :   unsigned short mode;
     383              :   unsigned short n;
     384              :   rtx rtl;
     385              :   struct stack_local_entry *next;
     386              : };
     387              : 
     388              : /* Which cpu are we scheduling for.  */
     389              : enum attr_cpu ix86_schedule;
     390              : 
     391              : /* Which cpu are we optimizing for.  */
     392              : enum processor_type ix86_tune;
     393              : 
     394              : /* Which instruction set architecture to use.  */
     395              : enum processor_type ix86_arch;
     396              : 
     397              : /* True if processor has SSE prefetch instruction.  */
     398              : unsigned char ix86_prefetch_sse;
     399              : 
     400              : /* Preferred alignment for stack boundary in bits.  */
     401              : unsigned int ix86_preferred_stack_boundary;
     402              : 
     403              : /* Alignment for incoming stack boundary in bits specified at
     404              :    command line.  */
     405              : unsigned int ix86_user_incoming_stack_boundary;
     406              : 
     407              : /* Default alignment for incoming stack boundary in bits.  */
     408              : unsigned int ix86_default_incoming_stack_boundary;
     409              : 
     410              : /* Alignment for incoming stack boundary in bits.  */
     411              : unsigned int ix86_incoming_stack_boundary;
     412              : 
     413              : /* True if there is no direct access to extern symbols.  */
     414              : bool ix86_has_no_direct_extern_access;
     415              : 
     416              : /* Calling abi specific va_list type nodes.  */
     417              : tree sysv_va_list_type_node;
     418              : tree ms_va_list_type_node;
     419              : 
     420              : /* Prefix built by ASM_GENERATE_INTERNAL_LABEL.  */
     421              : char internal_label_prefix[16];
     422              : int internal_label_prefix_len;
     423              : 
     424              : /* Fence to use after loop using movnt.  */
     425              : tree x86_mfence;
     426              : 
     427              : /* Register class used for passing given 64bit part of the argument.
     428              :    These represent classes as documented by the PS ABI, with the exception
     429              :    of SSESF, SSEDF classes, that are basically SSE class, just gcc will
     430              :    use SF or DFmode move instead of DImode to avoid reformatting penalties.
     431              : 
     432              :    Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
     433              :    whenever possible (upper half does contain padding).  */
     434              : enum x86_64_reg_class
     435              :   {
     436              :     X86_64_NO_CLASS,
     437              :     X86_64_INTEGER_CLASS,
     438              :     X86_64_INTEGERSI_CLASS,
     439              :     X86_64_SSE_CLASS,
     440              :     X86_64_SSEHF_CLASS,
     441              :     X86_64_SSESF_CLASS,
     442              :     X86_64_SSEDF_CLASS,
     443              :     X86_64_SSEUP_CLASS,
     444              :     X86_64_X87_CLASS,
     445              :     X86_64_X87UP_CLASS,
     446              :     X86_64_COMPLEX_X87_CLASS,
     447              :     X86_64_MEMORY_CLASS
     448              :   };
     449              : 
     450              : #define MAX_CLASSES 8
     451              : 
     452              : /* Table of constants used by fldpi, fldln2, etc....  */
     453              : static REAL_VALUE_TYPE ext_80387_constants_table [5];
     454              : static bool ext_80387_constants_init;
     455              : 
     456              : 
     457              : static rtx ix86_function_value (const_tree, const_tree, bool);
     458              : static bool ix86_function_value_regno_p (const unsigned int);
     459              : static unsigned int ix86_function_arg_boundary (machine_mode,
     460              :                                                 const_tree);
     461              : static rtx ix86_static_chain (const_tree, bool);
     462              : static int ix86_function_regparm (const_tree, const_tree);
     463              : static void ix86_compute_frame_layout (void);
     464              : static tree ix86_canonical_va_list_type (tree);
     465              : static unsigned int split_stack_prologue_scratch_regno (void);
     466              : static bool i386_asm_output_addr_const_extra (FILE *, rtx);
     467              : 
     468              : static bool ix86_can_inline_p (tree, tree);
     469              : static unsigned int ix86_minimum_incoming_stack_boundary (bool);
     470              : 
     471              : typedef enum ix86_flags_cc
     472              : {
     473              :   X86_CCO = 0, X86_CCNO, X86_CCB, X86_CCNB,
     474              :   X86_CCE, X86_CCNE, X86_CCBE, X86_CCNBE,
     475              :   X86_CCS, X86_CCNS, X86_CCP, X86_CCNP,
     476              :   X86_CCL, X86_CCNL, X86_CCLE, X86_CCNLE
     477              : } ix86_cc;
     478              : 
     479              : static const char *ix86_ccmp_dfv_mapping[] =
     480              : {
     481              :   "{dfv=of}", "{dfv=}", "{dfv=cf}", "{dfv=}",
     482              :   "{dfv=zf}", "{dfv=}", "{dfv=cf, zf}", "{dfv=}",
     483              :   "{dfv=sf}", "{dfv=}", "{dfv=cf}", "{dfv=}",
     484              :   "{dfv=sf}", "{dfv=sf, of}", "{dfv=sf, of, zf}", "{dfv=sf, of}"
     485              : };
     486              : 
     487              : 
     488              : /* Whether -mtune= or -march= were specified */
     489              : int ix86_tune_defaulted;
     490              : int ix86_arch_specified;
     491              : 
     492              : /* Return true if a red-zone is in use.  We can't use red-zone when
     493              :    there are local indirect jumps, like "indirect_jump" or "tablejump",
     494              :    which jumps to another place in the function, since "call" in the
     495              :    indirect thunk pushes the return address onto stack, destroying
     496              :    red-zone.
     497              : 
     498              :    NB: Don't use red-zone for functions with no_caller_saved_registers
     499              :    and 32 GPRs or 16 XMM registers since 128-byte red-zone is too small
     500              :    for 31 GPRs or 15 GPRs + 16 XMM registers.
     501              : 
     502              :    TODO: If we can reserve the first 2 WORDs, for PUSH and, another
     503              :    for CALL, in red-zone, we can allow local indirect jumps with
     504              :    indirect thunk.  */
     505              : 
     506              : bool
     507     10147348 : ix86_using_red_zone (void)
     508              : {
     509     10147348 :   return (TARGET_RED_ZONE
     510      9204329 :           && !TARGET_64BIT_MS_ABI
     511      8904783 :           && ((!TARGET_APX_EGPR && !TARGET_SSE)
     512      8881632 :               || (cfun->machine->call_saved_registers
     513      8881632 :                   != TYPE_NO_CALLER_SAVED_REGISTERS))
     514     19052036 :           && (!cfun->machine->has_local_indirect_jump
     515        52989 :               || cfun->machine->indirect_branch_type == indirect_branch_keep));
     516              : }
     517              : 
     518              : /* Return true, if profiling code should be emitted before
     519              :    prologue. Otherwise it returns false.
     520              :    Note: For x86 with "hotfix" it is sorried.  */
     521              : static bool
     522      4615031 : ix86_profile_before_prologue (void)
     523              : {
     524      4615031 :   return flag_fentry != 0;
     525              : }
     526              : 
     527              : /* Update register usage after having seen the compiler flags.  */
     528              : 
     529              : static void
     530       791585 : ix86_conditional_register_usage (void)
     531              : {
     532       791585 :   int i, c_mask;
     533              : 
     534              :   /* For 32-bit targets, disable the REX registers.  */
     535       791585 :   if (! TARGET_64BIT)
     536              :     {
     537       135378 :       for (i = FIRST_REX_INT_REG; i <= LAST_REX_INT_REG; i++)
     538       120336 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     539       135378 :       for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
     540       120336 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     541       255714 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     542       240672 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     543              :     }
     544              : 
     545              :   /* Set up the call-used registers based on the system ABI (ix86_abi).
     546              : 
     547              :      See the definition of CALL_USED_REGISTERS in i386.h.  */
     548       791585 :   c_mask = CALL_USED_REGISTERS_MASK (TARGET_64BIT && ix86_abi == MS_ABI);
     549              : 
     550       791585 :   CLEAR_HARD_REG_SET (reg_class_contents[(int)CLOBBERED_REGS]);
     551              : 
     552     75200575 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     553              :     {
     554              :       /* Set/reset conditionally defined registers from
     555              :          CALL_USED_REGISTERS initializer.  */
     556     74408990 :       if (call_used_regs[i] > 1)
     557     12665305 :         call_used_regs[i] = !!(call_used_regs[i] & c_mask);
     558              : 
     559              :       /* Calculate registers of CLOBBERED_REGS register set
     560              :          as call used registers from GENERAL_REGS register set.  */
     561     74408990 :       if (TEST_HARD_REG_BIT (reg_class_contents[(int)GENERAL_REGS], i)
     562     74408990 :           && call_used_regs[i])
     563     22193170 :         SET_HARD_REG_BIT (reg_class_contents[(int)CLOBBERED_REGS], i);
     564              :     }
     565              : 
     566              :   /* If MMX is disabled, disable the registers.  */
     567       791585 :   if (! TARGET_MMX)
     568       383632 :     accessible_reg_set &= ~reg_class_contents[MMX_REGS];
     569              : 
     570              :   /* If SSE is disabled, disable the registers.  */
     571       791585 :   if (! TARGET_SSE)
     572       378432 :     accessible_reg_set &= ~reg_class_contents[ALL_SSE_REGS];
     573              : 
     574              :   /* If the FPU is disabled, disable the registers.  */
     575       791585 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
     576       378872 :     accessible_reg_set &= ~reg_class_contents[FLOAT_REGS];
     577              : 
     578              :   /* If AVX512F is disabled, disable the registers.  */
     579       791585 :   if (! TARGET_AVX512F)
     580              :     {
     581      9236831 :       for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
     582      8693488 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     583              : 
     584      1086686 :       accessible_reg_set &= ~reg_class_contents[ALL_MASK_REGS];
     585              :     }
     586              : 
     587              :   /* If APX is disabled, disable the registers.  */
     588       791585 :   if (! (TARGET_APX_EGPR && TARGET_64BIT))
     589              :     {
     590     13448751 :       for (i = FIRST_REX2_INT_REG; i <= LAST_REX2_INT_REG; i++)
     591     12657648 :         CLEAR_HARD_REG_BIT (accessible_reg_set, i);
     592              :     }
     593              : 
     594              :   /* If AMX-TILE or ACEV1 is disabled, disable tmm registers.  */
     595       791585 :   if (! (TARGET_AMX_TILE || TARGET_ACEV1))
     596              :     {
     597       746630 :       CLEAR_HARD_REG_BIT (accessible_reg_set, TMM_REGNUM);
     598              :     }
     599              : 
     600              :   /* If ACEV1 is disabled, disable bsr0.  */
     601       791585 :   if (! TARGET_ACEV1)
     602              :     {
     603       786234 :       CLEAR_HARD_REG_BIT (accessible_reg_set, BSR0_REG);
     604              :     }
     605       791585 : }
     606              : 
     607              : /* Canonicalize a comparison from one we don't have to one we do have.  */
     608              : 
     609              : static void
     610     25343270 : ix86_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
     611              :                               bool op0_preserve_value)
     612              : {
     613              :   /* The order of operands in x87 ficom compare is forced by combine in
     614              :      simplify_comparison () function. Float operator is treated as RTX_OBJ
     615              :      with a precedence over other operators and is always put in the first
     616              :      place. Swap condition and operands to match ficom instruction.  */
     617     25343270 :   if (!op0_preserve_value
     618     24521935 :       && GET_CODE (*op0) == FLOAT && MEM_P (XEXP (*op0, 0)) && REG_P (*op1))
     619              :     {
     620           26 :       enum rtx_code scode = swap_condition ((enum rtx_code) *code);
     621              : 
     622              :       /* We are called only for compares that are split to SAHF instruction.
     623              :          Ensure that we have setcc/jcc insn for the swapped condition.  */
     624           26 :       if (ix86_fp_compare_code_to_integer (scode) != UNKNOWN)
     625              :         {
     626           10 :           std::swap (*op0, *op1);
     627           10 :           *code = (int) scode;
     628           10 :           return;
     629              :         }
     630              :     }
     631              : 
     632              :   /* SUB (a, b) underflows precisely when a < b.  Convert
     633              :      (compare (minus (a b)) a) to (compare (a b))
     634              :      to match *sub<mode>_3 pattern.  */
     635     24521925 :   if (!op0_preserve_value
     636     24521925 :       && (*code == GTU || *code == LEU)
     637      1936622 :       && GET_CODE (*op0) == MINUS
     638        86642 :       && rtx_equal_p (XEXP (*op0, 0), *op1))
     639              :     {
     640          487 :       *op1 = XEXP (*op0, 1);
     641          487 :       *op0 = XEXP (*op0, 0);
     642          487 :       *code = (int) swap_condition ((enum rtx_code) *code);
     643          487 :       return;
     644              :     }
     645              : 
     646              :   /* Swap operands of GTU comparison to canonicalize
     647              :      addcarry/subborrow comparison.  */
     648     25342773 :   if (!op0_preserve_value
     649     24521438 :       && *code == GTU
     650       924117 :       && GET_CODE (*op0) == PLUS
     651       338011 :       && ix86_carry_flag_operator (XEXP (*op0, 0), VOIDmode)
     652        52423 :       && GET_CODE (XEXP (*op0, 1)) == ZERO_EXTEND
     653     25391141 :       && GET_CODE (*op1) == ZERO_EXTEND)
     654              :     {
     655        45497 :       std::swap (*op0, *op1);
     656        45497 :       *code = (int) swap_condition ((enum rtx_code) *code);
     657        45497 :       return;
     658              :     }
     659              : }
     660              : 
     661              : /* Hook to determine if one function can safely inline another.  */
     662              : 
     663              : static bool
     664     10802712 : ix86_can_inline_p (tree caller, tree callee)
     665              : {
     666     10802712 :   tree caller_tree = DECL_FUNCTION_SPECIFIC_TARGET (caller);
     667     10802712 :   tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (callee);
     668              : 
     669              :   /* Changes of those flags can be tolerated for always inlines. Lets hope
     670              :      user knows what he is doing.  */
     671     10802712 :   unsigned HOST_WIDE_INT always_inline_safe_mask
     672              :          = (MASK_USE_8BIT_IDIV | MASK_ACCUMULATE_OUTGOING_ARGS
     673              :             | MASK_NO_ALIGN_STRINGOPS | MASK_AVX256_SPLIT_UNALIGNED_LOAD
     674              :             | MASK_AVX256_SPLIT_UNALIGNED_STORE | MASK_CLD
     675              :             | MASK_NO_FANCY_MATH_387 | MASK_IEEE_FP | MASK_INLINE_ALL_STRINGOPS
     676              :             | MASK_INLINE_STRINGOPS_DYNAMICALLY | MASK_RECIP | MASK_STACK_PROBE
     677              :             | MASK_STV | MASK_TLS_DIRECT_SEG_REFS | MASK_VZEROUPPER
     678              :             | MASK_NO_PUSH_ARGS | MASK_OMIT_LEAF_FRAME_POINTER);
     679              : 
     680              : 
     681     10802712 :   if (!callee_tree)
     682     10202511 :     callee_tree = target_option_default_node;
     683     10802712 :   if (!caller_tree)
     684     10202342 :     caller_tree = target_option_default_node;
     685     10802712 :   if (callee_tree == caller_tree)
     686              :     return true;
     687              : 
     688         5582 :   struct cl_target_option *caller_opts = TREE_TARGET_OPTION (caller_tree);
     689         5582 :   struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
     690         5582 :   bool ret = false;
     691         5582 :   bool always_inline
     692         5582 :     = (DECL_DISREGARD_INLINE_LIMITS (callee)
     693        10509 :        && lookup_attribute ("always_inline",
     694         4927 :                             DECL_ATTRIBUTES (callee)));
     695              : 
     696              :   /* If callee only uses GPRs, ignore MASK_80387.  */
     697         5582 :   if (TARGET_GENERAL_REGS_ONLY_P (callee_opts->x_ix86_target_flags))
     698         1030 :     always_inline_safe_mask |= MASK_80387;
     699              : 
     700         5582 :   cgraph_node *callee_node = cgraph_node::get (callee);
     701              :   /* Callee's isa options should be a subset of the caller's, i.e. a SSE4
     702              :      function can inline a SSE2 function but a SSE2 function can't inline
     703              :      a SSE4 function.  */
     704         5582 :   if (((caller_opts->x_ix86_isa_flags & callee_opts->x_ix86_isa_flags)
     705              :        != callee_opts->x_ix86_isa_flags)
     706         5346 :       || ((caller_opts->x_ix86_isa_flags2 & callee_opts->x_ix86_isa_flags2)
     707              :           != callee_opts->x_ix86_isa_flags2))
     708              :     ret = false;
     709              : 
     710              :   /* See if we have the same non-isa options.  */
     711         5309 :   else if ((!always_inline
     712          398 :             && caller_opts->x_target_flags != callee_opts->x_target_flags)
     713         5256 :            || (caller_opts->x_target_flags & ~always_inline_safe_mask)
     714         5256 :                != (callee_opts->x_target_flags & ~always_inline_safe_mask))
     715              :     ret = false;
     716              : 
     717         5256 :   else if (caller_opts->x_ix86_fpmath != callee_opts->x_ix86_fpmath
     718              :            /* If the callee doesn't use FP expressions differences in
     719              :               ix86_fpmath can be ignored.  We are called from FEs
     720              :               for multi-versioning call optimization, so beware of
     721              :               ipa_fn_summaries not available.  */
     722         1247 :            && (! ipa_fn_summaries
     723         1247 :                || ipa_fn_summaries->get (callee_node) == NULL
     724         1247 :                || ipa_fn_summaries->get (callee_node)->fp_expressions))
     725              :     ret = false;
     726              : 
     727              :   /* At this point we cannot identify whether arch or tune setting
     728              :      comes from target attribute or not. So the most conservative way
     729              :      is to allow the callee that uses default arch and tune string to
     730              :      be inlined.  */
     731         4982 :   else if (!strcmp (callee_opts->x_ix86_arch_string, "x86-64")
     732         1431 :            && !strcmp (callee_opts->x_ix86_tune_string, "generic"))
     733              :     ret = true;
     734              : 
     735              :   /* See if arch, tune, etc. are the same. As previous ISA flags already
     736              :      checks if callee's ISA is subset of caller's, do not block
     737              :      always_inline attribute for callee even it has different arch. */
     738         3559 :   else if (!always_inline && caller_opts->arch != callee_opts->arch)
     739              :     ret = false;
     740              : 
     741           15 :   else if (!always_inline && caller_opts->tune != callee_opts->tune)
     742              :     ret = false;
     743              : 
     744         3559 :   else if (!always_inline
     745           15 :            && caller_opts->branch_cost != callee_opts->branch_cost)
     746              :     ret = false;
     747              : 
     748              :   else
     749     10802112 :     ret = true;
     750              : 
     751              :   return ret;
     752              : }
     753              : 
     754              : /* Return true if this goes in large data/bss.  */
     755              : 
     756              : static bool
     757     88006771 : ix86_in_large_data_p (tree exp)
     758              : {
     759     88006771 :   if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC
     760     88006533 :       && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC)
     761              :     return false;
     762              : 
     763         1147 :   if (exp == NULL_TREE)
     764              :     return false;
     765              : 
     766              :   /* Functions are never large data.  */
     767         1147 :   if (TREE_CODE (exp) == FUNCTION_DECL)
     768              :     return false;
     769              : 
     770              :   /* Automatic variables are never large data.  */
     771          279 :   if (VAR_P (exp) && !is_global_var (exp))
     772              :     return false;
     773              : 
     774          279 :   if (VAR_P (exp) && DECL_SECTION_NAME (exp))
     775              :     {
     776           51 :       const char *section = DECL_SECTION_NAME (exp);
     777           51 :       if (strcmp (section, ".ldata") == 0
     778           51 :           || startswith (section, ".ldata.")
     779           51 :           || strcmp (section, ".lbss") == 0
     780           51 :           || startswith (section, ".lbss.")
     781           99 :           || startswith (section, ".gnu.linkonce.lb."))
     782            3 :         return true;
     783              :       return false;
     784              :     }
     785              :   else
     786              :     {
     787          228 :       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
     788              : 
     789              :       /* If this is an incomplete type with size 0, then we can't put it
     790              :          in data because it might be too big when completed.  Also,
     791              :          int_size_in_bytes returns -1 if size can vary or is larger than
     792              :          an integer in which case also it is safer to assume that it goes in
     793              :          large data.  */
     794          228 :       if (size <= 0 || size > ix86_section_threshold)
     795           48 :         return true;
     796              :     }
     797              : 
     798              :   return false;
     799              : }
     800              : 
     801              : /* i386-specific section flag to mark large sections.  */
     802              : #define SECTION_LARGE SECTION_MACH_DEP
     803              : 
     804              : /* Switch to the appropriate section for output of DECL.
     805              :    DECL is either a `VAR_DECL' node or a constant of some sort.
     806              :    RELOC indicates whether forming the initial value of DECL requires
     807              :    link-time relocations.  */
     808              : 
     809              : ATTRIBUTE_UNUSED static section *
     810      1687102 : x86_64_elf_select_section (tree decl, int reloc,
     811              :                            unsigned HOST_WIDE_INT align)
     812              : {
     813      1687102 :   if (ix86_in_large_data_p (decl))
     814              :     {
     815            6 :       const char *sname = NULL;
     816            6 :       unsigned int flags = SECTION_WRITE | SECTION_LARGE;
     817            6 :       switch (categorize_decl_for_section (decl, reloc))
     818              :         {
     819            1 :         case SECCAT_DATA:
     820            1 :           sname = ".ldata";
     821            1 :           break;
     822            0 :         case SECCAT_DATA_REL:
     823            0 :           sname = ".ldata.rel";
     824            0 :           break;
     825            0 :         case SECCAT_DATA_REL_LOCAL:
     826            0 :           sname = ".ldata.rel.local";
     827            0 :           break;
     828            0 :         case SECCAT_DATA_REL_RO:
     829            0 :           sname = ".ldata.rel.ro";
     830            0 :           break;
     831            0 :         case SECCAT_DATA_REL_RO_LOCAL:
     832            0 :           sname = ".ldata.rel.ro.local";
     833            0 :           break;
     834            0 :         case SECCAT_BSS:
     835            0 :           sname = ".lbss";
     836            0 :           flags |= SECTION_BSS;
     837            0 :           break;
     838              :         case SECCAT_RODATA:
     839              :         case SECCAT_RODATA_MERGE_STR:
     840              :         case SECCAT_RODATA_MERGE_STR_INIT:
     841              :         case SECCAT_RODATA_MERGE_CONST:
     842              :           sname = ".lrodata";
     843              :           flags &= ~SECTION_WRITE;
     844              :           break;
     845            0 :         case SECCAT_SRODATA:
     846            0 :         case SECCAT_SDATA:
     847            0 :         case SECCAT_SBSS:
     848            0 :           gcc_unreachable ();
     849              :         case SECCAT_TEXT:
     850              :         case SECCAT_TDATA:
     851              :         case SECCAT_TBSS:
     852              :           /* We don't split these for medium model.  Place them into
     853              :              default sections and hope for best.  */
     854              :           break;
     855              :         }
     856            1 :       if (sname)
     857              :         {
     858              :           /* We might get called with string constants, but get_named_section
     859              :              doesn't like them as they are not DECLs.  Also, we need to set
     860              :              flags in that case.  */
     861            6 :           if (!DECL_P (decl))
     862            3 :             return get_section (sname, flags, NULL);
     863            3 :           return get_named_section (decl, sname, reloc);
     864              :         }
     865              :     }
     866      1687096 :   return default_elf_select_section (decl, reloc, align);
     867              : }
     868              : 
     869              : /* Select a set of attributes for section NAME based on the properties
     870              :    of DECL and whether or not RELOC indicates that DECL's initializer
     871              :    might contain runtime relocations.  */
     872              : 
     873              : static unsigned int ATTRIBUTE_UNUSED
     874     74395655 : x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
     875              : {
     876     74395655 :   unsigned int flags = default_section_type_flags (decl, name, reloc);
     877              : 
     878     74395655 :   if (ix86_in_large_data_p (decl))
     879           10 :     flags |= SECTION_LARGE;
     880              : 
     881     74395655 :   if (decl == NULL_TREE
     882          370 :       && (strcmp (name, ".ldata.rel.ro") == 0
     883          370 :           || strcmp (name, ".ldata.rel.ro.local") == 0))
     884            0 :     flags |= SECTION_RELRO;
     885              : 
     886     74395655 :   if (strcmp (name, ".lbss") == 0
     887     74395651 :       || startswith (name, ".lbss.")
     888    148791303 :       || startswith (name, ".gnu.linkonce.lb."))
     889              :     {
     890            7 :       flags |= SECTION_BSS;
     891              :       /* Clear SECTION_NOTYPE so .lbss etc. are marked @nobits in
     892              :          default_elf_asm_named_section.  */
     893            7 :       flags &= ~SECTION_NOTYPE;
     894              :     }
     895              : 
     896     74395655 :   return flags;
     897              : }
     898              : 
     899              : /* Build up a unique section name, expressed as a
     900              :    STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
     901              :    RELOC indicates whether the initial value of EXP requires
     902              :    link-time relocations.  */
     903              : 
     904              : static void ATTRIBUTE_UNUSED
     905      1833900 : x86_64_elf_unique_section (tree decl, int reloc)
     906              : {
     907      1833900 :   if (ix86_in_large_data_p (decl))
     908              :     {
     909            3 :       const char *prefix = NULL;
     910              :       /* We only need to use .gnu.linkonce if we don't have COMDAT groups.  */
     911            3 :       bool one_only = DECL_COMDAT_GROUP (decl) && !HAVE_COMDAT_GROUP;
     912              : 
     913            3 :       switch (categorize_decl_for_section (decl, reloc))
     914              :         {
     915            0 :         case SECCAT_DATA:
     916            0 :         case SECCAT_DATA_REL:
     917            0 :         case SECCAT_DATA_REL_LOCAL:
     918            0 :         case SECCAT_DATA_REL_RO:
     919            0 :         case SECCAT_DATA_REL_RO_LOCAL:
     920            0 :           prefix = one_only ? ".ld" : ".ldata";
     921              :           break;
     922            3 :         case SECCAT_BSS:
     923            3 :           prefix = one_only ? ".lb" : ".lbss";
     924              :           break;
     925              :         case SECCAT_RODATA:
     926              :         case SECCAT_RODATA_MERGE_STR:
     927              :         case SECCAT_RODATA_MERGE_STR_INIT:
     928              :         case SECCAT_RODATA_MERGE_CONST:
     929              :           prefix = one_only ? ".lr" : ".lrodata";
     930              :           break;
     931            0 :         case SECCAT_SRODATA:
     932            0 :         case SECCAT_SDATA:
     933            0 :         case SECCAT_SBSS:
     934            0 :           gcc_unreachable ();
     935              :         case SECCAT_TEXT:
     936              :         case SECCAT_TDATA:
     937              :         case SECCAT_TBSS:
     938              :           /* We don't split these for medium model.  Place them into
     939              :              default sections and hope for best.  */
     940              :           break;
     941              :         }
     942            3 :       if (prefix)
     943              :         {
     944            3 :           const char *name, *linkonce;
     945            3 :           char *string;
     946              : 
     947            3 :           name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     948            3 :           name = targetm.strip_name_encoding (name);
     949              : 
     950              :           /* If we're using one_only, then there needs to be a .gnu.linkonce
     951              :              prefix to the section name.  */
     952            3 :           linkonce = one_only ? ".gnu.linkonce" : "";
     953              : 
     954            3 :           string = ACONCAT ((linkonce, prefix, ".", name, NULL));
     955              : 
     956            3 :           set_decl_section_name (decl, string);
     957            3 :           return;
     958              :         }
     959              :     }
     960      1833897 :   default_unique_section (decl, reloc);
     961              : }
     962              : 
     963              : /* Return true if TYPE has no_callee_saved_registers or preserve_none
     964              :    attribute.  */
     965              : 
     966              : static bool
     967      1625535 : ix86_type_no_callee_saved_registers_p (const_tree fntype)
     968              : {
     969       136435 :   auto type = ix86_fntype_call_saved_registers (fntype);
     970      1625535 :   return type == TYPE_PRESERVE_NONE || type == TYPE_NO_CALLEE_SAVED_REGISTERS;
     971              : }
     972              : 
     973              : #ifdef COMMON_ASM_OP
     974              : 
     975              : #ifndef LARGECOMM_SECTION_ASM_OP
     976              : #define LARGECOMM_SECTION_ASM_OP "\t.largecomm\t"
     977              : #endif
     978              : 
     979              : /* This says how to output assembler code to declare an
     980              :    uninitialized external linkage data object.
     981              : 
     982              :    For medium model x86-64 we need to use LARGECOMM_SECTION_ASM_OP opcode for
     983              :    large objects.  */
     984              : void
     985       171872 : x86_elf_aligned_decl_common (FILE *file, tree decl,
     986              :                         const char *name, unsigned HOST_WIDE_INT size,
     987              :                         unsigned align)
     988              : {
     989       171872 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
     990       171866 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
     991            7 :       && size > (unsigned int)ix86_section_threshold)
     992              :     {
     993            1 :       switch_to_section (get_named_section (decl, ".lbss", 0));
     994            1 :       fputs (LARGECOMM_SECTION_ASM_OP, file);
     995              :     }
     996              :   else
     997       171871 :     fputs (COMMON_ASM_OP, file);
     998       171872 :   assemble_name (file, name);
     999       171872 :   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n",
    1000              :            size, align / BITS_PER_UNIT);
    1001       171872 : }
    1002              : #endif
    1003              : 
    1004              : /* Utility function for targets to use in implementing
    1005              :    ASM_OUTPUT_ALIGNED_BSS.  */
    1006              : 
    1007              : void
    1008       771304 : x86_output_aligned_bss (FILE *file, tree decl, const char *name,
    1009              :                         unsigned HOST_WIDE_INT size, unsigned align)
    1010              : {
    1011       771304 :   if ((ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_MEDIUM_PIC
    1012       771294 :        || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
    1013           42 :       && size > (unsigned int)ix86_section_threshold)
    1014            3 :     switch_to_section (get_named_section (decl, ".lbss", 0));
    1015              :   else
    1016       771301 :     switch_to_section (bss_section);
    1017       928236 :   ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
    1018              : #ifdef ASM_DECLARE_OBJECT_NAME
    1019       771304 :   last_assemble_variable_decl = decl;
    1020       771304 :   ASM_DECLARE_OBJECT_NAME (file, name, decl);
    1021              : #else
    1022              :   /* Standard thing is just output label for the object.  */
    1023              :   ASM_OUTPUT_LABEL (file, name);
    1024              : #endif /* ASM_DECLARE_OBJECT_NAME */
    1025       771304 :   ASM_OUTPUT_SKIP (file, size ? size : 1);
    1026       771304 : }
    1027              : 
    1028              : /* Decide whether we must probe the stack before any space allocation
    1029              :    on this target.  It's essentially TARGET_STACK_PROBE except when
    1030              :    -fstack-check causes the stack to be already probed differently.  */
    1031              : 
    1032              : bool
    1033       887694 : ix86_target_stack_probe (void)
    1034              : {
    1035              :   /* Do not probe the stack twice if static stack checking is enabled.  */
    1036       887694 :   if (flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
    1037              :     return false;
    1038              : 
    1039       887694 :   return TARGET_STACK_PROBE;
    1040              : }
    1041              : 
    1042              : /* Decide whether we can make a sibling call to a function.  DECL is the
    1043              :    declaration of the function being targeted by the call and EXP is the
    1044              :    CALL_EXPR representing the call.  */
    1045              : 
    1046              : static bool
    1047       141766 : ix86_function_ok_for_sibcall (tree decl, tree exp)
    1048              : {
    1049       141766 :   tree type, decl_or_type;
    1050       141766 :   rtx a, b;
    1051       141766 :   bool bind_global = decl && !targetm.binds_local_p (decl);
    1052              : 
    1053       141766 :   if (ix86_function_naked (current_function_decl))
    1054              :     return false;
    1055              : 
    1056              :   /* Sibling call isn't OK if there are no caller-saved registers
    1057              :      since all registers must be preserved before return.  */
    1058       141764 :   if (cfun->machine->call_saved_registers
    1059       141764 :       == TYPE_NO_CALLER_SAVED_REGISTERS)
    1060              :     return false;
    1061              : 
    1062              :   /* If we are generating position-independent code, we cannot sibcall
    1063              :      optimize direct calls to global functions, as the PLT requires
    1064              :      %ebx be live. (Darwin does not have a PLT.)  */
    1065       141726 :   if (!TARGET_MACHO
    1066       141726 :       && !TARGET_64BIT
    1067        11353 :       && flag_pic
    1068         8411 :       && flag_plt
    1069         8411 :       && bind_global)
    1070              :     return false;
    1071              : 
    1072              :   /* If we need to align the outgoing stack, then sibcalling would
    1073              :      unalign the stack, which may break the called function.  */
    1074       137069 :   if (ix86_minimum_incoming_stack_boundary (true)
    1075       137069 :       < PREFERRED_STACK_BOUNDARY)
    1076              :     return false;
    1077              : 
    1078       136488 :   if (decl)
    1079              :     {
    1080       125533 :       decl_or_type = decl;
    1081       125533 :       type = TREE_TYPE (decl);
    1082              :     }
    1083              :   else
    1084              :     {
    1085              :       /* We're looking at the CALL_EXPR, we need the type of the function.  */
    1086        10955 :       type = CALL_EXPR_FN (exp);                /* pointer expression */
    1087        10955 :       type = TREE_TYPE (type);                  /* pointer type */
    1088        10955 :       type = TREE_TYPE (type);                  /* function type */
    1089        10955 :       decl_or_type = type;
    1090              :     }
    1091              : 
    1092              :   /* Sibling call isn't OK if callee has no callee-saved registers
    1093              :      and the calling function has callee-saved registers.  */
    1094       136488 :   if ((cfun->machine->call_saved_registers
    1095       136488 :        != TYPE_NO_CALLEE_SAVED_REGISTERS)
    1096       136488 :       && cfun->machine->call_saved_registers != TYPE_PRESERVE_NONE
    1097       272923 :       && ix86_type_no_callee_saved_registers_p (type))
    1098              :     return false;
    1099              : 
    1100              :   /* If outgoing reg parm stack space changes, we cannot do sibcall.  */
    1101       136468 :   if ((OUTGOING_REG_PARM_STACK_SPACE (type)
    1102       136468 :        != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
    1103       272178 :       || (REG_PARM_STACK_SPACE (decl_or_type)
    1104       135710 :           != REG_PARM_STACK_SPACE (current_function_decl)))
    1105              :     {
    1106          758 :       maybe_complain_about_tail_call (exp,
    1107              :                                       "inconsistent size of stack space"
    1108              :                                       " allocated for arguments which are"
    1109              :                                       " passed in registers");
    1110          758 :       return false;
    1111              :     }
    1112              : 
    1113              :   /* Check that the return value locations are the same.  Like
    1114              :      if we are returning floats on the 80387 register stack, we cannot
    1115              :      make a sibcall from a function that doesn't return a float to a
    1116              :      function that does or, conversely, from a function that does return
    1117              :      a float to a function that doesn't; the necessary stack adjustment
    1118              :      would not be executed.  This is also the place we notice
    1119              :      differences in the return value ABI.  Note that it is ok for one
    1120              :      of the functions to have void return type as long as the return
    1121              :      value of the other is passed in a register.  */
    1122       135710 :   a = ix86_function_value (TREE_TYPE (exp), decl_or_type, false);
    1123       135710 :   b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
    1124       135710 :                            cfun->decl, false);
    1125       135710 :   if (STACK_REG_P (a) || STACK_REG_P (b))
    1126              :     {
    1127          989 :       if (!rtx_equal_p (a, b))
    1128              :         return false;
    1129              :     }
    1130       134721 :   else if (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
    1131              :     ;
    1132        24891 :   else if (!rtx_equal_p (a, b))
    1133              :     return false;
    1134              : 
    1135       135321 :   if (TARGET_64BIT)
    1136              :     {
    1137              :       /* The SYSV ABI has more call-clobbered registers;
    1138              :          disallow sibcalls from MS to SYSV.  */
    1139       128625 :       if (cfun->machine->call_abi == MS_ABI
    1140       128625 :           && ix86_function_type_abi (type) == SYSV_ABI)
    1141              :         return false;
    1142              :     }
    1143              :   else
    1144              :     {
    1145              :       /* If this call is indirect, we'll need to be able to use a
    1146              :          call-clobbered register for the address of the target function.
    1147              :          Make sure that all such registers are not used for passing
    1148              :          parameters.  Note that DLLIMPORT functions and call to global
    1149              :          function via GOT slot are indirect.  */
    1150         6696 :       if (!decl
    1151         4799 :           || (bind_global && flag_pic && !flag_plt)
    1152              :           || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && DECL_DLLIMPORT_P (decl))
    1153         4799 :           || flag_force_indirect_call)
    1154              :         {
    1155              :           /* Check if regparm >= 3 since arg_reg_available is set to
    1156              :              false if regparm == 0.  If regparm is 1 or 2, there is
    1157              :              always a call-clobbered register available.
    1158              : 
    1159              :              ??? The symbol indirect call doesn't need a call-clobbered
    1160              :              register.  But we don't know if this is a symbol indirect
    1161              :              call or not here.  */
    1162         1897 :           if (ix86_function_regparm (type, decl) >= 3
    1163         1897 :               && !cfun->machine->arg_reg_available)
    1164              :             return false;
    1165              :         }
    1166              :     }
    1167              : 
    1168       135321 :   if (decl && ix86_use_pseudo_pic_reg ())
    1169              :     {
    1170              :       /* When PIC register is used, it must be restored after ifunc
    1171              :          function returns.  */
    1172         2067 :        cgraph_node *node = cgraph_node::get (decl);
    1173         2067 :        if (node && node->ifunc_resolver)
    1174              :          return false;
    1175              :     }
    1176              : 
    1177              :   /* Disable sibcall if callee has indirect_return attribute and
    1178              :      caller doesn't since callee will return to the caller's caller
    1179              :      via an indirect jump.  */
    1180       135321 :   if (((flag_cf_protection & (CF_RETURN | CF_BRANCH))
    1181              :        == (CF_RETURN | CF_BRANCH))
    1182        55979 :       && lookup_attribute ("indirect_return", TYPE_ATTRIBUTES (type))
    1183       135325 :       && !lookup_attribute ("indirect_return",
    1184            4 :                             TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))))
    1185            2 :     return false;
    1186              : 
    1187              :   /* Otherwise okay.  That also includes certain types of indirect calls.  */
    1188              :   return true;
    1189              : }
    1190              : 
    1191              : /* This function determines from TYPE the calling-convention.  */
    1192              : 
    1193              : unsigned int
    1194      6324869 : ix86_get_callcvt (const_tree type)
    1195              : {
    1196      6324869 :   unsigned int ret = 0;
    1197      6324869 :   bool is_stdarg;
    1198      6324869 :   tree attrs;
    1199              : 
    1200      6324869 :   if (TARGET_64BIT)
    1201              :     return IX86_CALLCVT_CDECL;
    1202              : 
    1203      3271165 :   attrs = TYPE_ATTRIBUTES (type);
    1204      3271165 :   if (attrs != NULL_TREE)
    1205              :     {
    1206        68391 :       if (lookup_attribute ("cdecl", attrs))
    1207              :         ret |= IX86_CALLCVT_CDECL;
    1208        68391 :       else if (lookup_attribute ("stdcall", attrs))
    1209              :         ret |= IX86_CALLCVT_STDCALL;
    1210        68391 :       else if (lookup_attribute ("fastcall", attrs))
    1211              :         ret |= IX86_CALLCVT_FASTCALL;
    1212        68382 :       else if (lookup_attribute ("thiscall", attrs))
    1213              :         ret |= IX86_CALLCVT_THISCALL;
    1214              : 
    1215              :       /* Regparm isn't allowed for thiscall and fastcall.  */
    1216              :       if ((ret & (IX86_CALLCVT_THISCALL | IX86_CALLCVT_FASTCALL)) == 0)
    1217              :         {
    1218        68382 :           if (lookup_attribute ("regparm", attrs))
    1219        15844 :             ret |= IX86_CALLCVT_REGPARM;
    1220        68382 :           if (lookup_attribute ("sseregparm", attrs))
    1221            0 :             ret |= IX86_CALLCVT_SSEREGPARM;
    1222              :         }
    1223              : 
    1224        68382 :       if (IX86_BASE_CALLCVT(ret) != 0)
    1225              :         return ret;
    1226              :     }
    1227              : 
    1228      3271156 :   is_stdarg = stdarg_p (type);
    1229      3271156 :   if (TARGET_RTD && !is_stdarg)
    1230            0 :     return IX86_CALLCVT_STDCALL | ret;
    1231              : 
    1232      3271156 :   if (ret != 0
    1233      3271156 :       || is_stdarg
    1234      3246214 :       || TREE_CODE (type) != METHOD_TYPE
    1235      3408022 :       || ix86_function_type_abi (type) != MS_ABI)
    1236      3271156 :     return IX86_CALLCVT_CDECL | ret;
    1237              : 
    1238              :   return IX86_CALLCVT_THISCALL;
    1239              : }
    1240              : 
    1241              : /* Return 0 if the attributes for two types are incompatible, 1 if they
    1242              :    are compatible, and 2 if they are nearly compatible (which causes a
    1243              :    warning to be generated).  */
    1244              : 
    1245              : static int
    1246      1544841 : ix86_comp_type_attributes (const_tree type1, const_tree type2)
    1247              : {
    1248      1544841 :   unsigned int ccvt1, ccvt2;
    1249              : 
    1250      1544841 :   if (TREE_CODE (type1) != FUNCTION_TYPE
    1251      1544841 :       && TREE_CODE (type1) != METHOD_TYPE)
    1252              :     return 1;
    1253              : 
    1254      1537992 :   ccvt1 = ix86_get_callcvt (type1);
    1255      1537992 :   ccvt2 = ix86_get_callcvt (type2);
    1256      1537992 :   if (ccvt1 != ccvt2)
    1257              :     return 0;
    1258      3053824 :   if (ix86_function_regparm (type1, NULL)
    1259      1526912 :       != ix86_function_regparm (type2, NULL))
    1260              :     return 0;
    1261              : 
    1262       744550 :   if (ix86_type_no_callee_saved_registers_p (type1)
    1263       744550 :       != ix86_type_no_callee_saved_registers_p (type2))
    1264              :     return 0;
    1265              : 
    1266              :   /* preserve_none attribute uses a different calling convention is
    1267              :      only for 64-bit.  */
    1268       744369 :   if (TARGET_64BIT
    1269      1488678 :       && (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type1))
    1270       744309 :           != lookup_attribute ("preserve_none",
    1271       744309 :                                TYPE_ATTRIBUTES (type2))))
    1272            2 :     return 0;
    1273              : 
    1274              :   return 1;
    1275              : }
    1276              : 
    1277              : /* Return the regparm value for a function with the indicated TYPE and DECL.
    1278              :    DECL may be NULL when calling function indirectly
    1279              :    or considering a libcall.  */
    1280              : 
    1281              : static int
    1282      4325444 : ix86_function_regparm (const_tree type, const_tree decl)
    1283              : {
    1284      4325444 :   tree attr;
    1285      4325444 :   int regparm;
    1286      4325444 :   unsigned int ccvt;
    1287              : 
    1288      4325444 :   if (TARGET_64BIT)
    1289      3053704 :     return (ix86_function_type_abi (type) == SYSV_ABI
    1290      3053704 :             ? X86_64_REGPARM_MAX : X86_64_MS_REGPARM_MAX);
    1291      1271740 :   ccvt = ix86_get_callcvt (type);
    1292      1271740 :   regparm = ix86_regparm;
    1293              : 
    1294      1271740 :   if ((ccvt & IX86_CALLCVT_REGPARM) != 0)
    1295              :     {
    1296         2020 :       attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
    1297         2020 :       if (attr)
    1298              :         {
    1299         2020 :           regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
    1300         2020 :           return regparm;
    1301              :         }
    1302              :     }
    1303      1269720 :   else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    1304              :     return 2;
    1305      1269720 :   else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    1306              :     return 1;
    1307              : 
    1308              :   /* Use register calling convention for local functions when possible.  */
    1309      1269720 :   if (decl
    1310      1205350 :       && TREE_CODE (decl) == FUNCTION_DECL)
    1311              :     {
    1312      1195259 :       cgraph_node *target = cgraph_node::get (decl);
    1313      1195259 :       if (target)
    1314      1187749 :         target = target->function_symbol ();
    1315              : 
    1316              :       /* Caller and callee must agree on the calling convention, so
    1317              :          checking here just optimize means that with
    1318              :          __attribute__((optimize (...))) caller could use regparm convention
    1319              :          and callee not, or vice versa.  Instead look at whether the callee
    1320              :          is optimized or not.  */
    1321      1187749 :       if (target && opt_for_fn (target->decl, optimize)
    1322      2374606 :           && !(profile_flag && !flag_fentry))
    1323              :         {
    1324      1186857 :           if (target->local && target->can_change_signature)
    1325              :             {
    1326       138252 :               int local_regparm, globals = 0, regno;
    1327              : 
    1328              :               /* Make sure no regparm register is taken by a
    1329              :                  fixed register variable.  */
    1330       138252 :               for (local_regparm = 0; local_regparm < REGPARM_MAX;
    1331              :                    local_regparm++)
    1332       103689 :                 if (fixed_regs[local_regparm])
    1333              :                   break;
    1334              : 
    1335              :               /* We don't want to use regparm(3) for nested functions as
    1336              :                  these use a static chain pointer in the third argument.  */
    1337        34563 :               if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl))
    1338              :                 local_regparm = 2;
    1339              : 
    1340              :               /* Save a register for the split stack.  */
    1341        34563 :               if (flag_split_stack)
    1342              :                 {
    1343        20152 :                   if (local_regparm == 3)
    1344              :                     local_regparm = 2;
    1345          707 :                   else if (local_regparm == 2
    1346          707 :                            && DECL_STATIC_CHAIN (target->decl))
    1347              :                     local_regparm = 1;
    1348              :                 }
    1349              : 
    1350              :               /* Each fixed register usage increases register pressure,
    1351              :                  so less registers should be used for argument passing.
    1352              :                  This functionality can be overridden by an explicit
    1353              :                  regparm value.  */
    1354       241941 :               for (regno = AX_REG; regno <= DI_REG; regno++)
    1355       207378 :                 if (fixed_regs[regno])
    1356            0 :                   globals++;
    1357              : 
    1358        34563 :               local_regparm
    1359        34563 :                 = globals < local_regparm ? local_regparm - globals : 0;
    1360              : 
    1361        34563 :               if (local_regparm > regparm)
    1362      4325444 :                 regparm = local_regparm;
    1363              :             }
    1364              :         }
    1365              :     }
    1366              : 
    1367              :   return regparm;
    1368              : }
    1369              : 
    1370              : /* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
    1371              :    DFmode (2) arguments in SSE registers for a function with the
    1372              :    indicated TYPE and DECL.  DECL may be NULL when calling function
    1373              :    indirectly or considering a libcall.  Return -1 if any FP parameter
    1374              :    should be rejected by error.  This is used in siutation we imply SSE
    1375              :    calling convention but the function is called from another function with
    1376              :    SSE disabled. Otherwise return 0.  */
    1377              : 
    1378              : static int
    1379      1079083 : ix86_function_sseregparm (const_tree type, const_tree decl, bool warn)
    1380              : {
    1381      1079083 :   gcc_assert (!TARGET_64BIT);
    1382              : 
    1383              :   /* Use SSE registers to pass SFmode and DFmode arguments if requested
    1384              :      by the sseregparm attribute.  */
    1385      1079083 :   if (TARGET_SSEREGPARM
    1386      1079083 :       || (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type))))
    1387              :     {
    1388            0 :       if (!TARGET_SSE)
    1389              :         {
    1390            0 :           if (warn)
    1391              :             {
    1392            0 :               if (decl)
    1393            0 :                 error ("calling %qD with attribute sseregparm without "
    1394              :                        "SSE/SSE2 enabled", decl);
    1395              :               else
    1396            0 :                 error ("calling %qT with attribute sseregparm without "
    1397              :                        "SSE/SSE2 enabled", type);
    1398              :             }
    1399              :           return 0;
    1400              :         }
    1401              : 
    1402              :       return 2;
    1403              :     }
    1404              : 
    1405      1079083 :   if (!decl)
    1406              :     return 0;
    1407              : 
    1408       979496 :   cgraph_node *target = cgraph_node::get (decl);
    1409       979496 :   if (target)
    1410       971993 :     target = target->function_symbol ();
    1411              : 
    1412              :   /* For local functions, pass up to SSE_REGPARM_MAX SFmode
    1413              :      (and DFmode for SSE2) arguments in SSE registers.  */
    1414       971993 :   if (target
    1415              :       /* TARGET_SSE_MATH */
    1416       971993 :       && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE)
    1417         1296 :       && opt_for_fn (target->decl, optimize)
    1418       973289 :       && !(profile_flag && !flag_fentry))
    1419              :     {
    1420         1296 :       if (target->local && target->can_change_signature)
    1421              :         {
    1422              :           /* Refuse to produce wrong code when local function with SSE enabled
    1423              :              is called from SSE disabled function.
    1424              :              FIXME: We need a way to detect these cases cross-ltrans partition
    1425              :              and avoid using SSE calling conventions on local functions called
    1426              :              from function with SSE disabled.  For now at least delay the
    1427              :              warning until we know we are going to produce wrong code.
    1428              :              See PR66047  */
    1429            0 :           if (!TARGET_SSE && warn)
    1430              :             return -1;
    1431            0 :           return TARGET_SSE2_P (target_opts_for_fn (target->decl)
    1432            0 :                                 ->x_ix86_isa_flags) ? 2 : 1;
    1433              :         }
    1434              :     }
    1435              : 
    1436              :   return 0;
    1437              : }
    1438              : 
    1439              : /* Return true if EAX is live at the start of the function.  Used by
    1440              :    ix86_expand_prologue to determine if we need special help before
    1441              :    calling allocate_stack_worker.  */
    1442              : 
    1443              : static bool
    1444         7090 : ix86_eax_live_at_start_p (void)
    1445              : {
    1446              :   /* Cheat.  Don't bother working forward from ix86_function_regparm
    1447              :      to the function type to whether an actual argument is located in
    1448              :      eax.  Instead just look at cfg info, which is still close enough
    1449              :      to correct at this point.  This gives false positives for broken
    1450              :      functions that might use uninitialized data that happens to be
    1451              :      allocated in eax, but who cares?  */
    1452         7090 :   return REGNO_REG_SET_P (df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)), 0);
    1453              : }
    1454              : 
    1455              : static bool
    1456       159594 : ix86_keep_aggregate_return_pointer (tree fntype)
    1457              : {
    1458       159594 :   tree attr;
    1459              : 
    1460       159594 :   if (!TARGET_64BIT)
    1461              :     {
    1462       159594 :       attr = lookup_attribute ("callee_pop_aggregate_return",
    1463       159594 :                                TYPE_ATTRIBUTES (fntype));
    1464       159594 :       if (attr)
    1465            0 :         return (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))) == 0);
    1466              : 
    1467              :       /* For 32-bit MS-ABI the default is to keep aggregate
    1468              :          return pointer.  */
    1469       159594 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    1470            0 :         return true;
    1471              :     }
    1472              :   return KEEP_AGGREGATE_RETURN_POINTER != 0;
    1473              : }
    1474              : 
    1475              : /* Value is the number of bytes of arguments automatically
    1476              :    popped when returning from a subroutine call.
    1477              :    FUNDECL is the declaration node of the function (as a tree),
    1478              :    FUNTYPE is the data type of the function (as a tree),
    1479              :    or for a library call it is an identifier node for the subroutine name.
    1480              :    SIZE is the number of bytes of arguments passed on the stack.
    1481              : 
    1482              :    On the 80386, the RTD insn may be used to pop them if the number
    1483              :      of args is fixed, but if the number is variable then the caller
    1484              :      must pop them all.  RTD can't be used for library calls now
    1485              :      because the library is compiled with the Unix compiler.
    1486              :    Use of RTD is a selectable option, since it is incompatible with
    1487              :    standard Unix calling sequences.  If the option is not selected,
    1488              :    the caller must always pop the args.
    1489              : 
    1490              :    The attribute stdcall is equivalent to RTD on a per module basis.  */
    1491              : 
    1492              : static poly_int64
    1493      7863061 : ix86_return_pops_args (tree fundecl, tree funtype, poly_int64 size)
    1494              : {
    1495      7863061 :   unsigned int ccvt;
    1496              : 
    1497              :   /* None of the 64-bit ABIs pop arguments.  */
    1498      7863061 :   if (TARGET_64BIT)
    1499      6989111 :     return 0;
    1500              : 
    1501       873950 :   ccvt = ix86_get_callcvt (funtype);
    1502              : 
    1503       873950 :   if ((ccvt & (IX86_CALLCVT_STDCALL | IX86_CALLCVT_FASTCALL
    1504              :                | IX86_CALLCVT_THISCALL)) != 0
    1505       873950 :       && ! stdarg_p (funtype))
    1506            3 :     return size;
    1507              : 
    1508              :   /* Lose any fake structure return argument if it is passed on the stack.  */
    1509       873947 :   if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
    1510       873947 :       && !ix86_keep_aggregate_return_pointer (funtype))
    1511              :     {
    1512       159594 :       int nregs = ix86_function_regparm (funtype, fundecl);
    1513       159594 :       if (nregs == 0)
    1514       458556 :         return GET_MODE_SIZE (Pmode);
    1515              :     }
    1516              : 
    1517       721095 :   return 0;
    1518              : }
    1519              : 
    1520              : /* Implement the TARGET_LEGITIMATE_COMBINED_INSN hook.  */
    1521              : 
    1522              : static bool
    1523     10320480 : ix86_legitimate_combined_insn (rtx_insn *insn)
    1524              : {
    1525     10320480 :   int i;
    1526              : 
    1527              :   /* Check operand constraints in case hard registers were propagated
    1528              :      into insn pattern.  This check prevents combine pass from
    1529              :      generating insn patterns with invalid hard register operands.
    1530              :      These invalid insns can eventually confuse reload to error out
    1531              :      with a spill failure.  See also PRs 46829 and 46843.  */
    1532              : 
    1533     10320480 :   gcc_assert (INSN_CODE (insn) >= 0);
    1534              : 
    1535     10320480 :   extract_insn (insn);
    1536     10320480 :   preprocess_constraints (insn);
    1537              : 
    1538     10320480 :   int n_operands = recog_data.n_operands;
    1539     10320480 :   int n_alternatives = recog_data.n_alternatives;
    1540     35171814 :   for (i = 0; i < n_operands; i++)
    1541              :     {
    1542     24854990 :       rtx op = recog_data.operand[i];
    1543     24854990 :       machine_mode mode = GET_MODE (op);
    1544     24854990 :       const operand_alternative *op_alt;
    1545     24854990 :       int offset = 0;
    1546     24854990 :       bool win;
    1547     24854990 :       int j;
    1548              : 
    1549              :       /* A unary operator may be accepted by the predicate, but it
    1550              :          is irrelevant for matching constraints.  */
    1551     24854990 :       if (UNARY_P (op))
    1552        47043 :         op = XEXP (op, 0);
    1553              : 
    1554     24854990 :       if (SUBREG_P (op))
    1555              :         {
    1556       883071 :           if (REG_P (SUBREG_REG (op))
    1557       883071 :               && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
    1558           54 :             offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
    1559           54 :                                           GET_MODE (SUBREG_REG (op)),
    1560           54 :                                           SUBREG_BYTE (op),
    1561           54 :                                           GET_MODE (op));
    1562       883071 :           op = SUBREG_REG (op);
    1563              :         }
    1564              : 
    1565     24854990 :       if (!(REG_P (op) && HARD_REGISTER_P (op)))
    1566     24596595 :         continue;
    1567              : 
    1568       258395 :       op_alt = recog_op_alt;
    1569              : 
    1570              :       /* Operand has no constraints, anything is OK.  */
    1571       258395 :       win = !n_alternatives;
    1572              : 
    1573       258395 :       alternative_mask preferred = get_preferred_alternatives (insn);
    1574       754176 :       for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
    1575              :         {
    1576       492076 :           if (!TEST_BIT (preferred, j))
    1577       153647 :             continue;
    1578       338429 :           if (op_alt[i].anything_ok
    1579       207255 :               || (op_alt[i].matches != -1
    1580        35172 :                   && operands_match_p
    1581        35172 :                   (recog_data.operand[i],
    1582        35172 :                    recog_data.operand[op_alt[i].matches]))
    1583       541532 :               || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
    1584              :             {
    1585              :               win = true;
    1586              :               break;
    1587              :             }
    1588              :         }
    1589              : 
    1590       258395 :       if (!win)
    1591              :         return false;
    1592              :     }
    1593              : 
    1594              :   return true;
    1595              : }
    1596              : 
    1597              : /* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
    1598              : 
    1599              : static unsigned HOST_WIDE_INT
    1600         4683 : ix86_asan_shadow_offset (void)
    1601              : {
    1602         4683 :   return SUBTARGET_SHADOW_OFFSET;
    1603              : }
    1604              : 
    1605              : /* Argument support functions.  */
    1606              : 
    1607              : /* Return true when register may be used to pass function parameters.  */
    1608              : bool
    1609   1552405554 : ix86_function_arg_regno_p (int regno)
    1610              : {
    1611   1552405554 :   int i;
    1612   1552405554 :   enum calling_abi call_abi;
    1613   1552405554 :   const int *parm_regs;
    1614              : 
    1615   1548848591 :   if (TARGET_SSE && SSE_REGNO_P (regno)
    1616   2546705508 :       && regno < FIRST_SSE_REG + SSE_REGPARM_MAX)
    1617              :     return true;
    1618              : 
    1619   1429569697 :    if (!TARGET_64BIT)
    1620    132128871 :      return (regno < REGPARM_MAX
    1621    132128871 :              || (TARGET_MMX && MMX_REGNO_P (regno)
    1622     11614360 :                  && regno < FIRST_MMX_REG + MMX_REGPARM_MAX));
    1623              : 
    1624              :   /* TODO: The function should depend on current function ABI but
    1625              :      builtins.cc would need updating then. Therefore we use the
    1626              :      default ABI.  */
    1627   1297440826 :   call_abi = ix86_cfun_abi ();
    1628              : 
    1629              :   /* RAX is used as hidden argument to va_arg functions.  */
    1630   1297440826 :   if (call_abi == SYSV_ABI && regno == AX_REG)
    1631              :     return true;
    1632              : 
    1633   1282805060 :   if (cfun
    1634   1282804720 :       && cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE)
    1635              :     parm_regs = x86_64_preserve_none_int_parameter_registers;
    1636   1282764160 :   else if (call_abi == MS_ABI)
    1637              :     parm_regs = x86_64_ms_abi_int_parameter_registers;
    1638              :   else
    1639   1244148086 :     parm_regs = x86_64_int_parameter_registers;
    1640              : 
    1641  17180970946 :   for (i = 0; i < (call_abi == MS_ABI
    1642   8590485473 :                    ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++)
    1643   7397262199 :     if (regno == parm_regs[i])
    1644              :       return true;
    1645              :   return false;
    1646              : }
    1647              : 
    1648              : /* Return if we do not know how to pass ARG solely in registers.  */
    1649              : 
    1650              : static bool
    1651    425929848 : ix86_must_pass_in_stack (const function_arg_info &arg)
    1652              : {
    1653    425929848 :   if (must_pass_in_stack_var_size_or_pad (arg))
    1654              :     return true;
    1655              : 
    1656              :   /* For 32-bit, we want TImode aggregates to go on the stack.  But watch out!
    1657              :      The layout_type routine is crafty and tries to trick us into passing
    1658              :      currently unsupported vector types on the stack by using TImode.  */
    1659      1773181 :   return (!TARGET_64BIT && arg.mode == TImode
    1660    425929811 :           && arg.type && TREE_CODE (arg.type) != VECTOR_TYPE);
    1661              : }
    1662              : 
    1663              : /* It returns the size, in bytes, of the area reserved for arguments passed
    1664              :    in registers for the function represented by fndecl dependent to the used
    1665              :    abi format.  */
    1666              : int
    1667     11127206 : ix86_reg_parm_stack_space (const_tree fndecl)
    1668              : {
    1669     11127206 :   enum calling_abi call_abi = SYSV_ABI;
    1670     11127206 :   if (fndecl != NULL_TREE && TREE_CODE (fndecl) == FUNCTION_DECL)
    1671     10804641 :     call_abi = ix86_function_abi (fndecl);
    1672              :   else
    1673       322565 :     call_abi = ix86_function_type_abi (fndecl);
    1674     11127206 :   if (TARGET_64BIT && call_abi == MS_ABI)
    1675       119430 :     return 32;
    1676              :   return 0;
    1677              : }
    1678              : 
    1679              : /* We add this as a workaround in order to use libc_has_function
    1680              :    hook in i386.md.  */
    1681              : bool
    1682            0 : ix86_libc_has_function (enum function_class fn_class)
    1683              : {
    1684            0 :   return targetm.libc_has_function (fn_class, NULL_TREE);
    1685              : }
    1686              : 
    1687              : /* Returns value SYSV_ABI, MS_ABI dependent on fntype,
    1688              :    specifying the call abi used.  */
    1689              : enum calling_abi
    1690    887199794 : ix86_function_type_abi (const_tree fntype)
    1691              : {
    1692    887199794 :   enum calling_abi abi = ix86_abi;
    1693              : 
    1694    887199794 :   if (fntype == NULL_TREE || TYPE_ATTRIBUTES (fntype) == NULL_TREE)
    1695              :     return abi;
    1696              : 
    1697     90203491 :   if (abi == SYSV_ABI
    1698     90203491 :       && lookup_attribute ("ms_abi", TYPE_ATTRIBUTES (fntype)))
    1699              :     {
    1700      4265624 :       static int warned;
    1701      4265624 :       if (TARGET_X32 && !warned)
    1702              :         {
    1703            1 :           error ("X32 does not support %<ms_abi%> attribute");
    1704            1 :           warned = 1;
    1705              :         }
    1706              : 
    1707              :       abi = MS_ABI;
    1708              :     }
    1709     85937867 :   else if (abi == MS_ABI
    1710     85937867 :            && lookup_attribute ("sysv_abi", TYPE_ATTRIBUTES (fntype)))
    1711              :     abi = SYSV_ABI;
    1712              : 
    1713              :   return abi;
    1714              : }
    1715              : 
    1716              : enum calling_abi
    1717    229592212 : ix86_function_abi (const_tree fndecl)
    1718              : {
    1719    229592212 :   return fndecl ? ix86_function_type_abi (TREE_TYPE (fndecl)) : ix86_abi;
    1720              : }
    1721              : 
    1722              : /* Returns value SYSV_ABI, MS_ABI dependent on cfun,
    1723              :    specifying the call abi used.  */
    1724              : enum calling_abi
    1725   2175196605 : ix86_cfun_abi (void)
    1726              : {
    1727   2175196605 :   return cfun ? cfun->machine->call_abi : ix86_abi;
    1728              : }
    1729              : 
    1730              : bool
    1731      5135432 : ix86_function_ms_hook_prologue (const_tree fn)
    1732              : {
    1733      5135432 :   if (fn && lookup_attribute ("ms_hook_prologue", DECL_ATTRIBUTES (fn)))
    1734              :     {
    1735            8 :       if (decl_function_context (fn) != NULL_TREE)
    1736            0 :         error_at (DECL_SOURCE_LOCATION (fn),
    1737              :                   "%<ms_hook_prologue%> attribute is not compatible "
    1738              :                   "with nested function");
    1739              :       else
    1740              :         return true;
    1741              :     }
    1742              :   return false;
    1743              : }
    1744              : 
    1745              : bool
    1746    127099859 : ix86_function_naked (const_tree fn)
    1747              : {
    1748    127099859 :   if (fn && lookup_attribute ("naked", DECL_ATTRIBUTES (fn)))
    1749          663 :     return true;
    1750              : 
    1751              :   return false;
    1752              : }
    1753              : 
    1754              : /* Write the extra assembler code needed to declare a function properly.  */
    1755              : 
    1756              : void
    1757      1592525 : ix86_asm_output_function_label (FILE *out_file, const char *fname,
    1758              :                                 tree decl)
    1759              : {
    1760      1592525 :   bool is_ms_hook = ix86_function_ms_hook_prologue (decl);
    1761              : 
    1762      1592525 :   if (cfun)
    1763      1588863 :     cfun->machine->function_label_emitted = true;
    1764              : 
    1765      1592525 :   if (is_ms_hook)
    1766              :     {
    1767            2 :       int i, filler_count = (TARGET_64BIT ? 32 : 16);
    1768            2 :       unsigned int filler_cc = 0xcccccccc;
    1769              : 
    1770           18 :       for (i = 0; i < filler_count; i += 4)
    1771           16 :         fprintf (out_file, ASM_LONG " %#x\n", filler_cc);
    1772              :     }
    1773              : 
    1774              : #ifdef SUBTARGET_ASM_UNWIND_INIT
    1775              :   SUBTARGET_ASM_UNWIND_INIT (out_file);
    1776              : #endif
    1777              : 
    1778      1592525 :   assemble_function_label_raw (out_file, fname);
    1779              : 
    1780              :   /* Output magic byte marker, if hot-patch attribute is set.  */
    1781      1592525 :   if (is_ms_hook)
    1782              :     {
    1783            2 :       if (TARGET_64BIT)
    1784              :         {
    1785              :           /* leaq [%rsp + 0], %rsp  */
    1786            2 :           fputs (ASM_BYTE "0x48, 0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00\n",
    1787              :                  out_file);
    1788              :         }
    1789              :       else
    1790              :         {
    1791              :           /* movl.s %edi, %edi
    1792              :              push   %ebp
    1793              :              movl.s %esp, %ebp */
    1794            0 :           fputs (ASM_BYTE "0x8b, 0xff, 0x55, 0x8b, 0xec\n", out_file);
    1795              :         }
    1796              :     }
    1797      1592525 : }
    1798              : 
    1799              : /* Output a user-defined label.  In AT&T syntax, registers are prefixed
    1800              :    with %, so labels require no punctuation.  In Intel syntax, registers
    1801              :    are unprefixed, so labels may clash with registers or other operators,
    1802              :    and require quoting.  */
    1803              : void
    1804     35677982 : ix86_asm_output_labelref (FILE *file, const char *prefix, const char *label)
    1805              : {
    1806     35677982 :   if (ASSEMBLER_DIALECT == ASM_ATT)
    1807     35676888 :     fprintf (file, "%s%s", prefix, label);
    1808              :   else
    1809         1094 :     fprintf (file, "\"%s%s\"", prefix, label);
    1810     35677982 : }
    1811              : 
    1812              : /* Implementation of call abi switching target hook. Specific to FNDECL
    1813              :    the specific call register sets are set.  See also
    1814              :    ix86_conditional_register_usage for more details.  */
    1815              : void
    1816    208253892 : ix86_call_abi_override (const_tree fndecl)
    1817              : {
    1818    208253892 :   cfun->machine->call_abi = ix86_function_abi (fndecl);
    1819    208253892 : }
    1820              : 
    1821              : /* Return 1 if pseudo register should be created and used to hold
    1822              :    GOT address for PIC code.  */
    1823              : bool
    1824    171584772 : ix86_use_pseudo_pic_reg (void)
    1825              : {
    1826    171584772 :   if ((TARGET_64BIT
    1827    160480249 :        && (ix86_cmodel == CM_SMALL_PIC
    1828              :            || TARGET_PECOFF))
    1829    160743172 :       || !flag_pic)
    1830    166753784 :     return false;
    1831              :   return true;
    1832              : }
    1833              : 
    1834              : /* Initialize large model PIC register.  */
    1835              : 
    1836              : static void
    1837           56 : ix86_init_large_pic_reg (unsigned int tmp_regno)
    1838              : {
    1839           56 :   rtx_code_label *label;
    1840           56 :   rtx tmp_reg;
    1841              : 
    1842           56 :   gcc_assert (Pmode == DImode);
    1843           56 :   label = gen_label_rtx ();
    1844           56 :   emit_label (label);
    1845           56 :   LABEL_PRESERVE_P (label) = 1;
    1846           56 :   tmp_reg = gen_rtx_REG (Pmode, tmp_regno);
    1847           56 :   gcc_assert (REGNO (pic_offset_table_rtx) != tmp_regno);
    1848           56 :   emit_insn (gen_set_rip_rex64 (pic_offset_table_rtx,
    1849              :                                 label));
    1850           56 :   emit_insn (gen_set_got_offset_rex64 (tmp_reg, label));
    1851           56 :   emit_insn (gen_add2_insn (pic_offset_table_rtx, tmp_reg));
    1852           56 :   const char *name = LABEL_NAME (label);
    1853           56 :   PUT_CODE (label, NOTE);
    1854           56 :   NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL;
    1855           56 :   NOTE_DELETED_LABEL_NAME (label) = name;
    1856           56 : }
    1857              : 
    1858              : /* Create and initialize PIC register if required.  */
    1859              : static void
    1860      1520561 : ix86_init_pic_reg (void)
    1861              : {
    1862      1520561 :   edge entry_edge;
    1863      1520561 :   rtx_insn *seq;
    1864              : 
    1865      1520561 :   if (!ix86_use_pseudo_pic_reg ())
    1866              :     return;
    1867              : 
    1868        40512 :   start_sequence ();
    1869              : 
    1870        40512 :   if (TARGET_64BIT)
    1871              :     {
    1872           69 :       if (ix86_cmodel == CM_LARGE_PIC)
    1873           53 :         ix86_init_large_pic_reg (R11_REG);
    1874              :       else
    1875           16 :         emit_insn (gen_set_got_rex64 (pic_offset_table_rtx));
    1876              :     }
    1877              :   else
    1878              :     {
    1879              :       /*  If there is future mcount call in the function it is more profitable
    1880              :           to emit SET_GOT into ABI defined REAL_PIC_OFFSET_TABLE_REGNUM.  */
    1881        40443 :       rtx reg = crtl->profile
    1882        40443 :                 ? gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM)
    1883        40443 :                 : pic_offset_table_rtx;
    1884        40443 :       rtx_insn *insn = emit_insn (gen_set_got (reg));
    1885        40443 :       RTX_FRAME_RELATED_P (insn) = 1;
    1886        40443 :       if (crtl->profile)
    1887            0 :         emit_move_insn (pic_offset_table_rtx, reg);
    1888        40443 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    1889              :     }
    1890              : 
    1891        40512 :   seq = end_sequence ();
    1892              : 
    1893        40512 :   entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    1894        40512 :   insert_insn_on_edge (seq, entry_edge);
    1895        40512 :   commit_one_edge_insertion (entry_edge);
    1896              : }
    1897              : 
    1898              : /* Initialize a variable CUM of type CUMULATIVE_ARGS
    1899              :    for a call to a function whose data type is FNTYPE.
    1900              :    For a library call, FNTYPE is 0.  */
    1901              : 
    1902              : void
    1903     10839594 : init_cumulative_args (CUMULATIVE_ARGS *cum,  /* Argument info to initialize */
    1904              :                       tree fntype,      /* tree ptr for function decl */
    1905              :                       rtx libname,      /* SYMBOL_REF of library name or 0 */
    1906              :                       tree fndecl,
    1907              :                       int caller)
    1908              : {
    1909     10839594 :   struct cgraph_node *local_info_node = NULL;
    1910     10839594 :   struct cgraph_node *target = NULL;
    1911              : 
    1912              :   /* Set silent_p to false to raise an error for invalid calls when
    1913              :      expanding function body.  */
    1914     10839594 :   cfun->machine->silent_p = false;
    1915              : 
    1916     10839594 :   memset (cum, 0, sizeof (*cum));
    1917              : 
    1918     10839594 :   tree preserve_none_type;
    1919     10839594 :   if (fndecl)
    1920              :     {
    1921     10486736 :       target = cgraph_node::get (fndecl);
    1922     10486736 :       if (target)
    1923              :         {
    1924     10328707 :           target = target->function_symbol ();
    1925     10328707 :           local_info_node = cgraph_node::local_info_node (target->decl);
    1926     10328707 :           cum->call_abi = ix86_function_abi (target->decl);
    1927     10328707 :           preserve_none_type = TREE_TYPE (target->decl);
    1928              :         }
    1929              :       else
    1930              :         {
    1931       158029 :           cum->call_abi = ix86_function_abi (fndecl);
    1932       158029 :           preserve_none_type = TREE_TYPE (fndecl);
    1933              :         }
    1934              :     }
    1935              :   else
    1936              :     {
    1937       352858 :       cum->call_abi = ix86_function_type_abi (fntype);
    1938       352858 :       preserve_none_type = fntype;
    1939              :     }
    1940              : 
    1941              :   /* For MS ABI functions, parameter passing scheme is unchanged.  */
    1942     10839594 :   cum->preserve_none_abi
    1943     10839594 :     = (preserve_none_type
    1944     10715484 :        && cum->call_abi != MS_ABI
    1945     21437968 :        && (lookup_attribute ("preserve_none",
    1946     10598374 :                              TYPE_ATTRIBUTES (preserve_none_type))
    1947              :            != nullptr));
    1948              : 
    1949     10839594 :   cum->caller = caller;
    1950              : 
    1951              :   /* Set up the number of registers to use for passing arguments.  */
    1952     10839594 :   cum->nregs = ix86_regparm;
    1953     10839594 :   if (TARGET_64BIT)
    1954              :     {
    1955      9802623 :       cum->nregs = (cum->call_abi == SYSV_ABI
    1956      9802623 :                    ? X86_64_REGPARM_MAX
    1957              :                    : X86_64_MS_REGPARM_MAX);
    1958              :     }
    1959     10839594 :   if (TARGET_SSE)
    1960              :     {
    1961     10830417 :       cum->sse_nregs = SSE_REGPARM_MAX;
    1962     10830417 :       if (TARGET_64BIT)
    1963              :         {
    1964      9793566 :           cum->sse_nregs = (cum->call_abi == SYSV_ABI
    1965      9793566 :                            ? X86_64_SSE_REGPARM_MAX
    1966              :                            : X86_64_MS_SSE_REGPARM_MAX);
    1967              :         }
    1968              :     }
    1969     10839594 :   if (TARGET_MMX)
    1970     11663681 :     cum->mmx_nregs = MMX_REGPARM_MAX;
    1971     10839594 :   cum->warn_avx512f = true;
    1972     10839594 :   cum->warn_avx = true;
    1973     10839594 :   cum->warn_sse = true;
    1974     10839594 :   cum->warn_mmx = true;
    1975              : 
    1976              :   /* Because type might mismatch in between caller and callee, we need to
    1977              :      use actual type of function for local calls.
    1978              :      FIXME: cgraph_analyze can be told to actually record if function uses
    1979              :      va_start so for local functions maybe_vaarg can be made aggressive
    1980              :      helping K&R code.
    1981              :      FIXME: once typesytem is fixed, we won't need this code anymore.  */
    1982     10839594 :   if (local_info_node && local_info_node->local
    1983       440994 :       && local_info_node->can_change_signature)
    1984       417645 :     fntype = TREE_TYPE (target->decl);
    1985     10839594 :   cum->stdarg = stdarg_p (fntype);
    1986     21679188 :   cum->maybe_vaarg = (fntype
    1987     11317560 :                       ? (!prototype_p (fntype) || stdarg_p (fntype))
    1988       124110 :                       : !libname);
    1989              : 
    1990     10839594 :   cum->decl = fndecl;
    1991              : 
    1992     10839594 :   cum->warn_empty = !warn_abi || cum->stdarg;
    1993     10839594 :   if (!cum->warn_empty && fntype)
    1994              :     {
    1995      2994731 :       function_args_iterator iter;
    1996      2994731 :       tree argtype;
    1997      2994731 :       bool seen_empty_type = false;
    1998      8336865 :       FOREACH_FUNCTION_ARGS (fntype, argtype, iter)
    1999              :         {
    2000      8336802 :           if (argtype == error_mark_node || VOID_TYPE_P (argtype))
    2001              :             break;
    2002      5366283 :           if (TYPE_EMPTY_P (argtype))
    2003              :             seen_empty_type = true;
    2004      5281290 :           else if (seen_empty_type)
    2005              :             {
    2006        24149 :               cum->warn_empty = true;
    2007        24149 :               break;
    2008              :             }
    2009              :         }
    2010              :     }
    2011              : 
    2012     10839594 :   if (!TARGET_64BIT)
    2013              :     {
    2014              :       /* If there are variable arguments, then we won't pass anything
    2015              :          in registers in 32-bit mode. */
    2016      1036971 :       if (stdarg_p (fntype))
    2017              :         {
    2018         9155 :           cum->nregs = 0;
    2019              :           /* Since in 32-bit, variable arguments are always passed on
    2020              :              stack, there is scratch register available for indirect
    2021              :              sibcall.  */
    2022         9155 :           cfun->machine->arg_reg_available = true;
    2023         9155 :           cum->sse_nregs = 0;
    2024         9155 :           cum->mmx_nregs = 0;
    2025         9155 :           cum->warn_avx512f = false;
    2026         9155 :           cum->warn_avx = false;
    2027         9155 :           cum->warn_sse = false;
    2028         9155 :           cum->warn_mmx = false;
    2029         9155 :           return;
    2030              :         }
    2031              : 
    2032              :       /* Use ecx and edx registers if function has fastcall attribute,
    2033              :          else look for regparm information.  */
    2034      1027816 :       if (fntype)
    2035              :         {
    2036      1014575 :           unsigned int ccvt = ix86_get_callcvt (fntype);
    2037      1014575 :           if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
    2038              :             {
    2039            0 :               cum->nregs = 1;
    2040            0 :               cum->fastcall = 1; /* Same first register as in fastcall.  */
    2041              :             }
    2042      1014575 :           else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
    2043              :             {
    2044            4 :               cum->nregs = 2;
    2045            4 :               cum->fastcall = 1;
    2046              :             }
    2047              :           else
    2048      1014571 :             cum->nregs = ix86_function_regparm (fntype, fndecl);
    2049              :         }
    2050              : 
    2051              :       /* Set up the number of SSE registers used for passing SFmode
    2052              :          and DFmode arguments.  Warn for mismatching ABI.  */
    2053      1027816 :       cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl, true);
    2054              :     }
    2055              : 
    2056     10830439 :   cfun->machine->arg_reg_available = (cum->nregs > 0);
    2057              : }
    2058              : 
    2059              : /* Return the "natural" mode for TYPE.  In most cases, this is just TYPE_MODE.
    2060              :    But in the case of vector types, it is some vector mode.
    2061              : 
    2062              :    When we have only some of our vector isa extensions enabled, then there
    2063              :    are some modes for which vector_mode_supported_p is false.  For these
    2064              :    modes, the generic vector support in gcc will choose some non-vector mode
    2065              :    in order to implement the type.  By computing the natural mode, we'll
    2066              :    select the proper ABI location for the operand and not depend on whatever
    2067              :    the middle-end decides to do with these vector types.
    2068              : 
    2069              :    The midde-end can't deal with the vector types > 16 bytes.  In this
    2070              :    case, we return the original mode and warn ABI change if CUM isn't
    2071              :    NULL.
    2072              : 
    2073              :    If INT_RETURN is true, warn ABI change if the vector mode isn't
    2074              :    available for function return value.  */
    2075              : 
    2076              : static machine_mode
    2077    239757087 : type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
    2078              :                    bool in_return)
    2079              : {
    2080    239757087 :   machine_mode mode = TYPE_MODE (type);
    2081              : 
    2082    239757087 :   if (VECTOR_TYPE_P (type) && !VECTOR_MODE_P (mode))
    2083              :     {
    2084       499688 :       HOST_WIDE_INT size = int_size_in_bytes (type);
    2085       499688 :       if ((size == 8 || size == 16 || size == 32 || size == 64)
    2086              :           /* ??? Generic code allows us to create width 1 vectors.  Ignore.  */
    2087       499688 :           && TYPE_VECTOR_SUBPARTS (type) > 1)
    2088              :         {
    2089       453635 :           machine_mode innermode = TYPE_MODE (TREE_TYPE (type));
    2090              : 
    2091              :           /* There are no XFmode vector modes ...  */
    2092       453635 :           if (innermode == XFmode)
    2093              :             return mode;
    2094              : 
    2095              :           /* ... and no decimal float vector modes.  */
    2096       453082 :           if (DECIMAL_FLOAT_MODE_P (innermode))
    2097              :             return mode;
    2098              : 
    2099       452789 :           if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (type)))
    2100              :             mode = MIN_MODE_VECTOR_FLOAT;
    2101              :           else
    2102       374193 :             mode = MIN_MODE_VECTOR_INT;
    2103              : 
    2104              :           /* Get the mode which has this inner mode and number of units.  */
    2105      9495938 :           FOR_EACH_MODE_FROM (mode, mode)
    2106     19769518 :             if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
    2107     10726369 :                 && GET_MODE_INNER (mode) == innermode)
    2108              :               {
    2109       452789 :                 if (size == 64 && !TARGET_AVX512F && !TARGET_IAMCU)
    2110              :                   {
    2111       300665 :                     static bool warnedavx512f;
    2112       300665 :                     static bool warnedavx512f_ret;
    2113              : 
    2114       300665 :                     if (cum && cum->warn_avx512f && !warnedavx512f)
    2115              :                       {
    2116         1361 :                         if (warning (OPT_Wpsabi, "AVX512F vector argument "
    2117              :                                      "without AVX512F enabled changes the ABI"))
    2118            2 :                           warnedavx512f = true;
    2119              :                       }
    2120       299304 :                     else if (in_return && !warnedavx512f_ret)
    2121              :                       {
    2122       283951 :                         if (warning (OPT_Wpsabi, "AVX512F vector return "
    2123              :                                      "without AVX512F enabled changes the ABI"))
    2124            8 :                           warnedavx512f_ret = true;
    2125              :                       }
    2126              : 
    2127       300665 :                     return TYPE_MODE (type);
    2128              :                   }
    2129       152124 :                 else if (size == 32 && !TARGET_AVX && !TARGET_IAMCU)
    2130              :                   {
    2131       150198 :                     static bool warnedavx;
    2132       150198 :                     static bool warnedavx_ret;
    2133              : 
    2134       150198 :                     if (cum && cum->warn_avx && !warnedavx)
    2135              :                       {
    2136          770 :                         if (warning (OPT_Wpsabi, "AVX vector argument "
    2137              :                                      "without AVX enabled changes the ABI"))
    2138            5 :                           warnedavx = true;
    2139              :                       }
    2140       149428 :                     else if (in_return && !warnedavx_ret)
    2141              :                       {
    2142       121906 :                         if (warning (OPT_Wpsabi, "AVX vector return "
    2143              :                                      "without AVX enabled changes the ABI"))
    2144           13 :                           warnedavx_ret = true;
    2145              :                       }
    2146              : 
    2147       150198 :                     return TYPE_MODE (type);
    2148              :                   }
    2149         1926 :                 else if (((size == 8 && TARGET_64BIT) || size == 16)
    2150         1923 :                          && !TARGET_SSE
    2151          140 :                          && !TARGET_IAMCU)
    2152              :                   {
    2153          140 :                     static bool warnedsse;
    2154          140 :                     static bool warnedsse_ret;
    2155              : 
    2156          140 :                     if (cum && cum->warn_sse && !warnedsse)
    2157              :                       {
    2158           19 :                         if (warning (OPT_Wpsabi, "SSE vector argument "
    2159              :                                      "without SSE enabled changes the ABI"))
    2160            6 :                           warnedsse = true;
    2161              :                       }
    2162          121 :                     else if (!TARGET_64BIT && in_return && !warnedsse_ret)
    2163              :                       {
    2164            0 :                         if (warning (OPT_Wpsabi, "SSE vector return "
    2165              :                                      "without SSE enabled changes the ABI"))
    2166            0 :                           warnedsse_ret = true;
    2167              :                       }
    2168              :                   }
    2169         1786 :                 else if ((size == 8 && !TARGET_64BIT)
    2170            0 :                          && (!cfun
    2171            0 :                              || cfun->machine->func_type == TYPE_NORMAL)
    2172            0 :                          && !TARGET_MMX
    2173            0 :                          && !TARGET_IAMCU)
    2174              :                   {
    2175            0 :                     static bool warnedmmx;
    2176            0 :                     static bool warnedmmx_ret;
    2177              : 
    2178            0 :                     if (cum && cum->warn_mmx && !warnedmmx)
    2179              :                       {
    2180            0 :                         if (warning (OPT_Wpsabi, "MMX vector argument "
    2181              :                                      "without MMX enabled changes the ABI"))
    2182            0 :                           warnedmmx = true;
    2183              :                       }
    2184            0 :                     else if (in_return && !warnedmmx_ret)
    2185              :                       {
    2186            0 :                         if (warning (OPT_Wpsabi, "MMX vector return "
    2187              :                                      "without MMX enabled changes the ABI"))
    2188            0 :                           warnedmmx_ret = true;
    2189              :                       }
    2190              :                   }
    2191              :                 return mode;
    2192              :               }
    2193              : 
    2194            0 :           gcc_unreachable ();
    2195              :         }
    2196              :     }
    2197              : 
    2198              :   return mode;
    2199              : }
    2200              : 
    2201              : /* We want to pass a value in REGNO whose "natural" mode is MODE.  However,
    2202              :    this may not agree with the mode that the type system has chosen for the
    2203              :    register, which is ORIG_MODE.  If ORIG_MODE is not BLKmode, then we can
    2204              :    go ahead and use it.  Otherwise we have to build a PARALLEL instead.  */
    2205              : 
    2206              : static rtx
    2207     37863878 : gen_reg_or_parallel (machine_mode mode, machine_mode orig_mode,
    2208              :                      unsigned int regno)
    2209              : {
    2210     37863878 :   rtx tmp;
    2211              : 
    2212     37863878 :   if (orig_mode != BLKmode)
    2213     37863715 :     tmp = gen_rtx_REG (orig_mode, regno);
    2214              :   else
    2215              :     {
    2216          163 :       tmp = gen_rtx_REG (mode, regno);
    2217          163 :       tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, const0_rtx);
    2218          163 :       tmp = gen_rtx_PARALLEL (orig_mode, gen_rtvec (1, tmp));
    2219              :     }
    2220              : 
    2221     37863878 :   return tmp;
    2222              : }
    2223              : 
    2224              : /* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
    2225              :    of this code is to classify each 8bytes of incoming argument by the register
    2226              :    class and assign registers accordingly.  */
    2227              : 
    2228              : /* Return the union class of CLASS1 and CLASS2.
    2229              :    See the x86-64 PS ABI for details.  */
    2230              : 
    2231              : static enum x86_64_reg_class
    2232     59261133 : merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
    2233              : {
    2234              :   /* Rule #1: If both classes are equal, this is the resulting class.  */
    2235     57957988 :   if (class1 == class2)
    2236              :     return class1;
    2237              : 
    2238              :   /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
    2239              :      the other class.  */
    2240     51133134 :   if (class1 == X86_64_NO_CLASS)
    2241              :     return class2;
    2242     52000427 :   if (class2 == X86_64_NO_CLASS)
    2243              :     return class1;
    2244              : 
    2245              :   /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
    2246      1748470 :   if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
    2247              :     return X86_64_MEMORY_CLASS;
    2248              : 
    2249              :   /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
    2250      1589612 :   if ((class1 == X86_64_INTEGERSI_CLASS
    2251       192170 :        && (class2 == X86_64_SSESF_CLASS || class2 == X86_64_SSEHF_CLASS))
    2252      1588406 :       || (class2 == X86_64_INTEGERSI_CLASS
    2253       960079 :           && (class1 == X86_64_SSESF_CLASS || class1 == X86_64_SSEHF_CLASS)))
    2254              :     return X86_64_INTEGERSI_CLASS;
    2255      1584469 :   if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
    2256       418156 :       || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
    2257              :     return X86_64_INTEGER_CLASS;
    2258              : 
    2259              :   /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class,
    2260              :      MEMORY is used.  */
    2261       101671 :   if (class1 == X86_64_X87_CLASS
    2262              :       || class1 == X86_64_X87UP_CLASS
    2263       101671 :       || class1 == X86_64_COMPLEX_X87_CLASS
    2264              :       || class2 == X86_64_X87_CLASS
    2265       100766 :       || class2 == X86_64_X87UP_CLASS
    2266        67264 :       || class2 == X86_64_COMPLEX_X87_CLASS)
    2267        34407 :     return X86_64_MEMORY_CLASS;
    2268              : 
    2269              :   /* Rule #6: Otherwise class SSE is used.  */
    2270              :   return X86_64_SSE_CLASS;
    2271              : }
    2272              : 
    2273              : /* Classify the argument of type TYPE and mode MODE.
    2274              :    CLASSES will be filled by the register class used to pass each word
    2275              :    of the operand.  The number of words is returned.  In case the parameter
    2276              :    should be passed in memory, 0 is returned. As a special case for zero
    2277              :    sized containers, classes[0] will be NO_CLASS and 1 is returned.
    2278              : 
    2279              :    BIT_OFFSET is used internally for handling records and specifies offset
    2280              :    of the offset in bits modulo 512 to avoid overflow cases.
    2281              : 
    2282              :    See the x86-64 PS ABI for details.
    2283              : */
    2284              : 
    2285              : static int
    2286    411417800 : classify_argument (machine_mode mode, const_tree type,
    2287              :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset,
    2288              :                    int &zero_width_bitfields)
    2289              : {
    2290    411417800 :   HOST_WIDE_INT bytes
    2291    816413471 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2292    411417800 :   int words = CEIL (bytes + (bit_offset % 64) / 8, UNITS_PER_WORD);
    2293              : 
    2294              :   /* Variable sized entities are always passed/returned in memory.  */
    2295    411417800 :   if (bytes < 0)
    2296              :     return 0;
    2297              : 
    2298    411416601 :   if (mode != VOIDmode)
    2299              :     {
    2300              :       /* The value of "named" doesn't matter.  */
    2301    410157041 :       function_arg_info arg (const_cast<tree> (type), mode, /*named=*/true);
    2302    410157041 :       if (targetm.calls.must_pass_in_stack (arg))
    2303           37 :         return 0;
    2304              :     }
    2305              : 
    2306    411416564 :   if (type && (AGGREGATE_TYPE_P (type)
    2307    372598176 :                || (BITINT_TYPE_P (type) && words > 1)))
    2308              :     {
    2309     39936729 :       int i;
    2310     39936729 :       tree field;
    2311     39936729 :       enum x86_64_reg_class subclasses[MAX_CLASSES];
    2312              : 
    2313              :       /* On x86-64 we pass structures larger than 64 bytes on the stack.  */
    2314     39936729 :       if (bytes > 64)
    2315              :         return 0;
    2316              : 
    2317    100169527 :       for (i = 0; i < words; i++)
    2318     61076283 :         classes[i] = X86_64_NO_CLASS;
    2319              : 
    2320              :       /* Zero sized arrays or structures are NO_CLASS.  We return 0 to
    2321              :          signalize memory class, so handle it as special case.  */
    2322     39093244 :       if (!words)
    2323              :         {
    2324        85032 :           classes[0] = X86_64_NO_CLASS;
    2325        85032 :           return 1;
    2326              :         }
    2327              : 
    2328              :       /* Classify each field of record and merge classes.  */
    2329     39008212 :       switch (TREE_CODE (type))
    2330              :         {
    2331     36883765 :         case RECORD_TYPE:
    2332              :           /* And now merge the fields of structure.  */
    2333   1023778375 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2334              :             {
    2335    987454376 :               if (TREE_CODE (field) == FIELD_DECL)
    2336              :                 {
    2337     54129502 :                   int num;
    2338              : 
    2339     54129502 :                   if (TREE_TYPE (field) == error_mark_node)
    2340            4 :                     continue;
    2341              : 
    2342              :                   /* Bitfields are always classified as integer.  Handle them
    2343              :                      early, since later code would consider them to be
    2344              :                      misaligned integers.  */
    2345     54129498 :                   if (DECL_BIT_FIELD (field))
    2346              :                     {
    2347      1312364 :                       if (integer_zerop (DECL_SIZE (field)))
    2348              :                         {
    2349        12839 :                           if (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD (field))
    2350         8021 :                             continue;
    2351         4818 :                           if (zero_width_bitfields != 2)
    2352              :                             {
    2353         4284 :                               zero_width_bitfields = 1;
    2354         4284 :                               continue;
    2355              :                             }
    2356              :                         }
    2357      1300059 :                       for (i = (int_bit_position (field)
    2358      1300059 :                                 + (bit_offset % 64)) / 8 / 8;
    2359      2603204 :                            i < ((int_bit_position (field) + (bit_offset % 64))
    2360      2603204 :                                 + tree_to_shwi (DECL_SIZE (field))
    2361      2603204 :                                 + 63) / 8 / 8; i++)
    2362      1303145 :                         classes[i]
    2363      2606290 :                           = merge_classes (X86_64_INTEGER_CLASS, classes[i]);
    2364              :                     }
    2365              :                   else
    2366              :                     {
    2367     52817134 :                       int pos;
    2368              : 
    2369     52817134 :                       type = TREE_TYPE (field);
    2370              : 
    2371              :                       /* Flexible array member is ignored.  */
    2372     52817134 :                       if (TYPE_MODE (type) == BLKmode
    2373       709007 :                           && TREE_CODE (type) == ARRAY_TYPE
    2374       178408 :                           && TYPE_SIZE (type) == NULL_TREE
    2375         2007 :                           && TYPE_DOMAIN (type) != NULL_TREE
    2376     52818376 :                           && (TYPE_MAX_VALUE (TYPE_DOMAIN (type))
    2377              :                               == NULL_TREE))
    2378              :                         {
    2379         1242 :                           static bool warned;
    2380              : 
    2381         1242 :                           if (!warned && warn_psabi)
    2382              :                             {
    2383            3 :                               warned = true;
    2384            3 :                               inform (input_location,
    2385              :                                       "the ABI of passing struct with"
    2386              :                                       " a flexible array member has"
    2387              :                                       " changed in GCC 4.4");
    2388              :                             }
    2389         1242 :                           continue;
    2390         1242 :                         }
    2391     52815892 :                       num = classify_argument (TYPE_MODE (type), type,
    2392              :                                                subclasses,
    2393     52815892 :                                                (int_bit_position (field)
    2394     52815892 :                                                 + bit_offset) % 512,
    2395              :                                                zero_width_bitfields);
    2396     52815892 :                       if (!num)
    2397              :                         return 0;
    2398     52256126 :                       pos = (int_bit_position (field)
    2399     52256126 :                              + (bit_offset % 64)) / 8 / 8;
    2400    108150971 :                       for (i = 0; i < num && (i + pos) < words; i++)
    2401     55894845 :                         classes[i + pos]
    2402     55894845 :                           = merge_classes (subclasses[i], classes[i + pos]);
    2403              :                     }
    2404              :                 }
    2405              :             }
    2406              :           break;
    2407              : 
    2408       494338 :         case ARRAY_TYPE:
    2409              :           /* Arrays are handled as small records.  */
    2410       494338 :           {
    2411       494338 :             int num;
    2412       494338 :             num = classify_argument (TYPE_MODE (TREE_TYPE (type)),
    2413       494338 :                                      TREE_TYPE (type), subclasses, bit_offset,
    2414              :                                      zero_width_bitfields);
    2415       494338 :             if (!num)
    2416              :               return 0;
    2417              : 
    2418              :             /* The partial classes are now full classes.  */
    2419       477818 :             if (subclasses[0] == X86_64_SSESF_CLASS && bytes != 4)
    2420        13959 :               subclasses[0] = X86_64_SSE_CLASS;
    2421       477818 :             if (subclasses[0] == X86_64_SSEHF_CLASS && bytes != 2)
    2422         5292 :               subclasses[0] = X86_64_SSE_CLASS;
    2423       477818 :             if (subclasses[0] == X86_64_INTEGERSI_CLASS
    2424       175988 :                 && !((bit_offset % 64) == 0 && bytes == 4))
    2425       138185 :               subclasses[0] = X86_64_INTEGER_CLASS;
    2426              : 
    2427      1445120 :             for (i = 0; i < words; i++)
    2428       967302 :               classes[i] = subclasses[i % num];
    2429              : 
    2430              :             break;
    2431              :           }
    2432       287775 :         case UNION_TYPE:
    2433       287775 :         case QUAL_UNION_TYPE:
    2434              :           /* Unions are similar to RECORD_TYPE but offset is always 0.
    2435              :              */
    2436      3304839 :           for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    2437              :             {
    2438      3052322 :               if (TREE_CODE (field) == FIELD_DECL)
    2439              :                 {
    2440      1318882 :                   int num;
    2441              : 
    2442      1318882 :                   if (TREE_TYPE (field) == error_mark_node)
    2443           10 :                     continue;
    2444              : 
    2445      1318872 :                   num = classify_argument (TYPE_MODE (TREE_TYPE (field)),
    2446      1318872 :                                            TREE_TYPE (field), subclasses,
    2447              :                                            bit_offset, zero_width_bitfields);
    2448      1318872 :                   if (!num)
    2449              :                     return 0;
    2450      3346757 :                   for (i = 0; i < num && i < words; i++)
    2451      2063143 :                     classes[i] = merge_classes (subclasses[i], classes[i]);
    2452              :                 }
    2453              :             }
    2454              :           break;
    2455              : 
    2456      1342334 :         case BITINT_TYPE:
    2457      1342334 :         case ENUMERAL_TYPE:
    2458              :           /* _BitInt(N) for N > 64 is passed as structure containing
    2459              :              (N + 63) / 64 64-bit elements.  */
    2460      1342334 :           if (words > 2)
    2461              :             return 0;
    2462        77427 :           classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2463        77427 :           return 2;
    2464              : 
    2465            0 :         default:
    2466            0 :           gcc_unreachable ();
    2467              :         }
    2468              : 
    2469     37054334 :       if (words > 2)
    2470              :         {
    2471              :           /* When size > 16 bytes, if the first one isn't
    2472              :              X86_64_SSE_CLASS or any other ones aren't
    2473              :              X86_64_SSEUP_CLASS, everything should be passed in
    2474              :              memory.  */
    2475      1734044 :           if (classes[0] != X86_64_SSE_CLASS)
    2476              :             return 0;
    2477              : 
    2478       203643 :           for (i = 1; i < words; i++)
    2479       185456 :             if (classes[i] != X86_64_SSEUP_CLASS)
    2480              :               return 0;
    2481              :         }
    2482              : 
    2483              :       /* Final merger cleanup.  */
    2484     82955352 :       for (i = 0; i < words; i++)
    2485              :         {
    2486              :           /* If one class is MEMORY, everything should be passed in
    2487              :              memory.  */
    2488     47652939 :           if (classes[i] == X86_64_MEMORY_CLASS)
    2489              :             return 0;
    2490              : 
    2491              :           /* The X86_64_SSEUP_CLASS should be always preceded by
    2492              :              X86_64_SSE_CLASS or X86_64_SSEUP_CLASS.  */
    2493     47619245 :           if (classes[i] == X86_64_SSEUP_CLASS
    2494       297204 :               && classes[i - 1] != X86_64_SSE_CLASS
    2495        76546 :               && classes[i - 1] != X86_64_SSEUP_CLASS)
    2496              :             {
    2497              :               /* The first one should never be X86_64_SSEUP_CLASS.  */
    2498         1916 :               gcc_assert (i != 0);
    2499         1916 :               classes[i] = X86_64_SSE_CLASS;
    2500              :             }
    2501              : 
    2502              :           /* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
    2503              :              everything should be passed in memory.  */
    2504     47619245 :           if (classes[i] == X86_64_X87UP_CLASS
    2505       186831 :               && (classes[i - 1] != X86_64_X87_CLASS))
    2506              :             {
    2507         2370 :               static bool warned;
    2508              : 
    2509              :               /* The first one should never be X86_64_X87UP_CLASS.  */
    2510         2370 :               gcc_assert (i != 0);
    2511         2370 :               if (!warned && warn_psabi)
    2512              :                 {
    2513            1 :                   warned = true;
    2514            1 :                   inform (input_location,
    2515              :                           "the ABI of passing union with %<long double%>"
    2516              :                           " has changed in GCC 4.4");
    2517              :                 }
    2518              :               return 0;
    2519              :             }
    2520              :         }
    2521              :       return words;
    2522              :     }
    2523              : 
    2524              :   /* Compute alignment needed.  We align all types to natural boundaries with
    2525              :      exception of XFmode that is aligned to 64bits.  */
    2526    371479835 :   if (mode != VOIDmode && mode != BLKmode)
    2527              :     {
    2528    369725471 :       int mode_alignment = GET_MODE_BITSIZE (mode);
    2529              : 
    2530    369725471 :       if (mode == XFmode)
    2531              :         mode_alignment = 128;
    2532    362529064 :       else if (mode == XCmode)
    2533       572503 :         mode_alignment = 256;
    2534    369725471 :       if (COMPLEX_MODE_P (mode))
    2535      2745872 :         mode_alignment /= 2;
    2536              :       /* Misaligned fields are always returned in memory.  */
    2537    369725471 :       if (bit_offset % mode_alignment)
    2538              :         return 0;
    2539              :     }
    2540              : 
    2541              :   /* for V1xx modes, just use the base mode */
    2542    371472202 :   if (VECTOR_MODE_P (mode) && mode != V1DImode && mode != V1TImode
    2543    468239891 :       && GET_MODE_UNIT_SIZE (mode) == bytes)
    2544         6651 :     mode = GET_MODE_INNER (mode);
    2545              : 
    2546              :   /* Classification of atomic types.  */
    2547    371472202 :   switch (mode)
    2548              :     {
    2549       206005 :     case E_SDmode:
    2550       206005 :     case E_DDmode:
    2551       206005 :       classes[0] = X86_64_SSE_CLASS;
    2552       206005 :       return 1;
    2553        98417 :     case E_TDmode:
    2554        98417 :       classes[0] = X86_64_SSE_CLASS;
    2555        98417 :       classes[1] = X86_64_SSEUP_CLASS;
    2556        98417 :       return 2;
    2557    243522399 :     case E_DImode:
    2558    243522399 :     case E_SImode:
    2559    243522399 :     case E_HImode:
    2560    243522399 :     case E_QImode:
    2561    243522399 :     case E_CSImode:
    2562    243522399 :     case E_CHImode:
    2563    243522399 :     case E_CQImode:
    2564    243522399 :       {
    2565    243522399 :         int size = bit_offset + (int) GET_MODE_BITSIZE (mode);
    2566              : 
    2567              :         /* Analyze last 128 bits only.  */
    2568    243522399 :         size = (size - 1) & 0x7f;
    2569              : 
    2570    243522399 :         if (size < 32)
    2571              :           {
    2572    106647625 :             classes[0] = X86_64_INTEGERSI_CLASS;
    2573    106647625 :             return 1;
    2574              :           }
    2575    136874774 :         else if (size < 64)
    2576              :           {
    2577    125472412 :             classes[0] = X86_64_INTEGER_CLASS;
    2578    125472412 :             return 1;
    2579              :           }
    2580     11402362 :         else if (size < 64+32)
    2581              :           {
    2582      4256064 :             classes[0] = X86_64_INTEGER_CLASS;
    2583      4256064 :             classes[1] = X86_64_INTEGERSI_CLASS;
    2584      4256064 :             return 2;
    2585              :           }
    2586      7146298 :         else if (size < 64+64)
    2587              :           {
    2588      7146298 :             classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2589      7146298 :             return 2;
    2590              :           }
    2591              :         else
    2592              :           gcc_unreachable ();
    2593              :       }
    2594      2582217 :     case E_CDImode:
    2595      2582217 :     case E_TImode:
    2596      2582217 :       classes[0] = classes[1] = X86_64_INTEGER_CLASS;
    2597      2582217 :       return 2;
    2598            0 :     case E_COImode:
    2599            0 :     case E_OImode:
    2600              :       /* OImode shouldn't be used directly.  */
    2601            0 :       gcc_unreachable ();
    2602              :     case E_CTImode:
    2603              :       return 0;
    2604      1033328 :     case E_HFmode:
    2605      1033328 :     case E_BFmode:
    2606      1033328 :       if (!(bit_offset % 64))
    2607      1020114 :         classes[0] = X86_64_SSEHF_CLASS;
    2608              :       else
    2609        13214 :         classes[0] = X86_64_SSE_CLASS;
    2610              :       return 1;
    2611     10151690 :     case E_SFmode:
    2612     10151690 :       if (!(bit_offset % 64))
    2613     10097752 :         classes[0] = X86_64_SSESF_CLASS;
    2614              :       else
    2615        53938 :         classes[0] = X86_64_SSE_CLASS;
    2616              :       return 1;
    2617      4490125 :     case E_DFmode:
    2618      4490125 :       classes[0] = X86_64_SSEDF_CLASS;
    2619      4490125 :       return 1;
    2620      7195691 :     case E_XFmode:
    2621      7195691 :       classes[0] = X86_64_X87_CLASS;
    2622      7195691 :       classes[1] = X86_64_X87UP_CLASS;
    2623      7195691 :       return 2;
    2624      1409775 :     case E_TFmode:
    2625      1409775 :       classes[0] = X86_64_SSE_CLASS;
    2626      1409775 :       classes[1] = X86_64_SSEUP_CLASS;
    2627      1409775 :       return 2;
    2628       106067 :     case E_HCmode:
    2629       106067 :     case E_BCmode:
    2630       106067 :       classes[0] = X86_64_SSE_CLASS;
    2631       106067 :       if (!(bit_offset % 64))
    2632              :         return 1;
    2633              :       else
    2634              :         {
    2635           98 :           classes[1] = X86_64_SSEHF_CLASS;
    2636           98 :           return 2;
    2637              :         }
    2638       734531 :     case E_SCmode:
    2639       734531 :       classes[0] = X86_64_SSE_CLASS;
    2640       734531 :       if (!(bit_offset % 64))
    2641              :         return 1;
    2642              :       else
    2643              :         {
    2644         1119 :           static bool warned;
    2645              : 
    2646         1119 :           if (!warned && warn_psabi)
    2647              :             {
    2648            2 :               warned = true;
    2649            2 :               inform (input_location,
    2650              :                       "the ABI of passing structure with %<complex float%>"
    2651              :                       " member has changed in GCC 4.4");
    2652              :             }
    2653         1119 :           classes[1] = X86_64_SSESF_CLASS;
    2654         1119 :           return 2;
    2655              :         }
    2656       742808 :     case E_DCmode:
    2657       742808 :       classes[0] = X86_64_SSEDF_CLASS;
    2658       742808 :       classes[1] = X86_64_SSEDF_CLASS;
    2659       742808 :       return 2;
    2660       572503 :     case E_XCmode:
    2661       572503 :       classes[0] = X86_64_COMPLEX_X87_CLASS;
    2662       572503 :       return 1;
    2663              :     case E_TCmode:
    2664              :       /* This modes is larger than 16 bytes.  */
    2665              :       return 0;
    2666     25806029 :     case E_V8SFmode:
    2667     25806029 :     case E_V8SImode:
    2668     25806029 :     case E_V32QImode:
    2669     25806029 :     case E_V16HFmode:
    2670     25806029 :     case E_V16BFmode:
    2671     25806029 :     case E_V16HImode:
    2672     25806029 :     case E_V4DFmode:
    2673     25806029 :     case E_V4DImode:
    2674     25806029 :       classes[0] = X86_64_SSE_CLASS;
    2675     25806029 :       classes[1] = X86_64_SSEUP_CLASS;
    2676     25806029 :       classes[2] = X86_64_SSEUP_CLASS;
    2677     25806029 :       classes[3] = X86_64_SSEUP_CLASS;
    2678     25806029 :       return 4;
    2679     28040386 :     case E_V8DFmode:
    2680     28040386 :     case E_V16SFmode:
    2681     28040386 :     case E_V32HFmode:
    2682     28040386 :     case E_V32BFmode:
    2683     28040386 :     case E_V8DImode:
    2684     28040386 :     case E_V16SImode:
    2685     28040386 :     case E_V32HImode:
    2686     28040386 :     case E_V64QImode:
    2687     28040386 :       classes[0] = X86_64_SSE_CLASS;
    2688     28040386 :       classes[1] = X86_64_SSEUP_CLASS;
    2689     28040386 :       classes[2] = X86_64_SSEUP_CLASS;
    2690     28040386 :       classes[3] = X86_64_SSEUP_CLASS;
    2691     28040386 :       classes[4] = X86_64_SSEUP_CLASS;
    2692     28040386 :       classes[5] = X86_64_SSEUP_CLASS;
    2693     28040386 :       classes[6] = X86_64_SSEUP_CLASS;
    2694     28040386 :       classes[7] = X86_64_SSEUP_CLASS;
    2695     28040386 :       return 8;
    2696     39583269 :     case E_V4SFmode:
    2697     39583269 :     case E_V4SImode:
    2698     39583269 :     case E_V16QImode:
    2699     39583269 :     case E_V8HImode:
    2700     39583269 :     case E_V8HFmode:
    2701     39583269 :     case E_V8BFmode:
    2702     39583269 :     case E_V2DFmode:
    2703     39583269 :     case E_V2DImode:
    2704     39583269 :       classes[0] = X86_64_SSE_CLASS;
    2705     39583269 :       classes[1] = X86_64_SSEUP_CLASS;
    2706     39583269 :       return 2;
    2707      3299017 :     case E_V1TImode:
    2708      3299017 :     case E_V1DImode:
    2709      3299017 :     case E_V2SFmode:
    2710      3299017 :     case E_V2SImode:
    2711      3299017 :     case E_V4HImode:
    2712      3299017 :     case E_V4HFmode:
    2713      3299017 :     case E_V4BFmode:
    2714      3299017 :     case E_V2HFmode:
    2715      3299017 :     case E_V2BFmode:
    2716      3299017 :     case E_V8QImode:
    2717      3299017 :       classes[0] = X86_64_SSE_CLASS;
    2718      3299017 :       return 1;
    2719              :     case E_BLKmode:
    2720              :     case E_VOIDmode:
    2721              :       return 0;
    2722        52801 :     default:
    2723        52801 :       gcc_assert (VECTOR_MODE_P (mode));
    2724              : 
    2725        52801 :       if (bytes > 16)
    2726              :         return 0;
    2727              : 
    2728        75872 :       gcc_assert (GET_MODE_CLASS (GET_MODE_INNER (mode)) == MODE_INT);
    2729              : 
    2730        75872 :       if (bit_offset + GET_MODE_BITSIZE (mode) <= 32)
    2731              :         classes[0] = X86_64_INTEGERSI_CLASS;
    2732              :       else
    2733          434 :         classes[0] = X86_64_INTEGER_CLASS;
    2734        37936 :       classes[1] = X86_64_INTEGER_CLASS;
    2735        37936 :       return 1 + (bytes > 8);
    2736              :     }
    2737              : }
    2738              : 
    2739              : /* Wrapper around classify_argument with the extra zero_width_bitfields
    2740              :    argument, to diagnose GCC 12.1 ABI differences for C.  */
    2741              : 
    2742              : static int
    2743    356788164 : classify_argument (machine_mode mode, const_tree type,
    2744              :                    enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
    2745              : {
    2746    356788164 :   int zero_width_bitfields = 0;
    2747    356788164 :   static bool warned = false;
    2748    356788164 :   int n = classify_argument (mode, type, classes, bit_offset,
    2749              :                              zero_width_bitfields);
    2750    356788164 :   if (!zero_width_bitfields || warned || !warn_psabi)
    2751              :     return n;
    2752          534 :   enum x86_64_reg_class alt_classes[MAX_CLASSES];
    2753          534 :   zero_width_bitfields = 2;
    2754          534 :   if (classify_argument (mode, type, alt_classes, bit_offset,
    2755              :                          zero_width_bitfields) != n)
    2756            0 :     zero_width_bitfields = 3;
    2757              :   else
    2758         1286 :     for (int i = 0; i < n; i++)
    2759          760 :       if (classes[i] != alt_classes[i])
    2760              :         {
    2761            8 :           zero_width_bitfields = 3;
    2762            8 :           break;
    2763              :         }
    2764          534 :   if (zero_width_bitfields == 3)
    2765              :     {
    2766            8 :       warned = true;
    2767            8 :       const char *url
    2768              :         = CHANGES_ROOT_URL "gcc-12/changes.html#zero_width_bitfields";
    2769              : 
    2770            8 :       inform (input_location,
    2771              :               "the ABI of passing C structures with zero-width bit-fields"
    2772              :               " has changed in GCC %{12.1%}", url);
    2773              :     }
    2774              :   return n;
    2775              : }
    2776              : 
    2777              : /* Examine the argument and return set number of register required in each
    2778              :    class.  Return true iff parameter should be passed in memory.  */
    2779              : 
    2780              : static bool
    2781    241408518 : examine_argument (machine_mode mode, const_tree type, bool in_return,
    2782              :                   int *int_nregs, int *sse_nregs)
    2783              : {
    2784    241408518 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2785    241408518 :   int n = classify_argument (mode, type, regclass, 0);
    2786              : 
    2787    241408518 :   *int_nregs = 0;
    2788    241408518 :   *sse_nregs = 0;
    2789              : 
    2790    241408518 :   if (!n)
    2791              :     return true;
    2792    693889766 :   for (n--; n >= 0; n--)
    2793    458314377 :     switch (regclass[n])
    2794              :       {
    2795    161403411 :       case X86_64_INTEGER_CLASS:
    2796    161403411 :       case X86_64_INTEGERSI_CLASS:
    2797    161403411 :         (*int_nregs)++;
    2798    161403411 :         break;
    2799     77339757 :       case X86_64_SSE_CLASS:
    2800     77339757 :       case X86_64_SSEHF_CLASS:
    2801     77339757 :       case X86_64_SSESF_CLASS:
    2802     77339757 :       case X86_64_SSEDF_CLASS:
    2803     77339757 :         (*sse_nregs)++;
    2804     77339757 :         break;
    2805              :       case X86_64_NO_CLASS:
    2806              :       case X86_64_SSEUP_CLASS:
    2807              :         break;
    2808      9825982 :       case X86_64_X87_CLASS:
    2809      9825982 :       case X86_64_X87UP_CLASS:
    2810      9825982 :       case X86_64_COMPLEX_X87_CLASS:
    2811      9825982 :         if (!in_return)
    2812              :           return true;
    2813              :         break;
    2814            0 :       case X86_64_MEMORY_CLASS:
    2815            0 :         gcc_unreachable ();
    2816              :       }
    2817              : 
    2818              :   return false;
    2819              : }
    2820              : 
    2821              : /* Construct container for the argument used by GCC interface.  See
    2822              :    FUNCTION_ARG for the detailed description.  */
    2823              : 
    2824              : static rtx
    2825    117006715 : construct_container (machine_mode mode, machine_mode orig_mode,
    2826              :                      const_tree type, bool in_return, int nintregs,
    2827              :                      int nsseregs, const int *intreg, int sse_regno)
    2828              : {
    2829              :   /* The following variables hold the static issued_error state.  */
    2830    117006715 :   static bool issued_sse_arg_error;
    2831    117006715 :   static bool issued_sse_ret_error;
    2832    117006715 :   static bool issued_x87_ret_error;
    2833              : 
    2834    117006715 :   machine_mode tmpmode;
    2835    117006715 :   int bytes
    2836    233311949 :     = mode == BLKmode ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
    2837    117006715 :   enum x86_64_reg_class regclass[MAX_CLASSES];
    2838    117006715 :   int n;
    2839    117006715 :   int i;
    2840    117006715 :   int nexps = 0;
    2841    117006715 :   int needed_sseregs, needed_intregs;
    2842    117006715 :   rtx exp[MAX_CLASSES];
    2843    117006715 :   rtx ret;
    2844              : 
    2845    117006715 :   if (examine_argument (mode, type, in_return, &needed_intregs,
    2846              :                         &needed_sseregs))
    2847              :     return NULL;
    2848              : 
    2849    116486777 :   if (needed_intregs > nintregs || needed_sseregs > nsseregs)
    2850              :     return NULL;
    2851              : 
    2852              :   /* We allowed the user to turn off SSE for kernel mode.  Don't crash if
    2853              :      some less clueful developer tries to use floating-point anyway.  */
    2854    115379714 :   if (needed_sseregs
    2855     38218596 :       && (!TARGET_SSE || (VALID_SSE2_TYPE_MODE (mode) && !TARGET_SSE2)))
    2856              :     {
    2857              :       /* Return early if we shouldn't raise an error for invalid
    2858              :          calls.  */
    2859           68 :       if (cfun != NULL && cfun->machine->silent_p)
    2860              :         return NULL;
    2861           36 :       if (in_return)
    2862              :         {
    2863           31 :           if (!issued_sse_ret_error)
    2864              :             {
    2865           13 :               if (VALID_SSE2_TYPE_MODE (mode))
    2866            5 :                 error ("SSE register return with SSE2 disabled");
    2867              :               else
    2868            8 :                 error ("SSE register return with SSE disabled");
    2869           13 :               issued_sse_ret_error = true;
    2870              :             }
    2871              :         }
    2872            5 :       else if (!issued_sse_arg_error)
    2873              :         {
    2874            5 :           if (VALID_SSE2_TYPE_MODE (mode))
    2875            0 :             error ("SSE register argument with SSE2 disabled");
    2876              :           else
    2877            5 :             error ("SSE register argument with SSE disabled");
    2878            5 :           issued_sse_arg_error = true;
    2879              :         }
    2880              :       return NULL;
    2881              :     }
    2882              : 
    2883    115379646 :   n = classify_argument (mode, type, regclass, 0);
    2884    115379646 :   gcc_assert (n);
    2885              : 
    2886              :   /* Likewise, error if the ABI requires us to return values in the
    2887              :      x87 registers and the user specified -mno-80387.  */
    2888    115379646 :   if (!TARGET_FLOAT_RETURNS_IN_80387 && in_return)
    2889      1435853 :     for (i = 0; i < n; i++)
    2890       758306 :       if (regclass[i] == X86_64_X87_CLASS
    2891              :           || regclass[i] == X86_64_X87UP_CLASS
    2892       758306 :           || regclass[i] == X86_64_COMPLEX_X87_CLASS)
    2893              :         {
    2894              :           /* Return early if we shouldn't raise an error for invalid
    2895              :              calls.  */
    2896           13 :           if (cfun != NULL && cfun->machine->silent_p)
    2897              :             return NULL;
    2898           10 :           if (!issued_x87_ret_error)
    2899              :             {
    2900            5 :               error ("x87 register return with x87 disabled");
    2901            5 :               issued_x87_ret_error = true;
    2902              :             }
    2903              :           return NULL;
    2904              :         }
    2905              : 
    2906              :   /* First construct simple cases.  Avoid SCmode, since we want to use
    2907              :      single register to pass this type.  */
    2908    115379633 :   if (n == 1 && mode != SCmode && mode != HCmode)
    2909     77006883 :     switch (regclass[0])
    2910              :       {
    2911     70669318 :       case X86_64_INTEGER_CLASS:
    2912     70669318 :       case X86_64_INTEGERSI_CLASS:
    2913     70669318 :         return gen_rtx_REG (mode, intreg[0]);
    2914      6129348 :       case X86_64_SSE_CLASS:
    2915      6129348 :       case X86_64_SSEHF_CLASS:
    2916      6129348 :       case X86_64_SSESF_CLASS:
    2917      6129348 :       case X86_64_SSEDF_CLASS:
    2918      6129348 :         if (mode != BLKmode)
    2919     12257836 :           return gen_reg_or_parallel (mode, orig_mode,
    2920     12257836 :                                       GET_SSE_REGNO (sse_regno));
    2921              :         break;
    2922       178402 :       case X86_64_X87_CLASS:
    2923       178402 :       case X86_64_COMPLEX_X87_CLASS:
    2924       178402 :         return gen_rtx_REG (mode, FIRST_STACK_REG);
    2925              :       case X86_64_NO_CLASS:
    2926              :         /* Zero sized array, struct or class.  */
    2927              :         return NULL;
    2928            0 :       default:
    2929            0 :         gcc_unreachable ();
    2930              :       }
    2931     38373180 :   if (n == 2
    2932     20213456 :       && regclass[0] == X86_64_SSE_CLASS
    2933     13665507 :       && regclass[1] == X86_64_SSEUP_CLASS
    2934     13659896 :       && mode != BLKmode)
    2935     27319792 :     return gen_reg_or_parallel (mode, orig_mode,
    2936     27319792 :                                 GET_SSE_REGNO (sse_regno));
    2937     24713284 :   if (n == 4
    2938      8585843 :       && regclass[0] == X86_64_SSE_CLASS
    2939      8585843 :       && regclass[1] == X86_64_SSEUP_CLASS
    2940      8585843 :       && regclass[2] == X86_64_SSEUP_CLASS
    2941      8585843 :       && regclass[3] == X86_64_SSEUP_CLASS
    2942      8585843 :       && mode != BLKmode)
    2943     17168308 :     return gen_reg_or_parallel (mode, orig_mode,
    2944     17168308 :                                 GET_SSE_REGNO (sse_regno));
    2945     16129130 :   if (n == 8
    2946      9316509 :       && regclass[0] == X86_64_SSE_CLASS
    2947      9316509 :       && regclass[1] == X86_64_SSEUP_CLASS
    2948      9316509 :       && regclass[2] == X86_64_SSEUP_CLASS
    2949      9316509 :       && regclass[3] == X86_64_SSEUP_CLASS
    2950      9316509 :       && regclass[4] == X86_64_SSEUP_CLASS
    2951      9316509 :       && regclass[5] == X86_64_SSEUP_CLASS
    2952      9316509 :       && regclass[6] == X86_64_SSEUP_CLASS
    2953      9316509 :       && regclass[7] == X86_64_SSEUP_CLASS
    2954      9316509 :       && mode != BLKmode)
    2955     18628746 :     return gen_reg_or_parallel (mode, orig_mode,
    2956     18628746 :                                 GET_SSE_REGNO (sse_regno));
    2957      6814757 :   if (n == 2
    2958      6553560 :       && regclass[0] == X86_64_X87_CLASS
    2959      2347808 :       && regclass[1] == X86_64_X87UP_CLASS)
    2960      2347808 :     return gen_rtx_REG (XFmode, FIRST_STACK_REG);
    2961              : 
    2962      4466949 :   if (n == 2
    2963      4205752 :       && regclass[0] == X86_64_INTEGER_CLASS
    2964      3758566 :       && regclass[1] == X86_64_INTEGER_CLASS
    2965      3750125 :       && (mode == CDImode || mode == TImode || mode == BLKmode)
    2966      3750125 :       && intreg[0] + 1 == intreg[1])
    2967              :     {
    2968      3426630 :       if (mode == BLKmode)
    2969              :         {
    2970              :           /* Use TImode for BLKmode values in 2 integer registers.  */
    2971       541884 :           exp[0] = gen_rtx_EXPR_LIST (VOIDmode,
    2972       270942 :                                       gen_rtx_REG (TImode, intreg[0]),
    2973              :                                       GEN_INT (0));
    2974       270942 :           ret = gen_rtx_PARALLEL (mode, rtvec_alloc (1));
    2975       270942 :           XVECEXP (ret, 0, 0) = exp[0];
    2976       270942 :           return ret;
    2977              :         }
    2978              :       else
    2979      3155688 :         return gen_rtx_REG (mode, intreg[0]);
    2980              :     }
    2981              : 
    2982              :   /* Otherwise figure out the entries of the PARALLEL.  */
    2983      2859760 :   for (i = 0; i < n; i++)
    2984              :     {
    2985      1819441 :       int pos;
    2986              : 
    2987      1819441 :       switch (regclass[i])
    2988              :         {
    2989              :           case X86_64_NO_CLASS:
    2990              :             break;
    2991      1021671 :           case X86_64_INTEGER_CLASS:
    2992      1021671 :           case X86_64_INTEGERSI_CLASS:
    2993              :             /* Merge TImodes on aligned occasions here too.  */
    2994      1021671 :             if (i * 8 + 8 > bytes)
    2995              :               {
    2996         3268 :                 unsigned int tmpbits = (bytes - i * 8) * BITS_PER_UNIT;
    2997         3268 :                 if (!int_mode_for_size (tmpbits, 0).exists (&tmpmode))
    2998              :                   /* We've requested 24 bytes we
    2999              :                      don't have mode for.  Use DImode.  */
    3000          357 :                   tmpmode = DImode;
    3001              :               }
    3002      1018403 :             else if (regclass[i] == X86_64_INTEGERSI_CLASS)
    3003              :               tmpmode = SImode;
    3004              :             else
    3005       836854 :               tmpmode = DImode;
    3006      2043342 :             exp [nexps++]
    3007      1021671 :               = gen_rtx_EXPR_LIST (VOIDmode,
    3008      1021671 :                                    gen_rtx_REG (tmpmode, *intreg),
    3009      1021671 :                                    GEN_INT (i*8));
    3010      1021671 :             intreg++;
    3011      1021671 :             break;
    3012          600 :           case X86_64_SSEHF_CLASS:
    3013          600 :             tmpmode = (mode == BFmode ? BFmode : HFmode);
    3014         1200 :             exp [nexps++]
    3015         1200 :               = gen_rtx_EXPR_LIST (VOIDmode,
    3016              :                                    gen_rtx_REG (tmpmode,
    3017          600 :                                                 GET_SSE_REGNO (sse_regno)),
    3018          600 :                                    GEN_INT (i*8));
    3019          600 :             sse_regno++;
    3020          600 :             break;
    3021         3060 :           case X86_64_SSESF_CLASS:
    3022         6120 :             exp [nexps++]
    3023         6120 :               = gen_rtx_EXPR_LIST (VOIDmode,
    3024              :                                    gen_rtx_REG (SFmode,
    3025         3060 :                                                 GET_SSE_REGNO (sse_regno)),
    3026         3060 :                                    GEN_INT (i*8));
    3027         3060 :             sse_regno++;
    3028         3060 :             break;
    3029       513692 :           case X86_64_SSEDF_CLASS:
    3030      1027384 :             exp [nexps++]
    3031      1027384 :               = gen_rtx_EXPR_LIST (VOIDmode,
    3032              :                                    gen_rtx_REG (DFmode,
    3033       513692 :                                                 GET_SSE_REGNO (sse_regno)),
    3034       513692 :                                    GEN_INT (i*8));
    3035       513692 :             sse_regno++;
    3036       513692 :             break;
    3037       272015 :           case X86_64_SSE_CLASS:
    3038       272015 :             pos = i;
    3039       272015 :             switch (n)
    3040              :               {
    3041              :               case 1:
    3042              :                 tmpmode = DImode;
    3043              :                 break;
    3044        11032 :               case 2:
    3045        11032 :                 if (i == 0 && regclass[1] == X86_64_SSEUP_CLASS)
    3046              :                   {
    3047            0 :                     tmpmode = TImode;
    3048            0 :                     i++;
    3049              :                   }
    3050              :                 else
    3051              :                   tmpmode = DImode;
    3052              :                 break;
    3053         1689 :               case 4:
    3054         1689 :                 gcc_assert (i == 0
    3055              :                             && regclass[1] == X86_64_SSEUP_CLASS
    3056              :                             && regclass[2] == X86_64_SSEUP_CLASS
    3057              :                             && regclass[3] == X86_64_SSEUP_CLASS);
    3058              :                 tmpmode = OImode;
    3059              :                 i += 3;
    3060              :                 break;
    3061         2136 :               case 8:
    3062         2136 :                 gcc_assert (i == 0
    3063              :                             && regclass[1] == X86_64_SSEUP_CLASS
    3064              :                             && regclass[2] == X86_64_SSEUP_CLASS
    3065              :                             && regclass[3] == X86_64_SSEUP_CLASS
    3066              :                             && regclass[4] == X86_64_SSEUP_CLASS
    3067              :                             && regclass[5] == X86_64_SSEUP_CLASS
    3068              :                             && regclass[6] == X86_64_SSEUP_CLASS
    3069              :                             && regclass[7] == X86_64_SSEUP_CLASS);
    3070              :                 tmpmode = XImode;
    3071              :                 i += 7;
    3072              :                 break;
    3073            0 :               default:
    3074            0 :                 gcc_unreachable ();
    3075              :               }
    3076       544030 :             exp [nexps++]
    3077       544030 :               = gen_rtx_EXPR_LIST (VOIDmode,
    3078              :                                    gen_rtx_REG (tmpmode,
    3079       272015 :                                                 GET_SSE_REGNO (sse_regno)),
    3080       272015 :                                    GEN_INT (pos*8));
    3081       272015 :             sse_regno++;
    3082       272015 :             break;
    3083            0 :           default:
    3084            0 :             gcc_unreachable ();
    3085              :         }
    3086              :     }
    3087              : 
    3088              :   /* Empty aligned struct, union or class.  */
    3089      1040319 :   if (nexps == 0)
    3090              :     return NULL;
    3091              : 
    3092      1040064 :   ret =  gen_rtx_PARALLEL (mode, rtvec_alloc (nexps));
    3093      2851102 :   for (i = 0; i < nexps; i++)
    3094      1811038 :     XVECEXP (ret, 0, i) = exp [i];
    3095              :   return ret;
    3096              : }
    3097              : 
    3098              : /* Update the data in CUM to advance over an argument of mode MODE
    3099              :    and data type TYPE.  (TYPE is null for libcalls where that information
    3100              :    may not be available.)
    3101              : 
    3102              :    Return a number of integer registers advanced over.  */
    3103              : 
    3104              : static int
    3105      2131561 : function_arg_advance_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3106              :                          const_tree type, HOST_WIDE_INT bytes,
    3107              :                          HOST_WIDE_INT words)
    3108              : {
    3109      2131561 :   int res = 0;
    3110      2131561 :   bool error_p = false;
    3111              : 
    3112      2131561 :   if (TARGET_IAMCU)
    3113              :     {
    3114              :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    3115              :          bytes in registers.  */
    3116            0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3117            0 :         goto pass_in_reg;
    3118              :       return res;
    3119              :     }
    3120              : 
    3121      2131561 :   switch (mode)
    3122              :     {
    3123              :     default:
    3124              :       break;
    3125              : 
    3126        93695 :     case E_BLKmode:
    3127        93695 :       if (bytes < 0)
    3128              :         break;
    3129              :       /* FALLTHRU */
    3130              : 
    3131      2094696 :     case E_DImode:
    3132      2094696 :     case E_SImode:
    3133      2094696 :     case E_HImode:
    3134      2094696 :     case E_QImode:
    3135        93695 : pass_in_reg:
    3136      2094696 :       cum->words += words;
    3137      2094696 :       cum->nregs -= words;
    3138      2094696 :       cum->regno += words;
    3139      2094696 :       if (cum->nregs >= 0)
    3140        47160 :         res = words;
    3141      2094696 :       if (cum->nregs <= 0)
    3142              :         {
    3143      2060761 :           cum->nregs = 0;
    3144      2060761 :           cfun->machine->arg_reg_available = false;
    3145      2060761 :           cum->regno = 0;
    3146              :         }
    3147              :       break;
    3148              : 
    3149            0 :     case E_OImode:
    3150              :       /* OImode shouldn't be used directly.  */
    3151            0 :       gcc_unreachable ();
    3152              : 
    3153         4771 :     case E_DFmode:
    3154         4771 :       if (cum->float_in_sse == -1)
    3155            0 :         error_p = true;
    3156         4771 :       if (cum->float_in_sse < 2)
    3157              :         break;
    3158              :       /* FALLTHRU */
    3159         1384 :     case E_SFmode:
    3160         1384 :       if (cum->float_in_sse == -1)
    3161            0 :         error_p = true;
    3162         1384 :       if (cum->float_in_sse < 1)
    3163              :         break;
    3164              :       /* FALLTHRU */
    3165              : 
    3166           52 :     case E_V16HFmode:
    3167           52 :     case E_V16BFmode:
    3168           52 :     case E_V8SFmode:
    3169           52 :     case E_V8SImode:
    3170           52 :     case E_V64QImode:
    3171           52 :     case E_V32HImode:
    3172           52 :     case E_V16SImode:
    3173           52 :     case E_V8DImode:
    3174           52 :     case E_V32HFmode:
    3175           52 :     case E_V32BFmode:
    3176           52 :     case E_V16SFmode:
    3177           52 :     case E_V8DFmode:
    3178           52 :     case E_V32QImode:
    3179           52 :     case E_V16HImode:
    3180           52 :     case E_V4DFmode:
    3181           52 :     case E_V4DImode:
    3182           52 :     case E_TImode:
    3183           52 :     case E_V16QImode:
    3184           52 :     case E_V8HImode:
    3185           52 :     case E_V4SImode:
    3186           52 :     case E_V2DImode:
    3187           52 :     case E_V8HFmode:
    3188           52 :     case E_V8BFmode:
    3189           52 :     case E_V4SFmode:
    3190           52 :     case E_V2DFmode:
    3191           52 :       if (!type || !AGGREGATE_TYPE_P (type))
    3192              :         {
    3193           52 :           cum->sse_words += words;
    3194           52 :           cum->sse_nregs -= 1;
    3195           52 :           cum->sse_regno += 1;
    3196           52 :           if (cum->sse_nregs <= 0)
    3197              :             {
    3198            4 :               cum->sse_nregs = 0;
    3199            4 :               cum->sse_regno = 0;
    3200              :             }
    3201              :         }
    3202              :       break;
    3203              : 
    3204           16 :     case E_V8QImode:
    3205           16 :     case E_V4HImode:
    3206           16 :     case E_V4HFmode:
    3207           16 :     case E_V4BFmode:
    3208           16 :     case E_V2SImode:
    3209           16 :     case E_V2SFmode:
    3210           16 :     case E_V1TImode:
    3211           16 :     case E_V1DImode:
    3212           16 :       if (!type || !AGGREGATE_TYPE_P (type))
    3213              :         {
    3214           16 :           cum->mmx_words += words;
    3215           16 :           cum->mmx_nregs -= 1;
    3216           16 :           cum->mmx_regno += 1;
    3217           16 :           if (cum->mmx_nregs <= 0)
    3218              :             {
    3219            0 :               cum->mmx_nregs = 0;
    3220            0 :               cum->mmx_regno = 0;
    3221              :             }
    3222              :         }
    3223              :       break;
    3224              :     }
    3225      2066968 :   if (error_p)
    3226              :     {
    3227            0 :       cum->float_in_sse = 0;
    3228            0 :       error ("calling %qD with SSE calling convention without "
    3229              :              "SSE/SSE2 enabled", cum->decl);
    3230            0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3231              :              "attribute used to function called");
    3232              :     }
    3233              : 
    3234              :   return res;
    3235              : }
    3236              : 
    3237              : static int
    3238     19889137 : function_arg_advance_64 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3239              :                          const_tree type, HOST_WIDE_INT words, bool named)
    3240              : {
    3241     19889137 :   int int_nregs, sse_nregs;
    3242              : 
    3243              :   /* Unnamed 512 and 256bit vector mode parameters are passed on stack.  */
    3244     19889137 :   if (!named && (VALID_AVX512F_REG_MODE (mode)
    3245              :                  || VALID_AVX256_REG_MODE (mode)))
    3246              :     return 0;
    3247              : 
    3248     19888773 :   if (!examine_argument (mode, type, false, &int_nregs, &sse_nregs)
    3249     19888773 :       && sse_nregs <= cum->sse_nregs && int_nregs <= cum->nregs)
    3250              :     {
    3251     17603020 :       cum->nregs -= int_nregs;
    3252     17603020 :       cum->sse_nregs -= sse_nregs;
    3253     17603020 :       cum->regno += int_nregs;
    3254     17603020 :       cum->sse_regno += sse_nregs;
    3255     17603020 :       return int_nregs;
    3256              :     }
    3257              :   else
    3258              :     {
    3259      2285753 :       int align = ix86_function_arg_boundary (mode, type) / BITS_PER_WORD;
    3260      2285753 :       cum->words = ROUND_UP (cum->words, align);
    3261      2285753 :       cum->words += words;
    3262      2285753 :       return 0;
    3263              :     }
    3264              : }
    3265              : 
    3266              : static int
    3267       447474 : function_arg_advance_ms_64 (CUMULATIVE_ARGS *cum, HOST_WIDE_INT bytes,
    3268              :                             HOST_WIDE_INT words)
    3269              : {
    3270              :   /* Otherwise, this should be passed indirect.  */
    3271       447474 :   gcc_assert (bytes == 1 || bytes == 2 || bytes == 4 || bytes == 8);
    3272              : 
    3273       447474 :   cum->words += words;
    3274       447474 :   if (cum->nregs > 0)
    3275              :     {
    3276       289715 :       cum->nregs -= 1;
    3277       289715 :       cum->regno += 1;
    3278       289715 :       return 1;
    3279              :     }
    3280              :   return 0;
    3281              : }
    3282              : 
    3283              : /* Update the data in CUM to advance over argument ARG.  */
    3284              : 
    3285              : static void
    3286     22468539 : ix86_function_arg_advance (cumulative_args_t cum_v,
    3287              :                            const function_arg_info &arg)
    3288              : {
    3289     22468539 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3290     22468539 :   machine_mode mode = arg.mode;
    3291     22468539 :   HOST_WIDE_INT bytes, words;
    3292     22468539 :   int nregs;
    3293              : 
    3294              :   /* The argument of interrupt handler is a special case and is
    3295              :      handled in ix86_function_arg.  */
    3296     22468539 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3297              :     return;
    3298              : 
    3299     22468172 :   bytes = arg.promoted_size_in_bytes ();
    3300     22468172 :   words = CEIL (bytes, UNITS_PER_WORD);
    3301              : 
    3302     22468172 :   if (arg.type)
    3303     22142058 :     mode = type_natural_mode (arg.type, NULL, false);
    3304              : 
    3305     22468172 :   if (TARGET_64BIT)
    3306              :     {
    3307     20336611 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3308              : 
    3309     20336611 :       if (call_abi == MS_ABI)
    3310       447474 :         nregs = function_arg_advance_ms_64 (cum, bytes, words);
    3311              :       else
    3312     19889137 :         nregs = function_arg_advance_64 (cum, mode, arg.type, words,
    3313     19889137 :                                          arg.named);
    3314              :     }
    3315              :   else
    3316      2131561 :     nregs = function_arg_advance_32 (cum, mode, arg.type, bytes, words);
    3317              : 
    3318     22468172 :   if (!nregs)
    3319              :     {
    3320              :       /* Track if there are outgoing arguments on stack.  */
    3321      5760005 :       if (cum->caller)
    3322      2735007 :         cfun->machine->outgoing_args_on_stack = true;
    3323              :     }
    3324              : }
    3325              : 
    3326              : /* Define where to put the arguments to a function.
    3327              :    Value is zero to push the argument on the stack,
    3328              :    or a hard register in which to store the argument.
    3329              : 
    3330              :    MODE is the argument's machine mode.
    3331              :    TYPE is the data type of the argument (as a tree).
    3332              :     This is null for libcalls where that information may
    3333              :     not be available.
    3334              :    CUM is a variable of type CUMULATIVE_ARGS which gives info about
    3335              :     the preceding args and about the function being called.
    3336              :    NAMED is nonzero if this argument is a named parameter
    3337              :     (otherwise it is an extra parameter matching an ellipsis).  */
    3338              : 
    3339              : static rtx
    3340      2558286 : function_arg_32 (CUMULATIVE_ARGS *cum, machine_mode mode,
    3341              :                  machine_mode orig_mode, const_tree type,
    3342              :                  HOST_WIDE_INT bytes, HOST_WIDE_INT words)
    3343              : {
    3344      2558286 :   bool error_p = false;
    3345              : 
    3346              :   /* Avoid the AL settings for the Unix64 ABI.  */
    3347      2558286 :   if (mode == VOIDmode)
    3348       742396 :     return constm1_rtx;
    3349              : 
    3350      1815890 :   if (TARGET_IAMCU)
    3351              :     {
    3352              :       /* Intel MCU psABI passes scalars and aggregates no larger than 8
    3353              :          bytes in registers.  */
    3354            0 :       if (!VECTOR_MODE_P (mode) && bytes <= 8)
    3355            0 :         goto pass_in_reg;
    3356              :       return NULL_RTX;
    3357              :     }
    3358              : 
    3359      1815890 :   switch (mode)
    3360              :     {
    3361              :     default:
    3362              :       break;
    3363              : 
    3364        77649 :     case E_BLKmode:
    3365        77649 :       if (bytes < 0)
    3366              :         break;
    3367              :       /* FALLTHRU */
    3368      1782282 :     case E_DImode:
    3369      1782282 :     case E_SImode:
    3370      1782282 :     case E_HImode:
    3371      1782282 :     case E_QImode:
    3372        77649 : pass_in_reg:
    3373      1782282 :       if (words <= cum->nregs)
    3374              :         {
    3375        45328 :           int regno = cum->regno;
    3376              : 
    3377              :           /* Fastcall allocates the first two DWORD (SImode) or
    3378              :             smaller arguments to ECX and EDX if it isn't an
    3379              :             aggregate type .  */
    3380        45328 :           if (cum->fastcall)
    3381              :             {
    3382            6 :               if (mode == BLKmode
    3383            6 :                   || mode == DImode
    3384            6 :                   || (type && AGGREGATE_TYPE_P (type)))
    3385              :                 break;
    3386              : 
    3387              :               /* ECX not EAX is the first allocated register.  */
    3388            6 :               if (regno == AX_REG)
    3389        45328 :                 regno = CX_REG;
    3390              :             }
    3391        45328 :           return gen_rtx_REG (mode, regno);
    3392              :         }
    3393              :       break;
    3394              : 
    3395         3381 :     case E_DFmode:
    3396         3381 :       if (cum->float_in_sse == -1)
    3397            0 :         error_p = true;
    3398         3381 :       if (cum->float_in_sse < 2)
    3399              :         break;
    3400              :       /* FALLTHRU */
    3401          984 :     case E_SFmode:
    3402          984 :       if (cum->float_in_sse == -1)
    3403            0 :         error_p = true;
    3404          984 :       if (cum->float_in_sse < 1)
    3405              :         break;
    3406              :       /* FALLTHRU */
    3407           12 :     case E_TImode:
    3408              :       /* In 32bit, we pass TImode in xmm registers.  */
    3409           12 :     case E_V16QImode:
    3410           12 :     case E_V8HImode:
    3411           12 :     case E_V4SImode:
    3412           12 :     case E_V2DImode:
    3413           12 :     case E_V8HFmode:
    3414           12 :     case E_V8BFmode:
    3415           12 :     case E_V4SFmode:
    3416           12 :     case E_V2DFmode:
    3417           12 :       if (!type || !AGGREGATE_TYPE_P (type))
    3418              :         {
    3419           12 :           if (cum->sse_nregs)
    3420           12 :             return gen_reg_or_parallel (mode, orig_mode,
    3421           12 :                                         cum->sse_regno + FIRST_SSE_REG);
    3422              :         }
    3423              :       break;
    3424              : 
    3425            0 :     case E_OImode:
    3426            0 :     case E_XImode:
    3427              :       /* OImode and XImode shouldn't be used directly.  */
    3428            0 :       gcc_unreachable ();
    3429              : 
    3430            9 :     case E_V64QImode:
    3431            9 :     case E_V32HImode:
    3432            9 :     case E_V16SImode:
    3433            9 :     case E_V8DImode:
    3434            9 :     case E_V32HFmode:
    3435            9 :     case E_V32BFmode:
    3436            9 :     case E_V16SFmode:
    3437            9 :     case E_V8DFmode:
    3438            9 :     case E_V16HFmode:
    3439            9 :     case E_V16BFmode:
    3440            9 :     case E_V8SFmode:
    3441            9 :     case E_V8SImode:
    3442            9 :     case E_V32QImode:
    3443            9 :     case E_V16HImode:
    3444            9 :     case E_V4DFmode:
    3445            9 :     case E_V4DImode:
    3446            9 :       if (!type || !AGGREGATE_TYPE_P (type))
    3447              :         {
    3448            9 :           if (cum->sse_nregs)
    3449            9 :             return gen_reg_or_parallel (mode, orig_mode,
    3450            9 :                                         cum->sse_regno + FIRST_SSE_REG);
    3451              :         }
    3452              :       break;
    3453              : 
    3454            8 :     case E_V8QImode:
    3455            8 :     case E_V4HImode:
    3456            8 :     case E_V4HFmode:
    3457            8 :     case E_V4BFmode:
    3458            8 :     case E_V2SImode:
    3459            8 :     case E_V2SFmode:
    3460            8 :     case E_V1TImode:
    3461            8 :     case E_V1DImode:
    3462            8 :       if (!type || !AGGREGATE_TYPE_P (type))
    3463              :         {
    3464            8 :           if (cum->mmx_nregs)
    3465            8 :             return gen_reg_or_parallel (mode, orig_mode,
    3466            8 :                                         cum->mmx_regno + FIRST_MMX_REG);
    3467              :         }
    3468              :       break;
    3469              :     }
    3470         4365 :   if (error_p)
    3471              :     {
    3472            0 :       cum->float_in_sse = 0;
    3473            0 :       error ("calling %qD with SSE calling convention without "
    3474              :              "SSE/SSE2 enabled", cum->decl);
    3475            0 :       sorry ("this is a GCC bug that can be worked around by adding "
    3476              :              "attribute used to function called");
    3477              :     }
    3478              : 
    3479              :   return NULL_RTX;
    3480              : }
    3481              : 
    3482              : static rtx
    3483     19525296 : function_arg_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3484              :                  machine_mode orig_mode, const_tree type, bool named)
    3485              : {
    3486              :   /* Handle a hidden AL argument containing number of registers
    3487              :      for varargs x86-64 functions.  */
    3488     19525296 :   if (mode == VOIDmode)
    3489      5431141 :     return GEN_INT (cum->maybe_vaarg
    3490              :                     ? (cum->sse_nregs < 0
    3491              :                        ? X86_64_SSE_REGPARM_MAX
    3492              :                        : cum->sse_regno)
    3493              :                     : -1);
    3494              : 
    3495     14094155 :   switch (mode)
    3496              :     {
    3497              :     default:
    3498              :       break;
    3499              : 
    3500        91670 :     case E_V16HFmode:
    3501        91670 :     case E_V16BFmode:
    3502        91670 :     case E_V8SFmode:
    3503        91670 :     case E_V8SImode:
    3504        91670 :     case E_V32QImode:
    3505        91670 :     case E_V16HImode:
    3506        91670 :     case E_V4DFmode:
    3507        91670 :     case E_V4DImode:
    3508        91670 :     case E_V32HFmode:
    3509        91670 :     case E_V32BFmode:
    3510        91670 :     case E_V16SFmode:
    3511        91670 :     case E_V16SImode:
    3512        91670 :     case E_V64QImode:
    3513        91670 :     case E_V32HImode:
    3514        91670 :     case E_V8DFmode:
    3515        91670 :     case E_V8DImode:
    3516              :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    3517        91670 :       if (!named)
    3518              :         return NULL;
    3519              :       break;
    3520              :     }
    3521              : 
    3522     14093791 :   const int *parm_regs;
    3523     14093791 :   if (cum->preserve_none_abi)
    3524              :     parm_regs = x86_64_preserve_none_int_parameter_registers;
    3525              :   else
    3526     14093591 :     parm_regs = x86_64_int_parameter_registers;
    3527              : 
    3528     14093791 :   return construct_container (mode, orig_mode, type, false,
    3529     14093791 :                               cum->nregs, cum->sse_nregs,
    3530     14093791 :                               &parm_regs[cum->regno],
    3531     14093791 :                               cum->sse_regno);
    3532              : }
    3533              : 
    3534              : static rtx
    3535       296679 : function_arg_ms_64 (const CUMULATIVE_ARGS *cum, machine_mode mode,
    3536              :                     machine_mode orig_mode, bool named, const_tree type,
    3537              :                     HOST_WIDE_INT bytes)
    3538              : {
    3539       296679 :   unsigned int regno;
    3540              : 
    3541              :   /* We need to add clobber for MS_ABI->SYSV ABI calls in expand_call.
    3542              :      We use value of -2 to specify that current function call is MSABI.  */
    3543       296679 :   if (mode == VOIDmode)
    3544        36329 :     return GEN_INT (-2);
    3545              : 
    3546              :   /* If we've run out of registers, it goes on the stack.  */
    3547       260350 :   if (cum->nregs == 0)
    3548              :     return NULL_RTX;
    3549              : 
    3550       176508 :   regno = x86_64_ms_abi_int_parameter_registers[cum->regno];
    3551              : 
    3552              :   /* Only floating point modes less than 64 bits are passed in anything but
    3553              :      integer regs.  Larger floating point types are excluded as the Windows
    3554              :      ABI requires vreg args can be shadowed in GPRs (for red zone / varargs). */
    3555       176508 :   if (TARGET_SSE && (mode == HFmode || mode == SFmode || mode == DFmode))
    3556              :     {
    3557        38309 :       if (named)
    3558              :         {
    3559        38309 :           if (type == NULL_TREE || !AGGREGATE_TYPE_P (type))
    3560        37312 :             regno = cum->regno + FIRST_SSE_REG;
    3561              :         }
    3562              :       else
    3563              :         {
    3564            0 :           rtx t1, t2;
    3565              : 
    3566              :           /* Unnamed floating parameters are passed in both the
    3567              :              SSE and integer registers.  */
    3568            0 :           t1 = gen_rtx_REG (mode, cum->regno + FIRST_SSE_REG);
    3569            0 :           t2 = gen_rtx_REG (mode, regno);
    3570            0 :           t1 = gen_rtx_EXPR_LIST (VOIDmode, t1, const0_rtx);
    3571            0 :           t2 = gen_rtx_EXPR_LIST (VOIDmode, t2, const0_rtx);
    3572            0 :           return gen_rtx_PARALLEL (mode, gen_rtvec (2, t1, t2));
    3573              :         }
    3574              :     }
    3575              :   /* Handle aggregated types passed in register.  */
    3576       176508 :   if (orig_mode == BLKmode)
    3577              :     {
    3578            0 :       if (bytes > 0 && bytes <= 8)
    3579            0 :         mode = (bytes > 4 ? DImode : SImode);
    3580            0 :       if (mode == BLKmode)
    3581            0 :         mode = DImode;
    3582              :     }
    3583              : 
    3584       176508 :   return gen_reg_or_parallel (mode, orig_mode, regno);
    3585              : }
    3586              : 
    3587              : /* Return where to put the arguments to a function.
    3588              :    Return zero to push the argument on the stack, or a hard register in which to store the argument.
    3589              : 
    3590              :    ARG describes the argument while CUM gives information about the
    3591              :    preceding args and about the function being called.  */
    3592              : 
    3593              : static rtx
    3594     22380448 : ix86_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    3595              : {
    3596     22380448 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3597     22380448 :   machine_mode mode = arg.mode;
    3598     22380448 :   HOST_WIDE_INT bytes, words;
    3599     22380448 :   rtx reg;
    3600              : 
    3601     22380448 :   if (!cum->caller && cfun->machine->func_type != TYPE_NORMAL)
    3602              :     {
    3603          187 :       gcc_assert (arg.type != NULL_TREE);
    3604          187 :       if (POINTER_TYPE_P (arg.type))
    3605              :         {
    3606              :           /* This is the pointer argument.  */
    3607          122 :           gcc_assert (TYPE_MODE (arg.type) == ptr_mode);
    3608              :           /* It is at -WORD(AP) in the current frame in interrupt and
    3609              :              exception handlers.  */
    3610          122 :           reg = plus_constant (Pmode, arg_pointer_rtx, -UNITS_PER_WORD);
    3611              :         }
    3612              :       else
    3613              :         {
    3614           65 :           gcc_assert (cfun->machine->func_type == TYPE_EXCEPTION
    3615              :                       && TREE_CODE (arg.type) == INTEGER_TYPE
    3616              :                       && TYPE_MODE (arg.type) == word_mode);
    3617              :           /* The error code is the word-mode integer argument at
    3618              :              -2 * WORD(AP) in the current frame of the exception
    3619              :              handler.  */
    3620           65 :           reg = gen_rtx_MEM (word_mode,
    3621           65 :                              plus_constant (Pmode,
    3622              :                                             arg_pointer_rtx,
    3623           65 :                                             -2 * UNITS_PER_WORD));
    3624              :         }
    3625              :       return reg;
    3626              :     }
    3627              : 
    3628     22380261 :   bytes = arg.promoted_size_in_bytes ();
    3629     22380261 :   words = CEIL (bytes, UNITS_PER_WORD);
    3630              : 
    3631              :   /* To simplify the code below, represent vector types with a vector mode
    3632              :      even if MMX/SSE are not active.  */
    3633     22380261 :   if (arg.type && VECTOR_TYPE_P (arg.type))
    3634       175104 :     mode = type_natural_mode (arg.type, cum, false);
    3635              : 
    3636     22380261 :   if (TARGET_64BIT)
    3637              :     {
    3638     19821975 :       if (cum->call_abi == MS_ABI)
    3639       296679 :         reg = function_arg_ms_64 (cum, mode, arg.mode, arg.named,
    3640       296679 :                                   arg.type, bytes);
    3641              :       else
    3642     19525296 :         reg = function_arg_64 (cum, mode, arg.mode, arg.type, arg.named);
    3643              :     }
    3644              :   else
    3645      2558286 :     reg = function_arg_32 (cum, mode, arg.mode, arg.type, bytes, words);
    3646              : 
    3647              :   /* Track if there are outgoing arguments on stack.  */
    3648     22380261 :   if (reg == NULL_RTX && cum->caller)
    3649      2204696 :     cfun->machine->outgoing_args_on_stack = true;
    3650              : 
    3651              :   return reg;
    3652              : }
    3653              : 
    3654              : /* A C expression that indicates when an argument must be passed by
    3655              :    reference.  If nonzero for an argument, a copy of that argument is
    3656              :    made in memory and a pointer to the argument is passed instead of
    3657              :    the argument itself.  The pointer is passed in whatever way is
    3658              :    appropriate for passing a pointer to that type.  */
    3659              : 
    3660              : static bool
    3661     22384638 : ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg)
    3662              : {
    3663     22384638 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    3664              : 
    3665     22384638 :   if (TARGET_64BIT)
    3666              :     {
    3667     20263325 :       enum calling_abi call_abi = cum ? cum->call_abi : ix86_abi;
    3668              : 
    3669              :       /* See Windows x64 Software Convention.  */
    3670     20263325 :       if (call_abi == MS_ABI)
    3671              :         {
    3672       441871 :           HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode);
    3673              : 
    3674       441871 :           if (tree type = arg.type)
    3675              :             {
    3676              :               /* Arrays are passed by reference.  */
    3677       441871 :               if (TREE_CODE (type) == ARRAY_TYPE)
    3678              :                 return true;
    3679              : 
    3680       441871 :               if (RECORD_OR_UNION_TYPE_P (type))
    3681              :                 {
    3682              :                   /* Structs/unions of sizes other than 8, 16, 32, or 64 bits
    3683              :                      are passed by reference.  */
    3684        15103 :                   msize = int_size_in_bytes (type);
    3685              :                 }
    3686              :             }
    3687              : 
    3688              :           /* __m128 is passed by reference.  */
    3689       441871 :           return msize != 1 && msize != 2 && msize != 4 && msize != 8;
    3690              :         }
    3691     19821454 :       else if (arg.type && int_size_in_bytes (arg.type) == -1)
    3692            0 :         return true;
    3693              :     }
    3694              : 
    3695              :   return false;
    3696              : }
    3697              : 
    3698              : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3699              :    passing ABI.  XXX: This function is obsolete and is only used for
    3700              :    checking psABI compatibility with previous versions of GCC.  */
    3701              : 
    3702              : static bool
    3703      1976485 : ix86_compat_aligned_value_p (const_tree type)
    3704              : {
    3705      1976485 :   machine_mode mode = TYPE_MODE (type);
    3706      1976485 :   if (((TARGET_SSE && SSE_REG_MODE_P (mode))
    3707      1976443 :        || mode == TDmode
    3708      1976443 :        || mode == TFmode
    3709              :        || mode == TCmode)
    3710      1976697 :       && (!TYPE_USER_ALIGN (type) || TYPE_ALIGN (type) > 128))
    3711              :     return true;
    3712      1976273 :   if (TYPE_ALIGN (type) < 128)
    3713              :     return false;
    3714              : 
    3715            0 :   if (AGGREGATE_TYPE_P (type))
    3716              :     {
    3717              :       /* Walk the aggregates recursively.  */
    3718            0 :       switch (TREE_CODE (type))
    3719              :         {
    3720            0 :         case RECORD_TYPE:
    3721            0 :         case UNION_TYPE:
    3722            0 :         case QUAL_UNION_TYPE:
    3723            0 :           {
    3724            0 :             tree field;
    3725              : 
    3726              :             /* Walk all the structure fields.  */
    3727            0 :             for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    3728              :               {
    3729            0 :                 if (TREE_CODE (field) == FIELD_DECL
    3730            0 :                     && ix86_compat_aligned_value_p (TREE_TYPE (field)))
    3731              :                   return true;
    3732              :               }
    3733              :             break;
    3734              :           }
    3735              : 
    3736            0 :         case ARRAY_TYPE:
    3737              :           /* Just for use if some languages passes arrays by value.  */
    3738            0 :           if (ix86_compat_aligned_value_p (TREE_TYPE (type)))
    3739              :             return true;
    3740              :           break;
    3741              : 
    3742              :         default:
    3743              :           gcc_unreachable ();
    3744              :         }
    3745              :     }
    3746              :   return false;
    3747              : }
    3748              : 
    3749              : /* Return the alignment boundary for MODE and TYPE with alignment ALIGN.
    3750              :    XXX: This function is obsolete and is only used for checking psABI
    3751              :    compatibility with previous versions of GCC.  */
    3752              : 
    3753              : static unsigned int
    3754      5653608 : ix86_compat_function_arg_boundary (machine_mode mode,
    3755              :                                    const_tree type, unsigned int align)
    3756              : {
    3757              :   /* In 32bit, only _Decimal128 and __float128 are aligned to their
    3758              :      natural boundaries.  */
    3759      5653608 :   if (!TARGET_64BIT && mode != TDmode && mode != TFmode)
    3760              :     {
    3761              :       /* i386 ABI defines all arguments to be 4 byte aligned.  We have to
    3762              :          make an exception for SSE modes since these require 128bit
    3763              :          alignment.
    3764              : 
    3765              :          The handling here differs from field_alignment.  ICC aligns MMX
    3766              :          arguments to 4 byte boundaries, while structure fields are aligned
    3767              :          to 8 byte boundaries.  */
    3768      1988431 :       if (!type)
    3769              :         {
    3770        11946 :           if (!(TARGET_SSE && SSE_REG_MODE_P (mode)))
    3771      1988219 :             align = PARM_BOUNDARY;
    3772              :         }
    3773              :       else
    3774              :         {
    3775      1976485 :           if (!ix86_compat_aligned_value_p (type))
    3776      1988219 :             align = PARM_BOUNDARY;
    3777              :         }
    3778              :     }
    3779     10900835 :   if (align > BIGGEST_ALIGNMENT)
    3780          105 :     align = BIGGEST_ALIGNMENT;
    3781      5653608 :   return align;
    3782              : }
    3783              : 
    3784              : /* Return true when TYPE should be 128bit aligned for 32bit argument
    3785              :    passing ABI.  */
    3786              : 
    3787              : static bool
    3788      1979182 : ix86_contains_aligned_value_p (const_tree type)
    3789              : {
    3790      1979182 :   machine_mode mode = TYPE_MODE (type);
    3791              : 
    3792      1979182 :   if (mode == XFmode || mode == XCmode)
    3793              :     return false;
    3794              : 
    3795      1977063 :   if (TYPE_ALIGN (type) < 128)
    3796              :     return false;
    3797              : 
    3798         2909 :   if (AGGREGATE_TYPE_P (type))
    3799              :     {
    3800              :       /* Walk the aggregates recursively.  */
    3801            0 :       switch (TREE_CODE (type))
    3802              :         {
    3803            0 :         case RECORD_TYPE:
    3804            0 :         case UNION_TYPE:
    3805            0 :         case QUAL_UNION_TYPE:
    3806            0 :           {
    3807            0 :             tree field;
    3808              : 
    3809              :             /* Walk all the structure fields.  */
    3810            0 :             for (field = TYPE_FIELDS (type);
    3811            0 :                  field;
    3812            0 :                  field = DECL_CHAIN (field))
    3813              :               {
    3814            0 :                 if (TREE_CODE (field) == FIELD_DECL
    3815            0 :                     && ix86_contains_aligned_value_p (TREE_TYPE (field)))
    3816              :                   return true;
    3817              :               }
    3818              :             break;
    3819              :           }
    3820              : 
    3821            0 :         case ARRAY_TYPE:
    3822              :           /* Just for use if some languages passes arrays by value.  */
    3823            0 :           if (ix86_contains_aligned_value_p (TREE_TYPE (type)))
    3824              :             return true;
    3825              :           break;
    3826              : 
    3827              :         default:
    3828              :           gcc_unreachable ();
    3829              :         }
    3830              :     }
    3831              :   else
    3832         2909 :     return TYPE_ALIGN (type) >= 128;
    3833              : 
    3834              :   return false;
    3835              : }
    3836              : 
    3837              : /* Gives the alignment boundary, in bits, of an argument with the
    3838              :    specified mode and type.  */
    3839              : 
    3840              : static unsigned int
    3841     11091069 : ix86_function_arg_boundary (machine_mode mode, const_tree type)
    3842              : {
    3843     11091069 :   unsigned int align;
    3844     11091069 :   if (type)
    3845              :     {
    3846              :       /* Since the main variant type is used for call, we convert it to
    3847              :          the main variant type.  */
    3848     11051146 :       type = TYPE_MAIN_VARIANT (type);
    3849     11051146 :       align = TYPE_ALIGN (type);
    3850     11051146 :       if (TYPE_EMPTY_P (type))
    3851        25563 :         return PARM_BOUNDARY;
    3852              :     }
    3853              :   else
    3854        39923 :     align = GET_MODE_ALIGNMENT (mode);
    3855     13091928 :   if (align < PARM_BOUNDARY)
    3856      4145363 :     align = PARM_BOUNDARY;
    3857              :   else
    3858              :     {
    3859      6920143 :       static bool warned;
    3860      6920143 :       unsigned int saved_align = align;
    3861              : 
    3862      6920143 :       if (!TARGET_64BIT)
    3863              :         {
    3864              :           /* i386 ABI defines XFmode arguments to be 4 byte aligned.  */
    3865      2015030 :           if (!type)
    3866              :             {
    3867        35848 :               if (mode == XFmode || mode == XCmode)
    3868              :                 align = PARM_BOUNDARY;
    3869              :             }
    3870      1979182 :           else if (!ix86_contains_aligned_value_p (type))
    3871              :             align = PARM_BOUNDARY;
    3872              : 
    3873        38757 :           if (align < 128)
    3874      1988219 :             align = PARM_BOUNDARY;
    3875              :         }
    3876              : 
    3877      6920143 :       if (warn_psabi
    3878      5662126 :           && !warned
    3879     12573751 :           && align != ix86_compat_function_arg_boundary (mode, type,
    3880              :                                                          saved_align))
    3881              :         {
    3882          105 :           warned = true;
    3883          105 :           inform (input_location,
    3884              :                   "the ABI for passing parameters with %d-byte"
    3885              :                   " alignment has changed in GCC 4.6",
    3886              :                   align / BITS_PER_UNIT);
    3887              :         }
    3888              :     }
    3889              : 
    3890              :   return align;
    3891              : }
    3892              : 
    3893              : /* Return true if N is a possible register number of function value.  */
    3894              : 
    3895              : static bool
    3896      4524812 : ix86_function_value_regno_p (const unsigned int regno)
    3897              : {
    3898      4524812 :   switch (regno)
    3899              :     {
    3900              :     case AX_REG:
    3901              :       return true;
    3902       109432 :     case DX_REG:
    3903       109432 :       return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI);
    3904              : 
    3905              :       /* Complex values are returned in %st(0)/%st(1) pair.  */
    3906        16252 :     case ST0_REG:
    3907        16252 :     case ST1_REG:
    3908              :       /* TODO: An ABI identifier should be passed as a parameter.
    3909              :          For now, most callers, including those in builtins.cc,
    3910              :          expect us to use the default ABI.  */
    3911        16252 :       if (TARGET_64BIT && ix86_abi == MS_ABI)
    3912              :         return false;
    3913        16252 :       return TARGET_FLOAT_RETURNS_IN_80387;
    3914              : 
    3915              :       /* Complex values are returned in %xmm0/%xmm1 pair.  */
    3916      1290676 :     case XMM0_REG:
    3917      1290676 :     case XMM1_REG:
    3918      1290676 :       return TARGET_SSE;
    3919              : 
    3920         5469 :     case MM0_REG:
    3921         5469 :       if (TARGET_MACHO || TARGET_64BIT)
    3922              :         return false;
    3923         2499 :       return TARGET_MMX;
    3924              :     }
    3925              : 
    3926              :   return false;
    3927              : }
    3928              : 
    3929              : /* Check whether the register REGNO should be zeroed on X86.
    3930              :    When ALL_SSE_ZEROED is true, all SSE registers have been zeroed
    3931              :    together, no need to zero it again.
    3932              :    When NEED_ZERO_MMX is true, MMX registers should be cleared.  */
    3933              : 
    3934              : static bool
    3935         1377 : zero_call_used_regno_p (const unsigned int regno,
    3936              :                         bool all_sse_zeroed,
    3937              :                         bool need_zero_mmx)
    3938              : {
    3939          835 :   return GENERAL_REGNO_P (regno)
    3940          819 :          || (!all_sse_zeroed && SSE_REGNO_P (regno))
    3941          439 :          || MASK_REGNO_P (regno)
    3942         1800 :          || (need_zero_mmx && MMX_REGNO_P (regno));
    3943              : }
    3944              : 
    3945              : /* Return the machine_mode that is used to zero register REGNO.  */
    3946              : 
    3947              : static machine_mode
    3948          954 : zero_call_used_regno_mode (const unsigned int regno)
    3949              : {
    3950              :   /* NB: We only need to zero the lower 32 bits for integer registers
    3951              :      and the lower 128 bits for vector registers since destination are
    3952              :      zero-extended to the full register width.  */
    3953          954 :   if (GENERAL_REGNO_P (regno))
    3954              :     return SImode;
    3955              :   else if (SSE_REGNO_P (regno))
    3956          380 :     return V4SFmode;
    3957              :   else if (MASK_REGNO_P (regno))
    3958              :     return HImode;
    3959              :   else if (MMX_REGNO_P (regno))
    3960            0 :     return V2SImode;
    3961              :   else
    3962            0 :     gcc_unreachable ();
    3963              : }
    3964              : 
    3965              : /* Generate a rtx to zero all vector registers together if possible,
    3966              :    otherwise, return NULL.  */
    3967              : 
    3968              : static rtx
    3969          131 : zero_all_vector_registers (HARD_REG_SET need_zeroed_hardregs)
    3970              : {
    3971          131 :   if (!TARGET_AVX)
    3972              :     return NULL;
    3973              : 
    3974          380 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    3975          376 :     if ((LEGACY_SSE_REGNO_P (regno)
    3976          344 :          || (TARGET_64BIT
    3977          344 :              && (REX_SSE_REGNO_P (regno)
    3978          312 :                  || (TARGET_AVX512F && EXT_REX_SSE_REGNO_P (regno)))))
    3979          440 :         && !TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    3980              :       return NULL;
    3981              : 
    3982            4 :   return gen_avx_vzeroall ();
    3983              : }
    3984              : 
    3985              : /* Generate insns to zero all st registers together.
    3986              :    Return true when zeroing instructions are generated.
    3987              :    Assume the number of st registers that are zeroed is num_of_st,
    3988              :    we will emit the following sequence to zero them together:
    3989              :                   fldz;         \
    3990              :                   fldz;         \
    3991              :                   ...
    3992              :                   fldz;         \
    3993              :                   fstp %%st(0); \
    3994              :                   fstp %%st(0); \
    3995              :                   ...
    3996              :                   fstp %%st(0);
    3997              :    i.e., num_of_st fldz followed by num_of_st fstp to clear the stack
    3998              :    mark stack slots empty.
    3999              : 
    4000              :    How to compute the num_of_st:
    4001              :    There is no direct mapping from stack registers to hard register
    4002              :    numbers.  If one stack register needs to be cleared, we don't know
    4003              :    where in the stack the value remains.  So, if any stack register
    4004              :    needs to be cleared, the whole stack should be cleared.  However,
    4005              :    x87 stack registers that hold the return value should be excluded.
    4006              :    x87 returns in the top (two for complex values) register, so
    4007              :    num_of_st should be 7/6 when x87 returns, otherwise it will be 8.
    4008              :    return the value of num_of_st.  */
    4009              : 
    4010              : 
    4011              : static int
    4012          131 : zero_all_st_registers (HARD_REG_SET need_zeroed_hardregs)
    4013              : {
    4014              : 
    4015              :   /* If the FPU is disabled, no need to zero all st registers.  */
    4016          131 :   if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
    4017              :     return 0;
    4018              : 
    4019        10547 :   unsigned int num_of_st = 0;
    4020        10547 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4021        10438 :     if ((STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
    4022        10438 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4023              :       {
    4024              :         num_of_st++;
    4025              :         break;
    4026              :       }
    4027              : 
    4028          130 :   if (num_of_st == 0)
    4029              :     return 0;
    4030              : 
    4031           21 :   bool return_with_x87 = false;
    4032           42 :   return_with_x87 = (crtl->return_rtx
    4033           21 :                      && (STACK_REG_P (crtl->return_rtx)));
    4034              : 
    4035           21 :   bool complex_return = false;
    4036           42 :   complex_return = (crtl->return_rtx
    4037           21 :                     && COMPLEX_MODE_P (GET_MODE (crtl->return_rtx)));
    4038              : 
    4039           21 :   if (return_with_x87)
    4040            2 :     if (complex_return)
    4041              :       num_of_st = 6;
    4042              :     else
    4043            1 :       num_of_st = 7;
    4044              :   else
    4045              :     num_of_st = 8;
    4046              : 
    4047           21 :   rtx st_reg = gen_rtx_REG (XFmode, FIRST_STACK_REG);
    4048          207 :   for (unsigned int i = 0; i < num_of_st; i++)
    4049          165 :     emit_insn (gen_rtx_SET (st_reg, CONST0_RTX (XFmode)));
    4050              : 
    4051          186 :   for (unsigned int i = 0; i < num_of_st; i++)
    4052              :     {
    4053          165 :       rtx insn;
    4054          165 :       insn = emit_insn (gen_rtx_SET (st_reg, st_reg));
    4055          165 :       add_reg_note (insn, REG_DEAD, st_reg);
    4056              :     }
    4057           21 :   return num_of_st;
    4058              : }
    4059              : 
    4060              : 
    4061              : /* When the routine exit in MMX mode, if any ST register needs
    4062              :    to be zeroed, we should clear all MMX registers except the
    4063              :    RET_MMX_REGNO that holds the return value.  */
    4064              : static bool
    4065            0 : zero_all_mm_registers (HARD_REG_SET need_zeroed_hardregs,
    4066              :                        unsigned int ret_mmx_regno)
    4067              : {
    4068            0 :   bool need_zero_all_mm = false;
    4069            0 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4070            0 :     if (STACK_REGNO_P (regno)
    4071            0 :         && TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4072              :       {
    4073              :         need_zero_all_mm = true;
    4074              :         break;
    4075              :       }
    4076              : 
    4077            0 :   if (!need_zero_all_mm)
    4078              :     return false;
    4079              : 
    4080              :   machine_mode mode = V2SImode;
    4081            0 :   for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    4082            0 :     if (regno != ret_mmx_regno)
    4083              :       {
    4084            0 :         rtx reg = gen_rtx_REG (mode, regno);
    4085            0 :         emit_insn (gen_rtx_SET (reg, CONST0_RTX (mode)));
    4086              :       }
    4087              :   return true;
    4088              : }
    4089              : 
    4090              : /* TARGET_ZERO_CALL_USED_REGS.  */
    4091              : /* Generate a sequence of instructions that zero registers specified by
    4092              :    NEED_ZEROED_HARDREGS.  Return the ZEROED_HARDREGS that are actually
    4093              :    zeroed.  */
    4094              : static HARD_REG_SET
    4095          131 : ix86_zero_call_used_regs (HARD_REG_SET need_zeroed_hardregs)
    4096              : {
    4097          131 :   HARD_REG_SET zeroed_hardregs;
    4098          131 :   bool all_sse_zeroed = false;
    4099          131 :   int all_st_zeroed_num = 0;
    4100          131 :   bool all_mm_zeroed = false;
    4101              : 
    4102          131 :   CLEAR_HARD_REG_SET (zeroed_hardregs);
    4103              : 
    4104              :   /* first, let's see whether we can zero all vector registers together.  */
    4105          131 :   rtx zero_all_vec_insn = zero_all_vector_registers (need_zeroed_hardregs);
    4106          131 :   if (zero_all_vec_insn)
    4107              :     {
    4108            4 :       emit_insn (zero_all_vec_insn);
    4109            4 :       all_sse_zeroed = true;
    4110            4 :       if (TARGET_64BIT && TARGET_AVX512F)
    4111              :         {
    4112            2 :           rtx zero = CONST0_RTX (V4SFmode);
    4113           34 :           for (unsigned int regno = XMM16_REG;
    4114           34 :                regno <= XMM31_REG;
    4115              :                regno++)
    4116              :             {
    4117           32 :               rtx reg = gen_rtx_REG (V4SFmode, regno);
    4118           32 :               emit_move_insn (reg, zero);
    4119              :             }
    4120              :         }
    4121              :     }
    4122              : 
    4123              :   /* mm/st registers are shared registers set, we should follow the following
    4124              :      rules to clear them:
    4125              :                         MMX exit mode         x87 exit mode
    4126              :         -------------|----------------------|---------------
    4127              :         uses x87 reg | clear all MMX        | clear all x87
    4128              :         uses MMX reg | clear individual MMX | clear all x87
    4129              :         x87 + MMX    | clear all MMX        | clear all x87
    4130              : 
    4131              :      first, we should decide which mode (MMX mode or x87 mode) the function
    4132              :      exit with.  */
    4133              : 
    4134          131 :   bool exit_with_mmx_mode = (crtl->return_rtx
    4135          131 :                              && (MMX_REG_P (crtl->return_rtx)));
    4136              : 
    4137          131 :   if (!exit_with_mmx_mode)
    4138              :     /* x87 exit mode, we should zero all st registers together.  */
    4139              :     {
    4140          131 :       all_st_zeroed_num = zero_all_st_registers (need_zeroed_hardregs);
    4141              : 
    4142          131 :       if (all_st_zeroed_num > 0)
    4143          189 :         for (unsigned int regno = FIRST_STACK_REG; regno <= LAST_STACK_REG; regno++)
    4144              :           /* x87 stack registers that hold the return value should be excluded.
    4145              :              x87 returns in the top (two for complex values) register.  */
    4146          168 :           if (all_st_zeroed_num == 8
    4147          168 :               || !((all_st_zeroed_num >= 6 && regno == REGNO (crtl->return_rtx))
    4148              :                    || (all_st_zeroed_num == 6
    4149            7 :                        && (regno == (REGNO (crtl->return_rtx) + 1)))))
    4150          165 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4151              :     }
    4152              :   else
    4153              :     /* MMX exit mode, check whether we can zero all mm registers.  */
    4154              :     {
    4155            0 :       unsigned int exit_mmx_regno = REGNO (crtl->return_rtx);
    4156            0 :       all_mm_zeroed = zero_all_mm_registers (need_zeroed_hardregs,
    4157              :                                              exit_mmx_regno);
    4158            0 :       if (all_mm_zeroed)
    4159            0 :         for (unsigned int regno = FIRST_MMX_REG; regno <= LAST_MMX_REG; regno++)
    4160            0 :           if (regno != exit_mmx_regno)
    4161            0 :             SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4162              :     }
    4163              : 
    4164              :   /* Now, generate instructions to zero all the other registers.  */
    4165              : 
    4166        12445 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    4167              :     {
    4168        12314 :       if (!TEST_HARD_REG_BIT (need_zeroed_hardregs, regno))
    4169        10937 :         continue;
    4170         1800 :       if (!zero_call_used_regno_p (regno, all_sse_zeroed,
    4171         1377 :                                    exit_with_mmx_mode && !all_mm_zeroed))
    4172          423 :         continue;
    4173              : 
    4174          954 :       SET_HARD_REG_BIT (zeroed_hardregs, regno);
    4175              : 
    4176          954 :       machine_mode mode = zero_call_used_regno_mode (regno);
    4177              : 
    4178          954 :       rtx reg = gen_rtx_REG (mode, regno);
    4179          954 :       rtx tmp = gen_rtx_SET (reg, CONST0_RTX (mode));
    4180              : 
    4181          954 :       switch (mode)
    4182              :         {
    4183          558 :         case E_SImode:
    4184          558 :           if (!TARGET_USE_MOV0 || optimize_insn_for_size_p ())
    4185              :             {
    4186          558 :               rtx clob = gen_rtx_CLOBBER (VOIDmode,
    4187              :                                           gen_rtx_REG (CCmode,
    4188              :                                                        FLAGS_REG));
    4189          558 :               tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
    4190              :                                                            tmp,
    4191              :                                                            clob));
    4192              :             }
    4193              :           /* FALLTHRU.  */
    4194              : 
    4195          954 :         case E_V4SFmode:
    4196          954 :         case E_HImode:
    4197          954 :         case E_V2SImode:
    4198          954 :           emit_insn (tmp);
    4199          954 :           break;
    4200              : 
    4201              :         default:
    4202              :           gcc_unreachable ();
    4203              :         }
    4204              :     }
    4205          131 :   return zeroed_hardregs;
    4206              : }
    4207              : 
    4208              : /* Define how to find the value returned by a function.
    4209              :    VALTYPE is the data type of the value (as a tree).
    4210              :    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    4211              :    otherwise, FUNC is 0.  */
    4212              : 
    4213              : static rtx
    4214      3958055 : function_value_32 (machine_mode orig_mode, machine_mode mode,
    4215              :                    const_tree fntype, const_tree fn)
    4216              : {
    4217      3958055 :   unsigned int regno;
    4218              : 
    4219              :   /* 8-byte vector modes in %mm0. See ix86_return_in_memory for where
    4220              :      we normally prevent this case when mmx is not available.  However
    4221              :      some ABIs may require the result to be returned like DImode.  */
    4222      4233400 :   if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 8)
    4223              :     regno = FIRST_MMX_REG;
    4224              : 
    4225              :   /* 16-byte vector modes in %xmm0.  See ix86_return_in_memory for where
    4226              :      we prevent this case when sse is not available.  However some ABIs
    4227              :      may require the result to be returned like integer TImode.  */
    4228      3948779 :   else if (mode == TImode
    4229      4214848 :            || (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 16))
    4230              :     regno = FIRST_SSE_REG;
    4231              : 
    4232              :   /* 32-byte vector modes in %ymm0.   */
    4233      3986126 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 32)
    4234              :     regno = FIRST_SSE_REG;
    4235              : 
    4236              :   /* 64-byte vector modes in %zmm0.   */
    4237      3839992 :   else if (VECTOR_MODE_P (mode) && GET_MODE_SIZE (mode) == 64)
    4238              :     regno = FIRST_SSE_REG;
    4239              : 
    4240              :   /* Floating point return values in %st(0) (unless -mno-fp-ret-in-387).  */
    4241      3682710 :   else if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387)
    4242              :     regno = FIRST_FLOAT_REG;
    4243              :   else
    4244              :     /* Most things go in %eax.  */
    4245      3616906 :     regno = AX_REG;
    4246              : 
    4247              :   /* Return __bf16/ _Float16/_Complex _Foat16 by sse register.  */
    4248      3958055 :   if (mode == HFmode || mode == BFmode)
    4249              :     {
    4250         1917 :       if (!TARGET_SSE2)
    4251              :         {
    4252            0 :           error ("SSE register return with SSE2 disabled");
    4253            0 :           regno = AX_REG;
    4254              :         }
    4255              :       else
    4256              :         regno = FIRST_SSE_REG;
    4257              :     }
    4258              : 
    4259      3958055 :   if (mode == HCmode)
    4260              :     {
    4261          129 :       if (!TARGET_SSE2)
    4262            0 :         error ("SSE register return with SSE2 disabled");
    4263              : 
    4264          129 :       rtx ret = gen_rtx_PARALLEL (mode, rtvec_alloc(1));
    4265          258 :       XVECEXP (ret, 0, 0)
    4266          258 :         = gen_rtx_EXPR_LIST (VOIDmode,
    4267              :                              gen_rtx_REG (SImode,
    4268          129 :                                           TARGET_SSE2 ? FIRST_SSE_REG : AX_REG),
    4269              :                              GEN_INT (0));
    4270          129 :       return ret;
    4271              :     }
    4272              : 
    4273              :   /* Override FP return register with %xmm0 for local functions when
    4274              :      SSE math is enabled or for functions with sseregparm attribute.  */
    4275      3957926 :   if ((fn || fntype) && (mode == SFmode || mode == DFmode))
    4276              :     {
    4277        51267 :       int sse_level = ix86_function_sseregparm (fntype, fn, false);
    4278        51267 :       if (sse_level == -1)
    4279              :         {
    4280            0 :           error ("calling %qD with SSE calling convention without "
    4281              :                  "SSE/SSE2 enabled", fn);
    4282            0 :           sorry ("this is a GCC bug that can be worked around by adding "
    4283              :                  "attribute used to function called");
    4284              :         }
    4285        51267 :       else if ((sse_level >= 1 && mode == SFmode)
    4286        51267 :                || (sse_level == 2 && mode == DFmode))
    4287              :         regno = FIRST_SSE_REG;
    4288              :     }
    4289              : 
    4290              :   /* OImode shouldn't be used directly.  */
    4291      3957926 :   gcc_assert (mode != OImode);
    4292              : 
    4293      3957926 :   return gen_rtx_REG (orig_mode, regno);
    4294              : }
    4295              : 
    4296              : static rtx
    4297    102970004 : function_value_64 (machine_mode orig_mode, machine_mode mode,
    4298              :                    const_tree valtype)
    4299              : {
    4300    102970004 :   rtx ret;
    4301              : 
    4302              :   /* Handle libcalls, which don't provide a type node.  */
    4303    102970004 :   if (valtype == NULL)
    4304              :     {
    4305       109110 :       unsigned int regno;
    4306              : 
    4307       109110 :       switch (mode)
    4308              :         {
    4309              :         case E_BFmode:
    4310              :         case E_HFmode:
    4311              :         case E_HCmode:
    4312              :         case E_SFmode:
    4313              :         case E_SCmode:
    4314              :         case E_DFmode:
    4315              :         case E_DCmode:
    4316              :         case E_TFmode:
    4317              :         case E_SDmode:
    4318              :         case E_DDmode:
    4319              :         case E_TDmode:
    4320              :           regno = FIRST_SSE_REG;
    4321              :           break;
    4322         1026 :         case E_XFmode:
    4323         1026 :         case E_XCmode:
    4324         1026 :           regno = FIRST_FLOAT_REG;
    4325         1026 :           break;
    4326              :         case E_TCmode:
    4327              :           return NULL;
    4328        57293 :         default:
    4329        57293 :           regno = AX_REG;
    4330              :         }
    4331              : 
    4332       109110 :       return gen_rtx_REG (mode, regno);
    4333              :     }
    4334    102860894 :   else if (POINTER_TYPE_P (valtype))
    4335              :     {
    4336              :       /* Pointers are always returned in word_mode.  */
    4337     17369692 :       mode = word_mode;
    4338              :     }
    4339              : 
    4340    102860894 :   ret = construct_container (mode, orig_mode, valtype, true,
    4341              :                              X86_64_MAX_RETURN_NREGS,
    4342              :                              X86_64_MAX_SSE_RETURN_NREGS,
    4343              :                              x86_64_int_return_registers, 0);
    4344              : 
    4345              :   /* For zero sized structures, construct_container returns NULL, but we
    4346              :      need to keep rest of compiler happy by returning meaningful value.  */
    4347    102860894 :   if (!ret)
    4348       210976 :     ret = gen_rtx_REG (orig_mode, AX_REG);
    4349              : 
    4350              :   return ret;
    4351              : }
    4352              : 
    4353              : static rtx
    4354            0 : function_value_ms_32 (machine_mode orig_mode, machine_mode mode,
    4355              :                       const_tree fntype, const_tree fn, const_tree valtype)
    4356              : {
    4357            0 :   unsigned int regno;
    4358              : 
    4359              :   /* Floating point return values in %st(0)
    4360              :      (unless -mno-fp-ret-in-387 or aggregate type of up to 8 bytes).  */
    4361            0 :   if (X87_FLOAT_MODE_P (mode) && TARGET_FLOAT_RETURNS_IN_80387
    4362            0 :            && (GET_MODE_SIZE (mode) > 8
    4363            0 :                || valtype == NULL_TREE || !AGGREGATE_TYPE_P (valtype)))
    4364              :   {
    4365            0 :     regno = FIRST_FLOAT_REG;
    4366            0 :     return gen_rtx_REG (orig_mode, regno);
    4367              :   }
    4368              :   else
    4369            0 :     return function_value_32(orig_mode, mode, fntype,fn);
    4370              : }
    4371              : 
    4372              : static rtx
    4373       804507 : function_value_ms_64 (machine_mode orig_mode, machine_mode mode,
    4374              :                       const_tree valtype)
    4375              : {
    4376       804507 :   unsigned int regno = AX_REG;
    4377              : 
    4378       804507 :   if (TARGET_SSE)
    4379              :     {
    4380       803778 :       unsigned int mode_size = GET_MODE_SIZE (mode);
    4381              : 
    4382       803778 :       switch (mode_size)
    4383              :         {
    4384        35435 :         case 16:
    4385        35435 :         case 32:
    4386        35435 :         case 64:
    4387        35435 :           if (mode_size == 32 && !TARGET_AVX)
    4388              :             break;
    4389        35435 :           if (mode_size == 64 && !TARGET_AVX512F)
    4390              :             break;
    4391        35435 :           if (valtype != NULL_TREE
    4392        35435 :               && !VECTOR_INTEGER_TYPE_P (valtype)
    4393        51401 :               && !VECTOR_FLOAT_TYPE_P (valtype))
    4394              :             break;
    4395        35435 :           if (VECTOR_MODE_P (mode)
    4396              :               && !COMPLEX_MODE_P (mode))
    4397       225402 :             regno = FIRST_SSE_REG;
    4398              :           break;
    4399       756704 :         case 8:
    4400       756704 :         case 4:
    4401       756704 :         case 2:
    4402       756704 :           if (valtype != NULL_TREE && AGGREGATE_TYPE_P (valtype))
    4403              :             break;
    4404       739410 :           if (mode == HFmode || mode == SFmode || mode == DFmode)
    4405       225402 :             regno = FIRST_SSE_REG;
    4406              :           break;
    4407              :         default:
    4408              :           break;
    4409              :         }
    4410              :     }
    4411       804507 :   return gen_rtx_REG (orig_mode, regno);
    4412              : }
    4413              : 
    4414              : static rtx
    4415    107732566 : ix86_function_value_1 (const_tree valtype, const_tree fntype_or_decl,
    4416              :                        machine_mode orig_mode, machine_mode mode)
    4417              : {
    4418    107732566 :   const_tree fn, fntype;
    4419              : 
    4420    107732566 :   fn = NULL_TREE;
    4421    107732566 :   if (fntype_or_decl && DECL_P (fntype_or_decl))
    4422      3664362 :     fn = fntype_or_decl;
    4423      3664362 :   fntype = fn ? TREE_TYPE (fn) : fntype_or_decl;
    4424              : 
    4425    107732566 :   if (ix86_function_type_abi (fntype) == MS_ABI)
    4426              :     {
    4427       804507 :       if (TARGET_64BIT)
    4428       804507 :         return function_value_ms_64 (orig_mode, mode, valtype);
    4429              :       else
    4430            0 :         return function_value_ms_32 (orig_mode, mode, fntype, fn, valtype);
    4431              :     }
    4432    106928059 :   else if (TARGET_64BIT)
    4433    102970004 :     return function_value_64 (orig_mode, mode, valtype);
    4434              :   else
    4435      3958055 :     return function_value_32 (orig_mode, mode, fntype, fn);
    4436              : }
    4437              : 
    4438              : static rtx
    4439    107620271 : ix86_function_value (const_tree valtype, const_tree fntype_or_decl, bool)
    4440              : {
    4441    107620271 :   machine_mode mode, orig_mode;
    4442              : 
    4443    107620271 :   orig_mode = TYPE_MODE (valtype);
    4444    107620271 :   mode = type_natural_mode (valtype, NULL, true);
    4445    107620271 :   return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
    4446              : }
    4447              : 
    4448              : /* Pointer function arguments and return values are promoted to
    4449              :    word_mode for normal functions.  */
    4450              : 
    4451              : static machine_mode
    4452     33120221 : ix86_promote_function_mode (const_tree type, machine_mode mode,
    4453              :                             int *punsignedp, const_tree fntype,
    4454              :                             int for_return)
    4455              : {
    4456     33120221 :   if (cfun->machine->func_type == TYPE_NORMAL
    4457     33119198 :       && type != NULL_TREE
    4458     33084732 :       && POINTER_TYPE_P (type))
    4459              :     {
    4460     16741759 :       *punsignedp = POINTERS_EXTEND_UNSIGNED;
    4461     16741759 :       return word_mode;
    4462              :     }
    4463     16378462 :   return default_promote_function_mode (type, mode, punsignedp, fntype,
    4464     16378462 :                                         for_return);
    4465              : }
    4466              : 
    4467              : /* Return true if a structure, union or array with MODE containing FIELD
    4468              :    should be accessed using BLKmode.  */
    4469              : 
    4470              : static bool
    4471    151978658 : ix86_member_type_forces_blk (const_tree field, machine_mode mode)
    4472              : {
    4473              :   /* Union with XFmode must be in BLKmode.  */
    4474    151978658 :   return (mode == XFmode
    4475    152156355 :           && (TREE_CODE (DECL_FIELD_CONTEXT (field)) == UNION_TYPE
    4476       135931 :               || TREE_CODE (DECL_FIELD_CONTEXT (field)) == QUAL_UNION_TYPE));
    4477              : }
    4478              : 
    4479              : rtx
    4480       112295 : ix86_libcall_value (machine_mode mode)
    4481              : {
    4482       112295 :   return ix86_function_value_1 (NULL, NULL, mode, mode);
    4483              : }
    4484              : 
    4485              : /* Return true iff type is returned in memory.  */
    4486              : 
    4487              : static bool
    4488    109767596 : ix86_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
    4489              : {
    4490    109767596 :   const machine_mode mode = type_natural_mode (type, NULL, true);
    4491    109767596 :   HOST_WIDE_INT size;
    4492              : 
    4493    109767596 :   if (TARGET_64BIT)
    4494              :     {
    4495    105207978 :       if (ix86_function_type_abi (fntype) == MS_ABI)
    4496              :         {
    4497       723912 :           size = int_size_in_bytes (type);
    4498              : 
    4499              :           /* __m128 is returned in xmm0.  256/512-bit vector values are
    4500              :              returned in ymm0/zmm0 when AVX/AVX512 is enabled.  */
    4501       723912 :           if ((!type || VECTOR_INTEGER_TYPE_P (type)
    4502       703441 :                || VECTOR_FLOAT_TYPE_P (type))
    4503        36437 :               && VECTOR_MODE_P (mode)
    4504              :               && !COMPLEX_MODE_P (mode)
    4505       760349 :               && ((GET_MODE_SIZE (mode) == 16 || size == 16)
    4506        43404 :                   || (TARGET_AVX && (GET_MODE_SIZE (mode) == 32 || size == 32))
    4507        11826 :                   || (TARGET_AVX512F
    4508        11322 :                       && (GET_MODE_SIZE (mode) == 64 || size == 64))))
    4509              :             return false;
    4510              : 
    4511              :           /* Otherwise, the size must be exactly in [1248]. */
    4512       688483 :           return size != 1 && size != 2 && size != 4 && size != 8;
    4513              :         }
    4514              :       else
    4515              :         {
    4516    104484066 :           int needed_intregs, needed_sseregs;
    4517              : 
    4518    104484066 :           return examine_argument (mode, type, true,
    4519              :                                    &needed_intregs, &needed_sseregs);
    4520              :         }
    4521              :     }
    4522              :   else
    4523              :     {
    4524      4559618 :       size = int_size_in_bytes (type);
    4525              : 
    4526              :       /* Intel MCU psABI returns scalars and aggregates no larger than 8
    4527              :          bytes in registers.  */
    4528      4559618 :       if (TARGET_IAMCU)
    4529            0 :         return VECTOR_MODE_P (mode) || size < 0 || size > 8;
    4530              : 
    4531      4559618 :       if (mode == BLKmode)
    4532              :         return true;
    4533              : 
    4534      4559618 :       if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
    4535              :         return false;
    4536              : 
    4537      4559618 :       if (VECTOR_MODE_P (mode) || mode == TImode)
    4538              :         {
    4539              :           /* User-created vectors small enough to fit in EAX.  */
    4540       275315 :           if (size < 8)
    4541              :             return false;
    4542              : 
    4543              :           /* Unless ABI prescribes otherwise,
    4544              :              MMX/3dNow values are returned in MM0 if available.  */
    4545              : 
    4546       275315 :           if (size == 8)
    4547         9266 :             return TARGET_VECT8_RETURNS || !TARGET_MMX;
    4548              : 
    4549              :           /* SSE values are returned in XMM0 if available.  */
    4550       266049 :           if (size == 16)
    4551       114351 :             return !TARGET_SSE;
    4552              : 
    4553              :           /* AVX values are returned in YMM0 if available.  */
    4554       151698 :           if (size == 32)
    4555        73058 :             return !TARGET_AVX;
    4556              : 
    4557              :           /* AVX512F values are returned in ZMM0 if available.  */
    4558        78640 :           if (size == 64)
    4559        78640 :             return !TARGET_AVX512F;
    4560              :         }
    4561              : 
    4562      4284303 :       if (mode == XFmode)
    4563              :         return false;
    4564              : 
    4565      4272221 :       if (size > 12)
    4566              :         return true;
    4567              : 
    4568              :       /* OImode shouldn't be used directly.  */
    4569      3296623 :       gcc_assert (mode != OImode);
    4570              : 
    4571              :       return false;
    4572              :     }
    4573              : }
    4574              : 
    4575              : /* Implement TARGET_PUSH_ARGUMENT.  */
    4576              : 
    4577              : static bool
    4578      9558945 : ix86_push_argument (unsigned int npush)
    4579              : {
    4580              :   /* If SSE2 is available, use vector move to put large argument onto
    4581              :      stack.  NB:  In 32-bit mode, use 8-byte vector move.  */
    4582     11985581 :   return ((!TARGET_SSE2 || npush < (TARGET_64BIT ? 16 : 8))
    4583      9293621 :           && TARGET_PUSH_ARGS
    4584     18852408 :           && !ACCUMULATE_OUTGOING_ARGS);
    4585              : }
    4586              : 
    4587              : 
    4588              : /* Create the va_list data type.  */
    4589              : 
    4590              : static tree
    4591       287896 : ix86_build_builtin_va_list_64 (void)
    4592              : {
    4593       287896 :   tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
    4594              : 
    4595       287896 :   record = lang_hooks.types.make_type (RECORD_TYPE);
    4596       287896 :   type_decl = build_decl (BUILTINS_LOCATION,
    4597              :                           TYPE_DECL, get_identifier ("__va_list_tag"), record);
    4598              : 
    4599       287896 :   f_gpr = build_decl (BUILTINS_LOCATION,
    4600              :                       FIELD_DECL, get_identifier ("gp_offset"),
    4601              :                       unsigned_type_node);
    4602       287896 :   f_fpr = build_decl (BUILTINS_LOCATION,
    4603              :                       FIELD_DECL, get_identifier ("fp_offset"),
    4604              :                       unsigned_type_node);
    4605       287896 :   f_ovf = build_decl (BUILTINS_LOCATION,
    4606              :                       FIELD_DECL, get_identifier ("overflow_arg_area"),
    4607              :                       ptr_type_node);
    4608       287896 :   f_sav = build_decl (BUILTINS_LOCATION,
    4609              :                       FIELD_DECL, get_identifier ("reg_save_area"),
    4610              :                       ptr_type_node);
    4611              : 
    4612       287896 :   va_list_gpr_counter_field = f_gpr;
    4613       287896 :   va_list_fpr_counter_field = f_fpr;
    4614              : 
    4615       287896 :   DECL_FIELD_CONTEXT (f_gpr) = record;
    4616       287896 :   DECL_FIELD_CONTEXT (f_fpr) = record;
    4617       287896 :   DECL_FIELD_CONTEXT (f_ovf) = record;
    4618       287896 :   DECL_FIELD_CONTEXT (f_sav) = record;
    4619              : 
    4620       287896 :   TYPE_STUB_DECL (record) = type_decl;
    4621       287896 :   TYPE_NAME (record) = type_decl;
    4622       287896 :   TYPE_FIELDS (record) = f_gpr;
    4623       287896 :   DECL_CHAIN (f_gpr) = f_fpr;
    4624       287896 :   DECL_CHAIN (f_fpr) = f_ovf;
    4625       287896 :   DECL_CHAIN (f_ovf) = f_sav;
    4626       287896 :   TREE_PUBLIC (type_decl) = 1;
    4627              : 
    4628       287896 :   layout_type (record);
    4629              : 
    4630       287896 :   TYPE_ATTRIBUTES (record) = tree_cons (get_identifier ("sysv_abi va_list"),
    4631       287896 :                                         NULL_TREE, TYPE_ATTRIBUTES (record));
    4632              : 
    4633              :   /* The correct type is an array type of one element.  */
    4634       287896 :   return build_array_type (record, build_index_type (size_zero_node));
    4635              : }
    4636              : 
    4637              : /* Setup the builtin va_list data type and for 64-bit the additional
    4638              :    calling convention specific va_list data types.  */
    4639              : 
    4640              : static tree
    4641       295058 : ix86_build_builtin_va_list (void)
    4642              : {
    4643       295058 :   if (TARGET_64BIT)
    4644              :     {
    4645              :       /* Initialize ABI specific va_list builtin types.
    4646              : 
    4647              :          In lto1, we can encounter two va_list types:
    4648              :          - one as a result of the type-merge across TUs, and
    4649              :          - the one constructed here.
    4650              :          These two types will not have the same TYPE_MAIN_VARIANT, and therefore
    4651              :          a type identity check in canonical_va_list_type based on
    4652              :          TYPE_MAIN_VARIANT (which we used to have) will not work.
    4653              :          Instead, we tag each va_list_type_node with its unique attribute, and
    4654              :          look for the attribute in the type identity check in
    4655              :          canonical_va_list_type.
    4656              : 
    4657              :          Tagging sysv_va_list_type_node directly with the attribute is
    4658              :          problematic since it's a array of one record, which will degrade into a
    4659              :          pointer to record when used as parameter (see build_va_arg comments for
    4660              :          an example), dropping the attribute in the process.  So we tag the
    4661              :          record instead.  */
    4662              : 
    4663              :       /* For SYSV_ABI we use an array of one record.  */
    4664       287896 :       sysv_va_list_type_node = ix86_build_builtin_va_list_64 ();
    4665              : 
    4666              :       /* For MS_ABI we use plain pointer to argument area.  */
    4667       287896 :       tree char_ptr_type = build_pointer_type (char_type_node);
    4668       287896 :       tree attr = tree_cons (get_identifier ("ms_abi va_list"), NULL_TREE,
    4669       287896 :                              TYPE_ATTRIBUTES (char_ptr_type));
    4670       287896 :       ms_va_list_type_node = build_type_attribute_variant (char_ptr_type, attr);
    4671              : 
    4672       287896 :       return ((ix86_abi == MS_ABI)
    4673       287896 :               ? ms_va_list_type_node
    4674       287846 :               : sysv_va_list_type_node);
    4675              :     }
    4676              :   else
    4677              :     {
    4678              :       /* For i386 we use plain pointer to argument area.  */
    4679         7162 :       return build_pointer_type (char_type_node);
    4680              :     }
    4681              : }
    4682              : 
    4683              : /* Worker function for TARGET_SETUP_INCOMING_VARARGS.  */
    4684              : 
    4685              : static void
    4686        15794 : setup_incoming_varargs_64 (CUMULATIVE_ARGS *cum)
    4687              : {
    4688        15794 :   rtx save_area, mem;
    4689        15794 :   alias_set_type set;
    4690        15794 :   int i, max;
    4691              : 
    4692              :   /* GPR size of varargs save area.  */
    4693        15794 :   if (cfun->va_list_gpr_size)
    4694        15331 :     ix86_varargs_gpr_size = X86_64_REGPARM_MAX * UNITS_PER_WORD;
    4695              :   else
    4696          463 :     ix86_varargs_gpr_size = 0;
    4697              : 
    4698              :   /* FPR size of varargs save area.  We don't need it if we don't pass
    4699              :      anything in SSE registers.  */
    4700        15794 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4701        14724 :     ix86_varargs_fpr_size = X86_64_SSE_REGPARM_MAX * 16;
    4702              :   else
    4703         1070 :     ix86_varargs_fpr_size = 0;
    4704              : 
    4705        15794 :   if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
    4706              :     return;
    4707              : 
    4708        15500 :   save_area = frame_pointer_rtx;
    4709        15500 :   set = get_varargs_alias_set ();
    4710              : 
    4711        15500 :   max = cum->regno + cfun->va_list_gpr_size / UNITS_PER_WORD;
    4712        15500 :   if (max > X86_64_REGPARM_MAX)
    4713              :     max = X86_64_REGPARM_MAX;
    4714              : 
    4715        15500 :   const int *parm_regs;
    4716        15500 :   if (cum->preserve_none_abi)
    4717              :     parm_regs = x86_64_preserve_none_int_parameter_registers;
    4718              :   else
    4719        15498 :     parm_regs = x86_64_int_parameter_registers;
    4720              : 
    4721        86087 :   for (i = cum->regno; i < max; i++)
    4722              :     {
    4723        70587 :       mem = gen_rtx_MEM (word_mode,
    4724        70587 :                          plus_constant (Pmode, save_area, i * UNITS_PER_WORD));
    4725        70587 :       MEM_NOTRAP_P (mem) = 1;
    4726        70587 :       set_mem_alias_set (mem, set);
    4727        70587 :       emit_move_insn (mem,
    4728        70587 :                       gen_rtx_REG (word_mode, parm_regs[i]));
    4729              :     }
    4730              : 
    4731        15500 :   if (ix86_varargs_fpr_size)
    4732              :     {
    4733        14724 :       machine_mode smode;
    4734        14724 :       rtx_code_label *label;
    4735        14724 :       rtx test;
    4736              : 
    4737              :       /* Now emit code to save SSE registers.  The AX parameter contains number
    4738              :          of SSE parameter registers used to call this function, though all we
    4739              :          actually check here is the zero/non-zero status.  */
    4740              : 
    4741        14724 :       label = gen_label_rtx ();
    4742        14724 :       test = gen_rtx_EQ (VOIDmode, gen_rtx_REG (QImode, AX_REG), const0_rtx);
    4743        14724 :       emit_jump_insn (gen_cbranchqi4 (test, XEXP (test, 0), XEXP (test, 1),
    4744              :                                       label));
    4745              : 
    4746              :       /* ??? If !TARGET_SSE_TYPELESS_STORES, would we perform better if
    4747              :          we used movdqa (i.e. TImode) instead?  Perhaps even better would
    4748              :          be if we could determine the real mode of the data, via a hook
    4749              :          into pass_stdarg.  Ignore all that for now.  */
    4750        14724 :       smode = V4SFmode;
    4751        14724 :       if (crtl->stack_alignment_needed < GET_MODE_ALIGNMENT (smode))
    4752         4217 :         crtl->stack_alignment_needed = GET_MODE_ALIGNMENT (smode);
    4753              : 
    4754        14724 :       max = cum->sse_regno + cfun->va_list_fpr_size / 16;
    4755        14724 :       if (max > X86_64_SSE_REGPARM_MAX)
    4756              :         max = X86_64_SSE_REGPARM_MAX;
    4757              : 
    4758       130892 :       for (i = cum->sse_regno; i < max; ++i)
    4759              :         {
    4760       116168 :           mem = plus_constant (Pmode, save_area,
    4761       116168 :                                i * 16 + ix86_varargs_gpr_size);
    4762       116168 :           mem = gen_rtx_MEM (smode, mem);
    4763       116168 :           MEM_NOTRAP_P (mem) = 1;
    4764       116168 :           set_mem_alias_set (mem, set);
    4765       116168 :           set_mem_align (mem, GET_MODE_ALIGNMENT (smode));
    4766              : 
    4767       116168 :           emit_move_insn (mem, gen_rtx_REG (smode, GET_SSE_REGNO (i)));
    4768              :         }
    4769              : 
    4770        14724 :       emit_label (label);
    4771              :     }
    4772              : }
    4773              : 
    4774              : static void
    4775         5656 : setup_incoming_varargs_ms_64 (CUMULATIVE_ARGS *cum)
    4776              : {
    4777         5656 :   alias_set_type set = get_varargs_alias_set ();
    4778         5656 :   int i;
    4779              : 
    4780              :   /* Reset to zero, as there might be a sysv vaarg used
    4781              :      before.  */
    4782         5656 :   ix86_varargs_gpr_size = 0;
    4783         5656 :   ix86_varargs_fpr_size = 0;
    4784              : 
    4785        14170 :   for (i = cum->regno; i < X86_64_MS_REGPARM_MAX; i++)
    4786              :     {
    4787         8514 :       rtx reg, mem;
    4788              : 
    4789         8514 :       mem = gen_rtx_MEM (Pmode,
    4790         8514 :                          plus_constant (Pmode, virtual_incoming_args_rtx,
    4791         8514 :                                         i * UNITS_PER_WORD));
    4792         8514 :       MEM_NOTRAP_P (mem) = 1;
    4793         8514 :       set_mem_alias_set (mem, set);
    4794              : 
    4795         8514 :       reg = gen_rtx_REG (Pmode, x86_64_ms_abi_int_parameter_registers[i]);
    4796         8514 :       emit_move_insn (mem, reg);
    4797              :     }
    4798         5656 : }
    4799              : 
    4800              : static void
    4801        21604 : ix86_setup_incoming_varargs (cumulative_args_t cum_v,
    4802              :                              const function_arg_info &arg,
    4803              :                              int *, int no_rtl)
    4804              : {
    4805        21604 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    4806        21604 :   CUMULATIVE_ARGS next_cum;
    4807        21604 :   tree fntype;
    4808              : 
    4809              :   /* This argument doesn't appear to be used anymore.  Which is good,
    4810              :      because the old code here didn't suppress rtl generation.  */
    4811        21604 :   gcc_assert (!no_rtl);
    4812              : 
    4813        21604 :   if (!TARGET_64BIT)
    4814          154 :     return;
    4815              : 
    4816        21450 :   fntype = TREE_TYPE (current_function_decl);
    4817              : 
    4818              :   /* For varargs, we do not want to skip the dummy va_dcl argument.
    4819              :      For stdargs, we do want to skip the last named argument.  */
    4820        21450 :   next_cum = *cum;
    4821        21450 :   if ((!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
    4822          151 :        || arg.type != NULL_TREE)
    4823        21487 :       && stdarg_p (fntype))
    4824        21336 :     ix86_function_arg_advance (pack_cumulative_args (&next_cum), arg);
    4825              : 
    4826        21450 :   if (cum->call_abi == MS_ABI)
    4827         5656 :     setup_incoming_varargs_ms_64 (&next_cum);
    4828              :   else
    4829        15794 :     setup_incoming_varargs_64 (&next_cum);
    4830              : }
    4831              : 
    4832              : /* Checks if TYPE is of kind va_list char *.  */
    4833              : 
    4834              : static bool
    4835        73410 : is_va_list_char_pointer (tree type)
    4836              : {
    4837        73410 :   tree canonic;
    4838              : 
    4839              :   /* For 32-bit it is always true.  */
    4840        73410 :   if (!TARGET_64BIT)
    4841              :     return true;
    4842        73248 :   canonic = ix86_canonical_va_list_type (type);
    4843        73248 :   return (canonic == ms_va_list_type_node
    4844        73248 :           || (ix86_abi == MS_ABI && canonic == va_list_type_node));
    4845              : }
    4846              : 
    4847              : /* Implement va_start.  */
    4848              : 
    4849              : static void
    4850        21092 : ix86_va_start (tree valist, rtx nextarg)
    4851              : {
    4852        21092 :   HOST_WIDE_INT words, n_gpr, n_fpr;
    4853        21092 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4854        21092 :   tree gpr, fpr, ovf, sav, t;
    4855        21092 :   tree type;
    4856        21092 :   rtx ovf_rtx;
    4857              : 
    4858        21092 :   if (flag_split_stack
    4859           12 :       && cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4860              :     {
    4861           12 :       unsigned int scratch_regno;
    4862              : 
    4863              :       /* When we are splitting the stack, we can't refer to the stack
    4864              :          arguments using internal_arg_pointer, because they may be on
    4865              :          the old stack.  The split stack prologue will arrange to
    4866              :          leave a pointer to the old stack arguments in a scratch
    4867              :          register, which we here copy to a pseudo-register.  The split
    4868              :          stack prologue can't set the pseudo-register directly because
    4869              :          it (the prologue) runs before any registers have been saved.  */
    4870              : 
    4871           12 :       scratch_regno = split_stack_prologue_scratch_regno ();
    4872           12 :       if (scratch_regno != INVALID_REGNUM)
    4873              :         {
    4874           12 :           rtx reg;
    4875           12 :           rtx_insn *seq;
    4876              : 
    4877           16 :           reg = gen_reg_rtx (Pmode);
    4878           12 :           cfun->machine->split_stack_varargs_pointer = reg;
    4879              : 
    4880           12 :           start_sequence ();
    4881           16 :           emit_move_insn (reg, gen_rtx_REG (Pmode, scratch_regno));
    4882           12 :           seq = end_sequence ();
    4883              : 
    4884           12 :           push_topmost_sequence ();
    4885           12 :           emit_insn_after (seq, entry_of_function ());
    4886           12 :           pop_topmost_sequence ();
    4887              :         }
    4888              :     }
    4889              : 
    4890              :   /* Only 64bit target needs something special.  */
    4891        21092 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4892              :     {
    4893         5660 :       if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4894         5656 :         std_expand_builtin_va_start (valist, nextarg);
    4895              :       else
    4896              :         {
    4897            4 :           rtx va_r, next;
    4898              : 
    4899            4 :           va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
    4900            8 :           next = expand_binop (ptr_mode, add_optab,
    4901            4 :                                cfun->machine->split_stack_varargs_pointer,
    4902              :                                crtl->args.arg_offset_rtx,
    4903              :                                NULL_RTX, 0, OPTAB_LIB_WIDEN);
    4904            4 :           convert_move (va_r, next, 0);
    4905              :         }
    4906              :       return;
    4907              :     }
    4908              : 
    4909        15432 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    4910        15432 :   f_fpr = DECL_CHAIN (f_gpr);
    4911        15432 :   f_ovf = DECL_CHAIN (f_fpr);
    4912        15432 :   f_sav = DECL_CHAIN (f_ovf);
    4913              : 
    4914        15432 :   valist = build_simple_mem_ref (valist);
    4915        15432 :   TREE_TYPE (valist) = TREE_TYPE (sysv_va_list_type_node);
    4916              :   /* The following should be folded into the MEM_REF offset.  */
    4917        15432 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), unshare_expr (valist),
    4918              :                 f_gpr, NULL_TREE);
    4919        15432 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
    4920              :                 f_fpr, NULL_TREE);
    4921        15432 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
    4922              :                 f_ovf, NULL_TREE);
    4923        15432 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
    4924              :                 f_sav, NULL_TREE);
    4925              : 
    4926              :   /* Count number of gp and fp argument registers used.  */
    4927        15432 :   words = crtl->args.info.words;
    4928        15432 :   n_gpr = crtl->args.info.regno;
    4929        15432 :   n_fpr = crtl->args.info.sse_regno;
    4930              : 
    4931        15432 :   if (cfun->va_list_gpr_size)
    4932              :     {
    4933        15185 :       type = TREE_TYPE (gpr);
    4934        15185 :       t = build2 (MODIFY_EXPR, type,
    4935        15185 :                   gpr, build_int_cst (type, n_gpr * 8));
    4936        15185 :       TREE_SIDE_EFFECTS (t) = 1;
    4937        15185 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4938              :     }
    4939              : 
    4940        15432 :   if (TARGET_SSE && cfun->va_list_fpr_size)
    4941              :     {
    4942        14566 :       type = TREE_TYPE (fpr);
    4943        14566 :       t = build2 (MODIFY_EXPR, type, fpr,
    4944        14566 :                   build_int_cst (type, n_fpr * 16 + 8*X86_64_REGPARM_MAX));
    4945        14566 :       TREE_SIDE_EFFECTS (t) = 1;
    4946        14566 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4947              :     }
    4948              : 
    4949              :   /* Find the overflow area.  */
    4950        15432 :   type = TREE_TYPE (ovf);
    4951        15432 :   if (cfun->machine->split_stack_varargs_pointer == NULL_RTX)
    4952        15424 :     ovf_rtx = crtl->args.internal_arg_pointer;
    4953              :   else
    4954              :     ovf_rtx = cfun->machine->split_stack_varargs_pointer;
    4955        15432 :   t = make_tree (type, ovf_rtx);
    4956        15432 :   if (words != 0)
    4957          492 :     t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
    4958              : 
    4959        15432 :   t = build2 (MODIFY_EXPR, type, ovf, t);
    4960        15432 :   TREE_SIDE_EFFECTS (t) = 1;
    4961        15432 :   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4962              : 
    4963        15432 :   if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
    4964              :     {
    4965              :       /* Find the register save area.
    4966              :          Prologue of the function save it right above stack frame.  */
    4967        15354 :       type = TREE_TYPE (sav);
    4968        15354 :       t = make_tree (type, frame_pointer_rtx);
    4969        15354 :       if (!ix86_varargs_gpr_size)
    4970          169 :         t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
    4971              : 
    4972        15354 :       t = build2 (MODIFY_EXPR, type, sav, t);
    4973        15354 :       TREE_SIDE_EFFECTS (t) = 1;
    4974        15354 :       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
    4975              :     }
    4976              : }
    4977              : 
    4978              : /* Implement va_arg.  */
    4979              : 
    4980              : static tree
    4981        52318 : ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
    4982              :                       gimple_seq *post_p)
    4983              : {
    4984        52318 :   static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
    4985        52318 :   tree f_gpr, f_fpr, f_ovf, f_sav;
    4986        52318 :   tree gpr, fpr, ovf, sav, t;
    4987        52318 :   int size, rsize;
    4988        52318 :   tree lab_false, lab_over = NULL_TREE;
    4989        52318 :   tree addr, t2;
    4990        52318 :   rtx container;
    4991        52318 :   int indirect_p = 0;
    4992        52318 :   tree ptrtype;
    4993        52318 :   machine_mode nat_mode;
    4994        52318 :   unsigned int arg_boundary;
    4995        52318 :   unsigned int type_align;
    4996              : 
    4997              :   /* Only 64bit target needs something special.  */
    4998        52318 :   if (is_va_list_char_pointer (TREE_TYPE (valist)))
    4999          260 :     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
    5000              : 
    5001        52058 :   f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node));
    5002        52058 :   f_fpr = DECL_CHAIN (f_gpr);
    5003        52058 :   f_ovf = DECL_CHAIN (f_fpr);
    5004        52058 :   f_sav = DECL_CHAIN (f_ovf);
    5005              : 
    5006        52058 :   gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr),
    5007              :                 valist, f_gpr, NULL_TREE);
    5008              : 
    5009        52058 :   fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
    5010        52058 :   ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
    5011        52058 :   sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
    5012              : 
    5013        52058 :   indirect_p = pass_va_arg_by_reference (type);
    5014        52058 :   if (indirect_p)
    5015          103 :     type = build_pointer_type (type);
    5016        52058 :   size = arg_int_size_in_bytes (type);
    5017        52058 :   rsize = CEIL (size, UNITS_PER_WORD);
    5018              : 
    5019        52058 :   nat_mode = type_natural_mode (type, NULL, false);
    5020        52058 :   switch (nat_mode)
    5021              :     {
    5022           28 :     case E_V16HFmode:
    5023           28 :     case E_V16BFmode:
    5024           28 :     case E_V8SFmode:
    5025           28 :     case E_V8SImode:
    5026           28 :     case E_V32QImode:
    5027           28 :     case E_V16HImode:
    5028           28 :     case E_V4DFmode:
    5029           28 :     case E_V4DImode:
    5030           28 :     case E_V32HFmode:
    5031           28 :     case E_V32BFmode:
    5032           28 :     case E_V16SFmode:
    5033           28 :     case E_V16SImode:
    5034           28 :     case E_V64QImode:
    5035           28 :     case E_V32HImode:
    5036           28 :     case E_V8DFmode:
    5037           28 :     case E_V8DImode:
    5038              :       /* Unnamed 256 and 512bit vector mode parameters are passed on stack.  */
    5039           28 :       if (!TARGET_64BIT_MS_ABI)
    5040              :         {
    5041              :           container = NULL;
    5042              :           break;
    5043              :         }
    5044              :       /* FALLTHRU */
    5045              : 
    5046        52030 :     default:
    5047        52030 :       container = construct_container (nat_mode, TYPE_MODE (type),
    5048              :                                        type, false, X86_64_REGPARM_MAX,
    5049              :                                        X86_64_SSE_REGPARM_MAX, intreg, 0);
    5050        52030 :       break;
    5051              :     }
    5052              : 
    5053              :   /* Pull the value out of the saved registers.  */
    5054              : 
    5055        52058 :   addr = create_tmp_var (ptr_type_node, "addr");
    5056        52058 :   type_align = TYPE_ALIGN (type);
    5057              : 
    5058        52058 :   if (container)
    5059              :     {
    5060        28964 :       int needed_intregs, needed_sseregs;
    5061        28964 :       bool need_temp;
    5062        28964 :       tree int_addr, sse_addr;
    5063              : 
    5064        28964 :       lab_false = create_artificial_label (UNKNOWN_LOCATION);
    5065        28964 :       lab_over = create_artificial_label (UNKNOWN_LOCATION);
    5066              : 
    5067        28964 :       examine_argument (nat_mode, type, false,
    5068              :                         &needed_intregs, &needed_sseregs);
    5069              : 
    5070        28964 :       bool container_in_reg = false;
    5071        28964 :       if (REG_P (container))
    5072              :         container_in_reg = true;
    5073         1641 :       else if (GET_CODE (container) == PARALLEL
    5074         1641 :                && GET_MODE (container) == BLKmode
    5075          580 :                && XVECLEN (container, 0) == 1)
    5076              :         {
    5077              :           /* Check if it is a PARALLEL BLKmode container of an EXPR_LIST
    5078              :              expression in a TImode register.  In this case, temp isn't
    5079              :              needed.  Otherwise, the TImode variable will be put in the
    5080              :              GPR save area which guarantees only 8-byte alignment.   */
    5081          509 :           rtx x = XVECEXP (container, 0, 0);
    5082          509 :           if (GET_CODE (x) == EXPR_LIST
    5083          509 :               && REG_P (XEXP (x, 0))
    5084          509 :               && XEXP (x, 1) == const0_rtx)
    5085              :             container_in_reg = true;
    5086              :         }
    5087              : 
    5088          680 :       need_temp = (!container_in_reg
    5089         1150 :                    && ((needed_intregs && TYPE_ALIGN (type) > 64)
    5090          680 :                        || TYPE_ALIGN (type) > 128));
    5091              : 
    5092              :       /* In case we are passing structure, verify that it is consecutive block
    5093              :          on the register save area.  If not we need to do moves.  */
    5094          680 :       if (!need_temp && !container_in_reg)
    5095              :         {
    5096              :           /* Verify that all registers are strictly consecutive  */
    5097          966 :           if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
    5098              :             {
    5099              :               int i;
    5100              : 
    5101          815 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    5102              :                 {
    5103          529 :                   rtx slot = XVECEXP (container, 0, i);
    5104          529 :                   if (REGNO (XEXP (slot, 0)) != FIRST_SSE_REG + (unsigned int) i
    5105          529 :                       || INTVAL (XEXP (slot, 1)) != i * 16)
    5106              :                     need_temp = true;
    5107              :                 }
    5108              :             }
    5109              :           else
    5110              :             {
    5111              :               int i;
    5112              : 
    5113         1120 :               for (i = 0; i < XVECLEN (container, 0) && !need_temp; i++)
    5114              :                 {
    5115          726 :                   rtx slot = XVECEXP (container, 0, i);
    5116          726 :                   if (REGNO (XEXP (slot, 0)) != (unsigned int) i
    5117          726 :                       || INTVAL (XEXP (slot, 1)) != i * 8)
    5118              :                     need_temp = true;
    5119              :                 }
    5120              :             }
    5121              :         }
    5122        28964 :       if (!need_temp)
    5123              :         {
    5124              :           int_addr = addr;
    5125              :           sse_addr = addr;
    5126              :         }
    5127              :       else
    5128              :         {
    5129          877 :           int_addr = create_tmp_var (ptr_type_node, "int_addr");
    5130          877 :           sse_addr = create_tmp_var (ptr_type_node, "sse_addr");
    5131              :         }
    5132              : 
    5133              :       /* First ensure that we fit completely in registers.  */
    5134        28964 :       if (needed_intregs)
    5135              :         {
    5136        18198 :           t = build_int_cst (TREE_TYPE (gpr),
    5137        18198 :                              (X86_64_REGPARM_MAX - needed_intregs + 1) * 8);
    5138        18198 :           t = build2 (GE_EXPR, boolean_type_node, gpr, t);
    5139        18198 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    5140        18198 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    5141        18198 :           gimplify_and_add (t, pre_p);
    5142              :         }
    5143        28964 :       if (needed_sseregs)
    5144              :         {
    5145        11158 :           t = build_int_cst (TREE_TYPE (fpr),
    5146              :                              (X86_64_SSE_REGPARM_MAX - needed_sseregs + 1) * 16
    5147        11158 :                              + X86_64_REGPARM_MAX * 8);
    5148        11158 :           t = build2 (GE_EXPR, boolean_type_node, fpr, t);
    5149        11158 :           t2 = build1 (GOTO_EXPR, void_type_node, lab_false);
    5150        11158 :           t = build3 (COND_EXPR, void_type_node, t, t2, NULL_TREE);
    5151        11158 :           gimplify_and_add (t, pre_p);
    5152              :         }
    5153              : 
    5154              :       /* Compute index to start of area used for integer regs.  */
    5155        28964 :       if (needed_intregs)
    5156              :         {
    5157              :           /* int_addr = gpr + sav; */
    5158        18198 :           t = fold_build_pointer_plus (sav, gpr);
    5159        18198 :           gimplify_assign (int_addr, t, pre_p);
    5160              :         }
    5161        28964 :       if (needed_sseregs)
    5162              :         {
    5163              :           /* sse_addr = fpr + sav; */
    5164        11158 :           t = fold_build_pointer_plus (sav, fpr);
    5165        11158 :           gimplify_assign (sse_addr, t, pre_p);
    5166              :         }
    5167        28964 :       if (need_temp)
    5168              :         {
    5169          877 :           int i, prev_size = 0;
    5170          877 :           tree temp = create_tmp_var (type, "va_arg_tmp");
    5171          877 :           TREE_ADDRESSABLE (temp) = 1;
    5172              : 
    5173              :           /* addr = &temp; */
    5174          877 :           t = build1 (ADDR_EXPR, build_pointer_type (type), temp);
    5175          877 :           gimplify_assign (addr, t, pre_p);
    5176              : 
    5177         3118 :           for (i = 0; i < XVECLEN (container, 0); i++)
    5178              :             {
    5179         1364 :               rtx slot = XVECEXP (container, 0, i);
    5180         1364 :               rtx reg = XEXP (slot, 0);
    5181         1364 :               machine_mode mode = GET_MODE (reg);
    5182         1364 :               tree piece_type;
    5183         1364 :               tree addr_type;
    5184         1364 :               tree daddr_type;
    5185         1364 :               tree src_addr, src;
    5186         1364 :               int src_offset;
    5187         1364 :               tree dest_addr, dest;
    5188         1364 :               int cur_size = GET_MODE_SIZE (mode);
    5189              : 
    5190         1364 :               gcc_assert (prev_size <= INTVAL (XEXP (slot, 1)));
    5191         1364 :               prev_size = INTVAL (XEXP (slot, 1));
    5192         1364 :               if (prev_size + cur_size > size)
    5193              :                 {
    5194           30 :                   cur_size = size - prev_size;
    5195           30 :                   unsigned int nbits = cur_size * BITS_PER_UNIT;
    5196           30 :                   if (!int_mode_for_size (nbits, 1).exists (&mode))
    5197           10 :                     mode = QImode;
    5198              :                 }
    5199         1364 :               piece_type = lang_hooks.types.type_for_mode (mode, 1);
    5200         1364 :               if (mode == GET_MODE (reg))
    5201         1334 :                 addr_type = build_pointer_type (piece_type);
    5202              :               else
    5203           30 :                 addr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5204              :                                                          true);
    5205         1364 :               daddr_type = build_pointer_type_for_mode (piece_type, ptr_mode,
    5206              :                                                         true);
    5207              : 
    5208         1364 :               if (SSE_REGNO_P (REGNO (reg)))
    5209              :                 {
    5210          534 :                   src_addr = sse_addr;
    5211          534 :                   src_offset = (REGNO (reg) - FIRST_SSE_REG) * 16;
    5212              :                 }
    5213              :               else
    5214              :                 {
    5215          830 :                   src_addr = int_addr;
    5216          830 :                   src_offset = REGNO (reg) * 8;
    5217              :                 }
    5218         1364 :               src_addr = fold_convert (addr_type, src_addr);
    5219         1364 :               src_addr = fold_build_pointer_plus_hwi (src_addr, src_offset);
    5220              : 
    5221         1364 :               dest_addr = fold_convert (daddr_type, addr);
    5222         1364 :               dest_addr = fold_build_pointer_plus_hwi (dest_addr, prev_size);
    5223         2728 :               if (cur_size == GET_MODE_SIZE (mode))
    5224              :                 {
    5225         1354 :                   src = build_va_arg_indirect_ref (src_addr);
    5226         1354 :                   dest = build_va_arg_indirect_ref (dest_addr);
    5227              : 
    5228         1354 :                   gimplify_assign (dest, src, pre_p);
    5229              :                 }
    5230              :               else
    5231              :                 {
    5232           10 :                   tree copy
    5233           20 :                     = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
    5234              :                                        3, dest_addr, src_addr,
    5235           10 :                                        size_int (cur_size));
    5236           10 :                   gimplify_and_add (copy, pre_p);
    5237              :                 }
    5238         1364 :               prev_size += cur_size;
    5239              :             }
    5240              :         }
    5241              : 
    5242        28964 :       if (needed_intregs)
    5243              :         {
    5244        18198 :           t = build2 (PLUS_EXPR, TREE_TYPE (gpr), gpr,
    5245        18198 :                       build_int_cst (TREE_TYPE (gpr), needed_intregs * 8));
    5246        18198 :           gimplify_assign (gpr, t, pre_p);
    5247              :           /* The GPR save area guarantees only 8-byte alignment.  */
    5248        18198 :           if (!need_temp)
    5249        17394 :             type_align = MIN (type_align, 64);
    5250              :         }
    5251              : 
    5252        28964 :       if (needed_sseregs)
    5253              :         {
    5254        11158 :           t = build2 (PLUS_EXPR, TREE_TYPE (fpr), fpr,
    5255        11158 :                       build_int_cst (TREE_TYPE (fpr), needed_sseregs * 16));
    5256        11158 :           gimplify_assign (unshare_expr (fpr), t, pre_p);
    5257              :         }
    5258              : 
    5259        28964 :       gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
    5260              : 
    5261        28964 :       gimple_seq_add_stmt (pre_p, gimple_build_label (lab_false));
    5262              :     }
    5263              : 
    5264              :   /* ... otherwise out of the overflow area.  */
    5265              : 
    5266              :   /* When we align parameter on stack for caller, if the parameter
    5267              :      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
    5268              :      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
    5269              :      here with caller.  */
    5270        52058 :   arg_boundary = ix86_function_arg_boundary (VOIDmode, type);
    5271        52058 :   if ((unsigned int) arg_boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
    5272              :     arg_boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
    5273              : 
    5274              :   /* ARG_BOUNDARY is computed from TYPE_MAIN_VARIANT, so it can be smaller
    5275              :      than the alignment of a variant type that carries a user-specified
    5276              :      alignment (e.g. a typedef with attribute aligned).  Do not let the
    5277              :      access claim more alignment than the argument slot is placed at.  */
    5278        52058 :   type_align = MIN (type_align, arg_boundary);
    5279              : 
    5280              :   /* Care for on-stack alignment if needed.  */
    5281        52058 :   if (arg_boundary <= 64 || size == 0)
    5282        35018 :     t = ovf;
    5283              :  else
    5284              :     {
    5285        17040 :       HOST_WIDE_INT align = arg_boundary / 8;
    5286        17040 :       t = fold_build_pointer_plus_hwi (ovf, align - 1);
    5287        17040 :       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
    5288        17040 :                   build_int_cst (TREE_TYPE (t), -align));
    5289              :     }
    5290              : 
    5291        52058 :   gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
    5292        52058 :   gimplify_assign (addr, t, pre_p);
    5293              : 
    5294        52058 :   t = fold_build_pointer_plus_hwi (t, rsize * UNITS_PER_WORD);
    5295        52058 :   gimplify_assign (unshare_expr (ovf), t, pre_p);
    5296              : 
    5297        52058 :   if (container)
    5298        28964 :     gimple_seq_add_stmt (pre_p, gimple_build_label (lab_over));
    5299              : 
    5300        52058 :   type = build_aligned_type (type, type_align);
    5301        52058 :   ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
    5302        52058 :   addr = fold_convert (ptrtype, addr);
    5303              : 
    5304        52058 :   if (indirect_p)
    5305          103 :     addr = build_va_arg_indirect_ref (addr);
    5306        52058 :   return build_va_arg_indirect_ref (addr);
    5307              : }
    5308              : 
    5309              : /* Return true if OPNUM's MEM should be matched
    5310              :    in movabs* patterns.  */
    5311              : 
    5312              : bool
    5313          421 : ix86_check_movabs (rtx insn, int opnum)
    5314              : {
    5315          421 :   rtx set, mem;
    5316              : 
    5317          421 :   set = PATTERN (insn);
    5318          421 :   if (GET_CODE (set) == PARALLEL)
    5319            0 :     set = XVECEXP (set, 0, 0);
    5320          421 :   gcc_assert (GET_CODE (set) == SET);
    5321          421 :   mem = XEXP (set, opnum);
    5322          421 :   while (SUBREG_P (mem))
    5323            0 :     mem = SUBREG_REG (mem);
    5324          421 :   gcc_assert (MEM_P (mem));
    5325          421 :   return volatile_ok || !MEM_VOLATILE_P (mem);
    5326              : }
    5327              : 
    5328              : /* Return true if XVECEXP idx of INSN satisfies MOVS arguments.  */
    5329              : bool
    5330       235925 : ix86_check_movs (rtx insn, int idx)
    5331              : {
    5332       235925 :   rtx pat = PATTERN (insn);
    5333       235925 :   gcc_assert (GET_CODE (pat) == PARALLEL);
    5334              : 
    5335       235925 :   rtx set = XVECEXP (pat, 0, idx);
    5336       235925 :   gcc_assert (GET_CODE (set) == SET);
    5337              : 
    5338       235925 :   rtx dst = SET_DEST (set);
    5339       235925 :   gcc_assert (MEM_P (dst));
    5340              : 
    5341       235925 :   rtx src = SET_SRC (set);
    5342       235925 :   gcc_assert (MEM_P (src));
    5343              : 
    5344       235925 :   return (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (dst))
    5345       471850 :           && (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (src))
    5346            0 :               || Pmode == word_mode));
    5347              : }
    5348              : 
    5349              : /* Return false if INSN contains a MEM with a non-default address space.  */
    5350              : bool
    5351        65499 : ix86_check_no_addr_space (rtx insn)
    5352              : {
    5353        65499 :   subrtx_var_iterator::array_type array;
    5354      1441431 :   FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), ALL)
    5355              :     {
    5356      1375932 :       rtx x = *iter;
    5357      1506930 :       if (MEM_P (x) && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)))
    5358            0 :         return false;
    5359              :     }
    5360        65499 :   return true;
    5361        65499 : }
    5362              : 
    5363              : /* Initialize the table of extra 80387 mathematical constants.  */
    5364              : 
    5365              : static void
    5366         2403 : init_ext_80387_constants (void)
    5367              : {
    5368         2403 :   static const char * cst[5] =
    5369              :   {
    5370              :     "0.3010299956639811952256464283594894482",  /* 0: fldlg2  */
    5371              :     "0.6931471805599453094286904741849753009",  /* 1: fldln2  */
    5372              :     "1.4426950408889634073876517827983434472",  /* 2: fldl2e  */
    5373              :     "3.3219280948873623478083405569094566090",  /* 3: fldl2t  */
    5374              :     "3.1415926535897932385128089594061862044",  /* 4: fldpi   */
    5375              :   };
    5376         2403 :   int i;
    5377              : 
    5378        14418 :   for (i = 0; i < 5; i++)
    5379              :     {
    5380        12015 :       real_from_string (&ext_80387_constants_table[i], cst[i]);
    5381              :       /* Ensure each constant is rounded to XFmode precision.  */
    5382        12015 :       real_convert (&ext_80387_constants_table[i],
    5383        24030 :                     XFmode, &ext_80387_constants_table[i]);
    5384              :     }
    5385              : 
    5386         2403 :   ext_80387_constants_init = 1;
    5387         2403 : }
    5388              : 
    5389              : /* Return non-zero if the constant is something that
    5390              :    can be loaded with a special instruction.  */
    5391              : 
    5392              : int
    5393      4958406 : standard_80387_constant_p (rtx x)
    5394              : {
    5395      4958406 :   machine_mode mode = GET_MODE (x);
    5396              : 
    5397      4958406 :   const REAL_VALUE_TYPE *r;
    5398              : 
    5399      4958406 :   if (!(CONST_DOUBLE_P (x) && X87_FLOAT_MODE_P (mode)))
    5400              :     return -1;
    5401              : 
    5402      4484360 :   if (x == CONST0_RTX (mode))
    5403              :     return 1;
    5404      2030273 :   if (x == CONST1_RTX (mode))
    5405              :     return 2;
    5406              : 
    5407      1229544 :   r = CONST_DOUBLE_REAL_VALUE (x);
    5408              : 
    5409              :   /* For XFmode constants, try to find a special 80387 instruction when
    5410              :      optimizing for size or on those CPUs that benefit from them.  */
    5411      1229544 :   if (mode == XFmode
    5412       791721 :       && (optimize_function_for_size_p (cfun) || TARGET_EXT_80387_CONSTANTS)
    5413      2021265 :       && !flag_rounding_math)
    5414              :     {
    5415       783671 :       int i;
    5416              : 
    5417       783671 :       if (! ext_80387_constants_init)
    5418         2396 :         init_ext_80387_constants ();
    5419              : 
    5420      4690651 :       for (i = 0; i < 5; i++)
    5421      3916638 :         if (real_identical (r, &ext_80387_constants_table[i]))
    5422         9658 :           return i + 3;
    5423              :     }
    5424              : 
    5425              :   /* Load of the constant -0.0 or -1.0 will be split as
    5426              :      fldz;fchs or fld1;fchs sequence.  */
    5427      1219886 :   if (real_isnegzero (r))
    5428              :     return 8;
    5429      1203461 :   if (real_identical (r, &dconstm1))
    5430       280312 :     return 9;
    5431              : 
    5432              :   return 0;
    5433              : }
    5434              : 
    5435              : /* Return the opcode of the special instruction to be used to load
    5436              :    the constant X.  */
    5437              : 
    5438              : const char *
    5439        44737 : standard_80387_constant_opcode (rtx x)
    5440              : {
    5441        44737 :   switch (standard_80387_constant_p (x))
    5442              :     {
    5443              :     case 1:
    5444              :       return "fldz";
    5445        25038 :     case 2:
    5446        25038 :       return "fld1";
    5447            1 :     case 3:
    5448            1 :       return "fldlg2";
    5449           10 :     case 4:
    5450           10 :       return "fldln2";
    5451           12 :     case 5:
    5452           12 :       return "fldl2e";
    5453            2 :     case 6:
    5454            2 :       return "fldl2t";
    5455          210 :     case 7:
    5456          210 :       return "fldpi";
    5457            0 :     case 8:
    5458            0 :     case 9:
    5459            0 :       return "#";
    5460            0 :     default:
    5461            0 :       gcc_unreachable ();
    5462              :     }
    5463              : }
    5464              : 
    5465              : /* Return the CONST_DOUBLE representing the 80387 constant that is
    5466              :    loaded by the specified special instruction.  The argument IDX
    5467              :    matches the return value from standard_80387_constant_p.  */
    5468              : 
    5469              : rtx
    5470           24 : standard_80387_constant_rtx (int idx)
    5471              : {
    5472           24 :   int i;
    5473              : 
    5474           24 :   if (! ext_80387_constants_init)
    5475            7 :     init_ext_80387_constants ();
    5476              : 
    5477           24 :   switch (idx)
    5478              :     {
    5479           24 :     case 3:
    5480           24 :     case 4:
    5481           24 :     case 5:
    5482           24 :     case 6:
    5483           24 :     case 7:
    5484           24 :       i = idx - 3;
    5485           24 :       break;
    5486              : 
    5487            0 :     default:
    5488            0 :       gcc_unreachable ();
    5489              :     }
    5490              : 
    5491           24 :   return const_double_from_real_value (ext_80387_constants_table[i],
    5492           24 :                                        XFmode);
    5493              : }
    5494              : 
    5495              : /* Return 1 if X is all bits 0, 2 if X is all bits 1
    5496              :    and 3 if X is all bits 1 with zero extend
    5497              :    in supported SSE/AVX vector mode.  */
    5498              : 
    5499              : int
    5500     71216379 : standard_sse_constant_p (rtx x, machine_mode pred_mode)
    5501              : {
    5502     71216379 :   machine_mode mode;
    5503              : 
    5504     71216379 :   if (!TARGET_SSE)
    5505              :     return 0;
    5506              : 
    5507     71045032 :   mode = GET_MODE (x);
    5508              : 
    5509     71045032 :   if (x == const0_rtx || const0_operand (x, mode))
    5510              :     return 1;
    5511              : 
    5512     56975865 :   if (x == constm1_rtx
    5513     56832783 :       || vector_all_ones_operand (x, mode)
    5514    113138295 :       || ((GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5515     49162471 :            || GET_MODE_CLASS (pred_mode) == MODE_VECTOR_FLOAT)
    5516      7001005 :           && float_vector_all_ones_operand (x, mode)))
    5517              :     {
    5518              :       /* VOIDmode integer constant, get mode from the predicate.  */
    5519       815423 :       if (mode == VOIDmode)
    5520       143082 :         mode = pred_mode;
    5521              : 
    5522      1630846 :       switch (GET_MODE_SIZE (mode))
    5523              :         {
    5524        33445 :         case 64:
    5525        33445 :           if (TARGET_AVX512F)
    5526              :             return 2;
    5527              :           break;
    5528        43527 :         case 32:
    5529        43527 :           if (TARGET_AVX2)
    5530              :             return 2;
    5531              :           break;
    5532       724996 :         case 16:
    5533       724996 :           if (TARGET_SSE2)
    5534              :             return 2;
    5535              :           break;
    5536            0 :         case 0:
    5537              :           /* VOIDmode */
    5538            0 :           gcc_unreachable ();
    5539              :         default:
    5540              :           break;
    5541              :         }
    5542              :     }
    5543              : 
    5544     56174828 :   if (vector_all_ones_zero_extend_half_operand (x, mode)
    5545     56174828 :       || vector_all_ones_zero_extend_quarter_operand (x, mode))
    5546          768 :     return 3;
    5547              : 
    5548              :   return 0;
    5549              : }
    5550              : 
    5551              : /* Return the opcode of the special instruction to be used to load
    5552              :    the constant operands[1] into operands[0].  */
    5553              : 
    5554              : const char *
    5555       469287 : standard_sse_constant_opcode (rtx_insn *insn, rtx *operands)
    5556              : {
    5557       469287 :   machine_mode mode;
    5558       469287 :   rtx x = operands[1];
    5559              : 
    5560       469287 :   gcc_assert (TARGET_SSE);
    5561              : 
    5562       469287 :   mode = GET_MODE (x);
    5563              : 
    5564       469287 :   if (x == const0_rtx || const0_operand (x, mode))
    5565              :     {
    5566       456587 :       switch (get_attr_mode (insn))
    5567              :         {
    5568       438580 :         case MODE_TI:
    5569       438580 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5570              :             return "%vpxor\t%0, %d0";
    5571              :           /* FALLTHRU */
    5572         6235 :         case MODE_XI:
    5573         6235 :         case MODE_OI:
    5574         6235 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5575              :             {
    5576           65 :               if (TARGET_AVX512VL)
    5577              :                 return "vpxord\t%x0, %x0, %x0";
    5578              :               else
    5579           28 :                 return "vpxord\t%g0, %g0, %g0";
    5580              :             }
    5581              :           return "vpxor\t%x0, %x0, %x0";
    5582              : 
    5583         2130 :         case MODE_V2DF:
    5584         2130 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5585              :             return "%vxorpd\t%0, %d0";
    5586              :           /* FALLTHRU */
    5587          856 :         case MODE_V8DF:
    5588          856 :         case MODE_V4DF:
    5589          856 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5590              :             {
    5591            6 :               if (TARGET_AVX512DQ)
    5592              :                 {
    5593            0 :                   if (TARGET_AVX512VL)
    5594              :                     return "vxorpd\t%x0, %x0, %x0";
    5595              :                   else
    5596            0 :                     return "vxorpd\t%g0, %g0, %g0";
    5597              :                 }
    5598              :               else
    5599              :                 {
    5600            6 :                   if (TARGET_AVX512VL)
    5601              :                     return "vpxorq\t%x0, %x0, %x0";
    5602              :                   else
    5603            6 :                     return "vpxorq\t%g0, %g0, %g0";
    5604              :                 }
    5605              :             }
    5606              :           return "vxorpd\t%x0, %x0, %x0";
    5607              : 
    5608         6835 :         case MODE_V4SF:
    5609         6835 :           if (!EXT_REX_SSE_REG_P (operands[0]))
    5610              :             return "%vxorps\t%0, %d0";
    5611              :           /* FALLTHRU */
    5612         2013 :         case MODE_V16SF:
    5613         2013 :         case MODE_V8SF:
    5614         2013 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5615              :             {
    5616           68 :               if (TARGET_AVX512DQ)
    5617              :                 {
    5618           26 :                   if (TARGET_AVX512VL)
    5619              :                     return "vxorps\t%x0, %x0, %x0";
    5620              :                   else
    5621            0 :                     return "vxorps\t%g0, %g0, %g0";
    5622              :                 }
    5623              :               else
    5624              :                 {
    5625           42 :                   if (TARGET_AVX512VL)
    5626              :                     return "vpxord\t%x0, %x0, %x0";
    5627              :                   else
    5628           40 :                     return "vpxord\t%g0, %g0, %g0";
    5629              :                 }
    5630              :             }
    5631              :           return "vxorps\t%x0, %x0, %x0";
    5632              : 
    5633            0 :         default:
    5634            0 :           gcc_unreachable ();
    5635              :         }
    5636              :     }
    5637        12700 :   else if (x == constm1_rtx
    5638        12689 :            || vector_all_ones_operand (x, mode)
    5639        12767 :            || (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
    5640           45 :                && float_vector_all_ones_operand (x, mode)))
    5641              :     {
    5642        12678 :       enum attr_mode insn_mode = get_attr_mode (insn);
    5643              : 
    5644        12678 :       switch (insn_mode)
    5645              :         {
    5646            3 :         case MODE_XI:
    5647            3 :         case MODE_V8DF:
    5648            3 :         case MODE_V16SF:
    5649            3 :           gcc_assert (TARGET_AVX512F);
    5650              :           return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5651              : 
    5652          958 :         case MODE_OI:
    5653          958 :         case MODE_V4DF:
    5654          958 :         case MODE_V8SF:
    5655          958 :           gcc_assert (TARGET_AVX2);
    5656              :           /* FALLTHRU */
    5657        12675 :         case MODE_TI:
    5658        12675 :         case MODE_V2DF:
    5659        12675 :         case MODE_V4SF:
    5660        12675 :           gcc_assert (TARGET_SSE2);
    5661        12675 :           if (EXT_REX_SSE_REG_P (operands[0]))
    5662              :             {
    5663            2 :               if (TARGET_AVX512VL)
    5664              :                 return "vpternlogd\t{$0xFF, %0, %0, %0|%0, %0, %0, 0xFF}";
    5665              :               else
    5666            0 :                 return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
    5667              :             }
    5668        12673 :           return (TARGET_AVX
    5669        12673 :                   ? "vpcmpeqd\t%0, %0, %0"
    5670              :                   : "pcmpeqd\t%0, %0");
    5671              : 
    5672            0 :         default:
    5673            0 :           gcc_unreachable ();
    5674              :         }
    5675              :    }
    5676           22 :   else if (vector_all_ones_zero_extend_half_operand (x, mode))
    5677              :     {
    5678           40 :       if (GET_MODE_SIZE (mode) == 64)
    5679              :         {
    5680            5 :           gcc_assert (TARGET_AVX512F);
    5681              :           return "vpcmpeqd\t%t0, %t0, %t0";
    5682              :         }
    5683           30 :       else if (GET_MODE_SIZE (mode) == 32)
    5684              :         {
    5685           15 :           gcc_assert (TARGET_AVX);
    5686              :           return "vpcmpeqd\t%x0, %x0, %x0";
    5687              :         }
    5688            0 :       gcc_unreachable ();
    5689              :     }
    5690            2 :   else if (vector_all_ones_zero_extend_quarter_operand (x, mode))
    5691              :     {
    5692            2 :       gcc_assert (TARGET_AVX512F);
    5693              :       return "vpcmpeqd\t%x0, %x0, %x0";
    5694              :     }
    5695              : 
    5696            0 :   gcc_unreachable ();
    5697              : }
    5698              : 
    5699              : /* Returns true if INSN can be transformed from a memory load
    5700              :    to a supported FP constant load.  */
    5701              : 
    5702              : bool
    5703      2155647 : ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
    5704              : {
    5705      2155647 :   rtx src = find_constant_src (insn);
    5706              : 
    5707      2155647 :   gcc_assert (REG_P (dst));
    5708              : 
    5709      2155647 :   if (src == NULL
    5710       594997 :       || (SSE_REGNO_P (REGNO (dst))
    5711       470588 :           && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
    5712       158467 :       || (!TARGET_AVX512VL
    5713       158406 :           && EXT_REX_SSE_REGNO_P (REGNO (dst))
    5714            0 :           && standard_sse_constant_p (src, GET_MODE (dst)) == 1)
    5715      2314114 :       || (STACK_REGNO_P (REGNO (dst))
    5716       124409 :            && standard_80387_constant_p (src) < 1))
    5717      2087970 :     return false;
    5718              : 
    5719              :   return true;
    5720              : }
    5721              : 
    5722              : /* Predicate for pre-reload splitters with associated instructions,
    5723              :    which can match any time before the split1 pass (usually combine),
    5724              :    then are unconditionally split in that pass and should not be
    5725              :    matched again afterwards.  */
    5726              : 
    5727              : bool
    5728     19356516 : ix86_pre_reload_split (void)
    5729              : {
    5730     19356516 :   return (can_create_pseudo_p ()
    5731     29742438 :           && !(cfun->curr_properties & PROP_rtl_split_insns));
    5732              : }
    5733              : 
    5734              : /* Return the opcode of the TYPE_SSEMOV instruction.  To move from
    5735              :    or to xmm16-xmm31/ymm16-ymm31 registers, we either require
    5736              :    TARGET_AVX512VL or it is a register to register move which can
    5737              :    be done with zmm register move. */
    5738              : 
    5739              : static const char *
    5740      4096417 : ix86_get_ssemov (rtx *operands, unsigned size,
    5741              :                  enum attr_mode insn_mode, machine_mode mode)
    5742              : {
    5743      4096417 :   char buf[128];
    5744      4096417 :   bool misaligned_p = (misaligned_operand (operands[0], mode)
    5745      4096417 :                        || misaligned_operand (operands[1], mode));
    5746      4096417 :   bool evex_reg_p = (size == 64
    5747      4008979 :                      || EXT_REX_SSE_REG_P (operands[0])
    5748      8104658 :                      || EXT_REX_SSE_REG_P (operands[1]));
    5749              : 
    5750      4096417 :   bool egpr_p = (TARGET_APX_EGPR
    5751      4096417 :                  && (x86_extended_rex2reg_mentioned_p (operands[0])
    5752          198 :                      || x86_extended_rex2reg_mentioned_p (operands[1])));
    5753          204 :   bool egpr_vl = egpr_p && TARGET_AVX512VL;
    5754              : 
    5755      4096417 :   machine_mode scalar_mode;
    5756              : 
    5757      4096417 :   const char *opcode = NULL;
    5758      4096417 :   enum
    5759              :     {
    5760              :       opcode_int,
    5761              :       opcode_float,
    5762              :       opcode_double
    5763      4096417 :     } type = opcode_int;
    5764              : 
    5765      4096417 :   switch (insn_mode)
    5766              :     {
    5767              :     case MODE_V16SF:
    5768              :     case MODE_V8SF:
    5769              :     case MODE_V4SF:
    5770              :       scalar_mode = E_SFmode;
    5771              :       type = opcode_float;
    5772              :       break;
    5773       214633 :     case MODE_V8DF:
    5774       214633 :     case MODE_V4DF:
    5775       214633 :     case MODE_V2DF:
    5776       214633 :       scalar_mode = E_DFmode;
    5777       214633 :       type = opcode_double;
    5778       214633 :       break;
    5779      1462021 :     case MODE_XI:
    5780      1462021 :     case MODE_OI:
    5781      1462021 :     case MODE_TI:
    5782      1462021 :       scalar_mode = GET_MODE_INNER (mode);
    5783              :       break;
    5784            0 :     default:
    5785            0 :       gcc_unreachable ();
    5786              :     }
    5787              : 
    5788              :   /* NB: To move xmm16-xmm31/ymm16-ymm31 registers without AVX512VL,
    5789              :      we can only use zmm register move without memory operand.  */
    5790      4096417 :   if (evex_reg_p
    5791        89497 :       && !TARGET_AVX512VL
    5792      4146472 :       && GET_MODE_SIZE (mode) < 64)
    5793              :     {
    5794              :       /* NB: Even though ix86_hard_regno_mode_ok doesn't allow
    5795              :          xmm16-xmm31 nor ymm16-ymm31 in 128/256 bit modes when
    5796              :          AVX512VL is disabled, LRA can still generate reg to
    5797              :          reg moves with xmm16-xmm31 and ymm16-ymm31 in 128/256 bit
    5798              :          modes.  */
    5799            0 :       if (memory_operand (operands[0], mode)
    5800            0 :           || memory_operand (operands[1], mode))
    5801            0 :         gcc_unreachable ();
    5802            0 :       size = 64;
    5803            0 :       switch (type)
    5804              :         {
    5805            0 :         case opcode_int:
    5806            0 :           if (scalar_mode == E_HFmode || scalar_mode == E_BFmode)
    5807            0 :             opcode = (misaligned_p
    5808            0 :                       ? (TARGET_AVX512BW ? "vmovdqu16" : "vmovdqu64")
    5809              :                       : "vmovdqa64");
    5810              :           else
    5811            0 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5812              :           break;
    5813            0 :         case opcode_float:
    5814            0 :           opcode = misaligned_p ? "vmovups" : "vmovaps";
    5815              :           break;
    5816            0 :         case opcode_double:
    5817            0 :           opcode = misaligned_p ? "vmovupd" : "vmovapd";
    5818              :           break;
    5819              :         }
    5820              :     }
    5821      4096417 :   else if (SCALAR_FLOAT_MODE_P (scalar_mode))
    5822              :     {
    5823      2811615 :       switch (scalar_mode)
    5824              :         {
    5825        36826 :         case E_HFmode:
    5826        36826 :         case E_BFmode:
    5827        36826 :           if (evex_reg_p || egpr_vl)
    5828        11622 :             opcode = (misaligned_p
    5829          175 :                       ? (TARGET_AVX512BW
    5830              :                          ? "vmovdqu16"
    5831              :                          : "vmovdqu64")
    5832              :                       : "vmovdqa64");
    5833        25204 :           else if (egpr_p)
    5834       739336 :             opcode = (misaligned_p
    5835            0 :                       ? (TARGET_AVX512BW
    5836            0 :                          ? "vmovdqu16"
    5837              :                          : "%vmovups")
    5838              :                       : "%vmovaps");
    5839              :           else
    5840       357986 :             opcode = (misaligned_p
    5841        25204 :                       ? (TARGET_AVX512BW && evex_reg_p
    5842              :                          ? "vmovdqu16"
    5843              :                          : "%vmovdqu")
    5844              :                       : "%vmovdqa");
    5845              :           break;
    5846      2419763 :         case E_SFmode:
    5847      2419763 :           opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5848              :           break;
    5849       214633 :         case E_DFmode:
    5850       214633 :           opcode = misaligned_p ? "%vmovupd" : "%vmovapd";
    5851              :           break;
    5852       140393 :         case E_TFmode:
    5853       140393 :           if (evex_reg_p || egpr_vl)
    5854           14 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5855       140379 :           else if (egpr_p)
    5856            0 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5857              :           else
    5858       140379 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5859              :           break;
    5860            0 :         default:
    5861            0 :           gcc_unreachable ();
    5862              :         }
    5863              :     }
    5864      1284802 :   else if (SCALAR_INT_MODE_P (scalar_mode))
    5865              :     {
    5866      1284802 :       switch (scalar_mode)
    5867              :         {
    5868        74707 :         case E_QImode:
    5869        74707 :           if (evex_reg_p || egpr_vl)
    5870      4107116 :             opcode = (misaligned_p
    5871        10699 :                       ? (TARGET_AVX512BW
    5872         5264 :                          ? "vmovdqu8"
    5873              :                          : "vmovdqu64")
    5874              :                       : "vmovdqa64");
    5875        64008 :           else if (egpr_p)
    5876           30 :             opcode = (misaligned_p
    5877            0 :                       ? (TARGET_AVX512BW
    5878              :                          ? "vmovdqu8"
    5879              :                          : "%vmovups")
    5880              :                       : "%vmovaps");
    5881              :           else
    5882        63978 :             opcode = (misaligned_p
    5883              :                       ? (TARGET_AVX512BW && evex_reg_p
    5884              :                          ? "vmovdqu8"
    5885              :                          : "%vmovdqu")
    5886              :                       : "%vmovdqa");
    5887              :           break;
    5888        44604 :         case E_HImode:
    5889        44604 :           if (evex_reg_p || egpr_vl)
    5890         3693 :             opcode = (misaligned_p
    5891          310 :                       ? (TARGET_AVX512BW
    5892              :                          ? "vmovdqu16"
    5893              :                          : "vmovdqu64")
    5894              :                       : "vmovdqa64");
    5895        40911 :           else if (egpr_p)
    5896       739336 :             opcode = (misaligned_p
    5897           27 :                       ? (TARGET_AVX512BW
    5898            0 :                          ? "vmovdqu16"
    5899              :                          : "%vmovups")
    5900              :                       : "%vmovaps");
    5901              :           else
    5902       332782 :             opcode = (misaligned_p
    5903        40884 :                       ? (TARGET_AVX512BW && evex_reg_p
    5904              :                          ? "vmovdqu16"
    5905              :                          : "%vmovdqu")
    5906              :                       : "%vmovdqa");
    5907              :           break;
    5908       189015 :         case E_SImode:
    5909       189015 :           if (evex_reg_p || egpr_vl)
    5910         8346 :             opcode = misaligned_p ? "vmovdqu32" : "vmovdqa32";
    5911       180669 :           else if (egpr_p)
    5912           14 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5913              :           else
    5914       180655 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5915              :           break;
    5916       964632 :         case E_DImode:
    5917       964632 :         case E_TImode:
    5918       964632 :         case E_OImode:
    5919       964632 :           if (evex_reg_p || egpr_vl)
    5920        18787 :             opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5921       945845 :           else if (egpr_p)
    5922           26 :             opcode = misaligned_p ? "%vmovups" : "%vmovaps";
    5923              :           else
    5924       945819 :             opcode = misaligned_p ? "%vmovdqu" : "%vmovdqa";
    5925              :           break;
    5926        11844 :         case E_XImode:
    5927        50005 :           opcode = misaligned_p ? "vmovdqu64" : "vmovdqa64";
    5928              :           break;
    5929            0 :         default:
    5930            0 :           gcc_unreachable ();
    5931              :         }
    5932              :     }
    5933              :   else
    5934            0 :     gcc_unreachable ();
    5935              : 
    5936      4096417 :   switch (size)
    5937              :     {
    5938        87438 :     case 64:
    5939        87438 :       snprintf (buf, sizeof (buf), "%s\t{%%g1, %%g0|%%g0, %%g1}",
    5940              :                 opcode);
    5941        87438 :       break;
    5942        92361 :     case 32:
    5943        92361 :       snprintf (buf, sizeof (buf), "%s\t{%%t1, %%t0|%%t0, %%t1}",
    5944              :                 opcode);
    5945        92361 :       break;
    5946      3916618 :     case 16:
    5947      3916618 :       snprintf (buf, sizeof (buf), "%s\t{%%x1, %%x0|%%x0, %%x1}",
    5948              :                 opcode);
    5949      3916618 :       break;
    5950            0 :     default:
    5951            0 :       gcc_unreachable ();
    5952              :     }
    5953      4096417 :   output_asm_insn (buf, operands);
    5954      4096417 :   return "";
    5955              : }
    5956              : 
    5957              : /* Return the template of the TYPE_SSEMOV instruction to move
    5958              :    operands[1] into operands[0].  */
    5959              : 
    5960              : const char *
    5961      6458566 : ix86_output_ssemov (rtx_insn *insn, rtx *operands)
    5962              : {
    5963      6458566 :   machine_mode mode = GET_MODE (operands[0]);
    5964      6458566 :   if (get_attr_type (insn) != TYPE_SSEMOV
    5965      6458566 :       || mode != GET_MODE (operands[1]))
    5966            0 :     gcc_unreachable ();
    5967              : 
    5968      6458566 :   enum attr_mode insn_mode = get_attr_mode (insn);
    5969              : 
    5970      6458566 :   switch (insn_mode)
    5971              :     {
    5972        87438 :     case MODE_XI:
    5973        87438 :     case MODE_V8DF:
    5974        87438 :     case MODE_V16SF:
    5975        87438 :       return ix86_get_ssemov (operands, 64, insn_mode, mode);
    5976              : 
    5977        92361 :     case MODE_OI:
    5978        92361 :     case MODE_V4DF:
    5979        92361 :     case MODE_V8SF:
    5980        92361 :       return ix86_get_ssemov (operands, 32, insn_mode, mode);
    5981              : 
    5982      3916618 :     case MODE_TI:
    5983      3916618 :     case MODE_V2DF:
    5984      3916618 :     case MODE_V4SF:
    5985      3916618 :       return ix86_get_ssemov (operands, 16, insn_mode, mode);
    5986              : 
    5987       646431 :     case MODE_DI:
    5988              :       /* Handle broken assemblers that require movd instead of movq. */
    5989       646431 :       if (GENERAL_REG_P (operands[0]))
    5990              :         {
    5991              :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5992              :             return "%vmovq\t{%1, %q0|%q0, %1}";
    5993              :           else
    5994              :             return "%vmovd\t{%1, %q0|%q0, %1}";
    5995              :         }
    5996       578229 :       else if (GENERAL_REG_P (operands[1]))
    5997              :         {
    5998       168515 :           if (HAVE_AS_IX86_INTERUNIT_MOVQ)
    5999       168515 :             return "%vmovq\t{%q1, %0|%0, %q1}";
    6000              :           else
    6001              :             return "%vmovd\t{%q1, %0|%0, %q1}";
    6002              :         }
    6003              :       else
    6004              :         return "%vmovq\t{%1, %0|%0, %1}";
    6005              : 
    6006       194706 :     case MODE_SI:
    6007       194706 :       if (GENERAL_REG_P (operands[0]))
    6008              :         return "%vmovd\t{%1, %k0|%k0, %1}";
    6009       133576 :       else if (GENERAL_REG_P (operands[1]))
    6010        82541 :         return "%vmovd\t{%k1, %0|%0, %k1}";
    6011              :       else
    6012              :         return "%vmovd\t{%1, %0|%0, %1}";
    6013              : 
    6014        54062 :     case MODE_HI:
    6015        54062 :       if (GENERAL_REG_P (operands[0]))
    6016              :         return "vmovw\t{%1, %k0|%k0, %1}";
    6017        53898 :       else if (GENERAL_REG_P (operands[1]))
    6018          233 :         return "vmovw\t{%k1, %0|%0, %k1}";
    6019              :       else
    6020              :         return "vmovw\t{%1, %0|%0, %1}";
    6021              : 
    6022       791639 :     case MODE_DF:
    6023       791639 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    6024              :         return "vmovsd\t{%d1, %0|%0, %d1}";
    6025              :       else
    6026       790800 :         return "%vmovsd\t{%1, %0|%0, %1}";
    6027              : 
    6028       671318 :     case MODE_SF:
    6029       671318 :       if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
    6030              :         return "vmovss\t{%d1, %0|%0, %d1}";
    6031              :       else
    6032       670727 :         return "%vmovss\t{%1, %0|%0, %1}";
    6033              : 
    6034           96 :     case MODE_HF:
    6035           96 :     case MODE_BF:
    6036           96 :       if (REG_P (operands[0]) && REG_P (operands[1]))
    6037              :         return "vmovsh\t{%d1, %0|%0, %d1}";
    6038              :       else
    6039            0 :         return "vmovsh\t{%1, %0|%0, %1}";
    6040              : 
    6041           35 :     case MODE_V1DF:
    6042           35 :       gcc_assert (!TARGET_AVX);
    6043              :       return "movlpd\t{%1, %0|%0, %1}";
    6044              : 
    6045         3862 :     case MODE_V2SF:
    6046         3862 :       if (TARGET_AVX && REG_P (operands[0]))
    6047              :         return "vmovlps\t{%1, %d0|%d0, %1}";
    6048              :       else
    6049         3789 :         return "%vmovlps\t{%1, %0|%0, %1}";
    6050              : 
    6051            0 :     default:
    6052            0 :       gcc_unreachable ();
    6053              :     }
    6054              : }
    6055              : 
    6056              : /* Returns true if OP contains a symbol reference */
    6057              : 
    6058              : bool
    6059    582057944 : symbolic_reference_mentioned_p (const_rtx op)
    6060              : {
    6061    582057944 :   const char *fmt;
    6062    582057944 :   int i;
    6063              : 
    6064    582057944 :   if (SYMBOL_REF_P (op) || LABEL_REF_P (op))
    6065              :     return true;
    6066              : 
    6067    440047404 :   fmt = GET_RTX_FORMAT (GET_CODE (op));
    6068    747016110 :   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
    6069              :     {
    6070    596068641 :       if (fmt[i] == 'E')
    6071              :         {
    6072      2032036 :           int j;
    6073              : 
    6074      4077530 :           for (j = XVECLEN (op, i) - 1; j >= 0; j--)
    6075      3355394 :             if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
    6076              :               return true;
    6077              :         }
    6078              : 
    6079    594036605 :       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
    6080              :         return true;
    6081              :     }
    6082              : 
    6083              :   return false;
    6084              : }
    6085              : 
    6086              : /* Return true if it is appropriate to emit `ret' instructions in the
    6087              :    body of a function.  Do this only if the epilogue is simple, needing a
    6088              :    couple of insns.  Prior to reloading, we can't tell how many registers
    6089              :    must be saved, so return false then.  Return false if there is no frame
    6090              :    marker to de-allocate.  */
    6091              : 
    6092              : bool
    6093            0 : ix86_can_use_return_insn_p (void)
    6094              : {
    6095            0 :   if (ix86_function_ms_hook_prologue (current_function_decl))
    6096              :     return false;
    6097              : 
    6098            0 :   if (ix86_function_naked (current_function_decl))
    6099              :     return false;
    6100              : 
    6101              :   /* Don't use `ret' instruction in interrupt handler.  */
    6102            0 :   if (! reload_completed
    6103            0 :       || frame_pointer_needed
    6104            0 :       || cfun->machine->func_type != TYPE_NORMAL)
    6105              :     return 0;
    6106              : 
    6107              :   /* Don't allow more than 32k pop, since that's all we can do
    6108              :      with one instruction.  */
    6109            0 :   if (crtl->args.pops_args && crtl->args.size >= 32768)
    6110              :     return 0;
    6111              : 
    6112            0 :   struct ix86_frame &frame = cfun->machine->frame;
    6113            0 :   return (frame.stack_pointer_offset == UNITS_PER_WORD
    6114            0 :           && (frame.nregs + frame.nsseregs) == 0);
    6115              : }
    6116              : 
    6117              : /* Return stack frame size.  get_frame_size () returns used stack slots
    6118              :    during compilation, which may be optimized out later.  If stack frame
    6119              :    is needed, stack_frame_required should be true.  */
    6120              : 
    6121              : static HOST_WIDE_INT
    6122      8447974 : ix86_get_frame_size (void)
    6123              : {
    6124      8447974 :   if (cfun->machine->stack_frame_required)
    6125      8376747 :     return get_frame_size ();
    6126              :   else
    6127              :     return 0;
    6128              : }
    6129              : 
    6130              : /* Value should be nonzero if functions must have frame pointers.
    6131              :    Zero means the frame pointer need not be set up (and parms may
    6132              :    be accessed via the stack pointer) in functions that seem suitable.  */
    6133              : 
    6134              : static bool
    6135      1253249 : ix86_frame_pointer_required (void)
    6136              : {
    6137              :   /* If we accessed previous frames, then the generated code expects
    6138              :      to be able to access the saved ebp value in our frame.  */
    6139      1253249 :   if (cfun->machine->accesses_prev_frame)
    6140              :     return true;
    6141              : 
    6142              :   /* Several x86 os'es need a frame pointer for other reasons,
    6143              :      usually pertaining to setjmp.  */
    6144      1253216 :   if (SUBTARGET_FRAME_POINTER_REQUIRED)
    6145              :     return true;
    6146              : 
    6147              :   /* For older 32-bit runtimes setjmp requires valid frame-pointer.  */
    6148      1253216 :   if (TARGET_32BIT_MS_ABI && cfun->calls_setjmp)
    6149              :     return true;
    6150              : 
    6151              :   /* Win64 SEH, very large frames need a frame-pointer as maximum stack
    6152              :      allocation is 4GB.  */
    6153      1253216 :   if (TARGET_64BIT_MS_ABI && ix86_get_frame_size () > SEH_MAX_FRAME_SIZE)
    6154              :     return true;
    6155              : 
    6156              :   /* SSE saves require frame-pointer when stack is misaligned.  */
    6157      1253216 :   if (TARGET_64BIT_MS_ABI && ix86_incoming_stack_boundary < 128)
    6158              :     return true;
    6159              : 
    6160              :   /* In ix86_option_override_internal, TARGET_OMIT_LEAF_FRAME_POINTER
    6161              :      turns off the frame pointer by default.  Turn it back on now if
    6162              :      we've not got a leaf function.  */
    6163      1253215 :   if (TARGET_OMIT_LEAF_FRAME_POINTER
    6164      1253215 :       && (!crtl->is_leaf
    6165            0 :           || ix86_current_function_calls_tls_descriptor))
    6166              :     return true;
    6167              : 
    6168              :   /* Several versions of mcount for the x86 assumes that there is a
    6169              :      frame, so we cannot allow profiling without a frame pointer.  */
    6170      1253215 :   if (crtl->profile && !flag_fentry)
    6171           12 :     return true;
    6172              : 
    6173              :   return false;
    6174              : }
    6175              : 
    6176              : /* Record that the current function accesses previous call frames.  */
    6177              : 
    6178              : void
    6179          972 : ix86_setup_frame_addresses (void)
    6180              : {
    6181          972 :   cfun->machine->accesses_prev_frame = 1;
    6182          972 : }
    6183              : 
    6184              : #if defined(HAVE_GAS_HIDDEN) && (SUPPORTS_ONE_ONLY - 0)
    6185              : # define USE_HIDDEN_LINKONCE 1
    6186              : #else
    6187              : # define USE_HIDDEN_LINKONCE 0
    6188              : #endif
    6189              : 
    6190              : /* Label count for call and return thunks.  It is used to make unique
    6191              :    labels in call and return thunks.  */
    6192              : static int indirectlabelno;
    6193              : 
    6194              : /* True if call thunk function is needed.  */
    6195              : static bool indirect_thunk_needed = false;
    6196              : 
    6197              : /* Bit masks of integer registers, which contain branch target, used
    6198              :    by call thunk functions.  */
    6199              : static HARD_REG_SET indirect_thunks_used;
    6200              : 
    6201              : /* True if return thunk function is needed.  */
    6202              : static bool indirect_return_needed = false;
    6203              : 
    6204              : /* True if return thunk function via CX is needed.  */
    6205              : static bool indirect_return_via_cx;
    6206              : 
    6207              : #ifndef INDIRECT_LABEL
    6208              : # define INDIRECT_LABEL "LIND"
    6209              : #endif
    6210              : 
    6211              : /* Indicate what prefix is needed for an indirect branch.  */
    6212              : enum indirect_thunk_prefix
    6213              : {
    6214              :   indirect_thunk_prefix_none,
    6215              :   indirect_thunk_prefix_nt
    6216              : };
    6217              : 
    6218              : /* Return the prefix needed for an indirect branch INSN.  */
    6219              : 
    6220              : enum indirect_thunk_prefix
    6221           67 : indirect_thunk_need_prefix (rtx_insn *insn)
    6222              : {
    6223           67 :   enum indirect_thunk_prefix need_prefix;
    6224           67 :   if ((cfun->machine->indirect_branch_type
    6225           67 :             == indirect_branch_thunk_extern)
    6226           67 :            && ix86_notrack_prefixed_insn_p (insn))
    6227              :     {
    6228              :       /* NOTRACK prefix is only used with external thunk so that it
    6229              :          can be properly updated to support CET at run-time.  */
    6230              :       need_prefix = indirect_thunk_prefix_nt;
    6231              :     }
    6232              :   else
    6233              :     need_prefix = indirect_thunk_prefix_none;
    6234           67 :   return need_prefix;
    6235              : }
    6236              : 
    6237              : /* Fills in the label name that should be used for the indirect thunk.  */
    6238              : 
    6239              : static void
    6240           73 : indirect_thunk_name (char name[32], unsigned int regno,
    6241              :                      enum indirect_thunk_prefix need_prefix,
    6242              :                      bool ret_p)
    6243              : {
    6244           73 :   if (regno != INVALID_REGNUM && regno != CX_REG && ret_p)
    6245            0 :     gcc_unreachable ();
    6246              : 
    6247           73 :   if (USE_HIDDEN_LINKONCE)
    6248              :     {
    6249           73 :       const char *prefix;
    6250              : 
    6251           73 :       if (need_prefix == indirect_thunk_prefix_nt
    6252           73 :           && regno != INVALID_REGNUM)
    6253              :         {
    6254              :           /* NOTRACK prefix is only used with external thunk via
    6255              :              register so that NOTRACK prefix can be added to indirect
    6256              :              branch via register to support CET at run-time.  */
    6257              :           prefix = "_nt";
    6258              :         }
    6259              :       else
    6260           71 :         prefix = "";
    6261              : 
    6262           73 :       const char *ret = ret_p ? "return" : "indirect";
    6263              : 
    6264           73 :       if (regno != INVALID_REGNUM)
    6265              :         {
    6266           55 :           const char *reg_prefix;
    6267           55 :           if (LEGACY_INT_REGNO_P (regno))
    6268           53 :             reg_prefix = TARGET_64BIT ? "r" : "e";
    6269              :           else
    6270              :             reg_prefix = "";
    6271           55 :           sprintf (name, "__x86_%s_thunk%s_%s%s",
    6272              :                    ret, prefix, reg_prefix, reg_names[regno]);
    6273              :         }
    6274              :       else
    6275           18 :         sprintf (name, "__x86_%s_thunk%s", ret, prefix);
    6276              :     }
    6277              :   else
    6278              :     {
    6279              :       if (regno != INVALID_REGNUM)
    6280              :         ASM_GENERATE_INTERNAL_LABEL (name, "LITR", regno);
    6281              :       else
    6282              :         {
    6283              :           if (ret_p)
    6284              :             ASM_GENERATE_INTERNAL_LABEL (name, "LRT", 0);
    6285              :           else
    6286           73 :             ASM_GENERATE_INTERNAL_LABEL (name, "LIT", 0);
    6287              :         }
    6288              :     }
    6289           73 : }
    6290              : 
    6291              : /* Output a call and return thunk for indirect branch.  If REGNO != -1,
    6292              :    the function address is in REGNO and the call and return thunk looks like:
    6293              : 
    6294              :         call    L2
    6295              :    L1:
    6296              :         pause
    6297              :         lfence
    6298              :         jmp     L1
    6299              :    L2:
    6300              :         mov     %REG, (%sp)
    6301              :         ret
    6302              : 
    6303              :    Otherwise, the function address is on the top of stack and the
    6304              :    call and return thunk looks like:
    6305              : 
    6306              :         call L2
    6307              :   L1:
    6308              :         pause
    6309              :         lfence
    6310              :         jmp L1
    6311              :   L2:
    6312              :         lea WORD_SIZE(%sp), %sp
    6313              :         ret
    6314              :  */
    6315              : 
    6316              : static void
    6317           38 : output_indirect_thunk (unsigned int regno)
    6318              : {
    6319           38 :   char indirectlabel1[32];
    6320           38 :   char indirectlabel2[32];
    6321              : 
    6322           38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel1, INDIRECT_LABEL,
    6323              :                                indirectlabelno++);
    6324           38 :   ASM_GENERATE_INTERNAL_LABEL (indirectlabel2, INDIRECT_LABEL,
    6325              :                                indirectlabelno++);
    6326              : 
    6327              :   /* Call */
    6328           38 :   fputs ("\tcall\t", asm_out_file);
    6329           38 :   assemble_name_raw (asm_out_file, indirectlabel2);
    6330           38 :   fputc ('\n', asm_out_file);
    6331              : 
    6332           38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
    6333              : 
    6334              :   /* AMD and Intel CPUs prefer each a different instruction as loop filler.
    6335              :      Usage of both pause + lfence is compromise solution.  */
    6336           38 :   fprintf (asm_out_file, "\tpause\n\tlfence\n");
    6337              : 
    6338              :   /* Jump.  */
    6339           38 :   fputs ("\tjmp\t", asm_out_file);
    6340           38 :   assemble_name_raw (asm_out_file, indirectlabel1);
    6341           38 :   fputc ('\n', asm_out_file);
    6342              : 
    6343           38 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
    6344              : 
    6345              :   /* The above call insn pushed a word to stack.  Adjust CFI info.  */
    6346           38 :   if (flag_asynchronous_unwind_tables && dwarf2out_do_frame ())
    6347              :     {
    6348           38 :       if (! dwarf2out_do_cfi_asm ())
    6349              :         {
    6350            0 :           dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6351            0 :           xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
    6352            0 :           xcfi->dw_cfi_oprnd1.dw_cfi_addr = ggc_strdup (indirectlabel2);
    6353            0 :           vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6354              :         }
    6355           38 :       dw_cfi_ref xcfi = ggc_cleared_alloc<dw_cfi_node> ();
    6356           38 :       xcfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
    6357           38 :       xcfi->dw_cfi_oprnd1.dw_cfi_offset = 2 * UNITS_PER_WORD;
    6358           38 :       vec_safe_push (cfun->fde->dw_fde_cfi, xcfi);
    6359           38 :       dwarf2out_emit_cfi (xcfi);
    6360              :     }
    6361              : 
    6362           38 :   if (regno != INVALID_REGNUM)
    6363              :     {
    6364              :       /* MOV.  */
    6365           27 :       rtx xops[2];
    6366           27 :       xops[0] = gen_rtx_MEM (word_mode, stack_pointer_rtx);
    6367           27 :       xops[1] = gen_rtx_REG (word_mode, regno);
    6368           27 :       output_asm_insn ("mov\t{%1, %0|%0, %1}", xops);
    6369              :     }
    6370              :   else
    6371              :     {
    6372              :       /* LEA.  */
    6373           11 :       rtx xops[2];
    6374           11 :       xops[0] = stack_pointer_rtx;
    6375           11 :       xops[1] = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    6376           11 :       output_asm_insn ("lea\t{%E1, %0|%0, %E1}", xops);
    6377              :     }
    6378              : 
    6379           38 :   fputs ("\tret\n", asm_out_file);
    6380           38 :   if ((ix86_harden_sls & harden_sls_return))
    6381            1 :     fputs ("\tint3\n", asm_out_file);
    6382           38 : }
    6383              : 
    6384              : /* Output a function with a call and return thunk for indirect branch.
    6385              :    If REGNO != INVALID_REGNUM, the function address is in REGNO.
    6386              :    Otherwise, the function address is on the top of stack.  Thunk is
    6387              :    used for function return if RET_P is true.  */
    6388              : 
    6389              : static void
    6390           22 : output_indirect_thunk_function (enum indirect_thunk_prefix need_prefix,
    6391              :                                 unsigned int regno, bool ret_p)
    6392              : {
    6393           22 :   char name[32];
    6394           22 :   tree decl;
    6395              : 
    6396              :   /* Create __x86_indirect_thunk.  */
    6397           22 :   indirect_thunk_name (name, regno, need_prefix, ret_p);
    6398           22 :   decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6399              :                      get_identifier (name),
    6400              :                      build_function_type_list (void_type_node, NULL_TREE));
    6401           22 :   DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6402              :                                    NULL_TREE, void_type_node);
    6403           22 :   TREE_PUBLIC (decl) = 1;
    6404           22 :   TREE_STATIC (decl) = 1;
    6405           22 :   DECL_IGNORED_P (decl) = 1;
    6406              : 
    6407              : #if TARGET_MACHO
    6408              :   if (TARGET_MACHO)
    6409              :     {
    6410              :       switch_to_section (darwin_sections[picbase_thunk_section]);
    6411              :       fputs ("\t.weak_definition\t", asm_out_file);
    6412              :       assemble_name (asm_out_file, name);
    6413              :       fputs ("\n\t.private_extern\t", asm_out_file);
    6414              :       assemble_name (asm_out_file, name);
    6415              :       putc ('\n', asm_out_file);
    6416              :       ASM_OUTPUT_LABEL (asm_out_file, name);
    6417              :       DECL_WEAK (decl) = 1;
    6418              :     }
    6419              :   else
    6420              : #endif
    6421           22 :     if (USE_HIDDEN_LINKONCE)
    6422              :       {
    6423           22 :         cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6424              : 
    6425           22 :         targetm.asm_out.unique_section (decl, 0);
    6426           22 :         switch_to_section (get_named_section (decl, NULL, 0));
    6427              : 
    6428           22 :         targetm.asm_out.globalize_label (asm_out_file, name);
    6429           22 :         fputs ("\t.hidden\t", asm_out_file);
    6430           22 :         assemble_name (asm_out_file, name);
    6431           22 :         putc ('\n', asm_out_file);
    6432           22 :         ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6433              :       }
    6434              :     else
    6435              :       {
    6436              :         switch_to_section (text_section);
    6437           22 :         ASM_OUTPUT_LABEL (asm_out_file, name);
    6438              :       }
    6439              : 
    6440           22 :   DECL_INITIAL (decl) = make_node (BLOCK);
    6441           22 :   current_function_decl = decl;
    6442           22 :   allocate_struct_function (decl, false);
    6443           22 :   init_function_start (decl);
    6444              :   /* We're about to hide the function body from callees of final_* by
    6445              :      emitting it directly; tell them we're a thunk, if they care.  */
    6446           22 :   cfun->is_thunk = true;
    6447           22 :   first_function_block_is_cold = false;
    6448              :   /* Make sure unwind info is emitted for the thunk if needed.  */
    6449           22 :   final_start_function (emit_barrier (), asm_out_file, 1);
    6450              : 
    6451           22 :   output_indirect_thunk (regno);
    6452              : 
    6453           22 :   final_end_function ();
    6454           22 :   init_insn_lengths ();
    6455           22 :   free_after_compilation (cfun);
    6456           22 :   set_cfun (NULL);
    6457           22 :   current_function_decl = NULL;
    6458           22 : }
    6459              : 
    6460              : static int pic_labels_used;
    6461              : 
    6462              : /* Fills in the label name that should be used for a pc thunk for
    6463              :    the given register.  */
    6464              : 
    6465              : static void
    6466        37558 : get_pc_thunk_name (char name[32], unsigned int regno)
    6467              : {
    6468        37558 :   gcc_assert (!TARGET_64BIT);
    6469              : 
    6470        37558 :   if (USE_HIDDEN_LINKONCE)
    6471        37558 :     sprintf (name, "__x86.get_pc_thunk.%s", reg_names[regno]);
    6472              :   else
    6473        37558 :     ASM_GENERATE_INTERNAL_LABEL (name, "LPR", regno);
    6474        37558 : }
    6475              : 
    6476              : 
    6477              : /* This function generates code for -fpic that loads %ebx with
    6478              :    the return address of the caller and then returns.  */
    6479              : 
    6480              : static void
    6481       238343 : ix86_code_end (void)
    6482              : {
    6483       238343 :   rtx xops[2];
    6484       238343 :   unsigned int regno;
    6485              : 
    6486       238343 :   if (indirect_return_needed)
    6487            6 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6488              :                                     INVALID_REGNUM, true);
    6489       238343 :   if (indirect_return_via_cx)
    6490            0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6491              :                                     CX_REG, true);
    6492       238343 :   if (indirect_thunk_needed)
    6493            0 :     output_indirect_thunk_function (indirect_thunk_prefix_none,
    6494              :                                     INVALID_REGNUM, false);
    6495              : 
    6496      2145087 :   for (regno = FIRST_REX_INT_REG; regno <= LAST_REX_INT_REG; regno++)
    6497              :     {
    6498      1906744 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6499            0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6500              :                                         regno, false);
    6501              :     }
    6502              : 
    6503      4051831 :   for (regno = FIRST_REX2_INT_REG; regno <= LAST_REX2_INT_REG; regno++)
    6504              :     {
    6505      3813488 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6506            0 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6507              :                                         regno, false);
    6508              :     }
    6509              : 
    6510      2145087 :   for (regno = FIRST_INT_REG; regno <= LAST_INT_REG; regno++)
    6511              :     {
    6512      1906744 :       char name[32];
    6513      1906744 :       tree decl;
    6514              : 
    6515      1906744 :       if (TEST_HARD_REG_BIT (indirect_thunks_used, regno))
    6516           16 :         output_indirect_thunk_function (indirect_thunk_prefix_none,
    6517              :                                         regno, false);
    6518              : 
    6519      1906744 :       if (!(pic_labels_used & (1 << regno)))
    6520      1903104 :         continue;
    6521              : 
    6522         3640 :       get_pc_thunk_name (name, regno);
    6523              : 
    6524         3640 :       decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
    6525              :                          get_identifier (name),
    6526              :                          build_function_type_list (void_type_node, NULL_TREE));
    6527         3640 :       DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
    6528              :                                        NULL_TREE, void_type_node);
    6529         3640 :       TREE_PUBLIC (decl) = 1;
    6530         3640 :       TREE_STATIC (decl) = 1;
    6531         3640 :       DECL_IGNORED_P (decl) = 1;
    6532              : 
    6533              : #if TARGET_MACHO
    6534              :       if (TARGET_MACHO)
    6535              :         {
    6536              :           switch_to_section (darwin_sections[picbase_thunk_section]);
    6537              :           fputs ("\t.weak_definition\t", asm_out_file);
    6538              :           assemble_name (asm_out_file, name);
    6539              :           fputs ("\n\t.private_extern\t", asm_out_file);
    6540              :           assemble_name (asm_out_file, name);
    6541              :           putc ('\n', asm_out_file);
    6542              :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6543              :           DECL_WEAK (decl) = 1;
    6544              :         }
    6545              :       else
    6546              : #endif
    6547         3640 :       if (USE_HIDDEN_LINKONCE)
    6548              :         {
    6549         3640 :           cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
    6550              : 
    6551         3640 :           targetm.asm_out.unique_section (decl, 0);
    6552         3640 :           switch_to_section (get_named_section (decl, NULL, 0));
    6553              : 
    6554         3640 :           targetm.asm_out.globalize_label (asm_out_file, name);
    6555         3640 :           fputs ("\t.hidden\t", asm_out_file);
    6556         3640 :           assemble_name (asm_out_file, name);
    6557         3640 :           putc ('\n', asm_out_file);
    6558         3640 :           ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
    6559              :         }
    6560              :       else
    6561              :         {
    6562              :           switch_to_section (text_section);
    6563         3640 :           ASM_OUTPUT_LABEL (asm_out_file, name);
    6564              :         }
    6565              : 
    6566         3640 :       DECL_INITIAL (decl) = make_node (BLOCK);
    6567         3640 :       current_function_decl = decl;
    6568         3640 :       allocate_struct_function (decl, false);
    6569         3640 :       init_function_start (decl);
    6570              :       /* We're about to hide the function body from callees of final_* by
    6571              :          emitting it directly; tell them we're a thunk, if they care.  */
    6572         3640 :       cfun->is_thunk = true;
    6573         3640 :       first_function_block_is_cold = false;
    6574              :       /* Make sure unwind info is emitted for the thunk if needed.  */
    6575         3640 :       final_start_function (emit_barrier (), asm_out_file, 1);
    6576              : 
    6577              :       /* Pad stack IP move with 4 instructions (two NOPs count
    6578              :          as one instruction).  */
    6579         3640 :       if (TARGET_PAD_SHORT_FUNCTION)
    6580              :         {
    6581              :           int i = 8;
    6582              : 
    6583            0 :           while (i--)
    6584            0 :             fputs ("\tnop\n", asm_out_file);
    6585              :         }
    6586              : 
    6587         7280 :       xops[0] = gen_rtx_REG (Pmode, regno);
    6588         7280 :       xops[1] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
    6589         3640 :       output_asm_insn ("mov%z0\t{%1, %0|%0, %1}", xops);
    6590         3640 :       fputs ("\tret\n", asm_out_file);
    6591         3640 :       final_end_function ();
    6592         3640 :       init_insn_lengths ();
    6593         3640 :       free_after_compilation (cfun);
    6594         3640 :       set_cfun (NULL);
    6595         3640 :       current_function_decl = NULL;
    6596              :     }
    6597              : 
    6598       238343 :   if (flag_split_stack)
    6599         4712 :     file_end_indicate_split_stack ();
    6600       238343 : }
    6601              : 
    6602              : /* Emit code for the SET_GOT patterns.  */
    6603              : 
    6604              : const char *
    6605        33918 : output_set_got (rtx dest, rtx label)
    6606              : {
    6607        33918 :   rtx xops[3];
    6608              : 
    6609        33918 :   xops[0] = dest;
    6610              : 
    6611        33918 :   if (TARGET_VXWORKS_GOTTPIC && TARGET_VXWORKS_RTP && flag_pic)
    6612              :     {
    6613              :       /* Load (*VXWORKS_GOTT_BASE) into the PIC register.  */
    6614              :       xops[2] = gen_rtx_MEM (Pmode,
    6615              :                              gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE));
    6616              :       output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
    6617              : 
    6618              :       /* Load (*VXWORKS_GOTT_BASE)[VXWORKS_GOTT_INDEX] into the PIC register.
    6619              :          Use %P and a local symbol in order to print VXWORKS_GOTT_INDEX as
    6620              :          an unadorned address.  */
    6621              :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
    6622              :       SYMBOL_REF_FLAGS (xops[2]) |= SYMBOL_FLAG_LOCAL;
    6623              :       output_asm_insn ("mov{l}\t{%P2(%0), %0|%0, DWORD PTR %P2[%0]}", xops);
    6624              :       return "";
    6625              :     }
    6626              : 
    6627        67836 :   xops[1] = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
    6628              : 
    6629        33918 :   if (flag_pic)
    6630              :     {
    6631        33918 :       char name[32];
    6632        33918 :       get_pc_thunk_name (name, REGNO (dest));
    6633        33918 :       pic_labels_used |= 1 << REGNO (dest);
    6634              : 
    6635        67836 :       xops[2] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
    6636        33918 :       xops[2] = gen_rtx_MEM (QImode, xops[2]);
    6637        33918 :       output_asm_insn ("%!call\t%X2", xops);
    6638              : 
    6639              : #if TARGET_MACHO
    6640              :       /* Output the Mach-O "canonical" pic base label name ("Lxx$pb") here.
    6641              :          This is what will be referenced by the Mach-O PIC subsystem.  */
    6642              :       if (machopic_should_output_picbase_label () || !label)
    6643              :         ASM_OUTPUT_LABEL (asm_out_file, MACHOPIC_FUNCTION_BASE_NAME);
    6644              : 
    6645              :       /* When we are restoring the pic base at the site of a nonlocal label,
    6646              :          and we decided to emit the pic base above, we will still output a
    6647              :          local label used for calculating the correction offset (even though
    6648              :          the offset will be 0 in that case).  */
    6649              :       if (label)
    6650              :         targetm.asm_out.internal_label (asm_out_file, "L",
    6651              :                                            CODE_LABEL_NUMBER (label));
    6652              : #endif
    6653              :     }
    6654              :   else
    6655              :     {
    6656            0 :       if (TARGET_MACHO)
    6657              :         /* We don't need a pic base, we're not producing pic.  */
    6658              :         gcc_unreachable ();
    6659              : 
    6660            0 :       xops[2] = gen_rtx_LABEL_REF (Pmode, label ? label : gen_label_rtx ());
    6661            0 :       output_asm_insn ("mov%z0\t{%2, %0|%0, %2}", xops);
    6662            0 :       targetm.asm_out.internal_label (asm_out_file, "L",
    6663            0 :                                       CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
    6664              :     }
    6665              : 
    6666        33918 :   if (!TARGET_MACHO)
    6667        33918 :     output_asm_insn ("add%z0\t{%1, %0|%0, %1}", xops);
    6668              : 
    6669        33918 :   return "";
    6670              : }
    6671              : 
    6672              : /* Generate an "push" pattern for input ARG.  */
    6673              : 
    6674              : rtx
    6675      1932249 : gen_push (rtx arg, bool ppx_p)
    6676              : {
    6677      1932249 :   struct machine_function *m = cfun->machine;
    6678              : 
    6679      1932249 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6680      1656406 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6681      1932249 :   m->fs.sp_offset += UNITS_PER_WORD;
    6682              : 
    6683      1932249 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6684           26 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6685              : 
    6686      1932249 :   rtx stack = gen_rtx_MEM (word_mode,
    6687      1932249 :                            gen_rtx_PRE_DEC (Pmode,
    6688              :                                             stack_pointer_rtx));
    6689      3864409 :   return ppx_p ? gen_pushp_di (stack, arg) : gen_rtx_SET (stack, arg);
    6690              : }
    6691              : 
    6692              : rtx
    6693           21 : gen_pushfl (void)
    6694              : {
    6695           21 :   struct machine_function *m = cfun->machine;
    6696           21 :   rtx flags, mem;
    6697              : 
    6698           21 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6699            0 :     m->fs.cfa_offset += UNITS_PER_WORD;
    6700           21 :   m->fs.sp_offset += UNITS_PER_WORD;
    6701              : 
    6702           21 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6703              : 
    6704           21 :   mem = gen_rtx_MEM (word_mode,
    6705           21 :                      gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
    6706              : 
    6707           21 :   return gen_pushfl2 (word_mode, mem, flags);
    6708              : }
    6709              : 
    6710              : /* Generate an "pop" pattern for input ARG.  */
    6711              : 
    6712              : rtx
    6713      1509902 : gen_pop (rtx arg, bool ppx_p)
    6714              : {
    6715      1509902 :   if (REG_P (arg) && GET_MODE (arg) != word_mode)
    6716           22 :     arg = gen_rtx_REG (word_mode, REGNO (arg));
    6717              : 
    6718      1509902 :   rtx stack = gen_rtx_MEM (word_mode,
    6719      1509902 :                            gen_rtx_POST_INC (Pmode,
    6720              :                                              stack_pointer_rtx));
    6721              : 
    6722      3019715 :   return ppx_p ? gen_popp_di (arg, stack) : gen_rtx_SET (arg, stack);
    6723              : }
    6724              : 
    6725              : rtx
    6726           21 : gen_popfl (void)
    6727              : {
    6728           21 :   rtx flags, mem;
    6729              : 
    6730           21 :   flags = gen_rtx_REG (CCmode, FLAGS_REG);
    6731              : 
    6732           21 :   mem = gen_rtx_MEM (word_mode,
    6733           21 :                      gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
    6734              : 
    6735           21 :   return gen_popfl1 (word_mode, flags, mem);
    6736              : }
    6737              : 
    6738              : /* Generate a "push2" pattern for input ARG.  */
    6739              : rtx
    6740           19 : gen_push2 (rtx mem, rtx reg1, rtx reg2, bool ppx_p = false)
    6741              : {
    6742           19 :   struct machine_function *m = cfun->machine;
    6743           19 :   const int offset = UNITS_PER_WORD * 2;
    6744              : 
    6745           19 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    6746           14 :     m->fs.cfa_offset += offset;
    6747           19 :   m->fs.sp_offset += offset;
    6748              : 
    6749           19 :   if (REG_P (reg1) && GET_MODE (reg1) != word_mode)
    6750            0 :     reg1 = gen_rtx_REG (word_mode, REGNO (reg1));
    6751              : 
    6752           19 :   if (REG_P (reg2) && GET_MODE (reg2) != word_mode)
    6753            0 :     reg2 = gen_rtx_REG (word_mode, REGNO (reg2));
    6754              : 
    6755           19 :   return ppx_p ? gen_push2p_di (mem, reg1, reg2)
    6756            4 :                : gen_push2_di (mem, reg1, reg2);
    6757              : }
    6758              : 
    6759              : /* Return >= 0 if there is an unused call-clobbered register available
    6760              :    for the entire function.  */
    6761              : 
    6762              : static unsigned int
    6763            0 : ix86_select_alt_pic_regnum (void)
    6764              : {
    6765            0 :   if (ix86_use_pseudo_pic_reg ())
    6766              :     return INVALID_REGNUM;
    6767              : 
    6768            0 :   if (crtl->is_leaf
    6769            0 :       && !crtl->profile
    6770            0 :       && !ix86_current_function_calls_tls_descriptor)
    6771              :     {
    6772            0 :       int i, drap;
    6773              :       /* Can't use the same register for both PIC and DRAP.  */
    6774            0 :       if (crtl->drap_reg)
    6775            0 :         drap = REGNO (crtl->drap_reg);
    6776              :       else
    6777              :         drap = -1;
    6778            0 :       for (i = 2; i >= 0; --i)
    6779            0 :         if (i != drap && !df_regs_ever_live_p (i))
    6780              :           return i;
    6781              :     }
    6782              : 
    6783              :   return INVALID_REGNUM;
    6784              : }
    6785              : 
    6786              : /* Return true if REGNO is used by the epilogue.  */
    6787              : 
    6788              : bool
    6789   1746145460 : ix86_epilogue_uses (int regno)
    6790              : {
    6791              :   /* If there are no caller-saved registers, we preserve all registers,
    6792              :      except for MMX and x87 registers which aren't supported when saving
    6793              :      and restoring registers.  Don't explicitly save SP register since
    6794              :      it is always preserved.  */
    6795   1746145460 :   return (epilogue_completed
    6796    275120084 :           && (cfun->machine->call_saved_registers
    6797    275120084 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    6798        29986 :           && !fixed_regs[regno]
    6799         5441 :           && !STACK_REGNO_P (regno)
    6800   1746150901 :           && !MMX_REGNO_P (regno));
    6801              : }
    6802              : 
    6803              : /* Return nonzero if register REGNO can be used as a scratch register
    6804              :    in peephole2.  */
    6805              : 
    6806              : static bool
    6807      1329901 : ix86_hard_regno_scratch_ok (unsigned int regno)
    6808              : {
    6809              :   /* If there are no caller-saved registers, we can't use any register
    6810              :      as a scratch register after epilogue and use REGNO as scratch
    6811              :      register only if it has been used before to avoid saving and
    6812              :      restoring it.  */
    6813      1329901 :   return ((cfun->machine->call_saved_registers
    6814      1329901 :            != TYPE_NO_CALLER_SAVED_REGISTERS)
    6815      1329901 :           || (!epilogue_completed
    6816            0 :               && df_regs_ever_live_p (regno)));
    6817              : }
    6818              : 
    6819              : /* Return TRUE if we need to save REGNO.  */
    6820              : 
    6821              : bool
    6822    361983702 : ix86_save_reg (unsigned int regno, bool maybe_eh_return, bool ignore_outlined)
    6823              : {
    6824              :   /* Save and restore DRAP register between prologue and epilogue so
    6825              :      that stack pointer can be restored.  */
    6826    361983702 :   if (crtl->drap_reg
    6827      2267366 :       && regno == REGNO (crtl->drap_reg)
    6828    362038760 :       && !cfun->machine->no_drap_save_restore)
    6829              :     return true;
    6830              : 
    6831              :   /* ??? Treat no_callee_saved_registers as a special case in order
    6832              :      to cope with -mnoreturn-no-callee-saved-registers, which is not
    6833              :      reflected in crtl->abi.  */
    6834    361928644 :   if (cfun->machine->call_saved_registers == TYPE_NO_CALLEE_SAVED_REGISTERS
    6835        16312 :       && regno != HARD_FRAME_POINTER_REGNUM)
    6836              :     return false;
    6837              : 
    6838    395915439 :   if (regno == REAL_PIC_OFFSET_TABLE_REGNUM
    6839     11021027 :       && pic_offset_table_rtx)
    6840              :     {
    6841       386091 :       if (ix86_use_pseudo_pic_reg ())
    6842              :         {
    6843              :           /* REAL_PIC_OFFSET_TABLE_REGNUM used by call to
    6844              :           _mcount in prologue.  */
    6845       386091 :           if (!TARGET_64BIT && flag_pic && crtl->profile)
    6846              :             return true;
    6847              :         }
    6848            0 :       else if (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM)
    6849            0 :                || crtl->profile
    6850            0 :                || crtl->calls_eh_return
    6851            0 :                || crtl->uses_const_pool
    6852            0 :                || cfun->has_nonlocal_label)
    6853            0 :         return ix86_select_alt_pic_regnum () == INVALID_REGNUM;
    6854              :     }
    6855              : 
    6856    361912822 :   if (crtl->calls_eh_return && maybe_eh_return)
    6857              :     {
    6858              :       unsigned i;
    6859        13237 :       for (i = 0; ; i++)
    6860              :         {
    6861        20181 :           unsigned test = EH_RETURN_DATA_REGNO (i);
    6862        13671 :           if (test == INVALID_REGNUM)
    6863              :             break;
    6864        13671 :           if (test == regno)
    6865              :             return true;
    6866        13237 :         }
    6867              :     }
    6868              : 
    6869    361912388 :   if (ignore_outlined && cfun->machine->call_ms2sysv)
    6870              :     {
    6871      2642240 :       unsigned count = cfun->machine->call_ms2sysv_extra_regs
    6872              :                        + xlogue_layout::MIN_REGS;
    6873      2642240 :       if (xlogue_layout::is_stub_managed_reg (regno, count))
    6874              :         return false;
    6875              :     }
    6876              : 
    6877    361413295 :   return (df_regs_ever_live_p (regno)
    6878     68776292 :           && !fixed_regs[regno]
    6879     60731806 :           && !crtl->abi->clobbers_full_reg_p (regno)
    6880    380512483 :           && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed));
    6881              : }
    6882              : 
    6883              : /* Return number of saved general prupose registers.  */
    6884              : 
    6885              : static int
    6886      8371998 : ix86_nsaved_regs (void)
    6887              : {
    6888      8371998 :   int nregs = 0;
    6889      8371998 :   int regno;
    6890              : 
    6891    795339810 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6892    786967812 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6893      8403132 :       nregs ++;
    6894      8371998 :   return nregs;
    6895              : }
    6896              : 
    6897              : /* Return number of saved SSE registers.  */
    6898              : 
    6899              : static int
    6900      8407894 : ix86_nsaved_sseregs (void)
    6901              : {
    6902      8407894 :   int nregs = 0;
    6903      8407894 :   int regno;
    6904              : 
    6905      7605039 :   if (!TARGET_64BIT_MS_ABI
    6906      8407894 :       && (cfun->machine->call_saved_registers
    6907      8185497 :           != TYPE_NO_CALLER_SAVED_REGISTERS))
    6908              :     return 0;
    6909     21204570 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    6910     20981364 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    6911      1863843 :       nregs ++;
    6912              :   return nregs;
    6913              : }
    6914              : 
    6915              : /* Given FROM and TO register numbers, say whether this elimination is
    6916              :    allowed.  If stack alignment is needed, we can only replace argument
    6917              :    pointer with hard frame pointer, or replace frame pointer with stack
    6918              :    pointer.  Otherwise, frame pointer elimination is automatically
    6919              :    handled and all other eliminations are valid.  */
    6920              : 
    6921              : static bool
    6922     49585587 : ix86_can_eliminate (const int from, const int to)
    6923              : {
    6924     49585587 :   if (stack_realign_fp)
    6925      1732184 :     return ((from == ARG_POINTER_REGNUM
    6926      1732184 :              && to == HARD_FRAME_POINTER_REGNUM)
    6927      1732184 :             || (from == FRAME_POINTER_REGNUM
    6928      1299138 :                 && to == STACK_POINTER_REGNUM));
    6929              :   else
    6930     47853403 :     return to == STACK_POINTER_REGNUM ? !frame_pointer_needed : true;
    6931              : }
    6932              : 
    6933              : /* Return the offset between two registers, one to be eliminated, and the other
    6934              :    its replacement, at the start of a routine.  */
    6935              : 
    6936              : HOST_WIDE_INT
    6937    142167359 : ix86_initial_elimination_offset (int from, int to)
    6938              : {
    6939    142167359 :   struct ix86_frame &frame = cfun->machine->frame;
    6940              : 
    6941    142167359 :   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
    6942     10626858 :     return frame.hard_frame_pointer_offset;
    6943    131540501 :   else if (from == FRAME_POINTER_REGNUM
    6944    131540501 :            && to == HARD_FRAME_POINTER_REGNUM)
    6945      8335724 :     return frame.hard_frame_pointer_offset - frame.frame_pointer_offset;
    6946              :   else
    6947              :     {
    6948    123204777 :       gcc_assert (to == STACK_POINTER_REGNUM);
    6949              : 
    6950    123204777 :       if (from == ARG_POINTER_REGNUM)
    6951    114869053 :         return frame.stack_pointer_offset;
    6952              : 
    6953      8335724 :       gcc_assert (from == FRAME_POINTER_REGNUM);
    6954      8335724 :       return frame.stack_pointer_offset - frame.frame_pointer_offset;
    6955              :     }
    6956              : }
    6957              : 
    6958              : /* Emits a warning for unsupported msabi to sysv pro/epilogues.  */
    6959              : void
    6960            0 : warn_once_call_ms2sysv_xlogues (const char *feature)
    6961              : {
    6962            0 :   static bool warned_once = false;
    6963            0 :   if (!warned_once)
    6964              :     {
    6965            0 :       warning (0, "%<-mcall-ms2sysv-xlogues%> is not compatible with %s",
    6966              :                feature);
    6967            0 :       warned_once = true;
    6968              :     }
    6969            0 : }
    6970              : 
    6971              : /* Return the probing interval for -fstack-clash-protection.  */
    6972              : 
    6973              : static HOST_WIDE_INT
    6974          494 : get_probe_interval (void)
    6975              : {
    6976          341 :   if (flag_stack_clash_protection)
    6977          412 :     return (HOST_WIDE_INT_1U
    6978          412 :             << param_stack_clash_protection_probe_interval);
    6979              :   else
    6980              :     return (HOST_WIDE_INT_1U << STACK_CHECK_PROBE_INTERVAL_EXP);
    6981              : }
    6982              : 
    6983              : /* When using -fsplit-stack, the allocation routines set a field in
    6984              :    the TCB to the bottom of the stack plus this much space, measured
    6985              :    in bytes.  */
    6986              : 
    6987              : #define SPLIT_STACK_AVAILABLE 256
    6988              : 
    6989              : /* Return true if push2/pop2 can be generated.  */
    6990              : 
    6991              : static bool
    6992      8372667 : ix86_can_use_push2pop2 (void)
    6993              : {
    6994              :   /* Use push2/pop2 only if the incoming stack is 16-byte aligned.  */
    6995      8372667 :   unsigned int incoming_stack_boundary
    6996      8372667 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    6997      8372667 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    6998      8372667 :   return incoming_stack_boundary % 128 == 0;
    6999              : }
    7000              : 
    7001              : /* Helper function to determine whether push2/pop2 can be used in prologue or
    7002              :    epilogue for register save/restore.  */
    7003              : static bool
    7004      8371998 : ix86_pro_and_epilogue_can_use_push2pop2 (int nregs)
    7005              : {
    7006      8371998 :   if (!ix86_can_use_push2pop2 ())
    7007              :     return false;
    7008      8336030 :   int aligned = cfun->machine->fs.sp_offset % 16 == 0;
    7009      8336030 :   return TARGET_APX_PUSH2POP2
    7010         2912 :          && !cfun->machine->frame.save_regs_using_mov
    7011         2900 :          && cfun->machine->func_type == TYPE_NORMAL
    7012      8338922 :          && (nregs + aligned) >= 3;
    7013              : }
    7014              : 
    7015              : /* Check if push/pop should be used to save/restore registers.  */
    7016              : static bool
    7017      9119339 : save_regs_using_push_pop (HOST_WIDE_INT to_allocate)
    7018              : {
    7019      3288100 :   return ((!to_allocate && cfun->machine->frame.nregs <= 1)
    7020      6082099 :           || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000))
    7021              :           /* If static stack checking is enabled and done with probes,
    7022              :              the registers need to be saved before allocating the frame.  */
    7023      6081438 :           || flag_stack_check == STATIC_BUILTIN_STACK_CHECK
    7024              :           /* If stack clash probing needs a loop, then it needs a
    7025              :              scratch register.  But the returned register is only guaranteed
    7026              :              to be safe to use after register saves are complete.  So if
    7027              :              stack clash protections are enabled and the allocated frame is
    7028              :              larger than the probe interval, then use pushes to save
    7029              :              callee saved registers.  */
    7030     15200703 :           || (flag_stack_clash_protection
    7031          341 :               && !ix86_target_stack_probe ()
    7032          341 :               && to_allocate > get_probe_interval ()));
    7033              : }
    7034              : 
    7035              : /* Fill structure ix86_frame about frame of currently computed function.  */
    7036              : 
    7037              : static void
    7038      8371998 : ix86_compute_frame_layout (void)
    7039              : {
    7040      8371998 :   struct ix86_frame *frame = &cfun->machine->frame;
    7041      8371998 :   struct machine_function *m = cfun->machine;
    7042      8371998 :   unsigned HOST_WIDE_INT stack_alignment_needed;
    7043      8371998 :   HOST_WIDE_INT offset;
    7044      8371998 :   unsigned HOST_WIDE_INT preferred_alignment;
    7045      8371998 :   HOST_WIDE_INT size = ix86_get_frame_size ();
    7046      8371998 :   HOST_WIDE_INT to_allocate;
    7047              : 
    7048              :   /* m->call_ms2sysv is initially enabled in ix86_expand_call for all 64-bit
    7049              :    * ms_abi functions that call a sysv function.  We now need to prune away
    7050              :    * cases where it should be disabled.  */
    7051      8371998 :   if (TARGET_64BIT && m->call_ms2sysv)
    7052              :     {
    7053        35225 :       gcc_assert (TARGET_64BIT_MS_ABI);
    7054        35225 :       gcc_assert (TARGET_CALL_MS2SYSV_XLOGUES);
    7055        35225 :       gcc_assert (!TARGET_SEH);
    7056        35225 :       gcc_assert (TARGET_SSE);
    7057        35225 :       gcc_assert (!ix86_using_red_zone ());
    7058              : 
    7059        35225 :       if (crtl->calls_eh_return)
    7060              :         {
    7061            0 :           gcc_assert (!reload_completed);
    7062            0 :           m->call_ms2sysv = false;
    7063            0 :           warn_once_call_ms2sysv_xlogues ("__builtin_eh_return");
    7064              :         }
    7065              : 
    7066        35225 :       else if (ix86_static_chain_on_stack)
    7067              :         {
    7068            0 :           gcc_assert (!reload_completed);
    7069            0 :           m->call_ms2sysv = false;
    7070            0 :           warn_once_call_ms2sysv_xlogues ("static call chains");
    7071              :         }
    7072              : 
    7073              :       /* Finally, compute which registers the stub will manage.  */
    7074              :       else
    7075              :         {
    7076        35225 :           unsigned count = xlogue_layout::count_stub_managed_regs ();
    7077        35225 :           m->call_ms2sysv_extra_regs = count - xlogue_layout::MIN_REGS;
    7078        35225 :           m->call_ms2sysv_pad_in = 0;
    7079              :         }
    7080              :     }
    7081              : 
    7082      8371998 :   frame->nregs = ix86_nsaved_regs ();
    7083      8371998 :   frame->nsseregs = ix86_nsaved_sseregs ();
    7084              : 
    7085              :   /* 64-bit MS ABI seem to require stack alignment to be always 16,
    7086              :      except for function prologues, leaf functions and when the default
    7087              :      incoming stack boundary is overridden at command line or via
    7088              :      force_align_arg_pointer attribute.
    7089              : 
    7090              :      Darwin's ABI specifies 128b alignment for both 32 and  64 bit variants
    7091              :      at call sites, including profile function calls.
    7092              : 
    7093              :      For APX push2/pop2, the stack also requires 128b alignment.  */
    7094      8371998 :   if ((ix86_pro_and_epilogue_can_use_push2pop2 (frame->nregs)
    7095           65 :        && crtl->preferred_stack_boundary < 128)
    7096      8372061 :       || (((TARGET_64BIT_MS_ABI || TARGET_MACHO)
    7097       222395 :            && crtl->preferred_stack_boundary < 128)
    7098            0 :           && (!crtl->is_leaf || cfun->calls_alloca != 0
    7099            0 :               || ix86_current_function_calls_tls_descriptor
    7100            0 :               || (TARGET_MACHO && crtl->profile)
    7101            0 :               || ix86_incoming_stack_boundary < 128)))
    7102              :     {
    7103            2 :       crtl->preferred_stack_boundary = 128;
    7104            2 :       if (crtl->stack_alignment_needed < 128)
    7105            1 :         crtl->stack_alignment_needed = 128;
    7106              :     }
    7107              : 
    7108      8371998 :   stack_alignment_needed = crtl->stack_alignment_needed / BITS_PER_UNIT;
    7109      8371998 :   preferred_alignment = crtl->preferred_stack_boundary / BITS_PER_UNIT;
    7110              : 
    7111      8371998 :   gcc_assert (!size || stack_alignment_needed);
    7112      9174824 :   gcc_assert (preferred_alignment >= STACK_BOUNDARY / BITS_PER_UNIT);
    7113      8371998 :   gcc_assert (preferred_alignment <= stack_alignment_needed);
    7114              : 
    7115              :   /* The only ABI saving SSE regs should be 64-bit ms_abi or with
    7116              :      no_caller_saved_registers attribute.  */
    7117      8371998 :   gcc_assert (TARGET_64BIT
    7118              :               || (cfun->machine->call_saved_registers
    7119              :                   == TYPE_NO_CALLER_SAVED_REGISTERS)
    7120              :               || !frame->nsseregs);
    7121      8371998 :   if (TARGET_64BIT && m->call_ms2sysv)
    7122              :     {
    7123        35225 :       gcc_assert (stack_alignment_needed >= 16);
    7124        35225 :       gcc_assert ((cfun->machine->call_saved_registers
    7125              :                    == TYPE_NO_CALLER_SAVED_REGISTERS)
    7126              :                   || !frame->nsseregs);
    7127              :     }
    7128              : 
    7129              :   /* For SEH we have to limit the amount of code movement into the prologue.
    7130              :      At present we do this via a BLOCKAGE, at which point there's very little
    7131              :      scheduling that can be done, which means that there's very little point
    7132              :      in doing anything except PUSHs.  */
    7133      8371998 :   if (TARGET_SEH)
    7134              :     m->use_fast_prologue_epilogue = false;
    7135      8371998 :   else if (!optimize_bb_for_size_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    7136              :     {
    7137      8031663 :       int count = frame->nregs;
    7138      8031663 :       struct cgraph_node *node = cgraph_node::get (current_function_decl);
    7139              : 
    7140              :       /* The fast prologue uses move instead of push to save registers.  This
    7141              :          is significantly longer, but also executes faster as modern hardware
    7142              :          can execute the moves in parallel, but can't do that for push/pop.
    7143              : 
    7144              :          Be careful about choosing what prologue to emit:  When function takes
    7145              :          many instructions to execute we may use slow version as well as in
    7146              :          case function is known to be outside hot spot (this is known with
    7147              :          feedback only).  Weight the size of function by number of registers
    7148              :          to save as it is cheap to use one or two push instructions but very
    7149              :          slow to use many of them.
    7150              : 
    7151              :          Calling this hook multiple times with the same frame requirements
    7152              :          must produce the same layout, since the RA might otherwise be
    7153              :          unable to reach a fixed point or might fail its final sanity checks.
    7154              :          This means that once we've assumed that a function does or doesn't
    7155              :          have a particular size, we have to stick to that assumption
    7156              :          regardless of how the function has changed since.  */
    7157      8031663 :       if (count)
    7158      2670022 :         count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
    7159      8031663 :       if (node->frequency < NODE_FREQUENCY_NORMAL
    7160      7325108 :           || (flag_branch_probabilities
    7161          971 :               && node->frequency < NODE_FREQUENCY_HOT))
    7162       706880 :         m->use_fast_prologue_epilogue = false;
    7163              :       else
    7164              :         {
    7165      7324783 :           if (count != frame->expensive_count)
    7166              :             {
    7167       293072 :               frame->expensive_count = count;
    7168       293072 :               frame->expensive_p = expensive_function_p (count);
    7169              :             }
    7170      7324783 :           m->use_fast_prologue_epilogue = !frame->expensive_p;
    7171              :         }
    7172              :     }
    7173              : 
    7174      8371998 :   frame->save_regs_using_mov
    7175      8371998 :     = TARGET_PROLOGUE_USING_MOVE && m->use_fast_prologue_epilogue;
    7176              : 
    7177              :   /* Skip return address and error code in exception handler.  */
    7178      8371998 :   offset = INCOMING_FRAME_SP_OFFSET;
    7179              : 
    7180              :   /* Skip pushed static chain.  */
    7181      8371998 :   if (ix86_static_chain_on_stack)
    7182            0 :     offset += UNITS_PER_WORD;
    7183              : 
    7184              :   /* Skip saved base pointer.  */
    7185      8371998 :   if (frame_pointer_needed)
    7186      2858241 :     offset += UNITS_PER_WORD;
    7187      8371998 :   frame->hfp_save_offset = offset;
    7188              : 
    7189              :   /* The traditional frame pointer location is at the top of the frame.  */
    7190      8371998 :   frame->hard_frame_pointer_offset = offset;
    7191              : 
    7192              :   /* Register save area */
    7193      8371998 :   offset += frame->nregs * UNITS_PER_WORD;
    7194      8371998 :   frame->reg_save_offset = offset;
    7195              : 
    7196              :   /* Calculate the size of the va-arg area (not including padding, if any).  */
    7197      8371998 :   frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
    7198              : 
    7199              :   /* Also adjust stack_realign_offset for the largest alignment of
    7200              :      stack slot actually used.  */
    7201      8371998 :   if (stack_realign_fp
    7202      8060711 :       || (cfun->machine->max_used_stack_alignment != 0
    7203          188 :           && (offset % cfun->machine->max_used_stack_alignment) != 0))
    7204              :     {
    7205              :       /* We may need a 16-byte aligned stack for the remainder of the
    7206              :          register save area, but the stack frame for the local function
    7207              :          may require a greater alignment if using AVX/2/512.  In order
    7208              :          to avoid wasting space, we first calculate the space needed for
    7209              :          the rest of the register saves, add that to the stack pointer,
    7210              :          and then realign the stack to the boundary of the start of the
    7211              :          frame for the local function.  */
    7212       311373 :       HOST_WIDE_INT space_needed = 0;
    7213       311373 :       HOST_WIDE_INT sse_reg_space_needed = 0;
    7214              : 
    7215       311373 :       if (TARGET_64BIT)
    7216              :         {
    7217       309546 :           if (m->call_ms2sysv)
    7218              :             {
    7219         6415 :               m->call_ms2sysv_pad_in = 0;
    7220         6415 :               space_needed = xlogue_layout::get_instance ().get_stack_space_used ();
    7221              :             }
    7222              : 
    7223       303131 :           else if (frame->nsseregs)
    7224              :             /* The only ABI that has saved SSE registers (Win64) also has a
    7225              :                16-byte aligned default stack.  However, many programs violate
    7226              :                the ABI, and Wine64 forces stack realignment to compensate.  */
    7227         6447 :             space_needed = frame->nsseregs * 16;
    7228              : 
    7229       309546 :           sse_reg_space_needed = space_needed = ROUND_UP (space_needed, 16);
    7230              : 
    7231              :           /* 64-bit frame->va_arg_size should always be a multiple of 16, but
    7232              :              rounding to be pedantic.  */
    7233       309546 :           space_needed = ROUND_UP (space_needed + frame->va_arg_size, 16);
    7234              :         }
    7235              :       else
    7236         1827 :         space_needed = frame->va_arg_size;
    7237              : 
    7238              :       /* Record the allocation size required prior to the realignment AND.  */
    7239       311373 :       frame->stack_realign_allocate = space_needed;
    7240              : 
    7241              :       /* The re-aligned stack starts at frame->stack_realign_offset.  Values
    7242              :          before this point are not directly comparable with values below
    7243              :          this point.  Use sp_valid_at to determine if the stack pointer is
    7244              :          valid for a given offset, fp_valid_at for the frame pointer, or
    7245              :          choose_baseaddr to have a base register chosen for you.
    7246              : 
    7247              :          Note that the result of (frame->stack_realign_offset
    7248              :          & (stack_alignment_needed - 1)) may not equal zero.  */
    7249       311373 :       offset = ROUND_UP (offset + space_needed, stack_alignment_needed);
    7250       311373 :       frame->stack_realign_offset = offset - space_needed;
    7251       311373 :       frame->sse_reg_save_offset = frame->stack_realign_offset
    7252       311373 :                                                         + sse_reg_space_needed;
    7253       311373 :     }
    7254              :   else
    7255              :     {
    7256      8060625 :       frame->stack_realign_offset = offset;
    7257              : 
    7258      8060625 :       if (TARGET_64BIT && m->call_ms2sysv)
    7259              :         {
    7260        28810 :           m->call_ms2sysv_pad_in = !!(offset & UNITS_PER_WORD);
    7261        28810 :           offset += xlogue_layout::get_instance ().get_stack_space_used ();
    7262              :         }
    7263              : 
    7264              :       /* Align and set SSE register save area.  */
    7265      8031815 :       else if (frame->nsseregs)
    7266              :         {
    7267              :           /* If the incoming stack boundary is at least 16 bytes, or DRAP is
    7268              :              required and the DRAP re-alignment boundary is at least 16 bytes,
    7269              :              then we want the SSE register save area properly aligned.  */
    7270       179934 :           if (ix86_incoming_stack_boundary >= 128
    7271         6400 :                   || (stack_realign_drap && stack_alignment_needed >= 16))
    7272       179934 :             offset = ROUND_UP (offset, 16);
    7273       179934 :           offset += frame->nsseregs * 16;
    7274              :         }
    7275      8060625 :       frame->sse_reg_save_offset = offset;
    7276      8060625 :       offset += frame->va_arg_size;
    7277              :     }
    7278              : 
    7279              :   /* Align start of frame for local function.  When a function call
    7280              :      is removed, it may become a leaf function.  But if argument may
    7281              :      be passed on stack, we need to align the stack when there is no
    7282              :      tail call.  */
    7283      8371998 :   if (m->call_ms2sysv
    7284      8336773 :       || frame->va_arg_size != 0
    7285      8257295 :       || size != 0
    7286      4489129 :       || !crtl->is_leaf
    7287      2104694 :       || (!crtl->tail_call_emit
    7288      1778088 :           && cfun->machine->outgoing_args_on_stack)
    7289      2104644 :       || cfun->calls_alloca
    7290     10474918 :       || ix86_current_function_calls_tls_descriptor)
    7291      6269498 :     offset = ROUND_UP (offset, stack_alignment_needed);
    7292              : 
    7293              :   /* Frame pointer points here.  */
    7294      8371998 :   frame->frame_pointer_offset = offset;
    7295              : 
    7296      8371998 :   offset += size;
    7297              : 
    7298              :   /* Add outgoing arguments area.  Can be skipped if we eliminated
    7299              :      all the function calls as dead code.
    7300              :      Skipping is however impossible when function calls alloca.  Alloca
    7301              :      expander assumes that last crtl->outgoing_args_size
    7302              :      of stack frame are unused.  */
    7303      8371998 :   if (ACCUMULATE_OUTGOING_ARGS
    7304      8997561 :       && (!crtl->is_leaf || cfun->calls_alloca
    7305       402598 :           || ix86_current_function_calls_tls_descriptor))
    7306              :     {
    7307       222965 :       offset += crtl->outgoing_args_size;
    7308       222965 :       frame->outgoing_arguments_size = crtl->outgoing_args_size;
    7309              :     }
    7310              :   else
    7311      8149033 :     frame->outgoing_arguments_size = 0;
    7312              : 
    7313              :   /* Align stack boundary.  Only needed if we're calling another function
    7314              :      or using alloca.  */
    7315      2847840 :   if (!crtl->is_leaf || cfun->calls_alloca
    7316     11216440 :       || ix86_current_function_calls_tls_descriptor)
    7317      5529372 :     offset = ROUND_UP (offset, preferred_alignment);
    7318              : 
    7319              :   /* We've reached end of stack frame.  */
    7320      8371998 :   frame->stack_pointer_offset = offset;
    7321              : 
    7322              :   /* Size prologue needs to allocate.  */
    7323      8371998 :   to_allocate = offset - frame->sse_reg_save_offset;
    7324              : 
    7325      8371998 :   if (save_regs_using_push_pop (to_allocate))
    7326      2652640 :     frame->save_regs_using_mov = false;
    7327              : 
    7328      8371998 :   if (ix86_using_red_zone ()
    7329      7346558 :       && crtl->sp_is_unchanging
    7330      6701810 :       && crtl->is_leaf
    7331      2748570 :       && !cfun->machine->asm_redzone_clobber_seen
    7332      2748557 :       && !ix86_pc_thunk_call_expanded
    7333     11120555 :       && !ix86_current_function_calls_tls_descriptor)
    7334              :     {
    7335      2748542 :       frame->red_zone_size = to_allocate;
    7336      2748542 :       if (frame->save_regs_using_mov)
    7337       143541 :         frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
    7338      2748542 :       if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
    7339       103845 :         frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
    7340              :     }
    7341              :   else
    7342      5623456 :     frame->red_zone_size = 0;
    7343      8371998 :   frame->stack_pointer_offset -= frame->red_zone_size;
    7344              : 
    7345              :   /* The SEH frame pointer location is near the bottom of the frame.
    7346              :      This is enforced by the fact that the difference between the
    7347              :      stack pointer and the frame pointer is limited to 240 bytes in
    7348              :      the unwind data structure.  */
    7349      8371998 :   if (TARGET_SEH)
    7350              :     {
    7351              :       /* Force the frame pointer to point at or below the lowest register save
    7352              :          area, see the SEH code in config/i386/winnt.cc for the rationale.  */
    7353              :       frame->hard_frame_pointer_offset = frame->sse_reg_save_offset;
    7354              : 
    7355              :       /* If we can leave the frame pointer where it is, do so; however return
    7356              :          the establisher frame for __builtin_frame_address (0) or else if the
    7357              :          frame overflows the SEH maximum frame size.
    7358              : 
    7359              :          Note that the value returned by __builtin_frame_address (0) is quite
    7360              :          constrained, because setjmp is piggybacked on the SEH machinery with
    7361              :          recent versions of MinGW:
    7362              : 
    7363              :           #    elif defined(__SEH__)
    7364              :           #     if defined(__aarch64__) || defined(_ARM64_)
    7365              :           #      define setjmp(BUF) _setjmp((BUF), __builtin_sponentry())
    7366              :           #     elif (__MINGW_GCC_VERSION < 40702)
    7367              :           #      define setjmp(BUF) _setjmp((BUF), mingw_getsp())
    7368              :           #     else
    7369              :           #      define setjmp(BUF) _setjmp((BUF), __builtin_frame_address (0))
    7370              :           #     endif
    7371              : 
    7372              :          and the second argument passed to _setjmp, if not null, is forwarded
    7373              :          to the TargetFrame parameter of RtlUnwindEx by longjmp (after it has
    7374              :          built an ExceptionRecord on the fly describing the setjmp buffer).  */
    7375              :       const HOST_WIDE_INT diff
    7376              :         = frame->stack_pointer_offset - frame->hard_frame_pointer_offset;
    7377              :       if (diff <= 255 && !crtl->accesses_prior_frames)
    7378              :         {
    7379              :           /* The resulting diff will be a multiple of 16 lower than 255,
    7380              :              i.e. at most 240 as required by the unwind data structure.  */
    7381              :           frame->hard_frame_pointer_offset += (diff & 15);
    7382              :         }
    7383              :       else if (diff <= SEH_MAX_FRAME_SIZE && !crtl->accesses_prior_frames)
    7384              :         {
    7385              :           /* Ideally we'd determine what portion of the local stack frame
    7386              :              (within the constraint of the lowest 240) is most heavily used.
    7387              :              But without that complication, simply bias the frame pointer
    7388              :              by 128 bytes so as to maximize the amount of the local stack
    7389              :              frame that is addressable with 8-bit offsets.  */
    7390              :           frame->hard_frame_pointer_offset = frame->stack_pointer_offset - 128;
    7391              :         }
    7392              :       else
    7393              :         frame->hard_frame_pointer_offset = frame->hfp_save_offset;
    7394              :     }
    7395      8371998 : }
    7396              : 
    7397              : /* This is semi-inlined memory_address_length, but simplified
    7398              :    since we know that we're always dealing with reg+offset, and
    7399              :    to avoid having to create and discard all that rtl.  */
    7400              : 
    7401              : static inline int
    7402      1018047 : choose_baseaddr_len (unsigned int regno, HOST_WIDE_INT offset)
    7403              : {
    7404      1018047 :   int len = 4;
    7405              : 
    7406            0 :   if (offset == 0)
    7407              :     {
    7408              :       /* EBP and R13 cannot be encoded without an offset.  */
    7409            0 :       len = (regno == BP_REG || regno == R13_REG);
    7410              :     }
    7411      1009660 :   else if (IN_RANGE (offset, -128, 127))
    7412       649693 :     len = 1;
    7413              : 
    7414              :   /* ESP and R12 must be encoded with a SIB byte.  */
    7415            0 :   if (regno == SP_REG || regno == R12_REG)
    7416            0 :     len++;
    7417              : 
    7418      1018047 :   return len;
    7419              : }
    7420              : 
    7421              : /* Determine if the stack pointer is valid for accessing the CFA_OFFSET in
    7422              :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7423              : 
    7424              : static bool
    7425      3546140 : sp_valid_at (HOST_WIDE_INT cfa_offset)
    7426              : {
    7427      3546140 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7428      3546140 :   if (fs.sp_realigned && cfa_offset <= fs.sp_realigned_offset)
    7429              :     {
    7430              :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7431        46788 :       gcc_assert (cfa_offset <= fs.sp_realigned_fp_last);
    7432              :       return false;
    7433              :     }
    7434      3499352 :   return fs.sp_valid;
    7435              : }
    7436              : 
    7437              : /* Determine if the frame pointer is valid for accessing the CFA_OFFSET in
    7438              :    the frame save area.  The register is saved at CFA - CFA_OFFSET.  */
    7439              : 
    7440              : static inline bool
    7441      1354375 : fp_valid_at (HOST_WIDE_INT cfa_offset)
    7442              : {
    7443      1354375 :   const struct machine_frame_state &fs = cfun->machine->fs;
    7444      1354375 :   if (fs.sp_realigned && cfa_offset > fs.sp_realigned_fp_last)
    7445              :     {
    7446              :       /* Validate that the cfa_offset isn't in a "no-man's land".  */
    7447        28328 :       gcc_assert (cfa_offset >= fs.sp_realigned_offset);
    7448              :       return false;
    7449              :     }
    7450      1326047 :   return fs.fp_valid;
    7451              : }
    7452              : 
    7453              : /* Choose a base register based upon alignment requested, speed and/or
    7454              :    size.  */
    7455              : 
    7456              : static void
    7457      1354375 : choose_basereg (HOST_WIDE_INT cfa_offset, rtx &base_reg,
    7458              :                 HOST_WIDE_INT &base_offset,
    7459              :                 unsigned int align_reqested, unsigned int *align)
    7460              : {
    7461      1354375 :   const struct machine_function *m = cfun->machine;
    7462      1354375 :   unsigned int hfp_align;
    7463      1354375 :   unsigned int drap_align;
    7464      1354375 :   unsigned int sp_align;
    7465      1354375 :   bool hfp_ok  = fp_valid_at (cfa_offset);
    7466      1354375 :   bool drap_ok = m->fs.drap_valid;
    7467      1354375 :   bool sp_ok   = sp_valid_at (cfa_offset);
    7468              : 
    7469      1354375 :   hfp_align = drap_align = sp_align = INCOMING_STACK_BOUNDARY;
    7470              : 
    7471              :   /* Filter out any registers that don't meet the requested alignment
    7472              :      criteria.  */
    7473      1354375 :   if (align_reqested)
    7474              :     {
    7475       973633 :       if (m->fs.realigned)
    7476        28160 :         hfp_align = drap_align = sp_align = crtl->stack_alignment_needed;
    7477              :       /* SEH unwind code does do not currently support REG_CFA_EXPRESSION
    7478              :          notes (which we would need to use a realigned stack pointer),
    7479              :          so disable on SEH targets.  */
    7480       945473 :       else if (m->fs.sp_realigned)
    7481        28328 :         sp_align = crtl->stack_alignment_needed;
    7482              : 
    7483       973633 :       hfp_ok = hfp_ok && hfp_align >= align_reqested;
    7484       973633 :       drap_ok = drap_ok && drap_align >= align_reqested;
    7485       973633 :       sp_ok = sp_ok && sp_align >= align_reqested;
    7486              :     }
    7487              : 
    7488      1354375 :   if (m->use_fast_prologue_epilogue)
    7489              :     {
    7490              :       /* Choose the base register most likely to allow the most scheduling
    7491              :          opportunities.  Generally FP is valid throughout the function,
    7492              :          while DRAP must be reloaded within the epilogue.  But choose either
    7493              :          over the SP due to increased encoding size.  */
    7494              : 
    7495       631882 :       if (hfp_ok)
    7496              :         {
    7497       119965 :           base_reg = hard_frame_pointer_rtx;
    7498       119965 :           base_offset = m->fs.fp_offset - cfa_offset;
    7499              :         }
    7500       511917 :       else if (drap_ok)
    7501              :         {
    7502            0 :           base_reg = crtl->drap_reg;
    7503            0 :           base_offset = 0 - cfa_offset;
    7504              :         }
    7505       511917 :       else if (sp_ok)
    7506              :         {
    7507       511917 :           base_reg = stack_pointer_rtx;
    7508       511917 :           base_offset = m->fs.sp_offset - cfa_offset;
    7509              :         }
    7510              :     }
    7511              :   else
    7512              :     {
    7513       722493 :       HOST_WIDE_INT toffset;
    7514       722493 :       int len = 16, tlen;
    7515              : 
    7516              :       /* Choose the base register with the smallest address encoding.
    7517              :          With a tie, choose FP > DRAP > SP.  */
    7518       722493 :       if (sp_ok)
    7519              :         {
    7520       705175 :           base_reg = stack_pointer_rtx;
    7521       705175 :           base_offset = m->fs.sp_offset - cfa_offset;
    7522      1401963 :           len = choose_baseaddr_len (STACK_POINTER_REGNUM, base_offset);
    7523              :         }
    7524       722493 :       if (drap_ok)
    7525              :         {
    7526            0 :           toffset = 0 - cfa_offset;
    7527            0 :           tlen = choose_baseaddr_len (REGNO (crtl->drap_reg), toffset);
    7528            0 :           if (tlen <= len)
    7529              :             {
    7530            0 :               base_reg = crtl->drap_reg;
    7531            0 :               base_offset = toffset;
    7532            0 :               len = tlen;
    7533              :             }
    7534              :         }
    7535       722493 :       if (hfp_ok)
    7536              :         {
    7537       312872 :           toffset = m->fs.fp_offset - cfa_offset;
    7538       312872 :           tlen = choose_baseaddr_len (HARD_FRAME_POINTER_REGNUM, toffset);
    7539       312872 :           if (tlen <= len)
    7540              :             {
    7541       225412 :               base_reg = hard_frame_pointer_rtx;
    7542       225412 :               base_offset = toffset;
    7543              :             }
    7544              :         }
    7545              :     }
    7546              : 
    7547              :     /* Set the align return value.  */
    7548      1354375 :     if (align)
    7549              :       {
    7550       973633 :         if (base_reg == stack_pointer_rtx)
    7551       688596 :           *align = sp_align;
    7552       285037 :         else if (base_reg == crtl->drap_reg)
    7553            0 :           *align = drap_align;
    7554       285037 :         else if (base_reg == hard_frame_pointer_rtx)
    7555       285037 :           *align = hfp_align;
    7556              :       }
    7557      1354375 : }
    7558              : 
    7559              : /* Return an RTX that points to CFA_OFFSET within the stack frame and
    7560              :    the alignment of address.  If ALIGN is non-null, it should point to
    7561              :    an alignment value (in bits) that is preferred or zero and will
    7562              :    receive the alignment of the base register that was selected,
    7563              :    irrespective of rather or not CFA_OFFSET is a multiple of that
    7564              :    alignment value.  If it is possible for the base register offset to be
    7565              :    non-immediate then SCRATCH_REGNO should specify a scratch register to
    7566              :    use.
    7567              : 
    7568              :    The valid base registers are taken from CFUN->MACHINE->FS.  */
    7569              : 
    7570              : static rtx
    7571      1354375 : choose_baseaddr (HOST_WIDE_INT cfa_offset, unsigned int *align,
    7572              :                  unsigned int scratch_regno = INVALID_REGNUM)
    7573              : {
    7574      1354375 :   rtx base_reg = NULL;
    7575      1354375 :   HOST_WIDE_INT base_offset = 0;
    7576              : 
    7577              :   /* If a specific alignment is requested, try to get a base register
    7578              :      with that alignment first.  */
    7579      1354375 :   if (align && *align)
    7580       973633 :     choose_basereg (cfa_offset, base_reg, base_offset, *align, align);
    7581              : 
    7582      1354375 :   if (!base_reg)
    7583       380742 :     choose_basereg (cfa_offset, base_reg, base_offset, 0, align);
    7584              : 
    7585      1354375 :   gcc_assert (base_reg != NULL);
    7586              : 
    7587      1354375 :   rtx base_offset_rtx = GEN_INT (base_offset);
    7588              : 
    7589      1405136 :   if (!x86_64_immediate_operand (base_offset_rtx, Pmode))
    7590              :     {
    7591            1 :       gcc_assert (scratch_regno != INVALID_REGNUM);
    7592              : 
    7593            1 :       rtx scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
    7594            1 :       emit_move_insn (scratch_reg, base_offset_rtx);
    7595              : 
    7596            1 :       return gen_rtx_PLUS (Pmode, base_reg, scratch_reg);
    7597              :     }
    7598              : 
    7599      1405135 :   return plus_constant (Pmode, base_reg, base_offset);
    7600              : }
    7601              : 
    7602              : /* Emit code to save registers in the prologue.  */
    7603              : 
    7604              : static void
    7605       440414 : ix86_emit_save_regs (void)
    7606              : {
    7607       440414 :   int regno;
    7608       440414 :   rtx_insn *insn;
    7609       440414 :   bool use_ppx = TARGET_APX_PPX && !crtl->calls_eh_return;
    7610              : 
    7611       440414 :   if (!TARGET_APX_PUSH2POP2
    7612           91 :       || !ix86_can_use_push2pop2 ()
    7613       440503 :       || cfun->machine->func_type != TYPE_NORMAL)
    7614              :     {
    7615     41830970 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7616     41390644 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7617              :           {
    7618      1231709 :             insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7619              :                                         use_ppx));
    7620      1231709 :             RTX_FRAME_RELATED_P (insn) = 1;
    7621              :           }
    7622              :     }
    7623              :   else
    7624              :     {
    7625           88 :       int regno_list[2];
    7626           88 :       regno_list[0] = regno_list[1] = -1;
    7627           88 :       int loaded_regnum = 0;
    7628           88 :       bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
    7629              : 
    7630         8360 :       for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
    7631         8272 :         if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7632              :           {
    7633          128 :             if (aligned)
    7634              :               {
    7635           45 :                 regno_list[loaded_regnum++] = regno;
    7636           45 :                 if (loaded_regnum == 2)
    7637              :                   {
    7638           19 :                     gcc_assert (regno_list[0] != -1
    7639              :                                 && regno_list[1] != -1
    7640              :                                 && regno_list[0] != regno_list[1]);
    7641           19 :                     const int offset = UNITS_PER_WORD * 2;
    7642           19 :                     rtx mem = gen_rtx_MEM (TImode,
    7643           19 :                                            gen_rtx_PRE_DEC (Pmode,
    7644              :                                                             stack_pointer_rtx));
    7645           19 :                     insn = emit_insn (gen_push2 (mem,
    7646              :                                                  gen_rtx_REG (word_mode,
    7647              :                                                               regno_list[0]),
    7648              :                                                  gen_rtx_REG (word_mode,
    7649              :                                                               regno_list[1]),
    7650              :                                                  use_ppx));
    7651           19 :                     RTX_FRAME_RELATED_P (insn) = 1;
    7652           19 :                     rtx dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (3));
    7653              : 
    7654           57 :                     for (int i = 0; i < 2; i++)
    7655              :                       {
    7656           76 :                         rtx dwarf_reg = gen_rtx_REG (word_mode,
    7657           38 :                                                      regno_list[i]);
    7658           38 :                         rtx sp_offset = plus_constant (Pmode,
    7659              :                                                        stack_pointer_rtx,
    7660           38 :                                                        + UNITS_PER_WORD
    7661           38 :                                                          * (1 - i));
    7662           38 :                         rtx tmp = gen_rtx_SET (gen_frame_mem (DImode,
    7663              :                                                               sp_offset),
    7664              :                                                dwarf_reg);
    7665           38 :                         RTX_FRAME_RELATED_P (tmp) = 1;
    7666           38 :                         XVECEXP (dwarf, 0, i + 1) = tmp;
    7667              :                       }
    7668           19 :                     rtx sp_tmp = gen_rtx_SET (stack_pointer_rtx,
    7669              :                                               plus_constant (Pmode,
    7670              :                                                              stack_pointer_rtx,
    7671              :                                                              -offset));
    7672           19 :                     RTX_FRAME_RELATED_P (sp_tmp) = 1;
    7673           19 :                     XVECEXP (dwarf, 0, 0) = sp_tmp;
    7674           19 :                     add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
    7675              : 
    7676           19 :                     loaded_regnum = 0;
    7677           19 :                     regno_list[0] = regno_list[1] = -1;
    7678              :                   }
    7679              :               }
    7680              :             else
    7681              :               {
    7682           83 :                 insn = emit_insn (gen_push (gen_rtx_REG (word_mode, regno),
    7683              :                                             use_ppx));
    7684           83 :                 RTX_FRAME_RELATED_P (insn) = 1;
    7685           83 :                 aligned = true;
    7686              :               }
    7687              :           }
    7688           88 :       if (loaded_regnum == 1)
    7689              :         {
    7690            7 :           insn = emit_insn (gen_push (gen_rtx_REG (word_mode,
    7691            7 :                                                    regno_list[0]),
    7692              :                                       use_ppx));
    7693            7 :           RTX_FRAME_RELATED_P (insn) = 1;
    7694              :         }
    7695              :     }
    7696       440414 : }
    7697              : 
    7698              : /* Emit a single register save at CFA - CFA_OFFSET.  */
    7699              : 
    7700              : static void
    7701       619438 : ix86_emit_save_reg_using_mov (machine_mode mode, unsigned int regno,
    7702              :                               HOST_WIDE_INT cfa_offset)
    7703              : {
    7704       619438 :   struct machine_function *m = cfun->machine;
    7705       619438 :   rtx reg = gen_rtx_REG (mode, regno);
    7706       619438 :   rtx mem, addr, base, insn;
    7707       619438 :   unsigned int align = GET_MODE_ALIGNMENT (mode);
    7708              : 
    7709       619438 :   addr = choose_baseaddr (cfa_offset, &align);
    7710       619438 :   mem = gen_frame_mem (mode, addr);
    7711              : 
    7712              :   /* The location alignment depends upon the base register.  */
    7713       619438 :   align = MIN (GET_MODE_ALIGNMENT (mode), align);
    7714       619438 :   gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
    7715       619438 :   set_mem_align (mem, align);
    7716              : 
    7717       619438 :   insn = emit_insn (gen_rtx_SET (mem, reg));
    7718       619438 :   RTX_FRAME_RELATED_P (insn) = 1;
    7719              : 
    7720       619438 :   base = addr;
    7721       619438 :   if (GET_CODE (base) == PLUS)
    7722       607352 :     base = XEXP (base, 0);
    7723       619438 :   gcc_checking_assert (REG_P (base));
    7724              : 
    7725              :   /* When saving registers into a re-aligned local stack frame, avoid
    7726              :      any tricky guessing by dwarf2out.  */
    7727       619438 :   if (m->fs.realigned)
    7728              :     {
    7729        12800 :       gcc_checking_assert (stack_realign_drap);
    7730              : 
    7731        12800 :       if (regno == REGNO (crtl->drap_reg))
    7732              :         {
    7733              :           /* A bit of a hack.  We force the DRAP register to be saved in
    7734              :              the re-aligned stack frame, which provides us with a copy
    7735              :              of the CFA that will last past the prologue.  Install it.  */
    7736            0 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7737            0 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7738            0 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7739            0 :           mem = gen_rtx_MEM (mode, addr);
    7740            0 :           add_reg_note (insn, REG_CFA_DEF_CFA, mem);
    7741              :         }
    7742              :       else
    7743              :         {
    7744              :           /* The frame pointer is a stable reference within the
    7745              :              aligned frame.  Use it.  */
    7746        12800 :           gcc_checking_assert (cfun->machine->fs.fp_valid);
    7747        12800 :           addr = plus_constant (Pmode, hard_frame_pointer_rtx,
    7748        12800 :                                 cfun->machine->fs.fp_offset - cfa_offset);
    7749        12800 :           mem = gen_rtx_MEM (mode, addr);
    7750        12800 :           add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7751              :         }
    7752              :     }
    7753              : 
    7754       606638 :   else if (base == stack_pointer_rtx && m->fs.sp_realigned
    7755        12881 :            && cfa_offset >= m->fs.sp_realigned_offset)
    7756              :     {
    7757        12881 :       gcc_checking_assert (stack_realign_fp);
    7758        12881 :       add_reg_note (insn, REG_CFA_EXPRESSION, gen_rtx_SET (mem, reg));
    7759              :     }
    7760              : 
    7761              :   /* The memory may not be relative to the current CFA register,
    7762              :      which means that we may need to generate a new pattern for
    7763              :      use by the unwind info.  */
    7764       593757 :   else if (base != m->fs.cfa_reg)
    7765              :     {
    7766        43473 :       addr = plus_constant (Pmode, m->fs.cfa_reg,
    7767        43473 :                             m->fs.cfa_offset - cfa_offset);
    7768        43473 :       mem = gen_rtx_MEM (mode, addr);
    7769        43473 :       add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
    7770              :     }
    7771       619438 : }
    7772              : 
    7773              : /* Emit code to save registers using MOV insns.
    7774              :    First register is stored at CFA - CFA_OFFSET.  */
    7775              : static void
    7776        45895 : ix86_emit_save_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7777              : {
    7778        45895 :   unsigned int regno;
    7779              : 
    7780      4360025 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7781      4314130 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7782              :       {
    7783              :         /* Skip registers, already processed by shrink wrap separate.  */
    7784       195223 :         if (!cfun->machine->reg_is_wrapped_separately[regno])
    7785        86480 :           ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
    7786       209979 :         cfa_offset -= UNITS_PER_WORD;
    7787              :       }
    7788        45895 : }
    7789              : 
    7790              : /* Emit code to save SSE registers using MOV insns.
    7791              :    First register is stored at CFA - CFA_OFFSET.  */
    7792              : static void
    7793        33376 : ix86_emit_save_sse_regs_using_mov (HOST_WIDE_INT cfa_offset)
    7794              : {
    7795        33376 :   unsigned int regno;
    7796              : 
    7797      3170720 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    7798      3137344 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, true, true))
    7799              :       {
    7800       333769 :         ix86_emit_save_reg_using_mov (V4SFmode, regno, cfa_offset);
    7801       333769 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
    7802              :       }
    7803        33376 : }
    7804              : 
    7805              : static GTY(()) rtx queued_cfa_restores;
    7806              : 
    7807              : /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
    7808              :    manipulation insn.  The value is on the stack at CFA - CFA_OFFSET.
    7809              :    Don't add the note if the previously saved value will be left untouched
    7810              :    within stack red-zone till return, as unwinders can find the same value
    7811              :    in the register and on the stack.  */
    7812              : 
    7813              : static void
    7814      2342819 : ix86_add_cfa_restore_note (rtx_insn *insn, rtx reg, HOST_WIDE_INT cfa_offset)
    7815              : {
    7816      2342819 :   if (!crtl->shrink_wrapped
    7817      2323614 :       && cfa_offset <= cfun->machine->fs.red_zone_offset)
    7818              :     return;
    7819              : 
    7820       769101 :   if (insn)
    7821              :     {
    7822       358255 :       add_reg_note (insn, REG_CFA_RESTORE, reg);
    7823       358255 :       RTX_FRAME_RELATED_P (insn) = 1;
    7824              :     }
    7825              :   else
    7826       410846 :     queued_cfa_restores
    7827       410846 :       = alloc_reg_note (REG_CFA_RESTORE, reg, queued_cfa_restores);
    7828              : }
    7829              : 
    7830              : /* Add queued REG_CFA_RESTORE notes if any to INSN.  */
    7831              : 
    7832              : static void
    7833      2613921 : ix86_add_queued_cfa_restore_notes (rtx insn)
    7834              : {
    7835      2613921 :   rtx last;
    7836      2613921 :   if (!queued_cfa_restores)
    7837              :     return;
    7838       410846 :   for (last = queued_cfa_restores; XEXP (last, 1); last = XEXP (last, 1))
    7839              :     ;
    7840        52965 :   XEXP (last, 1) = REG_NOTES (insn);
    7841        52965 :   REG_NOTES (insn) = queued_cfa_restores;
    7842        52965 :   queued_cfa_restores = NULL_RTX;
    7843        52965 :   RTX_FRAME_RELATED_P (insn) = 1;
    7844              : }
    7845              : 
    7846              : /* Expand prologue or epilogue stack adjustment.
    7847              :    The pattern exist to put a dependency on all ebp-based memory accesses.
    7848              :    STYLE should be negative if instructions should be marked as frame related,
    7849              :    zero if %r11 register is live and cannot be freely used and positive
    7850              :    otherwise.  */
    7851              : 
    7852              : static rtx
    7853      1614041 : pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset,
    7854              :                            int style, bool set_cfa)
    7855              : {
    7856      1614041 :   struct machine_function *m = cfun->machine;
    7857      1614041 :   rtx addend = offset;
    7858      1614041 :   rtx insn;
    7859      1614041 :   bool add_frame_related_expr = false;
    7860              : 
    7861      1832563 :   if (!x86_64_immediate_operand (offset, Pmode))
    7862              :     {
    7863              :       /* r11 is used by indirect sibcall return as well, set before the
    7864              :          epilogue and used after the epilogue.  */
    7865          199 :       if (style)
    7866          174 :         addend = gen_rtx_REG (Pmode, R11_REG);
    7867              :       else
    7868              :         {
    7869           25 :           gcc_assert (src != hard_frame_pointer_rtx
    7870              :                       && dest != hard_frame_pointer_rtx);
    7871              :           addend = hard_frame_pointer_rtx;
    7872              :         }
    7873          199 :       emit_insn (gen_rtx_SET (addend, offset));
    7874          199 :       if (style < 0)
    7875           88 :         add_frame_related_expr = true;
    7876              :     }
    7877              : 
    7878              :   /*  Shrink wrap separate may insert prologue between TEST and JMP.  In order
    7879              :       not to affect EFlags, emit add without reg clobbering.  */
    7880      1614041 :   if (crtl->shrink_wrapped_separate)
    7881        96979 :     insn = emit_insn (gen_pro_epilogue_adjust_stack_add_nocc
    7882        96979 :                       (Pmode, dest, src, addend));
    7883              :   else
    7884      1517062 :     insn = emit_insn (gen_pro_epilogue_adjust_stack_add
    7885      1517062 :                       (Pmode, dest, src, addend));
    7886              : 
    7887      1614041 :   if (style >= 0)
    7888       710900 :     ix86_add_queued_cfa_restore_notes (insn);
    7889              : 
    7890      1614041 :   if (set_cfa)
    7891              :     {
    7892      1244840 :       rtx r;
    7893              : 
    7894      1244840 :       gcc_assert (m->fs.cfa_reg == src);
    7895      1244840 :       m->fs.cfa_offset += INTVAL (offset);
    7896      1244840 :       m->fs.cfa_reg = dest;
    7897              : 
    7898      1440950 :       r = gen_rtx_PLUS (Pmode, src, offset);
    7899      1244840 :       r = gen_rtx_SET (dest, r);
    7900      1244840 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, r);
    7901      1244840 :       RTX_FRAME_RELATED_P (insn) = 1;
    7902              :     }
    7903       369201 :   else if (style < 0)
    7904              :     {
    7905       302500 :       RTX_FRAME_RELATED_P (insn) = 1;
    7906       302500 :       if (add_frame_related_expr)
    7907              :         {
    7908           20 :           rtx r = gen_rtx_PLUS (Pmode, src, offset);
    7909           20 :           r = gen_rtx_SET (dest, r);
    7910           20 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, r);
    7911              :         }
    7912              :     }
    7913              : 
    7914      1614041 :   if (dest == stack_pointer_rtx)
    7915              :     {
    7916      1614041 :       HOST_WIDE_INT ooffset = m->fs.sp_offset;
    7917      1614041 :       bool valid = m->fs.sp_valid;
    7918      1614041 :       bool realigned = m->fs.sp_realigned;
    7919              : 
    7920      1614041 :       if (src == hard_frame_pointer_rtx)
    7921              :         {
    7922        29704 :           valid = m->fs.fp_valid;
    7923        29704 :           realigned = false;
    7924        29704 :           ooffset = m->fs.fp_offset;
    7925              :         }
    7926      1584337 :       else if (src == crtl->drap_reg)
    7927              :         {
    7928            0 :           valid = m->fs.drap_valid;
    7929            0 :           realigned = false;
    7930            0 :           ooffset = 0;
    7931              :         }
    7932              :       else
    7933              :         {
    7934              :           /* Else there are two possibilities: SP itself, which we set
    7935              :              up as the default above.  Or EH_RETURN_STACKADJ_RTX, which is
    7936              :              taken care of this by hand along the eh_return path.  */
    7937      1584337 :           gcc_checking_assert (src == stack_pointer_rtx
    7938              :                                || offset == const0_rtx);
    7939              :         }
    7940              : 
    7941      1614041 :       m->fs.sp_offset = ooffset - INTVAL (offset);
    7942      1614041 :       m->fs.sp_valid = valid;
    7943      1614041 :       m->fs.sp_realigned = realigned;
    7944              :     }
    7945      1614041 :   return insn;
    7946              : }
    7947              : 
    7948              : /* Find an available register to be used as dynamic realign argument
    7949              :    pointer register.  Such a register will be written in prologue and
    7950              :    used in begin of body, so it must not be
    7951              :         1. parameter passing register.
    7952              :         2. GOT pointer.
    7953              :    We reuse static-chain register if it is available.  Otherwise, we
    7954              :    use DI for i386 and R13 for x86-64.  We chose R13 since it has
    7955              :    shorter encoding.
    7956              : 
    7957              :    Return: the regno of chosen register.  */
    7958              : 
    7959              : static unsigned int
    7960         7243 : find_drap_reg (void)
    7961              : {
    7962         7243 :   tree decl = cfun->decl;
    7963              : 
    7964              :   /* Always use callee-saved register if there are no caller-saved
    7965              :      registers.  */
    7966         7243 :   if (TARGET_64BIT)
    7967              :     {
    7968              :       /* In preserve_none functions, any register can be used for DRAP,
    7969              :          except AX, R12–R15, DI, SI (argument registers), SP, and BP.  */
    7970         6958 :       if (cfun->machine->call_saved_registers == TYPE_PRESERVE_NONE)
    7971              :         return R11_REG;
    7972              : 
    7973              :       /* Use R13 for nested function or function need static chain.
    7974              :          Since function with tail call may use any caller-saved
    7975              :          registers in epilogue, DRAP must not use caller-saved
    7976              :          register in such case.  */
    7977         6957 :       if (DECL_STATIC_CHAIN (decl)
    7978         6915 :           || (cfun->machine->call_saved_registers
    7979              :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7980        13872 :           || crtl->tail_call_emit)
    7981          191 :         return R13_REG;
    7982              : 
    7983              :       return R10_REG;
    7984              :     }
    7985              :   else
    7986              :     {
    7987              :       /* Use DI for nested function or function need static chain.
    7988              :          Since function with tail call may use any caller-saved
    7989              :          registers in epilogue, DRAP must not use caller-saved
    7990              :          register in such case.  */
    7991          285 :       if (DECL_STATIC_CHAIN (decl)
    7992          285 :           || (cfun->machine->call_saved_registers
    7993          285 :               == TYPE_NO_CALLER_SAVED_REGISTERS)
    7994          285 :           || crtl->tail_call_emit
    7995          550 :           || crtl->calls_eh_return)
    7996              :         return DI_REG;
    7997              : 
    7998              :       /* Reuse static chain register if it isn't used for parameter
    7999              :          passing.  */
    8000          265 :       if (ix86_function_regparm (TREE_TYPE (decl), decl) <= 2)
    8001              :         {
    8002          265 :           unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
    8003          265 :           if ((ccvt & (IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) == 0)
    8004              :             return CX_REG;
    8005              :         }
    8006            0 :       return DI_REG;
    8007              :     }
    8008              : }
    8009              : 
    8010              : /* Return minimum incoming stack alignment.  */
    8011              : 
    8012              : static unsigned int
    8013      1658409 : ix86_minimum_incoming_stack_boundary (bool sibcall)
    8014              : {
    8015      1658409 :   unsigned int incoming_stack_boundary;
    8016              : 
    8017              :   /* Stack of interrupt handler is aligned to 128 bits in 64bit mode.  */
    8018      1658409 :   if (cfun->machine->func_type != TYPE_NORMAL)
    8019          120 :     incoming_stack_boundary = TARGET_64BIT ? 128 : MIN_STACK_BOUNDARY;
    8020              :   /* Prefer the one specified at command line. */
    8021      1658289 :   else if (ix86_user_incoming_stack_boundary)
    8022              :     incoming_stack_boundary = ix86_user_incoming_stack_boundary;
    8023              :   /* In 32bit, use MIN_STACK_BOUNDARY for incoming stack boundary
    8024              :      if -mstackrealign is used, it isn't used for sibcall check and
    8025              :      estimated stack alignment is 128bit.  */
    8026      1658267 :   else if (!sibcall
    8027      1521203 :            && ix86_force_align_arg_pointer
    8028         4572 :            && crtl->stack_alignment_estimated == 128)
    8029          596 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    8030              :   else
    8031      1657671 :     incoming_stack_boundary = ix86_default_incoming_stack_boundary;
    8032              : 
    8033              :   /* Incoming stack alignment can be changed on individual functions
    8034              :      via force_align_arg_pointer attribute.  We use the smallest
    8035              :      incoming stack boundary.  */
    8036      1658409 :   if (incoming_stack_boundary > MIN_STACK_BOUNDARY
    8037      3316212 :       && lookup_attribute ("force_align_arg_pointer",
    8038      1657803 :                            TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
    8039         5708 :     incoming_stack_boundary = MIN_STACK_BOUNDARY;
    8040              : 
    8041              :   /* The incoming stack frame has to be aligned at least at
    8042              :      parm_stack_boundary.  */
    8043      1658409 :   if (incoming_stack_boundary < crtl->parm_stack_boundary)
    8044              :     incoming_stack_boundary = crtl->parm_stack_boundary;
    8045              : 
    8046              :   /* Stack at entrance of main is aligned by runtime.  We use the
    8047              :      smallest incoming stack boundary. */
    8048      1658409 :   if (incoming_stack_boundary > MAIN_STACK_BOUNDARY
    8049       140919 :       && DECL_NAME (current_function_decl)
    8050       140919 :       && MAIN_NAME_P (DECL_NAME (current_function_decl))
    8051      1660886 :       && DECL_FILE_SCOPE_P (current_function_decl))
    8052         2477 :     incoming_stack_boundary = MAIN_STACK_BOUNDARY;
    8053              : 
    8054      1658409 :   return incoming_stack_boundary;
    8055              : }
    8056              : 
    8057              : /* Update incoming stack boundary and estimated stack alignment.  */
    8058              : 
    8059              : static void
    8060      1521340 : ix86_update_stack_boundary (void)
    8061              : {
    8062      1521340 :   ix86_incoming_stack_boundary
    8063      1521340 :     = ix86_minimum_incoming_stack_boundary (false);
    8064              : 
    8065              :   /* x86_64 vararg needs 16byte stack alignment for register save area.  */
    8066      1521340 :   if (TARGET_64BIT
    8067      1394685 :       && cfun->stdarg
    8068        21451 :       && crtl->stack_alignment_estimated < 128)
    8069        10270 :     crtl->stack_alignment_estimated = 128;
    8070              : 
    8071              :   /* __tls_get_addr needs to be called with 16-byte aligned stack.  */
    8072      1521340 :   if (ix86_tls_descriptor_calls_expanded_in_cfun
    8073         1085 :       && crtl->preferred_stack_boundary < 128)
    8074          750 :     crtl->preferred_stack_boundary = 128;
    8075              : 
    8076              :   /* For 32-bit MS ABI, both the incoming and preferred stack boundaries
    8077              :      are 32 bits, but if force_align_arg_pointer is specified, it should
    8078              :      prefer 128 bits for a backward-compatibility reason, which is also
    8079              :      what the doc suggests.  */
    8080      1521340 :   if (lookup_attribute ("force_align_arg_pointer",
    8081      1521340 :                         TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))
    8082      1521340 :       && crtl->preferred_stack_boundary < 128)
    8083            4 :     crtl->preferred_stack_boundary = 128;
    8084      1521340 : }
    8085              : 
    8086              : /* Handle the TARGET_GET_DRAP_RTX hook.  Return NULL if no DRAP is
    8087              :    needed or an rtx for DRAP otherwise.  */
    8088              : 
    8089              : static rtx
    8090      1628529 : ix86_get_drap_rtx (void)
    8091              : {
    8092              :   /* We must use DRAP if there are outgoing arguments on stack or
    8093              :      the stack pointer register is clobbered by asm statement and
    8094              :      ACCUMULATE_OUTGOING_ARGS is false.  */
    8095      1628529 :   if (ix86_force_drap
    8096      1628529 :       || ((cfun->machine->outgoing_args_on_stack
    8097      1293543 :            || crtl->sp_is_clobbered_by_asm)
    8098       333041 :           && !ACCUMULATE_OUTGOING_ARGS))
    8099       312831 :     crtl->need_drap = true;
    8100              : 
    8101      1628529 :   if (stack_realign_drap)
    8102              :     {
    8103              :       /* Assign DRAP to vDRAP and returns vDRAP */
    8104         7243 :       unsigned int regno = find_drap_reg ();
    8105         7243 :       rtx drap_vreg;
    8106         7243 :       rtx arg_ptr;
    8107         7243 :       rtx_insn *seq, *insn;
    8108              : 
    8109         7528 :       arg_ptr = gen_rtx_REG (Pmode, regno);
    8110         7243 :       crtl->drap_reg = arg_ptr;
    8111              : 
    8112         7243 :       start_sequence ();
    8113         7243 :       drap_vreg = copy_to_reg (arg_ptr);
    8114         7243 :       seq = end_sequence ();
    8115              : 
    8116         7243 :       insn = emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
    8117         7243 :       if (!optimize)
    8118              :         {
    8119         1897 :           add_reg_note (insn, REG_CFA_SET_VDRAP, drap_vreg);
    8120         1897 :           RTX_FRAME_RELATED_P (insn) = 1;
    8121              :         }
    8122              :       return drap_vreg;
    8123              :     }
    8124              :   else
    8125              :     return NULL;
    8126              : }
    8127              : 
    8128              : /* Handle the TARGET_INTERNAL_ARG_POINTER hook.  */
    8129              : 
    8130              : static rtx
    8131      1521342 : ix86_internal_arg_pointer (void)
    8132              : {
    8133      1521342 :   return virtual_incoming_args_rtx;
    8134              : }
    8135              : 
    8136              : struct scratch_reg {
    8137              :   rtx reg;
    8138              :   bool saved;
    8139              : };
    8140              : 
    8141              : /* Return a short-lived scratch register for use on function entry.
    8142              :    In 32-bit mode, it is valid only after the registers are saved
    8143              :    in the prologue.  This register must be released by means of
    8144              :    release_scratch_register_on_entry once it is dead.  */
    8145              : 
    8146              : static void
    8147           25 : get_scratch_register_on_entry (struct scratch_reg *sr)
    8148              : {
    8149           25 :   int regno;
    8150              : 
    8151           25 :   sr->saved = false;
    8152              : 
    8153           25 :   if (TARGET_64BIT)
    8154              :     {
    8155              :       /* We always use R11 in 64-bit mode.  */
    8156              :       regno = R11_REG;
    8157              :     }
    8158              :   else
    8159              :     {
    8160            0 :       tree decl = current_function_decl, fntype = TREE_TYPE (decl);
    8161            0 :       bool fastcall_p
    8162            0 :         = lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    8163            0 :       bool thiscall_p
    8164            0 :         = lookup_attribute ("thiscall", TYPE_ATTRIBUTES (fntype)) != NULL_TREE;
    8165            0 :       bool static_chain_p = DECL_STATIC_CHAIN (decl);
    8166            0 :       int regparm = ix86_function_regparm (fntype, decl);
    8167            0 :       int drap_regno
    8168            0 :         = crtl->drap_reg ? REGNO (crtl->drap_reg) : INVALID_REGNUM;
    8169              : 
    8170              :       /* 'fastcall' sets regparm to 2, uses ecx/edx for arguments and eax
    8171              :           for the static chain register.  */
    8172            0 :       if ((regparm < 1 || (fastcall_p && !static_chain_p))
    8173            0 :           && drap_regno != AX_REG)
    8174              :         regno = AX_REG;
    8175              :       /* 'thiscall' sets regparm to 1, uses ecx for arguments and edx
    8176              :           for the static chain register.  */
    8177            0 :       else if (thiscall_p && !static_chain_p && drap_regno != AX_REG)
    8178              :         regno = AX_REG;
    8179            0 :       else if (regparm < 2 && !thiscall_p && drap_regno != DX_REG)
    8180              :         regno = DX_REG;
    8181              :       /* ecx is the static chain register.  */
    8182            0 :       else if (regparm < 3 && !fastcall_p && !thiscall_p
    8183            0 :                && !static_chain_p
    8184            0 :                && drap_regno != CX_REG)
    8185              :         regno = CX_REG;
    8186            0 :       else if (ix86_save_reg (BX_REG, true, false))
    8187              :         regno = BX_REG;
    8188              :       /* esi is the static chain register.  */
    8189            0 :       else if (!(regparm == 3 && static_chain_p)
    8190            0 :                && ix86_save_reg (SI_REG, true, false))
    8191              :         regno = SI_REG;
    8192            0 :       else if (ix86_save_reg (DI_REG, true, false))
    8193              :         regno = DI_REG;
    8194              :       else
    8195              :         {
    8196            0 :           regno = (drap_regno == AX_REG ? DX_REG : AX_REG);
    8197            0 :           sr->saved = true;
    8198              :         }
    8199              :     }
    8200              : 
    8201           25 :   sr->reg = gen_rtx_REG (Pmode, regno);
    8202           25 :   if (sr->saved)
    8203              :     {
    8204            0 :       rtx_insn *insn = emit_insn (gen_push (sr->reg));
    8205            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    8206              :     }
    8207           25 : }
    8208              : 
    8209              : /* Release a scratch register obtained from the preceding function.
    8210              : 
    8211              :    If RELEASE_VIA_POP is true, we just pop the register off the stack
    8212              :    to release it.  This is what non-Linux systems use with -fstack-check.
    8213              : 
    8214              :    Otherwise we use OFFSET to locate the saved register and the
    8215              :    allocated stack space becomes part of the local frame and is
    8216              :    deallocated by the epilogue.  */
    8217              : 
    8218              : static void
    8219           25 : release_scratch_register_on_entry (struct scratch_reg *sr, HOST_WIDE_INT offset,
    8220              :                                    bool release_via_pop)
    8221              : {
    8222           25 :   if (sr->saved)
    8223              :     {
    8224            0 :       if (release_via_pop)
    8225              :         {
    8226            0 :           struct machine_function *m = cfun->machine;
    8227            0 :           rtx x, insn = emit_insn (gen_pop (sr->reg));
    8228              : 
    8229              :           /* The RX FRAME_RELATED_P mechanism doesn't know about pop.  */
    8230            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    8231            0 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8232            0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8233            0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR, x);
    8234            0 :           m->fs.sp_offset -= UNITS_PER_WORD;
    8235              :         }
    8236              :       else
    8237              :         {
    8238            0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    8239            0 :           x = gen_rtx_SET (sr->reg, gen_rtx_MEM (word_mode, x));
    8240            0 :           emit_insn (x);
    8241              :         }
    8242              :     }
    8243           25 : }
    8244              : 
    8245              : /* Emit code to adjust the stack pointer by SIZE bytes while probing it.
    8246              : 
    8247              :    If INT_REGISTERS_SAVED is true, then integer registers have already been
    8248              :    pushed on the stack.
    8249              : 
    8250              :    If PROTECTION AREA is true, then probe PROBE_INTERVAL plus a small dope
    8251              :    beyond SIZE bytes.
    8252              : 
    8253              :    This assumes no knowledge of the current probing state, i.e. it is never
    8254              :    allowed to allocate more than PROBE_INTERVAL bytes of stack space without
    8255              :    a suitable probe.  */
    8256              : 
    8257              : static void
    8258          126 : ix86_adjust_stack_and_probe (HOST_WIDE_INT size,
    8259              :                              const bool int_registers_saved,
    8260              :                              const bool protection_area)
    8261              : {
    8262          126 :   struct machine_function *m = cfun->machine;
    8263              : 
    8264              :   /* If this function does not statically allocate stack space, then
    8265              :      no probes are needed.  */
    8266          126 :   if (!size)
    8267              :     {
    8268              :       /* However, the allocation of space via pushes for register
    8269              :          saves could be viewed as allocating space, but without the
    8270              :          need to probe.  */
    8271           43 :       if (m->frame.nregs || m->frame.nsseregs || frame_pointer_needed)
    8272           23 :         dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8273              :       else
    8274           20 :         dump_stack_clash_frame_info (NO_PROBE_NO_FRAME, false);
    8275              :       return;
    8276              :     }
    8277              : 
    8278              :   /* If we are a noreturn function, then we have to consider the
    8279              :      possibility that we're called via a jump rather than a call.
    8280              : 
    8281              :      Thus we don't have the implicit probe generated by saving the
    8282              :      return address into the stack at the call.  Thus, the stack
    8283              :      pointer could be anywhere in the guard page.  The safe thing
    8284              :      to do is emit a probe now.
    8285              : 
    8286              :      The probe can be avoided if we have already emitted any callee
    8287              :      register saves into the stack or have a frame pointer (which will
    8288              :      have been saved as well).  Those saves will function as implicit
    8289              :      probes.
    8290              : 
    8291              :      ?!? This should be revamped to work like aarch64 and s390 where
    8292              :      we track the offset from the most recent probe.  Normally that
    8293              :      offset would be zero.  For a noreturn function we would reset
    8294              :      it to PROBE_INTERVAL - (STACK_BOUNDARY / BITS_PER_UNIT).   Then
    8295              :      we just probe when we cross PROBE_INTERVAL.  */
    8296           83 :   if (TREE_THIS_VOLATILE (cfun->decl)
    8297           15 :       && !(m->frame.nregs || m->frame.nsseregs || frame_pointer_needed))
    8298              :     {
    8299              :       /* We can safely use any register here since we're just going to push
    8300              :          its value and immediately pop it back.  But we do try and avoid
    8301              :          argument passing registers so as not to introduce dependencies in
    8302              :          the pipeline.  For 32 bit we use %esi and for 64 bit we use %rax.  */
    8303           15 :       rtx dummy_reg = gen_rtx_REG (word_mode, TARGET_64BIT ? AX_REG : SI_REG);
    8304           15 :       rtx_insn *insn_push = emit_insn (gen_push (dummy_reg));
    8305           15 :       rtx_insn *insn_pop = emit_insn (gen_pop (dummy_reg));
    8306           15 :       m->fs.sp_offset -= UNITS_PER_WORD;
    8307           15 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8308              :         {
    8309           15 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    8310           15 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    8311           15 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8312           15 :           add_reg_note (insn_push, REG_CFA_ADJUST_CFA, x);
    8313           15 :           RTX_FRAME_RELATED_P (insn_push) = 1;
    8314           15 :           x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    8315           15 :           x = gen_rtx_SET (stack_pointer_rtx, x);
    8316           15 :           add_reg_note (insn_pop, REG_CFA_ADJUST_CFA, x);
    8317           15 :           RTX_FRAME_RELATED_P (insn_pop) = 1;
    8318              :         }
    8319           15 :       emit_insn (gen_blockage ());
    8320              :     }
    8321              : 
    8322           83 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8323           83 :   const int dope = 4 * UNITS_PER_WORD;
    8324              : 
    8325              :   /* If there is protection area, take it into account in the size.  */
    8326           83 :   if (protection_area)
    8327           24 :     size += probe_interval + dope;
    8328              : 
    8329              :   /* If we allocate less than the size of the guard statically,
    8330              :      then no probing is necessary, but we do need to allocate
    8331              :      the stack.  */
    8332           59 :   else if (size < (1 << param_stack_clash_protection_guard_size))
    8333              :     {
    8334           38 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8335              :                                  GEN_INT (-size), -1,
    8336           38 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    8337           38 :       dump_stack_clash_frame_info (NO_PROBE_SMALL_FRAME, true);
    8338           38 :       return;
    8339              :     }
    8340              : 
    8341              :   /* We're allocating a large enough stack frame that we need to
    8342              :      emit probes.  Either emit them inline or in a loop depending
    8343              :      on the size.  */
    8344           45 :   if (size <= 4 * probe_interval)
    8345              :     {
    8346              :       HOST_WIDE_INT i;
    8347           47 :       for (i = probe_interval; i <= size; i += probe_interval)
    8348              :         {
    8349              :           /* Allocate PROBE_INTERVAL bytes.  */
    8350           27 :           rtx insn
    8351           27 :             = pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8352              :                                          GEN_INT (-probe_interval), -1,
    8353           27 :                                          m->fs.cfa_reg == stack_pointer_rtx);
    8354           27 :           add_reg_note (insn, REG_STACK_CHECK, const0_rtx);
    8355              : 
    8356              :           /* And probe at *sp.  */
    8357           27 :           emit_stack_probe (stack_pointer_rtx);
    8358           27 :           emit_insn (gen_blockage ());
    8359              :         }
    8360              : 
    8361              :       /* We need to allocate space for the residual, but we do not need
    8362              :          to probe the residual...  */
    8363           20 :       HOST_WIDE_INT residual = (i - probe_interval - size);
    8364           20 :       if (residual)
    8365              :         {
    8366           20 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8367              :                                      GEN_INT (residual), -1,
    8368           20 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8369              : 
    8370              :           /* ...except if there is a protection area to maintain.  */
    8371           20 :           if (protection_area)
    8372           11 :             emit_stack_probe (stack_pointer_rtx);
    8373              :         }
    8374              : 
    8375           20 :       dump_stack_clash_frame_info (PROBE_INLINE, residual != 0);
    8376              :     }
    8377              :   else
    8378              :     {
    8379              :       /* We expect the GP registers to be saved when probes are used
    8380              :          as the probing sequences might need a scratch register and
    8381              :          the routine to allocate one assumes the integer registers
    8382              :          have already been saved.  */
    8383           25 :       gcc_assert (int_registers_saved);
    8384              : 
    8385           25 :       struct scratch_reg sr;
    8386           25 :       get_scratch_register_on_entry (&sr);
    8387              : 
    8388              :       /* If we needed to save a register, then account for any space
    8389              :          that was pushed (we are not going to pop the register when
    8390              :          we do the restore).  */
    8391           25 :       if (sr.saved)
    8392            0 :         size -= UNITS_PER_WORD;
    8393              : 
    8394              :       /* Step 1: round SIZE down to a multiple of the interval.  */
    8395           25 :       HOST_WIDE_INT rounded_size = size & -probe_interval;
    8396              : 
    8397              :       /* Step 2: compute final value of the loop counter.  Use lea if
    8398              :          possible.  */
    8399           25 :       rtx addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
    8400           25 :       rtx insn;
    8401           25 :       if (address_no_seg_operand (addr, Pmode))
    8402           13 :         insn = emit_insn (gen_rtx_SET (sr.reg, addr));
    8403              :       else
    8404              :         {
    8405           12 :           emit_move_insn (sr.reg, GEN_INT (-rounded_size));
    8406           12 :           insn = emit_insn (gen_rtx_SET (sr.reg,
    8407              :                                          gen_rtx_PLUS (Pmode, sr.reg,
    8408              :                                                        stack_pointer_rtx)));
    8409              :         }
    8410           25 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8411              :         {
    8412           22 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8413           22 :                         plus_constant (Pmode, sr.reg,
    8414           22 :                                        m->fs.cfa_offset + rounded_size));
    8415           22 :           RTX_FRAME_RELATED_P (insn) = 1;
    8416              :         }
    8417              : 
    8418              :       /* Step 3: the loop.  */
    8419           25 :       rtx size_rtx = GEN_INT (rounded_size);
    8420           25 :       insn = emit_insn (gen_adjust_stack_and_probe (Pmode, sr.reg, sr.reg,
    8421              :                                                     size_rtx));
    8422           25 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    8423              :         {
    8424           22 :           m->fs.cfa_offset += rounded_size;
    8425           22 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    8426           22 :                         plus_constant (Pmode, stack_pointer_rtx,
    8427           22 :                                        m->fs.cfa_offset));
    8428           22 :           RTX_FRAME_RELATED_P (insn) = 1;
    8429              :         }
    8430           25 :       m->fs.sp_offset += rounded_size;
    8431           25 :       emit_insn (gen_blockage ());
    8432              : 
    8433              :       /* Step 4: adjust SP if we cannot assert at compile-time that SIZE
    8434              :          is equal to ROUNDED_SIZE.  */
    8435              : 
    8436           25 :       if (size != rounded_size)
    8437              :         {
    8438           25 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8439              :                                      GEN_INT (rounded_size - size), -1,
    8440           25 :                                      m->fs.cfa_reg == stack_pointer_rtx);
    8441              : 
    8442           25 :           if (protection_area)
    8443           13 :             emit_stack_probe (stack_pointer_rtx);
    8444              :         }
    8445              : 
    8446           25 :       dump_stack_clash_frame_info (PROBE_LOOP, size != rounded_size);
    8447              : 
    8448              :       /* This does not deallocate the space reserved for the scratch
    8449              :          register.  That will be deallocated in the epilogue.  */
    8450           25 :       release_scratch_register_on_entry (&sr, size, false);
    8451              :     }
    8452              : 
    8453              :   /* Adjust back to account for the protection area.  */
    8454           45 :   if (protection_area)
    8455           24 :     pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    8456           24 :                                GEN_INT (probe_interval + dope), -1,
    8457           24 :                                m->fs.cfa_reg == stack_pointer_rtx);
    8458              : 
    8459              :   /* Make sure nothing is scheduled before we are done.  */
    8460           45 :   emit_insn (gen_blockage ());
    8461              : }
    8462              : 
    8463              : /* Adjust the stack pointer up to REG while probing it.  */
    8464              : 
    8465              : const char *
    8466           25 : output_adjust_stack_and_probe (rtx reg)
    8467              : {
    8468           25 :   static int labelno = 0;
    8469           25 :   char loop_lab[32];
    8470           25 :   rtx xops[2];
    8471              : 
    8472           25 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8473              : 
    8474              :   /* Loop.  */
    8475           25 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8476              : 
    8477              :   /* SP = SP + PROBE_INTERVAL.  */
    8478           25 :   xops[0] = stack_pointer_rtx;
    8479           37 :   xops[1] = GEN_INT (get_probe_interval ());
    8480           25 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8481              : 
    8482              :   /* Probe at SP.  */
    8483           25 :   xops[1] = const0_rtx;
    8484           25 :   output_asm_insn ("or{b}\t{%1, (%0)|BYTE PTR [%0], %1}", xops);
    8485              : 
    8486              :   /* Test if SP == LAST_ADDR.  */
    8487           25 :   xops[0] = stack_pointer_rtx;
    8488           25 :   xops[1] = reg;
    8489           25 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8490              : 
    8491              :   /* Branch.  */
    8492           25 :   fputs ("\tjne\t", asm_out_file);
    8493           25 :   assemble_name_raw (asm_out_file, loop_lab);
    8494           25 :   fputc ('\n', asm_out_file);
    8495              : 
    8496           25 :   return "";
    8497              : }
    8498              : 
    8499              : /* Emit code to probe a range of stack addresses from FIRST to FIRST+SIZE,
    8500              :    inclusive.  These are offsets from the current stack pointer.
    8501              : 
    8502              :    INT_REGISTERS_SAVED is true if integer registers have already been
    8503              :    pushed on the stack.  */
    8504              : 
    8505              : static void
    8506            0 : ix86_emit_probe_stack_range (HOST_WIDE_INT first, HOST_WIDE_INT size,
    8507              :                              const bool int_registers_saved)
    8508              : {
    8509            0 :   const HOST_WIDE_INT probe_interval = get_probe_interval ();
    8510              : 
    8511              :   /* See if we have a constant small number of probes to generate.  If so,
    8512              :      that's the easy case.  The run-time loop is made up of 6 insns in the
    8513              :      generic case while the compile-time loop is made up of n insns for n #
    8514              :      of intervals.  */
    8515            0 :   if (size <= 6 * probe_interval)
    8516              :     {
    8517              :       HOST_WIDE_INT i;
    8518              : 
    8519              :       /* Probe at FIRST + N * PROBE_INTERVAL for values of N from 1 until
    8520              :          it exceeds SIZE.  If only one probe is needed, this will not
    8521              :          generate any code.  Then probe at FIRST + SIZE.  */
    8522            0 :       for (i = probe_interval; i < size; i += probe_interval)
    8523            0 :         emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8524            0 :                                          -(first + i)));
    8525              : 
    8526            0 :       emit_stack_probe (plus_constant (Pmode, stack_pointer_rtx,
    8527            0 :                                        -(first + size)));
    8528              :     }
    8529              : 
    8530              :   /* Otherwise, do the same as above, but in a loop.  Note that we must be
    8531              :      extra careful with variables wrapping around because we might be at
    8532              :      the very top (or the very bottom) of the address space and we have
    8533              :      to be able to handle this case properly; in particular, we use an
    8534              :      equality test for the loop condition.  */
    8535              :   else
    8536              :     {
    8537              :       /* We expect the GP registers to be saved when probes are used
    8538              :          as the probing sequences might need a scratch register and
    8539              :          the routine to allocate one assumes the integer registers
    8540              :          have already been saved.  */
    8541            0 :       gcc_assert (int_registers_saved);
    8542              : 
    8543            0 :       HOST_WIDE_INT rounded_size, last;
    8544            0 :       struct scratch_reg sr;
    8545              : 
    8546            0 :       get_scratch_register_on_entry (&sr);
    8547              : 
    8548              : 
    8549              :       /* Step 1: round SIZE to the previous multiple of the interval.  */
    8550              : 
    8551            0 :       rounded_size = ROUND_DOWN (size, probe_interval);
    8552              : 
    8553              : 
    8554              :       /* Step 2: compute initial and final value of the loop counter.  */
    8555              : 
    8556              :       /* TEST_OFFSET = FIRST.  */
    8557            0 :       emit_move_insn (sr.reg, GEN_INT (-first));
    8558              : 
    8559              :       /* LAST_OFFSET = FIRST + ROUNDED_SIZE.  */
    8560            0 :       last = first + rounded_size;
    8561              : 
    8562              : 
    8563              :       /* Step 3: the loop
    8564              : 
    8565              :          do
    8566              :            {
    8567              :              TEST_ADDR = TEST_ADDR + PROBE_INTERVAL
    8568              :              probe at TEST_ADDR
    8569              :            }
    8570              :          while (TEST_ADDR != LAST_ADDR)
    8571              : 
    8572              :          probes at FIRST + N * PROBE_INTERVAL for values of N from 1
    8573              :          until it is equal to ROUNDED_SIZE.  */
    8574              : 
    8575            0 :       emit_insn
    8576            0 :         (gen_probe_stack_range (Pmode, sr.reg, sr.reg, GEN_INT (-last)));
    8577              : 
    8578              : 
    8579              :       /* Step 4: probe at FIRST + SIZE if we cannot assert at compile-time
    8580              :          that SIZE is equal to ROUNDED_SIZE.  */
    8581              : 
    8582            0 :       if (size != rounded_size)
    8583            0 :         emit_stack_probe (plus_constant (Pmode,
    8584            0 :                                          gen_rtx_PLUS (Pmode,
    8585              :                                                        stack_pointer_rtx,
    8586              :                                                        sr.reg),
    8587            0 :                                          rounded_size - size));
    8588              : 
    8589            0 :       release_scratch_register_on_entry (&sr, size, true);
    8590              :     }
    8591              : 
    8592              :   /* Make sure nothing is scheduled before we are done.  */
    8593            0 :   emit_insn (gen_blockage ());
    8594            0 : }
    8595              : 
    8596              : /* Probe a range of stack addresses from REG to END, inclusive.  These are
    8597              :    offsets from the current stack pointer.  */
    8598              : 
    8599              : const char *
    8600            0 : output_probe_stack_range (rtx reg, rtx end)
    8601              : {
    8602            0 :   static int labelno = 0;
    8603            0 :   char loop_lab[32];
    8604            0 :   rtx xops[3];
    8605              : 
    8606            0 :   ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
    8607              : 
    8608              :   /* Loop.  */
    8609            0 :   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
    8610              : 
    8611              :   /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL.  */
    8612            0 :   xops[0] = reg;
    8613            0 :   xops[1] = GEN_INT (get_probe_interval ());
    8614            0 :   output_asm_insn ("sub%z0\t{%1, %0|%0, %1}", xops);
    8615              : 
    8616              :   /* Probe at TEST_ADDR.  */
    8617            0 :   xops[0] = stack_pointer_rtx;
    8618            0 :   xops[1] = reg;
    8619            0 :   xops[2] = const0_rtx;
    8620            0 :   output_asm_insn ("or{b}\t{%2, (%0,%1)|BYTE PTR [%0+%1], %2}", xops);
    8621              : 
    8622              :   /* Test if TEST_ADDR == LAST_ADDR.  */
    8623            0 :   xops[0] = reg;
    8624            0 :   xops[1] = end;
    8625            0 :   output_asm_insn ("cmp%z0\t{%1, %0|%0, %1}", xops);
    8626              : 
    8627              :   /* Branch.  */
    8628            0 :   fputs ("\tjne\t", asm_out_file);
    8629            0 :   assemble_name_raw (asm_out_file, loop_lab);
    8630            0 :   fputc ('\n', asm_out_file);
    8631              : 
    8632            0 :   return "";
    8633              : }
    8634              : 
    8635              : /* Data passed to ix86_update_stack_alignment.  */
    8636              : struct stack_access_data
    8637              : {
    8638              :   /* The stack access register.  */
    8639              :   const_rtx reg;
    8640              :   /* Pointer to stack alignment.  */
    8641              :   unsigned int *stack_alignment;
    8642              : };
    8643              : 
    8644              : /* Return true if OP is a stack argument set up by the caller.  */
    8645              : 
    8646              : static bool
    8647        61842 : ix86_argument_passed_on_stack_p (const_rtx op)
    8648              : {
    8649        61842 :   tree mem_expr = MEM_EXPR (op);
    8650        61842 :   if (!mem_expr)
    8651              :     return false;
    8652              : 
    8653        59866 :   tree var = get_base_address (mem_expr);
    8654        59866 :   if (TREE_CODE (var) != PARM_DECL)
    8655              :     return false;
    8656              : 
    8657              :   /* For PARM_DECL, DECL_INCOMING_RTL holds an RTL for the stack slot
    8658              :      or register where the data was actually passed.  Return true if
    8659              :      OP is passed in memory.  */
    8660        36706 :   return DECL_INCOMING_RTL (var) && MEM_P (DECL_INCOMING_RTL (var));
    8661              : }
    8662              : 
    8663              : /* Update the maximum stack slot alignment from memory alignment in PAT.  */
    8664              : 
    8665              : static void
    8666        98885 : ix86_update_stack_alignment (rtx, const_rtx pat, void *data)
    8667              : {
    8668              :   /* This insn may reference stack slot.  Update the maximum stack slot
    8669              :      alignment if the memory is referenced by the stack access register. */
    8670        98885 :   stack_access_data *p = (stack_access_data *) data;
    8671              : 
    8672        98885 :   subrtx_iterator::array_type array;
    8673       370777 :   FOR_EACH_SUBRTX (iter, array, pat, ALL)
    8674              :     {
    8675       324158 :       auto op = *iter;
    8676       324158 :       if (MEM_P (op))
    8677              :         {
    8678              :           /* NB: Ignore arguments passed on stack since caller is
    8679              :              responsible to align the outgoing stack for arguments
    8680              :              passed on stack.  */
    8681        94933 :           if (reg_mentioned_p (p->reg, XEXP (op, 0))
    8682        94933 :               && !ix86_argument_passed_on_stack_p (op))
    8683              :             {
    8684        52266 :               unsigned int alignment = MEM_ALIGN (op);
    8685              : 
    8686        52266 :               if (alignment > *p->stack_alignment)
    8687        52161 :                 *p->stack_alignment = alignment;
    8688              :               break;
    8689              :             }
    8690              :           else
    8691        42667 :             iter.skip_subrtxes ();
    8692              :         }
    8693              :     }
    8694        98885 : }
    8695              : 
    8696              : /* Helper function for ix86_find_all_reg_uses.  */
    8697              : 
    8698              : static void
    8699     46600467 : ix86_find_all_reg_uses_1 (HARD_REG_SET &regset,
    8700              :                           rtx set, unsigned int regno,
    8701              :                           auto_bitmap &worklist)
    8702              : {
    8703     46600467 :   rtx dest = SET_DEST (set);
    8704              : 
    8705     46600467 :   if (!REG_P (dest))
    8706     42182546 :     return;
    8707              : 
    8708              :   /* Reject non-Pmode modes.  */
    8709     35333135 :   if (GET_MODE (dest) != Pmode)
    8710              :     return;
    8711              : 
    8712     18918307 :   unsigned int dst_regno = REGNO (dest);
    8713              : 
    8714     18918307 :   if (TEST_HARD_REG_BIT (regset, dst_regno))
    8715              :     return;
    8716              : 
    8717      4417921 :   const_rtx src = SET_SRC (set);
    8718              : 
    8719      4417921 :   subrtx_iterator::array_type array;
    8720      8820888 :   FOR_EACH_SUBRTX (iter, array, src, ALL)
    8721              :     {
    8722      5725045 :       auto op = *iter;
    8723              : 
    8724      5725045 :       if (MEM_P (op))
    8725      3072803 :         iter.skip_subrtxes ();
    8726              : 
    8727      5725045 :       if (REG_P (op) && REGNO (op) == regno)
    8728              :         {
    8729              :           /* Add this register to register set.  */
    8730      1489471 :           add_to_hard_reg_set (&regset, Pmode, dst_regno);
    8731      1322078 :           bitmap_set_bit (worklist, dst_regno);
    8732      1322078 :           break;
    8733              :         }
    8734              :     }
    8735      4417921 : }
    8736              : 
    8737              : /* Find all registers defined with register REGNO.  */
    8738              : 
    8739              : static void
    8740      2367068 : ix86_find_all_reg_uses (HARD_REG_SET &regset,
    8741              :                         unsigned int regno, auto_bitmap &worklist)
    8742              : {
    8743      2367068 :   for (df_ref ref = DF_REG_USE_CHAIN (regno);
    8744     84658965 :        ref != NULL;
    8745     82291897 :        ref = DF_REF_NEXT_REG (ref))
    8746              :     {
    8747     82291897 :       if (DF_REF_IS_ARTIFICIAL (ref))
    8748     17036490 :         continue;
    8749              : 
    8750     65255407 :       rtx_insn *insn = DF_REF_INSN (ref);
    8751              : 
    8752     65255407 :       if (!NONJUMP_INSN_P (insn))
    8753     19389950 :         continue;
    8754              : 
    8755     45865457 :       unsigned int ref_regno = DF_REF_REGNO (ref);
    8756              : 
    8757     45865457 :       rtx set = single_set (insn);
    8758     45865457 :       if (set)
    8759              :         {
    8760     45027643 :           ix86_find_all_reg_uses_1 (regset, set,
    8761              :                                     ref_regno, worklist);
    8762     45027643 :           continue;
    8763              :         }
    8764              : 
    8765       837814 :       rtx pat = PATTERN (insn);
    8766       837814 :       if (GET_CODE (pat) != PARALLEL)
    8767       126815 :         continue;
    8768              : 
    8769      2764234 :       for (int i = 0; i < XVECLEN (pat, 0); i++)
    8770              :         {
    8771      2053235 :           rtx exp = XVECEXP (pat, 0, i);
    8772              : 
    8773      2053235 :           if (GET_CODE (exp) == SET)
    8774      1572824 :             ix86_find_all_reg_uses_1 (regset, exp,
    8775              :                                       ref_regno, worklist);
    8776              :         }
    8777              :     }
    8778      2367068 : }
    8779              : 
    8780              : /* Return true if the hard register REGNO used for a stack access is
    8781              :    defined in a basic block that dominates the block where it is used.  */
    8782              : 
    8783              : static bool
    8784        41890 : ix86_access_stack_p (unsigned int regno, basic_block bb,
    8785              :                      HARD_REG_SET &set_up_by_prologue,
    8786              :                      HARD_REG_SET &prologue_used,
    8787              :                      auto_bitmap reg_dominate_bbs_known[],
    8788              :                      auto_bitmap reg_dominate_bbs[])
    8789              : {
    8790        41890 :   if (bitmap_bit_p (reg_dominate_bbs_known[regno], bb->index))
    8791        12135 :     return bitmap_bit_p (reg_dominate_bbs[regno], bb->index);
    8792              : 
    8793        29755 :   bitmap_set_bit (reg_dominate_bbs_known[regno], bb->index);
    8794              : 
    8795              :   /* Get all BBs which set REGNO and dominate the current BB from all
    8796              :      DEFs of REGNO.  */
    8797        29755 :   for (df_ref def = DF_REG_DEF_CHAIN (regno);
    8798      1558943 :        def;
    8799      1529188 :        def = DF_REF_NEXT_REG (def))
    8800      1557474 :     if (!DF_REF_IS_ARTIFICIAL (def)
    8801      1555762 :         && !DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)
    8802      1530120 :         && !DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER))
    8803              :       {
    8804      1528305 :         basic_block set_bb = DF_REF_BB (def);
    8805      1528305 :         if (dominated_by_p (CDI_DOMINATORS, bb, set_bb))
    8806              :           {
    8807        87830 :             rtx_insn *insn = DF_REF_INSN (def);
    8808              :             /* Return true if INSN requires stack.  */
    8809        87830 :             if (requires_stack_frame_p (insn, prologue_used,
    8810              :                                         set_up_by_prologue))
    8811              :               {
    8812        28286 :                 bitmap_set_bit (reg_dominate_bbs[regno], bb->index);
    8813        28286 :                 return true;
    8814              :               }
    8815              :           }
    8816              :       }
    8817              : 
    8818              :   /* When we get here, REGNO used in the current BB doesn't access
    8819              :      stack.  */
    8820              :   return false;
    8821              : }
    8822              : 
    8823              : /* Return true if OP isn't a memory operand with SYMBOLIC_CONST and
    8824              :    needs alignment > ALIGNMENT.  */
    8825              : 
    8826              : static bool
    8827     28284903 : ix86_need_alignment_p_2 (const_rtx op, unsigned int alignment)
    8828              : {
    8829     28284903 :   bool need_alignment = MEM_ALIGN (op) > alignment;
    8830     28284903 :   tree mem_expr = MEM_EXPR (op);
    8831     28284903 :   if (!mem_expr)
    8832              :     return need_alignment;
    8833              : 
    8834     23407796 :   tree var = get_base_address (mem_expr);
    8835     23407796 :   if (!VAR_P (var) || !DECL_RTL_SET_P (var))
    8836              :     return need_alignment;
    8837              : 
    8838     14787326 :   rtx x = DECL_RTL (var);
    8839     14787326 :   if (!MEM_P (x))
    8840              :     return need_alignment;
    8841              : 
    8842     14787323 :   x = XEXP (x, 0);
    8843     14787323 :   return !SYMBOLIC_CONST (x) && need_alignment;
    8844              : }
    8845              : 
    8846              : /* Return true if SET needs alignment > ALIGNMENT.  */
    8847              : 
    8848              : static bool
    8849     46599651 : ix86_need_alignment_p_1 (rtx set, unsigned int alignment)
    8850              : {
    8851     46599651 :   rtx dest = SET_DEST (set);
    8852              : 
    8853     46599651 :   if (MEM_P (dest))
    8854     17490262 :     return ix86_need_alignment_p_2 (dest, alignment);
    8855              : 
    8856     29109389 :   const_rtx src = SET_SRC (set);
    8857              : 
    8858     29109389 :   subrtx_iterator::array_type array;
    8859     84507922 :   FOR_EACH_SUBRTX (iter, array, src, ALL)
    8860              :     {
    8861     66193174 :       auto op = *iter;
    8862              : 
    8863     66193174 :       if (MEM_P (op))
    8864     10794641 :         return ix86_need_alignment_p_2 (op, alignment);
    8865              :     }
    8866              : 
    8867     18314748 :   return false;
    8868     29109389 : }
    8869              : 
    8870              : /* Return true if INSN needs alignment > ALIGNMENT.  */
    8871              : 
    8872              : static bool
    8873     45865457 : ix86_need_alignment_p (rtx_insn *insn, unsigned int alignment)
    8874              : {
    8875     45865457 :   rtx set = single_set (insn);
    8876     45865457 :   if (set)
    8877     45027643 :     return ix86_need_alignment_p_1 (set, alignment);
    8878              : 
    8879       837814 :   rtx pat = PATTERN (insn);
    8880       837814 :   if (GET_CODE (pat) != PARALLEL)
    8881              :     return false;
    8882              : 
    8883      2762151 :   for (int i = 0; i < XVECLEN (pat, 0); i++)
    8884              :     {
    8885      2052103 :       rtx exp = XVECEXP (pat, 0, i);
    8886              : 
    8887      2052103 :       if (GET_CODE (exp) == SET
    8888      2052103 :           && ix86_need_alignment_p_1 (exp, alignment))
    8889              :         return true;
    8890              :     }
    8891              : 
    8892              :   return false;
    8893              : }
    8894              : 
    8895              : /* Set stack_frame_required to false if stack frame isn't required.
    8896              :    Update STACK_ALIGNMENT to the largest alignment, in bits, of stack
    8897              :    slot used if stack frame is required and CHECK_STACK_SLOT is true.  */
    8898              : 
    8899              : static void
    8900      1520486 : ix86_find_max_used_stack_alignment (unsigned int &stack_alignment,
    8901              :                                     bool check_stack_slot)
    8902              : {
    8903      1520486 :   HARD_REG_SET set_up_by_prologue, prologue_used;
    8904      1520486 :   basic_block bb;
    8905              : 
    8906      6081944 :   CLEAR_HARD_REG_SET (prologue_used);
    8907      1520486 :   CLEAR_HARD_REG_SET (set_up_by_prologue);
    8908      1647248 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
    8909      1520486 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
    8910      1520486 :   add_to_hard_reg_set (&set_up_by_prologue, Pmode,
    8911              :                        HARD_FRAME_POINTER_REGNUM);
    8912              : 
    8913      1520486 :   bool require_stack_frame = false;
    8914              : 
    8915     16318688 :   FOR_EACH_BB_FN (bb, cfun)
    8916              :     {
    8917     14798202 :       rtx_insn *insn;
    8918     94452168 :       FOR_BB_INSNS (bb, insn)
    8919     87820504 :         if (NONDEBUG_INSN_P (insn)
    8920     87820504 :             && requires_stack_frame_p (insn, prologue_used,
    8921              :                                        set_up_by_prologue))
    8922              :           {
    8923              :             require_stack_frame = true;
    8924              :             break;
    8925              :           }
    8926              :     }
    8927              : 
    8928      1520486 :   cfun->machine->stack_frame_required = require_stack_frame;
    8929              : 
    8930              :   /* Stop if we don't need to check stack slot.  */
    8931      1520486 :   if (!check_stack_slot)
    8932       810038 :     return;
    8933              : 
    8934              :   /* The preferred stack alignment is the minimum stack alignment.  */
    8935       710448 :   if (stack_alignment > crtl->preferred_stack_boundary)
    8936       145749 :     stack_alignment = crtl->preferred_stack_boundary;
    8937              : 
    8938       710448 :   HARD_REG_SET stack_slot_access;
    8939       710448 :   CLEAR_HARD_REG_SET (stack_slot_access);
    8940              : 
    8941              :   /* Stack slot can be accessed by stack pointer, frame pointer or
    8942              :      registers defined by stack pointer or frame pointer.  */
    8943       710448 :   auto_bitmap worklist;
    8944              : 
    8945       770022 :   add_to_hard_reg_set (&stack_slot_access, Pmode, STACK_POINTER_REGNUM);
    8946       710448 :   bitmap_set_bit (worklist, STACK_POINTER_REGNUM);
    8947              : 
    8948       710448 :   if (frame_pointer_needed)
    8949              :     {
    8950       343593 :       add_to_hard_reg_set (&stack_slot_access, Pmode,
    8951              :                            HARD_FRAME_POINTER_REGNUM);
    8952       334542 :       bitmap_set_bit (worklist, HARD_FRAME_POINTER_REGNUM);
    8953              :     }
    8954              : 
    8955              :   /* Registers on HARD_STACK_SLOT_ACCESS always access stack.  */
    8956       710448 :   HARD_REG_SET hard_stack_slot_access = stack_slot_access;
    8957              : 
    8958       710448 :   calculate_dominance_info (CDI_DOMINATORS);
    8959              : 
    8960      2367068 :   unsigned int regno;
    8961              : 
    8962      2367068 :   do
    8963              :     {
    8964      2367068 :       regno = bitmap_clear_first_set_bit (worklist);
    8965      2367068 :       ix86_find_all_reg_uses (stack_slot_access, regno, worklist);
    8966              :     }
    8967      2367068 :   while (!bitmap_empty_p (worklist));
    8968              : 
    8969       710448 :   hard_reg_set_iterator hrsi;
    8970       710448 :   stack_access_data data;
    8971              : 
    8972    134274672 :   auto_bitmap reg_dominate_bbs_known[FIRST_PSEUDO_REGISTER];
    8973    134274672 :   auto_bitmap reg_dominate_bbs[FIRST_PSEUDO_REGISTER];
    8974              : 
    8975       710448 :   data.stack_alignment = &stack_alignment;
    8976              : 
    8977      3077516 :   EXECUTE_IF_SET_IN_HARD_REG_SET (stack_slot_access, 0, regno, hrsi)
    8978              :     {
    8979      2367068 :       for (df_ref ref = DF_REG_USE_CHAIN (regno);
    8980     84658965 :            ref != NULL;
    8981     82291897 :            ref = DF_REF_NEXT_REG (ref))
    8982              :         {
    8983     82291897 :           if (DF_REF_IS_ARTIFICIAL (ref))
    8984     17036490 :             continue;
    8985              : 
    8986     65255407 :           rtx_insn *insn = DF_REF_INSN (ref);
    8987              : 
    8988     65255407 :           if (!NONJUMP_INSN_P (insn))
    8989     19389950 :             continue;
    8990              : 
    8991              :           /* Call ix86_access_stack_p only if INSN needs alignment >
    8992              :              STACK_ALIGNMENT.  */
    8993     45865457 :           if (ix86_need_alignment_p (insn, stack_alignment)
    8994     45865457 :               && (TEST_HARD_REG_BIT (hard_stack_slot_access, regno)
    8995        41890 :                   || ix86_access_stack_p (regno, BLOCK_FOR_INSN (insn),
    8996              :                                           set_up_by_prologue,
    8997              :                                           prologue_used,
    8998              :                                           reg_dominate_bbs_known,
    8999              :                                           reg_dominate_bbs)))
    9000              :             {
    9001              :               /* Update stack alignment if REGNO is used for stack
    9002              :                  access.  */
    9003        92007 :               data.reg = DF_REF_REG (ref);
    9004        92007 :               note_stores (insn, ix86_update_stack_alignment, &data);
    9005              :             }
    9006              :         }
    9007              :     }
    9008              : 
    9009       710448 :   free_dominance_info (CDI_DOMINATORS);
    9010    135695568 : }
    9011              : 
    9012              : /* Finalize stack_realign_needed and frame_pointer_needed flags, which
    9013              :    will guide prologue/epilogue to be generated in correct form.  */
    9014              : 
    9015              : static void
    9016      3520517 : ix86_finalize_stack_frame_flags (void)
    9017              : {
    9018              :   /* Check if stack realign is really needed after reload, and
    9019              :      stores result in cfun */
    9020      3520517 :   unsigned int incoming_stack_boundary
    9021      3520517 :     = (crtl->parm_stack_boundary > ix86_incoming_stack_boundary
    9022      3520517 :        ? crtl->parm_stack_boundary : ix86_incoming_stack_boundary);
    9023      3520517 :   unsigned int stack_alignment
    9024      1215539 :     = (crtl->is_leaf && !ix86_current_function_calls_tls_descriptor
    9025      4736056 :        ? crtl->max_used_stack_slot_alignment
    9026      3520517 :        : crtl->stack_alignment_needed);
    9027      3520517 :   unsigned int stack_realign
    9028      3520517 :     = (incoming_stack_boundary < stack_alignment);
    9029      3520517 :   bool recompute_frame_layout_p = false;
    9030              : 
    9031      3520517 :   if (crtl->stack_realign_finalized)
    9032              :     {
    9033              :       /* After stack_realign_needed is finalized, we can't no longer
    9034              :          change it.  */
    9035      2000031 :       gcc_assert (crtl->stack_realign_needed == stack_realign);
    9036      2000031 :       return;
    9037              :     }
    9038              : 
    9039              :   /* It is always safe to compute max_used_stack_alignment.  We
    9040              :      compute it only if 128-bit aligned load/store may be generated
    9041              :      on misaligned stack slot which will lead to segfault. */
    9042      3040972 :   bool check_stack_slot
    9043      1520486 :     = (stack_realign || crtl->max_used_stack_slot_alignment >= 128);
    9044      1520486 :   ix86_find_max_used_stack_alignment (stack_alignment,
    9045              :                                       check_stack_slot);
    9046              : 
    9047              :   /* If the only reason for frame_pointer_needed is that we conservatively
    9048              :      assumed stack realignment might be needed or -fno-omit-frame-pointer
    9049              :      is used, but in the end nothing that needed the stack alignment had
    9050              :      been spilled nor stack access, clear frame_pointer_needed and say we
    9051              :      don't need stack realignment.
    9052              : 
    9053              :      When vector register is used for piecewise move and store, we don't
    9054              :      increase stack_alignment_needed as there is no register spill for
    9055              :      piecewise move and store.  Since stack_realign_needed is set to true
    9056              :      by checking stack_alignment_estimated which is updated by pseudo
    9057              :      vector register usage, we also need to check stack_realign_needed to
    9058              :      eliminate frame pointer.  */
    9059      1520486 :   if ((stack_realign
    9060      1453275 :        || (!flag_omit_frame_pointer && optimize)
    9061      1443025 :        || crtl->stack_realign_needed)
    9062        78188 :       && frame_pointer_needed
    9063        78188 :       && crtl->is_leaf
    9064        54001 :       && crtl->sp_is_unchanging
    9065        53952 :       && !ix86_current_function_calls_tls_descriptor
    9066        53952 :       && !crtl->accesses_prior_frames
    9067        53952 :       && !cfun->calls_alloca
    9068        53952 :       && !crtl->calls_eh_return
    9069              :       /* See ira_setup_eliminable_regset for the rationale.  */
    9070        53952 :       && !(STACK_CHECK_MOVING_SP
    9071        53952 :            && flag_stack_check
    9072            0 :            && flag_exceptions
    9073            0 :            && cfun->can_throw_non_call_exceptions)
    9074        53952 :       && !ix86_frame_pointer_required ()
    9075        53951 :       && ix86_get_frame_size () == 0
    9076        35896 :       && ix86_nsaved_sseregs () == 0
    9077      1556382 :       && ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
    9078              :     {
    9079        35896 :       if (cfun->machine->stack_frame_required)
    9080              :         {
    9081              :           /* Stack frame is required.  If stack alignment needed is less
    9082              :              than incoming stack boundary, don't realign stack.  */
    9083          284 :           stack_realign = incoming_stack_boundary < stack_alignment;
    9084          284 :           if (!stack_realign)
    9085              :             {
    9086          284 :               crtl->max_used_stack_slot_alignment
    9087          284 :                 = incoming_stack_boundary;
    9088          284 :               crtl->stack_alignment_needed
    9089          284 :                 = incoming_stack_boundary;
    9090              :               /* Also update preferred_stack_boundary for leaf
    9091              :                  functions.  */
    9092          284 :               crtl->preferred_stack_boundary
    9093          284 :                 = incoming_stack_boundary;
    9094              :             }
    9095              :         }
    9096              :       else
    9097              :         {
    9098              :           /* If drap has been set, but it actually isn't live at the
    9099              :              start of the function, there is no reason to set it up.  */
    9100        35612 :           if (crtl->drap_reg)
    9101              :             {
    9102           35 :               basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    9103           70 :               if (! REGNO_REG_SET_P (DF_LR_IN (bb),
    9104              :                                      REGNO (crtl->drap_reg)))
    9105              :                 {
    9106           35 :                   crtl->drap_reg = NULL_RTX;
    9107           35 :                   crtl->need_drap = false;
    9108              :                 }
    9109              :             }
    9110              :           else
    9111        35577 :             cfun->machine->no_drap_save_restore = true;
    9112              : 
    9113        35612 :           frame_pointer_needed = false;
    9114        35612 :           stack_realign = false;
    9115        35612 :           crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
    9116        35612 :           crtl->stack_alignment_needed = incoming_stack_boundary;
    9117        35612 :           crtl->stack_alignment_estimated = incoming_stack_boundary;
    9118        35612 :           if (crtl->preferred_stack_boundary > incoming_stack_boundary)
    9119            1 :             crtl->preferred_stack_boundary = incoming_stack_boundary;
    9120        35612 :           df_finish_pass (true);
    9121        35612 :           df_scan_alloc (NULL);
    9122        35612 :           df_scan_blocks ();
    9123        35612 :           df_compute_regs_ever_live (true);
    9124        35612 :           df_analyze ();
    9125              : 
    9126        35612 :           if (flag_var_tracking)
    9127              :             {
    9128              :               /* Since frame pointer is no longer available, replace it with
    9129              :                  stack pointer - UNITS_PER_WORD in debug insns.  */
    9130          136 :               df_ref ref, next;
    9131          136 :               for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM);
    9132          136 :                    ref; ref = next)
    9133              :                 {
    9134            0 :                   next = DF_REF_NEXT_REG (ref);
    9135            0 :                   if (!DF_REF_INSN_INFO (ref))
    9136            0 :                     continue;
    9137              : 
    9138              :                   /* Make sure the next ref is for a different instruction,
    9139              :                      so that we're not affected by the rescan.  */
    9140            0 :                   rtx_insn *insn = DF_REF_INSN (ref);
    9141            0 :                   while (next && DF_REF_INSN (next) == insn)
    9142            0 :                     next = DF_REF_NEXT_REG (next);
    9143              : 
    9144            0 :                   if (DEBUG_INSN_P (insn))
    9145              :                     {
    9146              :                       bool changed = false;
    9147            0 :                       for (; ref != next; ref = DF_REF_NEXT_REG (ref))
    9148              :                         {
    9149            0 :                           rtx *loc = DF_REF_LOC (ref);
    9150            0 :                           if (*loc == hard_frame_pointer_rtx)
    9151              :                             {
    9152            0 :                               *loc = plus_constant (Pmode,
    9153              :                                                     stack_pointer_rtx,
    9154            0 :                                                     -UNITS_PER_WORD);
    9155            0 :                               changed = true;
    9156              :                             }
    9157              :                         }
    9158            0 :                       if (changed)
    9159            0 :                         df_insn_rescan (insn);
    9160              :                     }
    9161              :                 }
    9162              :             }
    9163              : 
    9164              :           recompute_frame_layout_p = true;
    9165              :         }
    9166              :     }
    9167      1484590 :   else if (crtl->max_used_stack_slot_alignment >= 128
    9168       673556 :            && cfun->machine->stack_frame_required)
    9169              :     {
    9170              :       /* We don't need to realign stack.  max_used_stack_alignment is
    9171              :          used to decide how stack frame should be aligned.  This is
    9172              :          independent of any psABIs nor 32-bit vs 64-bit.  */
    9173       626937 :       cfun->machine->max_used_stack_alignment
    9174       626937 :         = stack_alignment / BITS_PER_UNIT;
    9175              :     }
    9176              : 
    9177      1520486 :   if (crtl->stack_realign_needed != stack_realign)
    9178        36180 :     recompute_frame_layout_p = true;
    9179      1520486 :   crtl->stack_realign_needed = stack_realign;
    9180      1520486 :   crtl->stack_realign_finalized = true;
    9181      1520486 :   if (recompute_frame_layout_p)
    9182        36274 :     ix86_compute_frame_layout ();
    9183              : }
    9184              : 
    9185              : /* Delete SET_GOT right after entry block if it is allocated to reg.  */
    9186              : 
    9187              : static void
    9188            0 : ix86_elim_entry_set_got (rtx reg)
    9189              : {
    9190            0 :   basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
    9191            0 :   rtx_insn *c_insn = BB_HEAD (bb);
    9192            0 :   if (!NONDEBUG_INSN_P (c_insn))
    9193            0 :     c_insn = next_nonnote_nondebug_insn (c_insn);
    9194            0 :   if (c_insn && NONJUMP_INSN_P (c_insn))
    9195              :     {
    9196            0 :       rtx pat = PATTERN (c_insn);
    9197            0 :       if (GET_CODE (pat) == PARALLEL)
    9198              :         {
    9199            0 :           rtx set = XVECEXP (pat, 0, 0);
    9200            0 :           if (GET_CODE (set) == SET
    9201            0 :               && GET_CODE (SET_SRC (set)) == UNSPEC
    9202            0 :               && XINT (SET_SRC (set), 1) == UNSPEC_SET_GOT
    9203            0 :               && REGNO (SET_DEST (set)) == REGNO (reg))
    9204            0 :             delete_insn (c_insn);
    9205              :         }
    9206              :     }
    9207            0 : }
    9208              : 
    9209              : static rtx
    9210       192918 : gen_frame_set (rtx reg, rtx frame_reg, int offset, bool store)
    9211              : {
    9212       192918 :   rtx addr, mem;
    9213              : 
    9214       192918 :   if (offset)
    9215       184232 :     addr = plus_constant (Pmode, frame_reg, offset);
    9216       192918 :   mem = gen_frame_mem (GET_MODE (reg), offset ? addr : frame_reg);
    9217       192918 :   return gen_rtx_SET (store ? mem : reg, store ? reg : mem);
    9218              : }
    9219              : 
    9220              : static inline rtx
    9221       100209 : gen_frame_load (rtx reg, rtx frame_reg, int offset)
    9222              : {
    9223       100209 :   return gen_frame_set (reg, frame_reg, offset, false);
    9224              : }
    9225              : 
    9226              : static inline rtx
    9227        92709 : gen_frame_store (rtx reg, rtx frame_reg, int offset)
    9228              : {
    9229        92709 :   return gen_frame_set (reg, frame_reg, offset, true);
    9230              : }
    9231              : 
    9232              : static void
    9233         7045 : ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
    9234              : {
    9235         7045 :   struct machine_function *m = cfun->machine;
    9236         7045 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
    9237         7045 :                           + m->call_ms2sysv_extra_regs;
    9238         7045 :   rtvec v = rtvec_alloc (ncregs + 1);
    9239         7045 :   unsigned int align, i, vi = 0;
    9240         7045 :   rtx_insn *insn;
    9241         7045 :   rtx sym, addr;
    9242         7045 :   rtx rax = gen_rtx_REG (word_mode, AX_REG);
    9243         7045 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
    9244              : 
    9245              :   /* AL should only be live with sysv_abi.  */
    9246         7045 :   gcc_assert (!ix86_eax_live_at_start_p ());
    9247         7045 :   gcc_assert (m->fs.sp_offset >= frame.sse_reg_save_offset);
    9248              : 
    9249              :   /* Setup RAX as the stub's base pointer.  We use stack_realign_offset rather
    9250              :      we've actually realigned the stack or not.  */
    9251         7045 :   align = GET_MODE_ALIGNMENT (V4SFmode);
    9252         7045 :   addr = choose_baseaddr (frame.stack_realign_offset
    9253         7045 :                           + xlogue.get_stub_ptr_offset (), &align, AX_REG);
    9254         7045 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
    9255              : 
    9256         7045 :   emit_insn (gen_rtx_SET (rax, addr));
    9257              : 
    9258              :   /* Get the stub symbol.  */
    9259         8327 :   sym = xlogue.get_stub_rtx (frame_pointer_needed ? XLOGUE_STUB_SAVE_HFP
    9260              :                                                   : XLOGUE_STUB_SAVE);
    9261         7045 :   RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
    9262              : 
    9263        99754 :   for (i = 0; i < ncregs; ++i)
    9264              :     {
    9265        92709 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
    9266        92709 :       rtx reg = gen_rtx_REG ((SSE_REGNO_P (r.regno) ? V4SFmode : word_mode),
    9267        92709 :                              r.regno);
    9268        92709 :       RTVEC_ELT (v, vi++) = gen_frame_store (reg, rax, -r.offset);
    9269              :     }
    9270              : 
    9271         7045 :   gcc_assert (vi == (unsigned)GET_NUM_ELEM (v));
    9272              : 
    9273         7045 :   insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
    9274         7045 :   RTX_FRAME_RELATED_P (insn) = true;
    9275         7045 : }
    9276              : 
    9277              : /* Generate and return an insn body to AND X with Y.  */
    9278              : 
    9279              : static rtx_insn *
    9280        31758 : gen_and2_insn (rtx x, rtx y)
    9281              : {
    9282        31758 :   enum insn_code icode = optab_handler (and_optab, GET_MODE (x));
    9283              : 
    9284        31758 :   gcc_assert (insn_operand_matches (icode, 0, x));
    9285        31758 :   gcc_assert (insn_operand_matches (icode, 1, x));
    9286        31758 :   gcc_assert (insn_operand_matches (icode, 2, y));
    9287              : 
    9288        31758 :   return GEN_FCN (icode) (x, x, y);
    9289              : }
    9290              : 
    9291              : /* Expand the prologue into a bunch of separate insns.  */
    9292              : 
    9293              : void
    9294      1566395 : ix86_expand_prologue (void)
    9295              : {
    9296      1566395 :   struct machine_function *m = cfun->machine;
    9297      1566395 :   rtx insn, t;
    9298      1566395 :   HOST_WIDE_INT allocate;
    9299      1566395 :   bool int_registers_saved;
    9300      1566395 :   bool sse_registers_saved;
    9301      1566395 :   bool save_stub_call_needed;
    9302      1566395 :   rtx static_chain = NULL_RTX;
    9303              : 
    9304      1566395 :   ix86_last_zero_store_uid = 0;
    9305      1566395 :   if (ix86_function_naked (current_function_decl))
    9306              :     {
    9307           76 :       if (flag_stack_usage_info)
    9308            0 :         current_function_static_stack_size = 0;
    9309              :       return;
    9310              :     }
    9311              : 
    9312      1566319 :   ix86_finalize_stack_frame_flags ();
    9313              : 
    9314              :   /* DRAP should not coexist with stack_realign_fp */
    9315      1566319 :   gcc_assert (!(crtl->drap_reg && stack_realign_fp));
    9316              : 
    9317      1566319 :   memset (&m->fs, 0, sizeof (m->fs));
    9318              : 
    9319              :   /* Initialize CFA state for before the prologue.  */
    9320      1566319 :   m->fs.cfa_reg = stack_pointer_rtx;
    9321      1566319 :   m->fs.cfa_offset = INCOMING_FRAME_SP_OFFSET;
    9322              : 
    9323              :   /* Track SP offset to the CFA.  We continue tracking this after we've
    9324              :      swapped the CFA register away from SP.  In the case of re-alignment
    9325              :      this is fudged; we're interested to offsets within the local frame.  */
    9326      1566319 :   m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    9327      1566319 :   m->fs.sp_valid = true;
    9328      1566319 :   m->fs.sp_realigned = false;
    9329              : 
    9330      1566319 :   const struct ix86_frame &frame = cfun->machine->frame;
    9331              : 
    9332      1566319 :   if (!TARGET_64BIT && ix86_function_ms_hook_prologue (current_function_decl))
    9333              :     {
    9334              :       /* We should have already generated an error for any use of
    9335              :          ms_hook on a nested function.  */
    9336            0 :       gcc_checking_assert (!ix86_static_chain_on_stack);
    9337              : 
    9338              :       /* Check if profiling is active and we shall use profiling before
    9339              :          prologue variant. If so sorry.  */
    9340            0 :       if (crtl->profile && flag_fentry != 0)
    9341            0 :         sorry ("%<ms_hook_prologue%> attribute is not compatible "
    9342              :                "with %<-mfentry%> for 32-bit");
    9343              : 
    9344              :       /* In ix86_asm_output_function_label we emitted:
    9345              :          8b ff     movl.s %edi,%edi
    9346              :          55        push   %ebp
    9347              :          8b ec     movl.s %esp,%ebp
    9348              : 
    9349              :          This matches the hookable function prologue in Win32 API
    9350              :          functions in Microsoft Windows XP Service Pack 2 and newer.
    9351              :          Wine uses this to enable Windows apps to hook the Win32 API
    9352              :          functions provided by Wine.
    9353              : 
    9354              :          What that means is that we've already set up the frame pointer.  */
    9355              : 
    9356            0 :       if (frame_pointer_needed
    9357            0 :           && !(crtl->drap_reg && crtl->stack_realign_needed))
    9358              :         {
    9359            0 :           rtx push, mov;
    9360              : 
    9361              :           /* We've decided to use the frame pointer already set up.
    9362              :              Describe this to the unwinder by pretending that both
    9363              :              push and mov insns happen right here.
    9364              : 
    9365              :              Putting the unwind info here at the end of the ms_hook
    9366              :              is done so that we can make absolutely certain we get
    9367              :              the required byte sequence at the start of the function,
    9368              :              rather than relying on an assembler that can produce
    9369              :              the exact encoding required.
    9370              : 
    9371              :              However it does mean (in the unpatched case) that we have
    9372              :              a 1 insn window where the asynchronous unwind info is
    9373              :              incorrect.  However, if we placed the unwind info at
    9374              :              its correct location we would have incorrect unwind info
    9375              :              in the patched case.  Which is probably all moot since
    9376              :              I don't expect Wine generates dwarf2 unwind info for the
    9377              :              system libraries that use this feature.  */
    9378              : 
    9379            0 :           insn = emit_insn (gen_blockage ());
    9380              : 
    9381            0 :           push = gen_push (hard_frame_pointer_rtx);
    9382            0 :           mov = gen_rtx_SET (hard_frame_pointer_rtx,
    9383              :                              stack_pointer_rtx);
    9384            0 :           RTX_FRAME_RELATED_P (push) = 1;
    9385            0 :           RTX_FRAME_RELATED_P (mov) = 1;
    9386              : 
    9387            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9388            0 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9389              :                         gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, push, mov)));
    9390              : 
    9391              :           /* Note that gen_push incremented m->fs.cfa_offset, even
    9392              :              though we didn't emit the push insn here.  */
    9393            0 :           m->fs.cfa_reg = hard_frame_pointer_rtx;
    9394            0 :           m->fs.fp_offset = m->fs.cfa_offset;
    9395            0 :           m->fs.fp_valid = true;
    9396            0 :         }
    9397              :       else
    9398              :         {
    9399              :           /* The frame pointer is not needed so pop %ebp again.
    9400              :              This leaves us with a pristine state.  */
    9401            0 :           emit_insn (gen_pop (hard_frame_pointer_rtx));
    9402              :         }
    9403              :     }
    9404              : 
    9405              :   /* The first insn of a function that accepts its static chain on the
    9406              :      stack is to push the register that would be filled in by a direct
    9407              :      call.  This insn will be skipped by the trampoline.  */
    9408      1566319 :   else if (ix86_static_chain_on_stack)
    9409              :     {
    9410            0 :       static_chain = ix86_static_chain (cfun->decl, false);
    9411            0 :       insn = emit_insn (gen_push (static_chain));
    9412            0 :       emit_insn (gen_blockage ());
    9413              : 
    9414              :       /* We don't want to interpret this push insn as a register save,
    9415              :          only as a stack adjustment.  The real copy of the register as
    9416              :          a save will be done later, if needed.  */
    9417            0 :       t = plus_constant (Pmode, stack_pointer_rtx, -UNITS_PER_WORD);
    9418            0 :       t = gen_rtx_SET (stack_pointer_rtx, t);
    9419            0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
    9420            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9421              :     }
    9422              : 
    9423              :   /* Emit prologue code to adjust stack alignment and setup DRAP, in case
    9424              :      of DRAP is needed and stack realignment is really needed after reload */
    9425      1566319 :   if (stack_realign_drap)
    9426              :     {
    9427         7012 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    9428              : 
    9429              :       /* Can't use DRAP in interrupt function.  */
    9430         7012 :       if (cfun->machine->func_type != TYPE_NORMAL)
    9431            0 :         sorry ("Dynamic Realign Argument Pointer (DRAP) not supported "
    9432              :                "in interrupt service routine.  This may be worked "
    9433              :                "around by avoiding functions with aggregate return.");
    9434              : 
    9435              :       /* Only need to push parameter pointer reg if it is caller saved.  */
    9436         7012 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    9437              :         {
    9438              :           /* Push arg pointer reg */
    9439          137 :           insn = emit_insn (gen_push (crtl->drap_reg));
    9440          137 :           RTX_FRAME_RELATED_P (insn) = 1;
    9441              :         }
    9442              : 
    9443              :       /* Grab the argument pointer.  */
    9444         7297 :       t = plus_constant (Pmode, stack_pointer_rtx, m->fs.sp_offset);
    9445         7012 :       insn = emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    9446         7012 :       RTX_FRAME_RELATED_P (insn) = 1;
    9447         7012 :       m->fs.cfa_reg = crtl->drap_reg;
    9448         7012 :       m->fs.cfa_offset = 0;
    9449              : 
    9450              :       /* Align the stack.  */
    9451         7012 :       insn = emit_insn (gen_and2_insn (stack_pointer_rtx,
    9452         7012 :                                        GEN_INT (-align_bytes)));
    9453         7012 :       RTX_FRAME_RELATED_P (insn) = 1;
    9454              : 
    9455              :       /* Replicate the return address on the stack so that return
    9456              :          address can be reached via (argp - 1) slot.  This is needed
    9457              :          to implement macro RETURN_ADDR_RTX and intrinsic function
    9458              :          expand_builtin_return_addr etc.  */
    9459         7582 :       t = plus_constant (Pmode, crtl->drap_reg, -UNITS_PER_WORD);
    9460         7012 :       t = gen_frame_mem (word_mode, t);
    9461         7012 :       insn = emit_insn (gen_push (t));
    9462         7012 :       RTX_FRAME_RELATED_P (insn) = 1;
    9463              : 
    9464              :       /* For the purposes of frame and register save area addressing,
    9465              :          we've started over with a new frame.  */
    9466         7012 :       m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
    9467         7012 :       m->fs.realigned = true;
    9468              : 
    9469         7012 :       if (static_chain)
    9470              :         {
    9471              :           /* Replicate static chain on the stack so that static chain
    9472              :              can be reached via (argp - 2) slot.  This is needed for
    9473              :              nested function with stack realignment.  */
    9474            0 :           insn = emit_insn (gen_push (static_chain));
    9475            0 :           RTX_FRAME_RELATED_P (insn) = 1;
    9476              :         }
    9477              :     }
    9478              : 
    9479      1566319 :   int_registers_saved = (frame.nregs == 0);
    9480      1566319 :   sse_registers_saved = (frame.nsseregs == 0);
    9481      1566319 :   save_stub_call_needed = (m->call_ms2sysv);
    9482      1566319 :   gcc_assert (sse_registers_saved || !save_stub_call_needed);
    9483              : 
    9484      1566319 :   if (frame_pointer_needed && !m->fs.fp_valid)
    9485              :     {
    9486              :       /* Note: AT&T enter does NOT have reversed args.  Enter is probably
    9487              :          slower on all targets.  Also sdb didn't like it.  */
    9488       497319 :       insn = emit_insn (gen_push (hard_frame_pointer_rtx));
    9489       497319 :       RTX_FRAME_RELATED_P (insn) = 1;
    9490              : 
    9491       497319 :       if (m->fs.sp_offset == frame.hard_frame_pointer_offset)
    9492              :         {
    9493       497319 :           insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
    9494       497319 :           RTX_FRAME_RELATED_P (insn) = 1;
    9495              : 
    9496       497319 :           if (m->fs.cfa_reg == stack_pointer_rtx)
    9497       490307 :             m->fs.cfa_reg = hard_frame_pointer_rtx;
    9498       497319 :           m->fs.fp_offset = m->fs.sp_offset;
    9499       497319 :           m->fs.fp_valid = true;
    9500              :         }
    9501              :     }
    9502              : 
    9503      1566319 :   if (!int_registers_saved)
    9504              :     {
    9505              :       /* If saving registers via PUSH, do so now.  */
    9506       486309 :       if (!frame.save_regs_using_mov)
    9507              :         {
    9508       440414 :           ix86_emit_save_regs ();
    9509       440414 :           m->fs.apx_ppx_used = TARGET_APX_PPX && !crtl->calls_eh_return;
    9510       440414 :           int_registers_saved = true;
    9511       440414 :           gcc_assert (m->fs.sp_offset == frame.reg_save_offset);
    9512              :         }
    9513              : 
    9514              :       /* When using red zone we may start register saving before allocating
    9515              :          the stack frame saving one cycle of the prologue.  However, avoid
    9516              :          doing this if we have to probe the stack; at least on x86_64 the
    9517              :          stack probe can turn into a call that clobbers a red zone location. */
    9518        45895 :       else if (ix86_using_red_zone ()
    9519        45895 :                 && (! TARGET_STACK_PROBE
    9520            0 :                     || frame.stack_pointer_offset < CHECK_STACK_LIMIT))
    9521              :         {
    9522        41443 :           HOST_WIDE_INT allocate_offset;
    9523        41443 :           if (crtl->shrink_wrapped_separate)
    9524              :             {
    9525        41387 :               allocate_offset = m->fs.sp_offset - frame.stack_pointer_offset;
    9526              : 
    9527              :               /* Adjust the total offset at the beginning of the function.  */
    9528        41387 :               pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9529              :                                          GEN_INT (allocate_offset), -1,
    9530        41387 :                                          m->fs.cfa_reg == stack_pointer_rtx);
    9531        41387 :               m->fs.sp_offset = cfun->machine->frame.stack_pointer_offset;
    9532              :             }
    9533              : 
    9534        41443 :           ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9535        41443 :           int_registers_saved = true;
    9536              :         }
    9537              :     }
    9538              : 
    9539      1566319 :   if (frame.red_zone_size != 0)
    9540       146770 :     cfun->machine->red_zone_used = true;
    9541              : 
    9542      1566319 :   if (stack_realign_fp)
    9543              :     {
    9544        24746 :       int align_bytes = crtl->stack_alignment_needed / BITS_PER_UNIT;
    9545        25095 :       gcc_assert (align_bytes > MIN_STACK_BOUNDARY / BITS_PER_UNIT);
    9546              : 
    9547              :       /* Record last valid frame pointer offset.  */
    9548        24746 :       m->fs.sp_realigned_fp_last = frame.reg_save_offset;
    9549              : 
    9550              :       /* The computation of the size of the re-aligned stack frame means
    9551              :          that we must allocate the size of the register save area before
    9552              :          performing the actual alignment.  Otherwise we cannot guarantee
    9553              :          that there's enough storage above the realignment point.  */
    9554        24746 :       allocate = frame.reg_save_offset - m->fs.sp_offset
    9555        24746 :                  + frame.stack_realign_allocate;
    9556        24746 :       if (allocate)
    9557         2691 :         pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9558              :                                    GEN_INT (-allocate), -1, false);
    9559              : 
    9560              :       /* Align the stack.  */
    9561        24746 :       emit_insn (gen_and2_insn (stack_pointer_rtx, GEN_INT (-align_bytes)));
    9562        24746 :       m->fs.sp_offset = ROUND_UP (m->fs.sp_offset, align_bytes);
    9563        24746 :       m->fs.sp_realigned_offset = m->fs.sp_offset
    9564        24746 :                                               - frame.stack_realign_allocate;
    9565              :       /* The stack pointer may no longer be equal to CFA - m->fs.sp_offset.
    9566              :          Beyond this point, stack access should be done via choose_baseaddr or
    9567              :          by using sp_valid_at and fp_valid_at to determine the correct base
    9568              :          register.  Henceforth, any CFA offset should be thought of as logical
    9569              :          and not physical.  */
    9570        24746 :       gcc_assert (m->fs.sp_realigned_offset >= m->fs.sp_realigned_fp_last);
    9571        24746 :       gcc_assert (m->fs.sp_realigned_offset == frame.stack_realign_offset);
    9572        24746 :       m->fs.sp_realigned = true;
    9573              : 
    9574              :       /* SEH unwind emit doesn't currently support REG_CFA_EXPRESSION, which
    9575              :          is needed to describe where a register is saved using a realigned
    9576              :          stack pointer, so we need to invalidate the stack pointer for that
    9577              :          target.  */
    9578        24746 :       if (TARGET_SEH)
    9579              :         m->fs.sp_valid = false;
    9580              : 
    9581              :       /* If SP offset is non-immediate after allocation of the stack frame,
    9582              :          then emit SSE saves or stub call prior to allocating the rest of the
    9583              :          stack frame.  This is less efficient for the out-of-line stub because
    9584              :          we can't combine allocations across the call barrier, but it's better
    9585              :          than using a scratch register.  */
    9586        24746 :       else if (!x86_64_immediate_operand (GEN_INT (frame.stack_pointer_offset
    9587              :                                                    - m->fs.sp_realigned_offset),
    9588        24746 :                                           Pmode))
    9589              :         {
    9590            3 :           if (!sse_registers_saved)
    9591              :             {
    9592            1 :               ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9593            1 :               sse_registers_saved = true;
    9594              :             }
    9595            2 :           else if (save_stub_call_needed)
    9596              :             {
    9597            1 :               ix86_emit_outlined_ms2sysv_save (frame);
    9598            1 :               save_stub_call_needed = false;
    9599              :             }
    9600              :         }
    9601              :     }
    9602              : 
    9603      1566319 :   allocate = frame.stack_pointer_offset - m->fs.sp_offset;
    9604              : 
    9605      1566319 :   if (flag_stack_usage_info)
    9606              :     {
    9607              :       /* We start to count from ARG_POINTER.  */
    9608          355 :       HOST_WIDE_INT stack_size = frame.stack_pointer_offset;
    9609              : 
    9610              :       /* If it was realigned, take into account the fake frame.  */
    9611          355 :       if (stack_realign_drap)
    9612              :         {
    9613            1 :           if (ix86_static_chain_on_stack)
    9614            0 :             stack_size += UNITS_PER_WORD;
    9615              : 
    9616            1 :           if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
    9617            0 :             stack_size += UNITS_PER_WORD;
    9618              : 
    9619              :           /* This over-estimates by 1 minimal-stack-alignment-unit but
    9620              :              mitigates that by counting in the new return address slot.  */
    9621            1 :           current_function_dynamic_stack_size
    9622            1 :             += crtl->stack_alignment_needed / BITS_PER_UNIT;
    9623              :         }
    9624              : 
    9625          355 :       current_function_static_stack_size = stack_size;
    9626              :     }
    9627              : 
    9628              :   /* On SEH target with very large frame size, allocate an area to save
    9629              :      SSE registers (as the very large allocation won't be described).  */
    9630      1566319 :   if (TARGET_SEH
    9631              :       && frame.stack_pointer_offset > SEH_MAX_FRAME_SIZE
    9632              :       && !sse_registers_saved)
    9633              :     {
    9634              :       HOST_WIDE_INT sse_size
    9635              :         = frame.sse_reg_save_offset - frame.reg_save_offset;
    9636              : 
    9637              :       gcc_assert (int_registers_saved);
    9638              : 
    9639              :       /* No need to do stack checking as the area will be immediately
    9640              :          written.  */
    9641              :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9642              :                                  GEN_INT (-sse_size), -1,
    9643              :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9644              :       allocate -= sse_size;
    9645              :       ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9646              :       sse_registers_saved = true;
    9647              :     }
    9648              : 
    9649              :   /* If stack clash protection is requested, then probe the stack, unless it
    9650              :      is already probed on the target.  */
    9651      1566319 :   if (allocate >= 0
    9652      1566315 :       && flag_stack_clash_protection
    9653      1566417 :       && !ix86_target_stack_probe ())
    9654              :     {
    9655           98 :       ix86_adjust_stack_and_probe (allocate, int_registers_saved, false);
    9656           98 :       allocate = 0;
    9657              :     }
    9658              : 
    9659              :   /* The stack has already been decremented by the instruction calling us
    9660              :      so probe if the size is non-negative to preserve the protection area.  */
    9661      1566221 :   else if (allocate >= 0 && flag_stack_check == STATIC_BUILTIN_STACK_CHECK)
    9662              :     {
    9663           45 :       const HOST_WIDE_INT probe_interval = get_probe_interval ();
    9664              : 
    9665           45 :       if (STACK_CHECK_MOVING_SP)
    9666              :         {
    9667           45 :           if (crtl->is_leaf
    9668           18 :               && !cfun->calls_alloca
    9669           18 :               && allocate <= probe_interval)
    9670              :             ;
    9671              : 
    9672              :           else
    9673              :             {
    9674           28 :               ix86_adjust_stack_and_probe (allocate, int_registers_saved, true);
    9675           28 :               allocate = 0;
    9676              :             }
    9677              :         }
    9678              : 
    9679              :       else
    9680              :         {
    9681              :           HOST_WIDE_INT size = allocate;
    9682              : 
    9683              :           if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
    9684              :             size = 0x80000000 - get_stack_check_protect () - 1;
    9685              : 
    9686              :           if (TARGET_STACK_PROBE)
    9687              :             {
    9688              :               if (crtl->is_leaf && !cfun->calls_alloca)
    9689              :                 {
    9690              :                   if (size > probe_interval)
    9691              :                     ix86_emit_probe_stack_range (0, size, int_registers_saved);
    9692              :                 }
    9693              :               else
    9694              :                 ix86_emit_probe_stack_range (0,
    9695              :                                              size + get_stack_check_protect (),
    9696              :                                              int_registers_saved);
    9697              :             }
    9698              :           else
    9699              :             {
    9700              :               if (crtl->is_leaf && !cfun->calls_alloca)
    9701              :                 {
    9702              :                   if (size > probe_interval
    9703              :                       && size > get_stack_check_protect ())
    9704              :                     ix86_emit_probe_stack_range (get_stack_check_protect (),
    9705              :                                                  (size
    9706              :                                                   - get_stack_check_protect ()),
    9707              :                                                  int_registers_saved);
    9708              :                 }
    9709              :               else
    9710              :                 ix86_emit_probe_stack_range (get_stack_check_protect (), size,
    9711              :                                              int_registers_saved);
    9712              :             }
    9713              :         }
    9714              :     }
    9715              : 
    9716      1566315 :   if (allocate == 0)
    9717              :     ;
    9718       858974 :   else if (!ix86_target_stack_probe ()
    9719       858974 :            || frame.stack_pointer_offset < CHECK_STACK_LIMIT)
    9720              :     {
    9721       858929 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
    9722              :                                  GEN_INT (-allocate), -1,
    9723       858929 :                                  m->fs.cfa_reg == stack_pointer_rtx);
    9724              :     }
    9725              :   else
    9726              :     {
    9727           45 :       rtx eax = gen_rtx_REG (Pmode, AX_REG);
    9728           45 :       rtx r10 = NULL;
    9729           45 :       const bool sp_is_cfa_reg = (m->fs.cfa_reg == stack_pointer_rtx);
    9730           45 :       bool eax_live = ix86_eax_live_at_start_p ();
    9731           45 :       bool r10_live = false;
    9732              : 
    9733           45 :       if (TARGET_64BIT)
    9734           45 :         r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
    9735              : 
    9736           45 :       if (eax_live)
    9737              :         {
    9738            0 :           insn = emit_insn (gen_push (eax));
    9739            0 :           allocate -= UNITS_PER_WORD;
    9740              :           /* Note that SEH directives need to continue tracking the stack
    9741              :              pointer even after the frame pointer has been set up.  */
    9742            0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9743              :             {
    9744            0 :               if (sp_is_cfa_reg)
    9745            0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9746            0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9747            0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9748            0 :                             gen_rtx_SET (stack_pointer_rtx,
    9749              :                                          plus_constant (Pmode,
    9750              :                                                         stack_pointer_rtx,
    9751              :                                                         -UNITS_PER_WORD)));
    9752              :             }
    9753              :         }
    9754              : 
    9755           45 :       if (r10_live)
    9756              :         {
    9757            0 :           r10 = gen_rtx_REG (Pmode, R10_REG);
    9758            0 :           insn = emit_insn (gen_push (r10));
    9759            0 :           allocate -= UNITS_PER_WORD;
    9760            0 :           if (sp_is_cfa_reg || TARGET_SEH)
    9761              :             {
    9762            0 :               if (sp_is_cfa_reg)
    9763            0 :                 m->fs.cfa_offset += UNITS_PER_WORD;
    9764            0 :               RTX_FRAME_RELATED_P (insn) = 1;
    9765            0 :               add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9766            0 :                             gen_rtx_SET (stack_pointer_rtx,
    9767              :                                          plus_constant (Pmode,
    9768              :                                                         stack_pointer_rtx,
    9769              :                                                         -UNITS_PER_WORD)));
    9770              :             }
    9771              :         }
    9772              : 
    9773           45 :       emit_move_insn (eax, GEN_INT (allocate));
    9774           45 :       emit_insn (gen_allocate_stack_worker_probe (Pmode, eax, eax));
    9775              : 
    9776              :       /* Use the fact that AX still contains ALLOCATE.  */
    9777           45 :       insn = emit_insn (gen_pro_epilogue_adjust_stack_sub
    9778           45 :                         (Pmode, stack_pointer_rtx, stack_pointer_rtx, eax));
    9779              : 
    9780           45 :       if (sp_is_cfa_reg || TARGET_SEH)
    9781              :         {
    9782           37 :           if (sp_is_cfa_reg)
    9783           37 :             m->fs.cfa_offset += allocate;
    9784           37 :           RTX_FRAME_RELATED_P (insn) = 1;
    9785           37 :           add_reg_note (insn, REG_FRAME_RELATED_EXPR,
    9786           37 :                         gen_rtx_SET (stack_pointer_rtx,
    9787              :                                      plus_constant (Pmode, stack_pointer_rtx,
    9788              :                                                     -allocate)));
    9789              :         }
    9790           45 :       m->fs.sp_offset += allocate;
    9791              : 
    9792              :       /* Use stack_pointer_rtx for relative addressing so that code works for
    9793              :          realigned stack.  But this means that we need a blockage to prevent
    9794              :          stores based on the frame pointer from being scheduled before.  */
    9795           45 :       if (r10_live && eax_live)
    9796              :         {
    9797            0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9798            0 :           emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
    9799              :                           gen_frame_mem (word_mode, t));
    9800            0 :           t = plus_constant (Pmode, t, UNITS_PER_WORD);
    9801            0 :           emit_move_insn (gen_rtx_REG (word_mode, AX_REG),
    9802              :                           gen_frame_mem (word_mode, t));
    9803            0 :           emit_insn (gen_memory_blockage ());
    9804              :         }
    9805           45 :       else if (eax_live || r10_live)
    9806              :         {
    9807            0 :           t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, eax);
    9808            0 :           emit_move_insn (gen_rtx_REG (word_mode,
    9809              :                                        (eax_live ? AX_REG : R10_REG)),
    9810              :                           gen_frame_mem (word_mode, t));
    9811            0 :           emit_insn (gen_memory_blockage ());
    9812              :         }
    9813              :     }
    9814      1566319 :   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);
    9815              : 
    9816              :   /* If we haven't already set up the frame pointer, do so now.  */
    9817      1566319 :   if (frame_pointer_needed && !m->fs.fp_valid)
    9818              :     {
    9819            0 :       insn = gen_add3_insn (hard_frame_pointer_rtx, stack_pointer_rtx,
    9820            0 :                             GEN_INT (frame.stack_pointer_offset
    9821              :                                      - frame.hard_frame_pointer_offset));
    9822            0 :       insn = emit_insn (insn);
    9823            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9824            0 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL);
    9825              : 
    9826            0 :       if (m->fs.cfa_reg == stack_pointer_rtx)
    9827            0 :         m->fs.cfa_reg = hard_frame_pointer_rtx;
    9828            0 :       m->fs.fp_offset = frame.hard_frame_pointer_offset;
    9829            0 :       m->fs.fp_valid = true;
    9830              :     }
    9831              : 
    9832      1566319 :   if (!int_registers_saved)
    9833         4452 :     ix86_emit_save_regs_using_mov (frame.reg_save_offset);
    9834      1566319 :   if (!sse_registers_saved)
    9835        33375 :     ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset);
    9836      1532944 :   else if (save_stub_call_needed)
    9837         7044 :     ix86_emit_outlined_ms2sysv_save (frame);
    9838              : 
    9839              :   /* For the mcount profiling on 32 bit PIC mode we need to emit SET_GOT
    9840              :      in PROLOGUE.  */
    9841      1566319 :   if (!TARGET_64BIT && pic_offset_table_rtx && crtl->profile && !flag_fentry)
    9842              :     {
    9843            0 :       rtx pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
    9844            0 :       insn = emit_insn (gen_set_got (pic));
    9845            0 :       RTX_FRAME_RELATED_P (insn) = 1;
    9846            0 :       add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    9847            0 :       emit_insn (gen_prologue_use (pic));
    9848              :       /* Deleting already emitted SET_GOT if exist and allocated to
    9849              :          REAL_PIC_OFFSET_TABLE_REGNUM.  */
    9850            0 :       ix86_elim_entry_set_got (pic);
    9851              :     }
    9852              : 
    9853      1566319 :   if (crtl->drap_reg && !crtl->stack_realign_needed)
    9854              :     {
    9855              :       /* vDRAP is setup but after reload it turns out stack realign
    9856              :          isn't necessary, here we will emit prologue to setup DRAP
    9857              :          without stack realign adjustment */
    9858          195 :       t = choose_baseaddr (0, NULL);
    9859          195 :       emit_insn (gen_rtx_SET (crtl->drap_reg, t));
    9860              :     }
    9861              : 
    9862              :   /* Prevent instructions from being scheduled into register save push
    9863              :      sequence when access to the redzone area is done through frame pointer.
    9864              :      The offset between the frame pointer and the stack pointer is calculated
    9865              :      relative to the value of the stack pointer at the end of the function
    9866              :      prologue, and moving instructions that access redzone area via frame
    9867              :      pointer inside push sequence violates this assumption.  */
    9868      1566319 :   if (frame_pointer_needed && frame.red_zone_size)
    9869       135716 :     emit_insn (gen_memory_blockage ());
    9870              : 
    9871              :   /* SEH requires that the prologue end within 256 bytes of the start of
    9872              :      the function.  Prevent instruction schedules that would extend that.
    9873              :      Further, prevent alloca modifications to the stack pointer from being
    9874              :      combined with prologue modifications.  */
    9875              :   if (TARGET_SEH)
    9876              :     emit_insn (gen_prologue_use (stack_pointer_rtx));
    9877              : }
    9878              : 
    9879              : /* Emit code to restore REG using a POP or POPP insn.  */
    9880              : 
    9881              : static void
    9882      1509849 : ix86_emit_restore_reg_using_pop (rtx reg, bool ppx_p)
    9883              : {
    9884      1509849 :   struct machine_function *m = cfun->machine;
    9885      1509849 :   rtx_insn *insn = emit_insn (gen_pop (reg, ppx_p));
    9886              : 
    9887      1509849 :   ix86_add_cfa_restore_note (insn, reg, m->fs.sp_offset);
    9888      1509849 :   m->fs.sp_offset -= UNITS_PER_WORD;
    9889              : 
    9890      1509849 :   if (m->fs.cfa_reg == crtl->drap_reg
    9891      1509849 :       && REGNO (reg) == REGNO (crtl->drap_reg))
    9892              :     {
    9893              :       /* Previously we'd represented the CFA as an expression
    9894              :          like *(%ebp - 8).  We've just popped that value from
    9895              :          the stack, which means we need to reset the CFA to
    9896              :          the drap register.  This will remain until we restore
    9897              :          the stack pointer.  */
    9898         3975 :       add_reg_note (insn, REG_CFA_DEF_CFA, reg);
    9899         3975 :       RTX_FRAME_RELATED_P (insn) = 1;
    9900              : 
    9901              :       /* This means that the DRAP register is valid for addressing too.  */
    9902         3975 :       m->fs.drap_valid = true;
    9903         3975 :       return;
    9904              :     }
    9905              : 
    9906      1505874 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9907              :     {
    9908      1415716 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
    9909      1051617 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9910      1051617 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9911      1051617 :       RTX_FRAME_RELATED_P (insn) = 1;
    9912              : 
    9913      1233659 :       m->fs.cfa_offset -= UNITS_PER_WORD;
    9914              :     }
    9915              : 
    9916              :   /* When the frame pointer is the CFA, and we pop it, we are
    9917              :      swapping back to the stack pointer as the CFA.  This happens
    9918              :      for stack frames that don't allocate other data, so we assume
    9919              :      the stack pointer is now pointing at the return address, i.e.
    9920              :      the function entry state, which makes the offset be 1 word.  */
    9921      1505874 :   if (reg == hard_frame_pointer_rtx)
    9922              :     {
    9923       246225 :       m->fs.fp_valid = false;
    9924       246225 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9925              :         {
    9926       242237 :           m->fs.cfa_reg = stack_pointer_rtx;
    9927       242237 :           m->fs.cfa_offset -= UNITS_PER_WORD;
    9928              : 
    9929       242237 :           add_reg_note (insn, REG_CFA_DEF_CFA,
    9930       242237 :                         plus_constant (Pmode, stack_pointer_rtx,
    9931       242237 :                                        m->fs.cfa_offset));
    9932       242237 :           RTX_FRAME_RELATED_P (insn) = 1;
    9933              :         }
    9934              :     }
    9935              : }
    9936              : 
    9937              : /* Emit code to restore REG using a POP2 insn.  */
    9938              : static void
    9939           19 : ix86_emit_restore_reg_using_pop2 (rtx reg1, rtx reg2, bool ppx_p = false)
    9940              : {
    9941           19 :   struct machine_function *m = cfun->machine;
    9942           19 :   const int offset = UNITS_PER_WORD * 2;
    9943           19 :   rtx_insn *insn;
    9944              : 
    9945           19 :   rtx mem = gen_rtx_MEM (TImode, gen_rtx_POST_INC (Pmode,
    9946              :                                                    stack_pointer_rtx));
    9947              : 
    9948           19 :   if (ppx_p)
    9949           15 :     insn = emit_insn (gen_pop2p_di (reg1, mem, reg2));
    9950              :   else
    9951            4 :     insn = emit_insn (gen_pop2_di (reg1, mem, reg2));
    9952              : 
    9953           19 :   RTX_FRAME_RELATED_P (insn) = 1;
    9954              : 
    9955           19 :   rtx dwarf = NULL_RTX;
    9956           19 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg1, dwarf);
    9957           19 :   dwarf = alloc_reg_note (REG_CFA_RESTORE, reg2, dwarf);
    9958           19 :   REG_NOTES (insn) = dwarf;
    9959           19 :   m->fs.sp_offset -= offset;
    9960              : 
    9961           19 :   if (m->fs.cfa_reg == crtl->drap_reg
    9962           19 :       && (REGNO (reg1) == REGNO (crtl->drap_reg)
    9963            3 :           || REGNO (reg2) == REGNO (crtl->drap_reg)))
    9964              :     {
    9965              :       /* Previously we'd represented the CFA as an expression
    9966              :          like *(%ebp - 8).  We've just popped that value from
    9967              :          the stack, which means we need to reset the CFA to
    9968              :          the drap register.  This will remain until we restore
    9969              :          the stack pointer.  */
    9970            1 :       add_reg_note (insn, REG_CFA_DEF_CFA,
    9971            1 :                     REGNO (reg1) == REGNO (crtl->drap_reg) ? reg1 : reg2);
    9972            1 :       RTX_FRAME_RELATED_P (insn) = 1;
    9973              : 
    9974              :       /* This means that the DRAP register is valid for addressing too.  */
    9975            1 :       m->fs.drap_valid = true;
    9976            1 :       return;
    9977              :     }
    9978              : 
    9979           18 :   if (m->fs.cfa_reg == stack_pointer_rtx)
    9980              :     {
    9981           14 :       rtx x = plus_constant (Pmode, stack_pointer_rtx, offset);
    9982           14 :       x = gen_rtx_SET (stack_pointer_rtx, x);
    9983           14 :       add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
    9984           14 :       RTX_FRAME_RELATED_P (insn) = 1;
    9985              : 
    9986           14 :       m->fs.cfa_offset -= offset;
    9987              :     }
    9988              : 
    9989              :   /* When the frame pointer is the CFA, and we pop it, we are
    9990              :      swapping back to the stack pointer as the CFA.  This happens
    9991              :      for stack frames that don't allocate other data, so we assume
    9992              :      the stack pointer is now pointing at the return address, i.e.
    9993              :      the function entry state, which makes the offset be 1 word.  */
    9994           18 :   if (reg1 == hard_frame_pointer_rtx || reg2 == hard_frame_pointer_rtx)
    9995              :     {
    9996            0 :       m->fs.fp_valid = false;
    9997            0 :       if (m->fs.cfa_reg == hard_frame_pointer_rtx)
    9998              :         {
    9999            0 :           m->fs.cfa_reg = stack_pointer_rtx;
   10000            0 :           m->fs.cfa_offset -= offset;
   10001              : 
   10002            0 :           add_reg_note (insn, REG_CFA_DEF_CFA,
   10003            0 :                         plus_constant (Pmode, stack_pointer_rtx,
   10004            0 :                                        m->fs.cfa_offset));
   10005            0 :           RTX_FRAME_RELATED_P (insn) = 1;
   10006              :         }
   10007              :     }
   10008              : }
   10009              : 
   10010              : /* Emit code to restore saved registers using POP insns.  */
   10011              : 
   10012              : static void
   10013      1389793 : ix86_emit_restore_regs_using_pop (bool ppx_p)
   10014              : {
   10015      1389793 :   unsigned int regno;
   10016              : 
   10017    132030335 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10018    130640542 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
   10019      1263302 :       ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno), ppx_p);
   10020      1389793 : }
   10021              : 
   10022              : /* Emit code to restore saved registers using POP2 insns.  */
   10023              : 
   10024              : static void
   10025          575 : ix86_emit_restore_regs_using_pop2 (void)
   10026              : {
   10027          575 :   int regno;
   10028          575 :   int regno_list[2];
   10029          575 :   regno_list[0] = regno_list[1] = -1;
   10030          575 :   int loaded_regnum = 0;
   10031          575 :   bool aligned = cfun->machine->fs.sp_offset % 16 == 0;
   10032              : 
   10033        54625 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10034        54050 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, false, true))
   10035              :       {
   10036          128 :         if (aligned)
   10037              :           {
   10038          121 :             regno_list[loaded_regnum++] = regno;
   10039          121 :             if (loaded_regnum == 2)
   10040              :               {
   10041           19 :                 gcc_assert (regno_list[0] != -1
   10042              :                             && regno_list[1] != -1
   10043              :                             && regno_list[0] != regno_list[1]);
   10044              : 
   10045           19 :                 ix86_emit_restore_reg_using_pop2 (gen_rtx_REG (word_mode,
   10046              :                                                                regno_list[0]),
   10047              :                                                   gen_rtx_REG (word_mode,
   10048              :                                                                regno_list[1]),
   10049           19 :                                                   TARGET_APX_PPX);
   10050           19 :                 loaded_regnum = 0;
   10051           19 :                 regno_list[0] = regno_list[1] = -1;
   10052              :               }
   10053              :           }
   10054              :         else
   10055              :           {
   10056           14 :             ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno),
   10057            7 :                                              TARGET_APX_PPX);
   10058            7 :             aligned = true;
   10059              :           }
   10060              :       }
   10061              : 
   10062          575 :   if (loaded_regnum == 1)
   10063           83 :     ix86_emit_restore_reg_using_pop (gen_rtx_REG (word_mode, regno_list[0]),
   10064           83 :                                      TARGET_APX_PPX);
   10065          575 : }
   10066              : 
   10067              : /* Emit code and notes for the LEAVE instruction.  If insn is non-null,
   10068              :    omits the emit and only attaches the notes.  */
   10069              : 
   10070              : static void
   10071       252398 : ix86_emit_leave (rtx_insn *insn)
   10072              : {
   10073       252398 :   struct machine_function *m = cfun->machine;
   10074              : 
   10075       252398 :   if (!insn)
   10076       251435 :     insn = emit_insn (gen_leave (word_mode));
   10077              : 
   10078       252398 :   ix86_add_queued_cfa_restore_notes (insn);
   10079              : 
   10080       252398 :   gcc_assert (m->fs.fp_valid);
   10081       252398 :   m->fs.sp_valid = true;
   10082       252398 :   m->fs.sp_realigned = false;
   10083       252398 :   m->fs.sp_offset = m->fs.fp_offset - UNITS_PER_WORD;
   10084       252398 :   m->fs.fp_valid = false;
   10085              : 
   10086       252398 :   if (m->fs.cfa_reg == hard_frame_pointer_rtx)
   10087              :     {
   10088       249266 :       m->fs.cfa_reg = stack_pointer_rtx;
   10089       249266 :       m->fs.cfa_offset = m->fs.sp_offset;
   10090              : 
   10091       249266 :       add_reg_note (insn, REG_CFA_DEF_CFA,
   10092       249266 :                     plus_constant (Pmode, stack_pointer_rtx,
   10093       249266 :                                    m->fs.sp_offset));
   10094       249266 :       RTX_FRAME_RELATED_P (insn) = 1;
   10095              :     }
   10096       252398 :   ix86_add_cfa_restore_note (insn, hard_frame_pointer_rtx,
   10097              :                              m->fs.fp_offset);
   10098       252398 : }
   10099              : 
   10100              : /* Emit code to restore saved registers using MOV insns.
   10101              :    First register is restored from CFA - CFA_OFFSET.  */
   10102              : static void
   10103        99159 : ix86_emit_restore_regs_using_mov (HOST_WIDE_INT cfa_offset,
   10104              :                                   bool maybe_eh_return)
   10105              : {
   10106        99159 :   struct machine_function *m = cfun->machine;
   10107        99159 :   unsigned int regno;
   10108              : 
   10109      9420105 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10110      9320946 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
   10111              :       {
   10112              : 
   10113              :         /* Skip registers, already processed by shrink wrap separate.  */
   10114       270971 :         if (!cfun->machine->reg_is_wrapped_separately[regno])
   10115              :           {
   10116       143966 :             rtx reg = gen_rtx_REG (word_mode, regno);
   10117       143966 :             rtx mem;
   10118       143966 :             rtx_insn *insn;
   10119              : 
   10120       143966 :             mem = choose_baseaddr (cfa_offset, NULL);
   10121       143966 :             mem = gen_frame_mem (word_mode, mem);
   10122       143966 :             insn = emit_move_insn (reg, mem);
   10123              : 
   10124       143966 :             if (m->fs.cfa_reg == crtl->drap_reg
   10125       143966 :                 && regno == REGNO (crtl->drap_reg))
   10126              :               {
   10127              :                 /* Previously we'd represented the CFA as an expression
   10128              :                    like *(%ebp - 8).  We've just popped that value from
   10129              :                    the stack, which means we need to reset the CFA to
   10130              :                    the drap register.  This will remain until we restore
   10131              :                    the stack pointer.  */
   10132         3132 :                 add_reg_note (insn, REG_CFA_DEF_CFA, reg);
   10133         3132 :                 RTX_FRAME_RELATED_P (insn) = 1;
   10134              : 
   10135              :                 /* DRAP register is valid for addressing.  */
   10136         3132 :                 m->fs.drap_valid = true;
   10137              :               }
   10138              :             else
   10139       140834 :               ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
   10140              :           }
   10141       291393 :         cfa_offset -= UNITS_PER_WORD;
   10142              :       }
   10143        99159 : }
   10144              : 
   10145              : /* Emit code to restore saved registers using MOV insns.
   10146              :    First register is restored from CFA - CFA_OFFSET.  */
   10147              : static void
   10148        33952 : ix86_emit_restore_sse_regs_using_mov (HOST_WIDE_INT cfa_offset,
   10149              :                                       bool maybe_eh_return)
   10150              : {
   10151        33952 :   unsigned int regno;
   10152              : 
   10153      3225440 :   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   10154      3191488 :     if (SSE_REGNO_P (regno) && ix86_save_reg (regno, maybe_eh_return, true))
   10155              :       {
   10156       339529 :         rtx reg = gen_rtx_REG (V4SFmode, regno);
   10157       339529 :         rtx mem;
   10158       339529 :         unsigned int align = GET_MODE_ALIGNMENT (V4SFmode);
   10159              : 
   10160       339529 :         mem = choose_baseaddr (cfa_offset, &align);
   10161       339529 :         mem = gen_rtx_MEM (V4SFmode, mem);
   10162              : 
   10163              :         /* The location alignment depends upon the base register.  */
   10164       339529 :         align = MIN (GET_MODE_ALIGNMENT (V4SFmode), align);
   10165       339529 :         gcc_assert (! (cfa_offset & (align / BITS_PER_UNIT - 1)));
   10166       339529 :         set_mem_align (mem, align);
   10167       339529 :         emit_insn (gen_rtx_SET (reg, mem));
   10168              : 
   10169       339529 :         ix86_add_cfa_restore_note (NULL, reg, cfa_offset);
   10170              : 
   10171       339529 :         cfa_offset -= GET_MODE_SIZE (V4SFmode);
   10172              :       }
   10173        33952 : }
   10174              : 
   10175              : static void
   10176         7621 : ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
   10177              :                                   bool use_call, int style)
   10178              : {
   10179         7621 :   struct machine_function *m = cfun->machine;
   10180         7621 :   const unsigned ncregs = NUM_X86_64_MS_CLOBBERED_REGS
   10181         7621 :                           + m->call_ms2sysv_extra_regs;
   10182         7621 :   rtvec v;
   10183         7621 :   unsigned int elems_needed, align, i, vi = 0;
   10184         7621 :   rtx_insn *insn;
   10185         7621 :   rtx sym, tmp;
   10186         7621 :   rtx rsi = gen_rtx_REG (word_mode, SI_REG);
   10187         7621 :   rtx r10 = NULL_RTX;
   10188         7621 :   const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
   10189         7621 :   HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
   10190         7621 :   HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
   10191         7621 :   rtx rsi_frame_load = NULL_RTX;
   10192         7621 :   HOST_WIDE_INT rsi_restore_offset = (HOST_WIDE_INT)-1;
   10193         7621 :   enum xlogue_stub stub;
   10194              : 
   10195         7621 :   gcc_assert (!m->fs.fp_valid || frame_pointer_needed);
   10196              : 
   10197              :   /* If using a realigned stack, we should never start with padding.  */
   10198         7621 :   gcc_assert (!stack_realign_fp || !xlogue.get_stack_align_off_in ());
   10199              : 
   10200              :   /* Setup RSI as the stub's base pointer.  */
   10201         7621 :   align = GET_MODE_ALIGNMENT (V4SFmode);
   10202         7621 :   tmp = choose_baseaddr (rsi_offset, &align, SI_REG);
   10203         7621 :   gcc_assert (align >= GET_MODE_ALIGNMENT (V4SFmode));
   10204              : 
   10205         7621 :   emit_insn (gen_rtx_SET (rsi, tmp));
   10206              : 
   10207              :   /* Get a symbol for the stub.  */
   10208         7621 :   if (frame_pointer_needed)
   10209         5955 :     stub = use_call ? XLOGUE_STUB_RESTORE_HFP
   10210              :                     : XLOGUE_STUB_RESTORE_HFP_TAIL;
   10211              :   else
   10212         1666 :     stub = use_call ? XLOGUE_STUB_RESTORE
   10213              :                     : XLOGUE_STUB_RESTORE_TAIL;
   10214         7621 :   sym = xlogue.get_stub_rtx (stub);
   10215              : 
   10216         7621 :   elems_needed = ncregs;
   10217         7621 :   if (use_call)
   10218         6506 :     elems_needed += 1;
   10219              :   else
   10220         1267 :     elems_needed += frame_pointer_needed ? 5 : 3;
   10221         7621 :   v = rtvec_alloc (elems_needed);
   10222              : 
   10223              :   /* We call the epilogue stub when we need to pop incoming args or we are
   10224              :      doing a sibling call as the tail.  Otherwise, we will emit a jmp to the
   10225              :      epilogue stub and it is the tail-call.  */
   10226         7621 :   if (use_call)
   10227         6506 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
   10228              :   else
   10229              :     {
   10230         1115 :       RTVEC_ELT (v, vi++) = ret_rtx;
   10231         1115 :       RTVEC_ELT (v, vi++) = gen_rtx_USE (VOIDmode, sym);
   10232         1115 :       if (frame_pointer_needed)
   10233              :         {
   10234          963 :           rtx rbp = gen_rtx_REG (DImode, BP_REG);
   10235          963 :           gcc_assert (m->fs.fp_valid);
   10236          963 :           gcc_assert (m->fs.cfa_reg == hard_frame_pointer_rtx);
   10237              : 
   10238          963 :           tmp = plus_constant (DImode, rbp, 8);
   10239          963 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, tmp);
   10240          963 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (rbp, gen_rtx_MEM (DImode, rbp));
   10241          963 :           tmp = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode));
   10242          963 :           RTVEC_ELT (v, vi++) = gen_rtx_CLOBBER (VOIDmode, tmp);
   10243              :         }
   10244              :       else
   10245              :         {
   10246              :           /* If no hard frame pointer, we set R10 to the SP restore value.  */
   10247          152 :           gcc_assert (!m->fs.fp_valid);
   10248          152 :           gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
   10249          152 :           gcc_assert (m->fs.sp_valid);
   10250              : 
   10251          152 :           r10 = gen_rtx_REG (DImode, R10_REG);
   10252          152 :           tmp = plus_constant (Pmode, rsi, stub_ptr_offset);
   10253          152 :           emit_insn (gen_rtx_SET (r10, tmp));
   10254              : 
   10255          152 :           RTVEC_ELT (v, vi++) = gen_rtx_SET (stack_pointer_rtx, r10);
   10256              :         }
   10257              :     }
   10258              : 
   10259              :   /* Generate frame load insns and restore notes.  */
   10260       107830 :   for (i = 0; i < ncregs; ++i)
   10261              :     {
   10262       100209 :       const xlogue_layout::reginfo &r = xlogue.get_reginfo (i);
   10263       100209 :       machine_mode mode = SSE_REGNO_P (r.regno) ? V4SFmode : word_mode;
   10264       100209 :       rtx reg, frame_load;
   10265              : 
   10266       100209 :       reg = gen_rtx_REG (mode, r.regno);
   10267       100209 :       frame_load = gen_frame_load (reg, rsi, r.offset);
   10268              : 
   10269              :       /* Save RSI frame load insn & note to add last.  */
   10270       100209 :       if (r.regno == SI_REG)
   10271              :         {
   10272         7621 :           gcc_assert (!rsi_frame_load);
   10273         7621 :           rsi_frame_load = frame_load;
   10274         7621 :           rsi_restore_offset = r.offset;
   10275              :         }
   10276              :       else
   10277              :         {
   10278        92588 :           RTVEC_ELT (v, vi++) = frame_load;
   10279        92588 :           ix86_add_cfa_restore_note (NULL, reg, r.offset);
   10280              :         }
   10281              :     }
   10282              : 
   10283              :   /* Add RSI frame load & restore note at the end.  */
   10284         7621 :   gcc_assert (rsi_frame_load);
   10285         7621 :   gcc_assert (rsi_restore_offset != (HOST_WIDE_INT)-1);
   10286         7621 :   RTVEC_ELT (v, vi++) = rsi_frame_load;
   10287         7621 :   ix86_add_cfa_restore_note (NULL, gen_rtx_REG (DImode, SI_REG),
   10288              :                              rsi_restore_offset);
   10289              : 
   10290              :   /* Finally, for tail-call w/o a hard frame pointer, set SP to R10.  */
   10291         7621 :   if (!use_call && !frame_pointer_needed)
   10292              :     {
   10293          152 :       gcc_assert (m->fs.sp_valid);
   10294          152 :       gcc_assert (!m->fs.sp_realigned);
   10295              : 
   10296              :       /* At this point, R10 should point to frame.stack_realign_offset.  */
   10297          152 :       if (m->fs.cfa_reg == stack_pointer_rtx)
   10298          152 :         m->fs.cfa_offset += m->fs.sp_offset - frame.stack_realign_offset;
   10299          152 :       m->fs.sp_offset = frame.stack_realign_offset;
   10300              :     }
   10301              : 
   10302         7621 :   gcc_assert (vi == (unsigned int)GET_NUM_ELEM (v));
   10303         7621 :   tmp = gen_rtx_PARALLEL (VOIDmode, v);
   10304         7621 :   if (use_call)
   10305         6506 :       insn = emit_insn (tmp);
   10306              :   else
   10307              :     {
   10308         1115 :       insn = emit_jump_insn (tmp);
   10309         1115 :       JUMP_LABEL (insn) = ret_rtx;
   10310              : 
   10311         1115 :       if (frame_pointer_needed)
   10312          963 :         ix86_emit_leave (insn);
   10313              :       else
   10314              :         {
   10315              :           /* Need CFA adjust note.  */
   10316          152 :           tmp = gen_rtx_SET (stack_pointer_rtx, r10);
   10317          152 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, tmp);
   10318              :         }
   10319              :     }
   10320              : 
   10321         7621 :   RTX_FRAME_RELATED_P (insn) = true;
   10322         7621 :   ix86_add_queued_cfa_restore_notes (insn);
   10323              : 
   10324              :   /* If we're not doing a tail-call, we need to adjust the stack.  */
   10325         7621 :   if (use_call && m->fs.sp_valid)
   10326              :     {
   10327         3706 :       HOST_WIDE_INT dealloc = m->fs.sp_offset - frame.stack_realign_offset;
   10328         3706 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10329              :                                 GEN_INT (dealloc), style,
   10330         3706 :                                 m->fs.cfa_reg == stack_pointer_rtx);
   10331              :     }
   10332         7621 : }
   10333              : 
   10334              : /* Restore function stack, frame, and registers.  */
   10335              : 
   10336              : void
   10337      1694304 : ix86_expand_epilogue (int style)
   10338              : {
   10339      1694304 :   struct machine_function *m = cfun->machine;
   10340      1694304 :   struct machine_frame_state frame_state_save = m->fs;
   10341      1694304 :   bool restore_regs_via_mov;
   10342      1694304 :   bool using_drap;
   10343      1694304 :   bool restore_stub_is_tail = false;
   10344              : 
   10345      1694304 :   if (ix86_function_naked (current_function_decl))
   10346              :     {
   10347              :       /* The program should not reach this point.  */
   10348           76 :       emit_insn (gen_ud2 ());
   10349       128032 :       return;
   10350              :     }
   10351              : 
   10352      1694228 :   ix86_finalize_stack_frame_flags ();
   10353      1694228 :   const struct ix86_frame &frame = cfun->machine->frame;
   10354              : 
   10355      1694228 :   m->fs.sp_realigned = stack_realign_fp;
   10356        31893 :   m->fs.sp_valid = stack_realign_fp
   10357      1669443 :                    || !frame_pointer_needed
   10358      2168093 :                    || crtl->sp_is_unchanging;
   10359      1694228 :   gcc_assert (!m->fs.sp_valid
   10360              :               || m->fs.sp_offset == frame.stack_pointer_offset);
   10361              : 
   10362              :   /* The FP must be valid if the frame pointer is present.  */
   10363      1694228 :   gcc_assert (frame_pointer_needed == m->fs.fp_valid);
   10364      1694228 :   gcc_assert (!m->fs.fp_valid
   10365              :               || m->fs.fp_offset == frame.hard_frame_pointer_offset);
   10366              : 
   10367              :   /* We must have *some* valid pointer to the stack frame.  */
   10368      1694228 :   gcc_assert (m->fs.sp_valid || m->fs.fp_valid);
   10369              : 
   10370              :   /* The DRAP is never valid at this point.  */
   10371      1694228 :   gcc_assert (!m->fs.drap_valid);
   10372              : 
   10373              :   /* See the comment about red zone and frame
   10374              :      pointer usage in ix86_expand_prologue.  */
   10375      1694228 :   if (frame_pointer_needed && frame.red_zone_size)
   10376       135746 :     emit_insn (gen_memory_blockage ());
   10377              : 
   10378      1694228 :   using_drap = crtl->drap_reg && crtl->stack_realign_needed;
   10379         7108 :   gcc_assert (!using_drap || m->fs.cfa_reg == crtl->drap_reg);
   10380              : 
   10381              :   /* Determine the CFA offset of the end of the red-zone.  */
   10382      1694228 :   m->fs.red_zone_offset = 0;
   10383      1694228 :   if (ix86_using_red_zone () && crtl->args.pops_args < 65536)
   10384              :     {
   10385              :       /* The red-zone begins below return address and error code in
   10386              :          exception handler.  */
   10387      1516637 :       m->fs.red_zone_offset = RED_ZONE_SIZE + INCOMING_FRAME_SP_OFFSET;
   10388              : 
   10389              :       /* When the register save area is in the aligned portion of
   10390              :          the stack, determine the maximum runtime displacement that
   10391              :          matches up with the aligned frame.  */
   10392      1516637 :       if (stack_realign_drap)
   10393         8486 :         m->fs.red_zone_offset -= (crtl->stack_alignment_needed / BITS_PER_UNIT
   10394         4243 :                                   + UNITS_PER_WORD);
   10395              :     }
   10396              : 
   10397      1694228 :   HOST_WIDE_INT reg_save_offset = frame.reg_save_offset;
   10398              : 
   10399              :   /* Special care must be taken for the normal return case of a function
   10400              :      using eh_return: the eax and edx registers are marked as saved, but
   10401              :      not restored along this path.  Adjust the save location to match.  */
   10402      1694228 :   if (crtl->calls_eh_return && style != 2)
   10403           37 :     reg_save_offset -= 2 * UNITS_PER_WORD;
   10404              : 
   10405              :   /* EH_RETURN requires the use of moves to function properly.  */
   10406      1694228 :   if (crtl->calls_eh_return)
   10407              :     restore_regs_via_mov = true;
   10408              :   /* SEH requires the use of pops to identify the epilogue.  */
   10409      1694170 :   else if (TARGET_SEH)
   10410              :     restore_regs_via_mov = false;
   10411              :   /* If we already save reg with pushp, don't use move at epilogue.  */
   10412      1694170 :   else if (m->fs.apx_ppx_used)
   10413              :     restore_regs_via_mov = false;
   10414              :   /* If we're only restoring one register and sp cannot be used then
   10415              :      using a move instruction to restore the register since it's
   10416              :      less work than reloading sp and popping the register.  */
   10417      1694082 :   else if (!sp_valid_at (frame.hfp_save_offset) && frame.nregs <= 1)
   10418              :     restore_regs_via_mov = true;
   10419      1632298 :   else if (crtl->shrink_wrapped_separate
   10420      1578776 :            || (TARGET_EPILOGUE_USING_MOVE
   10421        58252 :                && cfun->machine->use_fast_prologue_epilogue
   10422        58196 :                && (frame.nregs > 1
   10423        58182 :                    || m->fs.sp_offset != reg_save_offset)))
   10424              :     restore_regs_via_mov = true;
   10425      1578541 :   else if (frame_pointer_needed
   10426       434238 :            && !frame.nregs
   10427       337156 :            && m->fs.sp_offset != reg_save_offset)
   10428              :     restore_regs_via_mov = true;
   10429      1421813 :   else if (frame_pointer_needed
   10430       277510 :            && TARGET_USE_LEAVE
   10431       277435 :            && cfun->machine->use_fast_prologue_epilogue
   10432       220335 :            && frame.nregs == 1)
   10433              :     restore_regs_via_mov = true;
   10434              :   else
   10435      1694228 :     restore_regs_via_mov = false;
   10436              : 
   10437      1694228 :   if (crtl->shrink_wrapped_separate)
   10438        53553 :     gcc_assert (restore_regs_via_mov);
   10439              : 
   10440      1640675 :   if (restore_regs_via_mov || frame.nsseregs)
   10441              :     {
   10442              :       /* Ensure that the entire register save area is addressable via
   10443              :          the stack pointer, if we will restore SSE regs via sp.  */
   10444       337457 :       if (TARGET_64BIT
   10445       324876 :           && m->fs.sp_offset > 0x7fffffff
   10446           23 :           && sp_valid_at (frame.stack_realign_offset + 1)
   10447       337479 :           && (frame.nsseregs + frame.nregs) != 0)
   10448              :         {
   10449            6 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10450            6 :                                      GEN_INT (m->fs.sp_offset
   10451              :                                               - frame.sse_reg_save_offset),
   10452              :                                      style,
   10453            6 :                                      m->fs.cfa_reg == stack_pointer_rtx);
   10454              :         }
   10455              :     }
   10456              : 
   10457              :   /* If there are any SSE registers to restore, then we have to do it
   10458              :      via moves, since there's obviously no pop for SSE regs.  */
   10459      1694228 :   if (frame.nsseregs)
   10460        33952 :     ix86_emit_restore_sse_regs_using_mov (frame.sse_reg_save_offset,
   10461              :                                           style == 2);
   10462              : 
   10463      1694228 :   if (m->call_ms2sysv)
   10464              :     {
   10465         7621 :       int pop_incoming_args = crtl->args.pops_args && crtl->args.size;
   10466              : 
   10467              :       /* We cannot use a tail-call for the stub if:
   10468              :          1. We have to pop incoming args,
   10469              :          2. We have additional int regs to restore, or
   10470              :          3. A sibling call will be the tail-call, or
   10471              :          4. We are emitting an eh_return_internal epilogue.
   10472              : 
   10473              :          TODO: Item 4 has not yet tested!
   10474              : 
   10475              :          If any of the above are true, we will call the stub rather than
   10476              :          jump to it.  */
   10477         7621 :       restore_stub_is_tail = !(pop_incoming_args || frame.nregs || style != 1);
   10478         7621 :       ix86_emit_outlined_ms2sysv_restore (frame, !restore_stub_is_tail, style);
   10479              :     }
   10480              : 
   10481              :   /* If using out-of-line stub that is a tail-call, then...*/
   10482      1694228 :   if (m->call_ms2sysv && restore_stub_is_tail)
   10483              :     {
   10484              :       /* TODO: parinoid tests. (remove eventually)  */
   10485         1115 :       gcc_assert (m->fs.sp_valid);
   10486         1115 :       gcc_assert (!m->fs.sp_realigned);
   10487         1115 :       gcc_assert (!m->fs.fp_valid);
   10488         1115 :       gcc_assert (!m->fs.realigned);
   10489         1115 :       gcc_assert (m->fs.sp_offset == UNITS_PER_WORD);
   10490         1115 :       gcc_assert (!crtl->drap_reg);
   10491         1115 :       gcc_assert (!frame.nregs);
   10492         1115 :       gcc_assert (!crtl->shrink_wrapped_separate);
   10493              :     }
   10494      1693113 :   else if (restore_regs_via_mov)
   10495              :     {
   10496       302745 :       rtx t;
   10497              : 
   10498       302745 :       if (frame.nregs)
   10499        99159 :         ix86_emit_restore_regs_using_mov (reg_save_offset, style == 2);
   10500              : 
   10501              :       /* eh_return epilogues need %ecx added to the stack pointer.  */
   10502       302745 :       if (style == 2)
   10503              :         {
   10504           37 :           rtx sa = EH_RETURN_STACKADJ_RTX;
   10505           29 :           rtx_insn *insn;
   10506              : 
   10507           29 :           gcc_assert (!crtl->shrink_wrapped_separate);
   10508              : 
   10509              :           /* Stack realignment doesn't work with eh_return.  */
   10510           29 :           if (crtl->stack_realign_needed)
   10511            0 :             sorry ("Stack realignment not supported with "
   10512              :                    "%<__builtin_eh_return%>");
   10513              : 
   10514              :           /* regparm nested functions don't work with eh_return.  */
   10515           29 :           if (ix86_static_chain_on_stack)
   10516            0 :             sorry ("regparm nested function not supported with "
   10517              :                    "%<__builtin_eh_return%>");
   10518              : 
   10519           29 :           if (frame_pointer_needed)
   10520              :             {
   10521           35 :               t = gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, sa);
   10522           43 :               t = plus_constant (Pmode, t, m->fs.fp_offset - UNITS_PER_WORD);
   10523           27 :               emit_insn (gen_rtx_SET (sa, t));
   10524              : 
   10525              :               /* NB: eh_return epilogues must restore the frame pointer
   10526              :                  in word_mode since the upper 32 bits of RBP register
   10527              :                  can have any values.  */
   10528           27 :               t = gen_frame_mem (word_mode, hard_frame_pointer_rtx);
   10529           27 :               rtx frame_reg = gen_rtx_REG (word_mode,
   10530              :                                            HARD_FRAME_POINTER_REGNUM);
   10531           27 :               insn = emit_move_insn (frame_reg, t);
   10532              : 
   10533              :               /* Note that we use SA as a temporary CFA, as the return
   10534              :                  address is at the proper place relative to it.  We
   10535              :                  pretend this happens at the FP restore insn because
   10536              :                  prior to this insn the FP would be stored at the wrong
   10537              :                  offset relative to SA, and after this insn we have no
   10538              :                  other reasonable register to use for the CFA.  We don't
   10539              :                  bother resetting the CFA to the SP for the duration of
   10540              :                  the return insn, unless the control flow instrumentation
   10541              :                  is done.  In this case the SP is used later and we have
   10542              :                  to reset CFA to SP.  */
   10543           27 :               add_reg_note (insn, REG_CFA_DEF_CFA,
   10544           35 :                             plus_constant (Pmode, sa, UNITS_PER_WORD));
   10545           27 :               ix86_add_queued_cfa_restore_notes (insn);
   10546           27 :               add_reg_note (insn, REG_CFA_RESTORE, frame_reg);
   10547           27 :               RTX_FRAME_RELATED_P (insn) = 1;
   10548              : 
   10549           27 :               m->fs.cfa_reg = sa;
   10550           27 :               m->fs.cfa_offset = UNITS_PER_WORD;
   10551           27 :               m->fs.fp_valid = false;
   10552              : 
   10553           27 :               pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
   10554              :                                          const0_rtx, style,
   10555           27 :                                          flag_cf_protection);
   10556              :             }
   10557              :           else
   10558              :             {
   10559            2 :               t = gen_rtx_PLUS (Pmode, stack_pointer_rtx, sa);
   10560            2 :               t = plus_constant (Pmode, t, m->fs.sp_offset - UNITS_PER_WORD);
   10561            2 :               insn = emit_insn (gen_rtx_SET (stack_pointer_rtx, t));
   10562            2 :               ix86_add_queued_cfa_restore_notes (insn);
   10563              : 
   10564            2 :               gcc_assert (m->fs.cfa_reg == stack_pointer_rtx);
   10565            2 :               if (m->fs.cfa_offset != UNITS_PER_WORD)
   10566              :                 {
   10567            2 :                   m->fs.cfa_offset = UNITS_PER_WORD;
   10568            2 :                   add_reg_note (insn, REG_CFA_DEF_CFA,
   10569            2 :                                 plus_constant (Pmode, stack_pointer_rtx,
   10570            2 :                                                UNITS_PER_WORD));
   10571            2 :                   RTX_FRAME_RELATED_P (insn) = 1;
   10572              :                 }
   10573              :             }
   10574           29 :           m->fs.sp_offset = UNITS_PER_WORD;
   10575           29 :           m->fs.sp_valid = true;
   10576           29 :           m->fs.sp_realigned = false;
   10577              :         }
   10578              :     }
   10579              :   else
   10580              :     {
   10581              :       /* SEH requires that the function end with (1) a stack adjustment
   10582              :          if necessary, (2) a sequence of pops, and (3) a return or
   10583              :          jump instruction.  Prevent insns from the function body from
   10584              :          being scheduled into this sequence.  */
   10585      1390368 :       if (TARGET_SEH)
   10586              :         {
   10587              :           /* Prevent a catch region from being adjacent to the standard
   10588              :              epilogue sequence.  Unfortunately neither crtl->uses_eh_lsda
   10589              :              nor several other flags that would be interesting to test are
   10590              :              set up yet.  */
   10591              :           if (flag_non_call_exceptions)
   10592              :             emit_insn (gen_nops (const1_rtx));
   10593              :           else
   10594              :             emit_insn (gen_blockage ());
   10595              :         }
   10596              : 
   10597              :       /* First step is to deallocate the stack frame so that we can
   10598              :          pop the registers.  If the stack pointer was realigned, it needs
   10599              :          to be restored now.  Also do it on SEH target for very large
   10600              :          frame as the emitted instructions aren't allowed by the ABI
   10601              :          in epilogues.  */
   10602      1390368 :       if (!m->fs.sp_valid || m->fs.sp_realigned
   10603              :           || (TARGET_SEH
   10604              :               && (m->fs.sp_offset - reg_save_offset
   10605              :                   >= SEH_MAX_FRAME_SIZE)))
   10606              :         {
   10607        29692 :           pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx,
   10608        29692 :                                      GEN_INT (m->fs.fp_offset
   10609              :                                               - reg_save_offset),
   10610              :                                      style, false);
   10611              :         }
   10612      1360676 :       else if (m->fs.sp_offset != reg_save_offset)
   10613              :         {
   10614       626202 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10615              :                                      GEN_INT (m->fs.sp_offset
   10616              :                                               - reg_save_offset),
   10617              :                                      style,
   10618       626202 :                                      m->fs.cfa_reg == stack_pointer_rtx);
   10619              :         }
   10620              : 
   10621      1390368 :       if (TARGET_APX_PUSH2POP2
   10622          578 :           && ix86_can_use_push2pop2 ()
   10623      1390944 :           && m->func_type == TYPE_NORMAL)
   10624          575 :         ix86_emit_restore_regs_using_pop2 ();
   10625              :       else
   10626      1389793 :         ix86_emit_restore_regs_using_pop (TARGET_APX_PPX);
   10627              :     }
   10628              : 
   10629              :   /* If we used a stack pointer and haven't already got rid of it,
   10630              :      then do so now.  */
   10631      1694228 :   if (m->fs.fp_valid)
   10632              :     {
   10633              :       /* If the stack pointer is valid and pointing at the frame
   10634              :          pointer store address, then we only need a pop.  */
   10635       497660 :       if (sp_valid_at (frame.hfp_save_offset)
   10636       497660 :           && m->fs.sp_offset == frame.hfp_save_offset)
   10637       246213 :         ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10638              :       /* Leave results in shorter dependency chains on CPUs that are
   10639              :          able to grok it fast.  */
   10640       251447 :       else if (TARGET_USE_LEAVE
   10641           12 :                || optimize_bb_for_size_p (EXIT_BLOCK_PTR_FOR_FN (cfun))
   10642       251459 :                || !cfun->machine->use_fast_prologue_epilogue)
   10643       251435 :         ix86_emit_leave (NULL);
   10644              :       else
   10645              :         {
   10646           12 :           pro_epilogue_adjust_stack (stack_pointer_rtx,
   10647              :                                      hard_frame_pointer_rtx,
   10648              :                                      const0_rtx, style, !using_drap);
   10649           12 :           ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx);
   10650              :         }
   10651              :     }
   10652              : 
   10653      1694228 :   if (using_drap)
   10654              :     {
   10655         7108 :       int param_ptr_offset = UNITS_PER_WORD;
   10656         7108 :       rtx_insn *insn;
   10657              : 
   10658         7108 :       gcc_assert (stack_realign_drap);
   10659              : 
   10660         7108 :       if (ix86_static_chain_on_stack)
   10661            0 :         param_ptr_offset += UNITS_PER_WORD;
   10662         7108 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10663          232 :         param_ptr_offset += UNITS_PER_WORD;
   10664              : 
   10665         7413 :       insn = emit_insn (gen_rtx_SET
   10666              :                         (stack_pointer_rtx,
   10667              :                          plus_constant (Pmode, crtl->drap_reg,
   10668              :                                         -param_ptr_offset)));
   10669         7108 :       m->fs.cfa_reg = stack_pointer_rtx;
   10670         7108 :       m->fs.cfa_offset = param_ptr_offset;
   10671         7108 :       m->fs.sp_offset = param_ptr_offset;
   10672         7108 :       m->fs.realigned = false;
   10673              : 
   10674         7413 :       add_reg_note (insn, REG_CFA_DEF_CFA,
   10675         7108 :                     plus_constant (Pmode, stack_pointer_rtx,
   10676         7108 :                                    param_ptr_offset));
   10677         7108 :       RTX_FRAME_RELATED_P (insn) = 1;
   10678              : 
   10679         7108 :       if (!call_used_or_fixed_reg_p (REGNO (crtl->drap_reg)))
   10680          232 :         ix86_emit_restore_reg_using_pop (crtl->drap_reg);
   10681              :     }
   10682              : 
   10683              :   /* At this point the stack pointer must be valid, and we must have
   10684              :      restored all of the registers.  We may not have deallocated the
   10685              :      entire stack frame.  We've delayed this until now because it may
   10686              :      be possible to merge the local stack deallocation with the
   10687              :      deallocation forced by ix86_static_chain_on_stack.   */
   10688      1694228 :   gcc_assert (m->fs.sp_valid);
   10689      1694228 :   gcc_assert (!m->fs.sp_realigned);
   10690      1694228 :   gcc_assert (!m->fs.fp_valid);
   10691      1694228 :   gcc_assert (!m->fs.realigned);
   10692      1830021 :   if (m->fs.sp_offset != UNITS_PER_WORD)
   10693              :     {
   10694        51255 :       pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10695              :                                  GEN_INT (m->fs.sp_offset - UNITS_PER_WORD),
   10696              :                                  style, true);
   10697              :     }
   10698              :   else
   10699      1642973 :     ix86_add_queued_cfa_restore_notes (get_last_insn ());
   10700              : 
   10701              :   /* Sibcall epilogues don't want a return instruction.  */
   10702      1694228 :   if (style == 0)
   10703              :     {
   10704       127880 :       m->fs = frame_state_save;
   10705       127880 :       return;
   10706              :     }
   10707              : 
   10708      1566348 :   if (cfun->machine->func_type != TYPE_NORMAL)
   10709          120 :     emit_jump_insn (gen_interrupt_return ());
   10710      1566228 :   else if (crtl->args.pops_args && crtl->args.size)
   10711              :     {
   10712        25976 :       rtx popc = GEN_INT (crtl->args.pops_args);
   10713              : 
   10714              :       /* i386 can only pop 64K bytes.  If asked to pop more, pop return
   10715              :          address, do explicit add, and jump indirectly to the caller.  */
   10716              : 
   10717        25976 :       if (crtl->args.pops_args >= 65536)
   10718              :         {
   10719            0 :           rtx ecx = gen_rtx_REG (SImode, CX_REG);
   10720            0 :           rtx_insn *insn;
   10721              : 
   10722              :           /* There is no "pascal" calling convention in any 64bit ABI.  */
   10723            0 :           gcc_assert (!TARGET_64BIT);
   10724              : 
   10725            0 :           insn = emit_insn (gen_pop (ecx));
   10726            0 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10727            0 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10728              : 
   10729            0 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10730            0 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10731            0 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10732            0 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10733            0 :           RTX_FRAME_RELATED_P (insn) = 1;
   10734              : 
   10735            0 :           pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
   10736              :                                      popc, -1, true);
   10737            0 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10738              :         }
   10739              :       else
   10740        25976 :         emit_jump_insn (gen_simple_return_pop_internal (popc));
   10741              :     }
   10742      1540252 :   else if (!m->call_ms2sysv || !restore_stub_is_tail)
   10743              :     {
   10744              :       /* In case of return from EH a simple return cannot be used
   10745              :          as a return address will be compared with a shadow stack
   10746              :          return address.  Use indirect jump instead.  */
   10747      1539137 :       if (style == 2 && flag_cf_protection)
   10748              :         {
   10749              :           /* Register used in indirect jump must be in word_mode.  But
   10750              :              Pmode may not be the same as word_mode for x32.  */
   10751           17 :           rtx ecx = gen_rtx_REG (word_mode, CX_REG);
   10752           17 :           rtx_insn *insn;
   10753              : 
   10754           17 :           insn = emit_insn (gen_pop (ecx));
   10755           17 :           m->fs.cfa_offset -= UNITS_PER_WORD;
   10756           17 :           m->fs.sp_offset -= UNITS_PER_WORD;
   10757              : 
   10758           33 :           rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
   10759           17 :           x = gen_rtx_SET (stack_pointer_rtx, x);
   10760           17 :           add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
   10761           17 :           add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
   10762           17 :           RTX_FRAME_RELATED_P (insn) = 1;
   10763              : 
   10764           17 :           emit_jump_insn (gen_simple_return_indirect_internal (ecx));
   10765           17 :         }
   10766              :       else
   10767      1539120 :         emit_jump_insn (gen_simple_return_internal ());
   10768              :     }
   10769              : 
   10770              :   /* Restore the state back to the state from the prologue,
   10771              :      so that it's correct for the next epilogue.  */
   10772      1566348 :   m->fs = frame_state_save;
   10773              : }
   10774              : 
   10775              : /* Reset from the function's potential modifications.  */
   10776              : 
   10777              : static void
   10778      1526121 : ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED)
   10779              : {
   10780      1526121 :   if (pic_offset_table_rtx
   10781      1526121 :       && !ix86_use_pseudo_pic_reg ())
   10782            0 :     SET_REGNO (pic_offset_table_rtx, REAL_PIC_OFFSET_TABLE_REGNUM);
   10783              : 
   10784      1526121 :   if (TARGET_MACHO)
   10785              :     {
   10786              :       rtx_insn *insn = get_last_insn ();
   10787              :       rtx_insn *deleted_debug_label = NULL;
   10788              : 
   10789              :       /* Mach-O doesn't support labels at the end of objects, so if
   10790              :          it looks like we might want one, take special action.
   10791              :         First, collect any sequence of deleted debug labels.  */
   10792              :       while (insn
   10793              :              && NOTE_P (insn)
   10794              :              && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
   10795              :         {
   10796              :           /* Don't insert a nop for NOTE_INSN_DELETED_DEBUG_LABEL
   10797              :              notes only, instead set their CODE_LABEL_NUMBER to -1,
   10798              :              otherwise there would be code generation differences
   10799              :              in between -g and -g0.  */
   10800              :           if (NOTE_P (insn) && NOTE_KIND (insn)
   10801              :               == NOTE_INSN_DELETED_DEBUG_LABEL)
   10802              :             deleted_debug_label = insn;
   10803              :           insn = PREV_INSN (insn);
   10804              :         }
   10805              : 
   10806              :       /* If we have:
   10807              :          label:
   10808              :             barrier
   10809              :           then this needs to be detected, so skip past the barrier.  */
   10810              : 
   10811              :       if (insn && BARRIER_P (insn))
   10812              :         insn = PREV_INSN (insn);
   10813              : 
   10814              :       /* Up to now we've only seen notes or barriers.  */
   10815              :       if (insn)
   10816              :         {
   10817              :           if (LABEL_P (insn)
   10818              :               || (NOTE_P (insn)
   10819              :                   && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))
   10820              :             /* Trailing label.  */
   10821              :             fputs ("\tnop\n", file);
   10822              :           else if (cfun && ! cfun->is_thunk)
   10823              :             {
   10824              :               /* See if we have a completely empty function body, skipping
   10825              :                  the special case of the picbase thunk emitted as asm.  */
   10826              :               while (insn && ! INSN_P (insn))
   10827              :                 insn = PREV_INSN (insn);
   10828              :               /* If we don't find any insns, we've got an empty function body;
   10829              :                  I.e. completely empty - without a return or branch.  This is
   10830              :                  taken as the case where a function body has been removed
   10831              :                  because it contains an inline __builtin_unreachable().  GCC
   10832              :                  declares that reaching __builtin_unreachable() means UB so
   10833              :                  we're not obliged to do anything special; however, we want
   10834              :                  non-zero-sized function bodies.  To meet this, and help the
   10835              :                  user out, let's trap the case.  */
   10836              :               if (insn == NULL)
   10837              :                 fputs ("\tud2\n", file);
   10838              :             }
   10839              :         }
   10840              :       else if (deleted_debug_label)
   10841              :         for (insn = deleted_debug_label; insn; insn = NEXT_INSN (insn))
   10842              :           if (NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL)
   10843              :             CODE_LABEL_NUMBER (insn) = -1;
   10844              :     }
   10845      1526121 : }
   10846              : 
   10847              : /* Implement TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY.  */
   10848              : 
   10849              : void
   10850           59 : ix86_print_patchable_function_entry (FILE *file,
   10851              :                                      unsigned HOST_WIDE_INT patch_area_size,
   10852              :                                      bool record_p)
   10853              : {
   10854           59 :   if (cfun->machine->function_label_emitted)
   10855              :     {
   10856              :       /* NB: When ix86_print_patchable_function_entry is called after
   10857              :          function table has been emitted, we have inserted or queued
   10858              :          a pseudo UNSPECV_PATCHABLE_AREA instruction at the proper
   10859              :          place.  There is nothing to do here.  */
   10860              :       return;
   10861              :     }
   10862              : 
   10863            8 :   default_print_patchable_function_entry (file, patch_area_size,
   10864              :                                           record_p);
   10865              : }
   10866              : 
   10867              : /* Output patchable area.  NB: default_print_patchable_function_entry
   10868              :    isn't available in i386.md.  */
   10869              : 
   10870              : void
   10871           51 : ix86_output_patchable_area (unsigned int patch_area_size,
   10872              :                             bool record_p)
   10873              : {
   10874           51 :   default_print_patchable_function_entry (asm_out_file,
   10875              :                                           patch_area_size,
   10876              :                                           record_p);
   10877           51 : }
   10878              : 
   10879              : /* Return a scratch register to use in the split stack prologue.  The
   10880              :    split stack prologue is used for -fsplit-stack.  It is the first
   10881              :    instructions in the function, even before the regular prologue.
   10882              :    The scratch register can be any caller-saved register which is not
   10883              :    used for parameters or for the static chain.  */
   10884              : 
   10885              : static unsigned int
   10886        24529 : split_stack_prologue_scratch_regno (void)
   10887              : {
   10888        24529 :   if (TARGET_64BIT)
   10889              :     return R11_REG;
   10890              :   else
   10891              :     {
   10892         6862 :       bool is_fastcall, is_thiscall;
   10893         6862 :       int regparm;
   10894              : 
   10895         6862 :       is_fastcall = (lookup_attribute ("fastcall",
   10896         6862 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10897              :                      != NULL);
   10898         6862 :       is_thiscall = (lookup_attribute ("thiscall",
   10899         6862 :                                        TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)))
   10900              :                      != NULL);
   10901         6862 :       regparm = ix86_function_regparm (TREE_TYPE (cfun->decl), cfun->decl);
   10902              : 
   10903         6862 :       if (is_fastcall)
   10904              :         {
   10905            0 :           if (DECL_STATIC_CHAIN (cfun->decl))
   10906              :             {
   10907            0 :               sorry ("%<-fsplit-stack%> does not support fastcall with "
   10908              :                      "nested function");
   10909            0 :               return INVALID_REGNUM;
   10910              :             }
   10911              :           return AX_REG;
   10912              :         }
   10913         6862 :       else if (is_thiscall)
   10914              :         {
   10915            0 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10916              :             return DX_REG;
   10917            0 :           return AX_REG;
   10918              :         }
   10919         6862 :       else if (regparm < 3)
   10920              :         {
   10921         6862 :           if (!DECL_STATIC_CHAIN (cfun->decl))
   10922              :             return CX_REG;
   10923              :           else
   10924              :             {
   10925          449 :               if (regparm >= 2)
   10926              :                 {
   10927            0 :                   sorry ("%<-fsplit-stack%> does not support 2 register "
   10928              :                          "parameters for a nested function");
   10929            0 :                   return INVALID_REGNUM;
   10930              :                 }
   10931              :               return DX_REG;
   10932              :             }
   10933              :         }
   10934              :       else
   10935              :         {
   10936              :           /* FIXME: We could make this work by pushing a register
   10937              :              around the addition and comparison.  */
   10938            0 :           sorry ("%<-fsplit-stack%> does not support 3 register parameters");
   10939            0 :           return INVALID_REGNUM;
   10940              :         }
   10941              :     }
   10942              : }
   10943              : 
   10944              : /* A SYMBOL_REF for the function which allocates new stackspace for
   10945              :    -fsplit-stack.  */
   10946              : 
   10947              : static GTY(()) rtx split_stack_fn;
   10948              : 
   10949              : /* A SYMBOL_REF for the more stack function when using the large model.  */
   10950              : 
   10951              : static GTY(()) rtx split_stack_fn_large;
   10952              : 
   10953              : /* Return location of the stack guard value in the TLS block.  */
   10954              : 
   10955              : rtx
   10956       259980 : ix86_split_stack_guard (void)
   10957              : {
   10958       259980 :   int offset;
   10959       259980 :   addr_space_t as = DEFAULT_TLS_SEG_REG;
   10960       259980 :   rtx r;
   10961              : 
   10962       259980 :   gcc_assert (flag_split_stack);
   10963              : 
   10964              : #ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
   10965       259980 :   offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
   10966              : #else
   10967              :   gcc_unreachable ();
   10968              : #endif
   10969              : 
   10970       259980 :   r = GEN_INT (offset);
   10971       357953 :   r = gen_const_mem (Pmode, r);
   10972       259980 :   set_mem_addr_space (r, as);
   10973              : 
   10974       259980 :   return r;
   10975              : }
   10976              : 
   10977              : /* Handle -fsplit-stack.  These are the first instructions in the
   10978              :    function, even before the regular prologue.  */
   10979              : 
   10980              : void
   10981       259970 : ix86_expand_split_stack_prologue (void)
   10982              : {
   10983       259970 :   HOST_WIDE_INT allocate;
   10984       259970 :   unsigned HOST_WIDE_INT args_size;
   10985       259970 :   rtx_code_label *label;
   10986       259970 :   rtx limit, current, allocate_rtx, call_fusage;
   10987       259970 :   rtx_insn *call_insn;
   10988       259970 :   unsigned int scratch_regno = INVALID_REGNUM;
   10989       259970 :   rtx scratch_reg = NULL_RTX;
   10990       259970 :   rtx_code_label *varargs_label = NULL;
   10991       259970 :   rtx fn;
   10992              : 
   10993       259970 :   gcc_assert (flag_split_stack && reload_completed);
   10994              : 
   10995       259970 :   ix86_finalize_stack_frame_flags ();
   10996       259970 :   struct ix86_frame &frame = cfun->machine->frame;
   10997       259970 :   allocate = frame.stack_pointer_offset - INCOMING_FRAME_SP_OFFSET;
   10998              : 
   10999              :   /* This is the label we will branch to if we have enough stack
   11000              :      space.  We expect the basic block reordering pass to reverse this
   11001              :      branch if optimizing, so that we branch in the unlikely case.  */
   11002       259970 :   label = gen_label_rtx ();
   11003              : 
   11004              :   /* We need to compare the stack pointer minus the frame size with
   11005              :      the stack boundary in the TCB.  The stack boundary always gives
   11006              :      us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
   11007              :      can compare directly.  Otherwise we need to do an addition.  */
   11008              : 
   11009       259970 :   limit = ix86_split_stack_guard ();
   11010              : 
   11011       259970 :   if (allocate >= SPLIT_STACK_AVAILABLE
   11012       235604 :       || flag_force_indirect_call)
   11013              :     {
   11014        24381 :       scratch_regno = split_stack_prologue_scratch_regno ();
   11015        24381 :       if (scratch_regno == INVALID_REGNUM)
   11016            0 :         return;
   11017              :     }
   11018              : 
   11019       259970 :   if (allocate >= SPLIT_STACK_AVAILABLE)
   11020              :     {
   11021        24366 :       rtx offset;
   11022              : 
   11023              :       /* We need a scratch register to hold the stack pointer minus
   11024              :          the required frame size.  Since this is the very start of the
   11025              :          function, the scratch register can be any caller-saved
   11026              :          register which is not used for parameters.  */
   11027        24366 :       offset = GEN_INT (- allocate);
   11028              : 
   11029        31174 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   11030        24366 :       if (!TARGET_64BIT || x86_64_immediate_operand (offset, Pmode))
   11031              :         {
   11032              :           /* We don't use gen_add in this case because it will
   11033              :              want to split to lea, but when not optimizing the insn
   11034              :              will not be split after this point.  */
   11035        31174 :           emit_insn (gen_rtx_SET (scratch_reg,
   11036              :                                   gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   11037              :                                                 offset)));
   11038              :         }
   11039              :       else
   11040              :         {
   11041            0 :           emit_move_insn (scratch_reg, offset);
   11042            0 :           emit_insn (gen_add2_insn (scratch_reg, stack_pointer_rtx));
   11043              :         }
   11044              :       current = scratch_reg;
   11045              :     }
   11046              :   else
   11047       235604 :     current = stack_pointer_rtx;
   11048              : 
   11049       259970 :   ix86_expand_branch (GEU, current, limit, label);
   11050       259970 :   rtx_insn *jump_insn = get_last_insn ();
   11051       259970 :   JUMP_LABEL (jump_insn) = label;
   11052              : 
   11053              :   /* Mark the jump as very likely to be taken.  */
   11054       259970 :   add_reg_br_prob_note (jump_insn, profile_probability::very_likely ());
   11055              : 
   11056       259970 :   if (split_stack_fn == NULL_RTX)
   11057              :     {
   11058         5451 :       split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack");
   11059         4347 :       SYMBOL_REF_FLAGS (split_stack_fn) |= SYMBOL_FLAG_LOCAL;
   11060              :     }
   11061       259970 :   fn = split_stack_fn;
   11062              : 
   11063              :   /* Get more stack space.  We pass in the desired stack space and the
   11064              :      size of the arguments to copy to the new stack.  In 32-bit mode
   11065              :      we push the parameters; __morestack will return on a new stack
   11066              :      anyhow.  In 64-bit mode we pass the parameters in r10 and
   11067              :      r11.  */
   11068       259970 :   allocate_rtx = GEN_INT (allocate);
   11069       259970 :   args_size = crtl->args.size >= 0 ? (HOST_WIDE_INT) crtl->args.size : 0;
   11070       259970 :   call_fusage = NULL_RTX;
   11071       259970 :   rtx pop = NULL_RTX;
   11072       259970 :   if (TARGET_64BIT)
   11073              :     {
   11074       161997 :       rtx reg10, reg11;
   11075              : 
   11076       161997 :       reg10 = gen_rtx_REG (DImode, R10_REG);
   11077       161997 :       reg11 = gen_rtx_REG (DImode, R11_REG);
   11078              : 
   11079              :       /* If this function uses a static chain, it will be in %r10.
   11080              :          Preserve it across the call to __morestack.  */
   11081       161997 :       if (DECL_STATIC_CHAIN (cfun->decl))
   11082              :         {
   11083         7505 :           rtx rax;
   11084              : 
   11085         7505 :           rax = gen_rtx_REG (word_mode, AX_REG);
   11086         7505 :           emit_move_insn (rax, gen_rtx_REG (word_mode, R10_REG));
   11087         7505 :           use_reg (&call_fusage, rax);
   11088              :         }
   11089              : 
   11090       161997 :       if (flag_force_indirect_call
   11091       161982 :           || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
   11092              :         {
   11093           16 :           HOST_WIDE_INT argval;
   11094              : 
   11095           16 :           if (split_stack_fn_large == NULL_RTX)
   11096              :             {
   11097            7 :               split_stack_fn_large
   11098            7 :                 = gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model");
   11099            7 :               SYMBOL_REF_FLAGS (split_stack_fn_large) |= SYMBOL_FLAG_LOCAL;
   11100              :             }
   11101              : 
   11102           16 :           fn = split_stack_fn_large;
   11103              : 
   11104           16 :           if (ix86_cmodel == CM_LARGE_PIC)
   11105              :             {
   11106            3 :               rtx_code_label *label;
   11107            3 :               rtx x;
   11108              : 
   11109            3 :               gcc_assert (Pmode == DImode);
   11110              : 
   11111            3 :               label = gen_label_rtx ();
   11112            3 :               emit_label (label);
   11113            3 :               LABEL_PRESERVE_P (label) = 1;
   11114            3 :               emit_insn (gen_set_rip_rex64 (reg10, label));
   11115            3 :               emit_insn (gen_set_got_offset_rex64 (reg11, label));
   11116            3 :               emit_insn (gen_add2_insn (reg10, reg11));
   11117            3 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fn), UNSPEC_GOT);
   11118            3 :               x = gen_rtx_CONST (Pmode, x);
   11119            3 :               emit_move_insn (reg11, x);
   11120            3 :               x = gen_rtx_PLUS (Pmode, reg10, reg11);
   11121            3 :               x = gen_const_mem (Pmode, x);
   11122            3 :               fn = copy_to_suggested_reg (x, reg11, Pmode);
   11123              :             }
   11124           13 :           else if (ix86_cmodel == CM_LARGE)
   11125            1 :             fn = copy_to_suggested_reg (fn, reg11, Pmode);
   11126              : 
   11127              :           /* When using the large model we need to load the address
   11128              :              into a register, and we've run out of registers.  So we
   11129              :              switch to a different calling convention, and we call a
   11130              :              different function: __morestack_large.  We pass the
   11131              :              argument size in the upper 32 bits of r10 and pass the
   11132              :              frame size in the lower 32 bits.  */
   11133           16 :           gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
   11134           16 :           gcc_assert ((args_size & 0xffffffff) == args_size);
   11135              : 
   11136           16 :           argval = ((args_size << 16) << 16) + allocate;
   11137           16 :           emit_move_insn (reg10, GEN_INT (argval));
   11138           16 :         }
   11139              :       else
   11140              :         {
   11141       161981 :           emit_move_insn (reg10, allocate_rtx);
   11142       161981 :           emit_move_insn (reg11, GEN_INT (args_size));
   11143       161981 :           use_reg (&call_fusage, reg11);
   11144              :         }
   11145              : 
   11146       161997 :       use_reg (&call_fusage, reg10);
   11147              :     }
   11148              :   else
   11149              :     {
   11150        97973 :       if (flag_force_indirect_call && flag_pic)
   11151              :         {
   11152            0 :           rtx x;
   11153              : 
   11154            0 :           gcc_assert (Pmode == SImode);
   11155              : 
   11156            0 :           scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   11157              : 
   11158            0 :           emit_insn (gen_set_got (scratch_reg));
   11159            0 :           x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, split_stack_fn),
   11160              :                               UNSPEC_GOT);
   11161            0 :           x = gen_rtx_CONST (Pmode, x);
   11162            0 :           x = gen_rtx_PLUS (Pmode, scratch_reg, x);
   11163            0 :           x = gen_const_mem (Pmode, x);
   11164            0 :           fn = copy_to_suggested_reg (x, scratch_reg, Pmode);
   11165              :         }
   11166              : 
   11167        97973 :       rtx_insn *insn = emit_insn (gen_push (GEN_INT (args_size)));
   11168       195946 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (UNITS_PER_WORD));
   11169        97973 :       insn = emit_insn (gen_push (allocate_rtx));
   11170       195946 :       add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (2 * UNITS_PER_WORD));
   11171       195946 :       pop = GEN_INT (2 * UNITS_PER_WORD);
   11172              :     }
   11173              : 
   11174       259970 :   if (flag_force_indirect_call && !register_operand (fn, VOIDmode))
   11175              :     {
   11176           12 :       scratch_reg = gen_rtx_REG (word_mode, scratch_regno);
   11177              : 
   11178           12 :       if (GET_MODE (fn) != word_mode)
   11179            0 :         fn = gen_rtx_ZERO_EXTEND (word_mode, fn);
   11180              : 
   11181           12 :       fn = copy_to_suggested_reg (fn, scratch_reg, word_mode);
   11182              :     }
   11183              : 
   11184       259970 :   call_insn = ix86_expand_call (NULL_RTX, gen_rtx_MEM (QImode, fn),
   11185       259970 :                                 GEN_INT (UNITS_PER_WORD), constm1_rtx,
   11186              :                                 pop, false);
   11187       259970 :   add_function_usage_to (call_insn, call_fusage);
   11188       259970 :   if (!TARGET_64BIT)
   11189        97973 :     add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (0));
   11190              :   /* Indicate that this function can't jump to non-local gotos.  */
   11191       259970 :   make_reg_eh_region_note_nothrow_nononlocal (call_insn);
   11192              : 
   11193              :   /* In order to make call/return prediction work right, we now need
   11194              :      to execute a return instruction.  See
   11195              :      libgcc/config/i386/morestack.S for the details on how this works.
   11196              : 
   11197              :      For flow purposes gcc must not see this as a return
   11198              :      instruction--we need control flow to continue at the subsequent
   11199              :      label.  Therefore, we use an unspec.  */
   11200       259970 :   gcc_assert (crtl->args.pops_args < 65536);
   11201       259970 :   rtx_insn *ret_insn
   11202       259970 :     = emit_insn (gen_split_stack_return (GEN_INT (crtl->args.pops_args)));
   11203              : 
   11204       259970 :   if ((flag_cf_protection & CF_BRANCH))
   11205              :     {
   11206              :       /* Insert ENDBR since __morestack will jump back here via indirect
   11207              :          call.  */
   11208           21 :       rtx cet_eb = gen_nop_endbr ();
   11209           21 :       emit_insn_after (cet_eb, ret_insn);
   11210              :     }
   11211              : 
   11212              :   /* If we are in 64-bit mode and this function uses a static chain,
   11213              :      we saved %r10 in %rax before calling _morestack.  */
   11214       259970 :   if (TARGET_64BIT && DECL_STATIC_CHAIN (cfun->decl))
   11215         7505 :     emit_move_insn (gen_rtx_REG (word_mode, R10_REG),
   11216              :                     gen_rtx_REG (word_mode, AX_REG));
   11217              : 
   11218              :   /* If this function calls va_start, we need to store a pointer to
   11219              :      the arguments on the old stack, because they may not have been
   11220              :      all copied to the new stack.  At this point the old stack can be
   11221              :      found at the frame pointer value used by __morestack, because
   11222              :      __morestack has set that up before calling back to us.  Here we
   11223              :      store that pointer in a scratch register, and in
   11224              :      ix86_expand_prologue we store the scratch register in a stack
   11225              :      slot.  */
   11226       259970 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   11227              :     {
   11228           12 :       rtx frame_reg;
   11229           12 :       int words;
   11230              : 
   11231           12 :       scratch_regno = split_stack_prologue_scratch_regno ();
   11232           16 :       scratch_reg = gen_rtx_REG (Pmode, scratch_regno);
   11233           16 :       frame_reg = gen_rtx_REG (Pmode, BP_REG);
   11234              : 
   11235              :       /* 64-bit:
   11236              :          fp -> old fp value
   11237              :                return address within this function
   11238              :                return address of caller of this function
   11239              :                stack arguments
   11240              :          So we add three words to get to the stack arguments.
   11241              : 
   11242              :          32-bit:
   11243              :          fp -> old fp value
   11244              :                return address within this function
   11245              :                first argument to __morestack
   11246              :                second argument to __morestack
   11247              :                return address of caller of this function
   11248              :                stack arguments
   11249              :          So we add five words to get to the stack arguments.
   11250              :       */
   11251           12 :       words = TARGET_64BIT ? 3 : 5;
   11252           20 :       emit_insn (gen_rtx_SET (scratch_reg,
   11253              :                               plus_constant (Pmode, frame_reg,
   11254              :                                              words * UNITS_PER_WORD)));
   11255              : 
   11256           12 :       varargs_label = gen_label_rtx ();
   11257           12 :       emit_jump_insn (gen_jump (varargs_label));
   11258           12 :       JUMP_LABEL (get_last_insn ()) = varargs_label;
   11259              : 
   11260           12 :       emit_barrier ();
   11261              :     }
   11262              : 
   11263       259970 :   emit_label (label);
   11264       259970 :   LABEL_NUSES (label) = 1;
   11265              : 
   11266              :   /* If this function calls va_start, we now have to set the scratch
   11267              :      register for the case where we do not call __morestack.  In this
   11268              :      case we need to set it based on the stack pointer.  */
   11269       259970 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   11270              :     {
   11271           20 :       emit_insn (gen_rtx_SET (scratch_reg,
   11272              :                               plus_constant (Pmode, stack_pointer_rtx,
   11273              :                                              UNITS_PER_WORD)));
   11274              : 
   11275           12 :       emit_label (varargs_label);
   11276           12 :       LABEL_NUSES (varargs_label) = 1;
   11277              :     }
   11278              : }
   11279              : 
   11280              : /* We may have to tell the dataflow pass that the split stack prologue
   11281              :    is initializing a scratch register.  */
   11282              : 
   11283              : static void
   11284     16279703 : ix86_live_on_entry (bitmap regs)
   11285              : {
   11286     16279703 :   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
   11287              :     {
   11288          124 :       gcc_assert (flag_split_stack);
   11289          124 :       bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());
   11290              :     }
   11291     16279703 : }
   11292              : 
   11293              : /* Extract the parts of an RTL expression that is a valid memory address
   11294              :    for an instruction.  Return false if the structure of the address is
   11295              :    grossly off.  */
   11296              : 
   11297              : bool
   11298   4366235458 : ix86_decompose_address (rtx addr, struct ix86_address *out)
   11299              : {
   11300   4366235458 :   rtx base = NULL_RTX, index = NULL_RTX, disp = NULL_RTX;
   11301   4366235458 :   rtx base_reg, index_reg;
   11302   4366235458 :   HOST_WIDE_INT scale = 1;
   11303   4366235458 :   rtx scale_rtx = NULL_RTX;
   11304   4366235458 :   rtx tmp;
   11305   4366235458 :   addr_space_t seg = ADDR_SPACE_GENERIC;
   11306              : 
   11307              :   /* Allow zero-extended SImode addresses,
   11308              :      they will be emitted with addr32 prefix.  */
   11309   4366235458 :   if (TARGET_64BIT && GET_MODE (addr) == DImode)
   11310              :     {
   11311   2324731084 :       if (GET_CODE (addr) == ZERO_EXTEND
   11312      2076601 :           && GET_MODE (XEXP (addr, 0)) == SImode)
   11313              :         {
   11314      1970798 :           addr = XEXP (addr, 0);
   11315      1970798 :           if (CONST_INT_P (addr))
   11316              :             return false;
   11317              :         }
   11318   2322760286 :       else if (GET_CODE (addr) == AND)
   11319              :         {
   11320      2927190 :           rtx mask = XEXP (addr, 1);
   11321      2927190 :           rtx shift_val;
   11322              : 
   11323      2927190 :           if (const_32bit_mask (mask, DImode)
   11324              :               /* For ASHIFT inside AND, combine will not generate
   11325              :                  canonical zero-extend. Merge mask for AND and shift_count
   11326              :                  to check if it is canonical zero-extend.  */
   11327      2927190 :               || (CONST_INT_P (mask)
   11328      1914552 :                   && GET_CODE (XEXP (addr, 0)) == ASHIFT
   11329       156490 :                   && CONST_INT_P (shift_val = XEXP (XEXP (addr, 0), 1))
   11330       153384 :                   && ((UINTVAL (mask)
   11331       153384 :                        | ((HOST_WIDE_INT_1U << INTVAL (shift_val)) - 1))
   11332              :                       == HOST_WIDE_INT_UC (0xffffffff))))
   11333              :             {
   11334        83417 :               addr = lowpart_subreg (SImode, XEXP (addr, 0), DImode);
   11335        83417 :               if (addr == NULL_RTX)
   11336              :                 return false;
   11337              : 
   11338        83417 :               if (CONST_INT_P (addr))
   11339              :                 return false;
   11340              :             }
   11341              :         }
   11342              :     }
   11343              : 
   11344              :   /* Allow SImode subregs of DImode addresses,
   11345              :      they will be emitted with addr32 prefix.  */
   11346   4366235458 :   if (TARGET_64BIT && GET_MODE (addr) == SImode)
   11347              :     {
   11348     17072860 :       if (SUBREG_P (addr)
   11349       245132 :           && GET_MODE (SUBREG_REG (addr)) == DImode)
   11350              :         {
   11351       217513 :           addr = SUBREG_REG (addr);
   11352       217513 :           if (CONST_INT_P (addr))
   11353              :             return false;
   11354              :         }
   11355              :     }
   11356              : 
   11357   4366235458 :   if (REG_P (addr))
   11358              :     base = addr;
   11359              :   else if (SUBREG_P (addr))
   11360              :     {
   11361       471921 :       if (REG_P (SUBREG_REG (addr)))
   11362              :         base = addr;
   11363              :       else
   11364              :         return false;
   11365              :     }
   11366              :   else if (GET_CODE (addr) == PLUS)
   11367              :     {
   11368              :       rtx addends[4], op;
   11369              :       int n = 0, i;
   11370              : 
   11371              :       op = addr;
   11372   3170490638 :       do
   11373              :         {
   11374   3170490638 :           if (n >= 4)
   11375    646788469 :             return false;
   11376   3170468795 :           addends[n++] = XEXP (op, 1);
   11377   3170468795 :           op = XEXP (op, 0);
   11378              :         }
   11379   3170468795 :       while (GET_CODE (op) == PLUS);
   11380   3108950988 :       if (n >= 4)
   11381              :         return false;
   11382   3108938751 :       addends[n] = op;
   11383              : 
   11384   8097573546 :       for (i = n; i >= 0; --i)
   11385              :         {
   11386   5635389184 :           op = addends[i];
   11387   5635389184 :           switch (GET_CODE (op))
   11388              :             {
   11389     60179930 :             case MULT:
   11390     60179930 :               if (index)
   11391              :                 return false;
   11392     60139783 :               index = XEXP (op, 0);
   11393     60139783 :               scale_rtx = XEXP (op, 1);
   11394     60139783 :               break;
   11395              : 
   11396     12879487 :             case ASHIFT:
   11397     12879487 :               if (index)
   11398              :                 return false;
   11399     12806996 :               index = XEXP (op, 0);
   11400     12806996 :               tmp = XEXP (op, 1);
   11401     12806996 :               if (!CONST_INT_P (tmp))
   11402              :                 return false;
   11403     12792268 :               scale = INTVAL (tmp);
   11404     12792268 :               if ((unsigned HOST_WIDE_INT) scale > 3)
   11405              :                 return false;
   11406     12334782 :               scale = 1 << scale;
   11407     12334782 :               break;
   11408              : 
   11409       827369 :             case ZERO_EXTEND:
   11410       827369 :               op = XEXP (op, 0);
   11411       827369 :               if (GET_CODE (op) != UNSPEC)
   11412              :                 return false;
   11413              :               /* FALLTHRU */
   11414              : 
   11415       702229 :             case UNSPEC:
   11416       702229 :               if (XINT (op, 1) == UNSPEC_TP
   11417       694033 :                   && TARGET_TLS_DIRECT_SEG_REFS
   11418       694033 :                   && seg == ADDR_SPACE_GENERIC)
   11419       694033 :                 seg = DEFAULT_TLS_SEG_REG;
   11420              :               else
   11421              :                 return false;
   11422              :               break;
   11423              : 
   11424       692993 :             case SUBREG:
   11425       692993 :               if (!REG_P (SUBREG_REG (op)))
   11426              :                 return false;
   11427              :               /* FALLTHRU */
   11428              : 
   11429   2529676493 :             case REG:
   11430   2529676493 :               if (!base)
   11431              :                 base = op;
   11432     78844477 :               else if (!index)
   11433              :                 index = op;
   11434              :               else
   11435              :                 return false;
   11436              :               break;
   11437              : 
   11438   2386688205 :             case CONST:
   11439   2386688205 :             case CONST_INT:
   11440   2386688205 :             case SYMBOL_REF:
   11441   2386688205 :             case LABEL_REF:
   11442   2386688205 :               if (disp)
   11443              :                 return false;
   11444              :               disp = op;
   11445              :               break;
   11446              : 
   11447              :             default:
   11448              :               return false;
   11449              :             }
   11450              :         }
   11451              :     }
   11452              :   else if (GET_CODE (addr) == MULT)
   11453              :     {
   11454      4107380 :       index = XEXP (addr, 0);           /* index*scale */
   11455      4107380 :       scale_rtx = XEXP (addr, 1);
   11456              :     }
   11457              :   else if (GET_CODE (addr) == ASHIFT)
   11458              :     {
   11459              :       /* We're called for lea too, which implements ashift on occasion.  */
   11460      3358440 :       index = XEXP (addr, 0);
   11461      3358440 :       tmp = XEXP (addr, 1);
   11462      3358440 :       if (!CONST_INT_P (tmp))
   11463              :         return false;
   11464      2966741 :       scale = INTVAL (tmp);
   11465      2966741 :       if ((unsigned HOST_WIDE_INT) scale > 3)
   11466              :         return false;
   11467      2201765 :       scale = 1 << scale;
   11468              :     }
   11469              :   else
   11470              :     disp = addr;                        /* displacement */
   11471              : 
   11472   2468493507 :   if (index)
   11473              :     {
   11474    147625119 :       if (REG_P (index))
   11475              :         ;
   11476      4428560 :       else if (SUBREG_P (index)
   11477       476601 :                && REG_P (SUBREG_REG (index)))
   11478              :         ;
   11479              :       else
   11480              :         return false;
   11481              :     }
   11482              : 
   11483              :   /* Extract the integral value of scale.  */
   11484   3714260848 :   if (scale_rtx)
   11485              :     {
   11486     55316744 :       if (!CONST_INT_P (scale_rtx))
   11487              :         return false;
   11488     54653805 :       scale = INTVAL (scale_rtx);
   11489              :     }
   11490              : 
   11491   3713597909 :   base_reg = base && SUBREG_P (base) ? SUBREG_REG (base) : base;
   11492   3713597909 :   index_reg = index && SUBREG_P (index) ? SUBREG_REG (index) : index;
   11493              : 
   11494              :   /* Avoid useless 0 displacement.  */
   11495   3713597909 :   if (disp == const0_rtx && (base || index))
   11496   3713597909 :     disp = NULL_RTX;
   11497              : 
   11498              :   /* Allow arg pointer and stack pointer as index if there is not scaling.  */
   11499   2685723873 :   if (base_reg && index_reg && scale == 1
   11500   3790812603 :       && (REGNO (index_reg) == ARG_POINTER_REGNUM
   11501              :           || REGNO (index_reg) == FRAME_POINTER_REGNUM
   11502              :           || REGNO (index_reg) == SP_REG))
   11503              :     {
   11504              :       std::swap (base, index);
   11505              :       std::swap (base_reg, index_reg);
   11506              :     }
   11507              : 
   11508              :   /* Special case: rewrite index*1+disp into base+disp.  */
   11509   3713597909 :   if (!base && index && scale == 1)
   11510            4 :     base = index, base_reg = index_reg, index = index_reg = NULL_RTX;
   11511              : 
   11512              :   /* Special case: %ebp cannot be encoded as a base without a displacement.
   11513              :      Similarly %r13.  */
   11514    317573947 :   if (!disp && base_reg
   11515   4026530536 :       && (REGNO (base_reg) == ARG_POINTER_REGNUM
   11516              :           || REGNO (base_reg) == FRAME_POINTER_REGNUM
   11517              :           || REGNO (base_reg) == BP_REG
   11518              :           || REGNO (base_reg) == R13_REG))
   11519              :     disp = const0_rtx;
   11520              : 
   11521              :   /* Special case: on K6, [%esi] makes the instruction vector decoded.
   11522              :      Avoid this by transforming to [%esi+0].
   11523              :      Reload calls address legitimization without cfun defined, so we need
   11524              :      to test cfun for being non-NULL. */
   11525            0 :   if (TARGET_CPU_P (K6) && cfun && optimize_function_for_speed_p (cfun)
   11526            0 :       && base_reg && !index_reg && !disp
   11527   3713597909 :       && REGNO (base_reg) == SI_REG)
   11528            0 :     disp = const0_rtx;
   11529              : 
   11530              :   /* Special case: encode reg+reg instead of reg*2.  */
   11531   3713597909 :   if (!base && index && scale == 2)
   11532   1027874032 :     base = index, base_reg = index_reg, scale = 1;
   11533              : 
   11534              :   /* Special case: scaling cannot be encoded without base or displacement.  */
   11535   1027874032 :   if (!base && !disp && index && scale != 1)
   11536      3652541 :     disp = const0_rtx;
   11537              : 
   11538   3713597909 :   out->base = base;
   11539   3713597909 :   out->index = index;
   11540   3713597909 :   out->disp = disp;
   11541   3713597909 :   out->scale = scale;
   11542   3713597909 :   out->seg = seg;
   11543              : 
   11544   3713597909 :   return true;
   11545              : }
   11546              : 
   11547              : /* Return cost of the memory address x.
   11548              :    For i386, it is better to use a complex address than let gcc copy
   11549              :    the address into a reg and make a new pseudo.  But not if the address
   11550              :    requires to two regs - that would mean more pseudos with longer
   11551              :    lifetimes.  */
   11552              : static int
   11553     10879034 : ix86_address_cost (rtx x, machine_mode, addr_space_t, bool)
   11554              : {
   11555     10879034 :   struct ix86_address parts;
   11556     10879034 :   int cost = 1;
   11557     10879034 :   int ok = ix86_decompose_address (x, &parts);
   11558              : 
   11559     10879034 :   gcc_assert (ok);
   11560              : 
   11561     10879034 :   if (parts.base && SUBREG_P (parts.base))
   11562          245 :     parts.base = SUBREG_REG (parts.base);
   11563     10879034 :   if (parts.index && SUBREG_P (parts.index))
   11564           66 :     parts.index = SUBREG_REG (parts.index);
   11565              : 
   11566              :   /* Attempt to minimize number of registers in the address by increasing
   11567              :      address cost for each used register.  We don't increase address cost
   11568              :      for "pic_offset_table_rtx".  When a memopt with "pic_offset_table_rtx"
   11569              :      is not invariant itself it most likely means that base or index is not
   11570              :      invariant.  Therefore only "pic_offset_table_rtx" could be hoisted out,
   11571              :      which is not profitable for x86.  */
   11572     10879034 :   if (parts.base
   11573      9450835 :       && (!REG_P (parts.base) || REGNO (parts.base) >= FIRST_PSEUDO_REGISTER)
   11574     20014049 :       && (current_pass->type == GIMPLE_PASS
   11575      2706232 :           || !pic_offset_table_rtx
   11576       124882 :           || !REG_P (parts.base)
   11577       124882 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.base)))
   11578              :     cost++;
   11579              : 
   11580     10879034 :   if (parts.index
   11581      5187454 :       && (!REG_P (parts.index) || REGNO (parts.index) >= FIRST_PSEUDO_REGISTER)
   11582     16054787 :       && (current_pass->type == GIMPLE_PASS
   11583       668167 :           || !pic_offset_table_rtx
   11584        55926 :           || !REG_P (parts.index)
   11585        55926 :           || REGNO (pic_offset_table_rtx) != REGNO (parts.index)))
   11586      5174457 :     cost++;
   11587              : 
   11588              :   /* AMD-K6 don't like addresses with ModR/M set to 00_xxx_100b,
   11589              :      since it's predecode logic can't detect the length of instructions
   11590              :      and it degenerates to vector decoded.  Increase cost of such
   11591              :      addresses here.  The penalty is minimally 2 cycles.  It may be worthwhile
   11592              :      to split such addresses or even refuse such addresses at all.
   11593              : 
   11594              :      Following addressing modes are affected:
   11595              :       [base+scale*index]
   11596              :       [scale*index+disp]
   11597              :       [base+index]
   11598              : 
   11599              :      The first and last case  may be avoidable by explicitly coding the zero in
   11600              :      memory address, but I don't have AMD-K6 machine handy to check this
   11601              :      theory.  */
   11602              : 
   11603     10879034 :   if (TARGET_CPU_P (K6)
   11604            0 :       && ((!parts.disp && parts.base && parts.index && parts.scale != 1)
   11605            0 :           || (parts.disp && !parts.base && parts.index && parts.scale != 1)
   11606            0 :           || (!parts.disp && parts.base && parts.index && parts.scale == 1)))
   11607            0 :     cost += 10;
   11608              : 
   11609     10879034 :   return cost;
   11610              : }
   11611              : 
   11612              : /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P.  */
   11613              : 
   11614              : bool
   11615      1207958 : ix86_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
   11616              :                                      unsigned int align,
   11617              :                                      enum by_pieces_operation op,
   11618              :                                      bool speed_p)
   11619              : {
   11620              :   /* Return true when we are currently expanding memcpy/memset epilogue
   11621              :      with move_by_pieces or store_by_pieces.  */
   11622      1207958 :   if (cfun->machine->by_pieces_in_use)
   11623              :     return true;
   11624              : 
   11625      1205872 :   return default_use_by_pieces_infrastructure_p (size, align, op,
   11626      1205872 :                                                  speed_p);
   11627              : }
   11628              : 
   11629              : /* Allow {LABEL | SYMBOL}_REF - SYMBOL_REF-FOR-PICBASE for Mach-O as
   11630              :    this is used for to form addresses to local data when -fPIC is in
   11631              :    use.  */
   11632              : 
   11633              : static bool
   11634            0 : darwin_local_data_pic (rtx disp)
   11635              : {
   11636            0 :   return (GET_CODE (disp) == UNSPEC
   11637            0 :           && XINT (disp, 1) == UNSPEC_MACHOPIC_OFFSET);
   11638              : }
   11639              : 
   11640              : /* True if the function symbol operand X should be loaded from GOT.
   11641              :    If CALL_P is true, X is a call operand.
   11642              : 
   11643              :    NB: -mno-direct-extern-access doesn't force load from GOT for
   11644              :    call.
   11645              : 
   11646              :    NB: In 32-bit mode, only non-PIC is allowed in inline assembly
   11647              :    statements, since a PIC register could not be available at the
   11648              :    call site.  */
   11649              : 
   11650              : bool
   11651   1862224176 : ix86_force_load_from_GOT_p (rtx x, bool call_p)
   11652              : {
   11653     95703976 :   return ((TARGET_64BIT || (!flag_pic && HAVE_AS_IX86_GOT32X))
   11654              :           && !TARGET_PECOFF && !TARGET_MACHO
   11655   1859359770 :           && (!flag_pic || this_is_asm_operands)
   11656   1822646841 :           && ix86_cmodel != CM_LARGE
   11657   1822640842 :           && ix86_cmodel != CM_LARGE_PIC
   11658   1822640841 :           && SYMBOL_REF_P (x)
   11659   1822640839 :           && ((!call_p
   11660   1817195172 :                && (!ix86_direct_extern_access
   11661   1817192902 :                    || (SYMBOL_REF_DECL (x)
   11662   1635677040 :                        && lookup_attribute ("nodirect_extern_access",
   11663   1635677040 :                                             DECL_ATTRIBUTES (SYMBOL_REF_DECL (x))))))
   11664   1822638115 :               || (SYMBOL_REF_FUNCTION_P (x)
   11665    699272020 :                   && (!flag_plt
   11666    699267609 :                       || (SYMBOL_REF_DECL (x)
   11667    699267609 :                           && lookup_attribute ("noplt",
   11668    699267609 :                                                DECL_ATTRIBUTES (SYMBOL_REF_DECL (x)))))))
   11669   1862231710 :           && !SYMBOL_REF_LOCAL_P (x));
   11670              : }
   11671              : 
   11672              : /* Determine if a given RTX is a valid constant.  We already know this
   11673              :    satisfies CONSTANT_P.  */
   11674              : 
   11675              : static bool
   11676   1571227985 : ix86_legitimate_constant_p (machine_mode mode, rtx x)
   11677              : {
   11678   1571227985 :   switch (GET_CODE (x))
   11679              :     {
   11680    134965884 :     case CONST:
   11681    134965884 :       x = XEXP (x, 0);
   11682              : 
   11683    134965884 :       if (GET_CODE (x) == PLUS)
   11684              :         {
   11685    134848065 :           if (!CONST_INT_P (XEXP (x, 1)))
   11686              :             return false;
   11687    134848065 :           x = XEXP (x, 0);
   11688              :         }
   11689              : 
   11690    134965884 :       if (TARGET_MACHO && darwin_local_data_pic (x))
   11691              :         return true;
   11692              : 
   11693              :       /* Only some unspecs are valid as "constants".  */
   11694    134965884 :       if (GET_CODE (x) == UNSPEC)
   11695       501796 :         switch (XINT (x, 1))
   11696              :           {
   11697        20883 :           case UNSPEC_GOT:
   11698        20883 :           case UNSPEC_GOTOFF:
   11699        20883 :           case UNSPEC_PLTOFF:
   11700        20883 :             return TARGET_64BIT;
   11701       480550 :           case UNSPEC_TPOFF:
   11702       480550 :           case UNSPEC_NTPOFF:
   11703       480550 :             x = XVECEXP (x, 0, 0);
   11704       480550 :             return (SYMBOL_REF_P (x)
   11705       480550 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11706          275 :           case UNSPEC_DTPOFF:
   11707          275 :             x = XVECEXP (x, 0, 0);
   11708          275 :             return (SYMBOL_REF_P (x)
   11709          275 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC);
   11710            0 :           case UNSPEC_SECREL32:
   11711            0 :             x = XVECEXP (x, 0, 0);
   11712            0 :             return SYMBOL_REF_P (x);
   11713              :           default:
   11714              :             return false;
   11715              :           }
   11716              : 
   11717              :       /* We must have drilled down to a symbol.  */
   11718    134464088 :       if (LABEL_REF_P (x))
   11719              :         return true;
   11720    134458156 :       if (!SYMBOL_REF_P (x))
   11721              :         return false;
   11722              :       /* FALLTHRU */
   11723              : 
   11724    929344373 :     case SYMBOL_REF:
   11725              :       /* TLS symbols are never valid.  */
   11726    929344373 :       if (SYMBOL_REF_TLS_MODEL (x))
   11727              :         return false;
   11728              : 
   11729              :       /* DLLIMPORT symbols are never valid.  */
   11730    929239732 :       if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
   11731              :           && SYMBOL_REF_DLLIMPORT_P (x))
   11732              :         return false;
   11733              : 
   11734              : #if TARGET_MACHO
   11735              :       /* mdynamic-no-pic */
   11736              :       if (MACHO_DYNAMIC_NO_PIC_P)
   11737              :         return machopic_symbol_defined_p (x);
   11738              : #endif
   11739              : 
   11740              :       /* External function address should be loaded
   11741              :          via the GOT slot to avoid PLT.  */
   11742    929239732 :       if (ix86_force_load_from_GOT_p (x))
   11743              :         return false;
   11744              : 
   11745              :       break;
   11746              : 
   11747    619628470 :     CASE_CONST_SCALAR_INT:
   11748    619628470 :       if (ix86_endbr_immediate_operand (x, VOIDmode))
   11749              :         return false;
   11750              : 
   11751    619628269 :       switch (mode)
   11752              :         {
   11753      1494403 :         case E_TImode:
   11754      1494403 :           if (TARGET_64BIT)
   11755              :             return true;
   11756              :           /* FALLTHRU */
   11757        25328 :         case E_OImode:
   11758        25328 :         case E_XImode:
   11759        25328 :           if (!standard_sse_constant_p (x, mode)
   11760        41383 :               && GET_MODE_SIZE (TARGET_AVX512F
   11761              :                                 ? XImode
   11762              :                                 : (TARGET_AVX
   11763              :                                    ? OImode
   11764              :                                    : (TARGET_SSE2
   11765        16055 :                                       ? TImode : DImode))) < GET_MODE_SIZE (mode))
   11766              :             return false;
   11767              :         default:
   11768              :           break;
   11769              :         }
   11770              :       break;
   11771              : 
   11772      9245223 :     case CONST_VECTOR:
   11773      9245223 :       if (!standard_sse_constant_p (x, mode))
   11774              :         return false;
   11775              :       break;
   11776              : 
   11777      7753712 :     case CONST_DOUBLE:
   11778      7753712 :       if (mode == E_BFmode)
   11779              :         return false;
   11780              : 
   11781              :     default:
   11782              :       break;
   11783              :     }
   11784              : 
   11785              :   /* Otherwise we handle everything else in the move patterns.  */
   11786              :   return true;
   11787              : }
   11788              : 
   11789              : /* Determine if it's legal to put X into the constant pool.  This
   11790              :    is not possible for the address of thread-local symbols, which
   11791              :    is checked above.  */
   11792              : 
   11793              : static bool
   11794     64045759 : ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   11795              : {
   11796              :   /* We can put any immediate constant in memory.  */
   11797     64045759 :   switch (GET_CODE (x))
   11798              :     {
   11799              :     CASE_CONST_ANY:
   11800              :       return false;
   11801              : 
   11802      2448414 :     default:
   11803      2448414 :       break;
   11804              :     }
   11805              : 
   11806      2448414 :   return !ix86_legitimate_constant_p (mode, x);
   11807              : }
   11808              : 
   11809              : /* Return a unique alias set for the GOT.  */
   11810              : 
   11811              : alias_set_type
   11812       219176 : ix86_GOT_alias_set (void)
   11813              : {
   11814       219176 :   static alias_set_type set = -1;
   11815       219176 :   if (set == -1)
   11816         4750 :     set = new_alias_set ();
   11817       219176 :   return set;
   11818              : }
   11819              : 
   11820              : /* Nonzero if the constant value X is a legitimate general operand
   11821              :    when generating PIC code.  It is given that flag_pic is on and
   11822              :    that X satisfies CONSTANT_P.  */
   11823              : 
   11824              : bool
   11825    143794758 : legitimate_pic_operand_p (rtx x)
   11826              : {
   11827    143794758 :   rtx inner;
   11828              : 
   11829    143794758 :   switch (GET_CODE (x))
   11830              :     {
   11831      2556539 :     case CONST:
   11832      2556539 :       inner = XEXP (x, 0);
   11833      2556539 :       if (GET_CODE (inner) == PLUS
   11834       405064 :           && CONST_INT_P (XEXP (inner, 1)))
   11835       405064 :         inner = XEXP (inner, 0);
   11836              : 
   11837              :       /* Only some unspecs are valid as "constants".  */
   11838      2556539 :       if (GET_CODE (inner) == UNSPEC)
   11839      2258848 :         switch (XINT (inner, 1))
   11840              :           {
   11841      2197900 :           case UNSPEC_GOT:
   11842      2197900 :           case UNSPEC_GOTOFF:
   11843      2197900 :           case UNSPEC_PLTOFF:
   11844      2197900 :             return TARGET_64BIT;
   11845            0 :           case UNSPEC_TPOFF:
   11846            0 :             x = XVECEXP (inner, 0, 0);
   11847            0 :             return (SYMBOL_REF_P (x)
   11848            0 :                     && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_EXEC);
   11849            0 :           case UNSPEC_SECREL32:
   11850            0 :             x = XVECEXP (inner, 0, 0);
   11851            0 :             return SYMBOL_REF_P (x);
   11852            0 :           case UNSPEC_MACHOPIC_OFFSET:
   11853            0 :             return legitimate_pic_address_disp_p (x);
   11854              :           default:
   11855              :             return false;
   11856              :           }
   11857              :       /* FALLTHRU */
   11858              : 
   11859     13286301 :     case SYMBOL_REF:
   11860     13286301 :     case LABEL_REF:
   11861     13286301 :       return legitimate_pic_address_disp_p (x);
   11862              : 
   11863              :     default:
   11864              :       return true;
   11865              :     }
   11866              : }
   11867              : 
   11868              : /* Determine if a given CONST RTX is a valid memory displacement
   11869              :    in PIC mode.  */
   11870              : 
   11871              : bool
   11872     93874371 : legitimate_pic_address_disp_p (rtx disp)
   11873              : {
   11874     93874371 :   bool saw_plus;
   11875              : 
   11876              :   /* In 64bit mode we can allow direct addresses of symbols and labels
   11877              :      when they are not dynamic symbols.  */
   11878     93874371 :   if (TARGET_64BIT)
   11879              :     {
   11880     68674813 :       rtx op0 = disp, op1;
   11881              : 
   11882     68674813 :       switch (GET_CODE (disp))
   11883              :         {
   11884              :         case LABEL_REF:
   11885              :           return true;
   11886              : 
   11887     15082671 :         case CONST:
   11888     15082671 :           if (GET_CODE (XEXP (disp, 0)) != PLUS)
   11889              :             break;
   11890      4045062 :           op0 = XEXP (XEXP (disp, 0), 0);
   11891      4045062 :           op1 = XEXP (XEXP (disp, 0), 1);
   11892      4045062 :           if (!CONST_INT_P (op1))
   11893              :             break;
   11894      4045062 :           if (GET_CODE (op0) == UNSPEC
   11895          296 :               && (XINT (op0, 1) == UNSPEC_DTPOFF
   11896          296 :                   || XINT (op0, 1) == UNSPEC_NTPOFF)
   11897      4045358 :               && trunc_int_for_mode (INTVAL (op1), SImode) == INTVAL (op1))
   11898              :             return true;
   11899      4044766 :           if (INTVAL (op1) >= 16*1024*1024
   11900      4044766 :               || INTVAL (op1) < -16*1024*1024)
   11901              :             break;
   11902      4044678 :           if (LABEL_REF_P (op0))
   11903              :             return true;
   11904      4044678 :           if (GET_CODE (op0) == CONST
   11905            0 :               && GET_CODE (XEXP (op0, 0)) == UNSPEC
   11906            0 :               && XINT (XEXP (op0, 0), 1) == UNSPEC_PCREL)
   11907              :             return true;
   11908      4044678 :           if (GET_CODE (op0) == UNSPEC
   11909            0 :               && XINT (op0, 1) == UNSPEC_PCREL)
   11910              :             return true;
   11911      4044678 :           if (!SYMBOL_REF_P (op0))
   11912              :             break;
   11913              :           /* FALLTHRU */
   11914              : 
   11915     57401992 :         case SYMBOL_REF:
   11916              :           /* TLS references should always be enclosed in UNSPEC.
   11917              :              The dllimported symbol needs always to be resolved.  */
   11918     57401992 :           if (SYMBOL_REF_TLS_MODEL (op0)
   11919              :               || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0)))
   11920              :             return false;
   11921              : 
   11922     57246003 :           if (TARGET_PECOFF)
   11923              :             {
   11924              : #if TARGET_PECOFF
   11925              :               if (is_imported_p (op0))
   11926              :                 return true;
   11927              : #endif
   11928              : 
   11929              :               if (SYMBOL_REF_FAR_ADDR_P (op0) || !SYMBOL_REF_LOCAL_P (op0))
   11930              :                 break;
   11931              : 
   11932              :               /* Non-external-weak function symbols need to be resolved only
   11933              :                  for the large model.  Non-external symbols don't need to be
   11934              :                  resolved for large and medium models.  For the small model,
   11935              :                  we don't need to resolve anything here.  */
   11936              :               if ((ix86_cmodel != CM_LARGE_PIC
   11937              :                    && SYMBOL_REF_FUNCTION_P (op0)
   11938              :                    && !(SYMBOL_REF_EXTERNAL_P (op0) && SYMBOL_REF_WEAK (op0)))
   11939              :                   || !SYMBOL_REF_EXTERNAL_P (op0)
   11940              :                   || ix86_cmodel == CM_SMALL_PIC)
   11941              :                 return true;
   11942              :             }
   11943     57246003 :           else if (!SYMBOL_REF_FAR_ADDR_P (op0)
   11944     57245999 :                    && (SYMBOL_REF_LOCAL_P (op0)
   11945     25353615 :                        || ((ix86_direct_extern_access
   11946     50535188 :                             && !(SYMBOL_REF_DECL (op0)
   11947     25181736 :                                  && lookup_attribute ("nodirect_extern_access",
   11948     25181736 :                                                       DECL_ATTRIBUTES (SYMBOL_REF_DECL (op0)))))
   11949              :                            && HAVE_LD_PIE_COPYRELOC
   11950     25353289 :                            && flag_pie
   11951      6946128 :                            && !SYMBOL_REF_WEAK (op0)
   11952      6945740 :                            && !SYMBOL_REF_FUNCTION_P (op0)))
   11953     89262959 :                    && ix86_cmodel != CM_LARGE_PIC)
   11954              :             return true;
   11955              :           break;
   11956              : 
   11957              :         default:
   11958              :           break;
   11959              :         }
   11960              :     }
   11961     61470171 :   if (GET_CODE (disp) != CONST)
   11962              :     return false;
   11963     16233699 :   disp = XEXP (disp, 0);
   11964              : 
   11965     16233699 :   if (TARGET_64BIT)
   11966              :     {
   11967              :       /* We are unsafe to allow PLUS expressions.  This limit allowed distance
   11968              :          of GOT tables.  We should not need these anyway.  */
   11969     11088898 :       if (GET_CODE (disp) != UNSPEC
   11970     11037609 :           || (XINT (disp, 1) != UNSPEC_GOTPCREL
   11971     11037609 :               && XINT (disp, 1) != UNSPEC_GOTOFF
   11972              :               && XINT (disp, 1) != UNSPEC_PCREL
   11973              :               && XINT (disp, 1) != UNSPEC_PLTOFF))
   11974              :         return false;
   11975              : 
   11976     11037609 :       if (!SYMBOL_REF_P (XVECEXP (disp, 0, 0))
   11977     11037609 :           && !LABEL_REF_P (XVECEXP (disp, 0, 0)))
   11978              :         return false;
   11979              :       return true;
   11980              :     }
   11981              : 
   11982      5144801 :   saw_plus = false;
   11983      5144801 :   if (GET_CODE (disp) == PLUS)
   11984              :     {
   11985       586082 :       if (!CONST_INT_P (XEXP (disp, 1)))
   11986              :         return false;
   11987       586082 :       disp = XEXP (disp, 0);
   11988       586082 :       saw_plus = true;
   11989              :     }
   11990              : 
   11991      5144801 :   if (TARGET_MACHO && darwin_local_data_pic (disp))
   11992              :     return true;
   11993              : 
   11994      5144801 :   if (GET_CODE (disp) != UNSPEC)
   11995              :     return false;
   11996              : 
   11997      4979727 :   switch (XINT (disp, 1))
   11998              :     {
   11999      2267569 :     case UNSPEC_GOT:
   12000      2267569 :       if (saw_plus)
   12001              :         return false;
   12002              :       /* We need to check for both symbols and labels because VxWorks loads
   12003              :          text labels with @GOT rather than @GOTOFF.  See gotoff_operand for
   12004              :          details.  */
   12005      2267568 :       return (SYMBOL_REF_P (XVECEXP (disp, 0, 0))
   12006      2267568 :               || LABEL_REF_P (XVECEXP (disp, 0, 0)));
   12007      2712158 :     case UNSPEC_GOTOFF:
   12008              :       /* Refuse GOTOFF in 64bit mode since it is always 64bit when used.
   12009              :          While ABI specify also 32bit relocation but we don't produce it in
   12010              :          small PIC model at all.  */
   12011      2712158 :       if ((SYMBOL_REF_P (XVECEXP (disp, 0, 0))
   12012      2712158 :            || LABEL_REF_P (XVECEXP (disp, 0, 0)))
   12013              :           && !TARGET_64BIT)
   12014      5424316 :         return !TARGET_PECOFF && gotoff_operand (XVECEXP (disp, 0, 0), Pmode);
   12015              :       return false;
   12016            0 :     case UNSPEC_GOTTPOFF:
   12017            0 :     case UNSPEC_GOTNTPOFF:
   12018            0 :     case UNSPEC_INDNTPOFF:
   12019            0 :       if (saw_plus)
   12020              :         return false;
   12021            0 :       disp = XVECEXP (disp, 0, 0);
   12022            0 :       return (SYMBOL_REF_P (disp)
   12023            0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_INITIAL_EXEC);
   12024            0 :     case UNSPEC_NTPOFF:
   12025            0 :       disp = XVECEXP (disp, 0, 0);
   12026            0 :       return (SYMBOL_REF_P (disp)
   12027            0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_EXEC);
   12028            0 :     case UNSPEC_DTPOFF:
   12029            0 :       disp = XVECEXP (disp, 0, 0);
   12030            0 :       return (SYMBOL_REF_P (disp)
   12031            0 :               && SYMBOL_REF_TLS_MODEL (disp) == TLS_MODEL_LOCAL_DYNAMIC);
   12032            0 :     case UNSPEC_SECREL32:
   12033            0 :       disp = XVECEXP (disp, 0, 0);
   12034            0 :       return SYMBOL_REF_P (disp);
   12035              :     }
   12036              : 
   12037              :   return false;
   12038              : }
   12039              : 
   12040              : /* Determine if op is suitable RTX for an address register.
   12041              :    Return naked register if a register or a register subreg is
   12042              :    found, otherwise return NULL_RTX.  */
   12043              : 
   12044              : static rtx
   12045   1335877774 : ix86_validate_address_register (rtx op)
   12046              : {
   12047   1335877774 :   machine_mode mode = GET_MODE (op);
   12048              : 
   12049              :   /* Only SImode or DImode registers can form the address.  */
   12050   1335877774 :   if (mode != SImode && mode != DImode)
   12051              :     return NULL_RTX;
   12052              : 
   12053   1335869914 :   if (REG_P (op))
   12054              :     return op;
   12055       894941 :   else if (SUBREG_P (op))
   12056              :     {
   12057       894941 :       rtx reg = SUBREG_REG (op);
   12058              : 
   12059       894941 :       if (!REG_P (reg))
   12060              :         return NULL_RTX;
   12061              : 
   12062       894941 :       mode = GET_MODE (reg);
   12063              : 
   12064              :       /* Don't allow SUBREGs that span more than a word.  It can
   12065              :          lead to spill failures when the register is one word out
   12066              :          of a two word structure.  */
   12067      1836125 :       if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   12068              :         return NULL_RTX;
   12069              : 
   12070              :       /* Allow only SUBREGs of non-eliminable hard registers.  */
   12071       418127 :       if (register_no_elim_operand (reg, mode))
   12072       417957 :         return reg;
   12073              :     }
   12074              : 
   12075              :   /* Op is not a register.  */
   12076              :   return NULL_RTX;
   12077              : }
   12078              : 
   12079              : /* Determine which memory address register set insn can use.  */
   12080              : 
   12081              : static enum attr_addr
   12082    260292476 : ix86_memory_address_reg_class (rtx_insn* insn)
   12083              : {
   12084              :   /* LRA can do some initialization with NULL insn,
   12085              :      return maximum register class in this case.  */
   12086    260292476 :   enum attr_addr addr_rclass = ADDR_GPR32;
   12087              : 
   12088    260292476 :   if (!insn)
   12089              :     return addr_rclass;
   12090              : 
   12091    134530249 :   if (asm_noperands (PATTERN (insn)) >= 0
   12092    134530249 :       || GET_CODE (PATTERN (insn)) == ASM_INPUT)
   12093        75542 :     return ix86_apx_inline_asm_use_gpr32 ? ADDR_GPR32 : ADDR_GPR16;
   12094              : 
   12095              :   /* Return maximum register class for unrecognized instructions.  */
   12096    134454707 :   if (INSN_CODE (insn) < 0)
   12097              :     return addr_rclass;
   12098              : 
   12099              :   /* Try to recognize the insn before calling get_attr_addr.
   12100              :      Save current recog_data and current alternative.  */
   12101    134437407 :   recog_state_saver recog_save;
   12102              : 
   12103              :   /* Update recog_data for processing of alternatives.  */
   12104    134437407 :   extract_insn_cached (insn);
   12105              : 
   12106              :   /* If current alternative is not set, loop through enabled
   12107              :      alternatives and get the most limited register class.  */
   12108    134437407 :   if (recog_save.saved_alternative == -1)
   12109              :     {
   12110     76230141 :       alternative_mask enabled = get_enabled_alternatives (insn);
   12111              : 
   12112   1375187791 :       for (int i = 0; i < recog_data.n_alternatives; i++)
   12113              :         {
   12114   1222727509 :           if (!TEST_BIT (enabled, i))
   12115    364218134 :             continue;
   12116              : 
   12117    858509375 :           which_alternative = i;
   12118    858509375 :           addr_rclass = MIN (addr_rclass, get_attr_addr (insn));
   12119              :         }
   12120              :     }
   12121              :   else
   12122              :     {
   12123     58207266 :       which_alternative = recog_save.saved_alternative;
   12124     58207266 :       addr_rclass = get_attr_addr (insn);
   12125              :     }
   12126              : 
   12127    134437407 :   return addr_rclass;
   12128    134437407 : }
   12129              : 
   12130              : /* Implement TARGET_BASE_REG_CLASS.
   12131              : 
   12132              :    Return memory address register class INSN can use.  MODE, AS, OUTER_CODE,
   12133              :    INDEX_CODE and MEM are unused: the EGPR-encoding restriction this
   12134              :    implements depends only on the instruction, not on the particular address
   12135              :    being formed.  */
   12136              : 
   12137              : static reg_class_t
   12138    218745163 : ix86_base_reg_class (machine_mode, addr_space_t, enum rtx_code, enum rtx_code,
   12139              :                      rtx, rtx_insn *insn)
   12140              : {
   12141    218745163 :   switch (ix86_memory_address_reg_class (insn))
   12142              :     {
   12143              :     case ADDR_GPR8:
   12144              :       return LEGACY_GENERAL_REGS;
   12145              :     case ADDR_GPR16:
   12146              :       return GENERAL_GPR16;
   12147              :     case ADDR_GPR32:
   12148              :       break;
   12149            0 :     default:
   12150            0 :       gcc_unreachable ();
   12151              :     }
   12152              : 
   12153              :   return BASE_REG_CLASS;
   12154              : }
   12155              : 
   12156              : bool
   12157      1194534 : ix86_regno_ok_for_insn_base_p (int regno, rtx_insn* insn)
   12158              : {
   12159      1194534 :   switch (ix86_memory_address_reg_class (insn))
   12160              :     {
   12161            0 :     case ADDR_GPR8:
   12162            0 :       return LEGACY_INT_REGNO_P (regno);
   12163            0 :     case ADDR_GPR16:
   12164            0 :       return GENERAL_GPR16_REGNO_P (regno);
   12165      1194534 :     case ADDR_GPR32:
   12166      1194534 :       break;
   12167            0 :     default:
   12168            0 :       gcc_unreachable ();
   12169              :     }
   12170              : 
   12171      1194534 :   return GENERAL_REGNO_P (regno);
   12172              : }
   12173              : 
   12174              : enum reg_class
   12175     40352779 : ix86_insn_index_reg_class (rtx_insn* insn)
   12176              : {
   12177     40352779 :   switch (ix86_memory_address_reg_class (insn))
   12178              :     {
   12179              :     case ADDR_GPR8:
   12180              :       return LEGACY_INDEX_REGS;
   12181              :     case ADDR_GPR16:
   12182              :       return INDEX_GPR16;
   12183              :     case ADDR_GPR32:
   12184              :       break;
   12185            0 :     default:
   12186            0 :       gcc_unreachable ();
   12187              :     }
   12188              : 
   12189              :   return INDEX_REG_CLASS;
   12190              : }
   12191              : 
   12192              : /* Recognizes RTL expressions that are valid memory addresses for an
   12193              :    instruction.  The MODE argument is the machine mode for the MEM
   12194              :    expression that wants to use this address.
   12195              : 
   12196              :    It only recognizes address in canonical form.  LEGITIMIZE_ADDRESS should
   12197              :    convert common non-canonical forms to canonical form so that they will
   12198              :    be recognized.  */
   12199              : 
   12200              : static bool
   12201   2240065908 : ix86_legitimate_address_p (machine_mode, rtx addr, bool strict,
   12202              :                            code_helper = ERROR_MARK)
   12203              : {
   12204   2240065908 :   struct ix86_address parts;
   12205   2240065908 :   rtx base, index, disp;
   12206   2240065908 :   HOST_WIDE_INT scale;
   12207   2240065908 :   addr_space_t seg;
   12208              : 
   12209   2240065908 :   if (ix86_decompose_address (addr, &parts) == 0)
   12210              :     /* Decomposition failed.  */
   12211              :     return false;
   12212              : 
   12213   2228006010 :   base = parts.base;
   12214   2228006010 :   index = parts.index;
   12215   2228006010 :   disp = parts.disp;
   12216   2228006010 :   scale = parts.scale;
   12217   2228006010 :   seg = parts.seg;
   12218              : 
   12219              :   /* Validate base register.  */
   12220   2228006010 :   if (base)
   12221              :     {
   12222   1252406791 :       rtx reg = ix86_validate_address_register (base);
   12223              : 
   12224   1252406791 :       if (reg == NULL_RTX)
   12225              :         return false;
   12226              : 
   12227   1251962912 :       unsigned int regno = REGNO (reg);
   12228   1251962912 :       if ((strict && !REGNO_OK_FOR_BASE_P (regno))
   12229   1247510745 :           || (!strict && !REGNO_OK_FOR_BASE_NONSTRICT_P (regno)))
   12230              :         /* Base is not valid.  */
   12231              :         return false;
   12232              :     }
   12233              : 
   12234              :   /* Validate index register.  */
   12235   2226238762 :   if (index)
   12236              :     {
   12237     83470983 :       rtx reg = ix86_validate_address_register (index);
   12238              : 
   12239     83470983 :       if (reg == NULL_RTX)
   12240              :         return false;
   12241              : 
   12242     83430018 :       unsigned int regno = REGNO (reg);
   12243     83430018 :       if ((strict && !REGNO_OK_FOR_INDEX_P (regno))
   12244     83421846 :           || (!strict && !REGNO_OK_FOR_INDEX_NONSTRICT_P (regno)))
   12245              :         /* Index is not valid.  */
   12246              :         return false;
   12247              :     }
   12248              : 
   12249              :   /* Index and base should have the same mode.  */
   12250   2226195587 :   if (base && index
   12251     73824270 :       && GET_MODE (base) != GET_MODE (index))
   12252              :     return false;
   12253              : 
   12254              :   /* Address override works only on the (%reg) part of %fs:(%reg).  */
   12255   2225985136 :   if (seg != ADDR_SPACE_GENERIC
   12256   2225985136 :       && ((base && GET_MODE (base) != word_mode)
   12257       341327 :           || (index && GET_MODE (index) != word_mode)))
   12258              :     return false;
   12259              : 
   12260              :   /* Validate scale factor.  */
   12261   2225985107 :   if (scale != 1)
   12262              :     {
   12263     39127595 :       if (!index)
   12264              :         /* Scale without index.  */
   12265              :         return false;
   12266              : 
   12267     39127595 :       if (scale != 2 && scale != 4 && scale != 8)
   12268              :         /* Scale is not a valid multiplier.  */
   12269              :         return false;
   12270              :     }
   12271              : 
   12272              :   /* Validate displacement.  */
   12273   2222897829 :   if (disp)
   12274              :     {
   12275   2003350748 :       if (ix86_endbr_immediate_operand (disp, VOIDmode))
   12276              :         return false;
   12277              : 
   12278   2003350705 :       if (GET_CODE (disp) == CONST
   12279    149409584 :           && GET_CODE (XEXP (disp, 0)) == UNSPEC
   12280     16674847 :           && XINT (XEXP (disp, 0), 1) != UNSPEC_MACHOPIC_OFFSET)
   12281     16674847 :         switch (XINT (XEXP (disp, 0), 1))
   12282              :           {
   12283              :           /* Refuse GOTOFF and GOT in 64bit mode since it is always 64bit
   12284              :              when used.  While ABI specify also 32bit relocations, we
   12285              :              don't produce them at all and use IP relative instead.
   12286              :              Allow GOT in 32bit mode for both PIC and non-PIC if symbol
   12287              :              should be loaded via GOT.  */
   12288      2267627 :           case UNSPEC_GOT:
   12289      2267627 :             if (!TARGET_64BIT
   12290      2267627 :                 && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   12291            0 :               goto is_legitimate_pic;
   12292              :             /* FALLTHRU */
   12293      4558922 :           case UNSPEC_GOTOFF:
   12294      4558922 :             gcc_assert (flag_pic);
   12295      4558922 :             if (!TARGET_64BIT)
   12296      4558719 :               goto is_legitimate_pic;
   12297              : 
   12298              :             /* 64bit address unspec.  */
   12299              :             return false;
   12300              : 
   12301     11037581 :           case UNSPEC_GOTPCREL:
   12302     11037581 :             if (ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   12303         2534 :               goto is_legitimate_pic;
   12304              :             /* FALLTHRU */
   12305     11035047 :           case UNSPEC_PCREL:
   12306     11035047 :             gcc_assert (flag_pic);
   12307     11035047 :             goto is_legitimate_pic;
   12308              : 
   12309              :           case UNSPEC_GOTTPOFF:
   12310              :           case UNSPEC_GOTNTPOFF:
   12311              :           case UNSPEC_INDNTPOFF:
   12312              :           case UNSPEC_NTPOFF:
   12313              :           case UNSPEC_DTPOFF:
   12314              :           case UNSPEC_SECREL32:
   12315              :             break;
   12316              : 
   12317           70 :           default:
   12318              :             /* Invalid address unspec.  */
   12319           70 :             return false;
   12320              :           }
   12321              : 
   12322   1239010284 :       else if (SYMBOLIC_CONST (disp)
   12323   2119410595 :                && (flag_pic
   12324              : #if TARGET_MACHO
   12325              :                    || (MACHOPIC_INDIRECT
   12326              :                        && !machopic_operand_p (disp))
   12327              : #endif
   12328              :                   ))
   12329              :         {
   12330              : 
   12331     80067662 :         is_legitimate_pic:
   12332     80067662 :           if (TARGET_64BIT && (index || base))
   12333              :             {
   12334              :               /* foo@dtpoff(%rX) is ok.  */
   12335        50388 :               if (GET_CODE (disp) != CONST
   12336         8734 :                   || GET_CODE (XEXP (disp, 0)) != PLUS
   12337         8734 :                   || GET_CODE (XEXP (XEXP (disp, 0), 0)) != UNSPEC
   12338         4637 :                   || !CONST_INT_P (XEXP (XEXP (disp, 0), 1))
   12339         4637 :                   || (XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_DTPOFF
   12340         4637 :                       && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_NTPOFF
   12341            6 :                       && XINT (XEXP (XEXP (disp, 0), 0), 1) != UNSPEC_SECREL32))
   12342              :                 /* Non-constant pic memory reference.  */
   12343        45757 :                 return false;
   12344              :             }
   12345     80017274 :           else if ((!TARGET_MACHO || flag_pic)
   12346     80017274 :                     && ! legitimate_pic_address_disp_p (disp))
   12347              :             /* Displacement is an invalid pic construct.  */
   12348              :             return false;
   12349              : #if TARGET_MACHO
   12350              :           else if (MACHO_DYNAMIC_NO_PIC_P
   12351              :                    && !ix86_legitimate_constant_p (Pmode, disp))
   12352              :             /* displacement must be referenced via non_lazy_pointer */
   12353              :             return false;
   12354              : #endif
   12355              : 
   12356              :           /* This code used to verify that a symbolic pic displacement
   12357              :              includes the pic_offset_table_rtx register.
   12358              : 
   12359              :              While this is good idea, unfortunately these constructs may
   12360              :              be created by "adds using lea" optimization for incorrect
   12361              :              code like:
   12362              : 
   12363              :              int a;
   12364              :              int foo(int i)
   12365              :                {
   12366              :                  return *(&a+i);
   12367              :                }
   12368              : 
   12369              :              This code is nonsensical, but results in addressing
   12370              :              GOT table with pic_offset_table_rtx base.  We can't
   12371              :              just refuse it easily, since it gets matched by
   12372              :              "addsi3" pattern, that later gets split to lea in the
   12373              :              case output register differs from input.  While this
   12374              :              can be handled by separate addsi pattern for this case
   12375              :              that never results in lea, this seems to be easier and
   12376              :              correct fix for crash to disable this test.  */
   12377              :         }
   12378   1922204496 :       else if (!LABEL_REF_P (disp)
   12379   1922022524 :                && !CONST_INT_P (disp)
   12380    874281369 :                && (GET_CODE (disp) != CONST
   12381    131365501 :                    || !ix86_legitimate_constant_p (Pmode, disp))
   12382   2668093007 :                && (!SYMBOL_REF_P (disp)
   12383    752310696 :                    || !ix86_legitimate_constant_p (Pmode, disp)))
   12384              :         /* Displacement is not constant.  */
   12385              :         return false;
   12386   1863591161 :       else if (TARGET_64BIT
   12387   1863591161 :                && !x86_64_immediate_operand (disp, VOIDmode))
   12388              :         /* Displacement is out of range.  */
   12389              :         return false;
   12390              :       /* In x32 mode, constant addresses are sign extended to 64bit, so
   12391              :          we have to prevent addresses from 0x80000000 to 0xffffffff.  */
   12392        44405 :       else if (TARGET_X32 && !(index || base)
   12393        15241 :                && CONST_INT_P (disp)
   12394   1863052310 :                && val_signbit_known_set_p (SImode, INTVAL (disp)))
   12395           88 :         return false;
   12396              :     }
   12397              : 
   12398              :   /* Everything looks valid.  */
   12399              :   return true;
   12400              : }
   12401              : 
   12402              : /* Determine if a given RTX is a valid constant address.  */
   12403              : 
   12404              : bool
   12405   2860503090 : constant_address_p (rtx x)
   12406              : {
   12407   2940842247 :   return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
   12408              : }
   12409              : 
   12410              : 
   12411              : /* Return a legitimate reference for ORIG (an address) using the
   12412              :    register REG.  If REG is 0, a new pseudo is generated.
   12413              : 
   12414              :    There are two types of references that must be handled:
   12415              : 
   12416              :    1. Global data references must load the address from the GOT, via
   12417              :       the PIC reg.  An insn is emitted to do this load, and the reg is
   12418              :       returned.
   12419              : 
   12420              :    2. Static data references, constant pool addresses, and code labels
   12421              :       compute the address as an offset from the GOT, whose base is in
   12422              :       the PIC reg.  Static data objects have SYMBOL_FLAG_LOCAL set to
   12423              :       differentiate them from global data objects.  The returned
   12424              :       address is the PIC reg + an unspec constant.
   12425              : 
   12426              :    TARGET_LEGITIMATE_ADDRESS_P rejects symbolic references unless the PIC
   12427              :    reg also appears in the address.  */
   12428              : 
   12429              : rtx
   12430       770587 : legitimize_pic_address (rtx orig, rtx reg)
   12431              : {
   12432       770587 :   rtx addr = orig;
   12433       770587 :   rtx new_rtx = orig;
   12434              : 
   12435              : #if TARGET_MACHO
   12436              :   if (TARGET_MACHO && !TARGET_64BIT)
   12437              :     {
   12438              :       if (reg == 0)
   12439              :         reg = gen_reg_rtx (Pmode);
   12440              :       /* Use the generic Mach-O PIC machinery.  */
   12441              :       return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
   12442              :     }
   12443              : #endif
   12444              : 
   12445       770587 :   if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   12446              :     {
   12447              : #if TARGET_PECOFF
   12448              :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   12449              :       if (tmp)
   12450              :         return tmp;
   12451              : #endif
   12452              :     }
   12453              : 
   12454       770587 :   if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
   12455              :     new_rtx = addr;
   12456       331910 :   else if ((!TARGET_64BIT
   12457       132119 :             || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
   12458              :            && !TARGET_PECOFF
   12459       531798 :            && gotoff_operand (addr, Pmode))
   12460              :     {
   12461              :       /* This symbol may be referenced via a displacement
   12462              :          from the PIC base address (@GOTOFF).  */
   12463        96446 :       if (GET_CODE (addr) == CONST)
   12464         3045 :         addr = XEXP (addr, 0);
   12465              : 
   12466        96446 :       if (GET_CODE (addr) == PLUS)
   12467              :           {
   12468         6090 :             new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
   12469              :                                       UNSPEC_GOTOFF);
   12470         6090 :             new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
   12471              :           }
   12472              :         else
   12473       186773 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
   12474              : 
   12475       192863 :       new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12476              : 
   12477        96446 :       if (TARGET_64BIT)
   12478           29 :         new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   12479              : 
   12480        96446 :       if (reg != 0)
   12481              :         {
   12482            3 :           gcc_assert (REG_P (reg));
   12483            3 :           new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   12484              :                                          new_rtx, reg, 1, OPTAB_DIRECT);
   12485              :         }
   12486              :       else
   12487       192860 :         new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12488              :     }
   12489       443757 :   else if ((SYMBOL_REF_P (addr) && SYMBOL_REF_TLS_MODEL (addr) == 0)
   12490              :            /* We can't always use @GOTOFF for text labels
   12491              :               on VxWorks, see gotoff_operand.  */
   12492       235464 :            || (TARGET_VXWORKS_VAROFF && LABEL_REF_P (addr)))
   12493              :     {
   12494              : #if TARGET_PECOFF
   12495              :       rtx tmp = legitimize_pe_coff_symbol (addr, true);
   12496              :       if (tmp)
   12497              :         return tmp;
   12498              : #endif
   12499              : 
   12500              :       /* For x64 PE-COFF there is no GOT table,
   12501              :          so we use address directly.  */
   12502       208290 :       if (TARGET_64BIT && TARGET_PECOFF)
   12503              :         {
   12504              :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
   12505              :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12506              :         }
   12507       208290 :       else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
   12508              :         {
   12509       124859 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
   12510              :                                     UNSPEC_GOTPCREL);
   12511       124859 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12512       124859 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   12513       124856 :           set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
   12514              :         }
   12515              :       else
   12516              :         {
   12517              :           /* This symbol must be referenced via a load
   12518              :              from the Global Offset Table (@GOT).  */
   12519       166845 :           new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
   12520       166845 :           new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12521              : 
   12522        83434 :           if (TARGET_64BIT)
   12523           23 :             new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   12524              : 
   12525        83434 :           if (reg != 0)
   12526              :             {
   12527            0 :               gcc_assert (REG_P (reg));
   12528            0 :               new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
   12529              :                                              new_rtx, reg, 1, OPTAB_DIRECT);
   12530              :             }
   12531              :           else
   12532       166845 :             new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12533              : 
   12534       166845 :           new_rtx = gen_const_mem (Pmode, new_rtx);
   12535        83434 :           set_mem_alias_set (new_rtx, GOT_ALIAS_SET);
   12536              :         }
   12537              : 
   12538       291704 :       new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
   12539              :     }
   12540              :   else
   12541              :     {
   12542        27174 :       if (CONST_INT_P (addr)
   12543        27174 :           && !x86_64_immediate_operand (addr, VOIDmode))
   12544            8 :         new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
   12545        27166 :       else if (GET_CODE (addr) == CONST)
   12546              :         {
   12547        16626 :           addr = XEXP (addr, 0);
   12548              : 
   12549              :           /* We must match stuff we generate before.  Assume the only
   12550              :              unspecs that can get here are ours.  Not that we could do
   12551              :              anything with them anyway....  */
   12552        16626 :           if (GET_CODE (addr) == UNSPEC
   12553         8981 :               || (GET_CODE (addr) == PLUS
   12554         8981 :                   && GET_CODE (XEXP (addr, 0)) == UNSPEC))
   12555              :             return orig;
   12556         6845 :           gcc_assert (GET_CODE (addr) == PLUS);
   12557              :         }
   12558              : 
   12559        17393 :       if (GET_CODE (addr) == PLUS)
   12560              :         {
   12561         8697 :           rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
   12562              : 
   12563              :           /* Check first to see if this is a constant
   12564              :              offset from a @GOTOFF symbol reference.  */
   12565         8697 :           if (!TARGET_PECOFF
   12566        13788 :               && gotoff_operand (op0, Pmode)
   12567         8697 :               && CONST_INT_P (op1))
   12568              :             {
   12569            4 :               if (!TARGET_64BIT)
   12570              :                 {
   12571            0 :                   new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
   12572              :                                             UNSPEC_GOTOFF);
   12573            0 :                   new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
   12574            0 :                   new_rtx = gen_rtx_CONST (Pmode, new_rtx);
   12575              : 
   12576            0 :                   if (reg != 0)
   12577              :                     {
   12578            0 :                       gcc_assert (REG_P (reg));
   12579            0 :                       new_rtx = expand_simple_binop (Pmode, PLUS,
   12580              :                                                      pic_offset_table_rtx,
   12581              :                                                      new_rtx, reg, 1,
   12582              :                                                      OPTAB_DIRECT);
   12583              :                     }
   12584              :                   else
   12585            0 :                     new_rtx
   12586            0 :                       = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
   12587              :                 }
   12588              :               else
   12589              :                 {
   12590            4 :                   if (INTVAL (op1) < -16*1024*1024
   12591            4 :                       || INTVAL (op1) >= 16*1024*1024)
   12592              :                     {
   12593            4 :                       if (!x86_64_immediate_operand (op1, Pmode))
   12594            4 :                         op1 = force_reg (Pmode, op1);
   12595              : 
   12596            4 :                       new_rtx
   12597            4 :                         = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
   12598              :                     }
   12599              :                 }
   12600              :             }
   12601              :           else
   12602              :             {
   12603         8693 :               rtx base = legitimize_pic_address (op0, reg);
   12604         8693 :               machine_mode mode = GET_MODE (base);
   12605         8693 :               new_rtx
   12606         8693 :                 = legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
   12607              : 
   12608         8693 :               if (CONST_INT_P (new_rtx))
   12609              :                 {
   12610         6833 :                   if (INTVAL (new_rtx) < -16*1024*1024
   12611         6833 :                       || INTVAL (new_rtx) >= 16*1024*1024)
   12612              :                     {
   12613            0 :                       if (!x86_64_immediate_operand (new_rtx, mode))
   12614            0 :                         new_rtx = force_reg (mode, new_rtx);
   12615              : 
   12616            0 :                       new_rtx
   12617            0 :                         = gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
   12618              :                     }
   12619              :                   else
   12620         6833 :                     new_rtx = plus_constant (mode, base, INTVAL (new_rtx));
   12621              :                 }
   12622              :               else
   12623              :                 {
   12624              :                   /* For %rip addressing, we have to use
   12625              :                      just disp32, not base nor index.  */
   12626         1860 :                   if (TARGET_64BIT
   12627          100 :                       && (SYMBOL_REF_P (base)
   12628          100 :                           || LABEL_REF_P (base)))
   12629            7 :                     base = force_reg (mode, base);
   12630         1860 :                   if (GET_CODE (new_rtx) == PLUS
   12631         1740 :                       && CONSTANT_P (XEXP (new_rtx, 1)))
   12632              :                     {
   12633         1736 :                       base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
   12634         1736 :                       new_rtx = XEXP (new_rtx, 1);
   12635              :                     }
   12636         1860 :                   new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
   12637              :                 }
   12638              :             }
   12639              :         }
   12640              :     }
   12641              :   return new_rtx;
   12642              : }
   12643              : 
   12644              : /* Load the thread pointer.  If TO_REG is true, force it into a register.  */
   12645              : 
   12646              : static rtx
   12647        24546 : get_thread_pointer (machine_mode tp_mode, bool to_reg)
   12648              : {
   12649        24546 :   rtx tp = gen_rtx_UNSPEC (ptr_mode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
   12650              : 
   12651        24546 :   if (GET_MODE (tp) != tp_mode)
   12652              :     {
   12653           11 :       gcc_assert (GET_MODE (tp) == SImode);
   12654           11 :       gcc_assert (tp_mode == DImode);
   12655              : 
   12656           11 :       tp = gen_rtx_ZERO_EXTEND (tp_mode, tp);
   12657              :     }
   12658              : 
   12659        24546 :   if (to_reg)
   12660         8163 :     tp = copy_to_mode_reg (tp_mode, tp);
   12661              : 
   12662        24546 :   return tp;
   12663              : }
   12664              : 
   12665              : /* Construct the SYMBOL_REF for the _tls_index symbol.  */
   12666              : 
   12667              : static GTY(()) rtx ix86_tls_index_symbol;
   12668              : 
   12669              : static rtx
   12670            0 : ix86_tls_index (void)
   12671              : {
   12672            0 :   if (!ix86_tls_index_symbol)
   12673            0 :     ix86_tls_index_symbol = gen_rtx_SYMBOL_REF (SImode, "_tls_index");
   12674              : 
   12675            0 :   if (flag_pic)
   12676            0 :     return gen_rtx_CONST (Pmode,
   12677              :                           gen_rtx_UNSPEC (Pmode,
   12678              :                                           gen_rtvec (1, ix86_tls_index_symbol),
   12679              :                                           UNSPEC_PCREL));
   12680              :   else
   12681            0 :     return ix86_tls_index_symbol;
   12682              : }
   12683              : 
   12684              : /* Construct the SYMBOL_REF for the tls_get_addr function.  */
   12685              : 
   12686              : static GTY(()) rtx ix86_tls_symbol;
   12687              : 
   12688              : rtx
   12689         6726 : ix86_tls_get_addr (void)
   12690              : {
   12691         6726 :   if (cfun->machine->call_saved_registers
   12692         6726 :       == TYPE_NO_CALLER_SAVED_REGISTERS)
   12693              :     {
   12694              :       /* __tls_get_addr doesn't preserve vector registers.  When a
   12695              :          function with no_caller_saved_registers attribute calls
   12696              :          __tls_get_addr, YMM and ZMM registers will be clobbered.
   12697              :          Issue an error and suggest -mtls-dialect=gnu2 in this case.  */
   12698            3 :       if (cfun->machine->func_type == TYPE_NORMAL)
   12699            1 :         error (G_("%<-mtls-dialect=gnu2%> must be used with a function"
   12700              :                   " with the %<no_caller_saved_registers%> attribute"));
   12701              :       else
   12702            3 :         error (cfun->machine->func_type == TYPE_EXCEPTION
   12703              :                ? G_("%<-mtls-dialect=gnu2%> must be used with an"
   12704              :                     " exception service routine")
   12705              :                : G_("%<-mtls-dialect=gnu2%> must be used with an"
   12706              :                     " interrupt service routine"));
   12707              :       /* Don't issue the same error twice.  */
   12708            3 :       cfun->machine->func_type = TYPE_NORMAL;
   12709            3 :       cfun->machine->call_saved_registers
   12710            3 :         = TYPE_DEFAULT_CALL_SAVED_REGISTERS;
   12711              :     }
   12712              : 
   12713         6726 :   if (!ix86_tls_symbol)
   12714              :     {
   12715          216 :       const char *sym
   12716          253 :         = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
   12717          253 :            ? "___tls_get_addr" : "__tls_get_addr");
   12718              : 
   12719          290 :       ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
   12720              :     }
   12721              : 
   12722         6726 :   if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
   12723              :     {
   12724            2 :       rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
   12725              :                                    UNSPEC_PLTOFF);
   12726            2 :       return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
   12727              :                            gen_rtx_CONST (Pmode, unspec));
   12728              :     }
   12729              : 
   12730         6724 :   return ix86_tls_symbol;
   12731              : }
   12732              : 
   12733              : /* Return the descriptor of the function ABI type for the tls_get_addr
   12734              :    function.  */
   12735              : 
   12736              : const predefined_function_abi &
   12737         5012 : ix86_tls_get_addr_abi (void)
   12738              : {
   12739         5012 :   if (ix86_abi == SYSV_ABI)
   12740         5000 :     return default_function_abi;
   12741              :   else
   12742           12 :     return ix86_alternate_abi ();
   12743              : }
   12744              : 
   12745              : /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
   12746              : 
   12747              : static GTY(()) rtx ix86_tls_module_base_symbol;
   12748              : 
   12749              : rtx
   12750           98 : ix86_tls_module_base (void)
   12751              : {
   12752           98 :   if (!ix86_tls_module_base_symbol)
   12753              :     {
   12754           11 :       ix86_tls_module_base_symbol
   12755           11 :         = gen_rtx_SYMBOL_REF (ptr_mode, "_TLS_MODULE_BASE_");
   12756              : 
   12757           11 :       SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
   12758           11 :         |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
   12759              :     }
   12760              : 
   12761           98 :   return ix86_tls_module_base_symbol;
   12762              : }
   12763              : 
   12764              : /* A subroutine of ix86_legitimize_address and ix86_expand_move.  FOR_MOV is
   12765              :    false if we expect this to be used for a memory address and true if
   12766              :    we expect to load the address into a register.  */
   12767              : 
   12768              : rtx
   12769        30973 : legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
   12770              : {
   12771        30973 :   rtx dest, base, off;
   12772        30973 :   rtx pic = NULL_RTX, tp = NULL_RTX;
   12773        30973 :   machine_mode tp_mode = Pmode;
   12774        30973 :   int type;
   12775              : 
   12776              :   /* Windows implements a single form of TLS.  */
   12777        30973 :   if (TARGET_WIN32_TLS)
   12778              :     {
   12779              :       /* Load the 32-bit index.  */
   12780              :       rtx ind = gen_const_mem (SImode, ix86_tls_index ());
   12781              :       set_mem_alias_set (ind, GOT_ALIAS_SET);
   12782              :       if (TARGET_64BIT)
   12783              :         ind = convert_to_mode (Pmode, ind, 1);
   12784              :       ind = force_reg (Pmode, ind);
   12785              : 
   12786              :       /* Add it to the thread pointer and load the base.  */
   12787              :       tp = get_thread_pointer (Pmode, true);
   12788              :       rtx addr = gen_rtx_PLUS (Pmode, tp,
   12789              :                                gen_rtx_MULT (Pmode, ind,
   12790              :                                              GEN_INT (UNITS_PER_WORD)));
   12791              :       base = gen_const_mem (Pmode, addr);
   12792              :       set_mem_alias_set (base, GOT_ALIAS_SET);
   12793              : 
   12794              :       /* Add the 32-bit section-relative offset to the base.  */
   12795              :       base = force_reg (Pmode, base);
   12796              :       off = gen_rtx_CONST (Pmode,
   12797              :                            gen_rtx_UNSPEC (SImode,
   12798              :                                            gen_rtvec (1, x),
   12799              :                                            UNSPEC_SECREL32));
   12800              :       return gen_rtx_PLUS (Pmode, base, off);
   12801              :     }
   12802              : 
   12803              :   /* Fall back to global dynamic model if tool chain cannot support local
   12804              :      dynamic.  */
   12805        30973 :   if (TARGET_SUN_TLS && !TARGET_64BIT
   12806              :       && !HAVE_AS_IX86_TLSLDMPLT && !HAVE_AS_IX86_TLSLDM
   12807              :       && model == TLS_MODEL_LOCAL_DYNAMIC)
   12808              :     model = TLS_MODEL_GLOBAL_DYNAMIC;
   12809              : 
   12810        30973 :   switch (model)
   12811              :     {
   12812         6112 :     case TLS_MODEL_GLOBAL_DYNAMIC:
   12813         6112 :       if (!TARGET_64BIT)
   12814              :         {
   12815         1922 :           if (flag_pic && !TARGET_PECOFF)
   12816         1922 :             pic = pic_offset_table_rtx;
   12817              :           else
   12818              :             {
   12819            0 :               pic = gen_reg_rtx (Pmode);
   12820            0 :               emit_insn (gen_set_got (pic));
   12821              :             }
   12822              :         }
   12823              : 
   12824         6112 :       if (TARGET_GNU2_TLS)
   12825              :         {
   12826           53 :           dest = gen_reg_rtx (ptr_mode);
   12827           53 :           if (TARGET_64BIT)
   12828           53 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, dest, x));
   12829              :           else
   12830            0 :             emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
   12831              : 
   12832           53 :           tp = get_thread_pointer (ptr_mode, true);
   12833           53 :           dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12834           61 :           if (GET_MODE (dest) != Pmode)
   12835            6 :              dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12836           61 :           dest = force_reg (Pmode, dest);
   12837              : 
   12838           61 :           if (GET_MODE (x) != Pmode)
   12839            3 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12840              : 
   12841           53 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12842              :         }
   12843              :       else
   12844              :         {
   12845         6059 :           rtx caddr = ix86_tls_get_addr ();
   12846              : 
   12847         7981 :           dest = gen_reg_rtx (Pmode);
   12848         6059 :           if (TARGET_64BIT)
   12849              :             {
   12850         4137 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12851         4137 :               rtx rdi = gen_rtx_REG (Pmode, DI_REG);
   12852         4137 :               rtx_insn *insns;
   12853              : 
   12854         4137 :               start_sequence ();
   12855         4137 :               rtx_insn *call_insn = emit_call_insn
   12856         4137 :                 (gen_tls_global_dynamic_64 (Pmode, rax, x, caddr, rdi));
   12857         4137 :               CALL_INSN_ABI_ID (call_insn)
   12858         4137 :                 = ix86_tls_get_addr_abi ().id ();
   12859         4137 :               insns = end_sequence ();
   12860              : 
   12861         4137 :               if (GET_MODE (x) != Pmode)
   12862            1 :                 x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12863              : 
   12864         4137 :               RTL_CONST_CALL_P (insns) = 1;
   12865         4137 :               emit_libcall_block (insns, dest, rax, x);
   12866              :             }
   12867              :           else
   12868         1922 :             emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
   12869              :         }
   12870              :       break;
   12871              : 
   12872          394 :     case TLS_MODEL_LOCAL_DYNAMIC:
   12873          394 :       if (!TARGET_64BIT)
   12874              :         {
   12875           92 :           if (flag_pic)
   12876           92 :             pic = pic_offset_table_rtx;
   12877              :           else
   12878              :             {
   12879            0 :               pic = gen_reg_rtx (Pmode);
   12880            0 :               emit_insn (gen_set_got (pic));
   12881              :             }
   12882              :         }
   12883              : 
   12884          394 :       if (TARGET_GNU2_TLS)
   12885              :         {
   12886           26 :           rtx tmp = ix86_tls_module_base ();
   12887              : 
   12888           26 :           base = gen_reg_rtx (ptr_mode);
   12889           26 :           if (TARGET_64BIT)
   12890           26 :             emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, base, tmp));
   12891              :           else
   12892            0 :             emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
   12893              : 
   12894           26 :           tp = get_thread_pointer (ptr_mode, true);
   12895           32 :           if (GET_MODE (base) != Pmode)
   12896            2 :             base = gen_rtx_ZERO_EXTEND (Pmode, base);
   12897           32 :           base = force_reg (Pmode, base);
   12898              :         }
   12899              :       else
   12900              :         {
   12901          368 :           rtx caddr = ix86_tls_get_addr ();
   12902              : 
   12903          460 :           base = gen_reg_rtx (Pmode);
   12904          368 :           if (TARGET_64BIT)
   12905              :             {
   12906          276 :               rtx rax = gen_rtx_REG (Pmode, AX_REG);
   12907          276 :               rtx rdi = gen_rtx_REG (Pmode, DI_REG);
   12908          276 :               rtx_insn *insns;
   12909          276 :               rtx eqv;
   12910              : 
   12911          276 :               start_sequence ();
   12912          276 :               rtx_insn *call_insn = emit_call_insn
   12913          276 :                 (gen_tls_local_dynamic_base_64 (Pmode, rax, caddr, rdi));
   12914          276 :               CALL_INSN_ABI_ID (call_insn)
   12915          276 :                 = ix86_tls_get_addr_abi ().id ();
   12916          276 :               insns = end_sequence ();
   12917              : 
   12918              :               /* Attach a unique REG_EQUAL, to allow the RTL optimizers to
   12919              :                  share the LD_BASE result with other LD model accesses.  */
   12920          276 :               eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
   12921              :                                     UNSPEC_TLS_LD_BASE);
   12922              : 
   12923          276 :               RTL_CONST_CALL_P (insns) = 1;
   12924          276 :               emit_libcall_block (insns, base, rax, eqv);
   12925              :             }
   12926              :           else
   12927           92 :             emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
   12928              :         }
   12929              : 
   12930          492 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
   12931          492 :       off = gen_rtx_CONST (Pmode, off);
   12932              : 
   12933          590 :       dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, off));
   12934              : 
   12935          394 :       if (TARGET_GNU2_TLS)
   12936              :         {
   12937           32 :           if (GET_MODE (tp) != Pmode)
   12938              :             {
   12939            2 :               dest = lowpart_subreg (ptr_mode, dest, Pmode);
   12940            2 :               dest = gen_rtx_PLUS (ptr_mode, tp, dest);
   12941            2 :               dest = gen_rtx_ZERO_EXTEND (Pmode, dest);
   12942              :             }
   12943              :           else
   12944           24 :             dest = gen_rtx_PLUS (Pmode, tp, dest);
   12945           32 :           dest = force_reg (Pmode, dest);
   12946              : 
   12947           32 :           if (GET_MODE (x) != Pmode)
   12948            1 :             x = gen_rtx_ZERO_EXTEND (Pmode, x);
   12949              : 
   12950           26 :           set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
   12951              :         }
   12952              :       break;
   12953              : 
   12954        10866 :     case TLS_MODEL_INITIAL_EXEC:
   12955        10866 :       if (TARGET_64BIT)
   12956              :         {
   12957              :           /* Generate DImode references to avoid %fs:(%reg32)
   12958              :              problems and linker IE->LE relaxation bug.  */
   12959              :           tp_mode = DImode;
   12960              :           pic = NULL;
   12961              :           type = UNSPEC_GOTNTPOFF;
   12962              :         }
   12963          786 :       else if (flag_pic)
   12964              :         {
   12965          785 :           pic = pic_offset_table_rtx;
   12966          785 :           type = TARGET_ANY_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
   12967              :         }
   12968            1 :       else if (!TARGET_ANY_GNU_TLS)
   12969              :         {
   12970            0 :           pic = gen_reg_rtx (Pmode);
   12971            0 :           emit_insn (gen_set_got (pic));
   12972            0 :           type = UNSPEC_GOTTPOFF;
   12973              :         }
   12974              :       else
   12975              :         {
   12976              :           pic = NULL;
   12977              :           type = UNSPEC_INDNTPOFF;
   12978              :         }
   12979              : 
   12980        10866 :       off = gen_rtx_UNSPEC (tp_mode, gen_rtvec (1, x), type);
   12981        10866 :       off = gen_rtx_CONST (tp_mode, off);
   12982        10866 :       if (pic)
   12983          785 :         off = gen_rtx_PLUS (tp_mode, pic, off);
   12984        10866 :       off = gen_const_mem (tp_mode, off);
   12985        10866 :       set_mem_alias_set (off, GOT_ALIAS_SET);
   12986              : 
   12987        10866 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   12988              :         {
   12989        21732 :           base = get_thread_pointer (tp_mode,
   12990         8165 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   12991        10866 :           off = force_reg (tp_mode, off);
   12992        10866 :           dest = gen_rtx_PLUS (tp_mode, base, off);
   12993        11656 :           if (tp_mode != Pmode)
   12994            4 :             dest = convert_to_mode (Pmode, dest, 1);
   12995              :         }
   12996              :       else
   12997              :         {
   12998            0 :           base = get_thread_pointer (Pmode, true);
   12999            0 :           dest = gen_reg_rtx (Pmode);
   13000            0 :           emit_insn (gen_sub3_insn (dest, base, off));
   13001              :         }
   13002              :       break;
   13003              : 
   13004        13601 :     case TLS_MODEL_LOCAL_EXEC:
   13005        28000 :       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   13006              :                             (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   13007              :                             ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
   13008        14399 :       off = gen_rtx_CONST (Pmode, off);
   13009              : 
   13010        13601 :       if (TARGET_64BIT || TARGET_ANY_GNU_TLS)
   13011              :         {
   13012        28000 :           base = get_thread_pointer (Pmode,
   13013         8218 :                                      for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
   13014        14399 :           return gen_rtx_PLUS (Pmode, base, off);
   13015              :         }
   13016              :       else
   13017              :         {
   13018            0 :           base = get_thread_pointer (Pmode, true);
   13019            0 :           dest = gen_reg_rtx (Pmode);
   13020            0 :           emit_insn (gen_sub3_insn (dest, base, off));
   13021              :         }
   13022            0 :       break;
   13023              : 
   13024            0 :     default:
   13025            0 :       gcc_unreachable ();
   13026              :     }
   13027              : 
   13028              :   return dest;
   13029              : }
   13030              : 
   13031              : /* Return true if the TLS address requires insn using integer registers.
   13032              :    It's used to prevent KMOV/VMOV in TLS code sequences which require integer
   13033              :    MOV instructions, refer to PR103275.  */
   13034              : bool
   13035     14900873 : ix86_gpr_tls_address_pattern_p (rtx mem)
   13036              : {
   13037     14900873 :   gcc_assert (MEM_P (mem));
   13038              : 
   13039     14900873 :   rtx addr = XEXP (mem, 0);
   13040     14900873 :   subrtx_var_iterator::array_type array;
   13041     51667031 :   FOR_EACH_SUBRTX_VAR (iter, array, addr, ALL)
   13042              :     {
   13043     36773807 :       rtx op = *iter;
   13044     36773807 :       if (GET_CODE (op) == UNSPEC)
   13045       230691 :         switch (XINT (op, 1))
   13046              :           {
   13047              :           case UNSPEC_GOTNTPOFF:
   13048         7649 :             return true;
   13049            0 :           case UNSPEC_TPOFF:
   13050            0 :             if (!TARGET_64BIT)
   13051              :               return true;
   13052              :             break;
   13053              :           default:
   13054              :             break;
   13055              :           }
   13056              :     }
   13057              : 
   13058     14893224 :   return false;
   13059     14900873 : }
   13060              : 
   13061              : /* Return true if OP refers to a TLS address.  */
   13062              : bool
   13063    239947773 : ix86_tls_address_pattern_p (rtx op)
   13064              : {
   13065    239947773 :   subrtx_var_iterator::array_type array;
   13066   1430928261 :   FOR_EACH_SUBRTX_VAR (iter, array, op, ALL)
   13067              :     {
   13068   1190998721 :       rtx op = *iter;
   13069   1190998721 :       if (MEM_P (op))
   13070              :         {
   13071    107404916 :           rtx *x = &XEXP (op, 0);
   13072    169870418 :           while (GET_CODE (*x) == PLUS)
   13073              :             {
   13074              :               int i;
   13075    187414762 :               for (i = 0; i < 2; i++)
   13076              :                 {
   13077    124949260 :                   rtx u = XEXP (*x, i);
   13078    124949260 :                   if (GET_CODE (u) == ZERO_EXTEND)
   13079        31593 :                     u = XEXP (u, 0);
   13080    124949260 :                   if (GET_CODE (u) == UNSPEC
   13081        18265 :                       && XINT (u, 1) == UNSPEC_TP)
   13082        18233 :                     return true;
   13083              :                 }
   13084     62465502 :               x = &XEXP (*x, 0);
   13085              :             }
   13086              : 
   13087    107386683 :           iter.skip_subrtxes ();
   13088              :         }
   13089              :     }
   13090              : 
   13091    239929540 :   return false;
   13092    239947773 : }
   13093              : 
   13094              : /* Rewrite *LOC so that it refers to a default TLS address space.  */
   13095              : static void
   13096        18233 : ix86_rewrite_tls_address_1 (rtx *loc)
   13097              : {
   13098        18233 :   subrtx_ptr_iterator::array_type array;
   13099        54277 :   FOR_EACH_SUBRTX_PTR (iter, array, loc, ALL)
   13100              :     {
   13101        54277 :       rtx *loc = *iter;
   13102        54277 :       if (MEM_P (*loc))
   13103              :         {
   13104        18422 :           rtx addr = XEXP (*loc, 0);
   13105        18422 :           rtx *x = &addr;
   13106        23333 :           while (GET_CODE (*x) == PLUS)
   13107              :             {
   13108              :               int i;
   13109        32989 :               for (i = 0; i < 2; i++)
   13110              :                 {
   13111        28078 :                   rtx u = XEXP (*x, i);
   13112        28078 :                   if (GET_CODE (u) == ZERO_EXTEND)
   13113           19 :                     u = XEXP (u, 0);
   13114        28078 :                   if (GET_CODE (u) == UNSPEC
   13115        18233 :                       && XINT (u, 1) == UNSPEC_TP)
   13116              :                     {
   13117              :                       /* NB: Since address override only applies to the
   13118              :                          (reg32) part in fs:(reg32), return if address
   13119              :                          override is used.  */
   13120        19932 :                       if (Pmode != word_mode
   13121        18233 :                           && REG_P (XEXP (*x, 1 - i)))
   13122        18233 :                         return;
   13123              : 
   13124        18231 :                       addr_space_t as = DEFAULT_TLS_SEG_REG;
   13125              : 
   13126        18231 :                       *x = XEXP (*x, 1 - i);
   13127              : 
   13128        18231 :                       *loc = replace_equiv_address_nv (*loc, addr, true);
   13129        18231 :                       set_mem_addr_space (*loc, as);
   13130        18231 :                       return;
   13131              :                     }
   13132              :                 }
   13133         4911 :               x = &XEXP (*x, 0);
   13134              :             }
   13135              : 
   13136          189 :           iter.skip_subrtxes ();
   13137              :         }
   13138              :     }
   13139        18233 : }
   13140              : 
   13141              : /* Rewrite instruction pattern involvning TLS address
   13142              :    so that it refers to a default TLS address space.  */
   13143              : rtx
   13144        18233 : ix86_rewrite_tls_address (rtx pattern)
   13145              : {
   13146        18233 :   pattern = copy_insn (pattern);
   13147        18233 :   ix86_rewrite_tls_address_1 (&pattern);
   13148        18233 :   return pattern;
   13149              : }
   13150              : 
   13151              : /* Try machine-dependent ways of modifying an illegitimate address
   13152              :    to be legitimate.  If we find one, return the new, valid address.
   13153              :    This macro is used in only one place: `memory_address' in explow.cc.
   13154              : 
   13155              :    OLDX is the address as it was before break_out_memory_refs was called.
   13156              :    In some cases it is useful to look at this to decide what needs to be done.
   13157              : 
   13158              :    It is always safe for this macro to do nothing.  It exists to recognize
   13159              :    opportunities to optimize the output.
   13160              : 
   13161              :    For the 80386, we handle X+REG by loading X into a register R and
   13162              :    using R+REG.  R will go in a general reg and indexing will be used.
   13163              :    However, if REG is a broken-out memory address or multiplication,
   13164              :    nothing needs to be done because REG can certainly go in a general reg.
   13165              : 
   13166              :    When -fpic is used, special handling is needed for symbolic references.
   13167              :    See comments by legitimize_pic_address in i386.cc for details.  */
   13168              : 
   13169              : static rtx
   13170       669398 : ix86_legitimize_address (rtx x, rtx, machine_mode mode)
   13171              : {
   13172       669398 :   bool changed = false;
   13173       669398 :   unsigned log;
   13174              : 
   13175       669398 :   log = SYMBOL_REF_P (x) ? SYMBOL_REF_TLS_MODEL (x) : 0;
   13176       152241 :   if (log)
   13177        20802 :     return legitimize_tls_address (x, (enum tls_model) log, false);
   13178       648596 :   if (GET_CODE (x) == CONST
   13179          508 :       && GET_CODE (XEXP (x, 0)) == PLUS
   13180          508 :       && SYMBOL_REF_P (XEXP (XEXP (x, 0), 0))
   13181       649104 :       && (log = SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0))))
   13182              :     {
   13183            5 :       rtx t = legitimize_tls_address (XEXP (XEXP (x, 0), 0),
   13184              :                                       (enum tls_model) log, false);
   13185            6 :       return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1));
   13186              :     }
   13187              : 
   13188       648591 :   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
   13189              :     {
   13190              : #if TARGET_PECOFF
   13191              :       rtx tmp = legitimize_pe_coff_symbol (x, true);
   13192              :       if (tmp)
   13193              :         return tmp;
   13194              : #endif
   13195              :     }
   13196              : 
   13197       648591 :   if (flag_pic && SYMBOLIC_CONST (x))
   13198       131821 :     return legitimize_pic_address (x, 0);
   13199              : 
   13200              : #if TARGET_MACHO
   13201              :   if (MACHO_DYNAMIC_NO_PIC_P && SYMBOLIC_CONST (x))
   13202              :     return machopic_indirect_data_reference (x, 0);
   13203              : #endif
   13204              : 
   13205              :   /* Canonicalize shifts by 0, 1, 2, 3 into multiply */
   13206       516770 :   if (GET_CODE (x) == ASHIFT
   13207            0 :       && CONST_INT_P (XEXP (x, 1))
   13208            0 :       && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) < 4)
   13209              :     {
   13210            0 :       changed = true;
   13211            0 :       log = INTVAL (XEXP (x, 1));
   13212            0 :       x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)),
   13213              :                         GEN_INT (1 << log));
   13214              :     }
   13215              : 
   13216       516770 :   if (GET_CODE (x) == PLUS)
   13217              :     {
   13218              :       /* Canonicalize shifts by 0, 1, 2, 3 into multiply.  */
   13219              : 
   13220       169112 :       if (GET_CODE (XEXP (x, 0)) == ASHIFT
   13221          609 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   13222          609 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 0), 1)) < 4)
   13223              :         {
   13224          609 :           changed = true;
   13225          609 :           log = INTVAL (XEXP (XEXP (x, 0), 1));
   13226         1783 :           XEXP (x, 0) = gen_rtx_MULT (Pmode,
   13227              :                                       force_reg (Pmode, XEXP (XEXP (x, 0), 0)),
   13228              :                                       GEN_INT (1 << log));
   13229              :         }
   13230              : 
   13231       169112 :       if (GET_CODE (XEXP (x, 1)) == ASHIFT
   13232            0 :           && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   13233            0 :           && (unsigned HOST_WIDE_INT) INTVAL (XEXP (XEXP (x, 1), 1)) < 4)
   13234              :         {
   13235            0 :           changed = true;
   13236            0 :           log = INTVAL (XEXP (XEXP (x, 1), 1));
   13237            0 :           XEXP (x, 1) = gen_rtx_MULT (Pmode,
   13238              :                                       force_reg (Pmode, XEXP (XEXP (x, 1), 0)),
   13239              :                                       GEN_INT (1 << log));
   13240              :         }
   13241              : 
   13242              :       /* Put multiply first if it isn't already.  */
   13243       169112 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   13244              :         {
   13245            0 :           std::swap (XEXP (x, 0), XEXP (x, 1));
   13246            0 :           changed = true;
   13247              :         }
   13248              : 
   13249              :       /* Canonicalize (plus (mult (reg) (const)) (plus (reg) (const)))
   13250              :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  This can be
   13251              :          created by virtual register instantiation, register elimination, and
   13252              :          similar optimizations.  */
   13253       169112 :       if (GET_CODE (XEXP (x, 0)) == MULT && GET_CODE (XEXP (x, 1)) == PLUS)
   13254              :         {
   13255         8952 :           changed = true;
   13256        13878 :           x = gen_rtx_PLUS (Pmode,
   13257              :                             gen_rtx_PLUS (Pmode, XEXP (x, 0),
   13258              :                                           XEXP (XEXP (x, 1), 0)),
   13259              :                             XEXP (XEXP (x, 1), 1));
   13260              :         }
   13261              : 
   13262              :       /* Canonicalize
   13263              :          (plus (plus (mult (reg) (const)) (plus (reg) (const))) const)
   13264              :          into (plus (plus (mult (reg) (const)) (reg)) (const)).  */
   13265       160160 :       else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
   13266        61044 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   13267        52076 :                && GET_CODE (XEXP (XEXP (x, 0), 1)) == PLUS
   13268            0 :                && CONSTANT_P (XEXP (x, 1)))
   13269              :         {
   13270            0 :           rtx constant;
   13271            0 :           rtx other = NULL_RTX;
   13272              : 
   13273            0 :           if (CONST_INT_P (XEXP (x, 1)))
   13274              :             {
   13275            0 :               constant = XEXP (x, 1);
   13276            0 :               other = XEXP (XEXP (XEXP (x, 0), 1), 1);
   13277              :             }
   13278            0 :           else if (CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 1), 1)))
   13279              :             {
   13280              :               constant = XEXP (XEXP (XEXP (x, 0), 1), 1);
   13281              :               other = XEXP (x, 1);
   13282              :             }
   13283              :           else
   13284              :             constant = 0;
   13285              : 
   13286            0 :           if (constant)
   13287              :             {
   13288            0 :               changed = true;
   13289            0 :               x = gen_rtx_PLUS (Pmode,
   13290              :                                 gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 0),
   13291              :                                               XEXP (XEXP (XEXP (x, 0), 1), 0)),
   13292              :                                 plus_constant (Pmode, other,
   13293              :                                                INTVAL (constant)));
   13294              :             }
   13295              :         }
   13296              : 
   13297       169112 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   13298         8989 :         return x;
   13299              : 
   13300       160123 :       if (GET_CODE (XEXP (x, 0)) == MULT)
   13301              :         {
   13302        19824 :           changed = true;
   13303        19824 :           XEXP (x, 0) = copy_addr_to_reg (XEXP (x, 0));
   13304              :         }
   13305              : 
   13306       160123 :       if (GET_CODE (XEXP (x, 1)) == MULT)
   13307              :         {
   13308            0 :           changed = true;
   13309            0 :           XEXP (x, 1) = copy_addr_to_reg (XEXP (x, 1));
   13310              :         }
   13311              : 
   13312       160123 :       if (changed
   13313        19830 :           && REG_P (XEXP (x, 1))
   13314        16135 :           && REG_P (XEXP (x, 0)))
   13315              :         return x;
   13316              : 
   13317       143988 :       if (flag_pic && SYMBOLIC_CONST (XEXP (x, 1)))
   13318              :         {
   13319         1852 :           changed = true;
   13320         1852 :           x = legitimize_pic_address (x, 0);
   13321              :         }
   13322              : 
   13323       143988 :       if (changed && ix86_legitimate_address_p (mode, x, false))
   13324         3972 :         return x;
   13325              : 
   13326       140016 :       if (REG_P (XEXP (x, 0)))
   13327              :         {
   13328        81273 :           rtx temp = gen_reg_rtx (Pmode);
   13329        78513 :           rtx val  = force_operand (XEXP (x, 1), temp);
   13330        78513 :           if (val != temp)
   13331              :             {
   13332        71597 :               val = convert_to_mode (Pmode, val, 1);
   13333        71273 :               emit_move_insn (temp, val);
   13334              :             }
   13335              : 
   13336        78513 :           XEXP (x, 1) = temp;
   13337        78513 :           return x;
   13338              :         }
   13339              : 
   13340        61503 :       else if (REG_P (XEXP (x, 1)))
   13341              :         {
   13342         4246 :           rtx temp = gen_reg_rtx (Pmode);
   13343         3383 :           rtx val  = force_operand (XEXP (x, 0), temp);
   13344         3383 :           if (val != temp)
   13345              :             {
   13346            0 :               val = convert_to_mode (Pmode, val, 1);
   13347            0 :               emit_move_insn (temp, val);
   13348              :             }
   13349              : 
   13350         3383 :           XEXP (x, 0) = temp;
   13351         3383 :           return x;
   13352              :         }
   13353              :     }
   13354              : 
   13355              :   return x;
   13356              : }
   13357              : 
   13358              : /* Print an integer constant expression in assembler syntax.  Addition
   13359              :    and subtraction are the only arithmetic that may appear in these
   13360              :    expressions.  FILE is the stdio stream to write to, X is the rtx, and
   13361              :    CODE is the operand print code from the output string.  */
   13362              : 
   13363              : static void
   13364      5063392 : output_pic_addr_const (FILE *file, rtx x, int code)
   13365              : {
   13366      5416376 :   char buf[256];
   13367              : 
   13368      5416376 :   switch (GET_CODE (x))
   13369              :     {
   13370            0 :     case PC:
   13371            0 :       gcc_assert (flag_pic);
   13372            0 :       putc ('.', file);
   13373            0 :       break;
   13374              : 
   13375      1572545 :     case SYMBOL_REF:
   13376      1572545 :       if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
   13377      1572545 :         output_addr_const (file, x);
   13378              :       else
   13379              :         {
   13380              :           const char *name = XSTR (x, 0);
   13381              : 
   13382              :           /* Mark the decl as referenced so that cgraph will
   13383              :              output the function.  */
   13384              :           if (SYMBOL_REF_DECL (x))
   13385              :             mark_decl_referenced (SYMBOL_REF_DECL (x));
   13386              : 
   13387              : #if TARGET_MACHO
   13388              :           if (MACHOPIC_INDIRECT
   13389              :               && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
   13390              :             name = machopic_indirection_name (x, /*stub_p=*/true);
   13391              : #endif
   13392              :           assemble_name (file, name);
   13393              :         }
   13394      1572545 :       if (!TARGET_MACHO && !(TARGET_64BIT && TARGET_PECOFF)
   13395      1572545 :           && code == 'P' && ix86_call_use_plt_p (x))
   13396       548181 :         fputs ("@PLT", file);
   13397              :       break;
   13398              : 
   13399         2717 :     case LABEL_REF:
   13400         2717 :       x = XEXP (x, 0);
   13401              :       /* FALLTHRU */
   13402         2717 :     case CODE_LABEL:
   13403         2717 :       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   13404         2717 :       assemble_name (asm_out_file, buf);
   13405         2717 :       break;
   13406              : 
   13407      3257282 :     CASE_CONST_SCALAR_INT:
   13408      3257282 :       output_addr_const (file, x);
   13409      3257282 :       break;
   13410              : 
   13411       287240 :     case CONST:
   13412              :       /* This used to output parentheses around the expression,
   13413              :          but that does not work on the 386 (either ATT or BSD assembler).  */
   13414       287240 :       output_pic_addr_const (file, XEXP (x, 0), code);
   13415       287240 :       break;
   13416              : 
   13417            0 :     case CONST_DOUBLE:
   13418              :       /* We can't handle floating point constants;
   13419              :          TARGET_PRINT_OPERAND must handle them.  */
   13420            0 :       output_operand_lossage ("floating constant misused");
   13421            0 :       break;
   13422              : 
   13423        65744 :     case PLUS:
   13424              :       /* Some assemblers need integer constants to appear first.  */
   13425        65744 :       if (CONST_INT_P (XEXP (x, 0)))
   13426              :         {
   13427            0 :           output_pic_addr_const (file, XEXP (x, 0), code);
   13428            0 :           putc ('+', file);
   13429            0 :           output_pic_addr_const (file, XEXP (x, 1), code);
   13430              :         }
   13431              :       else
   13432              :         {
   13433        65744 :           gcc_assert (CONST_INT_P (XEXP (x, 1)));
   13434        65744 :           output_pic_addr_const (file, XEXP (x, 1), code);
   13435        65744 :           putc ('+', file);
   13436        65744 :           output_pic_addr_const (file, XEXP (x, 0), code);
   13437              :         }
   13438              :       break;
   13439              : 
   13440            0 :     case MINUS:
   13441            0 :       if (!TARGET_MACHO)
   13442            0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? '(' : '[', file);
   13443            0 :       output_pic_addr_const (file, XEXP (x, 0), code);
   13444            0 :       putc ('-', file);
   13445            0 :       output_pic_addr_const (file, XEXP (x, 1), code);
   13446            0 :       if (!TARGET_MACHO)
   13447            0 :         putc (ASSEMBLER_DIALECT == ASM_INTEL ? ')' : ']', file);
   13448            0 :       break;
   13449              : 
   13450       230848 :     case UNSPEC:
   13451       230848 :       gcc_assert (XVECLEN (x, 0) == 1);
   13452       230848 :       output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
   13453       230848 :       switch (XINT (x, 1))
   13454              :         {
   13455        43354 :         case UNSPEC_GOT:
   13456        43354 :           fputs ("@GOT", file);
   13457        43354 :           break;
   13458        78006 :         case UNSPEC_GOTOFF:
   13459        78006 :           fputs ("@GOTOFF", file);
   13460        78006 :           break;
   13461           36 :         case UNSPEC_PLTOFF:
   13462           36 :           fputs ("@PLTOFF", file);
   13463           36 :           break;
   13464            0 :         case UNSPEC_PCREL:
   13465            0 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   13466              :                  "(%rip)" : "[rip]", file);
   13467            0 :           break;
   13468       105233 :         case UNSPEC_GOTPCREL:
   13469       105233 :           fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   13470              :                  "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file);
   13471       105233 :           break;
   13472            0 :         case UNSPEC_GOTTPOFF:
   13473              :           /* FIXME: This might be @TPOFF in Sun ld too.  */
   13474            0 :           fputs ("@gottpoff", file);
   13475            0 :           break;
   13476            0 :         case UNSPEC_TPOFF:
   13477            0 :           fputs ("@tpoff", file);
   13478            0 :           break;
   13479         1459 :         case UNSPEC_NTPOFF:
   13480         1459 :           if (TARGET_64BIT)
   13481         1459 :             fputs ("@tpoff", file);
   13482              :           else
   13483            0 :             fputs ("@ntpoff", file);
   13484              :           break;
   13485          319 :         case UNSPEC_DTPOFF:
   13486          319 :           fputs ("@dtpoff", file);
   13487          319 :           break;
   13488         2441 :         case UNSPEC_GOTNTPOFF:
   13489         2441 :           if (TARGET_64BIT)
   13490         2164 :             fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   13491              :                    "@gottpoff(%rip)": "@gottpoff[rip]", file);
   13492              :           else
   13493          277 :             fputs ("@gotntpoff", file);
   13494              :           break;
   13495            0 :         case UNSPEC_INDNTPOFF:
   13496            0 :           fputs ("@indntpoff", file);
   13497            0 :           break;
   13498            0 :         case UNSPEC_SECREL32:
   13499            0 :           fputs ("@secrel32", file);
   13500            0 :           break;
   13501              : #if TARGET_MACHO
   13502              :         case UNSPEC_MACHOPIC_OFFSET:
   13503              :           putc ('-', file);
   13504              :           machopic_output_function_base_name (file);
   13505              :           break;
   13506              : #endif
   13507            0 :         default:
   13508            0 :           output_operand_lossage ("invalid UNSPEC as operand");
   13509            0 :           break;
   13510              :         }
   13511              :        break;
   13512              : 
   13513            0 :     default:
   13514            0 :       output_operand_lossage ("invalid expression as operand");
   13515              :     }
   13516      5063392 : }
   13517              : 
   13518              : /* This is called from dwarf2out.cc via TARGET_ASM_OUTPUT_DWARF_DTPREL.
   13519              :    We need to emit DTP-relative relocations.  */
   13520              : 
   13521              : static void ATTRIBUTE_UNUSED
   13522          685 : i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
   13523              : {
   13524          685 :   fputs (ASM_LONG, file);
   13525          685 :   output_addr_const (file, x);
   13526              : #if TARGET_WIN32_TLS
   13527              :   fputs ("@secrel32", file);
   13528              : #else
   13529          685 :   fputs ("@dtpoff", file);
   13530              : #endif
   13531          685 :   switch (size)
   13532              :     {
   13533              :     case 4:
   13534              :       break;
   13535          553 :     case 8:
   13536          553 :       fputs (", 0", file);
   13537          553 :       break;
   13538            0 :     default:
   13539            0 :       gcc_unreachable ();
   13540              :    }
   13541          685 : }
   13542              : 
   13543              : /* Return true if X is a representation of the PIC register.  This copes
   13544              :    with calls from ix86_find_base_term, where the register might have
   13545              :    been replaced by a cselib value.  */
   13546              : 
   13547              : static bool
   13548     26871888 : ix86_pic_register_p (rtx x)
   13549              : {
   13550     26871888 :   if (GET_CODE (x) == VALUE && CSELIB_VAL_PTR (x))
   13551       768179 :     return (pic_offset_table_rtx
   13552       768179 :             && rtx_equal_for_cselib_p (x, pic_offset_table_rtx));
   13553     26103709 :   else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_SET_GOT)
   13554              :     return true;
   13555     26100880 :   else if (!REG_P (x))
   13556              :     return false;
   13557     25495210 :   else if (pic_offset_table_rtx)
   13558              :     {
   13559     25475575 :       if (REGNO (x) == REGNO (pic_offset_table_rtx))
   13560              :         return true;
   13561       402795 :       if (HARD_REGISTER_P (x)
   13562       381066 :           && !HARD_REGISTER_P (pic_offset_table_rtx)
   13563       783861 :           && ORIGINAL_REGNO (x) == REGNO (pic_offset_table_rtx))
   13564              :         return true;
   13565              :       return false;
   13566              :     }
   13567              :   else
   13568        19635 :     return REGNO (x) == PIC_OFFSET_TABLE_REGNUM;
   13569              : }
   13570              : 
   13571              : /* Helper function for ix86_delegitimize_address.
   13572              :    Attempt to delegitimize TLS local-exec accesses.  */
   13573              : 
   13574              : static rtx
   13575   3548095329 : ix86_delegitimize_tls_address (rtx orig_x)
   13576              : {
   13577   3548095329 :   rtx x = orig_x, unspec;
   13578   3548095329 :   struct ix86_address addr;
   13579              : 
   13580   3548095329 :   if (!TARGET_TLS_DIRECT_SEG_REFS)
   13581              :     return orig_x;
   13582   3548095329 :   if (MEM_P (x))
   13583     43963565 :     x = XEXP (x, 0);
   13584   5092592377 :   if (GET_CODE (x) != PLUS || GET_MODE (x) != Pmode)
   13585              :     return orig_x;
   13586   1709772150 :   if (ix86_decompose_address (x, &addr) == 0
   13587   1978934883 :       || addr.seg != DEFAULT_TLS_SEG_REG
   13588       270763 :       || addr.disp == NULL_RTX
   13589   1709990951 :       || GET_CODE (addr.disp) != CONST)
   13590              :     return orig_x;
   13591       112893 :   unspec = XEXP (addr.disp, 0);
   13592       112893 :   if (GET_CODE (unspec) == PLUS && CONST_INT_P (XEXP (unspec, 1)))
   13593        66056 :     unspec = XEXP (unspec, 0);
   13594       112893 :   if (GET_CODE (unspec) != UNSPEC || XINT (unspec, 1) != UNSPEC_NTPOFF)
   13595              :     return orig_x;
   13596       112830 :   x = XVECEXP (unspec, 0, 0);
   13597       112830 :   gcc_assert (SYMBOL_REF_P (x));
   13598       112830 :   if (unspec != XEXP (addr.disp, 0))
   13599        87545 :     x = gen_rtx_PLUS (Pmode, x, XEXP (XEXP (addr.disp, 0), 1));
   13600       112830 :   if (addr.index)
   13601              :     {
   13602          185 :       rtx idx = addr.index;
   13603          185 :       if (addr.scale != 1)
   13604          185 :         idx = gen_rtx_MULT (Pmode, idx, GEN_INT (addr.scale));
   13605          185 :       x = gen_rtx_PLUS (Pmode, idx, x);
   13606              :     }
   13607       112830 :   if (addr.base)
   13608            2 :     x = gen_rtx_PLUS (Pmode, addr.base, x);
   13609       112830 :   if (MEM_P (orig_x))
   13610          198 :     x = replace_equiv_address_nv (orig_x, x);
   13611              :   return x;
   13612              : }
   13613              : 
   13614              : /* In the name of slightly smaller debug output, and to cater to
   13615              :    general assembler lossage, recognize PIC+GOTOFF and turn it back
   13616              :    into a direct symbol reference.
   13617              : 
   13618              :    On Darwin, this is necessary to avoid a crash, because Darwin
   13619              :    has a different PIC label for each routine but the DWARF debugging
   13620              :    information is not associated with any particular routine, so it's
   13621              :    necessary to remove references to the PIC label from RTL stored by
   13622              :    the DWARF output code.
   13623              : 
   13624              :    This helper is used in the normal ix86_delegitimize_address
   13625              :    entrypoint (e.g. used in the target delegitimization hook) and
   13626              :    in ix86_find_base_term.  As compile time memory optimization, we
   13627              :    avoid allocating rtxes that will not change anything on the outcome
   13628              :    of the callers (find_base_value and find_base_term).  */
   13629              : 
   13630              : static inline rtx
   13631   3572932462 : ix86_delegitimize_address_1 (rtx x, bool base_term_p)
   13632              : {
   13633   3572932462 :   rtx orig_x = delegitimize_mem_from_attrs (x);
   13634              :   /* addend is NULL or some rtx if x is something+GOTOFF where
   13635              :      something doesn't include the PIC register.  */
   13636   3572932462 :   rtx addend = NULL_RTX;
   13637              :   /* reg_addend is NULL or a multiple of some register.  */
   13638   3572932462 :   rtx reg_addend = NULL_RTX;
   13639              :   /* const_addend is NULL or a const_int.  */
   13640   3572932462 :   rtx const_addend = NULL_RTX;
   13641              :   /* This is the result, or NULL.  */
   13642   3572932462 :   rtx result = NULL_RTX;
   13643              : 
   13644   3572932462 :   x = orig_x;
   13645              : 
   13646   3572932462 :   if (MEM_P (x))
   13647     63167823 :     x = XEXP (x, 0);
   13648              : 
   13649   3572932462 :   if (TARGET_64BIT)
   13650              :     {
   13651    266354754 :       if (GET_CODE (x) == CONST
   13652      8805197 :           && GET_CODE (XEXP (x, 0)) == PLUS
   13653      6855518 :           && GET_MODE (XEXP (x, 0)) == Pmode
   13654      6855469 :           && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   13655      6855469 :           && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
   13656    266359113 :           && XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_PCREL)
   13657              :         {
   13658              :           /* find_base_{value,term} only care about MEMs with arg_pointer_rtx
   13659              :              base.  A CONST can't be arg_pointer_rtx based.  */
   13660            0 :           if (base_term_p && MEM_P (orig_x))
   13661              :             return orig_x;
   13662            0 :           rtx x2 = XVECEXP (XEXP (XEXP (x, 0), 0), 0, 0);
   13663            0 :           x = gen_rtx_PLUS (Pmode, XEXP (XEXP (x, 0), 1), x2);
   13664            0 :           if (MEM_P (orig_x))
   13665            0 :             x = replace_equiv_address_nv (orig_x, x);
   13666              :           return x;
   13667              :         }
   13668              : 
   13669    266354754 :       if (GET_CODE (x) == CONST
   13670      8805197 :           && GET_CODE (XEXP (x, 0)) == UNSPEC
   13671      1949728 :           && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
   13672       657126 :               || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
   13673      1292602 :           && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
   13674              :         {
   13675       296637 :           x = XVECEXP (XEXP (x, 0), 0, 0);
   13676       296637 :           if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
   13677              :             {
   13678            9 :               x = lowpart_subreg (GET_MODE (orig_x), x, GET_MODE (x));
   13679            9 :               if (x == NULL_RTX)
   13680              :                 return orig_x;
   13681              :             }
   13682       296637 :           return x;
   13683              :         }
   13684              : 
   13685    266058117 :       if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
   13686    266056434 :         return ix86_delegitimize_tls_address (orig_x);
   13687              : 
   13688              :       /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
   13689              :          and -mcmodel=medium -fpic.  */
   13690              :     }
   13691              : 
   13692   3306579391 :   if (GET_CODE (x) != PLUS
   13693   1569036414 :       || GET_CODE (XEXP (x, 1)) != CONST)
   13694   3280258032 :     return ix86_delegitimize_tls_address (orig_x);
   13695              : 
   13696     26321359 :   if (ix86_pic_register_p (XEXP (x, 0)))
   13697              :     /* %ebx + GOT/GOTOFF */
   13698              :     ;
   13699      1294120 :   else if (GET_CODE (XEXP (x, 0)) == PLUS)
   13700              :     {
   13701              :       /* %ebx + %reg * scale + GOT/GOTOFF */
   13702       473132 :       reg_addend = XEXP (x, 0);
   13703       473132 :       if (ix86_pic_register_p (XEXP (reg_addend, 0)))
   13704       395735 :         reg_addend = XEXP (reg_addend, 1);
   13705        77397 :       else if (ix86_pic_register_p (XEXP (reg_addend, 1)))
   13706        45121 :         reg_addend = XEXP (reg_addend, 0);
   13707              :       else
   13708              :         {
   13709        32276 :           reg_addend = NULL_RTX;
   13710        32276 :           addend = XEXP (x, 0);
   13711              :         }
   13712              :     }
   13713              :   else
   13714              :     addend = XEXP (x, 0);
   13715              : 
   13716     26321359 :   x = XEXP (XEXP (x, 1), 0);
   13717     26321359 :   if (GET_CODE (x) == PLUS
   13718      1457328 :       && CONST_INT_P (XEXP (x, 1)))
   13719              :     {
   13720      1457328 :       const_addend = XEXP (x, 1);
   13721      1457328 :       x = XEXP (x, 0);
   13722              :     }
   13723              : 
   13724     26321359 :   if (GET_CODE (x) == UNSPEC
   13725     25634413 :       && ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
   13726      6726792 :           || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
   13727      1093921 :           || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
   13728            4 :               && !MEM_P (orig_x) && !addend)))
   13729     24540496 :     result = XVECEXP (x, 0, 0);
   13730              : 
   13731     24540496 :   if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
   13732              :       && !MEM_P (orig_x))
   13733              :     result = XVECEXP (x, 0, 0);
   13734              : 
   13735     24540496 :   if (! result)
   13736      1780863 :     return ix86_delegitimize_tls_address (orig_x);
   13737              : 
   13738              :   /* For (PLUS something CONST_INT) both find_base_{value,term} just
   13739              :      recurse on the first operand.  */
   13740     24540496 :   if (const_addend && !base_term_p)
   13741       341022 :     result = gen_rtx_CONST (Pmode, gen_rtx_PLUS (Pmode, result, const_addend));
   13742     24540496 :   if (reg_addend)
   13743       857246 :     result = gen_rtx_PLUS (Pmode, reg_addend, result);
   13744     24540496 :   if (addend)
   13745              :     {
   13746              :       /* If the rest of original X doesn't involve the PIC register, add
   13747              :          addend and subtract pic_offset_table_rtx.  This can happen e.g.
   13748              :          for code like:
   13749              :          leal (%ebx, %ecx, 4), %ecx
   13750              :          ...
   13751              :          movl foo@GOTOFF(%ecx), %edx
   13752              :          in which case we return (%ecx - %ebx) + foo
   13753              :          or (%ecx - _GLOBAL_OFFSET_TABLE_) + foo if pseudo_pic_reg
   13754              :          and reload has completed.  Don't do the latter for debug,
   13755              :          as _GLOBAL_OFFSET_TABLE_ can't be expressed in the assembly.  */
   13756       139208 :       if (pic_offset_table_rtx
   13757       139208 :           && (!reload_completed || !ix86_use_pseudo_pic_reg ()))
   13758         2328 :         result = gen_rtx_PLUS (Pmode, gen_rtx_MINUS (Pmode, copy_rtx (addend),
   13759              :                                                      pic_offset_table_rtx),
   13760              :                                result);
   13761       138432 :       else if (base_term_p
   13762       133705 :                && pic_offset_table_rtx
   13763              :                && !TARGET_MACHO
   13764              :                && !TARGET_VXWORKS_VAROFF)
   13765              :         {
   13766       267410 :           rtx tmp = gen_rtx_SYMBOL_REF (Pmode, GOT_SYMBOL_NAME);
   13767       267410 :           tmp = gen_rtx_MINUS (Pmode, copy_rtx (addend), tmp);
   13768       267410 :           result = gen_rtx_PLUS (Pmode, tmp, result);
   13769       133705 :         }
   13770              :       else
   13771              :         return orig_x;
   13772              :     }
   13773     49071453 :   if (GET_MODE (orig_x) != Pmode && MEM_P (orig_x))
   13774              :     {
   13775            0 :       result = lowpart_subreg (GET_MODE (orig_x), result, Pmode);
   13776            0 :       if (result == NULL_RTX)
   13777            0 :         return orig_x;
   13778              :     }
   13779              :   return result;
   13780              : }
   13781              : 
   13782              : /* The normal instantiation of the above template.  */
   13783              : 
   13784              : static rtx
   13785    338851296 : ix86_delegitimize_address (rtx x)
   13786              : {
   13787    338851296 :   return ix86_delegitimize_address_1 (x, false);
   13788              : }
   13789              : 
   13790              : /* If X is a machine specific address (i.e. a symbol or label being
   13791              :    referenced as a displacement from the GOT implemented using an
   13792              :    UNSPEC), then return the base term.  Otherwise return X.  */
   13793              : 
   13794              : rtx
   13795   6803784030 : ix86_find_base_term (rtx x)
   13796              : {
   13797   6803784030 :   rtx term;
   13798              : 
   13799   6803784030 :   if (TARGET_64BIT)
   13800              :     {
   13801   3569702864 :       if (GET_CODE (x) != CONST)
   13802              :         return x;
   13803     42242475 :       term = XEXP (x, 0);
   13804     42242475 :       if (GET_CODE (term) == PLUS
   13805     42227595 :           && CONST_INT_P (XEXP (term, 1)))
   13806     42227595 :         term = XEXP (term, 0);
   13807     42242475 :       if (GET_CODE (term) != UNSPEC
   13808        39826 :           || (XINT (term, 1) != UNSPEC_GOTPCREL
   13809        39794 :               && XINT (term, 1) != UNSPEC_PCREL))
   13810              :         return x;
   13811              : 
   13812           32 :       return XVECEXP (term, 0, 0);
   13813              :     }
   13814              : 
   13815   3234081166 :   return ix86_delegitimize_address_1 (x, true);
   13816              : }
   13817              : 
   13818              : /* Return true if X shouldn't be emitted into the debug info.
   13819              :    Disallow UNSPECs other than @gotoff - we can't emit _GLOBAL_OFFSET_TABLE_
   13820              :    symbol easily into the .debug_info section, so we need not to
   13821              :    delegitimize, but instead assemble as @gotoff.
   13822              :    Disallow _GLOBAL_OFFSET_TABLE_ SYMBOL_REF - the assembler magically
   13823              :    assembles that as _GLOBAL_OFFSET_TABLE_-. expression.  */
   13824              : 
   13825              : static bool
   13826      1961452 : ix86_const_not_ok_for_debug_p (rtx x)
   13827              : {
   13828      1961452 :   if (GET_CODE (x) == UNSPEC && XINT (x, 1) != UNSPEC_GOTOFF)
   13829              :     return true;
   13830              : 
   13831      1961432 :   if (SYMBOL_REF_P (x) && strcmp (XSTR (x, 0), GOT_SYMBOL_NAME) == 0)
   13832            0 :     return true;
   13833              : 
   13834              :   return false;
   13835              : }
   13836              : 
   13837              : static void
   13838      7337517 : put_condition_code (enum rtx_code code, machine_mode mode, bool reverse,
   13839              :                     bool fp, FILE *file)
   13840              : {
   13841      7337517 :   const char *suffix;
   13842              : 
   13843      7337517 :   if (mode == CCFPmode)
   13844              :     {
   13845       573370 :       code = ix86_fp_compare_code_to_integer (code);
   13846       573370 :       mode = CCmode;
   13847              :     }
   13848      7337517 :   if (reverse)
   13849       243908 :     code = reverse_condition (code);
   13850              : 
   13851      7337517 :   switch (code)
   13852              :     {
   13853      2859108 :     case EQ:
   13854      2859108 :       gcc_assert (mode != CCGZmode);
   13855      2859108 :       switch (mode)
   13856              :         {
   13857              :         case E_CCAmode:
   13858              :           suffix = "a";
   13859              :           break;
   13860              :         case E_CCCmode:
   13861        28888 :           suffix = "c";
   13862              :           break;
   13863              :         case E_CCOmode:
   13864      7337517 :           suffix = "o";
   13865              :           break;
   13866              :         case E_CCPmode:
   13867       235217 :           suffix = "p";
   13868              :           break;
   13869              :         case E_CCSmode:
   13870       133375 :           suffix = "s";
   13871              :           break;
   13872      2839123 :         default:
   13873      2839123 :           suffix = "e";
   13874      2839123 :           break;
   13875              :         }
   13876              :       break;
   13877      2379635 :     case NE:
   13878      2379635 :       gcc_assert (mode != CCGZmode);
   13879      2379635 :       switch (mode)
   13880              :         {
   13881              :         case E_CCAmode:
   13882              :           suffix = "na";
   13883              :           break;
   13884              :         case E_CCCmode:
   13885        12073 :           suffix = "nc";
   13886              :           break;
   13887        11025 :         case E_CCOmode:
   13888        11025 :           suffix = "no";
   13889        11025 :           break;
   13890              :         case E_CCPmode:
   13891         5011 :           suffix = "np";
   13892              :           break;
   13893              :         case E_CCSmode:
   13894        53752 :           suffix = "ns";
   13895              :           break;
   13896      2366723 :         default:
   13897      2366723 :           suffix = "ne";
   13898      2366723 :           break;
   13899              :         }
   13900              :       break;
   13901       258603 :     case GT:
   13902       258603 :       gcc_assert (mode == CCmode || mode == CCNOmode || mode == CCGCmode);
   13903              :       suffix = "g";
   13904              :       break;
   13905       191163 :     case GTU:
   13906              :       /* ??? Use "nbe" instead of "a" for fcmov lossage on some assemblers.
   13907              :          Those same assemblers have the same but opposite lossage on cmov.  */
   13908       191163 :       if (mode == CCmode)
   13909       191225 :         suffix = fp ? "nbe" : "a";
   13910              :       else
   13911            0 :         gcc_unreachable ();
   13912              :       break;
   13913       232907 :     case LT:
   13914       232907 :       switch (mode)
   13915              :         {
   13916              :         case E_CCNOmode:
   13917              :         case E_CCGOCmode:
   13918              :           suffix = "s";
   13919              :           break;
   13920              : 
   13921              :         case E_CCmode:
   13922              :         case E_CCGCmode:
   13923              :         case E_CCGZmode:
   13924      7337517 :           suffix = "l";
   13925              :           break;
   13926              : 
   13927            0 :         default:
   13928            0 :           gcc_unreachable ();
   13929              :         }
   13930              :       break;
   13931       441681 :     case LTU:
   13932       441681 :       if (mode == CCmode || mode == CCGZmode)
   13933              :         suffix = "b";
   13934        27558 :       else if (mode == CCCmode)
   13935        28888 :         suffix = fp ? "b" : "c";
   13936              :       else
   13937            0 :         gcc_unreachable ();
   13938              :       break;
   13939       146880 :     case GE:
   13940       146880 :       switch (mode)
   13941              :         {
   13942              :         case E_CCNOmode:
   13943              :         case E_CCGOCmode:
   13944              :           suffix = "ns";
   13945              :           break;
   13946              : 
   13947              :         case E_CCmode:
   13948              :         case E_CCGCmode:
   13949              :         case E_CCGZmode:
   13950      7337517 :           suffix = "ge";
   13951              :           break;
   13952              : 
   13953            0 :         default:
   13954            0 :           gcc_unreachable ();
   13955              :         }
   13956              :       break;
   13957       202539 :     case GEU:
   13958       202539 :       if (mode == CCmode || mode == CCGZmode)
   13959              :         suffix = "nb";
   13960        10206 :       else if (mode == CCCmode)
   13961        12073 :         suffix = fp ? "nb" : "nc";
   13962              :       else
   13963            0 :         gcc_unreachable ();
   13964              :       break;
   13965       256432 :     case LE:
   13966       256432 :       gcc_assert (mode == CCmode || mode == CCGCmode || mode == CCNOmode);
   13967              :       suffix = "le";
   13968              :       break;
   13969       128339 :     case LEU:
   13970       128339 :       if (mode == CCmode)
   13971              :         suffix = "be";
   13972              :       else
   13973            0 :         gcc_unreachable ();
   13974              :       break;
   13975       235217 :     case UNORDERED:
   13976       235224 :       suffix = fp ? "u" : "p";
   13977              :       break;
   13978         5013 :     case ORDERED:
   13979         5018 :       suffix = fp ? "nu" : "np";
   13980              :       break;
   13981            0 :     default:
   13982            0 :       gcc_unreachable ();
   13983              :     }
   13984      7337517 :   fputs (suffix, file);
   13985      7337517 : }
   13986              : 
   13987              : /* Print the name of register X to FILE based on its machine mode and number.
   13988              :    If CODE is 'w', pretend the mode is HImode.
   13989              :    If CODE is 'b', pretend the mode is QImode.
   13990              :    If CODE is 'k', pretend the mode is SImode.
   13991              :    If CODE is 'q', pretend the mode is DImode.
   13992              :    If CODE is 'x', pretend the mode is V4SFmode.
   13993              :    If CODE is 't', pretend the mode is V8SFmode.
   13994              :    If CODE is 'g', pretend the mode is V16SFmode.
   13995              :    If CODE is 'h', pretend the reg is the 'high' byte register.
   13996              :    If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
   13997              :    If CODE is 'd', duplicate the operand for AVX instruction.
   13998              :    If CODE is 'V', print naked full integer register name without %.
   13999              :  */
   14000              : 
   14001              : void
   14002    127060576 : print_reg (rtx x, int code, FILE *file)
   14003              : {
   14004    127060576 :   const char *reg;
   14005    127060576 :   int msize;
   14006    127060576 :   unsigned int regno;
   14007    127060576 :   bool duplicated;
   14008              : 
   14009    127060576 :   if (ASSEMBLER_DIALECT == ASM_ATT && code != 'V')
   14010    127058129 :     putc ('%', file);
   14011              : 
   14012    127060576 :   if (x == pc_rtx)
   14013              :     {
   14014      6079856 :       gcc_assert (TARGET_64BIT);
   14015      6079856 :       fputs ("rip", file);
   14016      6079856 :       return;
   14017              :     }
   14018              : 
   14019    120980720 :   if (code == 'y' && STACK_TOP_P (x))
   14020              :     {
   14021       290488 :       fputs ("st(0)", file);
   14022       290488 :       return;
   14023              :     }
   14024              : 
   14025    120690232 :   if (code == 'w')
   14026              :     msize = 2;
   14027              :   else if (code == 'b')
   14028              :     msize = 1;
   14029              :   else if (code == 'k')
   14030              :     msize = 4;
   14031              :   else if (code == 'q')
   14032              :     msize = 8;
   14033              :   else if (code == 'h')
   14034              :     msize = 0;
   14035              :   else if (code == 'x')
   14036              :     msize = 16;
   14037              :   else if (code == 't')
   14038              :     msize = 32;
   14039              :   else if (code == 'g')
   14040              :     msize = 64;
   14041              :   else
   14042    206958892 :     msize = GET_MODE_SIZE (GET_MODE (x));
   14043              : 
   14044    120690232 :   regno = REGNO (x);
   14045              : 
   14046    120690232 :   if (regno == ARG_POINTER_REGNUM
   14047    120690232 :       || regno == FRAME_POINTER_REGNUM
   14048    120690232 :       || regno == FPSR_REG)
   14049              :     {
   14050            0 :       output_operand_lossage
   14051            0 :         ("invalid use of register '%s'", reg_names[regno]);
   14052            0 :       return;
   14053              :     }
   14054    120690232 :   else if (regno == FLAGS_REG)
   14055              :     {
   14056            1 :       output_operand_lossage ("invalid use of asm flag output");
   14057            1 :       return;
   14058              :     }
   14059              : 
   14060    120690231 :   if (code == 'V')
   14061              :     {
   14062            1 :       if (GENERAL_REGNO_P (regno))
   14063            2 :         msize = GET_MODE_SIZE (word_mode);
   14064              :       else
   14065            0 :         error ("%<V%> modifier on non-integer register");
   14066              :     }
   14067              : 
   14068    120690231 :   duplicated = code == 'd' && TARGET_AVX;
   14069              : 
   14070    120690231 :   switch (msize)
   14071              :     {
   14072     80867893 :     case 16:
   14073     80867893 :     case 12:
   14074     80867893 :     case 8:
   14075    151647864 :       if (GENERAL_REGNO_P (regno) && msize > GET_MODE_SIZE (word_mode))
   14076            5 :         warning (0, "unsupported size for integer register");
   14077              :       /* FALLTHRU */
   14078    117167837 :     case 4:
   14079    117167837 :       if (LEGACY_INT_REGNO_P (regno))
   14080    126462370 :         putc (msize > 4 && TARGET_64BIT ? 'r' : 'e', file);
   14081              :       /* FALLTHRU */
   14082    118074002 :     case 2:
   14083    118074002 :     case 128:
   14084     22561643 :     normal:
   14085    118074002 :       reg = hi_reg_name[regno];
   14086    118074002 :       break;
   14087      2353120 :     case 1:
   14088      2353120 :       if (regno >= ARRAY_SIZE (qi_reg_name))
   14089       277705 :         goto normal;
   14090      2075415 :       if (!ANY_QI_REGNO_P (regno))
   14091            0 :         error ("unsupported size for integer register");
   14092      2075415 :       reg = qi_reg_name[regno];
   14093      2075415 :       break;
   14094        26303 :     case 0:
   14095        26303 :       if (regno >= ARRAY_SIZE (qi_high_reg_name))
   14096            0 :         goto normal;
   14097        26303 :       reg = qi_high_reg_name[regno];
   14098        26303 :       break;
   14099       514511 :     case 32:
   14100       514511 :     case 64:
   14101       514511 :       if (SSE_REGNO_P (regno))
   14102              :         {
   14103       514511 :           gcc_assert (!duplicated);
   14104       721606 :           putc (msize == 32 ? 'y' : 'z', file);
   14105       514511 :           reg = hi_reg_name[regno] + 1;
   14106       514511 :           break;
   14107              :         }
   14108            0 :       goto normal;
   14109            0 :     default:
   14110            0 :       gcc_unreachable ();
   14111              :     }
   14112              : 
   14113    120690231 :   fputs (reg, file);
   14114              : 
   14115              :   /* Irritatingly, AMD extended registers use
   14116              :      different naming convention: "r%d[bwd]"  */
   14117    120690231 :   if (REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   14118              :     {
   14119     10763978 :       gcc_assert (TARGET_64BIT);
   14120     10763978 :       switch (msize)
   14121              :         {
   14122            0 :           case 0:
   14123            0 :             error ("extended registers have no high halves");
   14124            0 :             break;
   14125       184122 :           case 1:
   14126       184122 :             putc ('b', file);
   14127       184122 :             break;
   14128        32838 :           case 2:
   14129        32838 :             putc ('w', file);
   14130        32838 :             break;
   14131      2517065 :           case 4:
   14132      2517065 :             putc ('d', file);
   14133      2517065 :             break;
   14134              :           case 8:
   14135              :             /* no suffix */
   14136              :             break;
   14137            0 :           default:
   14138            0 :             error ("unsupported operand size for extended register");
   14139            0 :             break;
   14140              :         }
   14141              :       return;
   14142              :     }
   14143              : 
   14144    109926253 :   if (duplicated)
   14145              :     {
   14146        17087 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14147        17072 :         fprintf (file, ", %%%s", reg);
   14148              :       else
   14149           15 :         fprintf (file, ", %s", reg);
   14150              :     }
   14151              : }
   14152              : 
   14153              : /* Meaning of CODE:
   14154              :    L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
   14155              :    C -- print opcode suffix for set/cmov insn.
   14156              :    c -- like C, but print reversed condition
   14157              :    F,f -- likewise, but for floating-point.
   14158              :    O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
   14159              :         otherwise nothing
   14160              :    R -- print embedded rounding and sae.
   14161              :    r -- print only sae.
   14162              :    z -- print the opcode suffix for the size of the current operand.
   14163              :    Z -- likewise, with special suffixes for x87 instructions.
   14164              :    * -- print a star (in certain assembler syntax)
   14165              :    A -- print an absolute memory reference.
   14166              :    E -- print address with DImode register names if TARGET_64BIT.
   14167              :    w -- print the operand as if it's a "word" (HImode) even if it isn't.
   14168              :    s -- print a shift double count, followed by the assemblers argument
   14169              :         delimiter.
   14170              :    b -- print the QImode name of the register for the indicated operand.
   14171              :         %b0 would print %al if operands[0] is reg 0.
   14172              :    w --  likewise, print the HImode name of the register.
   14173              :    k --  likewise, print the SImode name of the register.
   14174              :    q --  likewise, print the DImode name of the register.
   14175              :    x --  likewise, print the V4SFmode name of the register.
   14176              :    t --  likewise, print the V8SFmode name of the register.
   14177              :    g --  likewise, print the V16SFmode name of the register.
   14178              :    h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
   14179              :    y -- print "st(0)" instead of "st" as a register.
   14180              :    d -- print duplicated register operand for AVX instruction.
   14181              :    D -- print condition for SSE cmp instruction.
   14182              :    P -- if PIC, print an @PLT suffix.  For -fno-plt, load function
   14183              :         address from GOT.
   14184              :    p -- print raw symbol name.
   14185              :    X -- don't print any sort of PIC '@' suffix for a symbol.
   14186              :    & -- print some in-use local-dynamic symbol name.
   14187              :    H -- print a memory address offset by 8; used for sse high-parts
   14188              :    Y -- print condition for XOP pcom* instruction.
   14189              :    V -- print naked full integer register name without %.
   14190              :    v -- print segment override prefix
   14191              :    + -- print a branch hint as 'cs' or 'ds' prefix
   14192              :    ; -- print a semicolon (after prefixes due to bug in older gas).
   14193              :    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
   14194              :    ^ -- print addr32 prefix if Pmode != word_mode
   14195              :    M -- print addr32 prefix for TARGET_X32 with VSIB address.
   14196              :    ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
   14197              :    N -- print maskz if it's constant 0 operand.
   14198              :    G -- print embedded flag for ccmp/ctest.
   14199              :  */
   14200              : 
   14201              : void
   14202    181830644 : ix86_print_operand (FILE *file, rtx x, int code)
   14203              : {
   14204    182026418 :   if (code)
   14205              :     {
   14206     63468596 :       switch (code)
   14207              :         {
   14208       195770 :         case 'A':
   14209       195770 :           switch (ASSEMBLER_DIALECT)
   14210              :             {
   14211       195770 :             case ASM_ATT:
   14212       195770 :               putc ('*', file);
   14213       195770 :               break;
   14214              : 
   14215            0 :             case ASM_INTEL:
   14216              :               /* Intel syntax. For absolute addresses, registers should not
   14217              :                  be surrounded by braces.  */
   14218            0 :               if (!REG_P (x))
   14219              :                 {
   14220            0 :                   putc ('[', file);
   14221            0 :                   ix86_print_operand (file, x, 0);
   14222            0 :                   putc (']', file);
   14223            0 :                   return;
   14224              :                 }
   14225              :               break;
   14226              : 
   14227            0 :             default:
   14228            0 :               gcc_unreachable ();
   14229              :             }
   14230              : 
   14231              :           ix86_print_operand (file, x, 0);
   14232              :           return;
   14233              : 
   14234      4019627 :         case 'E':
   14235              :           /* Wrap address in an UNSPEC to declare special handling.  */
   14236      4019627 :           if (TARGET_64BIT)
   14237      3534224 :             x = gen_rtx_UNSPEC (DImode, gen_rtvec (1, x), UNSPEC_LEA_ADDR);
   14238              : 
   14239      4019627 :           output_address (VOIDmode, x);
   14240      4019627 :           return;
   14241              : 
   14242            0 :         case 'L':
   14243            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14244            0 :             putc ('l', file);
   14245              :           return;
   14246              : 
   14247            0 :         case 'W':
   14248            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14249            0 :             putc ('w', file);
   14250              :           return;
   14251              : 
   14252            0 :         case 'B':
   14253            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14254            0 :             putc ('b', file);
   14255              :           return;
   14256              : 
   14257            0 :         case 'Q':
   14258            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14259            0 :             putc ('l', file);
   14260              :           return;
   14261              : 
   14262            0 :         case 'S':
   14263            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14264            0 :             putc ('s', file);
   14265              :           return;
   14266              : 
   14267            0 :         case 'T':
   14268            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14269            0 :             putc ('t', file);
   14270              :           return;
   14271              : 
   14272              :         case 'O':
   14273              : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   14274              :           if (ASSEMBLER_DIALECT != ASM_ATT)
   14275              :             return;
   14276              : 
   14277              :           switch (GET_MODE_SIZE (GET_MODE (x)))
   14278              :             {
   14279              :             case 2:
   14280              :               putc ('w', file);
   14281              :               break;
   14282              : 
   14283              :             case 4:
   14284              :               putc ('l', file);
   14285              :               break;
   14286              : 
   14287              :             case 8:
   14288              :               putc ('q', file);
   14289              :               break;
   14290              : 
   14291              :             default:
   14292              :               output_operand_lossage ("invalid operand size for operand "
   14293              :                                       "code 'O'");
   14294              :               return;
   14295              :             }
   14296              : 
   14297              :           putc ('.', file);
   14298              : #endif
   14299              :           return;
   14300              : 
   14301        38160 :         case 'z':
   14302        38160 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   14303              :             {
   14304              :               /* Opcodes don't get size suffixes if using Intel opcodes.  */
   14305        38158 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   14306              :                 return;
   14307              : 
   14308        76316 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   14309              :                 {
   14310            6 :                 case 1:
   14311            6 :                   putc ('b', file);
   14312            6 :                   return;
   14313              : 
   14314            6 :                 case 2:
   14315            6 :                   putc ('w', file);
   14316            6 :                   return;
   14317              : 
   14318        37640 :                 case 4:
   14319        37640 :                   putc ('l', file);
   14320        37640 :                   return;
   14321              : 
   14322          506 :                 case 8:
   14323          506 :                   putc ('q', file);
   14324          506 :                   return;
   14325              : 
   14326            0 :                 default:
   14327            0 :                   output_operand_lossage ("invalid operand size for operand "
   14328              :                                           "code 'z'");
   14329            0 :                   return;
   14330              :                 }
   14331              :             }
   14332              : 
   14333            2 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   14334              :             {
   14335            1 :               if (this_is_asm_operands)
   14336            1 :                 warning_for_asm (this_is_asm_operands,
   14337              :                                  "non-integer operand used with operand code %<z%>");
   14338              :               else
   14339            0 :                 warning (0, "non-integer operand used with operand code %<z%>");
   14340              :             }
   14341              :           /* FALLTHRU */
   14342              : 
   14343       385497 :         case 'Z':
   14344              :           /* 387 opcodes don't get size suffixes if using Intel opcodes.  */
   14345       385497 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14346              :             return;
   14347              : 
   14348       385497 :           if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
   14349              :             {
   14350        29454 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   14351              :                 {
   14352         3523 :                 case 2:
   14353              : #ifdef HAVE_AS_IX86_FILDS
   14354         3523 :                   putc ('s', file);
   14355              : #endif
   14356         3523 :                   return;
   14357              : 
   14358         3991 :                 case 4:
   14359         3991 :                   putc ('l', file);
   14360         3991 :                   return;
   14361              : 
   14362         7213 :                 case 8:
   14363              : #ifdef HAVE_AS_IX86_FILDQ
   14364         7213 :                   putc ('q', file);
   14365              : #else
   14366              :                   fputs ("ll", file);
   14367              : #endif
   14368         7213 :                   return;
   14369              : 
   14370              :                 default:
   14371              :                   break;
   14372              :                 }
   14373              :             }
   14374       370770 :           else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
   14375              :             {
   14376              :               /* 387 opcodes don't get size suffixes
   14377              :                  if the operands are registers.  */
   14378       370768 :               if (STACK_REG_P (x))
   14379              :                 return;
   14380              : 
   14381       690976 :               switch (GET_MODE_SIZE (GET_MODE (x)))
   14382              :                 {
   14383        24059 :                 case 4:
   14384        24059 :                   putc ('s', file);
   14385        24059 :                   return;
   14386              : 
   14387        32940 :                 case 8:
   14388        32940 :                   putc ('l', file);
   14389        32940 :                   return;
   14390              : 
   14391       288487 :                 case 12:
   14392       288487 :                 case 16:
   14393       288487 :                   putc ('t', file);
   14394       288487 :                   return;
   14395              : 
   14396              :                 default:
   14397              :                   break;
   14398              :                 }
   14399              :             }
   14400              :           else
   14401              :             {
   14402            2 :               output_operand_lossage ("invalid operand type used with "
   14403              :                                       "operand code '%c'", code);
   14404            2 :               return;
   14405              :             }
   14406              : 
   14407            2 :           output_operand_lossage ("invalid operand size for operand code '%c'",
   14408              :                                   code);
   14409            2 :           return;
   14410              : 
   14411              :         case 'd':
   14412              :         case 'b':
   14413              :         case 'w':
   14414              :         case 'k':
   14415              :         case 'q':
   14416              :         case 'h':
   14417              :         case 't':
   14418              :         case 'g':
   14419              :         case 'y':
   14420              :         case 'x':
   14421              :         case 'X':
   14422              :         case 'P':
   14423              :         case 'p':
   14424              :         case 'V':
   14425              :           break;
   14426              : 
   14427            0 :         case 's':
   14428            0 :           if (CONST_INT_P (x) || ! SHIFT_DOUBLE_OMITS_COUNT)
   14429              :             {
   14430            0 :               ix86_print_operand (file, x, 0);
   14431            0 :               fputs (", ", file);
   14432              :             }
   14433              :           return;
   14434              : 
   14435          488 :         case 'Y':
   14436          488 :           switch (GET_CODE (x))
   14437              :             {
   14438          176 :             case NE:
   14439          176 :               fputs ("neq", file);
   14440          176 :               break;
   14441           32 :             case EQ:
   14442           32 :               fputs ("eq", file);
   14443           32 :               break;
   14444           64 :             case GE:
   14445           64 :             case GEU:
   14446           64 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "ge" : "unlt", file);
   14447           64 :               break;
   14448           40 :             case GT:
   14449           40 :             case GTU:
   14450           40 :               fputs (INTEGRAL_MODE_P (GET_MODE (x)) ? "gt" : "unle", file);
   14451           40 :               break;
   14452           64 :             case LE:
   14453           64 :             case LEU:
   14454           64 :               fputs ("le", file);
   14455           64 :               break;
   14456          112 :             case LT:
   14457          112 :             case LTU:
   14458          112 :               fputs ("lt", file);
   14459          112 :               break;
   14460            0 :             case UNORDERED:
   14461            0 :               fputs ("unord", file);
   14462            0 :               break;
   14463            0 :             case ORDERED:
   14464            0 :               fputs ("ord", file);
   14465            0 :               break;
   14466            0 :             case UNEQ:
   14467            0 :               fputs ("ueq", file);
   14468            0 :               break;
   14469            0 :             case UNGE:
   14470            0 :               fputs ("nlt", file);
   14471            0 :               break;
   14472            0 :             case UNGT:
   14473            0 :               fputs ("nle", file);
   14474            0 :               break;
   14475            0 :             case UNLE:
   14476            0 :               fputs ("ule", file);
   14477            0 :               break;
   14478            0 :             case UNLT:
   14479            0 :               fputs ("ult", file);
   14480            0 :               break;
   14481            0 :             case LTGT:
   14482            0 :               fputs ("une", file);
   14483            0 :               break;
   14484            0 :             default:
   14485            0 :               output_operand_lossage ("operand is not a condition code, "
   14486              :                                       "invalid operand code 'Y'");
   14487            0 :               return;
   14488              :             }
   14489              :           return;
   14490              : 
   14491        10130 :         case 'D':
   14492              :           /* Little bit of braindamage here.  The SSE compare instructions
   14493              :              does use completely different names for the comparisons that the
   14494              :              fp conditional moves.  */
   14495        10130 :           switch (GET_CODE (x))
   14496              :             {
   14497           16 :             case UNEQ:
   14498           16 :               if (TARGET_AVX)
   14499              :                 {
   14500           16 :                   fputs ("eq_uq", file);
   14501           16 :                   break;
   14502              :                 }
   14503              :              /* FALLTHRU */
   14504         5226 :             case EQ:
   14505         5226 :               fputs ("eq", file);
   14506         5226 :               break;
   14507            0 :             case UNLT:
   14508            0 :               if (TARGET_AVX)
   14509              :                 {
   14510            0 :                   fputs ("nge_uq", file);
   14511            0 :                   break;
   14512              :                 }
   14513              :              /* FALLTHRU */
   14514         1746 :             case LT:
   14515         1746 :               fputs ("lt", file);
   14516         1746 :               break;
   14517            0 :             case UNLE:
   14518            0 :               if (TARGET_AVX)
   14519              :                 {
   14520            0 :                   fputs ("ngt_uq", file);
   14521            0 :                   break;
   14522              :                 }
   14523              :              /* FALLTHRU */
   14524          820 :             case LE:
   14525          820 :               fputs ("le", file);
   14526          820 :               break;
   14527          103 :             case UNORDERED:
   14528          103 :               fputs ("unord", file);
   14529          103 :               break;
   14530           12 :             case LTGT:
   14531           12 :               if (TARGET_AVX)
   14532              :                 {
   14533           12 :                   fputs ("neq_oq", file);
   14534           12 :                   break;
   14535              :                 }
   14536              :              /* FALLTHRU */
   14537          905 :             case NE:
   14538          905 :               fputs ("neq", file);
   14539          905 :               break;
   14540            0 :             case GE:
   14541            0 :               if (TARGET_AVX)
   14542              :                 {
   14543            0 :                   fputs ("ge", file);
   14544            0 :                   break;
   14545              :                 }
   14546              :              /* FALLTHRU */
   14547          446 :             case UNGE:
   14548              :               /* Only AVX has the quiet form.  */
   14549          446 :               fputs (TARGET_AVX ? "nlt_uq" : "nlt", file);
   14550          446 :               break;
   14551            0 :             case GT:
   14552            0 :               if (TARGET_AVX)
   14553              :                 {
   14554            0 :                   fputs ("gt", file);
   14555            0 :                   break;
   14556              :                 }
   14557              :              /* FALLTHRU */
   14558          773 :             case UNGT:
   14559          773 :               fputs (TARGET_AVX ? "nle_uq" : "nle", file);
   14560          773 :               break;
   14561           83 :             case ORDERED:
   14562           83 :               fputs ("ord", file);
   14563           83 :               break;
   14564            0 :             default:
   14565            0 :               output_operand_lossage ("operand is not a condition code, "
   14566              :                                       "invalid operand code 'D'");
   14567            0 :               return;
   14568              :             }
   14569              :           return;
   14570              : 
   14571      7337517 :         case 'F':
   14572      7337517 :         case 'f':
   14573              : #ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
   14574              :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14575              :             putc ('.', file);
   14576              :           gcc_fallthrough ();
   14577              : #endif
   14578              : 
   14579      7337517 :         case 'C':
   14580      7337517 :         case 'c':
   14581      7337517 :           if (!COMPARISON_P (x))
   14582              :             {
   14583            0 :               output_operand_lossage ("operand is not a condition code, "
   14584              :                                       "invalid operand code '%c'", code);
   14585            0 :               return;
   14586              :             }
   14587      7337517 :           put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)),
   14588      7337517 :                               code == 'c' || code == 'f',
   14589      7337517 :                               code == 'F' || code == 'f',
   14590              :                               file);
   14591      7337517 :           return;
   14592              : 
   14593           23 :         case 'G':
   14594           23 :           {
   14595           23 :             int dfv = INTVAL (x);
   14596           23 :             const char *dfv_suffix = ix86_ccmp_dfv_mapping[dfv];
   14597           23 :             fputs (dfv_suffix, file);
   14598              :           }
   14599           23 :           return;
   14600              : 
   14601         1306 :         case 'H':
   14602         1306 :           if (!offsettable_memref_p (x))
   14603              :             {
   14604            1 :               output_operand_lossage ("operand is not an offsettable memory "
   14605              :                                       "reference, invalid operand code 'H'");
   14606            1 :               return;
   14607              :             }
   14608              :           /* It doesn't actually matter what mode we use here, as we're
   14609              :              only going to use this for printing.  */
   14610         1305 :           x = adjust_address_nv (x, DImode, 8);
   14611              :           /* Output 'qword ptr' for intel assembler dialect.  */
   14612         1305 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14613            0 :             code = 'q';
   14614              :           break;
   14615              : 
   14616        75994 :         case 'K':
   14617        75994 :           if (!CONST_INT_P (x))
   14618              :             {
   14619            1 :               output_operand_lossage ("operand is not an integer, invalid "
   14620              :                                       "operand code 'K'");
   14621            1 :               return;
   14622              :             }
   14623              : 
   14624        75993 :           if (INTVAL (x) & IX86_HLE_ACQUIRE)
   14625              : #ifdef HAVE_AS_IX86_HLE
   14626           22 :             fputs ("xacquire ", file);
   14627              : #else
   14628              :             fputs ("\n" ASM_BYTE "0xf2\n\t", file);
   14629              : #endif
   14630        75971 :           else if (INTVAL (x) & IX86_HLE_RELEASE)
   14631              : #ifdef HAVE_AS_IX86_HLE
   14632           24 :             fputs ("xrelease ", file);
   14633              : #else
   14634              :             fputs ("\n" ASM_BYTE "0xf3\n\t", file);
   14635              : #endif
   14636              :           /* We do not want to print value of the operand.  */
   14637              :           return;
   14638              : 
   14639        44326 :         case 'N':
   14640        44326 :           if (x == const0_rtx || x == CONST0_RTX (GET_MODE (x)))
   14641        15862 :             fputs ("{z}", file);
   14642              :           return;
   14643              : 
   14644         4060 :         case 'r':
   14645         4060 :           if (!CONST_INT_P (x) || INTVAL (x) != ROUND_SAE)
   14646              :             {
   14647            2 :               output_operand_lossage ("operand is not a specific integer, "
   14648              :                                       "invalid operand code 'r'");
   14649            2 :               return;
   14650              :             }
   14651              : 
   14652         4058 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14653            1 :             fputs (", ", file);
   14654              : 
   14655         4058 :           fputs ("{sae}", file);
   14656              : 
   14657         4058 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14658         4057 :             fputs (", ", file);
   14659              : 
   14660              :           return;
   14661              : 
   14662         5975 :         case 'R':
   14663         5975 :           if (!CONST_INT_P (x))
   14664              :             {
   14665            1 :               output_operand_lossage ("operand is not an integer, invalid "
   14666              :                                       "operand code 'R'");
   14667            1 :               return;
   14668              :             }
   14669              : 
   14670         5974 :           if (ASSEMBLER_DIALECT == ASM_INTEL)
   14671            6 :             fputs (", ", file);
   14672              : 
   14673         5974 :           switch (INTVAL (x))
   14674              :             {
   14675         5159 :             case ROUND_NEAREST_INT | ROUND_SAE:
   14676         5159 :               fputs ("{rn-sae}", file);
   14677         5159 :               break;
   14678          637 :             case ROUND_NEG_INF | ROUND_SAE:
   14679          637 :               fputs ("{rd-sae}", file);
   14680          637 :               break;
   14681           56 :             case ROUND_POS_INF | ROUND_SAE:
   14682           56 :               fputs ("{ru-sae}", file);
   14683           56 :               break;
   14684          121 :             case ROUND_ZERO | ROUND_SAE:
   14685          121 :               fputs ("{rz-sae}", file);
   14686          121 :               break;
   14687            1 :             default:
   14688            1 :               output_operand_lossage ("operand is not a specific integer, "
   14689              :                                       "invalid operand code 'R'");
   14690              :             }
   14691              : 
   14692         5974 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14693         5968 :             fputs (", ", file);
   14694              : 
   14695              :           return;
   14696              : 
   14697        11020 :         case 'v':
   14698        11020 :           if (MEM_P (x))
   14699              :             {
   14700        11148 :               switch (MEM_ADDR_SPACE (x))
   14701              :                 {
   14702              :                 case ADDR_SPACE_GENERIC:
   14703              :                   break;
   14704            0 :                 case ADDR_SPACE_SEG_FS:
   14705            0 :                   fputs ("fs ", file);
   14706            0 :                   break;
   14707            0 :                 case ADDR_SPACE_SEG_GS:
   14708            0 :                   fputs ("gs ", file);
   14709            0 :                   break;
   14710            0 :                 default:
   14711            0 :                   gcc_unreachable ();
   14712              :                 }
   14713              :             }
   14714              :           else
   14715            0 :             output_operand_lossage ("operand is not a memory reference, "
   14716              :                                     "invalid operand code 'v'");
   14717              :           return;
   14718              : 
   14719            0 :         case '*':
   14720            0 :           if (ASSEMBLER_DIALECT == ASM_ATT)
   14721            0 :             putc ('*', file);
   14722              :           return;
   14723              : 
   14724          206 :         case '&':
   14725          206 :           {
   14726          206 :             const char *name = get_some_local_dynamic_name ();
   14727          206 :             if (name == NULL)
   14728            1 :               output_operand_lossage ("'%%&' used without any "
   14729              :                                       "local dynamic TLS references");
   14730              :             else
   14731          205 :               assemble_name (file, name);
   14732              :             return;
   14733              :           }
   14734              : 
   14735      6637126 :         case '+':
   14736      6637126 :           {
   14737      6637126 :             rtx x;
   14738              : 
   14739      6637126 :             if (!optimize
   14740      5197345 :                 || optimize_function_for_size_p (cfun)
   14741     11645309 :                 || (!TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN
   14742      5008183 :                     && !TARGET_BRANCH_PREDICTION_HINTS_TAKEN))
   14743              :               return;
   14744              : 
   14745            0 :             x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
   14746            0 :             if (x)
   14747              :               {
   14748            0 :                 int pred_val = profile_probability::from_reg_br_prob_note
   14749            0 :                                  (XINT (x, 0)).to_reg_br_prob_base ();
   14750              : 
   14751            0 :                 bool taken = pred_val > REG_BR_PROB_BASE / 2;
   14752              :                 /* We use 3e (DS) prefix for taken branches and
   14753              :                    2e (CS) prefix for not taken branches.  */
   14754            0 :                 if (taken && TARGET_BRANCH_PREDICTION_HINTS_TAKEN)
   14755            0 :                   fputs ("ds ; ", file);
   14756            0 :                 else if (!taken && TARGET_BRANCH_PREDICTION_HINTS_NOT_TAKEN)
   14757            0 :                   fputs ("cs ; ", file);
   14758              :               }
   14759              :             return;
   14760              :           }
   14761              : 
   14762              :         case ';':
   14763              : #ifndef HAVE_AS_IX86_REP_LOCK_PREFIX
   14764              :           putc (';', file);
   14765              : #endif
   14766              :           return;
   14767              : 
   14768         3258 :         case '~':
   14769         3258 :           putc (TARGET_AVX2 ? 'i' : 'f', file);
   14770         3258 :           return;
   14771              : 
   14772         1646 :         case 'M':
   14773         1646 :           if (TARGET_X32)
   14774              :             {
   14775              :               /* NB: 32-bit indices in VSIB address are sign-extended
   14776              :                  to 64 bits. In x32, if 32-bit address 0xf7fa3010 is
   14777              :                  sign-extended to 0xfffffffff7fa3010 which is invalid
   14778              :                  address.  Add addr32 prefix if there is no base
   14779              :                  register nor symbol.  */
   14780            8 :               bool ok;
   14781            8 :               struct ix86_address parts;
   14782            8 :               ok = ix86_decompose_address (x, &parts);
   14783            8 :               gcc_assert (ok && parts.index == NULL_RTX);
   14784            8 :               if (parts.base == NULL_RTX
   14785            8 :                   && (parts.disp == NULL_RTX
   14786            2 :                       || !symbolic_operand (parts.disp,
   14787            2 :                                             GET_MODE (parts.disp))))
   14788            2 :                 fputs ("addr32 ", file);
   14789              :             }
   14790              :           return;
   14791              : 
   14792        24708 :         case '^':
   14793        27913 :           if (Pmode != word_mode)
   14794            0 :             fputs ("addr32 ", file);
   14795              :           return;
   14796              : 
   14797     15311784 :         case '!':
   14798     15311784 :           if (ix86_notrack_prefixed_insn_p (current_output_insn))
   14799         4650 :             fputs ("notrack ", file);
   14800              :           return;
   14801              : 
   14802            1 :         default:
   14803            1 :           output_operand_lossage ("invalid operand code '%c'", code);
   14804              :         }
   14805              :     }
   14806              : 
   14807    147474438 :   if (REG_P (x))
   14808     88204863 :     print_reg (x, code, file);
   14809              : 
   14810     59269575 :   else if (MEM_P (x))
   14811              :     {
   14812     33985730 :       rtx addr = XEXP (x, 0);
   14813              : 
   14814              :       /* No `byte ptr' prefix for call instructions ... */
   14815     33985730 :       if (ASSEMBLER_DIALECT == ASM_INTEL && code != 'X' && code != 'P')
   14816              :         {
   14817          316 :           machine_mode mode = GET_MODE (x);
   14818          316 :           const char *size;
   14819              : 
   14820              :           /* Check for explicit size override codes.  */
   14821          316 :           if (code == 'b')
   14822              :             size = "BYTE";
   14823              :           else if (code == 'w')
   14824              :             size = "WORD";
   14825              :           else if (code == 'k')
   14826              :             size = "DWORD";
   14827              :           else if (code == 'q')
   14828              :             size = "QWORD";
   14829              :           else if (code == 'x')
   14830              :             size = "XMMWORD";
   14831              :           else if (code == 't')
   14832              :             size = "YMMWORD";
   14833              :           else if (code == 'g')
   14834              :             size = "ZMMWORD";
   14835          230 :           else if (mode == BLKmode)
   14836              :             /* ... or BLKmode operands, when not overridden.  */
   14837              :             size = NULL;
   14838              :           else
   14839          456 :             switch (GET_MODE_SIZE (mode))
   14840              :               {
   14841              :               case 1: size = "BYTE"; break;
   14842              :               case 2: size = "WORD"; break;
   14843              :               case 4: size = "DWORD"; break;
   14844              :               case 8: size = "QWORD"; break;
   14845              :               case 12: size = "TBYTE"; break;
   14846            8 :               case 16:
   14847            8 :                 if (mode == XFmode)
   14848              :                   size = "TBYTE";
   14849              :                 else
   14850              :                   size = "XMMWORD";
   14851              :                 break;
   14852              :               case 32: size = "YMMWORD"; break;
   14853              :               case 64: size = "ZMMWORD"; break;
   14854            0 :               default:
   14855            0 :                 gcc_unreachable ();
   14856              :               }
   14857              :           if (size)
   14858              :             {
   14859          314 :               fputs (size, file);
   14860          314 :               fputs (" PTR ", file);
   14861              :             }
   14862              :         }
   14863              : 
   14864     33985730 :       if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   14865            0 :         output_operand_lossage ("invalid constraints for operand");
   14866              :       else
   14867     33985730 :         ix86_print_operand_address_as
   14868     34547106 :           (file, addr, MEM_ADDR_SPACE (x), code == 'p' || code == 'P');
   14869              :     }
   14870              : 
   14871     25283845 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == HFmode)
   14872              :     {
   14873          971 :       long l = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   14874          971 :                                REAL_MODE_FORMAT (HFmode));
   14875          971 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14876          971 :         putc ('$', file);
   14877          971 :       fprintf (file, "0x%04x", (unsigned int) l);
   14878          971 :     }
   14879              : 
   14880     25282874 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
   14881              :     {
   14882        20909 :       long l;
   14883              : 
   14884        20909 :       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14885              : 
   14886        20909 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14887        20909 :         putc ('$', file);
   14888              :       /* Sign extend 32bit SFmode immediate to 8 bytes.  */
   14889        20909 :       if (code == 'q')
   14890          327 :         fprintf (file, "0x%08" HOST_LONG_LONG_FORMAT "x",
   14891              :                  (unsigned long long) (int) l);
   14892              :       else
   14893        20582 :         fprintf (file, "0x%08x", (unsigned int) l);
   14894              :     }
   14895              : 
   14896     25261965 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == DFmode)
   14897              :     {
   14898         3909 :       long l[2];
   14899              : 
   14900         3909 :       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
   14901              : 
   14902         3909 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   14903         3909 :         putc ('$', file);
   14904         3909 :       fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
   14905         3909 :     }
   14906              : 
   14907              :   /* These float cases don't actually occur as immediate operands.  */
   14908     25258056 :   else if (CONST_DOUBLE_P (x) && GET_MODE (x) == XFmode)
   14909              :     {
   14910            0 :       char dstr[30];
   14911              : 
   14912            0 :       real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x), sizeof (dstr), 0, 1);
   14913            0 :       fputs (dstr, file);
   14914            0 :     }
   14915              : 
   14916              :   /* Print bcst_mem_operand.  */
   14917     25258056 :   else if (GET_CODE (x) == VEC_DUPLICATE)
   14918              :     {
   14919          314 :       machine_mode vmode = GET_MODE (x);
   14920              :       /* Must be bcst_memory_operand.  */
   14921          314 :       gcc_assert (bcst_mem_operand (x, vmode));
   14922              : 
   14923          314 :       rtx mem = XEXP (x,0);
   14924          314 :       ix86_print_operand (file, mem, 0);
   14925              : 
   14926          314 :       switch (vmode)
   14927              :         {
   14928           28 :         case E_V2DImode:
   14929           28 :         case E_V2DFmode:
   14930           28 :           fputs ("{1to2}", file);
   14931           28 :           break;
   14932           74 :         case E_V4SImode:
   14933           74 :         case E_V4SFmode:
   14934           74 :         case E_V4DImode:
   14935           74 :         case E_V4DFmode:
   14936           74 :           fputs ("{1to4}", file);
   14937           74 :           break;
   14938           94 :         case E_V8SImode:
   14939           94 :         case E_V8SFmode:
   14940           94 :         case E_V8DFmode:
   14941           94 :         case E_V8DImode:
   14942           94 :         case E_V8HFmode:
   14943           94 :           fputs ("{1to8}", file);
   14944           94 :           break;
   14945          110 :         case E_V16SFmode:
   14946          110 :         case E_V16SImode:
   14947          110 :         case E_V16HFmode:
   14948          110 :           fputs ("{1to16}", file);
   14949          110 :           break;
   14950            8 :         case E_V32HFmode:
   14951            8 :           fputs ("{1to32}", file);
   14952            8 :           break;
   14953            0 :         default:
   14954            0 :           gcc_unreachable ();
   14955              :         }
   14956              :     }
   14957              : 
   14958              :   else
   14959              :     {
   14960              :       /* We have patterns that allow zero sets of memory, for instance.
   14961              :          In 64-bit mode, we should probably support all 8-byte vectors,
   14962              :          since we can in fact encode that into an immediate.  */
   14963     25257742 :       if (CONST_VECTOR_P (x))
   14964              :         {
   14965         3204 :           if (x != CONST0_RTX (GET_MODE (x)))
   14966            2 :             output_operand_lossage ("invalid vector immediate");
   14967         3204 :           x = const0_rtx;
   14968              :         }
   14969              : 
   14970     25257742 :       if (code == 'P')
   14971              :         {
   14972      6156682 :           if (ix86_force_load_from_GOT_p (x, true))
   14973              :             {
   14974              :               /* For inline assembly statement, load function address
   14975              :                  from GOT with 'P' operand modifier to avoid PLT.  */
   14976            4 :               x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
   14977              :                                   (TARGET_64BIT
   14978              :                                    ? UNSPEC_GOTPCREL
   14979              :                                    : UNSPEC_GOT));
   14980            4 :               x = gen_rtx_CONST (Pmode, x);
   14981            4 :               x = gen_const_mem (Pmode, x);
   14982            4 :               ix86_print_operand (file, x, 'A');
   14983            4 :               return;
   14984              :             }
   14985              :         }
   14986     19101060 :       else if (code != 'p')
   14987              :         {
   14988     19100951 :           if (CONST_INT_P (x))
   14989              :             {
   14990     16015490 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14991     16015264 :                 putc ('$', file);
   14992              :             }
   14993      3085461 :           else if (GET_CODE (x) == CONST || SYMBOL_REF_P (x)
   14994         9355 :                    || LABEL_REF_P (x))
   14995              :             {
   14996      3085459 :               if (ASSEMBLER_DIALECT == ASM_ATT)
   14997      3085453 :                 putc ('$', file);
   14998              :               else
   14999            6 :                 fputs ("OFFSET FLAT:", file);
   15000              :             }
   15001              :         }
   15002     25257738 :       if (CONST_INT_P (x))
   15003     16015576 :         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
   15004      9242162 :       else if (flag_pic || MACHOPIC_INDIRECT)
   15005       745751 :         output_pic_addr_const (file, x, code);
   15006              :       else
   15007      8496411 :         output_addr_const (file, x);
   15008              :     }
   15009              : }
   15010              : 
   15011              : static bool
   15012     22060531 : ix86_print_operand_punct_valid_p (unsigned char code)
   15013              : {
   15014     22060531 :   return (code == '*' || code == '+' || code == '&' || code == ';'
   15015     15336492 :           || code == '~' || code == '^' || code == '!');
   15016              : }
   15017              : 
   15018              : /* Print a memory operand whose address is ADDR.  */
   15019              : 
   15020              : static void
   15021     38007636 : ix86_print_operand_address_as (FILE *file, rtx addr,
   15022              :                                addr_space_t as, bool raw)
   15023              : {
   15024     38007636 :   struct ix86_address parts;
   15025     38007636 :   rtx base, index, disp;
   15026     38007636 :   int scale;
   15027     38007636 :   int ok;
   15028     38007636 :   bool vsib = false;
   15029     38007636 :   int code = 0;
   15030              : 
   15031     38007636 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_VSIBADDR)
   15032              :     {
   15033         1646 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   15034         1646 :       gcc_assert (parts.index == NULL_RTX);
   15035         1646 :       parts.index = XVECEXP (addr, 0, 1);
   15036         1646 :       parts.scale = INTVAL (XVECEXP (addr, 0, 2));
   15037         1646 :       addr = XVECEXP (addr, 0, 0);
   15038         1646 :       vsib = true;
   15039              :     }
   15040     38005990 :   else if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LEA_ADDR)
   15041              :     {
   15042      3534224 :       gcc_assert (TARGET_64BIT);
   15043      3534224 :       ok = ix86_decompose_address (XVECEXP (addr, 0, 0), &parts);
   15044      3534224 :       code = 'q';
   15045              :     }
   15046              :   else
   15047     34471766 :     ok = ix86_decompose_address (addr, &parts);
   15048              : 
   15049     38007636 :   gcc_assert (ok);
   15050              : 
   15051     38007636 :   base = parts.base;
   15052     38007636 :   index = parts.index;
   15053     38007636 :   disp = parts.disp;
   15054     38007636 :   scale = parts.scale;
   15055              : 
   15056     38007636 :   if (ADDR_SPACE_GENERIC_P (as))
   15057     37725693 :     as = parts.seg;
   15058              :   else
   15059       281943 :     gcc_assert (ADDR_SPACE_GENERIC_P (parts.seg));
   15060              : 
   15061     38007636 :   if (!ADDR_SPACE_GENERIC_P (as) && !raw)
   15062              :     {
   15063       281958 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   15064       281956 :         putc ('%', file);
   15065              : 
   15066       281958 :       switch (as)
   15067              :         {
   15068       182247 :         case ADDR_SPACE_SEG_FS:
   15069       182247 :           fputs ("fs:", file);
   15070       182247 :           break;
   15071        99711 :         case ADDR_SPACE_SEG_GS:
   15072        99711 :           fputs ("gs:", file);
   15073        99711 :           break;
   15074            0 :         default:
   15075            0 :           gcc_unreachable ();
   15076              :         }
   15077              :     }
   15078              : 
   15079              :   /* Use one byte shorter RIP relative addressing for 64bit mode.  */
   15080     38007636 :   if (TARGET_64BIT && !base && !index && !raw)
   15081              :     {
   15082      6371027 :       rtx symbol = disp;
   15083              : 
   15084      6371027 :       if (GET_CODE (disp) == CONST
   15085      2217211 :           && GET_CODE (XEXP (disp, 0)) == PLUS
   15086      2102626 :           && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   15087      2102626 :         symbol = XEXP (XEXP (disp, 0), 0);
   15088              : 
   15089      6371027 :       if (LABEL_REF_P (symbol)
   15090      6371027 :           || (SYMBOL_REF_P (symbol)
   15091      6079928 :               && SYMBOL_REF_TLS_MODEL (symbol) == 0))
   15092      6079856 :         base = pc_rtx;
   15093              :     }
   15094              : 
   15095     38007636 :   if (!base && !index)
   15096              :     {
   15097              :       /* Displacement only requires special attention.  */
   15098       629011 :       if (CONST_INT_P (disp))
   15099              :         {
   15100       269422 :           if (ASSEMBLER_DIALECT == ASM_INTEL && ADDR_SPACE_GENERIC_P (as))
   15101            0 :             fputs ("ds:", file);
   15102       269422 :           fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
   15103              :         }
   15104              :       /* Load the external function address via the GOT slot to avoid PLT.  */
   15105       359589 :       else if (GET_CODE (disp) == CONST
   15106       143046 :                && GET_CODE (XEXP (disp, 0)) == UNSPEC
   15107       114826 :                && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOTPCREL
   15108         9593 :                    || XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
   15109       464822 :                && ix86_force_load_from_GOT_p (XVECEXP (XEXP (disp, 0), 0, 0)))
   15110           24 :         output_pic_addr_const (file, disp, 0);
   15111       359565 :       else if (flag_pic)
   15112       144332 :         output_pic_addr_const (file, disp, 0);
   15113              :       else
   15114       215233 :         output_addr_const (file, disp);
   15115              :     }
   15116              :   else
   15117              :     {
   15118              :       /* Print SImode register names to force addr32 prefix.  */
   15119     37378625 :       if (SImode_address_operand (addr, VOIDmode))
   15120              :         {
   15121           67 :           if (flag_checking)
   15122              :             {
   15123           67 :               gcc_assert (TARGET_64BIT);
   15124           67 :               switch (GET_CODE (addr))
   15125              :                 {
   15126            0 :                 case SUBREG:
   15127            0 :                   gcc_assert (GET_MODE (addr) == SImode);
   15128            0 :                   gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
   15129              :                   break;
   15130           67 :                 case ZERO_EXTEND:
   15131           67 :                 case AND:
   15132           67 :                   gcc_assert (GET_MODE (addr) == DImode);
   15133              :                   break;
   15134            0 :                 default:
   15135            0 :                   gcc_unreachable ();
   15136              :                 }
   15137              :             }
   15138           67 :           gcc_assert (!code);
   15139              :           code = 'k';
   15140              :         }
   15141     37378558 :       else if (code == 0
   15142     33845979 :                && TARGET_X32
   15143          516 :                && disp
   15144          416 :                && CONST_INT_P (disp)
   15145          324 :                && INTVAL (disp) < -16*1024*1024)
   15146              :         {
   15147              :           /* X32 runs in 64-bit mode, where displacement, DISP, in
   15148              :              address DISP(%r64), is encoded as 32-bit immediate sign-
   15149              :              extended from 32-bit to 64-bit.  For -0x40000300(%r64),
   15150              :              address is %r64 + 0xffffffffbffffd00.  When %r64 <
   15151              :              0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
   15152              :              which is invalid for x32.  The correct address is %r64
   15153              :              - 0x40000300 == 0xf7ffdd64.  To properly encode
   15154              :              -0x40000300(%r64) for x32, we zero-extend negative
   15155              :              displacement by forcing addr32 prefix which truncates
   15156              :              0xfffffffff7ffdd64 to 0xf7ffdd64.  In theory, we should
   15157              :              zero-extend all negative displacements, including -1(%rsp).
   15158              :              However, for small negative displacements, sign-extension
   15159              :              won't cause overflow.  We only zero-extend negative
   15160              :              displacements if they < -16*1024*1024, which is also used
   15161              :              to check legitimate address displacements for PIC.  */
   15162           67 :           code = 'k';
   15163              :         }
   15164              : 
   15165              :       /* Since the upper 32 bits of RSP are always zero for x32,
   15166              :          we can encode %esp as %rsp to avoid 0x67 prefix if
   15167              :          there is no index register.  */
   15168         1083 :       if (TARGET_X32 && Pmode == SImode
   15169     37379085 :           && !index && base && REG_P (base) && REGNO (base) == SP_REG)
   15170              :         code = 'q';
   15171              : 
   15172     37378625 :       if (ASSEMBLER_DIALECT == ASM_ATT)
   15173              :         {
   15174     37378241 :           if (disp)
   15175              :             {
   15176     33251985 :               if (flag_pic)
   15177      3876625 :                 output_pic_addr_const (file, disp, 0);
   15178     29375360 :               else if (LABEL_REF_P (disp))
   15179         6073 :                 output_asm_label (disp);
   15180              :               else
   15181     29369287 :                 output_addr_const (file, disp);
   15182              :             }
   15183              : 
   15184     37378241 :           putc ('(', file);
   15185     37378241 :           if (base)
   15186     36927671 :             print_reg (base, code, file);
   15187     37378241 :           if (index)
   15188              :             {
   15189      1927605 :               putc (',', file);
   15190      3853612 :               print_reg (index, vsib ? 0 : code, file);
   15191      1927605 :               if (scale != 1 || vsib)
   15192      1052125 :                 fprintf (file, ",%d", scale);
   15193              :             }
   15194     37378241 :           putc (')', file);
   15195              :         }
   15196              :       else
   15197              :         {
   15198          384 :           rtx offset = NULL_RTX;
   15199              : 
   15200          384 :           if (disp)
   15201              :             {
   15202              :               /* Pull out the offset of a symbol; print any symbol itself.  */
   15203          304 :               if (GET_CODE (disp) == CONST
   15204           14 :                   && GET_CODE (XEXP (disp, 0)) == PLUS
   15205           14 :                   && CONST_INT_P (XEXP (XEXP (disp, 0), 1)))
   15206              :                 {
   15207           14 :                   offset = XEXP (XEXP (disp, 0), 1);
   15208           14 :                   disp = gen_rtx_CONST (VOIDmode,
   15209              :                                         XEXP (XEXP (disp, 0), 0));
   15210              :                 }
   15211              : 
   15212          304 :               if (flag_pic)
   15213           68 :                 output_pic_addr_const (file, disp, 0);
   15214          236 :               else if (LABEL_REF_P (disp))
   15215            0 :                 output_asm_label (disp);
   15216          236 :               else if (CONST_INT_P (disp))
   15217              :                 offset = disp;
   15218              :               else
   15219           99 :                 output_addr_const (file, disp);
   15220              :             }
   15221              : 
   15222          384 :           putc ('[', file);
   15223          384 :           if (base)
   15224              :             {
   15225          347 :               print_reg (base, code, file);
   15226          347 :               if (offset)
   15227              :                 {
   15228          151 :                   if (INTVAL (offset) >= 0)
   15229           20 :                     putc ('+', file);
   15230          151 :                   fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   15231              :                 }
   15232              :             }
   15233           37 :           else if (offset)
   15234            0 :             fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (offset));
   15235              :           else
   15236           37 :             putc ('0', file);
   15237              : 
   15238          384 :           if (index)
   15239              :             {
   15240           90 :               putc ('+', file);
   15241          132 :               print_reg (index, vsib ? 0 : code, file);
   15242           90 :               if (scale != 1 || vsib)
   15243           88 :                 fprintf (file, "*%d", scale);
   15244              :             }
   15245          384 :           putc (']', file);
   15246              :         }
   15247              :     }
   15248     38007636 : }
   15249              : 
   15250              : static void
   15251      4021907 : ix86_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   15252              : {
   15253      4021907 :   if (this_is_asm_operands && ! address_operand (addr, VOIDmode))
   15254            1 :     output_operand_lossage ("invalid constraints for operand");
   15255              :   else
   15256      4021906 :     ix86_print_operand_address_as (file, addr, ADDR_SPACE_GENERIC, false);
   15257      4021907 : }
   15258              : 
   15259              : /* Implementation of TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA.  */
   15260              : 
   15261              : static bool
   15262        14774 : i386_asm_output_addr_const_extra (FILE *file, rtx x)
   15263              : {
   15264        14774 :   rtx op;
   15265              : 
   15266        14774 :   if (GET_CODE (x) != UNSPEC)
   15267              :     return false;
   15268              : 
   15269        14774 :   op = XVECEXP (x, 0, 0);
   15270        14774 :   switch (XINT (x, 1))
   15271              :     {
   15272          599 :     case UNSPEC_GOTOFF:
   15273          599 :       output_addr_const (file, op);
   15274          599 :       fputs ("@gotoff", file);
   15275          599 :       break;
   15276            0 :     case UNSPEC_GOTTPOFF:
   15277            0 :       output_addr_const (file, op);
   15278              :       /* FIXME: This might be @TPOFF in Sun ld.  */
   15279            0 :       fputs ("@gottpoff", file);
   15280            0 :       break;
   15281            0 :     case UNSPEC_TPOFF:
   15282            0 :       output_addr_const (file, op);
   15283            0 :       fputs ("@tpoff", file);
   15284            0 :       break;
   15285        11070 :     case UNSPEC_NTPOFF:
   15286        11070 :       output_addr_const (file, op);
   15287        11070 :       if (TARGET_64BIT)
   15288        10294 :         fputs ("@tpoff", file);
   15289              :       else
   15290          776 :         fputs ("@ntpoff", file);
   15291              :       break;
   15292            0 :     case UNSPEC_DTPOFF:
   15293            0 :       output_addr_const (file, op);
   15294            0 :       fputs ("@dtpoff", file);
   15295            0 :       break;
   15296         3104 :     case UNSPEC_GOTNTPOFF:
   15297         3104 :       output_addr_const (file, op);
   15298         3104 :       if (TARGET_64BIT)
   15299         3104 :         fputs (ASSEMBLER_DIALECT == ASM_ATT ?
   15300              :                "@gottpoff(%rip)" : "@gottpoff[rip]", file);
   15301              :       else
   15302            0 :         fputs ("@gotntpoff", file);
   15303              :       break;
   15304            1 :     case UNSPEC_INDNTPOFF:
   15305            1 :       output_addr_const (file, op);
   15306            1 :       fputs ("@indntpoff", file);
   15307            1 :       break;
   15308            0 :     case UNSPEC_SECREL32:
   15309            0 :       output_addr_const (file, op);
   15310            0 :       fputs ("@secrel32", file);
   15311            0 :       break;
   15312              : #if TARGET_MACHO
   15313              :     case UNSPEC_MACHOPIC_OFFSET:
   15314              :       output_addr_const (file, op);
   15315              :       putc ('-', file);
   15316              :       machopic_output_function_base_name (file);
   15317              :       break;
   15318              : #endif
   15319              : 
   15320              :     default:
   15321              :       return false;
   15322              :     }
   15323              : 
   15324              :   return true;
   15325              : }
   15326              : 
   15327              : 
   15328              : /* Output code to perform a 387 binary operation in INSN, one of PLUS,
   15329              :    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
   15330              :    is the expression of the binary operation.  The output may either be
   15331              :    emitted here, or returned to the caller, like all output_* functions.
   15332              : 
   15333              :    There is no guarantee that the operands are the same mode, as they
   15334              :    might be within FLOAT or FLOAT_EXTEND expressions.  */
   15335              : 
   15336              : #ifndef SYSV386_COMPAT
   15337              : /* Set to 1 for compatibility with brain-damaged assemblers.  No-one
   15338              :    wants to fix the assemblers because that causes incompatibility
   15339              :    with gcc.  No-one wants to fix gcc because that causes
   15340              :    incompatibility with assemblers...  You can use the option of
   15341              :    -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way.  */
   15342              : #define SYSV386_COMPAT 1
   15343              : #endif
   15344              : 
   15345              : const char *
   15346       610697 : output_387_binary_op (rtx_insn *insn, rtx *operands)
   15347              : {
   15348       610697 :   static char buf[40];
   15349       610697 :   const char *p;
   15350       610697 :   bool is_sse
   15351       610697 :     = (SSE_REG_P (operands[0])
   15352       666841 :        || SSE_REG_P (operands[1]) || SSE_REG_P (operands[2]));
   15353              : 
   15354        56144 :   if (is_sse)
   15355              :     p = "%v";
   15356        56144 :   else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
   15357        56137 :            || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
   15358              :     p = "fi";
   15359              :   else
   15360       610697 :     p = "f";
   15361              : 
   15362       610697 :   strcpy (buf, p);
   15363              : 
   15364       610697 :   switch (GET_CODE (operands[3]))
   15365              :     {
   15366              :     case PLUS:
   15367              :       p = "add"; break;
   15368              :     case MINUS:
   15369              :       p = "sub"; break;
   15370        95268 :     case MULT:
   15371        95268 :       p = "mul"; break;
   15372        28432 :     case DIV:
   15373        28432 :       p = "div"; break;
   15374            0 :     default:
   15375            0 :       gcc_unreachable ();
   15376              :     }
   15377              : 
   15378       610697 :   strcat (buf, p);
   15379              : 
   15380       610697 :   if (is_sse)
   15381              :    {
   15382       554553 :      p = GET_MODE (operands[0]) == SFmode ? "ss" : "sd";
   15383       554553 :      strcat (buf, p);
   15384              : 
   15385       554553 :      if (TARGET_AVX)
   15386              :        p = "\t{%2, %1, %0|%0, %1, %2}";
   15387              :      else
   15388       539177 :        p = "\t{%2, %0|%0, %2}";
   15389              : 
   15390       554553 :      strcat (buf, p);
   15391       554553 :      return buf;
   15392              :    }
   15393              : 
   15394              :   /* Even if we do not want to check the inputs, this documents input
   15395              :      constraints.  Which helps in understanding the following code.  */
   15396        56144 :   if (flag_checking)
   15397              :     {
   15398        56143 :       if (STACK_REG_P (operands[0])
   15399        56143 :           && ((REG_P (operands[1])
   15400        54476 :                && REGNO (operands[0]) == REGNO (operands[1])
   15401        50367 :                && (STACK_REG_P (operands[2]) || MEM_P (operands[2])))
   15402         5776 :               || (REG_P (operands[2])
   15403         5776 :                   && REGNO (operands[0]) == REGNO (operands[2])
   15404         5776 :                   && (STACK_REG_P (operands[1]) || MEM_P (operands[1]))))
   15405       112286 :           && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
   15406              :         ; /* ok */
   15407              :       else
   15408            0 :         gcc_unreachable ();
   15409              :     }
   15410              : 
   15411        56144 :   switch (GET_CODE (operands[3]))
   15412              :     {
   15413        41067 :     case MULT:
   15414        41067 :     case PLUS:
   15415        41067 :       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
   15416         2073 :         std::swap (operands[1], operands[2]);
   15417              : 
   15418              :       /* know operands[0] == operands[1].  */
   15419              : 
   15420        41067 :       if (MEM_P (operands[2]))
   15421              :         {
   15422              :           p = "%Z2\t%2";
   15423              :           break;
   15424              :         }
   15425              : 
   15426        36622 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   15427              :         {
   15428        21394 :           if (STACK_TOP_P (operands[0]))
   15429              :             /* How is it that we are storing to a dead operand[2]?
   15430              :                Well, presumably operands[1] is dead too.  We can't
   15431              :                store the result to st(0) as st(0) gets popped on this
   15432              :                instruction.  Instead store to operands[2] (which I
   15433              :                think has to be st(1)).  st(1) will be popped later.
   15434              :                gcc <= 2.8.1 didn't have this check and generated
   15435              :                assembly code that the Unixware assembler rejected.  */
   15436              :             p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
   15437              :           else
   15438              :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   15439              :           break;
   15440              :         }
   15441              : 
   15442        15228 :       if (STACK_TOP_P (operands[0]))
   15443              :         p = "\t{%y2, %0|%0, %y2}";    /* st(0) = st(0) op st(r2) */
   15444              :       else
   15445              :         p = "\t{%2, %0|%0, %2}";      /* st(r1) = st(r1) op st(0) */
   15446              :       break;
   15447              : 
   15448        15077 :     case MINUS:
   15449        15077 :     case DIV:
   15450        15077 :       if (MEM_P (operands[1]))
   15451              :         {
   15452              :           p = "r%Z1\t%1";
   15453              :           break;
   15454              :         }
   15455              : 
   15456        14614 :       if (MEM_P (operands[2]))
   15457              :         {
   15458              :           p = "%Z2\t%2";
   15459              :           break;
   15460              :         }
   15461              : 
   15462        13006 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
   15463              :         {
   15464              : #if SYSV386_COMPAT
   15465              :           /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
   15466              :              derived assemblers, confusingly reverse the direction of
   15467              :              the operation for fsub{r} and fdiv{r} when the
   15468              :              destination register is not st(0).  The Intel assembler
   15469              :              doesn't have this brain damage.  Read !SYSV386_COMPAT to
   15470              :              figure out what the hardware really does.  */
   15471         6260 :           if (STACK_TOP_P (operands[0]))
   15472              :             p = "{p\t%0, %2|rp\t%2, %0}";
   15473              :           else
   15474              :             p = "{rp\t%2, %0|p\t%0, %2}";
   15475              : #else
   15476              :           if (STACK_TOP_P (operands[0]))
   15477              :             /* As above for fmul/fadd, we can't store to st(0).  */
   15478              :             p = "rp\t{%0, %2|%2, %0}";        /* st(1) = st(0) op st(1); pop */
   15479              :           else
   15480              :             p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
   15481              : #endif
   15482              :           break;
   15483              :         }
   15484              : 
   15485         6746 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   15486              :         {
   15487              : #if SYSV386_COMPAT
   15488         3144 :           if (STACK_TOP_P (operands[0]))
   15489              :             p = "{rp\t%0, %1|p\t%1, %0}";
   15490              :           else
   15491              :             p = "{p\t%1, %0|rp\t%0, %1}";
   15492              : #else
   15493              :           if (STACK_TOP_P (operands[0]))
   15494              :             p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
   15495              :           else
   15496              :             p = "rp\t{%1, %0|%0, %1}";        /* st(r2) = st(0) op st(r2); pop */
   15497              : #endif
   15498              :           break;
   15499              :         }
   15500              : 
   15501         3602 :       if (STACK_TOP_P (operands[0]))
   15502              :         {
   15503         2719 :           if (STACK_TOP_P (operands[1]))
   15504              :             p = "\t{%y2, %0|%0, %y2}";        /* st(0) = st(0) op st(r2) */
   15505              :           else
   15506              :             p = "r\t{%y1, %0|%0, %y1}";       /* st(0) = st(r1) op st(0) */
   15507              :           break;
   15508              :         }
   15509          883 :       else if (STACK_TOP_P (operands[1]))
   15510              :         {
   15511              : #if SYSV386_COMPAT
   15512              :           p = "{\t%1, %0|r\t%0, %1}";
   15513              : #else
   15514              :           p = "r\t{%1, %0|%0, %1}";   /* st(r2) = st(0) op st(r2) */
   15515              : #endif
   15516              :         }
   15517              :       else
   15518              :         {
   15519              : #if SYSV386_COMPAT
   15520              :           p = "{r\t%2, %0|\t%0, %2}";
   15521              : #else
   15522              :           p = "\t{%2, %0|%0, %2}";    /* st(r1) = st(r1) op st(0) */
   15523              : #endif
   15524              :         }
   15525              :       break;
   15526              : 
   15527            0 :     default:
   15528            0 :       gcc_unreachable ();
   15529              :     }
   15530              : 
   15531        56144 :   strcat (buf, p);
   15532        56144 :   return buf;
   15533              : }
   15534              : 
   15535              : /* Return needed mode for entity in optimize_mode_switching pass.  */
   15536              : 
   15537              : static int
   15538         1656 : ix86_dirflag_mode_needed (rtx_insn *insn)
   15539              : {
   15540         1656 :   if (CALL_P (insn))
   15541              :     {
   15542          339 :       if (cfun->machine->func_type == TYPE_NORMAL)
   15543              :         return X86_DIRFLAG_ANY;
   15544              :       else
   15545              :         /* No need to emit CLD in interrupt handler for TARGET_CLD.  */
   15546          339 :         return TARGET_CLD ? X86_DIRFLAG_ANY : X86_DIRFLAG_RESET;
   15547              :     }
   15548              : 
   15549         1317 :   if (recog_memoized (insn) < 0)
   15550              :     return X86_DIRFLAG_ANY;
   15551              : 
   15552         1315 :   if (get_attr_type (insn) == TYPE_STR)
   15553              :     {
   15554              :       /* Emit cld instruction if stringops are used in the function.  */
   15555            1 :       if (cfun->machine->func_type == TYPE_NORMAL)
   15556            0 :         return TARGET_CLD ? X86_DIRFLAG_RESET : X86_DIRFLAG_ANY;
   15557              :       else
   15558              :         return X86_DIRFLAG_RESET;
   15559              :     }
   15560              : 
   15561              :   return X86_DIRFLAG_ANY;
   15562              : }
   15563              : 
   15564              : /* Check if a 256bit or 512 bit AVX register is referenced inside of EXP.   */
   15565              : 
   15566              : static bool
   15567      2238254 : ix86_check_avx_upper_register (const_rtx exp)
   15568              : {
   15569              :   /* construct_container may return a parallel with expr_list
   15570              :      which contains the real reg and mode  */
   15571      2238254 :   subrtx_iterator::array_type array;
   15572      8559360 :   FOR_EACH_SUBRTX (iter, array, exp, NONCONST)
   15573              :     {
   15574      6484516 :       const_rtx x = *iter;
   15575      2608670 :       if (SSE_REG_P (x)
   15576       840132 :           && !EXT_REX_SSE_REG_P (x)
   15577      8151936 :           && GET_MODE_BITSIZE (GET_MODE (x)) > 128)
   15578       163410 :         return true;
   15579              :     }
   15580              : 
   15581      2074844 :   return false;
   15582      2238254 : }
   15583              : 
   15584              : /* Check if a 256bit or 512bit AVX register is referenced in stores.   */
   15585              : 
   15586              : static void
   15587        51451 : ix86_check_avx_upper_stores (rtx dest, const_rtx, void *data)
   15588              : {
   15589        51451 :   if (SSE_REG_P (dest)
   15590        12721 :       && !EXT_REX_SSE_REG_P (dest)
   15591        76893 :       && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
   15592              :     {
   15593          754 :       bool *used = (bool *) data;
   15594          754 :       *used = true;
   15595              :     }
   15596        51451 : }
   15597              : 
   15598              : /* Return needed mode for entity in optimize_mode_switching pass.  */
   15599              : 
   15600              : static int
   15601      2085343 : ix86_avx_u128_mode_needed (rtx_insn *insn)
   15602              : {
   15603      2085343 :   if (DEBUG_INSN_P (insn))
   15604              :     return AVX_U128_ANY;
   15605              : 
   15606      2085343 :   if (CALL_P (insn))
   15607              :     {
   15608        49860 :       rtx link;
   15609              : 
   15610              :       /* Needed mode is set to AVX_U128_CLEAN if there are
   15611              :          no 256bit or 512bit modes used in function arguments. */
   15612        49860 :       for (link = CALL_INSN_FUNCTION_USAGE (insn);
   15613       136560 :            link;
   15614        86700 :            link = XEXP (link, 1))
   15615              :         {
   15616        87746 :           if (GET_CODE (XEXP (link, 0)) == USE)
   15617              :             {
   15618        86407 :               rtx arg = XEXP (XEXP (link, 0), 0);
   15619              : 
   15620        86407 :               if (ix86_check_avx_upper_register (arg))
   15621              :                 return AVX_U128_DIRTY;
   15622              :             }
   15623              :         }
   15624              : 
   15625              :       /* Needed mode is set to AVX_U128_CLEAN if there are no 256bit
   15626              :          nor 512bit registers used in the function return register.  */
   15627        48814 :       bool avx_upper_reg_found = false;
   15628        48814 :       note_stores (insn, ix86_check_avx_upper_stores,
   15629              :                    &avx_upper_reg_found);
   15630        48814 :       if (avx_upper_reg_found)
   15631              :         return AVX_U128_DIRTY;
   15632              : 
   15633              :       /* If the function is known to preserve some SSE registers,
   15634              :          RA and previous passes can legitimately rely on that for
   15635              :          modes wider than 256 bits.  It's only safe to issue a
   15636              :          vzeroupper if all SSE registers are clobbered.  */
   15637        48630 :       const function_abi &abi = insn_callee_abi (insn);
   15638        48630 :       if (vzeroupper_pattern (PATTERN (insn), VOIDmode)
   15639              :           /* Should be safe to issue an vzeroupper before sibling_call_p.
   15640              :              Also there not mode_exit for sibling_call, so there could be
   15641              :              missing vzeroupper for that.  */
   15642        48630 :           || !(SIBLING_CALL_P (insn)
   15643        47342 :                || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15644        55776 :                                          abi.mode_clobbers (V4DImode))))
   15645              :         return AVX_U128_ANY;
   15646              : 
   15647        40196 :       return AVX_U128_CLEAN;
   15648              :     }
   15649              : 
   15650      2035483 :   rtx set = single_set (insn);
   15651      2035483 :   if (set)
   15652              :     {
   15653      1961314 :       rtx dest = SET_DEST (set);
   15654      1961314 :       rtx src = SET_SRC (set);
   15655      1476597 :       if (SSE_REG_P (dest)
   15656       554735 :           && !EXT_REX_SSE_REG_P (dest)
   15657      3058646 :           && GET_MODE_BITSIZE (GET_MODE (dest)) > 128)
   15658              :         {
   15659              :           /* This is an YMM/ZMM load.  Return AVX_U128_DIRTY if the
   15660              :              source isn't zero.  */
   15661       169226 :           if (standard_sse_constant_p (src, GET_MODE (dest)) != 1)
   15662              :             return AVX_U128_DIRTY;
   15663              :           else
   15664         3006 :             return AVX_U128_ANY;
   15665              :         }
   15666              :       else
   15667              :         {
   15668      1792088 :           if (ix86_check_avx_upper_register (src))
   15669              :             return AVX_U128_DIRTY;
   15670              :         }
   15671              : 
   15672              :       /* This isn't YMM/ZMM load/store.  */
   15673      1715494 :       return AVX_U128_ANY;
   15674              :     }
   15675              : 
   15676              :   /* Require DIRTY mode if a 256bit or 512bit AVX register is referenced.
   15677              :      Hardware changes state only when a 256bit register is written to,
   15678              :      but we need to prevent the compiler from moving optimal insertion
   15679              :      point above eventual read from 256bit or 512 bit register.  */
   15680        74169 :   if (ix86_check_avx_upper_register (PATTERN (insn)))
   15681        25390 :     return AVX_U128_DIRTY;
   15682              : 
   15683              :   return AVX_U128_ANY;
   15684              : }
   15685              : 
   15686              : /* Return mode that i387 must be switched into
   15687              :    prior to the execution of insn.  */
   15688              : 
   15689              : static int
   15690       423239 : ix86_i387_mode_needed (int entity, rtx_insn *insn)
   15691              : {
   15692       423239 :   enum attr_i387_cw mode;
   15693              : 
   15694              :   /* The mode UNINITIALIZED is used to store control word after a
   15695              :      function call or ASM pattern.  The mode ANY specify that function
   15696              :      has no requirements on the control word and make no changes in the
   15697              :      bits we are interested in.  */
   15698              : 
   15699       423239 :   if (CALL_P (insn)
   15700       423239 :       || (NONJUMP_INSN_P (insn)
   15701       346987 :           && (asm_noperands (PATTERN (insn)) >= 0
   15702       346934 :               || GET_CODE (PATTERN (insn)) == ASM_INPUT)))
   15703              :     return I387_CW_UNINITIALIZED;
   15704              : 
   15705       408189 :   if (recog_memoized (insn) < 0)
   15706              :     return I387_CW_ANY;
   15707              : 
   15708       407247 :   mode = get_attr_i387_cw (insn);
   15709              : 
   15710       407247 :   switch (entity)
   15711              :     {
   15712            0 :     case I387_ROUNDEVEN:
   15713            0 :       if (mode == I387_CW_ROUNDEVEN)
   15714            0 :         return mode;
   15715              :       break;
   15716              : 
   15717       402584 :     case I387_TRUNC:
   15718       402584 :       if (mode == I387_CW_TRUNC)
   15719         7377 :         return mode;
   15720              :       break;
   15721              : 
   15722         3628 :     case I387_FLOOR:
   15723         3628 :       if (mode == I387_CW_FLOOR)
   15724          139 :         return mode;
   15725              :       break;
   15726              : 
   15727         1035 :     case I387_CEIL:
   15728         1035 :       if (mode == I387_CW_CEIL)
   15729           61 :         return mode;
   15730              :       break;
   15731              : 
   15732            0 :     default:
   15733            0 :       gcc_unreachable ();
   15734              :     }
   15735              : 
   15736              :   return I387_CW_ANY;
   15737              : }
   15738              : 
   15739              : /* Return mode that entity must be switched into
   15740              :    prior to the execution of insn.  */
   15741              : 
   15742              : static int
   15743      2510238 : ix86_mode_needed (int entity, rtx_insn *insn, HARD_REG_SET)
   15744              : {
   15745      2510238 :   switch (entity)
   15746              :     {
   15747         1656 :     case X86_DIRFLAG:
   15748         1656 :       return ix86_dirflag_mode_needed (insn);
   15749      2085343 :     case AVX_U128:
   15750      2085343 :       return ix86_avx_u128_mode_needed (insn);
   15751       423239 :     case I387_ROUNDEVEN:
   15752       423239 :     case I387_TRUNC:
   15753       423239 :     case I387_FLOOR:
   15754       423239 :     case I387_CEIL:
   15755       423239 :       return ix86_i387_mode_needed (entity, insn);
   15756            0 :     default:
   15757            0 :       gcc_unreachable ();
   15758              :     }
   15759              :   return 0;
   15760              : }
   15761              : 
   15762              : /* Calculate mode of upper 128bit AVX registers after the insn.  */
   15763              : 
   15764              : static int
   15765      2085343 : ix86_avx_u128_mode_after (int mode, rtx_insn *insn)
   15766              : {
   15767      2085343 :   rtx pat = PATTERN (insn);
   15768              : 
   15769      2085343 :   if (vzeroupper_pattern (pat, VOIDmode)
   15770      2085343 :       || vzeroall_pattern (pat, VOIDmode))
   15771              :     return AVX_U128_CLEAN;
   15772              : 
   15773              :   /* We know that state is clean after CALL insn if there are no
   15774              :      256bit or 512bit registers used in the function return register. */
   15775      2085184 :   if (CALL_P (insn))
   15776              :     {
   15777        49814 :       bool avx_upper_reg_found = false;
   15778        49814 :       note_stores (insn, ix86_check_avx_upper_stores, &avx_upper_reg_found);
   15779              : 
   15780        49814 :       if (avx_upper_reg_found)
   15781              :         return AVX_U128_DIRTY;
   15782              : 
   15783              :       /* If the function doesn't clobber any sse registers or only clobber
   15784              :          128-bit part, Then vzeroupper isn't issued before the function exit.
   15785              :          the status not CLEAN but ANY after the function.  */
   15786        49244 :       const function_abi &abi = insn_callee_abi (insn);
   15787        49244 :       if (!(SIBLING_CALL_P (insn)
   15788        47961 :             || hard_reg_set_subset_p (reg_class_contents[SSE_REGS],
   15789        47961 :                                       abi.mode_clobbers (V4DImode))))
   15790         8730 :         return AVX_U128_ANY;
   15791              : 
   15792        40514 :       return  AVX_U128_CLEAN;
   15793              :     }
   15794              : 
   15795              :   /* Otherwise, return current mode.  Remember that if insn
   15796              :      references AVX 256bit or 512bit registers, the mode was already
   15797              :      changed to DIRTY from MODE_NEEDED.  */
   15798              :   return mode;
   15799              : }
   15800              : 
   15801              : /* Return the mode that an insn results in.  */
   15802              : 
   15803              : static int
   15804      2509393 : ix86_mode_after (int entity, int mode, rtx_insn *insn, HARD_REG_SET)
   15805              : {
   15806      2509393 :   switch (entity)
   15807              :     {
   15808              :     case X86_DIRFLAG:
   15809              :       return mode;
   15810      2085343 :     case AVX_U128:
   15811      2085343 :       return ix86_avx_u128_mode_after (mode, insn);
   15812              :     case I387_ROUNDEVEN:
   15813              :     case I387_TRUNC:
   15814              :     case I387_FLOOR:
   15815              :     case I387_CEIL:
   15816              :       return mode;
   15817            0 :     default:
   15818            0 :       gcc_unreachable ();
   15819              :     }
   15820              : }
   15821              : 
   15822              : static int
   15823          120 : ix86_dirflag_mode_entry (void)
   15824              : {
   15825              :   /* For TARGET_CLD or in the interrupt handler we can't assume
   15826              :      direction flag state at function entry.  */
   15827          120 :   if (TARGET_CLD
   15828          118 :       || cfun->machine->func_type != TYPE_NORMAL)
   15829          120 :     return X86_DIRFLAG_ANY;
   15830              : 
   15831              :   return X86_DIRFLAG_RESET;
   15832              : }
   15833              : 
   15834              : static int
   15835       125656 : ix86_avx_u128_mode_entry (void)
   15836              : {
   15837       125656 :   tree arg;
   15838              : 
   15839              :   /* Entry mode is set to AVX_U128_DIRTY if there are
   15840              :      256bit or 512bit modes used in function arguments.  */
   15841       316818 :   for (arg = DECL_ARGUMENTS (current_function_decl); arg;
   15842       191162 :        arg = TREE_CHAIN (arg))
   15843              :     {
   15844       226339 :       rtx incoming = DECL_INCOMING_RTL (arg);
   15845              : 
   15846       226339 :       if (incoming && ix86_check_avx_upper_register (incoming))
   15847              :         return AVX_U128_DIRTY;
   15848              :     }
   15849              : 
   15850              :   return AVX_U128_CLEAN;
   15851              : }
   15852              : 
   15853              : /* Return a mode that ENTITY is assumed to be
   15854              :    switched to at function entry.  */
   15855              : 
   15856              : static int
   15857        77322 : ix86_mode_entry (int entity)
   15858              : {
   15859        77322 :   switch (entity)
   15860              :     {
   15861          120 :     case X86_DIRFLAG:
   15862          120 :       return ix86_dirflag_mode_entry ();
   15863        76055 :     case AVX_U128:
   15864        76055 :       return ix86_avx_u128_mode_entry ();
   15865              :     case I387_ROUNDEVEN:
   15866              :     case I387_TRUNC:
   15867              :     case I387_FLOOR:
   15868              :     case I387_CEIL:
   15869              :       return I387_CW_ANY;
   15870            0 :     default:
   15871            0 :       gcc_unreachable ();
   15872              :     }
   15873              : }
   15874              : 
   15875              : static int
   15876        74804 : ix86_avx_u128_mode_exit (void)
   15877              : {
   15878        74804 :   rtx reg = crtl->return_rtx;
   15879              : 
   15880              :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit
   15881              :      or 512 bit modes used in the function return register. */
   15882        74804 :   if (reg && ix86_check_avx_upper_register (reg))
   15883              :     return AVX_U128_DIRTY;
   15884              : 
   15885              :   /* Exit mode is set to AVX_U128_DIRTY if there are 256bit or 512bit
   15886              :      modes used in function arguments, otherwise return AVX_U128_CLEAN.
   15887              :    */
   15888        49601 :   return ix86_avx_u128_mode_entry ();
   15889              : }
   15890              : 
   15891              : /* Return a mode that ENTITY is assumed to be
   15892              :    switched to at function exit.  */
   15893              : 
   15894              : static int
   15895        75926 : ix86_mode_exit (int entity)
   15896              : {
   15897        75926 :   switch (entity)
   15898              :     {
   15899              :     case X86_DIRFLAG:
   15900              :       return X86_DIRFLAG_ANY;
   15901        74804 :     case AVX_U128:
   15902        74804 :       return ix86_avx_u128_mode_exit ();
   15903         1088 :     case I387_ROUNDEVEN:
   15904         1088 :     case I387_TRUNC:
   15905         1088 :     case I387_FLOOR:
   15906         1088 :     case I387_CEIL:
   15907         1088 :       return I387_CW_ANY;
   15908            0 :     default:
   15909            0 :       gcc_unreachable ();
   15910              :     }
   15911              : }
   15912              : 
   15913              : static int
   15914      2184781 : ix86_mode_priority (int, int n)
   15915              : {
   15916      2184781 :   return n;
   15917              : }
   15918              : 
   15919              : /* Output code to initialize control word copies used by trunc?f?i and
   15920              :    rounding patterns.  CURRENT_MODE is set to current control word,
   15921              :    while NEW_MODE is set to new control word.  */
   15922              : 
   15923              : static void
   15924         3320 : emit_i387_cw_initialization (int mode)
   15925              : {
   15926         3320 :   rtx stored_mode = assign_386_stack_local (HImode, SLOT_CW_STORED);
   15927         3320 :   rtx new_mode;
   15928              : 
   15929         3320 :   enum ix86_stack_slot slot;
   15930              : 
   15931         3320 :   rtx reg = gen_reg_rtx (HImode);
   15932              : 
   15933         3320 :   emit_insn (gen_x86_fnstcw_1 (stored_mode));
   15934         3320 :   emit_move_insn (reg, copy_rtx (stored_mode));
   15935              : 
   15936         3320 :   switch (mode)
   15937              :     {
   15938            0 :     case I387_CW_ROUNDEVEN:
   15939              :       /* round to nearest */
   15940            0 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15941            0 :       slot = SLOT_CW_ROUNDEVEN;
   15942            0 :       break;
   15943              : 
   15944         3124 :     case I387_CW_TRUNC:
   15945              :       /* round toward zero (truncate) */
   15946         3124 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
   15947         3124 :       slot = SLOT_CW_TRUNC;
   15948         3124 :       break;
   15949              : 
   15950          137 :     case I387_CW_FLOOR:
   15951              :       /* round down toward -oo */
   15952          137 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15953          137 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
   15954          137 :       slot = SLOT_CW_FLOOR;
   15955          137 :       break;
   15956              : 
   15957           59 :     case I387_CW_CEIL:
   15958              :       /* round up toward +oo */
   15959           59 :       emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
   15960           59 :       emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
   15961           59 :       slot = SLOT_CW_CEIL;
   15962           59 :       break;
   15963              : 
   15964            0 :     default:
   15965            0 :       gcc_unreachable ();
   15966              :     }
   15967              : 
   15968         3320 :   gcc_assert (slot < MAX_386_STACK_LOCALS);
   15969              : 
   15970         3320 :   new_mode = assign_386_stack_local (HImode, slot);
   15971         3320 :   emit_move_insn (new_mode, reg);
   15972         3320 : }
   15973              : 
   15974              : /* Generate one or more insns to set ENTITY to MODE.  */
   15975              : 
   15976              : static void
   15977        52441 : ix86_emit_mode_set (int entity, int mode, int prev_mode ATTRIBUTE_UNUSED,
   15978              :                     HARD_REG_SET regs_live ATTRIBUTE_UNUSED)
   15979              : {
   15980        52441 :   switch (entity)
   15981              :     {
   15982          265 :     case X86_DIRFLAG:
   15983          265 :       if (mode == X86_DIRFLAG_RESET)
   15984          265 :         emit_insn (gen_cld ());
   15985              :       break;
   15986        43876 :     case AVX_U128:
   15987        43876 :       if (mode == AVX_U128_CLEAN)
   15988        22323 :         ix86_expand_avx_vzeroupper ();
   15989              :       break;
   15990         8300 :     case I387_ROUNDEVEN:
   15991         8300 :     case I387_TRUNC:
   15992         8300 :     case I387_FLOOR:
   15993         8300 :     case I387_CEIL:
   15994         8300 :       if (mode != I387_CW_ANY
   15995         8300 :           && mode != I387_CW_UNINITIALIZED)
   15996         3320 :         emit_i387_cw_initialization (mode);
   15997              :       break;
   15998            0 :     default:
   15999            0 :       gcc_unreachable ();
   16000              :     }
   16001        52441 : }
   16002              : 
   16003              : /* Output code for INSN to convert a float to a signed int.  OPERANDS
   16004              :    are the insn operands.  The output may be [HSD]Imode and the input
   16005              :    operand may be [SDX]Fmode.  */
   16006              : 
   16007              : const char *
   16008         7465 : output_fix_trunc (rtx_insn *insn, rtx *operands, bool fisttp)
   16009              : {
   16010         7465 :   bool stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   16011         7465 :   bool dimode_p = GET_MODE (operands[0]) == DImode;
   16012         7465 :   int round_mode = get_attr_i387_cw (insn);
   16013              : 
   16014         7465 :   static char buf[40];
   16015         7465 :   const char *p;
   16016              : 
   16017              :   /* Jump through a hoop or two for DImode, since the hardware has no
   16018              :      non-popping instruction.  We used to do this a different way, but
   16019              :      that was somewhat fragile and broke with post-reload splitters.  */
   16020         7465 :   if ((dimode_p || fisttp) && !stack_top_dies)
   16021           25 :     output_asm_insn ("fld\t%y1", operands);
   16022              : 
   16023         7465 :   gcc_assert (STACK_TOP_P (operands[1]));
   16024         7465 :   gcc_assert (MEM_P (operands[0]));
   16025         7465 :   gcc_assert (GET_MODE (operands[1]) != TFmode);
   16026              : 
   16027         7465 :   if (fisttp)
   16028              :     return "fisttp%Z0\t%0";
   16029              : 
   16030         7464 :   strcpy (buf, "fist");
   16031              : 
   16032         7464 :   if (round_mode != I387_CW_ANY)
   16033         7420 :     output_asm_insn ("fldcw\t%3", operands);
   16034              : 
   16035         7464 :   p = "p%Z0\t%0";
   16036         7464 :   strcat (buf, p + !(stack_top_dies || dimode_p));
   16037              : 
   16038         7464 :   output_asm_insn (buf, operands);
   16039              : 
   16040         7464 :   if (round_mode != I387_CW_ANY)
   16041         7420 :     output_asm_insn ("fldcw\t%2", operands);
   16042              : 
   16043              :   return "";
   16044              : }
   16045              : 
   16046              : /* Output code for x87 ffreep insn.  The OPNO argument, which may only
   16047              :    have the values zero or one, indicates the ffreep insn's operand
   16048              :    from the OPERANDS array.  */
   16049              : 
   16050              : static const char *
   16051       274718 : output_387_ffreep (rtx *operands ATTRIBUTE_UNUSED, int opno)
   16052              : {
   16053            0 :   if (TARGET_USE_FFREEP)
   16054              : #ifdef HAVE_AS_IX86_FFREEP
   16055            0 :     return opno ? "ffreep\t%y1" : "ffreep\t%y0";
   16056              : #else
   16057              :     {
   16058              :       static char retval[32];
   16059              :       int regno = REGNO (operands[opno]);
   16060              : 
   16061              :       gcc_assert (STACK_REGNO_P (regno));
   16062              : 
   16063              :       regno -= FIRST_STACK_REG;
   16064              : 
   16065              :       snprintf (retval, sizeof (retval), ASM_SHORT "0xc%ddf", regno);
   16066              :       return retval;
   16067              :     }
   16068              : #endif
   16069              : 
   16070            0 :   return opno ? "fstp\t%y1" : "fstp\t%y0";
   16071              : }
   16072              : 
   16073              : 
   16074              : /* Output code for INSN to compare OPERANDS.  EFLAGS_P is 1 when fcomi
   16075              :    should be used.  UNORDERED_P is true when fucom should be used.  */
   16076              : 
   16077              : const char *
   16078       108254 : output_fp_compare (rtx_insn *insn, rtx *operands,
   16079              :                    bool eflags_p, bool unordered_p)
   16080              : {
   16081       108254 :   rtx *xops = eflags_p ? &operands[0] : &operands[1];
   16082       108254 :   bool stack_top_dies;
   16083              : 
   16084       108254 :   static char buf[40];
   16085       108254 :   const char *p;
   16086              : 
   16087       108254 :   gcc_assert (STACK_TOP_P (xops[0]));
   16088              : 
   16089       108254 :   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG);
   16090              : 
   16091       108254 :   if (eflags_p)
   16092              :     {
   16093       108254 :       p = unordered_p ? "fucomi" : "fcomi";
   16094       108254 :       strcpy (buf, p);
   16095              : 
   16096       108254 :       p = "p\t{%y1, %0|%0, %y1}";
   16097       108254 :       strcat (buf, p + !stack_top_dies);
   16098              : 
   16099       108254 :       return buf;
   16100              :     }
   16101              : 
   16102            0 :   if (STACK_REG_P (xops[1])
   16103            0 :       && stack_top_dies
   16104            0 :       && find_regno_note (insn, REG_DEAD, FIRST_STACK_REG + 1))
   16105              :     {
   16106            0 :       gcc_assert (REGNO (xops[1]) == FIRST_STACK_REG + 1);
   16107              : 
   16108              :       /* If both the top of the 387 stack die, and the other operand
   16109              :          is also a stack register that dies, then this must be a
   16110              :          `fcompp' float compare.  */
   16111            0 :       p = unordered_p ? "fucompp" : "fcompp";
   16112            0 :       strcpy (buf, p);
   16113              :     }
   16114            0 :   else if (const0_operand (xops[1], VOIDmode))
   16115              :     {
   16116            0 :       gcc_assert (!unordered_p);
   16117            0 :       strcpy (buf, "ftst");
   16118              :     }
   16119              :   else
   16120              :     {
   16121            0 :       if (GET_MODE_CLASS (GET_MODE (xops[1])) == MODE_INT)
   16122              :         {
   16123            0 :           gcc_assert (!unordered_p);
   16124              :           p = "ficom";
   16125              :         }
   16126              :       else
   16127            0 :         p = unordered_p ? "fucom" : "fcom";
   16128              : 
   16129            0 :       strcpy (buf, p);
   16130              : 
   16131            0 :       p = "p%Z2\t%y2";
   16132            0 :       strcat (buf, p + !stack_top_dies);
   16133              :     }
   16134              : 
   16135            0 :   output_asm_insn (buf, operands);
   16136            0 :   return "fnstsw\t%0";
   16137              : }
   16138              : 
   16139              : void
   16140       140037 : ix86_output_addr_vec_elt (FILE *file, int value)
   16141              : {
   16142       140037 :   const char *directive = ASM_LONG;
   16143              : 
   16144              : #ifdef ASM_QUAD
   16145       140037 :   if (TARGET_LP64)
   16146       128305 :     directive = ASM_QUAD;
   16147              : #else
   16148              :   gcc_assert (!TARGET_64BIT);
   16149              : #endif
   16150              : 
   16151       140037 :   fprintf (file, "%s%s%d\n", directive, LPREFIX, value);
   16152       140037 : }
   16153              : 
   16154              : void
   16155        27471 : ix86_output_addr_diff_elt (FILE *file, int value, int rel)
   16156              : {
   16157        27471 :   const char *directive = ASM_LONG;
   16158              : 
   16159              : #ifdef ASM_QUAD
   16160        41129 :   if (TARGET_64BIT && CASE_VECTOR_MODE == DImode)
   16161              :     directive = ASM_QUAD;
   16162              : #else
   16163              :   gcc_assert (!TARGET_64BIT);
   16164              : #endif
   16165              :   /* We can't use @GOTOFF for text labels on VxWorks; see gotoff_operand.  */
   16166        27471 :   if (TARGET_64BIT || TARGET_VXWORKS_VAROFF)
   16167        13658 :     fprintf (file, "%s%s%d-%s%d\n",
   16168              :              directive, LPREFIX, value, LPREFIX, rel);
   16169              : #if TARGET_MACHO
   16170              :   else if (TARGET_MACHO)
   16171              :     {
   16172              :       fprintf (file, ASM_LONG "%s%d-", LPREFIX, value);
   16173              :       machopic_output_function_base_name (file);
   16174              :       putc ('\n', file);
   16175              :     }
   16176              : #endif
   16177        13813 :   else if (HAVE_AS_GOTOFF_IN_DATA)
   16178        13813 :     fprintf (file, ASM_LONG "%s%d@GOTOFF\n", LPREFIX, value);
   16179              :   else
   16180              :     asm_fprintf (file, ASM_LONG "%U%s+[.-%s%d]\n",
   16181              :                  GOT_SYMBOL_NAME, LPREFIX, value);
   16182        27471 : }
   16183              : 
   16184              : #define LEA_MAX_STALL (3)
   16185              : #define LEA_SEARCH_THRESHOLD (LEA_MAX_STALL << 1)
   16186              : 
   16187              : /* Increase given DISTANCE in half-cycles according to
   16188              :    dependencies between PREV and NEXT instructions.
   16189              :    Add 1 half-cycle if there is no dependency and
   16190              :    go to next cycle if there is some dependency.  */
   16191              : 
   16192              : static unsigned int
   16193         2115 : increase_distance (rtx_insn *prev, rtx_insn *next, unsigned int distance)
   16194              : {
   16195         2115 :   df_ref def, use;
   16196              : 
   16197         2115 :   if (!prev || !next)
   16198          758 :     return distance + (distance & 1) + 2;
   16199              : 
   16200         1357 :   if (!DF_INSN_USES (next) || !DF_INSN_DEFS (prev))
   16201          228 :     return distance + 1;
   16202              : 
   16203         1855 :   FOR_EACH_INSN_USE (use, next)
   16204         2343 :     FOR_EACH_INSN_DEF (def, prev)
   16205         1617 :       if (!DF_REF_IS_ARTIFICIAL (def)
   16206         1617 :           && DF_REF_REGNO (use) == DF_REF_REGNO (def))
   16207          721 :         return distance + (distance & 1) + 2;
   16208              : 
   16209          408 :   return distance + 1;
   16210              : }
   16211              : 
   16212              : /* Function checks if instruction INSN defines register number
   16213              :    REGNO1 or REGNO2.  */
   16214              : 
   16215              : bool
   16216         2063 : insn_defines_reg (unsigned int regno1, unsigned int regno2,
   16217              :                   rtx_insn *insn)
   16218              : {
   16219         2063 :   df_ref def;
   16220              : 
   16221         3739 :   FOR_EACH_INSN_DEF (def, insn)
   16222         2076 :     if (DF_REF_REG_DEF_P (def)
   16223         2076 :         && !DF_REF_IS_ARTIFICIAL (def)
   16224         2076 :         && (regno1 == DF_REF_REGNO (def)
   16225         1693 :             || regno2 == DF_REF_REGNO (def)))
   16226              :       return true;
   16227              : 
   16228              :   return false;
   16229              : }
   16230              : 
   16231              : /* Function checks if instruction INSN uses register number
   16232              :    REGNO as a part of address expression.  */
   16233              : 
   16234              : static bool
   16235         1176 : insn_uses_reg_mem (unsigned int regno, rtx insn)
   16236              : {
   16237         1176 :   df_ref use;
   16238              : 
   16239         2445 :   FOR_EACH_INSN_USE (use, insn)
   16240         1356 :     if (DF_REF_REG_MEM_P (use) && regno == DF_REF_REGNO (use))
   16241              :       return true;
   16242              : 
   16243              :   return false;
   16244              : }
   16245              : 
   16246              : /* Search backward for non-agu definition of register number REGNO1
   16247              :    or register number REGNO2 in basic block starting from instruction
   16248              :    START up to head of basic block or instruction INSN.
   16249              : 
   16250              :    Function puts true value into *FOUND var if definition was found
   16251              :    and false otherwise.
   16252              : 
   16253              :    Distance in half-cycles between START and found instruction or head
   16254              :    of BB is added to DISTANCE and returned.  */
   16255              : 
   16256              : static int
   16257          625 : distance_non_agu_define_in_bb (unsigned int regno1, unsigned int regno2,
   16258              :                                rtx_insn *insn, int distance,
   16259              :                                rtx_insn *start, bool *found)
   16260              : {
   16261          625 :   basic_block bb = start ? BLOCK_FOR_INSN (start) : NULL;
   16262          625 :   rtx_insn *prev = start;
   16263          625 :   rtx_insn *next = NULL;
   16264              : 
   16265          625 :   *found = false;
   16266              : 
   16267          625 :   while (prev
   16268         1861 :          && prev != insn
   16269         1861 :          && distance < LEA_SEARCH_THRESHOLD)
   16270              :     {
   16271         1660 :       if (NONDEBUG_INSN_P (prev) && NONJUMP_INSN_P (prev))
   16272              :         {
   16273          939 :           distance = increase_distance (prev, next, distance);
   16274          939 :           if (insn_defines_reg (regno1, regno2, prev))
   16275              :             {
   16276          238 :               if (recog_memoized (prev) < 0
   16277          238 :                   || get_attr_type (prev) != TYPE_LEA)
   16278              :                 {
   16279          202 :                   *found = true;
   16280          202 :                   return distance;
   16281              :                 }
   16282              :             }
   16283              : 
   16284              :           next = prev;
   16285              :         }
   16286         1458 :       if (prev == BB_HEAD (bb))
   16287              :         break;
   16288              : 
   16289         1236 :       prev = PREV_INSN (prev);
   16290              :     }
   16291              : 
   16292              :   return distance;
   16293              : }
   16294              : 
   16295              : /* Search backward for non-agu definition of register number REGNO1
   16296              :    or register number REGNO2 in INSN's basic block until
   16297              :    1. Pass LEA_SEARCH_THRESHOLD instructions, or
   16298              :    2. Reach neighbor BBs boundary, or
   16299              :    3. Reach agu definition.
   16300              :    Returns the distance between the non-agu definition point and INSN.
   16301              :    If no definition point, returns -1.  */
   16302              : 
   16303              : static int
   16304          428 : distance_non_agu_define (unsigned int regno1, unsigned int regno2,
   16305              :                          rtx_insn *insn)
   16306              : {
   16307          428 :   basic_block bb = BLOCK_FOR_INSN (insn);
   16308          428 :   int distance = 0;
   16309          428 :   bool found = false;
   16310              : 
   16311          428 :   if (insn != BB_HEAD (bb))
   16312          428 :     distance = distance_non_agu_define_in_bb (regno1, regno2, insn,
   16313              :                                               distance, PREV_INSN (insn),
   16314              :                                               &found);
   16315              : 
   16316          428 :   if (!found && distance < LEA_SEARCH_THRESHOLD)
   16317              :     {
   16318          166 :       edge e;
   16319          166 :       edge_iterator ei;
   16320          166 :       bool simple_loop = false;
   16321              : 
   16322          337 :       FOR_EACH_EDGE (e, ei, bb->preds)
   16323          208 :         if (e->src == bb)
   16324              :           {
   16325              :             simple_loop = true;
   16326              :             break;
   16327              :           }
   16328              : 
   16329          166 :       if (simple_loop)
   16330           37 :         distance = distance_non_agu_define_in_bb (regno1, regno2,
   16331              :                                                   insn, distance,
   16332           37 :                                                   BB_END (bb), &found);
   16333              :       else
   16334              :         {
   16335          129 :           int shortest_dist = -1;
   16336          129 :           bool found_in_bb = false;
   16337              : 
   16338          289 :           FOR_EACH_EDGE (e, ei, bb->preds)
   16339              :             {
   16340          160 :               int bb_dist
   16341          320 :                 = distance_non_agu_define_in_bb (regno1, regno2,
   16342              :                                                  insn, distance,
   16343          160 :                                                  BB_END (e->src),
   16344              :                                                  &found_in_bb);
   16345          160 :               if (found_in_bb)
   16346              :                 {
   16347           24 :                   if (shortest_dist < 0)
   16348              :                     shortest_dist = bb_dist;
   16349            0 :                   else if (bb_dist > 0)
   16350            0 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   16351              : 
   16352           24 :                   found = true;
   16353              :                 }
   16354              :             }
   16355              : 
   16356          129 :           distance = shortest_dist;
   16357              :         }
   16358              :     }
   16359              : 
   16360          428 :   if (!found)
   16361              :     return -1;
   16362              : 
   16363          202 :   return distance >> 1;
   16364              : }
   16365              : 
   16366              : /* Return the distance in half-cycles between INSN and the next
   16367              :    insn that uses register number REGNO in memory address added
   16368              :    to DISTANCE.  Return -1 if REGNO0 is set.
   16369              : 
   16370              :    Put true value into *FOUND if register usage was found and
   16371              :    false otherwise.
   16372              :    Put true value into *REDEFINED if register redefinition was
   16373              :    found and false otherwise.  */
   16374              : 
   16375              : static int
   16376          770 : distance_agu_use_in_bb (unsigned int regno,
   16377              :                         rtx_insn *insn, int distance, rtx_insn *start,
   16378              :                         bool *found, bool *redefined)
   16379              : {
   16380          770 :   basic_block bb = NULL;
   16381          770 :   rtx_insn *next = start;
   16382          770 :   rtx_insn *prev = NULL;
   16383              : 
   16384          770 :   *found = false;
   16385          770 :   *redefined = false;
   16386              : 
   16387          770 :   if (start != NULL_RTX)
   16388              :     {
   16389          753 :       bb = BLOCK_FOR_INSN (start);
   16390          753 :       if (start != BB_HEAD (bb))
   16391              :         /* If insn and start belong to the same bb, set prev to insn,
   16392              :            so the call to increase_distance will increase the distance
   16393              :            between insns by 1.  */
   16394          411 :         prev = insn;
   16395              :     }
   16396              : 
   16397         2559 :   while (next
   16398         2559 :          && next != insn
   16399         2559 :          && distance < LEA_SEARCH_THRESHOLD)
   16400              :     {
   16401         2374 :       if (NONDEBUG_INSN_P (next) && NONJUMP_INSN_P (next))
   16402              :         {
   16403         1176 :           distance = increase_distance(prev, next, distance);
   16404         1176 :           if (insn_uses_reg_mem (regno, next))
   16405              :             {
   16406              :               /* Return DISTANCE if OP0 is used in memory
   16407              :                  address in NEXT.  */
   16408           87 :               *found = true;
   16409           87 :               return distance;
   16410              :             }
   16411              : 
   16412         1089 :           if (insn_defines_reg (regno, INVALID_REGNUM, next))
   16413              :             {
   16414              :               /* Return -1 if OP0 is set in NEXT.  */
   16415          157 :               *redefined = true;
   16416          157 :               return -1;
   16417              :             }
   16418              : 
   16419              :           prev = next;
   16420              :         }
   16421              : 
   16422         2130 :       if (next == BB_END (bb))
   16423              :         break;
   16424              : 
   16425         1789 :       next = NEXT_INSN (next);
   16426              :     }
   16427              : 
   16428              :   return distance;
   16429              : }
   16430              : 
   16431              : /* Return the distance between INSN and the next insn that uses
   16432              :    register number REGNO0 in memory address.  Return -1 if no such
   16433              :    a use is found within LEA_SEARCH_THRESHOLD or REGNO0 is set.  */
   16434              : 
   16435              : static int
   16436          428 : distance_agu_use (unsigned int regno0, rtx_insn *insn)
   16437              : {
   16438          428 :   basic_block bb = BLOCK_FOR_INSN (insn);
   16439          428 :   int distance = 0;
   16440          428 :   bool found = false;
   16441          428 :   bool redefined = false;
   16442              : 
   16443          428 :   if (insn != BB_END (bb))
   16444          411 :     distance = distance_agu_use_in_bb (regno0, insn, distance,
   16445              :                                        NEXT_INSN (insn),
   16446              :                                        &found, &redefined);
   16447              : 
   16448          428 :   if (!found && !redefined && distance < LEA_SEARCH_THRESHOLD)
   16449              :     {
   16450          255 :       edge e;
   16451          255 :       edge_iterator ei;
   16452          255 :       bool simple_loop = false;
   16453              : 
   16454          544 :       FOR_EACH_EDGE (e, ei, bb->succs)
   16455          359 :         if (e->dest == bb)
   16456              :           {
   16457              :             simple_loop = true;
   16458              :             break;
   16459              :           }
   16460              : 
   16461          255 :       if (simple_loop)
   16462           70 :         distance = distance_agu_use_in_bb (regno0, insn,
   16463              :                                            distance, BB_HEAD (bb),
   16464              :                                            &found, &redefined);
   16465              :       else
   16466              :         {
   16467          185 :           int shortest_dist = -1;
   16468          185 :           bool found_in_bb = false;
   16469          185 :           bool redefined_in_bb = false;
   16470              : 
   16471          474 :           FOR_EACH_EDGE (e, ei, bb->succs)
   16472              :             {
   16473          289 :               int bb_dist
   16474          578 :                 = distance_agu_use_in_bb (regno0, insn,
   16475          289 :                                           distance, BB_HEAD (e->dest),
   16476              :                                           &found_in_bb, &redefined_in_bb);
   16477          289 :               if (found_in_bb)
   16478              :                 {
   16479           15 :                   if (shortest_dist < 0)
   16480              :                     shortest_dist = bb_dist;
   16481            0 :                   else if (bb_dist > 0)
   16482            0 :                     shortest_dist = MIN (bb_dist, shortest_dist);
   16483              : 
   16484           15 :                   found = true;
   16485              :                 }
   16486              :             }
   16487              : 
   16488          185 :           distance = shortest_dist;
   16489              :         }
   16490              :     }
   16491              : 
   16492          428 :   if (!found || redefined)
   16493              :     return -1;
   16494              : 
   16495           87 :   return distance >> 1;
   16496              : }
   16497              : 
   16498              : /* Define this macro to tune LEA priority vs ADD, it take effect when
   16499              :    there is a dilemma of choosing LEA or ADD
   16500              :    Negative value: ADD is more preferred than LEA
   16501              :    Zero: Neutral
   16502              :    Positive value: LEA is more preferred than ADD.  */
   16503              : #define IX86_LEA_PRIORITY 0
   16504              : 
   16505              : /* Return true if usage of lea INSN has performance advantage
   16506              :    over a sequence of instructions.  Instructions sequence has
   16507              :    SPLIT_COST cycles higher latency than lea latency.  */
   16508              : 
   16509              : static bool
   16510         1596 : ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1,
   16511              :                       unsigned int regno2, int split_cost, bool has_scale)
   16512              : {
   16513         1596 :   int dist_define, dist_use;
   16514              : 
   16515              :   /* For Atom processors newer than Bonnell, if using a 2-source or
   16516              :      3-source LEA for non-destructive destination purposes, or due to
   16517              :      wanting ability to use SCALE, the use of LEA is justified.  */
   16518         1596 :   if (!TARGET_CPU_P (BONNELL))
   16519              :     {
   16520         1168 :       if (has_scale)
   16521              :         return true;
   16522         1149 :       if (split_cost < 1)
   16523              :         return false;
   16524          406 :       if (regno0 == regno1 || regno0 == regno2)
   16525              :         return false;
   16526          406 :       return true;
   16527              :     }
   16528              : 
   16529              :   /* distance_non_agu_define can call get_attr_type which can call
   16530              :      recog_memoized, restore recog_data back to previous content.  */
   16531          428 :   {
   16532          428 :     recog_state_saver recog_save;
   16533          428 :     dist_define = distance_non_agu_define (regno1, regno2, insn);
   16534          428 :     dist_use = distance_agu_use (regno0, insn);
   16535          428 :   }
   16536              : 
   16537          428 :   if (dist_define < 0 || dist_define >= LEA_MAX_STALL)
   16538              :     {
   16539              :       /* If there is no non AGU operand definition, no AGU
   16540              :          operand usage and split cost is 0 then both lea
   16541              :          and non lea variants have same priority.  Currently
   16542              :          we prefer lea for 64 bit code and non lea on 32 bit
   16543              :          code.  */
   16544          228 :       if (dist_use < 0 && split_cost == 0)
   16545          103 :         return TARGET_64BIT || IX86_LEA_PRIORITY;
   16546              :       else
   16547              :         return true;
   16548              :     }
   16549              : 
   16550              :   /* With longer definitions distance lea is more preferable.
   16551              :      Here we change it to take into account splitting cost and
   16552              :      lea priority.  */
   16553          200 :   dist_define += split_cost + IX86_LEA_PRIORITY;
   16554              : 
   16555              :   /* If there is no use in memory address then we just check
   16556              :      that split cost exceeds AGU stall.  */
   16557          200 :   if (dist_use < 0)
   16558          196 :     return dist_define > LEA_MAX_STALL;
   16559              : 
   16560              :   /* If this insn has both backward non-agu dependence and forward
   16561              :      agu dependence, the one with short distance takes effect.  */
   16562            4 :   return dist_define >= dist_use;
   16563              : }
   16564              : 
   16565              : /* Return true if we need to split op0 = op1 + op2 into a sequence of
   16566              :    move and add to avoid AGU stalls.  */
   16567              : 
   16568              : bool
   16569      9389704 : ix86_avoid_lea_for_add (rtx_insn *insn, rtx operands[])
   16570              : {
   16571      9389704 :   unsigned int regno0, regno1, regno2;
   16572              : 
   16573              :   /* Check if we need to optimize.  */
   16574      9389704 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16575              :     return false;
   16576              : 
   16577          779 :   regno0 = true_regnum (operands[0]);
   16578          779 :   regno1 = true_regnum (operands[1]);
   16579          779 :   regno2 = true_regnum (operands[2]);
   16580              : 
   16581              :   /* We need to split only adds with non destructive
   16582              :      destination operand.  */
   16583          779 :   if (regno0 == regno1 || regno0 == regno2)
   16584              :     return false;
   16585              :   else
   16586          244 :     return !ix86_lea_outperforms (insn, regno0, regno1, regno2, 1, false);
   16587              : }
   16588              : 
   16589              : /* Return true if we should emit lea instruction instead of mov
   16590              :    instruction.  */
   16591              : 
   16592              : bool
   16593     30517993 : ix86_use_lea_for_mov (rtx_insn *insn, rtx operands[])
   16594              : {
   16595     30517993 :   unsigned int regno0, regno1;
   16596              : 
   16597              :   /* Check if we need to optimize.  */
   16598     30517993 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16599              :     return false;
   16600              : 
   16601              :   /* Use lea for reg to reg moves only.  */
   16602         2274 :   if (!REG_P (operands[0]) || !REG_P (operands[1]))
   16603              :     return false;
   16604              : 
   16605          469 :   regno0 = true_regnum (operands[0]);
   16606          469 :   regno1 = true_regnum (operands[1]);
   16607              : 
   16608          469 :   return ix86_lea_outperforms (insn, regno0, regno1, INVALID_REGNUM, 0, false);
   16609              : }
   16610              : 
   16611              : /* Return true if we need to split lea into a sequence of
   16612              :    instructions to avoid AGU stalls during peephole2. */
   16613              : 
   16614              : bool
   16615     11683231 : ix86_avoid_lea_for_addr (rtx_insn *insn, rtx operands[])
   16616              : {
   16617     11683231 :   unsigned int regno0, regno1, regno2;
   16618     11683231 :   int split_cost;
   16619     11683231 :   struct ix86_address parts;
   16620     11683231 :   int ok;
   16621              : 
   16622              :   /* The "at least two components" test below might not catch simple
   16623              :      move or zero extension insns if parts.base is non-NULL and parts.disp
   16624              :      is const0_rtx as the only components in the address, e.g. if the
   16625              :      register is %rbp or %r13.  As this test is much cheaper and moves or
   16626              :      zero extensions are the common case, do this check first.  */
   16627     11683231 :   if (REG_P (operands[1])
   16628     11683231 :       || (SImode_address_operand (operands[1], VOIDmode)
   16629       141498 :           && REG_P (XEXP (operands[1], 0))))
   16630              :     return false;
   16631              : 
   16632      7372398 :   ok = ix86_decompose_address (operands[1], &parts);
   16633      7372398 :   gcc_assert (ok);
   16634              : 
   16635              :   /* There should be at least two components in the address.  */
   16636      7372398 :   if ((parts.base != NULL_RTX) + (parts.index != NULL_RTX)
   16637      7372398 :       + (parts.disp != NULL_RTX) + (parts.scale > 1) < 2)
   16638              :     return false;
   16639              : 
   16640              :   /* We should not split into add if non legitimate pic
   16641              :      operand is used as displacement. */
   16642      2810261 :   if (parts.disp && flag_pic && !LEGITIMATE_PIC_OPERAND_P (parts.disp))
   16643              :     return false;
   16644              : 
   16645      2760174 :   regno0 = true_regnum (operands[0]) ;
   16646      2760174 :   regno1 = INVALID_REGNUM;
   16647      2760174 :   regno2 = INVALID_REGNUM;
   16648              : 
   16649      2760174 :   if (parts.base)
   16650      2685177 :     regno1 = true_regnum (parts.base);
   16651      2760174 :   if (parts.index)
   16652       486839 :     regno2 = true_regnum (parts.index);
   16653              : 
   16654              :   /* Use add for a = a + b and a = b + a since it is faster and shorter
   16655              :      than lea for most processors.  For the processors like BONNELL, if
   16656              :      the destination register of LEA holds an actual address which will
   16657              :      be used soon, LEA is better and otherwise ADD is better.  */
   16658      2760174 :   if (!TARGET_CPU_P (BONNELL)
   16659      2760047 :       && parts.scale == 1
   16660      2515628 :       && (!parts.disp || parts.disp == const0_rtx)
   16661       186112 :       && (regno0 == regno1 || regno0 == regno2))
   16662              :     return true;
   16663              : 
   16664              :   /* Split with -Oz if the encoding requires fewer bytes.  */
   16665      2753427 :   if (optimize_size > 1
   16666           27 :       && parts.scale > 1
   16667            4 :       && !parts.base
   16668            4 :       && (!parts.disp || parts.disp == const0_rtx))
   16669              :     return true;
   16670              : 
   16671              :   /* Check we need to optimize.  */
   16672      2753423 :   if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
   16673              :     return false;
   16674              : 
   16675          339 :   split_cost = 0;
   16676              : 
   16677              :   /* Compute how many cycles we will add to execution time
   16678              :      if split lea into a sequence of instructions.  */
   16679          339 :   if (parts.base || parts.index)
   16680              :     {
   16681              :       /* Have to use mov instruction if non destructive
   16682              :          destination form is used.  */
   16683          339 :       if (regno1 != regno0 && regno2 != regno0)
   16684          262 :         split_cost += 1;
   16685              : 
   16686              :       /* Have to add index to base if both exist.  */
   16687          339 :       if (parts.base && parts.index)
   16688           54 :         split_cost += 1;
   16689              : 
   16690              :       /* Have to use shift and adds if scale is 2 or greater.  */
   16691          339 :       if (parts.scale > 1)
   16692              :         {
   16693           30 :           if (regno0 != regno1)
   16694           24 :             split_cost += 1;
   16695            6 :           else if (regno2 == regno0)
   16696            0 :             split_cost += 4;
   16697              :           else
   16698            6 :             split_cost += parts.scale;
   16699              :         }
   16700              : 
   16701              :       /* Have to use add instruction with immediate if
   16702              :          disp is non zero.  */
   16703          339 :       if (parts.disp && parts.disp != const0_rtx)
   16704          278 :         split_cost += 1;
   16705              : 
   16706              :       /* Subtract the price of lea.  */
   16707          339 :       split_cost -= 1;
   16708              :     }
   16709              : 
   16710          339 :   return !ix86_lea_outperforms (insn, regno0, regno1, regno2, split_cost,
   16711          339 :                                 parts.scale > 1);
   16712              : }
   16713              : 
   16714              : /* Return true if it is ok to optimize an ADD operation to LEA
   16715              :    operation to avoid flag register consumation.  For most processors,
   16716              :    ADD is faster than LEA.  For the processors like BONNELL, if the
   16717              :    destination register of LEA holds an actual address which will be
   16718              :    used soon, LEA is better and otherwise ADD is better.  */
   16719              : 
   16720              : bool
   16721      9451692 : ix86_lea_for_add_ok (rtx_insn *insn, rtx operands[])
   16722              : {
   16723      9451692 :   unsigned int regno0 = true_regnum (operands[0]);
   16724      9451692 :   unsigned int regno1 = true_regnum (operands[1]);
   16725      9451692 :   unsigned int regno2 = true_regnum (operands[2]);
   16726              : 
   16727              :   /* If a = b + c, (a!=b && a!=c), must use lea form. */
   16728      9451692 :   if (regno0 != regno1 && regno0 != regno2)
   16729              :     return true;
   16730              : 
   16731      7331614 :   if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
   16732              :     return false;
   16733              : 
   16734          544 :   return ix86_lea_outperforms (insn, regno0, regno1, regno2, 0, false);
   16735              : }
   16736              : 
   16737              : /* Return true if destination reg of SET_BODY is shift count of
   16738              :    USE_BODY.  */
   16739              : 
   16740              : static bool
   16741           85 : ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
   16742              : {
   16743           85 :   rtx set_dest;
   16744           85 :   rtx shift_rtx;
   16745           85 :   int i;
   16746              : 
   16747              :   /* Retrieve destination of SET_BODY.  */
   16748           85 :   switch (GET_CODE (set_body))
   16749              :     {
   16750           67 :     case SET:
   16751           67 :       set_dest = SET_DEST (set_body);
   16752           67 :       if (!set_dest || !REG_P (set_dest))
   16753              :         return false;
   16754           66 :       break;
   16755            9 :     case PARALLEL:
   16756           27 :       for (i = XVECLEN (set_body, 0) - 1; i >= 0; i--)
   16757           18 :         if (ix86_dep_by_shift_count_body (XVECEXP (set_body, 0, i),
   16758              :                                           use_body))
   16759              :           return true;
   16760              :       /* FALLTHROUGH */
   16761              :     default:
   16762              :       return false;
   16763              :     }
   16764              : 
   16765              :   /* Retrieve shift count of USE_BODY.  */
   16766           66 :   switch (GET_CODE (use_body))
   16767              :     {
   16768           22 :     case SET:
   16769           22 :       shift_rtx = XEXP (use_body, 1);
   16770           22 :       break;
   16771           22 :     case PARALLEL:
   16772           66 :       for (i = XVECLEN (use_body, 0) - 1; i >= 0; i--)
   16773           44 :         if (ix86_dep_by_shift_count_body (set_body,
   16774           44 :                                           XVECEXP (use_body, 0, i)))
   16775              :           return true;
   16776              :       /* FALLTHROUGH */
   16777              :     default:
   16778              :       return false;
   16779              :     }
   16780              : 
   16781           22 :   if (shift_rtx
   16782           22 :       && (GET_CODE (shift_rtx) == ASHIFT
   16783           21 :           || GET_CODE (shift_rtx) == LSHIFTRT
   16784            5 :           || GET_CODE (shift_rtx) == ASHIFTRT
   16785            0 :           || GET_CODE (shift_rtx) == ROTATE
   16786            0 :           || GET_CODE (shift_rtx) == ROTATERT))
   16787              :     {
   16788           22 :       rtx shift_count = XEXP (shift_rtx, 1);
   16789              : 
   16790              :       /* Return true if shift count is dest of SET_BODY.  */
   16791           22 :       if (REG_P (shift_count))
   16792              :         {
   16793              :           /* Add check since it can be invoked before register
   16794              :              allocation in pre-reload schedule.  */
   16795            0 :           if (reload_completed
   16796            0 :               && true_regnum (set_dest) == true_regnum (shift_count))
   16797              :             return true;
   16798            0 :           else if (REGNO(set_dest) == REGNO(shift_count))
   16799            0 :             return true;
   16800              :         }
   16801              :     }
   16802              : 
   16803              :   return false;
   16804              : }
   16805              : 
   16806              : /* Return true if destination reg of SET_INSN is shift count of
   16807              :    USE_INSN.  */
   16808              : 
   16809              : bool
   16810           23 : ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
   16811              : {
   16812           23 :   return ix86_dep_by_shift_count_body (PATTERN (set_insn),
   16813           23 :                                        PATTERN (use_insn));
   16814              : }
   16815              : 
   16816              : /* Return TRUE if the operands to a vec_interleave_{high,low}v2df
   16817              :    are ok, keeping in mind the possible movddup alternative.  */
   16818              : 
   16819              : bool
   16820        93713 : ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high)
   16821              : {
   16822        93713 :   if (MEM_P (operands[0]))
   16823         2114 :     return rtx_equal_p (operands[0], operands[1 + high]);
   16824        91599 :   if (MEM_P (operands[1]) && MEM_P (operands[2]))
   16825         1129 :     return false;
   16826              :   return true;
   16827              : }
   16828              : 
   16829              : /* A subroutine of ix86_build_signbit_mask.  If VECT is true,
   16830              :    then replicate the value for all elements of the vector
   16831              :    register.  */
   16832              : 
   16833              : rtx
   16834        76373 : ix86_build_const_vector (machine_mode mode, bool vect, rtx value)
   16835              : {
   16836        76373 :   int i, n_elt;
   16837        76373 :   rtvec v;
   16838        76373 :   machine_mode scalar_mode;
   16839              : 
   16840        76373 :   switch (mode)
   16841              :     {
   16842         1507 :     case E_V64QImode:
   16843         1507 :     case E_V32QImode:
   16844         1507 :     case E_V16QImode:
   16845         1507 :     case E_V32HImode:
   16846         1507 :     case E_V16HImode:
   16847         1507 :     case E_V8HImode:
   16848         1507 :     case E_V16SImode:
   16849         1507 :     case E_V8SImode:
   16850         1507 :     case E_V4SImode:
   16851         1507 :     case E_V2SImode:
   16852         1507 :     case E_V8DImode:
   16853         1507 :     case E_V4DImode:
   16854         1507 :     case E_V2DImode:
   16855         1507 :       gcc_assert (vect);
   16856              :       /* FALLTHRU */
   16857        76373 :     case E_V2HFmode:
   16858        76373 :     case E_V4HFmode:
   16859        76373 :     case E_V8HFmode:
   16860        76373 :     case E_V16HFmode:
   16861        76373 :     case E_V32HFmode:
   16862        76373 :     case E_V16SFmode:
   16863        76373 :     case E_V8SFmode:
   16864        76373 :     case E_V4SFmode:
   16865        76373 :     case E_V2SFmode:
   16866        76373 :     case E_V8DFmode:
   16867        76373 :     case E_V4DFmode:
   16868        76373 :     case E_V2DFmode:
   16869        76373 :     case E_V32BFmode:
   16870        76373 :     case E_V16BFmode:
   16871        76373 :     case E_V8BFmode:
   16872        76373 :     case E_V4BFmode:
   16873        76373 :     case E_V2BFmode:
   16874        76373 :       n_elt = GET_MODE_NUNITS (mode);
   16875        76373 :       v = rtvec_alloc (n_elt);
   16876        76373 :       scalar_mode = GET_MODE_INNER (mode);
   16877              : 
   16878        76373 :       RTVEC_ELT (v, 0) = value;
   16879              : 
   16880       237490 :       for (i = 1; i < n_elt; ++i)
   16881       161117 :         RTVEC_ELT (v, i) = vect ? value : CONST0_RTX (scalar_mode);
   16882              : 
   16883        76373 :       return gen_rtx_CONST_VECTOR (mode, v);
   16884              : 
   16885            0 :     default:
   16886            0 :       gcc_unreachable ();
   16887              :     }
   16888              : }
   16889              : 
   16890              : /* A subroutine of ix86_expand_fp_absneg_operator, copysign expanders
   16891              :    and ix86_expand_int_vcond.  Create a mask for the sign bit in MODE
   16892              :    for an SSE register.  If VECT is true, then replicate the mask for
   16893              :    all elements of the vector register.  If INVERT is true, then create
   16894              :    a mask excluding the sign bit.  */
   16895              : 
   16896              : rtx
   16897        78057 : ix86_build_signbit_mask (machine_mode mode, bool vect, bool invert)
   16898              : {
   16899        78057 :   machine_mode vec_mode, imode;
   16900        78057 :   wide_int w;
   16901        78057 :   rtx mask, v;
   16902              : 
   16903        78057 :   switch (mode)
   16904              :     {
   16905              :     case E_V2HFmode:
   16906              :     case E_V4HFmode:
   16907              :     case E_V8HFmode:
   16908              :     case E_V16HFmode:
   16909              :     case E_V32HFmode:
   16910              :     case E_V32BFmode:
   16911              :     case E_V16BFmode:
   16912              :     case E_V8BFmode:
   16913              :     case E_V4BFmode:
   16914              :     case E_V2BFmode:
   16915              :       vec_mode = mode;
   16916              :       imode = HImode;
   16917              :       break;
   16918              : 
   16919        34836 :     case E_V16SImode:
   16920        34836 :     case E_V16SFmode:
   16921        34836 :     case E_V8SImode:
   16922        34836 :     case E_V4SImode:
   16923        34836 :     case E_V8SFmode:
   16924        34836 :     case E_V4SFmode:
   16925        34836 :     case E_V2SFmode:
   16926        34836 :     case E_V2SImode:
   16927        34836 :       vec_mode = mode;
   16928        34836 :       imode = SImode;
   16929        34836 :       break;
   16930              : 
   16931        39935 :     case E_V8DImode:
   16932        39935 :     case E_V4DImode:
   16933        39935 :     case E_V2DImode:
   16934        39935 :     case E_V8DFmode:
   16935        39935 :     case E_V4DFmode:
   16936        39935 :     case E_V2DFmode:
   16937        39935 :       vec_mode = mode;
   16938        39935 :       imode = DImode;
   16939        39935 :       break;
   16940              : 
   16941         2781 :     case E_TImode:
   16942         2781 :     case E_TFmode:
   16943         2781 :       vec_mode = VOIDmode;
   16944         2781 :       imode = TImode;
   16945         2781 :       break;
   16946              : 
   16947            0 :     default:
   16948            0 :       gcc_unreachable ();
   16949              :     }
   16950              : 
   16951        78057 :   machine_mode inner_mode = GET_MODE_INNER (mode);
   16952       156114 :   w = wi::set_bit_in_zero (GET_MODE_BITSIZE (inner_mode) - 1,
   16953       156114 :                            GET_MODE_BITSIZE (inner_mode));
   16954        78057 :   if (invert)
   16955        41392 :     w = wi::bit_not (w);
   16956              : 
   16957              :   /* Force this value into the low part of a fp vector constant.  */
   16958        78057 :   mask = immed_wide_int_const (w, imode);
   16959        78057 :   mask = gen_lowpart (inner_mode, mask);
   16960              : 
   16961        78057 :   if (vec_mode == VOIDmode)
   16962         2781 :     return force_reg (inner_mode, mask);
   16963              : 
   16964        75276 :   v = ix86_build_const_vector (vec_mode, vect, mask);
   16965        75276 :   return force_reg (vec_mode, v);
   16966        78057 : }
   16967              : 
   16968              : /* Return HOST_WIDE_INT for const vector OP in MODE.  */
   16969              : 
   16970              : HOST_WIDE_INT
   16971       137725 : ix86_convert_const_vector_to_integer (rtx op, machine_mode mode)
   16972              : {
   16973       291673 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   16974            0 :     gcc_unreachable ();
   16975              : 
   16976       137725 :   int nunits = GET_MODE_NUNITS (mode);
   16977       275450 :   wide_int val = wi::zero (GET_MODE_BITSIZE (mode));
   16978       137725 :   machine_mode innermode = GET_MODE_INNER (mode);
   16979       137725 :   unsigned int innermode_bits = GET_MODE_BITSIZE (innermode);
   16980              : 
   16981       137725 :   switch (mode)
   16982              :     {
   16983              :     case E_V2QImode:
   16984              :     case E_V4QImode:
   16985              :     case E_V2HImode:
   16986              :     case E_V8QImode:
   16987              :     case E_V4HImode:
   16988              :     case E_V2SImode:
   16989       471041 :       for (int i = 0; i < nunits; ++i)
   16990              :         {
   16991       338696 :           int v = INTVAL (XVECEXP (op, 0, i));
   16992       338696 :           wide_int wv = wi::shwi (v, innermode_bits);
   16993       338696 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   16994       338696 :         }
   16995              :       break;
   16996          145 :     case E_V1SImode:
   16997          145 :     case E_V1DImode:
   16998          145 :       op = CONST_VECTOR_ELT (op, 0);
   16999          145 :       return INTVAL (op);
   17000              :     case E_V2HFmode:
   17001              :     case E_V2BFmode:
   17002              :     case E_V4HFmode:
   17003              :     case E_V4BFmode:
   17004              :     case E_V2SFmode:
   17005        15751 :       for (int i = 0; i < nunits; ++i)
   17006              :         {
   17007        10516 :           rtx x = XVECEXP (op, 0, i);
   17008        10516 :           int v = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (x),
   17009        10516 :                                   REAL_MODE_FORMAT (innermode));
   17010        10516 :           wide_int wv = wi::shwi (v, innermode_bits);
   17011        10516 :           val = wi::insert (val, wv, innermode_bits * i, innermode_bits);
   17012        10516 :         }
   17013              :       break;
   17014            0 :     default:
   17015            0 :       gcc_unreachable ();
   17016              :     }
   17017              : 
   17018       137580 :   return val.to_shwi ();
   17019       137725 : }
   17020              : 
   17021           34 : int ix86_get_flags_cc (rtx_code code)
   17022              : {
   17023           34 :   switch (code)
   17024              :     {
   17025              :       case NE: return X86_CCNE;
   17026              :       case EQ: return X86_CCE;
   17027              :       case GE: return X86_CCNL;
   17028              :       case GT: return X86_CCNLE;
   17029              :       case LE: return X86_CCLE;
   17030              :       case LT: return X86_CCL;
   17031              :       case GEU: return X86_CCNB;
   17032              :       case GTU: return X86_CCNBE;
   17033              :       case LEU: return X86_CCBE;
   17034              :       case LTU: return X86_CCB;
   17035              :       default: return -1;
   17036              :     }
   17037              : }
   17038              : 
   17039              : /* Return TRUE or FALSE depending on whether the first SET in INSN
   17040              :    has source and destination with matching CC modes, and that the
   17041              :    CC mode is at least as constrained as REQ_MODE.  */
   17042              : 
   17043              : bool
   17044     55453034 : ix86_match_ccmode (rtx insn, machine_mode req_mode)
   17045              : {
   17046     55453034 :   rtx set;
   17047     55453034 :   machine_mode set_mode;
   17048              : 
   17049     55453034 :   set = PATTERN (insn);
   17050     55453034 :   if (GET_CODE (set) == PARALLEL)
   17051       545075 :     set = XVECEXP (set, 0, 0);
   17052     55453034 :   gcc_assert (GET_CODE (set) == SET);
   17053     55453034 :   gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
   17054              : 
   17055     55453034 :   set_mode = GET_MODE (SET_DEST (set));
   17056     55453034 :   switch (set_mode)
   17057              :     {
   17058      1448604 :     case E_CCNOmode:
   17059      1448604 :       if (req_mode != CCNOmode
   17060       103602 :           && (req_mode != CCmode
   17061            0 :               || XEXP (SET_SRC (set), 1) != const0_rtx))
   17062              :         return false;
   17063              :       break;
   17064      5980265 :     case E_CCmode:
   17065      5980265 :       if (req_mode == CCGCmode)
   17066              :         return false;
   17067              :       /* FALLTHRU */
   17068      9602861 :     case E_CCGCmode:
   17069      9602861 :       if (req_mode == CCGOCmode || req_mode == CCNOmode)
   17070              :         return false;
   17071              :       /* FALLTHRU */
   17072     10708276 :     case E_CCGOCmode:
   17073     10708276 :       if (req_mode == CCZmode)
   17074              :         return false;
   17075              :       /* FALLTHRU */
   17076              :     case E_CCZmode:
   17077              :       break;
   17078              : 
   17079            0 :     case E_CCGZmode:
   17080              : 
   17081            0 :     case E_CCAmode:
   17082            0 :     case E_CCCmode:
   17083            0 :     case E_CCOmode:
   17084            0 :     case E_CCPmode:
   17085            0 :     case E_CCSmode:
   17086            0 :       if (set_mode != req_mode)
   17087              :         return false;
   17088              :       break;
   17089              : 
   17090            0 :     default:
   17091            0 :       gcc_unreachable ();
   17092              :     }
   17093              : 
   17094     55340373 :   return GET_MODE (SET_SRC (set)) == set_mode;
   17095              : }
   17096              : 
   17097              : machine_mode
   17098     14129789 : ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
   17099              : {
   17100     14129789 :   machine_mode mode = GET_MODE (op0);
   17101              : 
   17102     14129789 :   if (SCALAR_FLOAT_MODE_P (mode))
   17103              :     {
   17104       151422 :       gcc_assert (!DECIMAL_FLOAT_MODE_P (mode));
   17105              :       return CCFPmode;
   17106              :     }
   17107              : 
   17108     13978367 :   switch (code)
   17109              :     {
   17110              :       /* Only zero flag is needed.  */
   17111              :     case EQ:                    /* ZF=0 */
   17112              :     case NE:                    /* ZF!=0 */
   17113              :       return CCZmode;
   17114              :       /* Codes needing carry flag.  */
   17115      1000766 :     case GEU:                   /* CF=0 */
   17116      1000766 :     case LTU:                   /* CF=1 */
   17117      1000766 :       rtx geu;
   17118              :       /* Detect overflow checks.  They need just the carry flag.  */
   17119      1000766 :       if (GET_CODE (op0) == PLUS
   17120      1000766 :           && (rtx_equal_p (op1, XEXP (op0, 0))
   17121       102149 :               || rtx_equal_p (op1, XEXP (op0, 1))))
   17122              :         return CCCmode;
   17123              :       /* Similarly for *setcc_qi_addqi3_cconly_overflow_1_* patterns.
   17124              :          Match LTU of op0
   17125              :          (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   17126              :          and op1
   17127              :          (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
   17128              :          where CC_CCC is either CC or CCC.  */
   17129       985617 :       else if (code == LTU
   17130       359218 :                && GET_CODE (op0) == NEG
   17131           19 :                && GET_CODE (geu = XEXP (op0, 0)) == GEU
   17132            0 :                && REG_P (XEXP (geu, 0))
   17133            0 :                && (GET_MODE (XEXP (geu, 0)) == CCCmode
   17134            0 :                    || GET_MODE (XEXP (geu, 0)) == CCmode)
   17135            0 :                && REGNO (XEXP (geu, 0)) == FLAGS_REG
   17136            0 :                && XEXP (geu, 1) == const0_rtx
   17137            0 :                && GET_CODE (op1) == LTU
   17138            0 :                && REG_P (XEXP (op1, 0))
   17139            0 :                && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   17140            0 :                && REGNO (XEXP (op1, 0)) == FLAGS_REG
   17141       985617 :                && XEXP (op1, 1) == const0_rtx)
   17142              :         return CCCmode;
   17143              :       /* Similarly for *x86_cmc pattern.
   17144              :          Match LTU of op0 (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   17145              :          and op1 (geu:QI (reg:CCC FLAGS_REG) (const_int 0)).
   17146              :          It is sufficient to test that the operand modes are CCCmode.  */
   17147       985617 :       else if (code == LTU
   17148       359218 :                && GET_CODE (op0) == NEG
   17149           19 :                && GET_CODE (XEXP (op0, 0)) == LTU
   17150            0 :                && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   17151            0 :                && GET_CODE (op1) == GEU
   17152            0 :                && GET_MODE (XEXP (op1, 0)) == CCCmode)
   17153              :         return CCCmode;
   17154              :       /* Similarly for the comparison of addcarry/subborrow pattern.  */
   17155       359218 :       else if (code == LTU
   17156       359218 :                && GET_CODE (op0) == ZERO_EXTEND
   17157        15659 :                && GET_CODE (op1) == PLUS
   17158        11152 :                && ix86_carry_flag_operator (XEXP (op1, 0), VOIDmode)
   17159        11152 :                && GET_CODE (XEXP (op1, 1)) == ZERO_EXTEND)
   17160              :         return CCCmode;
   17161              :       else
   17162              :         return CCmode;
   17163              :     case GTU:                   /* CF=0 & ZF=0 */
   17164              :     case LEU:                   /* CF=1 | ZF=1 */
   17165              :       return CCmode;
   17166              :       /* Codes possibly doable only with sign flag when
   17167              :          comparing against zero.  */
   17168       813290 :     case GE:                    /* SF=OF   or   SF=0 */
   17169       813290 :     case LT:                    /* SF<>OF  or   SF=1 */
   17170       813290 :       if (op1 == const0_rtx)
   17171              :         return CCGOCmode;
   17172              :       else
   17173              :         /* For other cases Carry flag is not required.  */
   17174       437929 :         return CCGCmode;
   17175              :       /* Codes doable only with sign flag when comparing
   17176              :          against zero, but we miss jump instruction for it
   17177              :          so we need to use relational tests against overflow
   17178              :          that thus needs to be zero.  */
   17179       933285 :     case GT:                    /* ZF=0 & SF=OF */
   17180       933285 :     case LE:                    /* ZF=1 | SF<>OF */
   17181       933285 :       if (op1 == const0_rtx)
   17182              :         return CCNOmode;
   17183              :       else
   17184       621438 :         return CCGCmode;
   17185              :     default:
   17186              :       /* CCmode should be used in all other cases.  */
   17187              :       return CCmode;
   17188              :     }
   17189              : }
   17190              : 
   17191              : /* Return TRUE or FALSE depending on whether the ptest instruction
   17192              :    INSN has source and destination with suitable matching CC modes.  */
   17193              : 
   17194              : bool
   17195        91408 : ix86_match_ptest_ccmode (rtx insn)
   17196              : {
   17197        91408 :   rtx set, src;
   17198        91408 :   machine_mode set_mode;
   17199              : 
   17200        91408 :   set = PATTERN (insn);
   17201        91408 :   gcc_assert (GET_CODE (set) == SET);
   17202        91408 :   src = SET_SRC (set);
   17203        91408 :   gcc_assert (GET_CODE (src) == UNSPEC
   17204              :               && XINT (src, 1) == UNSPEC_PTEST);
   17205              : 
   17206        91408 :   set_mode = GET_MODE (src);
   17207        91408 :   if (set_mode != CCZmode
   17208              :       && set_mode != CCCmode
   17209              :       && set_mode != CCmode)
   17210              :     return false;
   17211        91408 :   return GET_MODE (SET_DEST (set)) == set_mode;
   17212              : }
   17213              : 
   17214              : /* Return the fixed registers used for condition codes.  */
   17215              : 
   17216              : static bool
   17217     19449303 : ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
   17218              : {
   17219     19449303 :   *p1 = FLAGS_REG;
   17220     19449303 :   *p2 = INVALID_REGNUM;
   17221     19449303 :   return true;
   17222              : }
   17223              : 
   17224              : /* If two condition code modes are compatible, return a condition code
   17225              :    mode which is compatible with both.  Otherwise, return
   17226              :    VOIDmode.  */
   17227              : 
   17228              : static machine_mode
   17229        32680 : ix86_cc_modes_compatible (machine_mode m1, machine_mode m2)
   17230              : {
   17231        32680 :   if (m1 == m2)
   17232              :     return m1;
   17233              : 
   17234        31075 :   if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
   17235              :     return VOIDmode;
   17236              : 
   17237        31075 :   if ((m1 == CCGCmode && m2 == CCGOCmode)
   17238        31075 :       || (m1 == CCGOCmode && m2 == CCGCmode))
   17239              :     return CCGCmode;
   17240              : 
   17241        31075 :   if ((m1 == CCNOmode && m2 == CCGOCmode)
   17242        30897 :       || (m1 == CCGOCmode && m2 == CCNOmode))
   17243              :     return CCNOmode;
   17244              : 
   17245        30781 :   if (m1 == CCZmode
   17246        16591 :       && (m2 == CCGCmode || m2 == CCGOCmode || m2 == CCNOmode))
   17247              :     return m2;
   17248        18278 :   else if (m2 == CCZmode
   17249        13943 :            && (m1 == CCGCmode || m1 == CCGOCmode || m1 == CCNOmode))
   17250              :     return m1;
   17251              : 
   17252         7636 :   switch (m1)
   17253              :     {
   17254            0 :     default:
   17255            0 :       gcc_unreachable ();
   17256              : 
   17257         7636 :     case E_CCmode:
   17258         7636 :     case E_CCGCmode:
   17259         7636 :     case E_CCGOCmode:
   17260         7636 :     case E_CCNOmode:
   17261         7636 :     case E_CCAmode:
   17262         7636 :     case E_CCCmode:
   17263         7636 :     case E_CCOmode:
   17264         7636 :     case E_CCPmode:
   17265         7636 :     case E_CCSmode:
   17266         7636 :     case E_CCZmode:
   17267         7636 :       switch (m2)
   17268              :         {
   17269              :         default:
   17270              :           return VOIDmode;
   17271              : 
   17272              :         case E_CCmode:
   17273              :         case E_CCGCmode:
   17274              :         case E_CCGOCmode:
   17275              :         case E_CCNOmode:
   17276              :         case E_CCAmode:
   17277              :         case E_CCCmode:
   17278              :         case E_CCOmode:
   17279              :         case E_CCPmode:
   17280              :         case E_CCSmode:
   17281              :         case E_CCZmode:
   17282              :           return CCmode;
   17283              :         }
   17284              : 
   17285              :     case E_CCFPmode:
   17286              :       /* These are only compatible with themselves, which we already
   17287              :          checked above.  */
   17288              :       return VOIDmode;
   17289              :     }
   17290              : }
   17291              : 
   17292              : /* Return strategy to use for floating-point.  We assume that fcomi is always
   17293              :    preferable where available, since that is also true when looking at size
   17294              :    (2 bytes, vs. 3 for fnstsw+sahf and at least 5 for fnstsw+test).  */
   17295              : 
   17296              : enum ix86_fpcmp_strategy
   17297      5651238 : ix86_fp_comparison_strategy (enum rtx_code)
   17298              : {
   17299              :   /* Do fcomi/sahf based test when profitable.  */
   17300              : 
   17301      5651238 :   if (TARGET_CMOVE)
   17302              :     return IX86_FPCMP_COMI;
   17303              : 
   17304            0 :   if (TARGET_SAHF && (TARGET_USE_SAHF || optimize_insn_for_size_p ()))
   17305            0 :     return IX86_FPCMP_SAHF;
   17306              : 
   17307              :   return IX86_FPCMP_ARITH;
   17308              : }
   17309              : 
   17310              : /* Convert comparison codes we use to represent FP comparison to integer
   17311              :    code that will result in proper branch.  Return UNKNOWN if no such code
   17312              :    is available.  */
   17313              : 
   17314              : enum rtx_code
   17315       600160 : ix86_fp_compare_code_to_integer (enum rtx_code code)
   17316              : {
   17317       600160 :   switch (code)
   17318              :     {
   17319              :     case GT:
   17320              :       return GTU;
   17321        19390 :     case GE:
   17322        19390 :       return GEU;
   17323              :     case ORDERED:
   17324              :     case UNORDERED:
   17325              :       return code;
   17326       119758 :     case UNEQ:
   17327       119758 :       return EQ;
   17328        25142 :     case UNLT:
   17329        25142 :       return LTU;
   17330        32794 :     case UNLE:
   17331        32794 :       return LEU;
   17332       114361 :     case LTGT:
   17333       114361 :       return NE;
   17334          639 :     case EQ:
   17335          639 :     case NE:
   17336          639 :       if (TARGET_AVX10_2)
   17337              :         return code;
   17338              :       /* FALLTHRU.  */
   17339          254 :     default:
   17340          254 :       return UNKNOWN;
   17341              :     }
   17342              : }
   17343              : 
   17344              : /* Zero extend possibly SImode EXP to Pmode register.  */
   17345              : rtx
   17346        38415 : ix86_zero_extend_to_Pmode (rtx exp)
   17347              : {
   17348        50307 :   return force_reg (Pmode, convert_to_mode (Pmode, exp, 1));
   17349              : }
   17350              : 
   17351              : /* Return true if the function is called via PLT.   */
   17352              : 
   17353              : bool
   17354      1429417 : ix86_call_use_plt_p (rtx call_op)
   17355              : {
   17356      1429417 :   if (SYMBOL_REF_LOCAL_P (call_op))
   17357              :     {
   17358       328827 :       if (SYMBOL_REF_DECL (call_op)
   17359       328827 :           && TREE_CODE (SYMBOL_REF_DECL (call_op)) == FUNCTION_DECL)
   17360              :         {
   17361              :           /* NB: All ifunc functions must be called via PLT.  */
   17362       245647 :           cgraph_node *node
   17363       245647 :             = cgraph_node::get (SYMBOL_REF_DECL (call_op));
   17364       245647 :           if (node && node->ifunc_resolver)
   17365              :             return true;
   17366              :         }
   17367       328807 :       return false;
   17368              :     }
   17369              :   return true;
   17370              : }
   17371              : 
   17372              : /* Implement TARGET_IFUNC_REF_LOCAL_OK.  If this hook returns true,
   17373              :    the PLT entry will be used as the function address for local IFUNC
   17374              :    functions.  When the PIC register is needed for PLT call, indirect
   17375              :    call via the PLT entry will fail since the PIC register may not be
   17376              :    set up properly for indirect call.  In this case, we should return
   17377              :    false.  */
   17378              : 
   17379              : static bool
   17380    803812557 : ix86_ifunc_ref_local_ok (void)
   17381              : {
   17382    803812557 :   return !flag_pic || (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC);
   17383              : }
   17384              : 
   17385              : /* Return true if the function being called was marked with attribute
   17386              :    "noplt" or using -fno-plt and we are compiling for non-PIC.  We need
   17387              :    to handle the non-PIC case in the backend because there is no easy
   17388              :    interface for the front-end to force non-PLT calls to use the GOT.
   17389              :    This is currently used only with 64-bit or 32-bit GOT32X ELF targets
   17390              :    to call the function marked "noplt" indirectly.  */
   17391              : 
   17392              : bool
   17393      6140872 : ix86_nopic_noplt_attribute_p (rtx call_op)
   17394              : {
   17395      5432605 :   if (flag_pic || ix86_cmodel == CM_LARGE
   17396              :       || !(TARGET_64BIT || HAVE_AS_IX86_GOT32X)
   17397              :       || TARGET_MACHO || TARGET_SEH || TARGET_PECOFF
   17398     11573477 :       || SYMBOL_REF_LOCAL_P (call_op))
   17399              :     return false;
   17400              : 
   17401      3791732 :   tree symbol_decl = SYMBOL_REF_DECL (call_op);
   17402              : 
   17403      3791732 :   if (!flag_plt
   17404      3791732 :       || (symbol_decl != NULL_TREE
   17405      3791700 :           && lookup_attribute ("noplt", DECL_ATTRIBUTES (symbol_decl))))
   17406           34 :     return true;
   17407              : 
   17408              :   return false;
   17409              : }
   17410              : 
   17411              : /* Helper to output the jmp/call.  */
   17412              : static void
   17413           33 : ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno)
   17414              : {
   17415           33 :   if (thunk_name != NULL)
   17416              :     {
   17417           22 :       if ((REX_INT_REGNO_P (regno) || REX2_INT_REGNO_P (regno))
   17418            1 :           && ix86_indirect_branch_cs_prefix)
   17419            1 :         fprintf (asm_out_file, "\tcs\n");
   17420           22 :       fprintf (asm_out_file, "\tjmp\t");
   17421           22 :       assemble_name (asm_out_file, thunk_name);
   17422           22 :       putc ('\n', asm_out_file);
   17423           22 :       if ((ix86_harden_sls & harden_sls_indirect_jmp))
   17424            2 :         fputs ("\tint3\n", asm_out_file);
   17425              :     }
   17426              :   else
   17427           11 :     output_indirect_thunk (regno);
   17428           33 : }
   17429              : 
   17430              : /* Output indirect branch via a call and return thunk.  CALL_OP is a
   17431              :    register which contains the branch target.  XASM is the assembly
   17432              :    template for CALL_OP.  Branch is a tail call if SIBCALL_P is true.
   17433              :    A normal call is converted to:
   17434              : 
   17435              :         call __x86_indirect_thunk_reg
   17436              : 
   17437              :    and a tail call is converted to:
   17438              : 
   17439              :         jmp __x86_indirect_thunk_reg
   17440              :  */
   17441              : 
   17442              : static void
   17443           50 : ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p)
   17444              : {
   17445           50 :   char thunk_name_buf[32];
   17446           50 :   char *thunk_name;
   17447           50 :   enum indirect_thunk_prefix need_prefix
   17448           50 :     = indirect_thunk_need_prefix (current_output_insn);
   17449           50 :   int regno = REGNO (call_op);
   17450              : 
   17451           50 :   if (cfun->machine->indirect_branch_type
   17452           50 :       != indirect_branch_thunk_inline)
   17453              :     {
   17454           39 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   17455           16 :         SET_HARD_REG_BIT (indirect_thunks_used, regno);
   17456              : 
   17457           39 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   17458           39 :       thunk_name = thunk_name_buf;
   17459              :     }
   17460              :   else
   17461              :     thunk_name = NULL;
   17462              : 
   17463           50 :   if (sibcall_p)
   17464           27 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17465              :   else
   17466              :     {
   17467           23 :       if (thunk_name != NULL)
   17468              :         {
   17469           17 :           if ((REX_INT_REGNO_P (regno) || REX_INT_REGNO_P (regno))
   17470            1 :               && ix86_indirect_branch_cs_prefix)
   17471            1 :             fprintf (asm_out_file, "\tcs\n");
   17472           17 :           fprintf (asm_out_file, "\tcall\t");
   17473           17 :           assemble_name (asm_out_file, thunk_name);
   17474           17 :           putc ('\n', asm_out_file);
   17475           17 :           return;
   17476              :         }
   17477              : 
   17478            6 :       char indirectlabel1[32];
   17479            6 :       char indirectlabel2[32];
   17480              : 
   17481            6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   17482              :                                    INDIRECT_LABEL,
   17483              :                                    indirectlabelno++);
   17484            6 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   17485              :                                    INDIRECT_LABEL,
   17486              :                                    indirectlabelno++);
   17487              : 
   17488              :       /* Jump.  */
   17489            6 :       fputs ("\tjmp\t", asm_out_file);
   17490            6 :       assemble_name_raw (asm_out_file, indirectlabel2);
   17491            6 :       fputc ('\n', asm_out_file);
   17492              : 
   17493            6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   17494              : 
   17495            6 :      ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17496              : 
   17497            6 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   17498              : 
   17499              :       /* Call.  */
   17500            6 :       fputs ("\tcall\t", asm_out_file);
   17501            6 :       assemble_name_raw (asm_out_file, indirectlabel1);
   17502            6 :       fputc ('\n', asm_out_file);
   17503              :     }
   17504              : }
   17505              : 
   17506              : /* Output indirect branch via a call and return thunk.  CALL_OP is
   17507              :    the branch target.  XASM is the assembly template for CALL_OP.
   17508              :    Branch is a tail call if SIBCALL_P is true.  A normal call is
   17509              :    converted to:
   17510              : 
   17511              :         jmp L2
   17512              :    L1:
   17513              :         push CALL_OP
   17514              :         jmp __x86_indirect_thunk
   17515              :    L2:
   17516              :         call L1
   17517              : 
   17518              :    and a tail call is converted to:
   17519              : 
   17520              :         push CALL_OP
   17521              :         jmp __x86_indirect_thunk
   17522              :  */
   17523              : 
   17524              : static void
   17525            0 : ix86_output_indirect_branch_via_push (rtx call_op, const char *xasm,
   17526              :                                       bool sibcall_p)
   17527              : {
   17528            0 :   char thunk_name_buf[32];
   17529            0 :   char *thunk_name;
   17530            0 :   char push_buf[64];
   17531            0 :   enum indirect_thunk_prefix need_prefix
   17532            0 :     = indirect_thunk_need_prefix (current_output_insn);
   17533            0 :   int regno = -1;
   17534              : 
   17535            0 :   if (cfun->machine->indirect_branch_type
   17536            0 :       != indirect_branch_thunk_inline)
   17537              :     {
   17538            0 :       if (cfun->machine->indirect_branch_type == indirect_branch_thunk)
   17539            0 :         indirect_thunk_needed = true;
   17540            0 :       indirect_thunk_name (thunk_name_buf, regno, need_prefix, false);
   17541            0 :       thunk_name = thunk_name_buf;
   17542              :     }
   17543              :   else
   17544              :     thunk_name = NULL;
   17545              : 
   17546            0 :   snprintf (push_buf, sizeof (push_buf), "push{%c}\t%s",
   17547            0 :             TARGET_64BIT ? 'q' : 'l', xasm);
   17548              : 
   17549            0 :   if (sibcall_p)
   17550              :     {
   17551            0 :       output_asm_insn (push_buf, &call_op);
   17552            0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17553              :     }
   17554              :   else
   17555              :     {
   17556            0 :       char indirectlabel1[32];
   17557            0 :       char indirectlabel2[32];
   17558              : 
   17559            0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel1,
   17560              :                                    INDIRECT_LABEL,
   17561              :                                    indirectlabelno++);
   17562            0 :       ASM_GENERATE_INTERNAL_LABEL (indirectlabel2,
   17563              :                                    INDIRECT_LABEL,
   17564              :                                    indirectlabelno++);
   17565              : 
   17566              :       /* Jump.  */
   17567            0 :       fputs ("\tjmp\t", asm_out_file);
   17568            0 :       assemble_name_raw (asm_out_file, indirectlabel2);
   17569            0 :       fputc ('\n', asm_out_file);
   17570              : 
   17571            0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel1);
   17572              : 
   17573              :       /* An external function may be called via GOT, instead of PLT.  */
   17574            0 :       if (MEM_P (call_op))
   17575              :         {
   17576            0 :           struct ix86_address parts;
   17577            0 :           rtx addr = XEXP (call_op, 0);
   17578            0 :           if (ix86_decompose_address (addr, &parts)
   17579            0 :               && parts.base == stack_pointer_rtx)
   17580              :             {
   17581              :               /* Since call will adjust stack by -UNITS_PER_WORD,
   17582              :                  we must convert "disp(stack, index, scale)" to
   17583              :                  "disp+UNITS_PER_WORD(stack, index, scale)".  */
   17584            0 :               if (parts.index)
   17585              :                 {
   17586            0 :                   addr = gen_rtx_MULT (Pmode, parts.index,
   17587              :                                        GEN_INT (parts.scale));
   17588            0 :                   addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
   17589              :                                        addr);
   17590              :                 }
   17591              :               else
   17592              :                 addr = stack_pointer_rtx;
   17593              : 
   17594            0 :               rtx disp;
   17595            0 :               if (parts.disp != NULL_RTX)
   17596            0 :                 disp = plus_constant (Pmode, parts.disp,
   17597            0 :                                       UNITS_PER_WORD);
   17598              :               else
   17599            0 :                 disp = GEN_INT (UNITS_PER_WORD);
   17600              : 
   17601            0 :               addr = gen_rtx_PLUS (Pmode, addr, disp);
   17602            0 :               call_op = gen_rtx_MEM (GET_MODE (call_op), addr);
   17603              :             }
   17604              :         }
   17605              : 
   17606            0 :       output_asm_insn (push_buf, &call_op);
   17607              : 
   17608            0 :       ix86_output_jmp_thunk_or_indirect (thunk_name, regno);
   17609              : 
   17610            0 :       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, indirectlabel2);
   17611              : 
   17612              :       /* Call.  */
   17613            0 :       fputs ("\tcall\t", asm_out_file);
   17614            0 :       assemble_name_raw (asm_out_file, indirectlabel1);
   17615            0 :       fputc ('\n', asm_out_file);
   17616              :     }
   17617            0 : }
   17618              : 
   17619              : /* Output indirect branch via a call and return thunk.  CALL_OP is
   17620              :    the branch target.  XASM is the assembly template for CALL_OP.
   17621              :    Branch is a tail call if SIBCALL_P is true.   */
   17622              : 
   17623              : static void
   17624           50 : ix86_output_indirect_branch (rtx call_op, const char *xasm,
   17625              :                              bool sibcall_p)
   17626              : {
   17627           50 :   if (REG_P (call_op))
   17628           50 :     ix86_output_indirect_branch_via_reg (call_op, sibcall_p);
   17629              :   else
   17630            0 :     ix86_output_indirect_branch_via_push (call_op, xasm, sibcall_p);
   17631           50 : }
   17632              : 
   17633              : /* Output indirect jump.  CALL_OP is the jump target.  */
   17634              : 
   17635              : const char *
   17636         8588 : ix86_output_indirect_jmp (rtx call_op)
   17637              : {
   17638         8588 :   if (cfun->machine->indirect_branch_type != indirect_branch_keep)
   17639              :     {
   17640              :       /* We can't have red-zone since "call" in the indirect thunk
   17641              :          pushes the return address onto stack, destroying red-zone.  */
   17642            4 :       if (ix86_red_zone_used)
   17643            0 :         gcc_unreachable ();
   17644              : 
   17645            4 :       ix86_output_indirect_branch (call_op, "%0", true);
   17646              :     }
   17647              :   else
   17648         8584 :     output_asm_insn ("%!jmp\t%A0", &call_op);
   17649         8588 :   return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : "";
   17650              : }
   17651              : 
   17652              : /* Output return instrumentation for current function if needed.  */
   17653              : 
   17654              : static void
   17655      1751774 : output_return_instrumentation (void)
   17656              : {
   17657      1751774 :   if (ix86_instrument_return != instrument_return_none
   17658            6 :       && flag_fentry
   17659      1751780 :       && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
   17660              :     {
   17661            5 :       if (ix86_flag_record_return)
   17662            5 :         fprintf (asm_out_file, "1:\n");
   17663            5 :       switch (ix86_instrument_return)
   17664              :         {
   17665            2 :         case instrument_return_call:
   17666            2 :           fprintf (asm_out_file, "\tcall\t__return__\n");
   17667            2 :           break;
   17668            3 :         case instrument_return_nop5:
   17669              :           /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1)  */
   17670            3 :           fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
   17671            3 :           break;
   17672              :         case instrument_return_none:
   17673              :           break;
   17674              :         }
   17675              : 
   17676            5 :       if (ix86_flag_record_return)
   17677              :         {
   17678            5 :           fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
   17679            5 :           fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   17680            5 :           fprintf (asm_out_file, "\t.previous\n");
   17681              :         }
   17682              :     }
   17683      1751774 : }
   17684              : 
   17685              : /* Output function return.  CALL_OP is the jump target.  Add a REP
   17686              :    prefix to RET if LONG_P is true and function return is kept.  */
   17687              : 
   17688              : const char *
   17689      1618803 : ix86_output_function_return (bool long_p)
   17690              : {
   17691      1618803 :   output_return_instrumentation ();
   17692              : 
   17693      1618803 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17694              :     {
   17695           17 :       char thunk_name[32];
   17696           17 :       enum indirect_thunk_prefix need_prefix
   17697           17 :         = indirect_thunk_need_prefix (current_output_insn);
   17698              : 
   17699           17 :       if (cfun->machine->function_return_type
   17700           17 :           != indirect_branch_thunk_inline)
   17701              :         {
   17702           12 :           bool need_thunk = (cfun->machine->function_return_type
   17703              :                              == indirect_branch_thunk);
   17704           12 :           indirect_thunk_name (thunk_name, INVALID_REGNUM, need_prefix,
   17705              :                                true);
   17706           12 :           indirect_return_needed |= need_thunk;
   17707           12 :           fprintf (asm_out_file, "\tjmp\t");
   17708           12 :           assemble_name (asm_out_file, thunk_name);
   17709           12 :           putc ('\n', asm_out_file);
   17710              :         }
   17711              :       else
   17712            5 :         output_indirect_thunk (INVALID_REGNUM);
   17713              : 
   17714           17 :       return "";
   17715              :     }
   17716              : 
   17717      3237084 :   output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr);
   17718      1618786 :   return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
   17719              : }
   17720              : 
   17721              : /* Output indirect function return.  RET_OP is the function return
   17722              :    target.  */
   17723              : 
   17724              : const char *
   17725           17 : ix86_output_indirect_function_return (rtx ret_op)
   17726              : {
   17727           17 :   if (cfun->machine->function_return_type != indirect_branch_keep)
   17728              :     {
   17729            0 :       char thunk_name[32];
   17730            0 :       enum indirect_thunk_prefix need_prefix
   17731            0 :         = indirect_thunk_need_prefix (current_output_insn);
   17732            0 :       unsigned int regno = REGNO (ret_op);
   17733            0 :       gcc_assert (regno == CX_REG);
   17734              : 
   17735            0 :       if (cfun->machine->function_return_type
   17736            0 :           != indirect_branch_thunk_inline)
   17737              :         {
   17738            0 :           bool need_thunk = (cfun->machine->function_return_type
   17739              :                              == indirect_branch_thunk);
   17740            0 :           indirect_thunk_name (thunk_name, regno, need_prefix, true);
   17741              : 
   17742            0 :           if (need_thunk)
   17743              :             {
   17744            0 :               indirect_return_via_cx = true;
   17745            0 :               SET_HARD_REG_BIT (indirect_thunks_used, CX_REG);
   17746              :             }
   17747            0 :           fprintf (asm_out_file, "\tjmp\t");
   17748            0 :           assemble_name (asm_out_file, thunk_name);
   17749            0 :           putc ('\n', asm_out_file);
   17750              :         }
   17751              :       else
   17752            0 :         output_indirect_thunk (regno);
   17753              :     }
   17754              :   else
   17755              :     {
   17756           17 :       output_asm_insn ("%!jmp\t%A0", &ret_op);
   17757           17 :       if (ix86_harden_sls & harden_sls_indirect_jmp)
   17758            1 :         fputs ("\tint3\n", asm_out_file);
   17759              :     }
   17760           17 :   return "";
   17761              : }
   17762              : 
   17763              : /* Output the assembly for a call instruction.  */
   17764              : 
   17765              : const char *
   17766      6327061 : ix86_output_call_insn (rtx_insn *insn, rtx call_op)
   17767              : {
   17768      6327061 :   bool direct_p = constant_call_address_operand (call_op, VOIDmode);
   17769      6327061 :   bool output_indirect_p
   17770              :     = (!TARGET_SEH
   17771      6327061 :        && cfun->machine->indirect_branch_type != indirect_branch_keep);
   17772      6327061 :   bool seh_nop_p = false;
   17773      6327061 :   const char *xasm;
   17774              : 
   17775      6327061 :   if (SIBLING_CALL_P (insn))
   17776              :     {
   17777       132971 :       output_return_instrumentation ();
   17778       132971 :       if (direct_p)
   17779              :         {
   17780       123253 :           if (ix86_nopic_noplt_attribute_p (call_op))
   17781              :             {
   17782            4 :               direct_p = false;
   17783            4 :               if (TARGET_64BIT)
   17784              :                 {
   17785            4 :                   if (output_indirect_p)
   17786              :                     xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17787              :                   else
   17788            4 :                     xasm = "%!jmp\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17789              :                 }
   17790              :               else
   17791              :                 {
   17792            0 :                   if (output_indirect_p)
   17793              :                     xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17794              :                   else
   17795            0 :                     xasm = "%!jmp\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17796              :                 }
   17797              :             }
   17798              :           else
   17799              :             xasm = "%!jmp\t%P0";
   17800              :         }
   17801              :       /* SEH epilogue detection requires the indirect branch case
   17802              :          to include REX.W.  */
   17803         9718 :       else if (TARGET_SEH)
   17804              :         xasm = "%!rex.W jmp\t%A0";
   17805              :       else
   17806              :         {
   17807         9718 :           if (output_indirect_p)
   17808              :             xasm = "%0";
   17809              :           else
   17810         9695 :             xasm = "%!jmp\t%A0";
   17811              :         }
   17812              : 
   17813       132971 :       if (output_indirect_p && !direct_p)
   17814           23 :         ix86_output_indirect_branch (call_op, xasm, true);
   17815              :       else
   17816              :         {
   17817       132948 :           output_asm_insn (xasm, &call_op);
   17818       132948 :           if (!direct_p
   17819         9699 :               && (ix86_harden_sls & harden_sls_indirect_jmp))
   17820              :             return "int3";
   17821              :         }
   17822       132970 :       return "";
   17823              :     }
   17824              : 
   17825              :   /* SEH unwinding can require an extra nop to be emitted in several
   17826              :      circumstances.  Determine if we have one of those.  */
   17827      6194090 :   if (TARGET_SEH)
   17828              :     {
   17829              :       rtx_insn *i;
   17830              : 
   17831              :       for (i = NEXT_INSN (insn); i ; i = NEXT_INSN (i))
   17832              :         {
   17833              :           /* Prevent a catch region from being adjacent to a jump that would
   17834              :              be interpreted as an epilogue sequence by the unwinder.  */
   17835              :           if (JUMP_P(i) && CROSSING_JUMP_P (i))
   17836              :             {
   17837              :               seh_nop_p = true;
   17838              :               break;
   17839              :             }
   17840              : 
   17841              :           /* If we get to another real insn, we don't need the nop.  */
   17842              :           if (INSN_P (i))
   17843              :             break;
   17844              : 
   17845              :           /* If we get to the epilogue note, prevent a catch region from
   17846              :              being adjacent to the standard epilogue sequence.  Note that,
   17847              :              if non-call exceptions are enabled, we already did it during
   17848              :              epilogue expansion, or else, if the insn can throw internally,
   17849              :              we already did it during the reorg pass.  */
   17850              :           if (NOTE_P (i) && NOTE_KIND (i) == NOTE_INSN_EPILOGUE_BEG
   17851              :               && !flag_non_call_exceptions
   17852              :               && !can_throw_internal (insn))
   17853              :             {
   17854              :               seh_nop_p = true;
   17855              :               break;
   17856              :             }
   17857              :         }
   17858              : 
   17859              :       /* If we didn't find a real insn following the call, prevent the
   17860              :          unwinder from looking into the next function.  */
   17861              :       if (i == NULL)
   17862              :         seh_nop_p = true;
   17863              :     }
   17864              : 
   17865      6194090 :   if (direct_p)
   17866              :     {
   17867      6016597 :       if (ix86_nopic_noplt_attribute_p (call_op))
   17868              :         {
   17869            6 :           direct_p = false;
   17870            6 :           if (TARGET_64BIT)
   17871              :             {
   17872            6 :               if (output_indirect_p)
   17873              :                 xasm = "{%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17874              :               else
   17875            6 :                 xasm = "%!call\t{*%p0@GOTPCREL(%%rip)|[QWORD PTR %p0@GOTPCREL[rip]]}";
   17876              :             }
   17877              :           else
   17878              :             {
   17879            0 :               if (output_indirect_p)
   17880              :                 xasm = "{%p0@GOT|[DWORD PTR %p0@GOT]}";
   17881              :               else
   17882            0 :                 xasm = "%!call\t{*%p0@GOT|[DWORD PTR %p0@GOT]}";
   17883              :             }
   17884              :         }
   17885              :       else
   17886              :         xasm = "%!call\t%P0";
   17887              :     }
   17888              :   else
   17889              :     {
   17890       177493 :       if (output_indirect_p)
   17891              :         xasm = "%0";
   17892              :       else
   17893       177470 :         xasm = "%!call\t%A0";
   17894              :     }
   17895              : 
   17896      6194090 :   if (output_indirect_p && !direct_p)
   17897           23 :     ix86_output_indirect_branch (call_op, xasm, false);
   17898              :   else
   17899      6194067 :     output_asm_insn (xasm, &call_op);
   17900              : 
   17901              :   if (seh_nop_p)
   17902              :     return "nop";
   17903              : 
   17904              :   return "";
   17905              : }
   17906              : 
   17907              : /* Return a MEM corresponding to a stack slot with mode MODE.
   17908              :    Allocate a new slot if necessary.
   17909              : 
   17910              :    The RTL for a function can have several slots available: N is
   17911              :    which slot to use.  */
   17912              : 
   17913              : rtx
   17914        22476 : assign_386_stack_local (machine_mode mode, enum ix86_stack_slot n)
   17915              : {
   17916        22476 :   struct stack_local_entry *s;
   17917              : 
   17918        22476 :   gcc_assert (n < MAX_386_STACK_LOCALS);
   17919              : 
   17920        33892 :   for (s = ix86_stack_locals; s; s = s->next)
   17921        31285 :     if (s->mode == mode && s->n == n)
   17922        19869 :       return validize_mem (copy_rtx (s->rtl));
   17923              : 
   17924         2607 :   int align = 0;
   17925              :   /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
   17926              :      alignment with -m32 -mpreferred-stack-boundary=2.  */
   17927         2607 :   if (mode == DImode
   17928          329 :       && !TARGET_64BIT
   17929          329 :       && n == SLOT_FLOATxFDI_387
   17930         2936 :       && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
   17931              :     align = 32;
   17932         2607 :   s = ggc_alloc<stack_local_entry> ();
   17933         2607 :   s->n = n;
   17934         2607 :   s->mode = mode;
   17935         5214 :   s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
   17936              : 
   17937         2607 :   s->next = ix86_stack_locals;
   17938         2607 :   ix86_stack_locals = s;
   17939         2607 :   return validize_mem (copy_rtx (s->rtl));
   17940              : }
   17941              : 
   17942              : static void
   17943      1520556 : ix86_instantiate_decls (void)
   17944              : {
   17945      1520556 :   struct stack_local_entry *s;
   17946              : 
   17947      1520556 :   for (s = ix86_stack_locals; s; s = s->next)
   17948            0 :     if (s->rtl != NULL_RTX)
   17949            0 :       instantiate_decl_rtl (s->rtl);
   17950      1520556 : }
   17951              : 
   17952              : /* Check whether x86 address PARTS is a pc-relative address.  */
   17953              : 
   17954              : bool
   17955     28828598 : ix86_rip_relative_addr_p (struct ix86_address *parts)
   17956              : {
   17957     28828598 :   rtx base, index, disp;
   17958              : 
   17959     28828598 :   base = parts->base;
   17960     28828598 :   index = parts->index;
   17961     28828598 :   disp = parts->disp;
   17962              : 
   17963     28828598 :   if (disp && !base && !index)
   17964              :     {
   17965     26994907 :       if (TARGET_64BIT)
   17966              :         {
   17967     25341455 :           rtx symbol = disp;
   17968              : 
   17969     25341455 :           if (GET_CODE (disp) == CONST)
   17970      7168206 :             symbol = XEXP (disp, 0);
   17971     25341455 :           if (GET_CODE (symbol) == PLUS
   17972      6623830 :               && CONST_INT_P (XEXP (symbol, 1)))
   17973      6623830 :             symbol = XEXP (symbol, 0);
   17974              : 
   17975     25341455 :           if (LABEL_REF_P (symbol)
   17976     25334094 :               || (SYMBOL_REF_P (symbol)
   17977     24039035 :                   && SYMBOL_REF_TLS_MODEL (symbol) == 0)
   17978     26636514 :               || (GET_CODE (symbol) == UNSPEC
   17979       563119 :                   && (XINT (symbol, 1) == UNSPEC_GOTPCREL
   17980              :                       || XINT (symbol, 1) == UNSPEC_PCREL
   17981              :                       || XINT (symbol, 1) == UNSPEC_GOTNTPOFF)))
   17982     24582166 :             return true;
   17983              :         }
   17984              :     }
   17985              :   return false;
   17986              : }
   17987              : 
   17988              : /* Calculate the length of the memory address in the instruction encoding.
   17989              :    Includes addr32 prefix, does not include the one-byte modrm, opcode,
   17990              :    or other prefixes.  We never generate addr32 prefix for LEA insn.  */
   17991              : 
   17992              : int
   17993    283158989 : memory_address_length (rtx addr, bool lea)
   17994              : {
   17995    283158989 :   struct ix86_address parts;
   17996    283158989 :   rtx base, index, disp;
   17997    283158989 :   int len;
   17998    283158989 :   int ok;
   17999              : 
   18000    283158989 :   if (GET_CODE (addr) == PRE_DEC
   18001    274468710 :       || GET_CODE (addr) == POST_INC
   18002    269884809 :       || GET_CODE (addr) == PRE_MODIFY
   18003    269884809 :       || GET_CODE (addr) == POST_MODIFY)
   18004              :     return 0;
   18005              : 
   18006    269884809 :   ok = ix86_decompose_address (addr, &parts);
   18007    269884809 :   gcc_assert (ok);
   18008              : 
   18009    269884809 :   len = (parts.seg == ADDR_SPACE_GENERIC) ? 0 : 1;
   18010              : 
   18011              :   /*  If this is not LEA instruction, add the length of addr32 prefix.  */
   18012    231039225 :   if (TARGET_64BIT && !lea
   18013    472255391 :       && (SImode_address_operand (addr, VOIDmode)
   18014    202370283 :           || (parts.base && GET_MODE (parts.base) == SImode)
   18015    202359624 :           || (parts.index && GET_MODE (parts.index) == SImode)))
   18016        10958 :     len++;
   18017              : 
   18018    269884809 :   base = parts.base;
   18019    269884809 :   index = parts.index;
   18020    269884809 :   disp = parts.disp;
   18021              : 
   18022    269884809 :   if (base && SUBREG_P (base))
   18023            2 :     base = SUBREG_REG (base);
   18024    269884809 :   if (index && SUBREG_P (index))
   18025            0 :     index = SUBREG_REG (index);
   18026              : 
   18027    269884809 :   gcc_assert (base == NULL_RTX || REG_P (base));
   18028    269884809 :   gcc_assert (index == NULL_RTX || REG_P (index));
   18029              : 
   18030              :   /* Rule of thumb:
   18031              :        - esp as the base always wants an index,
   18032              :        - ebp as the base always wants a displacement,
   18033              :        - r12 as the base always wants an index,
   18034              :        - r13 as the base always wants a displacement.  */
   18035              : 
   18036              :   /* Register Indirect.  */
   18037    269884809 :   if (base && !index && !disp)
   18038              :     {
   18039              :       /* esp (for its index) and ebp (for its displacement) need
   18040              :          the two-byte modrm form.  Similarly for r12 and r13 in 64-bit
   18041              :          code.  */
   18042     17364732 :       if (base == arg_pointer_rtx
   18043     17364732 :           || base == frame_pointer_rtx
   18044     17364732 :           || REGNO (base) == SP_REG
   18045     10436614 :           || REGNO (base) == BP_REG
   18046     10436614 :           || REGNO (base) == R12_REG
   18047     27331855 :           || REGNO (base) == R13_REG)
   18048      7397609 :         len++;
   18049              :     }
   18050              : 
   18051              :   /* Direct Addressing.  In 64-bit mode mod 00 r/m 5
   18052              :      is not disp32, but disp32(%rip), so for disp32
   18053              :      SIB byte is needed, unless print_operand_address
   18054              :      optimizes it into disp32(%rip) or (%rip) is implied
   18055              :      by UNSPEC.  */
   18056    252520077 :   else if (disp && !base && !index)
   18057              :     {
   18058     26012124 :       len += 4;
   18059     26012124 :       if (!ix86_rip_relative_addr_p (&parts))
   18060      1839976 :         len++;
   18061              :     }
   18062              :   else
   18063              :     {
   18064              :       /* Find the length of the displacement constant.  */
   18065    226507953 :       if (disp)
   18066              :         {
   18067    222479335 :           if (base && satisfies_constraint_K (disp))
   18068    130149122 :             len += 1;
   18069              :           else
   18070     92330213 :             len += 4;
   18071              :         }
   18072              :       /* ebp always wants a displacement.  Similarly r13.  */
   18073      4028618 :       else if (base && (REGNO (base) == BP_REG || REGNO (base) == R13_REG))
   18074         8604 :         len++;
   18075              : 
   18076              :       /* An index requires the two-byte modrm form....  */
   18077    226507953 :       if (index
   18078              :           /* ...like esp (or r12), which always wants an index.  */
   18079    216168070 :           || base == arg_pointer_rtx
   18080    216168070 :           || base == frame_pointer_rtx
   18081    442676023 :           || (base && (REGNO (base) == SP_REG || REGNO (base) == R12_REG)))
   18082    162831645 :         len++;
   18083              :     }
   18084              : 
   18085              :   return len;
   18086              : }
   18087              : 
   18088              : /* Compute default value for "length_immediate" attribute.  When SHORTFORM
   18089              :    is set, expect that insn have 8bit immediate alternative.  */
   18090              : int
   18091    328068575 : ix86_attr_length_immediate_default (rtx_insn *insn, bool shortform)
   18092              : {
   18093    328068575 :   int len = 0;
   18094    328068575 :   int i;
   18095    328068575 :   extract_insn_cached (insn);
   18096   1023757138 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   18097    695688563 :     if (CONSTANT_P (recog_data.operand[i]))
   18098              :       {
   18099    141733199 :         enum attr_mode mode = get_attr_mode (insn);
   18100              : 
   18101    141733199 :         gcc_assert (!len);
   18102    141733199 :         if (shortform && CONST_INT_P (recog_data.operand[i]))
   18103              :           {
   18104     38886029 :             HOST_WIDE_INT ival = INTVAL (recog_data.operand[i]);
   18105     38886029 :             switch (mode)
   18106              :               {
   18107      1461144 :               case MODE_QI:
   18108      1461144 :                 len = 1;
   18109      1461144 :                 continue;
   18110       449312 :               case MODE_HI:
   18111       449312 :                 ival = trunc_int_for_mode (ival, HImode);
   18112       449312 :                 break;
   18113     16260604 :               case MODE_SI:
   18114     16260604 :                 ival = trunc_int_for_mode (ival, SImode);
   18115     16260604 :                 break;
   18116              :               default:
   18117              :                 break;
   18118              :               }
   18119     37424885 :             if (IN_RANGE (ival, -128, 127))
   18120              :               {
   18121     33234032 :                 len = 1;
   18122     33234032 :                 continue;
   18123              :               }
   18124              :           }
   18125    107038023 :         switch (mode)
   18126              :           {
   18127              :           case MODE_QI:
   18128              :             len = 1;
   18129              :             break;
   18130              :           case MODE_HI:
   18131    695688563 :             len = 2;
   18132              :             break;
   18133              :           case MODE_SI:
   18134    101409773 :             len = 4;
   18135              :             break;
   18136              :           /* Immediates for DImode instructions are encoded
   18137              :              as 32bit sign extended values.  */
   18138              :           case MODE_DI:
   18139    101409773 :             len = 4;
   18140              :             break;
   18141            0 :           default:
   18142            0 :             fatal_insn ("unknown insn mode", insn);
   18143              :         }
   18144              :       }
   18145    328068575 :   return len;
   18146              : }
   18147              : 
   18148              : /* Compute default value for "length_address" attribute.  */
   18149              : int
   18150    461590338 : ix86_attr_length_address_default (rtx_insn *insn)
   18151              : {
   18152    461590338 :   int i;
   18153              : 
   18154    461590338 :   if (get_attr_type (insn) == TYPE_LEA)
   18155              :     {
   18156     31432403 :       rtx set = PATTERN (insn), addr;
   18157              : 
   18158     31432403 :       if (GET_CODE (set) == PARALLEL)
   18159        87040 :         set = XVECEXP (set, 0, 0);
   18160              : 
   18161     31432403 :       gcc_assert (GET_CODE (set) == SET);
   18162              : 
   18163     31432403 :       addr = SET_SRC (set);
   18164              : 
   18165     31432403 :       return memory_address_length (addr, true);
   18166              :     }
   18167              : 
   18168    430157935 :   extract_insn_cached (insn);
   18169    989188582 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   18170              :     {
   18171    810471485 :       rtx op = recog_data.operand[i];
   18172    810471485 :       if (MEM_P (op))
   18173              :         {
   18174    251723665 :           constrain_operands_cached (insn, reload_completed);
   18175    251723665 :           if (which_alternative != -1)
   18176              :             {
   18177    251723665 :               const char *constraints = recog_data.constraints[i];
   18178    251723665 :               int alt = which_alternative;
   18179              : 
   18180    399788910 :               while (*constraints == '=' || *constraints == '+')
   18181    148065245 :                 constraints++;
   18182   1144542635 :               while (alt-- > 0)
   18183   2186599341 :                 while (*constraints++ != ',')
   18184              :                   ;
   18185              :               /* Skip ignored operands.  */
   18186    251723665 :               if (*constraints == 'X')
   18187       282827 :                 continue;
   18188              :             }
   18189              : 
   18190    251440838 :           int len = memory_address_length (XEXP (op, 0), false);
   18191              : 
   18192              :           /* Account for segment prefix for non-default addr spaces.  */
   18193    264402624 :           if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)))
   18194       784144 :             len++;
   18195              : 
   18196              :           return len;
   18197              :         }
   18198              :     }
   18199              :   return 0;
   18200              : }
   18201              : 
   18202              : /* Compute default value for "length_vex" attribute. It includes
   18203              :    2 or 3 byte VEX prefix and 1 opcode byte.  */
   18204              : 
   18205              : int
   18206      5078561 : ix86_attr_length_vex_default (rtx_insn *insn, bool has_0f_opcode,
   18207              :                               bool has_vex_w)
   18208              : {
   18209      5078561 :   int i, reg_only = 2 + 1;
   18210      5078561 :   bool has_mem = false;
   18211              : 
   18212              :   /* Only 0f opcode can use 2 byte VEX prefix and  VEX W bit uses 3
   18213              :      byte VEX prefix.  */
   18214      5078561 :   if (!has_0f_opcode || has_vex_w)
   18215              :     return 3 + 1;
   18216              : 
   18217              :  /* We can always use 2 byte VEX prefix in 32bit.  */
   18218      4634662 :   if (!TARGET_64BIT)
   18219              :     return 2 + 1;
   18220              : 
   18221      3567683 :   extract_insn_cached (insn);
   18222              : 
   18223     11215827 :   for (i = recog_data.n_operands - 1; i >= 0; --i)
   18224      7963393 :     if (REG_P (recog_data.operand[i]))
   18225              :       {
   18226              :         /* REX.W bit uses 3 byte VEX prefix.
   18227              :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   18228      5246635 :         if (GET_MODE (recog_data.operand[i]) == DImode
   18229      5246635 :             && GENERAL_REG_P (recog_data.operand[i]))
   18230              :           return 3 + 1;
   18231              : 
   18232              :         /* REX.B bit requires 3-byte VEX. Right here we don't know which
   18233              :            operand will be encoded using VEX.B, so be conservative.
   18234              :            REX2 with vex use extended EVEX prefix length is 4-byte.  */
   18235      5234206 :         if (REX_INT_REGNO_P (recog_data.operand[i])
   18236      5234206 :             || REX2_INT_REGNO_P (recog_data.operand[i])
   18237      5234206 :             || REX_SSE_REGNO_P (recog_data.operand[i]))
   18238            0 :           reg_only = 3 + 1;
   18239              :       }
   18240      2716758 :     else if (MEM_P (recog_data.operand[i]))
   18241              :       {
   18242              :         /* REX2.X or REX2.B bits use 3 byte VEX prefix.  */
   18243      2045434 :         if (x86_extended_rex2reg_mentioned_p (recog_data.operand[i]))
   18244              :           return 4;
   18245              : 
   18246              :         /* REX.X or REX.B bits use 3 byte VEX prefix.  */
   18247      2045039 :         if (x86_extended_reg_mentioned_p (recog_data.operand[i]))
   18248              :           return 3 + 1;
   18249              : 
   18250              :         has_mem = true;
   18251              :       }
   18252              : 
   18253      3252434 :   return has_mem ? 2 + 1 : reg_only;
   18254              : }
   18255              : 
   18256              : 
   18257              : static bool
   18258              : ix86_class_likely_spilled_p (reg_class_t);
   18259              : 
   18260              : /* Returns true if lhs of insn is HW function argument register and set up
   18261              :    is_spilled to true if it is likely spilled HW register.  */
   18262              : static bool
   18263         1154 : insn_is_function_arg (rtx insn, bool* is_spilled)
   18264              : {
   18265         1154 :   rtx dst;
   18266              : 
   18267         1154 :   if (!NONDEBUG_INSN_P (insn))
   18268              :     return false;
   18269              :   /* Call instructions are not movable, ignore it.  */
   18270         1154 :   if (CALL_P (insn))
   18271              :     return false;
   18272         1080 :   insn = PATTERN (insn);
   18273         1080 :   if (GET_CODE (insn) == PARALLEL)
   18274           73 :     insn = XVECEXP (insn, 0, 0);
   18275         1080 :   if (GET_CODE (insn) != SET)
   18276              :     return false;
   18277         1080 :   dst = SET_DEST (insn);
   18278          984 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   18279         1957 :       && ix86_function_arg_regno_p (REGNO (dst)))
   18280              :     {
   18281              :       /* Is it likely spilled HW register?  */
   18282          877 :       if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
   18283          877 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
   18284          833 :         *is_spilled = true;
   18285              :       return true;
   18286              :     }
   18287              :   return false;
   18288              : }
   18289              : 
   18290              : /* Add output dependencies for chain of function adjacent arguments if only
   18291              :    there is a move to likely spilled HW register.  Return first argument
   18292              :    if at least one dependence was added or NULL otherwise.  */
   18293              : static rtx_insn *
   18294          419 : add_parameter_dependencies (rtx_insn *call, rtx_insn *head)
   18295              : {
   18296          419 :   rtx_insn *insn;
   18297          419 :   rtx_insn *last = call;
   18298          419 :   rtx_insn *first_arg = NULL;
   18299          419 :   bool is_spilled = false;
   18300              : 
   18301          419 :   head = PREV_INSN (head);
   18302              : 
   18303              :   /* Find nearest to call argument passing instruction.  */
   18304          419 :   while (true)
   18305              :     {
   18306          419 :       last = PREV_INSN (last);
   18307          419 :       if (last == head)
   18308              :         return NULL;
   18309          419 :       if (!NONDEBUG_INSN_P (last))
   18310            0 :         continue;
   18311          419 :       if (insn_is_function_arg (last, &is_spilled))
   18312              :         break;
   18313              :       return NULL;
   18314              :     }
   18315              : 
   18316              :   first_arg = last;
   18317         1058 :   while (true)
   18318              :     {
   18319         1058 :       insn = PREV_INSN (last);
   18320         1058 :       if (!INSN_P (insn))
   18321              :         break;
   18322          960 :       if (insn == head)
   18323              :         break;
   18324          916 :       if (!NONDEBUG_INSN_P (insn))
   18325              :         {
   18326          181 :           last = insn;
   18327          181 :           continue;
   18328              :         }
   18329          735 :       if (insn_is_function_arg (insn, &is_spilled))
   18330              :         {
   18331              :           /* Add output dependence between two function arguments if chain
   18332              :              of output arguments contains likely spilled HW registers.  */
   18333          466 :           if (is_spilled)
   18334          466 :             add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   18335          647 :           first_arg = last = insn;
   18336              :         }
   18337              :       else
   18338              :         break;
   18339              :     }
   18340          411 :   if (!is_spilled)
   18341            0 :     return NULL;
   18342              :   return first_arg;
   18343              : }
   18344              : 
   18345              : /* Add output or anti dependency from insn to first_arg to restrict its code
   18346              :    motion.  */
   18347              : static void
   18348         2336 : avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn)
   18349              : {
   18350         2336 :   rtx set;
   18351         2336 :   rtx tmp;
   18352              : 
   18353         2336 :   set = single_set (insn);
   18354         2336 :   if (!set)
   18355              :     return;
   18356         1452 :   tmp = SET_DEST (set);
   18357         1452 :   if (REG_P (tmp))
   18358              :     {
   18359              :       /* Add output dependency to the first function argument.  */
   18360         1257 :       add_dependence (first_arg, insn, REG_DEP_OUTPUT);
   18361         1257 :       return;
   18362              :     }
   18363              :   /* Add anti dependency.  */
   18364          195 :   add_dependence (first_arg, insn, REG_DEP_ANTI);
   18365              : }
   18366              : 
   18367              : /* Avoid cross block motion of function argument through adding dependency
   18368              :    from the first non-jump instruction in bb.  */
   18369              : static void
   18370           68 : add_dependee_for_func_arg (rtx_insn *arg, basic_block bb)
   18371              : {
   18372           68 :   rtx_insn *insn = BB_END (bb);
   18373              : 
   18374          134 :   while (insn)
   18375              :     {
   18376          134 :       if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
   18377              :         {
   18378           67 :           rtx set = single_set (insn);
   18379           67 :           if (set)
   18380              :             {
   18381           67 :               avoid_func_arg_motion (arg, insn);
   18382           67 :               return;
   18383              :             }
   18384              :         }
   18385           67 :       if (insn == BB_HEAD (bb))
   18386              :         return;
   18387           66 :       insn = PREV_INSN (insn);
   18388              :     }
   18389              : }
   18390              : 
   18391              : /* Hook for pre-reload schedule - avoid motion of function arguments
   18392              :    passed in likely spilled HW registers.  */
   18393              : static void
   18394     10616742 : ix86_dependencies_evaluation_hook (rtx_insn *head, rtx_insn *tail)
   18395              : {
   18396     10616742 :   rtx_insn *insn;
   18397     10616742 :   rtx_insn *first_arg = NULL;
   18398     10616742 :   if (reload_completed)
   18399              :     return;
   18400         2276 :   while (head != tail && DEBUG_INSN_P (head))
   18401          786 :     head = NEXT_INSN (head);
   18402        10860 :   for (insn = tail; insn != head; insn = PREV_INSN (insn))
   18403         9509 :     if (INSN_P (insn) && CALL_P (insn))
   18404              :       {
   18405          419 :         first_arg = add_parameter_dependencies (insn, head);
   18406          419 :         if (first_arg)
   18407              :           {
   18408              :             /* Add dependee for first argument to predecessors if only
   18409              :                region contains more than one block.  */
   18410          411 :             basic_block bb =  BLOCK_FOR_INSN (insn);
   18411          411 :             int rgn = CONTAINING_RGN (bb->index);
   18412          411 :             int nr_blks = RGN_NR_BLOCKS (rgn);
   18413              :             /* Skip trivial regions and region head blocks that can have
   18414              :                predecessors outside of region.  */
   18415          411 :             if (nr_blks > 1 && BLOCK_TO_BB (bb->index) != 0)
   18416              :               {
   18417           67 :                 edge e;
   18418           67 :                 edge_iterator ei;
   18419              : 
   18420              :                 /* Regions are SCCs with the exception of selective
   18421              :                    scheduling with pipelining of outer blocks enabled.
   18422              :                    So also check that immediate predecessors of a non-head
   18423              :                    block are in the same region.  */
   18424          137 :                 FOR_EACH_EDGE (e, ei, bb->preds)
   18425              :                   {
   18426              :                     /* Avoid creating of loop-carried dependencies through
   18427              :                        using topological ordering in the region.  */
   18428           70 :                     if (rgn == CONTAINING_RGN (e->src->index)
   18429           69 :                         && BLOCK_TO_BB (bb->index) > BLOCK_TO_BB (e->src->index))
   18430           68 :                       add_dependee_for_func_arg (first_arg, e->src);
   18431              :                   }
   18432              :               }
   18433          411 :             insn = first_arg;
   18434          411 :             if (insn == head)
   18435              :               break;
   18436              :           }
   18437              :       }
   18438         9090 :     else if (first_arg)
   18439         2269 :       avoid_func_arg_motion (first_arg, insn);
   18440              : }
   18441              : 
   18442              : /* Hook for pre-reload schedule - set priority of moves from likely spilled
   18443              :    HW registers to maximum, to schedule them at soon as possible. These are
   18444              :    moves from function argument registers at the top of the function entry
   18445              :    and moves from function return value registers after call.  */
   18446              : static int
   18447    115934411 : ix86_adjust_priority (rtx_insn *insn, int priority)
   18448              : {
   18449    115934411 :   rtx set;
   18450              : 
   18451    115934411 :   if (reload_completed)
   18452              :     return priority;
   18453              : 
   18454        14941 :   if (!NONDEBUG_INSN_P (insn))
   18455              :     return priority;
   18456              : 
   18457        12856 :   set = single_set (insn);
   18458        12856 :   if (set)
   18459              :     {
   18460        12227 :       rtx tmp = SET_SRC (set);
   18461        12227 :       if (REG_P (tmp)
   18462         2548 :           && HARD_REGISTER_P (tmp)
   18463          504 :           && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
   18464        12227 :           && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
   18465          453 :         return current_sched_info->sched_max_insns_priority;
   18466              :     }
   18467              : 
   18468              :   return priority;
   18469              : }
   18470              : 
   18471              : /* Prepare for scheduling pass.  */
   18472              : static void
   18473       987265 : ix86_sched_init_global (FILE *, int, int)
   18474              : {
   18475              :   /* Install scheduling hooks for current CPU.  Some of these hooks are used
   18476              :      in time-critical parts of the scheduler, so we only set them up when
   18477              :      they are actually used.  */
   18478       987265 :   switch (ix86_tune)
   18479              :     {
   18480       939476 :     case PROCESSOR_CORE2:
   18481       939476 :     case PROCESSOR_NEHALEM:
   18482       939476 :     case PROCESSOR_SANDYBRIDGE:
   18483       939476 :     case PROCESSOR_HASWELL:
   18484       939476 :     case PROCESSOR_TREMONT:
   18485       939476 :     case PROCESSOR_ALDERLAKE:
   18486       939476 :     case PROCESSOR_GENERIC:
   18487              :       /* Do not perform multipass scheduling for pre-reload schedule
   18488              :          to save compile time.  */
   18489       939476 :       if (reload_completed)
   18490              :         {
   18491       938987 :           ix86_core2i7_init_hooks ();
   18492       938987 :           break;
   18493              :         }
   18494              :       /* Fall through.  */
   18495        48278 :     default:
   18496        48278 :       targetm.sched.dfa_post_advance_cycle = NULL;
   18497        48278 :       targetm.sched.first_cycle_multipass_init = NULL;
   18498        48278 :       targetm.sched.first_cycle_multipass_begin = NULL;
   18499        48278 :       targetm.sched.first_cycle_multipass_issue = NULL;
   18500        48278 :       targetm.sched.first_cycle_multipass_backtrack = NULL;
   18501        48278 :       targetm.sched.first_cycle_multipass_end = NULL;
   18502        48278 :       targetm.sched.first_cycle_multipass_fini = NULL;
   18503        48278 :       break;
   18504              :     }
   18505       987265 : }
   18506              : 
   18507              : 
   18508              : /* Implement TARGET_STATIC_RTX_ALIGNMENT.  */
   18509              : 
   18510              : static HOST_WIDE_INT
   18511       734346 : ix86_static_rtx_alignment (machine_mode mode)
   18512              : {
   18513       734346 :   if (mode == DFmode)
   18514              :     return 64;
   18515              :   if (ALIGN_MODE_128 (mode))
   18516       160555 :     return MAX (128, GET_MODE_ALIGNMENT (mode));
   18517       487431 :   return GET_MODE_ALIGNMENT (mode);
   18518              : }
   18519              : 
   18520              : /* Implement TARGET_CONSTANT_ALIGNMENT.  */
   18521              : 
   18522              : static HOST_WIDE_INT
   18523      6912364 : ix86_constant_alignment (const_tree exp, HOST_WIDE_INT align)
   18524              : {
   18525      6912364 :   if (TREE_CODE (exp) == REAL_CST || TREE_CODE (exp) == VECTOR_CST
   18526              :       || TREE_CODE (exp) == INTEGER_CST)
   18527              :     {
   18528       374728 :       machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
   18529       374728 :       HOST_WIDE_INT mode_align = ix86_static_rtx_alignment (mode);
   18530       374728 :       return MAX (mode_align, align);
   18531              :     }
   18532      6393490 :   else if (!optimize_size && TREE_CODE (exp) == STRING_CST
   18533      9642489 :            && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
   18534              :     return BITS_PER_WORD;
   18535              : 
   18536              :   return align;
   18537              : }
   18538              : 
   18539              : /* Implement TARGET_EMPTY_RECORD_P.  */
   18540              : 
   18541              : static bool
   18542   1528922169 : ix86_is_empty_record (const_tree type)
   18543              : {
   18544   1528922169 :   if (!TARGET_64BIT)
   18545              :     return false;
   18546   1498338509 :   return default_is_empty_record (type);
   18547              : }
   18548              : 
   18549              : /* Implement TARGET_WARN_PARAMETER_PASSING_ABI.  */
   18550              : 
   18551              : static void
   18552     15772807 : ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
   18553              : {
   18554     15772807 :   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   18555              : 
   18556     15772807 :   if (!cum->warn_empty)
   18557              :     return;
   18558              : 
   18559     13254601 :   if (!TYPE_EMPTY_P (type))
   18560              :     return;
   18561              : 
   18562              :   /* Don't warn if the function isn't visible outside of the TU.  */
   18563        15423 :   if (cum->decl && !TREE_PUBLIC (cum->decl))
   18564              :     return;
   18565              : 
   18566        13935 :   tree decl = cum->decl;
   18567        13935 :   if (!decl)
   18568              :     /* If we don't know the target, look at the current TU.  */
   18569           39 :     decl = current_function_decl;
   18570              : 
   18571        13935 :   const_tree ctx = get_ultimate_context (decl);
   18572        13935 :   if (ctx == NULL_TREE
   18573        27836 :       || !TRANSLATION_UNIT_WARN_EMPTY_P (ctx))
   18574              :     return;
   18575              : 
   18576              :   /* If the actual size of the type is zero, then there is no change
   18577              :      in how objects of this size are passed.  */
   18578           72 :   if (int_size_in_bytes (type) == 0)
   18579              :     return;
   18580              : 
   18581           66 :   warning (OPT_Wabi, "empty class %qT parameter passing ABI "
   18582              :            "changes in %<-fabi-version=12%> (GCC 8)", type);
   18583              : 
   18584              :   /* Only warn once.  */
   18585           66 :   cum->warn_empty = false;
   18586              : }
   18587              : 
   18588              : /* This hook returns name of multilib ABI.  */
   18589              : 
   18590              : static const char *
   18591      3487215 : ix86_get_multilib_abi_name (void)
   18592              : {
   18593      3487215 :   if (!(TARGET_64BIT_P (ix86_isa_flags)))
   18594              :     return "i386";
   18595      3443043 :   else if (TARGET_X32_P (ix86_isa_flags))
   18596              :     return "x32";
   18597              :   else
   18598      3443043 :     return "x86_64";
   18599              : }
   18600              : 
   18601              : /* Compute the alignment for a variable for Intel MCU psABI.  TYPE is
   18602              :    the data type, and ALIGN is the alignment that the object would
   18603              :    ordinarily have.  */
   18604              : 
   18605              : static int
   18606            0 : iamcu_alignment (tree type, int align)
   18607              : {
   18608            0 :   machine_mode mode;
   18609              : 
   18610            0 :   if (align < 32 || TYPE_USER_ALIGN (type))
   18611              :     return align;
   18612              : 
   18613              :   /* Intel MCU psABI specifies scalar types > 4 bytes aligned to 4
   18614              :      bytes.  */
   18615            0 :   type = strip_array_types (type);
   18616            0 :   if (TYPE_ATOMIC (type))
   18617              :     return align;
   18618              : 
   18619            0 :   mode = TYPE_MODE (type);
   18620            0 :   switch (GET_MODE_CLASS (mode))
   18621              :     {
   18622              :     case MODE_INT:
   18623              :     case MODE_COMPLEX_INT:
   18624              :     case MODE_COMPLEX_FLOAT:
   18625              :     case MODE_FLOAT:
   18626              :     case MODE_DECIMAL_FLOAT:
   18627              :       return 32;
   18628              :     default:
   18629              :       return align;
   18630              :     }
   18631              : }
   18632              : 
   18633              : /* Compute the alignment for a static variable.
   18634              :    TYPE is the data type, and ALIGN is the alignment that
   18635              :    the object would ordinarily have.  The value of this function is used
   18636              :    instead of that alignment to align the object.  */
   18637              : 
   18638              : int
   18639     12146474 : ix86_data_alignment (tree type, unsigned int align, bool opt)
   18640              : {
   18641              :   /* GCC 4.8 and earlier used to incorrectly assume this alignment even
   18642              :      for symbols from other compilation units or symbols that don't need
   18643              :      to bind locally.  In order to preserve some ABI compatibility with
   18644              :      those compilers, ensure we don't decrease alignment from what we
   18645              :      used to assume.  */
   18646              : 
   18647     12146474 :   unsigned int max_align_compat = MIN (256, MAX_OFILE_ALIGNMENT);
   18648              : 
   18649              :   /* A data structure, equal or greater than the size of a cache line
   18650              :      (64 bytes in the Pentium 4 and other recent Intel processors, including
   18651              :      processors based on Intel Core microarchitecture) should be aligned
   18652              :      so that its base address is a multiple of a cache line size.  */
   18653              : 
   18654     12146474 :   unsigned int max_align
   18655     12146474 :     = MIN ((unsigned) ix86_tune_cost->prefetch_block * 8, MAX_OFILE_ALIGNMENT);
   18656              : 
   18657     14736818 :   if (max_align < BITS_PER_WORD)
   18658            0 :     max_align = BITS_PER_WORD;
   18659              : 
   18660     12146474 :   switch (ix86_align_data_type)
   18661              :     {
   18662     12146474 :     case ix86_align_data_type_abi: opt = false; break;
   18663     12146454 :     case ix86_align_data_type_compat: max_align = BITS_PER_WORD; break;
   18664              :     case ix86_align_data_type_cacheline: break;
   18665              :     }
   18666              : 
   18667     12146474 :   if (TARGET_IAMCU)
   18668            0 :     align = iamcu_alignment (type, align);
   18669              : 
   18670     12146474 :   if (opt
   18671      5835763 :       && AGGREGATE_TYPE_P (type)
   18672      3741616 :       && TYPE_SIZE (type)
   18673     15888038 :       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
   18674              :     {
   18675      6778218 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align_compat)
   18676      3741564 :           && align < max_align_compat)
   18677       704910 :         align = max_align_compat;
   18678      7418975 :       if (wi::geu_p (wi::to_wide (TYPE_SIZE (type)), max_align)
   18679      3741564 :           && align < max_align)
   18680        64153 :         align = max_align;
   18681              :     }
   18682              : 
   18683              :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18684              :      to 16byte boundary.  */
   18685     12146474 :   if (TARGET_64BIT)
   18686              :     {
   18687      5014780 :       if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
   18688      3301013 :           && TYPE_SIZE (type)
   18689      3300951 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18690     11008176 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18691     11633225 :           && align < 128)
   18692       625049 :         return 128;
   18693              :     }
   18694              : 
   18695     11521425 :   if (!opt)
   18696      6111585 :     return align;
   18697              : 
   18698      5409840 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18699              :     {
   18700      1113461 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18701              :         return 64;
   18702      1113461 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18703              :         return 128;
   18704              :     }
   18705      4296379 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18706              :     {
   18707              : 
   18708        13017 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18709              :         return 64;
   18710        13017 :       if ((TYPE_MODE (type) == XCmode
   18711        13017 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18712              :         return 128;
   18713              :     }
   18714      4283362 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18715      4283362 :            && TYPE_FIELDS (type))
   18716              :     {
   18717      2200461 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18718              :         return 64;
   18719      2200461 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18720              :         return 128;
   18721              :     }
   18722      2082901 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18723              :            || TREE_CODE (type) == INTEGER_TYPE)
   18724              :     {
   18725      1927026 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18726              :         return 64;
   18727      1927026 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18728              :         return 128;
   18729              :     }
   18730              : 
   18731      5409725 :   return align;
   18732              : }
   18733              : 
   18734              : /* Implement TARGET_LOWER_LOCAL_DECL_ALIGNMENT.  */
   18735              : static void
   18736     33118024 : ix86_lower_local_decl_alignment (tree decl)
   18737              : {
   18738     33118024 :   unsigned int new_align = ix86_local_alignment (decl, VOIDmode,
   18739     33118024 :                                                  DECL_ALIGN (decl), true);
   18740     33118024 :   if (new_align < DECL_ALIGN (decl))
   18741            0 :     SET_DECL_ALIGN (decl, new_align);
   18742     33118024 : }
   18743              : 
   18744              : /* Compute the alignment for a local variable or a stack slot.  EXP is
   18745              :    the data type or decl itself, MODE is the widest mode available and
   18746              :    ALIGN is the alignment that the object would ordinarily have.  The
   18747              :    value of this macro is used instead of that alignment to align the
   18748              :    object.  */
   18749              : 
   18750              : unsigned int
   18751     57659948 : ix86_local_alignment (tree exp, machine_mode mode,
   18752              :                       unsigned int align, bool may_lower)
   18753              : {
   18754     57659948 :   tree type, decl;
   18755              : 
   18756     57659948 :   if (exp && DECL_P (exp))
   18757              :     {
   18758     55434952 :       type = TREE_TYPE (exp);
   18759     55434952 :       decl = exp;
   18760              :     }
   18761              :   else
   18762              :     {
   18763              :       type = exp;
   18764              :       decl = NULL;
   18765              :     }
   18766              : 
   18767              :   /* Don't do dynamic stack realignment for long long objects with
   18768              :      -mpreferred-stack-boundary=2.  */
   18769     57659948 :   if (may_lower
   18770     33118024 :       && !TARGET_64BIT
   18771       250492 :       && align == 64
   18772        38970 :       && ix86_preferred_stack_boundary < 64
   18773            0 :       && (mode == DImode || (type && TYPE_MODE (type) == DImode))
   18774            0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18775            0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18776     57659948 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18777              :     align = 32;
   18778              : 
   18779              :   /* If TYPE is NULL, we are allocating a stack slot for caller-save
   18780              :      register in MODE.  We will return the largest alignment of XF
   18781              :      and DF.  */
   18782     57659948 :   if (!type)
   18783              :     {
   18784      1458163 :       if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
   18785         1452 :         align = GET_MODE_ALIGNMENT (DFmode);
   18786              :       return align;
   18787              :     }
   18788              : 
   18789              :   /* Don't increase alignment for Intel MCU psABI.  */
   18790     56201785 :   if (TARGET_IAMCU)
   18791              :     return align;
   18792              : 
   18793              :   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
   18794              :      to 16byte boundary.  Exact wording is:
   18795              : 
   18796              :      An array uses the same alignment as its elements, except that a local or
   18797              :      global array variable of length at least 16 bytes or
   18798              :      a C99 variable-length array variable always has alignment of at least 16 bytes.
   18799              : 
   18800              :      This was added to allow use of aligned SSE instructions at arrays.  This
   18801              :      rule is meant for static storage (where compiler cannot do the analysis
   18802              :      by itself).  We follow it for automatic variables only when convenient.
   18803              :      We fully control everything in the function compiled and functions from
   18804              :      other unit cannot rely on the alignment.
   18805              : 
   18806              :      Exclude va_list type.  It is the common case of local array where
   18807              :      we cannot benefit from the alignment.
   18808              : 
   18809              :      TODO: Probably one should optimize for size only when var is not escaping.  */
   18810     52157057 :   if (TARGET_64BIT && optimize_function_for_speed_p (cfun)
   18811    107757520 :       && TARGET_SSE)
   18812              :     {
   18813     51515652 :       if (AGGREGATE_TYPE_P (type)
   18814     14244570 :           && (va_list_type_node == NULL_TREE
   18815     14244570 :               || (TYPE_MAIN_VARIANT (type)
   18816     14244570 :                   != TYPE_MAIN_VARIANT (va_list_type_node)))
   18817     14107639 :           && TYPE_SIZE (type)
   18818     14107639 :           && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
   18819     53533210 :           && wi::geu_p (wi::to_wide (TYPE_SIZE (type)), 128)
   18820     62111737 :           && align < 128)
   18821      8578527 :         return 128;
   18822              :     }
   18823     47623258 :   if (TREE_CODE (type) == ARRAY_TYPE)
   18824              :     {
   18825      1392256 :       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
   18826              :         return 64;
   18827      1392256 :       if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (type))) && align < 128)
   18828              :         return 128;
   18829              :     }
   18830     46231002 :   else if (TREE_CODE (type) == COMPLEX_TYPE)
   18831              :     {
   18832       232048 :       if (TYPE_MODE (type) == DCmode && align < 64)
   18833              :         return 64;
   18834       232048 :       if ((TYPE_MODE (type) == XCmode
   18835       232048 :            || TYPE_MODE (type) == TCmode) && align < 128)
   18836              :         return 128;
   18837              :     }
   18838     45998954 :   else if (RECORD_OR_UNION_TYPE_P (type)
   18839     45998954 :            && TYPE_FIELDS (type))
   18840              :     {
   18841      7579486 :       if (DECL_MODE (TYPE_FIELDS (type)) == DFmode && align < 64)
   18842              :         return 64;
   18843      7574053 :       if (ALIGN_MODE_128 (DECL_MODE (TYPE_FIELDS (type))) && align < 128)
   18844              :         return 128;
   18845              :     }
   18846     38419468 :   else if (SCALAR_FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type)
   18847              :            || TREE_CODE (type) == INTEGER_TYPE)
   18848              :     {
   18849              : 
   18850     31372542 :       if (TYPE_MODE (type) == DFmode && align < 64)
   18851              :         return 64;
   18852     31372542 :       if (ALIGN_MODE_128 (TYPE_MODE (type)) && align < 128)
   18853              :         return 128;
   18854              :     }
   18855              :   return align;
   18856              : }
   18857              : 
   18858              : /* Compute the minimum required alignment for dynamic stack realignment
   18859              :    purposes for a local variable, parameter or a stack slot.  EXP is
   18860              :    the data type or decl itself, MODE is its mode and ALIGN is the
   18861              :    alignment that the object would ordinarily have.  */
   18862              : 
   18863              : unsigned int
   18864     49584323 : ix86_minimum_alignment (tree exp, machine_mode mode,
   18865              :                         unsigned int align)
   18866              : {
   18867     49584323 :   tree type, decl;
   18868              : 
   18869     49584323 :   if (exp && DECL_P (exp))
   18870              :     {
   18871     15719502 :       type = TREE_TYPE (exp);
   18872     15719502 :       decl = exp;
   18873              :     }
   18874              :   else
   18875              :     {
   18876              :       type = exp;
   18877              :       decl = NULL;
   18878              :     }
   18879              : 
   18880     49584323 :   if (TARGET_64BIT || align != 64 || ix86_preferred_stack_boundary >= 64)
   18881              :     return align;
   18882              : 
   18883              :   /* Don't do dynamic stack realignment for long long objects with
   18884              :      -mpreferred-stack-boundary=2.  */
   18885            0 :   if ((mode == DImode || (type && TYPE_MODE (type) == DImode))
   18886            0 :       && (!type || (!TYPE_USER_ALIGN (type)
   18887            0 :                     && !TYPE_ATOMIC (strip_array_types (type))))
   18888            0 :       && (!decl || !DECL_USER_ALIGN (decl)))
   18889              :     {
   18890            0 :       gcc_checking_assert (!TARGET_STV);
   18891              :       return 32;
   18892              :     }
   18893              : 
   18894              :   return align;
   18895              : }
   18896              : 
   18897              : /* Find a location for the static chain incoming to a nested function.
   18898              :    This is a register, unless all free registers are used by arguments.  */
   18899              : 
   18900              : static rtx
   18901       270880 : ix86_static_chain (const_tree fndecl_or_type, bool incoming_p)
   18902              : {
   18903       270880 :   unsigned regno;
   18904              : 
   18905       270880 :   if (TARGET_64BIT)
   18906              :     {
   18907              :       /* We always use R10 in 64-bit mode.  */
   18908              :       regno = R10_REG;
   18909              :     }
   18910              :   else
   18911              :     {
   18912        88353 :       const_tree fntype, fndecl;
   18913        88353 :       unsigned int ccvt;
   18914              : 
   18915              :       /* By default in 32-bit mode we use ECX to pass the static chain.  */
   18916        88353 :       regno = CX_REG;
   18917              : 
   18918        88353 :       if (TREE_CODE (fndecl_or_type) == FUNCTION_DECL)
   18919              :         {
   18920        78381 :           fntype = TREE_TYPE (fndecl_or_type);
   18921        78381 :           fndecl = fndecl_or_type;
   18922              :         }
   18923              :       else
   18924              :         {
   18925              :           fntype = fndecl_or_type;
   18926              :           fndecl = NULL;
   18927              :         }
   18928              : 
   18929        88353 :       ccvt = ix86_get_callcvt (fntype);
   18930        88353 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   18931              :         {
   18932              :           /* Fastcall functions use ecx/edx for arguments, which leaves
   18933              :              us with EAX for the static chain.
   18934              :              Thiscall functions use ecx for arguments, which also
   18935              :              leaves us with EAX for the static chain.  */
   18936              :           regno = AX_REG;
   18937              :         }
   18938        88353 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   18939              :         {
   18940              :           /* Thiscall functions use ecx for arguments, which leaves
   18941              :              us with EAX and EDX for the static chain.
   18942              :              We are using for abi-compatibility EAX.  */
   18943              :           regno = AX_REG;
   18944              :         }
   18945        88353 :       else if (ix86_function_regparm (fntype, fndecl) == 3)
   18946              :         {
   18947              :           /* For regparm 3, we have no free call-clobbered registers in
   18948              :              which to store the static chain.  In order to implement this,
   18949              :              we have the trampoline push the static chain to the stack.
   18950              :              However, we can't push a value below the return address when
   18951              :              we call the nested function directly, so we have to use an
   18952              :              alternate entry point.  For this we use ESI, and have the
   18953              :              alternate entry point push ESI, so that things appear the
   18954              :              same once we're executing the nested function.  */
   18955            0 :           if (incoming_p)
   18956              :             {
   18957            0 :               if (fndecl == current_function_decl
   18958            0 :                   && !ix86_static_chain_on_stack)
   18959              :                 {
   18960            0 :                   gcc_assert (!reload_completed);
   18961            0 :                   ix86_static_chain_on_stack = true;
   18962              :                 }
   18963            0 :               return gen_frame_mem (SImode,
   18964            0 :                                     plus_constant (Pmode,
   18965              :                                                    arg_pointer_rtx, -8));
   18966              :             }
   18967              :           regno = SI_REG;
   18968              :         }
   18969              :     }
   18970              : 
   18971       359246 :   return gen_rtx_REG (Pmode, regno);
   18972              : }
   18973              : 
   18974              : /* Emit RTL insns to initialize the variable parts of a trampoline.
   18975              :    FNDECL is the decl of the target address; M_TRAMP is a MEM for
   18976              :    the trampoline, and CHAIN_VALUE is an RTX for the static chain
   18977              :    to be passed to the target function.  */
   18978              : 
   18979              : static void
   18980          306 : ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   18981              : {
   18982          306 :   rtx mem, fnaddr;
   18983          306 :   int opcode;
   18984          306 :   int offset = 0;
   18985          306 :   bool need_endbr = (flag_cf_protection & CF_BRANCH);
   18986              : 
   18987          306 :   fnaddr = XEXP (DECL_RTL (fndecl), 0);
   18988              : 
   18989          306 :   if (TARGET_64BIT)
   18990              :     {
   18991          306 :       int size;
   18992              : 
   18993          306 :       if (need_endbr)
   18994              :         {
   18995              :           /* Insert ENDBR64.  */
   18996            1 :           mem = adjust_address (m_tramp, SImode, offset);
   18997            1 :           emit_move_insn (mem, gen_int_mode (0xfa1e0ff3, SImode));
   18998            1 :           offset += 4;
   18999              :         }
   19000              : 
   19001              :       /* Load the function address to r11.  Try to load address using
   19002              :          the shorter movl instead of movabs.  We may want to support
   19003              :          movq for kernel mode, but kernel does not use trampolines at
   19004              :          the moment.  FNADDR is a 32bit address and may not be in
   19005              :          DImode when ptr_mode == SImode.  Always use movl in this
   19006              :          case.  */
   19007          306 :       if (ptr_mode == SImode
   19008          306 :           || x86_64_zext_immediate_operand (fnaddr, VOIDmode))
   19009              :         {
   19010          274 :           fnaddr = copy_addr_to_reg (fnaddr);
   19011              : 
   19012          274 :           mem = adjust_address (m_tramp, HImode, offset);
   19013          274 :           emit_move_insn (mem, gen_int_mode (0xbb41, HImode));
   19014              : 
   19015          274 :           mem = adjust_address (m_tramp, SImode, offset + 2);
   19016          274 :           emit_move_insn (mem, gen_lowpart (SImode, fnaddr));
   19017          274 :           offset += 6;
   19018              :         }
   19019              :       else
   19020              :         {
   19021           32 :           mem = adjust_address (m_tramp, HImode, offset);
   19022           32 :           emit_move_insn (mem, gen_int_mode (0xbb49, HImode));
   19023              : 
   19024           32 :           mem = adjust_address (m_tramp, DImode, offset + 2);
   19025           32 :           emit_move_insn (mem, fnaddr);
   19026           32 :           offset += 10;
   19027              :         }
   19028              : 
   19029              :       /* Load static chain using movabs to r10.  Use the shorter movl
   19030              :          instead of movabs when ptr_mode == SImode.  */
   19031          306 :       if (ptr_mode == SImode)
   19032              :         {
   19033              :           opcode = 0xba41;
   19034              :           size = 6;
   19035              :         }
   19036              :       else
   19037              :         {
   19038          306 :           opcode = 0xba49;
   19039          306 :           size = 10;
   19040              :         }
   19041              : 
   19042          306 :       mem = adjust_address (m_tramp, HImode, offset);
   19043          306 :       emit_move_insn (mem, gen_int_mode (opcode, HImode));
   19044              : 
   19045          306 :       mem = adjust_address (m_tramp, ptr_mode, offset + 2);
   19046          306 :       emit_move_insn (mem, chain_value);
   19047          306 :       offset += size;
   19048              : 
   19049              :       /* Jump to r11; the last (unused) byte is a nop, only there to
   19050              :          pad the write out to a single 32-bit store.  */
   19051          306 :       mem = adjust_address (m_tramp, SImode, offset);
   19052          306 :       emit_move_insn (mem, gen_int_mode (0x90e3ff49, SImode));
   19053          306 :       offset += 4;
   19054              :     }
   19055              :   else
   19056              :     {
   19057            0 :       rtx disp, chain;
   19058              : 
   19059              :       /* Depending on the static chain location, either load a register
   19060              :          with a constant, or push the constant to the stack.  All of the
   19061              :          instructions are the same size.  */
   19062            0 :       chain = ix86_static_chain (fndecl, true);
   19063            0 :       if (REG_P (chain))
   19064              :         {
   19065            0 :           switch (REGNO (chain))
   19066              :             {
   19067              :             case AX_REG:
   19068              :               opcode = 0xb8; break;
   19069            0 :             case CX_REG:
   19070            0 :               opcode = 0xb9; break;
   19071            0 :             default:
   19072            0 :               gcc_unreachable ();
   19073              :             }
   19074              :         }
   19075              :       else
   19076              :         opcode = 0x68;
   19077              : 
   19078            0 :       if (need_endbr)
   19079              :         {
   19080              :           /* Insert ENDBR32.  */
   19081            0 :           mem = adjust_address (m_tramp, SImode, offset);
   19082            0 :           emit_move_insn (mem, gen_int_mode (0xfb1e0ff3, SImode));
   19083            0 :           offset += 4;
   19084              :         }
   19085              : 
   19086            0 :       mem = adjust_address (m_tramp, QImode, offset);
   19087            0 :       emit_move_insn (mem, gen_int_mode (opcode, QImode));
   19088              : 
   19089            0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   19090            0 :       emit_move_insn (mem, chain_value);
   19091            0 :       offset += 5;
   19092              : 
   19093            0 :       mem = adjust_address (m_tramp, QImode, offset);
   19094            0 :       emit_move_insn (mem, gen_int_mode (0xe9, QImode));
   19095              : 
   19096            0 :       mem = adjust_address (m_tramp, SImode, offset + 1);
   19097              : 
   19098              :       /* Compute offset from the end of the jmp to the target function.
   19099              :          In the case in which the trampoline stores the static chain on
   19100              :          the stack, we need to skip the first insn which pushes the
   19101              :          (call-saved) register static chain; this push is 1 byte.  */
   19102            0 :       offset += 5;
   19103            0 :       int skip = MEM_P (chain) ? 1 : 0;
   19104              :       /* Skip ENDBR32 at the entry of the target function.  */
   19105            0 :       if (need_endbr
   19106            0 :           && !cgraph_node::get (fndecl)->only_called_directly_p ())
   19107            0 :         skip += 4;
   19108            0 :       disp = expand_binop (SImode, sub_optab, fnaddr,
   19109            0 :                            plus_constant (Pmode, XEXP (m_tramp, 0),
   19110            0 :                                           offset - skip),
   19111              :                            NULL_RTX, 1, OPTAB_DIRECT);
   19112            0 :       emit_move_insn (mem, disp);
   19113              :     }
   19114              : 
   19115          306 :   gcc_assert (offset <= TRAMPOLINE_SIZE);
   19116              : 
   19117              : #ifdef HAVE_ENABLE_EXECUTE_STACK
   19118              : #ifdef CHECK_EXECUTE_STACK_ENABLED
   19119              :   if (CHECK_EXECUTE_STACK_ENABLED)
   19120              : #endif
   19121              :   emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
   19122              :                      LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
   19123              : #endif
   19124          306 : }
   19125              : 
   19126              : static bool
   19127     62811297 : ix86_allocate_stack_slots_for_args (void)
   19128              : {
   19129              :   /* Naked functions should not allocate stack slots for arguments.  */
   19130     62811297 :   return !ix86_function_naked (current_function_decl);
   19131              : }
   19132              : 
   19133              : static bool
   19134     40440632 : ix86_warn_func_return (tree decl)
   19135              : {
   19136              :   /* Naked functions are implemented entirely in assembly, including the
   19137              :      return sequence, so suppress warnings about this.  */
   19138     40440632 :   return !ix86_function_naked (decl);
   19139              : }
   19140              : 
   19141              : /* Return the shift count of a vector by scalar shift builtin second argument
   19142              :    ARG1.  */
   19143              : static tree
   19144        14142 : ix86_vector_shift_count (tree arg1)
   19145              : {
   19146        14142 :   if (tree_fits_uhwi_p (arg1))
   19147              :     return arg1;
   19148         8316 :   else if (TREE_CODE (arg1) == VECTOR_CST && CHAR_BIT == 8)
   19149              :     {
   19150              :       /* The count argument is weird, passed in as various 128-bit
   19151              :          (or 64-bit) vectors, the low 64 bits from it are the count.  */
   19152          162 :       unsigned char buf[16];
   19153          162 :       int len = native_encode_expr (arg1, buf, 16);
   19154          162 :       if (len == 0)
   19155          162 :         return NULL_TREE;
   19156          162 :       tree t = native_interpret_expr (uint64_type_node, buf, len);
   19157          162 :       if (t && tree_fits_uhwi_p (t))
   19158              :         return t;
   19159              :     }
   19160              :   return NULL_TREE;
   19161              : }
   19162              : 
   19163              : /* Return true if arg_mask is all ones, ELEMS is elements number of
   19164              :    corresponding vector.  */
   19165              : static bool
   19166        26083 : ix86_masked_all_ones (unsigned HOST_WIDE_INT elems, tree arg_mask)
   19167              : {
   19168        26083 :   if (TREE_CODE (arg_mask) != INTEGER_CST)
   19169              :     return false;
   19170              : 
   19171         7615 :   unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg_mask);
   19172         7615 :   if (elems == HOST_BITS_PER_WIDE_INT)
   19173           65 :     return  mask == HOST_WIDE_INT_M1U;
   19174         7550 :   if ((mask | (HOST_WIDE_INT_M1U << elems)) != HOST_WIDE_INT_M1U)
   19175         2784 :     return false;
   19176              : 
   19177              :   return true;
   19178              : }
   19179              : 
   19180              : static tree
   19181     71123431 : ix86_fold_builtin (tree fndecl, int n_args,
   19182              :                    tree *args, bool ignore ATTRIBUTE_UNUSED)
   19183              : {
   19184     71123431 :   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
   19185              :     {
   19186     71123431 :       enum ix86_builtins fn_code
   19187     71123431 :         = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   19188     71123431 :       enum rtx_code rcode;
   19189     71123431 :       bool is_vshift;
   19190     71123431 :       enum tree_code tcode;
   19191     71123431 :       bool is_scalar;
   19192     71123431 :       unsigned HOST_WIDE_INT mask;
   19193              : 
   19194     71123431 :       switch (fn_code)
   19195              :         {
   19196         8992 :         case IX86_BUILTIN_CPU_IS:
   19197         8992 :         case IX86_BUILTIN_CPU_SUPPORTS:
   19198         8992 :           gcc_assert (n_args == 1);
   19199         8992 :           return fold_builtin_cpu (fndecl, args);
   19200              : 
   19201        26757 :         case IX86_BUILTIN_NANQ:
   19202        26757 :         case IX86_BUILTIN_NANSQ:
   19203        26757 :           {
   19204        26757 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19205        26757 :             const char *str = c_getstr (*args);
   19206        26757 :             int quiet = fn_code == IX86_BUILTIN_NANQ;
   19207        26757 :             REAL_VALUE_TYPE real;
   19208              : 
   19209        26757 :             if (str && real_nan (&real, str, quiet, TYPE_MODE (type)))
   19210        26757 :               return build_real (type, real);
   19211            0 :             return NULL_TREE;
   19212              :           }
   19213              : 
   19214          108 :         case IX86_BUILTIN_INFQ:
   19215          108 :         case IX86_BUILTIN_HUGE_VALQ:
   19216          108 :           {
   19217          108 :             tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19218          108 :             REAL_VALUE_TYPE inf;
   19219          108 :             real_inf (&inf);
   19220          108 :             return build_real (type, inf);
   19221              :           }
   19222              : 
   19223        63461 :         case IX86_BUILTIN_TZCNT16:
   19224        63461 :         case IX86_BUILTIN_CTZS:
   19225        63461 :         case IX86_BUILTIN_TZCNT32:
   19226        63461 :         case IX86_BUILTIN_TZCNT64:
   19227        63461 :           gcc_assert (n_args == 1);
   19228        63461 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   19229              :             {
   19230           45 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19231           45 :               tree arg = args[0];
   19232           45 :               if (fn_code == IX86_BUILTIN_TZCNT16
   19233           45 :                   || fn_code == IX86_BUILTIN_CTZS)
   19234            3 :                 arg = fold_convert (short_unsigned_type_node, arg);
   19235           45 :               if (integer_zerop (arg))
   19236            6 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   19237              :               else
   19238           39 :                 return fold_const_call (CFN_CTZ, type, arg);
   19239              :             }
   19240              :           break;
   19241              : 
   19242        52822 :         case IX86_BUILTIN_LZCNT16:
   19243        52822 :         case IX86_BUILTIN_CLZS:
   19244        52822 :         case IX86_BUILTIN_LZCNT32:
   19245        52822 :         case IX86_BUILTIN_LZCNT64:
   19246        52822 :           gcc_assert (n_args == 1);
   19247        52822 :           if (TREE_CODE (args[0]) == INTEGER_CST)
   19248              :             {
   19249           54 :               tree type = TREE_TYPE (TREE_TYPE (fndecl));
   19250           54 :               tree arg = args[0];
   19251           54 :               if (fn_code == IX86_BUILTIN_LZCNT16
   19252           54 :                   || fn_code == IX86_BUILTIN_CLZS)
   19253           18 :                 arg = fold_convert (short_unsigned_type_node, arg);
   19254           54 :               if (integer_zerop (arg))
   19255            3 :                 return build_int_cst (type, TYPE_PRECISION (TREE_TYPE (arg)));
   19256              :               else
   19257           51 :                 return fold_const_call (CFN_CLZ, type, arg);
   19258              :             }
   19259              :           break;
   19260              : 
   19261        62199 :         case IX86_BUILTIN_BEXTR32:
   19262        62199 :         case IX86_BUILTIN_BEXTR64:
   19263        62199 :         case IX86_BUILTIN_BEXTRI32:
   19264        62199 :         case IX86_BUILTIN_BEXTRI64:
   19265        62199 :           gcc_assert (n_args == 2);
   19266        62199 :           if (tree_fits_uhwi_p (args[1]))
   19267              :             {
   19268          152 :               unsigned HOST_WIDE_INT res = 0;
   19269          152 :               unsigned int prec = TYPE_PRECISION (TREE_TYPE (args[0]));
   19270          152 :               unsigned int start = tree_to_uhwi (args[1]);
   19271          152 :               unsigned int len = (start & 0xff00) >> 8;
   19272          152 :               tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
   19273          152 :               start &= 0xff;
   19274          152 :               if (start >= prec || len == 0)
   19275          111 :                 return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
   19276              :                                          args[0]);
   19277           41 :               else if (!tree_fits_uhwi_p (args[0]))
   19278              :                 break;
   19279              :               else
   19280           24 :                 res = tree_to_uhwi (args[0]) >> start;
   19281           24 :               if (len > prec)
   19282              :                 len = prec;
   19283           24 :               if (len < HOST_BITS_PER_WIDE_INT)
   19284           15 :                 res &= (HOST_WIDE_INT_1U << len) - 1;
   19285           24 :               return build_int_cstu (lhs_type, res);
   19286              :             }
   19287              :           break;
   19288              : 
   19289        21360 :         case IX86_BUILTIN_BZHI32:
   19290        21360 :         case IX86_BUILTIN_BZHI64:
   19291        21360 :           gcc_assert (n_args == 2);
   19292        21360 :           if (tree_fits_uhwi_p (args[1]))
   19293              :             {
   19294          192 :               unsigned int idx = tree_to_uhwi (args[1]) & 0xff;
   19295          192 :               tree lhs_type = TREE_TYPE (TREE_TYPE (fndecl));
   19296          192 :               if (idx >= TYPE_PRECISION (TREE_TYPE (args[0])))
   19297     71123431 :                 return args[0];
   19298          192 :               if (idx == 0)
   19299           52 :                 return omit_one_operand (lhs_type, build_zero_cst (lhs_type),
   19300              :                                          args[0]);
   19301          140 :               if (!tree_fits_uhwi_p (args[0]))
   19302              :                 break;
   19303           12 :               unsigned HOST_WIDE_INT res = tree_to_uhwi (args[0]);
   19304           12 :               res &= ~(HOST_WIDE_INT_M1U << idx);
   19305           12 :               return build_int_cstu (lhs_type, res);
   19306              :             }
   19307              :           break;
   19308              : 
   19309        21116 :         case IX86_BUILTIN_PDEP32:
   19310        21116 :         case IX86_BUILTIN_PDEP64:
   19311        21116 :           gcc_assert (n_args == 2);
   19312        21116 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   19313              :             {
   19314           46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   19315           46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   19316           46 :               unsigned HOST_WIDE_INT res = 0;
   19317           46 :               unsigned HOST_WIDE_INT m, k = 1;
   19318         2990 :               for (m = 1; m; m <<= 1)
   19319         2944 :                 if ((mask & m) != 0)
   19320              :                   {
   19321         1440 :                     if ((src & k) != 0)
   19322          789 :                       res |= m;
   19323         1440 :                     k <<= 1;
   19324              :                   }
   19325           46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   19326              :             }
   19327              :           break;
   19328              : 
   19329        21118 :         case IX86_BUILTIN_PEXT32:
   19330        21118 :         case IX86_BUILTIN_PEXT64:
   19331        21118 :           gcc_assert (n_args == 2);
   19332        21118 :           if (tree_fits_uhwi_p (args[0]) && tree_fits_uhwi_p (args[1]))
   19333              :             {
   19334           46 :               unsigned HOST_WIDE_INT src = tree_to_uhwi (args[0]);
   19335           46 :               unsigned HOST_WIDE_INT mask = tree_to_uhwi (args[1]);
   19336           46 :               unsigned HOST_WIDE_INT res = 0;
   19337           46 :               unsigned HOST_WIDE_INT m, k = 1;
   19338         2990 :               for (m = 1; m; m <<= 1)
   19339         2944 :                 if ((mask & m) != 0)
   19340              :                   {
   19341         2016 :                     if ((src & m) != 0)
   19342         1063 :                       res |= k;
   19343         2016 :                     k <<= 1;
   19344              :                   }
   19345           46 :               return build_int_cstu (TREE_TYPE (TREE_TYPE (fndecl)), res);
   19346              :             }
   19347              :           break;
   19348              : 
   19349       127814 :         case IX86_BUILTIN_MOVMSKPS:
   19350       127814 :         case IX86_BUILTIN_PMOVMSKB:
   19351       127814 :         case IX86_BUILTIN_MOVMSKPD:
   19352       127814 :         case IX86_BUILTIN_PMOVMSKB128:
   19353       127814 :         case IX86_BUILTIN_MOVMSKPD256:
   19354       127814 :         case IX86_BUILTIN_MOVMSKPS256:
   19355       127814 :         case IX86_BUILTIN_PMOVMSKB256:
   19356       127814 :           gcc_assert (n_args == 1);
   19357       127814 :           if (TREE_CODE (args[0]) == VECTOR_CST)
   19358              :             {
   19359              :               HOST_WIDE_INT res = 0;
   19360         2969 :               for (unsigned i = 0; i < VECTOR_CST_NELTS (args[0]); ++i)
   19361              :                 {
   19362         2448 :                   tree e = VECTOR_CST_ELT (args[0], i);
   19363         2448 :                   if (TREE_CODE (e) == INTEGER_CST && !TREE_OVERFLOW (e))
   19364              :                     {
   19365         1168 :                       if (wi::neg_p (wi::to_wide (e)))
   19366         1119 :                         res |= HOST_WIDE_INT_1 << i;
   19367              :                     }
   19368         1280 :                   else if (TREE_CODE (e) == REAL_CST && !TREE_OVERFLOW (e))
   19369              :                     {
   19370         1280 :                       if (TREE_REAL_CST (e).sign)
   19371         1031 :                         res |= HOST_WIDE_INT_1 << i;
   19372              :                     }
   19373              :                   else
   19374              :                     return NULL_TREE;
   19375              :                 }
   19376          521 :               return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
   19377              :             }
   19378              :           break;
   19379              : 
   19380       669360 :         case IX86_BUILTIN_PSLLD:
   19381       669360 :         case IX86_BUILTIN_PSLLD128:
   19382       669360 :         case IX86_BUILTIN_PSLLD128_MASK:
   19383       669360 :         case IX86_BUILTIN_PSLLD256:
   19384       669360 :         case IX86_BUILTIN_PSLLD256_MASK:
   19385       669360 :         case IX86_BUILTIN_PSLLD512:
   19386       669360 :         case IX86_BUILTIN_PSLLDI:
   19387       669360 :         case IX86_BUILTIN_PSLLDI128:
   19388       669360 :         case IX86_BUILTIN_PSLLDI128_MASK:
   19389       669360 :         case IX86_BUILTIN_PSLLDI256:
   19390       669360 :         case IX86_BUILTIN_PSLLDI256_MASK:
   19391       669360 :         case IX86_BUILTIN_PSLLDI512:
   19392       669360 :         case IX86_BUILTIN_PSLLQ:
   19393       669360 :         case IX86_BUILTIN_PSLLQ128:
   19394       669360 :         case IX86_BUILTIN_PSLLQ128_MASK:
   19395       669360 :         case IX86_BUILTIN_PSLLQ256:
   19396       669360 :         case IX86_BUILTIN_PSLLQ256_MASK:
   19397       669360 :         case IX86_BUILTIN_PSLLQ512:
   19398       669360 :         case IX86_BUILTIN_PSLLQI:
   19399       669360 :         case IX86_BUILTIN_PSLLQI128:
   19400       669360 :         case IX86_BUILTIN_PSLLQI128_MASK:
   19401       669360 :         case IX86_BUILTIN_PSLLQI256:
   19402       669360 :         case IX86_BUILTIN_PSLLQI256_MASK:
   19403       669360 :         case IX86_BUILTIN_PSLLQI512:
   19404       669360 :         case IX86_BUILTIN_PSLLW:
   19405       669360 :         case IX86_BUILTIN_PSLLW128:
   19406       669360 :         case IX86_BUILTIN_PSLLW128_MASK:
   19407       669360 :         case IX86_BUILTIN_PSLLW256:
   19408       669360 :         case IX86_BUILTIN_PSLLW256_MASK:
   19409       669360 :         case IX86_BUILTIN_PSLLW512_MASK:
   19410       669360 :         case IX86_BUILTIN_PSLLWI:
   19411       669360 :         case IX86_BUILTIN_PSLLWI128:
   19412       669360 :         case IX86_BUILTIN_PSLLWI128_MASK:
   19413       669360 :         case IX86_BUILTIN_PSLLWI256:
   19414       669360 :         case IX86_BUILTIN_PSLLWI256_MASK:
   19415       669360 :         case IX86_BUILTIN_PSLLWI512_MASK:
   19416       669360 :           rcode = ASHIFT;
   19417       669360 :           is_vshift = false;
   19418       669360 :           goto do_shift;
   19419       609145 :         case IX86_BUILTIN_PSRAD:
   19420       609145 :         case IX86_BUILTIN_PSRAD128:
   19421       609145 :         case IX86_BUILTIN_PSRAD128_MASK:
   19422       609145 :         case IX86_BUILTIN_PSRAD256:
   19423       609145 :         case IX86_BUILTIN_PSRAD256_MASK:
   19424       609145 :         case IX86_BUILTIN_PSRAD512:
   19425       609145 :         case IX86_BUILTIN_PSRADI:
   19426       609145 :         case IX86_BUILTIN_PSRADI128:
   19427       609145 :         case IX86_BUILTIN_PSRADI128_MASK:
   19428       609145 :         case IX86_BUILTIN_PSRADI256:
   19429       609145 :         case IX86_BUILTIN_PSRADI256_MASK:
   19430       609145 :         case IX86_BUILTIN_PSRADI512:
   19431       609145 :         case IX86_BUILTIN_PSRAQ128_MASK:
   19432       609145 :         case IX86_BUILTIN_PSRAQ256_MASK:
   19433       609145 :         case IX86_BUILTIN_PSRAQ512:
   19434       609145 :         case IX86_BUILTIN_PSRAQI128_MASK:
   19435       609145 :         case IX86_BUILTIN_PSRAQI256_MASK:
   19436       609145 :         case IX86_BUILTIN_PSRAQI512:
   19437       609145 :         case IX86_BUILTIN_PSRAW:
   19438       609145 :         case IX86_BUILTIN_PSRAW128:
   19439       609145 :         case IX86_BUILTIN_PSRAW128_MASK:
   19440       609145 :         case IX86_BUILTIN_PSRAW256:
   19441       609145 :         case IX86_BUILTIN_PSRAW256_MASK:
   19442       609145 :         case IX86_BUILTIN_PSRAW512:
   19443       609145 :         case IX86_BUILTIN_PSRAWI:
   19444       609145 :         case IX86_BUILTIN_PSRAWI128:
   19445       609145 :         case IX86_BUILTIN_PSRAWI128_MASK:
   19446       609145 :         case IX86_BUILTIN_PSRAWI256:
   19447       609145 :         case IX86_BUILTIN_PSRAWI256_MASK:
   19448       609145 :         case IX86_BUILTIN_PSRAWI512:
   19449       609145 :           rcode = ASHIFTRT;
   19450       609145 :           is_vshift = false;
   19451       609145 :           goto do_shift;
   19452       642891 :         case IX86_BUILTIN_PSRLD:
   19453       642891 :         case IX86_BUILTIN_PSRLD128:
   19454       642891 :         case IX86_BUILTIN_PSRLD128_MASK:
   19455       642891 :         case IX86_BUILTIN_PSRLD256:
   19456       642891 :         case IX86_BUILTIN_PSRLD256_MASK:
   19457       642891 :         case IX86_BUILTIN_PSRLD512:
   19458       642891 :         case IX86_BUILTIN_PSRLDI:
   19459       642891 :         case IX86_BUILTIN_PSRLDI128:
   19460       642891 :         case IX86_BUILTIN_PSRLDI128_MASK:
   19461       642891 :         case IX86_BUILTIN_PSRLDI256:
   19462       642891 :         case IX86_BUILTIN_PSRLDI256_MASK:
   19463       642891 :         case IX86_BUILTIN_PSRLDI512:
   19464       642891 :         case IX86_BUILTIN_PSRLQ:
   19465       642891 :         case IX86_BUILTIN_PSRLQ128:
   19466       642891 :         case IX86_BUILTIN_PSRLQ128_MASK:
   19467       642891 :         case IX86_BUILTIN_PSRLQ256:
   19468       642891 :         case IX86_BUILTIN_PSRLQ256_MASK:
   19469       642891 :         case IX86_BUILTIN_PSRLQ512:
   19470       642891 :         case IX86_BUILTIN_PSRLQI:
   19471       642891 :         case IX86_BUILTIN_PSRLQI128:
   19472       642891 :         case IX86_BUILTIN_PSRLQI128_MASK:
   19473       642891 :         case IX86_BUILTIN_PSRLQI256:
   19474       642891 :         case IX86_BUILTIN_PSRLQI256_MASK:
   19475       642891 :         case IX86_BUILTIN_PSRLQI512:
   19476       642891 :         case IX86_BUILTIN_PSRLW:
   19477       642891 :         case IX86_BUILTIN_PSRLW128:
   19478       642891 :         case IX86_BUILTIN_PSRLW128_MASK:
   19479       642891 :         case IX86_BUILTIN_PSRLW256:
   19480       642891 :         case IX86_BUILTIN_PSRLW256_MASK:
   19481       642891 :         case IX86_BUILTIN_PSRLW512:
   19482       642891 :         case IX86_BUILTIN_PSRLWI:
   19483       642891 :         case IX86_BUILTIN_PSRLWI128:
   19484       642891 :         case IX86_BUILTIN_PSRLWI128_MASK:
   19485       642891 :         case IX86_BUILTIN_PSRLWI256:
   19486       642891 :         case IX86_BUILTIN_PSRLWI256_MASK:
   19487       642891 :         case IX86_BUILTIN_PSRLWI512:
   19488       642891 :           rcode = LSHIFTRT;
   19489       642891 :           is_vshift = false;
   19490       642891 :           goto do_shift;
   19491       279005 :         case IX86_BUILTIN_PSLLVV16HI:
   19492       279005 :         case IX86_BUILTIN_PSLLVV16SI:
   19493       279005 :         case IX86_BUILTIN_PSLLVV2DI:
   19494       279005 :         case IX86_BUILTIN_PSLLVV2DI_MASK:
   19495       279005 :         case IX86_BUILTIN_PSLLVV32HI:
   19496       279005 :         case IX86_BUILTIN_PSLLVV4DI:
   19497       279005 :         case IX86_BUILTIN_PSLLVV4DI_MASK:
   19498       279005 :         case IX86_BUILTIN_PSLLVV4SI:
   19499       279005 :         case IX86_BUILTIN_PSLLVV4SI_MASK:
   19500       279005 :         case IX86_BUILTIN_PSLLVV8DI:
   19501       279005 :         case IX86_BUILTIN_PSLLVV8HI:
   19502       279005 :         case IX86_BUILTIN_PSLLVV8SI:
   19503       279005 :         case IX86_BUILTIN_PSLLVV8SI_MASK:
   19504       279005 :           rcode = ASHIFT;
   19505       279005 :           is_vshift = true;
   19506       279005 :           goto do_shift;
   19507       278305 :         case IX86_BUILTIN_PSRAVQ128:
   19508       278305 :         case IX86_BUILTIN_PSRAVQ256:
   19509       278305 :         case IX86_BUILTIN_PSRAVV16HI:
   19510       278305 :         case IX86_BUILTIN_PSRAVV16SI:
   19511       278305 :         case IX86_BUILTIN_PSRAVV32HI:
   19512       278305 :         case IX86_BUILTIN_PSRAVV4SI:
   19513       278305 :         case IX86_BUILTIN_PSRAVV4SI_MASK:
   19514       278305 :         case IX86_BUILTIN_PSRAVV8DI:
   19515       278305 :         case IX86_BUILTIN_PSRAVV8HI:
   19516       278305 :         case IX86_BUILTIN_PSRAVV8SI:
   19517       278305 :         case IX86_BUILTIN_PSRAVV8SI_MASK:
   19518       278305 :           rcode = ASHIFTRT;
   19519       278305 :           is_vshift = true;
   19520       278305 :           goto do_shift;
   19521       278996 :         case IX86_BUILTIN_PSRLVV16HI:
   19522       278996 :         case IX86_BUILTIN_PSRLVV16SI:
   19523       278996 :         case IX86_BUILTIN_PSRLVV2DI:
   19524       278996 :         case IX86_BUILTIN_PSRLVV2DI_MASK:
   19525       278996 :         case IX86_BUILTIN_PSRLVV32HI:
   19526       278996 :         case IX86_BUILTIN_PSRLVV4DI:
   19527       278996 :         case IX86_BUILTIN_PSRLVV4DI_MASK:
   19528       278996 :         case IX86_BUILTIN_PSRLVV4SI:
   19529       278996 :         case IX86_BUILTIN_PSRLVV4SI_MASK:
   19530       278996 :         case IX86_BUILTIN_PSRLVV8DI:
   19531       278996 :         case IX86_BUILTIN_PSRLVV8HI:
   19532       278996 :         case IX86_BUILTIN_PSRLVV8SI:
   19533       278996 :         case IX86_BUILTIN_PSRLVV8SI_MASK:
   19534       278996 :           rcode = LSHIFTRT;
   19535       278996 :           is_vshift = true;
   19536       278996 :           goto do_shift;
   19537              : 
   19538      2757702 :         do_shift:
   19539      2757702 :           gcc_assert (n_args >= 2);
   19540      2757702 :           if (TREE_CODE (args[0]) != VECTOR_CST)
   19541              :             break;
   19542          927 :           mask = HOST_WIDE_INT_M1U;
   19543          927 :           if (n_args > 2)
   19544              :             {
   19545              :               /* This is masked shift.  */
   19546          678 :               if (!tree_fits_uhwi_p (args[n_args - 1])
   19547          678 :                   || TREE_SIDE_EFFECTS (args[n_args - 2]))
   19548              :                 break;
   19549          678 :               mask = tree_to_uhwi (args[n_args - 1]);
   19550          678 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19551          678 :               mask |= HOST_WIDE_INT_M1U << elems;
   19552          678 :               if (mask != HOST_WIDE_INT_M1U
   19553          567 :                   && TREE_CODE (args[n_args - 2]) != VECTOR_CST)
   19554              :                 break;
   19555          633 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   19556              :                 return args[n_args - 2];
   19557              :             }
   19558          879 :           if (is_vshift && TREE_CODE (args[1]) != VECTOR_CST)
   19559              :             break;
   19560          879 :           if (tree tem = (is_vshift ? integer_one_node
   19561          879 :                           : ix86_vector_shift_count (args[1])))
   19562              :             {
   19563          558 :               unsigned HOST_WIDE_INT count = tree_to_uhwi (tem);
   19564          558 :               unsigned HOST_WIDE_INT prec
   19565          558 :                 = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (args[0])));
   19566          558 :               if (count == 0 && mask == HOST_WIDE_INT_M1U)
   19567              :                 return args[0];
   19568          558 :               if (count >= prec)
   19569              :                 {
   19570           72 :                   if (rcode == ASHIFTRT)
   19571           27 :                     count = prec - 1;
   19572           45 :                   else if (mask == HOST_WIDE_INT_M1U)
   19573            3 :                     return build_zero_cst (TREE_TYPE (args[0]));
   19574              :                 }
   19575          555 :               tree countt = NULL_TREE;
   19576          555 :               if (!is_vshift)
   19577              :                 {
   19578          377 :                   if (count >= prec)
   19579           42 :                     countt = integer_zero_node;
   19580              :                   else
   19581          335 :                     countt = build_int_cst (integer_type_node, count);
   19582              :                 }
   19583          555 :               tree_vector_builder builder;
   19584          555 :               if (mask != HOST_WIDE_INT_M1U || is_vshift)
   19585          392 :                 builder.new_vector (TREE_TYPE (args[0]),
   19586          784 :                                     TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0])),
   19587              :                                     1);
   19588              :               else
   19589          163 :                 builder.new_unary_operation (TREE_TYPE (args[0]), args[0],
   19590              :                                              false);
   19591          555 :               unsigned int cnt = builder.encoded_nelts ();
   19592         5967 :               for (unsigned int i = 0; i < cnt; ++i)
   19593              :                 {
   19594         5412 :                   tree elt = VECTOR_CST_ELT (args[0], i);
   19595         5412 :                   if (TREE_CODE (elt) != INTEGER_CST || TREE_OVERFLOW (elt))
   19596            0 :                     return NULL_TREE;
   19597         5412 :                   tree type = TREE_TYPE (elt);
   19598         5412 :                   if (rcode == LSHIFTRT)
   19599         2040 :                     elt = fold_convert (unsigned_type_for (type), elt);
   19600         5412 :                   if (is_vshift)
   19601              :                     {
   19602         1846 :                       countt = VECTOR_CST_ELT (args[1], i);
   19603         1846 :                       if (TREE_CODE (countt) != INTEGER_CST
   19604         1846 :                           || TREE_OVERFLOW (countt))
   19605              :                         return NULL_TREE;
   19606         1846 :                       if (wi::neg_p (wi::to_wide (countt))
   19607         3610 :                           || wi::to_widest (countt) >= prec)
   19608              :                         {
   19609          325 :                           if (rcode == ASHIFTRT)
   19610          108 :                             countt = build_int_cst (TREE_TYPE (countt),
   19611          108 :                                                     prec - 1);
   19612              :                           else
   19613              :                             {
   19614          217 :                               elt = build_zero_cst (TREE_TYPE (elt));
   19615          217 :                               countt = build_zero_cst (TREE_TYPE (countt));
   19616              :                             }
   19617              :                         }
   19618              :                     }
   19619         3566 :                   else if (count >= prec)
   19620          504 :                     elt = build_zero_cst (TREE_TYPE (elt));
   19621         8950 :                   elt = const_binop (rcode == ASHIFT
   19622              :                                      ? LSHIFT_EXPR : RSHIFT_EXPR,
   19623         5412 :                                      TREE_TYPE (elt), elt, countt);
   19624         5412 :                   if (!elt || TREE_CODE (elt) != INTEGER_CST)
   19625              :                     return NULL_TREE;
   19626         5412 :                   if (rcode == LSHIFTRT)
   19627         2040 :                     elt = fold_convert (type, elt);
   19628         5412 :                   if ((mask & (HOST_WIDE_INT_1U << i)) == 0)
   19629              :                     {
   19630         1566 :                       elt = VECTOR_CST_ELT (args[n_args - 2], i);
   19631         1566 :                       if (TREE_CODE (elt) != INTEGER_CST
   19632         1566 :                           || TREE_OVERFLOW (elt))
   19633              :                         return NULL_TREE;
   19634              :                     }
   19635         5412 :                   builder.quick_push (elt);
   19636              :                 }
   19637          555 :               return builder.build ();
   19638          555 :             }
   19639              :           break;
   19640              : 
   19641        33265 :         case IX86_BUILTIN_MINSS:
   19642        33265 :         case IX86_BUILTIN_MINSH_MASK:
   19643        33265 :           tcode = LT_EXPR;
   19644        33265 :           is_scalar = true;
   19645        33265 :           goto do_minmax;
   19646              : 
   19647        33265 :         case IX86_BUILTIN_MAXSS:
   19648        33265 :         case IX86_BUILTIN_MAXSH_MASK:
   19649        33265 :           tcode = GT_EXPR;
   19650        33265 :           is_scalar = true;
   19651        33265 :           goto do_minmax;
   19652              : 
   19653       354623 :         case IX86_BUILTIN_MINPS:
   19654       354623 :         case IX86_BUILTIN_MINPD:
   19655       354623 :         case IX86_BUILTIN_MINPS256:
   19656       354623 :         case IX86_BUILTIN_MINPD256:
   19657       354623 :         case IX86_BUILTIN_MINPS512:
   19658       354623 :         case IX86_BUILTIN_MINPD512:
   19659       354623 :         case IX86_BUILTIN_MINPS128_MASK:
   19660       354623 :         case IX86_BUILTIN_MINPD128_MASK:
   19661       354623 :         case IX86_BUILTIN_MINPS256_MASK:
   19662       354623 :         case IX86_BUILTIN_MINPD256_MASK:
   19663       354623 :         case IX86_BUILTIN_MINPH128_MASK:
   19664       354623 :         case IX86_BUILTIN_MINPH256_MASK:
   19665       354623 :         case IX86_BUILTIN_MINPH512_MASK:
   19666       354623 :           tcode = LT_EXPR;
   19667       354623 :           is_scalar = false;
   19668       354623 :           goto do_minmax;
   19669              : 
   19670              :         case IX86_BUILTIN_MAXPS:
   19671              :         case IX86_BUILTIN_MAXPD:
   19672              :         case IX86_BUILTIN_MAXPS256:
   19673              :         case IX86_BUILTIN_MAXPD256:
   19674              :         case IX86_BUILTIN_MAXPS512:
   19675              :         case IX86_BUILTIN_MAXPD512:
   19676              :         case IX86_BUILTIN_MAXPS128_MASK:
   19677              :         case IX86_BUILTIN_MAXPD128_MASK:
   19678              :         case IX86_BUILTIN_MAXPS256_MASK:
   19679              :         case IX86_BUILTIN_MAXPD256_MASK:
   19680              :         case IX86_BUILTIN_MAXPH128_MASK:
   19681              :         case IX86_BUILTIN_MAXPH256_MASK:
   19682              :         case IX86_BUILTIN_MAXPH512_MASK:
   19683              :           tcode = GT_EXPR;
   19684              :           is_scalar = false;
   19685       775803 :         do_minmax:
   19686       775803 :           gcc_assert (n_args >= 2);
   19687       775803 :           if (TREE_CODE (args[0]) != VECTOR_CST
   19688           76 :               || TREE_CODE (args[1]) != VECTOR_CST)
   19689              :             break;
   19690           76 :           mask = HOST_WIDE_INT_M1U;
   19691           76 :           if (n_args > 2)
   19692              :             {
   19693           36 :               gcc_assert (n_args >= 4);
   19694              :               /* This is masked minmax.  */
   19695           36 :               if (TREE_CODE (args[3]) != INTEGER_CST
   19696           36 :                   || TREE_SIDE_EFFECTS (args[2]))
   19697              :                 break;
   19698           36 :               mask = TREE_INT_CST_LOW (args[3]);
   19699           36 :               unsigned elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19700           36 :               mask |= HOST_WIDE_INT_M1U << elems;
   19701           36 :               if (mask != HOST_WIDE_INT_M1U
   19702           32 :                   && TREE_CODE (args[2]) != VECTOR_CST)
   19703              :                 break;
   19704           36 :               if (n_args >= 5)
   19705              :                 {
   19706           20 :                   if (!tree_fits_uhwi_p (args[4]))
   19707              :                     break;
   19708           20 :                   if (tree_to_uhwi (args[4]) != 4
   19709            0 :                       && tree_to_uhwi (args[4]) != 8)
   19710              :                     break;
   19711              :                 }
   19712           36 :               if (mask == (HOST_WIDE_INT_M1U << elems))
   19713              :                 return args[2];
   19714              :             }
   19715              :           /* Punt on NaNs, unless exceptions are disabled.  */
   19716           76 :           if (HONOR_NANS (args[0])
   19717           76 :               && (n_args < 5 || tree_to_uhwi (args[4]) != 8))
   19718          184 :             for (int i = 0; i < 2; ++i)
   19719              :               {
   19720          134 :                 unsigned count = vector_cst_encoded_nelts (args[i]);
   19721         1091 :                 for (unsigned j = 0; j < count; ++j)
   19722          849 :                   if (tree_expr_nan_p (VECTOR_CST_ENCODED_ELT (args[i], j)))
   19723              :                     return NULL_TREE;
   19724              :               }
   19725           50 :           {
   19726           50 :             tree res = const_binop (tcode,
   19727           50 :                                     truth_type_for (TREE_TYPE (args[0])),
   19728              :                                     args[0], args[1]);
   19729           50 :             if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19730              :               break;
   19731           50 :             res = fold_ternary (VEC_COND_EXPR, TREE_TYPE (args[0]), res,
   19732              :                                 args[0], args[1]);
   19733           50 :             if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19734              :               break;
   19735           50 :             if (mask != HOST_WIDE_INT_M1U)
   19736              :               {
   19737           32 :                 unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19738           32 :                 vec_perm_builder sel (nelts, nelts, 1);
   19739          328 :                 for (unsigned int i = 0; i < nelts; i++)
   19740          296 :                   if (mask & (HOST_WIDE_INT_1U << i))
   19741          160 :                     sel.quick_push (i);
   19742              :                   else
   19743          136 :                     sel.quick_push (nelts + i);
   19744           32 :                 vec_perm_indices indices (sel, 2, nelts);
   19745           32 :                 res = fold_vec_perm (TREE_TYPE (args[0]), res, args[2],
   19746              :                                      indices);
   19747           32 :                 if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19748              :                   break;
   19749           32 :               }
   19750           50 :             if (is_scalar)
   19751              :               {
   19752           10 :                 unsigned nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (args[0]));
   19753           10 :                 vec_perm_builder sel (nelts, nelts, 1);
   19754           10 :                 sel.quick_push (0);
   19755           40 :                 for (unsigned int i = 1; i < nelts; i++)
   19756           30 :                   sel.quick_push (nelts + i);
   19757           10 :                 vec_perm_indices indices (sel, 2, nelts);
   19758           10 :                 res = fold_vec_perm (TREE_TYPE (args[0]), res, args[0],
   19759              :                                      indices);
   19760           10 :                 if (res == NULL_TREE || TREE_CODE (res) != VECTOR_CST)
   19761              :                   break;
   19762           10 :               }
   19763              :             return res;
   19764              :           }
   19765              : 
   19766              :         default:
   19767              :           break;
   19768              :         }
   19769              :     }
   19770              : 
   19771              : #ifdef SUBTARGET_FOLD_BUILTIN
   19772              :   return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
   19773              : #endif
   19774              : 
   19775              :   return NULL_TREE;
   19776              : }
   19777              : 
   19778              : /* Fold a MD builtin (use ix86_fold_builtin for folding into
   19779              :    constant) in GIMPLE.  */
   19780              : 
   19781              : bool
   19782      1157723 : ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   19783              : {
   19784      1157723 :   gimple *stmt = gsi_stmt (*gsi), *g;
   19785      1157723 :   gimple_seq stmts = NULL;
   19786      1157723 :   tree fndecl = gimple_call_fndecl (stmt);
   19787      1157723 :   gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
   19788      1157723 :   int n_args = gimple_call_num_args (stmt);
   19789      1157723 :   enum ix86_builtins fn_code
   19790      1157723 :     = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
   19791      1157723 :   tree decl = NULL_TREE;
   19792      1157723 :   tree arg0, arg1, arg2;
   19793      1157723 :   enum rtx_code rcode;
   19794      1157723 :   enum tree_code tcode;
   19795      1157723 :   unsigned HOST_WIDE_INT count;
   19796      1157723 :   bool is_vshift;
   19797      1157723 :   unsigned HOST_WIDE_INT elems;
   19798      1157723 :   location_t loc;
   19799              : 
   19800              :   /* Don't fold when there's isa mismatch.  */
   19801      1157723 :   if (!ix86_check_builtin_isa_match (fn_code, NULL, NULL))
   19802              :     return false;
   19803              : 
   19804      1157596 :   switch (fn_code)
   19805              :     {
   19806          288 :     case IX86_BUILTIN_TZCNT32:
   19807          288 :       decl = builtin_decl_implicit (BUILT_IN_CTZ);
   19808          288 :       goto fold_tzcnt_lzcnt;
   19809              : 
   19810          237 :     case IX86_BUILTIN_TZCNT64:
   19811          237 :       decl = builtin_decl_implicit (BUILT_IN_CTZLL);
   19812          237 :       goto fold_tzcnt_lzcnt;
   19813              : 
   19814          215 :     case IX86_BUILTIN_LZCNT32:
   19815          215 :       decl = builtin_decl_implicit (BUILT_IN_CLZ);
   19816          215 :       goto fold_tzcnt_lzcnt;
   19817              : 
   19818          224 :     case IX86_BUILTIN_LZCNT64:
   19819          224 :       decl = builtin_decl_implicit (BUILT_IN_CLZLL);
   19820          224 :       goto fold_tzcnt_lzcnt;
   19821              : 
   19822          964 :     fold_tzcnt_lzcnt:
   19823          964 :       gcc_assert (n_args == 1);
   19824          964 :       arg0 = gimple_call_arg (stmt, 0);
   19825          964 :       if (TREE_CODE (arg0) == SSA_NAME && decl && gimple_call_lhs (stmt))
   19826              :         {
   19827          799 :           int prec = TYPE_PRECISION (TREE_TYPE (arg0));
   19828              :           /* If arg0 is provably non-zero, optimize into generic
   19829              :              __builtin_c[tl]z{,ll} function the middle-end handles
   19830              :              better.  */
   19831          799 :           if (!expr_not_equal_to (arg0, wi::zero (prec)))
   19832              :             return false;
   19833              : 
   19834            9 :           loc = gimple_location (stmt);
   19835            9 :           g = gimple_build_call (decl, 1, arg0);
   19836            9 :           gimple_set_location (g, loc);
   19837            9 :           tree lhs = make_ssa_name (integer_type_node);
   19838            9 :           gimple_call_set_lhs (g, lhs);
   19839            9 :           gsi_insert_before (gsi, g, GSI_SAME_STMT);
   19840            9 :           g = gimple_build_assign (gimple_call_lhs (stmt), NOP_EXPR, lhs);
   19841            9 :           gimple_set_location (g, loc);
   19842            9 :           gsi_replace (gsi, g, false);
   19843            9 :           return true;
   19844              :         }
   19845              :       break;
   19846              : 
   19847          491 :     case IX86_BUILTIN_BZHI32:
   19848          491 :     case IX86_BUILTIN_BZHI64:
   19849          491 :       gcc_assert (n_args == 2);
   19850          491 :       arg1 = gimple_call_arg (stmt, 1);
   19851          491 :       if (tree_fits_uhwi_p (arg1) && gimple_call_lhs (stmt))
   19852              :         {
   19853          195 :           unsigned int idx = tree_to_uhwi (arg1) & 0xff;
   19854          195 :           arg0 = gimple_call_arg (stmt, 0);
   19855          195 :           if (idx < TYPE_PRECISION (TREE_TYPE (arg0)))
   19856              :             break;
   19857           31 :           loc = gimple_location (stmt);
   19858           31 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19859           31 :           gimple_set_location (g, loc);
   19860           31 :           gsi_replace (gsi, g, false);
   19861           31 :           return true;
   19862              :         }
   19863              :       break;
   19864              : 
   19865          502 :     case IX86_BUILTIN_PDEP32:
   19866          502 :     case IX86_BUILTIN_PDEP64:
   19867          502 :     case IX86_BUILTIN_PEXT32:
   19868          502 :     case IX86_BUILTIN_PEXT64:
   19869          502 :       gcc_assert (n_args == 2);
   19870          502 :       arg1 = gimple_call_arg (stmt, 1);
   19871          502 :       if (integer_all_onesp (arg1) && gimple_call_lhs (stmt))
   19872              :         {
   19873            4 :           loc = gimple_location (stmt);
   19874            4 :           arg0 = gimple_call_arg (stmt, 0);
   19875            4 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   19876            4 :           gimple_set_location (g, loc);
   19877            4 :           gsi_replace (gsi, g, false);
   19878            4 :           return true;
   19879              :         }
   19880              :       break;
   19881              : 
   19882         1148 :     case IX86_BUILTIN_PAVGUSB:
   19883         1148 :     case IX86_BUILTIN_PAVGB:
   19884         1148 :     case IX86_BUILTIN_PAVGW:
   19885         1148 :     case IX86_BUILTIN_PAVGB128:
   19886         1148 :     case IX86_BUILTIN_PAVGW128:
   19887         1148 :     case IX86_BUILTIN_PAVGB256:
   19888         1148 :     case IX86_BUILTIN_PAVGW256:
   19889         1148 :     case IX86_BUILTIN_PAVGB128_MASK:
   19890         1148 :     case IX86_BUILTIN_PAVGW128_MASK:
   19891         1148 :     case IX86_BUILTIN_PAVGB256_MASK:
   19892         1148 :     case IX86_BUILTIN_PAVGW256_MASK:
   19893         1148 :     case IX86_BUILTIN_PAVGB512:
   19894         1148 :     case IX86_BUILTIN_PAVGW512:
   19895         1148 :       gcc_assert (n_args == 2 || n_args == 4);
   19896         1148 :       if (!gimple_call_lhs (stmt))
   19897              :         break;
   19898         1148 :       arg0 = gimple_call_arg (stmt, 0);
   19899         1148 :       arg1 = gimple_call_arg (stmt, 1);
   19900              :       /* For masked PAVG, only canonicalize if the mask is all ones.  */
   19901         1148 :       if (n_args == 4)
   19902              :         {
   19903         1041 :           elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   19904         1041 :           if (!ix86_masked_all_ones (elems, gimple_call_arg (stmt, 3)))
   19905              :             break;
   19906              :         }
   19907          138 :       {
   19908              :         /* PAVG computes an unsigned average rounded towards positive
   19909              :            infinity.  The IFN selects signedness from its operand type.  */
   19910          138 :         tree utype = unsigned_type_for (TREE_TYPE (arg0));
   19911          138 :         bool equal_p = operand_equal_p (arg0, arg1, 0);
   19912          138 :         if (!equal_p
   19913          138 :             && !direct_internal_fn_supported_p (IFN_AVG_CEIL, utype,
   19914              :                                                 OPTIMIZE_FOR_BOTH))
   19915              :           break;
   19916              : 
   19917          138 :         loc = gimple_location (stmt);
   19918          138 :         tree uarg0 = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
   19919              :                                     utype, arg0);
   19920          138 :         tree uarg1 = equal_p
   19921          138 :           ? uarg0
   19922          138 :           : gimple_build (&stmts, loc, VIEW_CONVERT_EXPR, utype, arg1);
   19923          138 :         tree res = gimple_build (&stmts, loc, IFN_AVG_CEIL, utype,
   19924              :                                  uarg0, uarg1);
   19925          138 :         res = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
   19926          138 :                             TREE_TYPE (gimple_call_lhs (stmt)), res);
   19927          138 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19928          138 :         g = gimple_build_assign (gimple_call_lhs (stmt), res);
   19929          138 :         gimple_set_location (g, loc);
   19930          138 :         gsi_replace (gsi, g, false);
   19931          138 :         return true;
   19932              :       }
   19933              : 
   19934          145 :     case IX86_BUILTIN_PBLENDVB256:
   19935          145 :     case IX86_BUILTIN_BLENDVPS256:
   19936          145 :     case IX86_BUILTIN_BLENDVPD256:
   19937              :       /* pcmpeqb/d/q is under avx2, w/o avx2, it's veclower
   19938              :          to scalar operations and not combined back.  */
   19939          145 :       if (!TARGET_AVX2)
   19940              :         break;
   19941              : 
   19942              :       /* FALLTHRU.  */
   19943          112 :     case IX86_BUILTIN_BLENDVPD:
   19944              :       /* blendvpd is under sse4.1 but pcmpgtq is under sse4.2,
   19945              :          w/o sse4.2, it's veclowered to scalar operations and
   19946              :          not combined back.  */
   19947          112 :       if (!TARGET_SSE4_2)
   19948              :         break;
   19949              :       /* FALLTHRU.  */
   19950          166 :     case IX86_BUILTIN_PBLENDVB128:
   19951          166 :     case IX86_BUILTIN_BLENDVPS:
   19952          166 :       gcc_assert (n_args == 3);
   19953          166 :       arg0 = gimple_call_arg (stmt, 0);
   19954          166 :       arg1 = gimple_call_arg (stmt, 1);
   19955          166 :       arg2 = gimple_call_arg (stmt, 2);
   19956          166 :       if (gimple_call_lhs (stmt))
   19957              :         {
   19958          166 :           loc = gimple_location (stmt);
   19959          166 :           tree type = TREE_TYPE (arg2);
   19960          166 :           if (VECTOR_FLOAT_TYPE_P (type))
   19961              :             {
   19962           73 :               tree itype = GET_MODE_INNER (TYPE_MODE (type)) == E_SFmode
   19963           73 :                 ? intSI_type_node : intDI_type_node;
   19964           73 :               type = get_same_sized_vectype (itype, type);
   19965              :             }
   19966              :           else
   19967           93 :             type = signed_type_for (type);
   19968          166 :           arg2 = gimple_build (&stmts, VIEW_CONVERT_EXPR, type, arg2);
   19969          166 :           tree zero_vec = build_zero_cst (type);
   19970          166 :           tree cmp_type = truth_type_for (type);
   19971          166 :           tree cmp = gimple_build (&stmts, LT_EXPR, cmp_type, arg2, zero_vec);
   19972          166 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   19973          166 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   19974              :                                    VEC_COND_EXPR, cmp,
   19975              :                                    arg1, arg0);
   19976          166 :           gimple_set_location (g, loc);
   19977          166 :           gsi_replace (gsi, g, false);
   19978              :         }
   19979              :       else
   19980            0 :         gsi_replace (gsi, gimple_build_nop (), false);
   19981              :       return true;
   19982              : 
   19983              : 
   19984           16 :     case IX86_BUILTIN_PCMPEQB128:
   19985           16 :     case IX86_BUILTIN_PCMPEQW128:
   19986           16 :     case IX86_BUILTIN_PCMPEQD128:
   19987           16 :     case IX86_BUILTIN_PCMPEQQ:
   19988           16 :     case IX86_BUILTIN_PCMPEQB256:
   19989           16 :     case IX86_BUILTIN_PCMPEQW256:
   19990           16 :     case IX86_BUILTIN_PCMPEQD256:
   19991           16 :     case IX86_BUILTIN_PCMPEQQ256:
   19992           16 :       tcode = EQ_EXPR;
   19993           16 :       goto do_cmp;
   19994              : 
   19995              :     case IX86_BUILTIN_PCMPGTB128:
   19996              :     case IX86_BUILTIN_PCMPGTW128:
   19997              :     case IX86_BUILTIN_PCMPGTD128:
   19998              :     case IX86_BUILTIN_PCMPGTQ:
   19999              :     case IX86_BUILTIN_PCMPGTB256:
   20000              :     case IX86_BUILTIN_PCMPGTW256:
   20001              :     case IX86_BUILTIN_PCMPGTD256:
   20002              :     case IX86_BUILTIN_PCMPGTQ256:
   20003              :       tcode = GT_EXPR;
   20004              : 
   20005           33 :     do_cmp:
   20006           33 :       gcc_assert (n_args == 2);
   20007           33 :       arg0 = gimple_call_arg (stmt, 0);
   20008           33 :       arg1 = gimple_call_arg (stmt, 1);
   20009           33 :       if (gimple_call_lhs (stmt))
   20010              :         {
   20011           32 :           loc = gimple_location (stmt);
   20012           32 :           tree type = TREE_TYPE (arg0);
   20013           32 :           tree zero_vec = build_zero_cst (type);
   20014           32 :           tree minus_one_vec = build_minus_one_cst (type);
   20015           32 :           tree cmp_type = truth_type_for (type);
   20016           32 :           tree cmp = gimple_build (&stmts, tcode, cmp_type, arg0, arg1);
   20017           32 :           gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   20018           32 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   20019              :                                    VEC_COND_EXPR, cmp,
   20020              :                                    minus_one_vec, zero_vec);
   20021           32 :           gimple_set_location (g, loc);
   20022           32 :           gsi_replace (gsi, g, false);
   20023              :         }
   20024              :       else
   20025            1 :         gsi_replace (gsi, gimple_build_nop (), false);
   20026              :       return true;
   20027              : 
   20028         9297 :     case IX86_BUILTIN_PSLLD:
   20029         9297 :     case IX86_BUILTIN_PSLLD128:
   20030         9297 :     case IX86_BUILTIN_PSLLD128_MASK:
   20031         9297 :     case IX86_BUILTIN_PSLLD256:
   20032         9297 :     case IX86_BUILTIN_PSLLD256_MASK:
   20033         9297 :     case IX86_BUILTIN_PSLLD512:
   20034         9297 :     case IX86_BUILTIN_PSLLDI:
   20035         9297 :     case IX86_BUILTIN_PSLLDI128:
   20036         9297 :     case IX86_BUILTIN_PSLLDI128_MASK:
   20037         9297 :     case IX86_BUILTIN_PSLLDI256:
   20038         9297 :     case IX86_BUILTIN_PSLLDI256_MASK:
   20039         9297 :     case IX86_BUILTIN_PSLLDI512:
   20040         9297 :     case IX86_BUILTIN_PSLLQ:
   20041         9297 :     case IX86_BUILTIN_PSLLQ128:
   20042         9297 :     case IX86_BUILTIN_PSLLQ128_MASK:
   20043         9297 :     case IX86_BUILTIN_PSLLQ256:
   20044         9297 :     case IX86_BUILTIN_PSLLQ256_MASK:
   20045         9297 :     case IX86_BUILTIN_PSLLQ512:
   20046         9297 :     case IX86_BUILTIN_PSLLQI:
   20047         9297 :     case IX86_BUILTIN_PSLLQI128:
   20048         9297 :     case IX86_BUILTIN_PSLLQI128_MASK:
   20049         9297 :     case IX86_BUILTIN_PSLLQI256:
   20050         9297 :     case IX86_BUILTIN_PSLLQI256_MASK:
   20051         9297 :     case IX86_BUILTIN_PSLLQI512:
   20052         9297 :     case IX86_BUILTIN_PSLLW:
   20053         9297 :     case IX86_BUILTIN_PSLLW128:
   20054         9297 :     case IX86_BUILTIN_PSLLW128_MASK:
   20055         9297 :     case IX86_BUILTIN_PSLLW256:
   20056         9297 :     case IX86_BUILTIN_PSLLW256_MASK:
   20057         9297 :     case IX86_BUILTIN_PSLLW512_MASK:
   20058         9297 :     case IX86_BUILTIN_PSLLWI:
   20059         9297 :     case IX86_BUILTIN_PSLLWI128:
   20060         9297 :     case IX86_BUILTIN_PSLLWI128_MASK:
   20061         9297 :     case IX86_BUILTIN_PSLLWI256:
   20062         9297 :     case IX86_BUILTIN_PSLLWI256_MASK:
   20063         9297 :     case IX86_BUILTIN_PSLLWI512_MASK:
   20064         9297 :       rcode = ASHIFT;
   20065         9297 :       is_vshift = false;
   20066         9297 :       goto do_shift;
   20067         6495 :     case IX86_BUILTIN_PSRAD:
   20068         6495 :     case IX86_BUILTIN_PSRAD128:
   20069         6495 :     case IX86_BUILTIN_PSRAD128_MASK:
   20070         6495 :     case IX86_BUILTIN_PSRAD256:
   20071         6495 :     case IX86_BUILTIN_PSRAD256_MASK:
   20072         6495 :     case IX86_BUILTIN_PSRAD512:
   20073         6495 :     case IX86_BUILTIN_PSRADI:
   20074         6495 :     case IX86_BUILTIN_PSRADI128:
   20075         6495 :     case IX86_BUILTIN_PSRADI128_MASK:
   20076         6495 :     case IX86_BUILTIN_PSRADI256:
   20077         6495 :     case IX86_BUILTIN_PSRADI256_MASK:
   20078         6495 :     case IX86_BUILTIN_PSRADI512:
   20079         6495 :     case IX86_BUILTIN_PSRAQ128_MASK:
   20080         6495 :     case IX86_BUILTIN_PSRAQ256_MASK:
   20081         6495 :     case IX86_BUILTIN_PSRAQ512:
   20082         6495 :     case IX86_BUILTIN_PSRAQI128_MASK:
   20083         6495 :     case IX86_BUILTIN_PSRAQI256_MASK:
   20084         6495 :     case IX86_BUILTIN_PSRAQI512:
   20085         6495 :     case IX86_BUILTIN_PSRAW:
   20086         6495 :     case IX86_BUILTIN_PSRAW128:
   20087         6495 :     case IX86_BUILTIN_PSRAW128_MASK:
   20088         6495 :     case IX86_BUILTIN_PSRAW256:
   20089         6495 :     case IX86_BUILTIN_PSRAW256_MASK:
   20090         6495 :     case IX86_BUILTIN_PSRAW512:
   20091         6495 :     case IX86_BUILTIN_PSRAWI:
   20092         6495 :     case IX86_BUILTIN_PSRAWI128:
   20093         6495 :     case IX86_BUILTIN_PSRAWI128_MASK:
   20094         6495 :     case IX86_BUILTIN_PSRAWI256:
   20095         6495 :     case IX86_BUILTIN_PSRAWI256_MASK:
   20096         6495 :     case IX86_BUILTIN_PSRAWI512:
   20097         6495 :       rcode = ASHIFTRT;
   20098         6495 :       is_vshift = false;
   20099         6495 :       goto do_shift;
   20100         7960 :     case IX86_BUILTIN_PSRLD:
   20101         7960 :     case IX86_BUILTIN_PSRLD128:
   20102         7960 :     case IX86_BUILTIN_PSRLD128_MASK:
   20103         7960 :     case IX86_BUILTIN_PSRLD256:
   20104         7960 :     case IX86_BUILTIN_PSRLD256_MASK:
   20105         7960 :     case IX86_BUILTIN_PSRLD512:
   20106         7960 :     case IX86_BUILTIN_PSRLDI:
   20107         7960 :     case IX86_BUILTIN_PSRLDI128:
   20108         7960 :     case IX86_BUILTIN_PSRLDI128_MASK:
   20109         7960 :     case IX86_BUILTIN_PSRLDI256:
   20110         7960 :     case IX86_BUILTIN_PSRLDI256_MASK:
   20111         7960 :     case IX86_BUILTIN_PSRLDI512:
   20112         7960 :     case IX86_BUILTIN_PSRLQ:
   20113         7960 :     case IX86_BUILTIN_PSRLQ128:
   20114         7960 :     case IX86_BUILTIN_PSRLQ128_MASK:
   20115         7960 :     case IX86_BUILTIN_PSRLQ256:
   20116         7960 :     case IX86_BUILTIN_PSRLQ256_MASK:
   20117         7960 :     case IX86_BUILTIN_PSRLQ512:
   20118         7960 :     case IX86_BUILTIN_PSRLQI:
   20119         7960 :     case IX86_BUILTIN_PSRLQI128:
   20120         7960 :     case IX86_BUILTIN_PSRLQI128_MASK:
   20121         7960 :     case IX86_BUILTIN_PSRLQI256:
   20122         7960 :     case IX86_BUILTIN_PSRLQI256_MASK:
   20123         7960 :     case IX86_BUILTIN_PSRLQI512:
   20124         7960 :     case IX86_BUILTIN_PSRLW:
   20125         7960 :     case IX86_BUILTIN_PSRLW128:
   20126         7960 :     case IX86_BUILTIN_PSRLW128_MASK:
   20127         7960 :     case IX86_BUILTIN_PSRLW256:
   20128         7960 :     case IX86_BUILTIN_PSRLW256_MASK:
   20129         7960 :     case IX86_BUILTIN_PSRLW512:
   20130         7960 :     case IX86_BUILTIN_PSRLWI:
   20131         7960 :     case IX86_BUILTIN_PSRLWI128:
   20132         7960 :     case IX86_BUILTIN_PSRLWI128_MASK:
   20133         7960 :     case IX86_BUILTIN_PSRLWI256:
   20134         7960 :     case IX86_BUILTIN_PSRLWI256_MASK:
   20135         7960 :     case IX86_BUILTIN_PSRLWI512:
   20136         7960 :       rcode = LSHIFTRT;
   20137         7960 :       is_vshift = false;
   20138         7960 :       goto do_shift;
   20139         2384 :     case IX86_BUILTIN_PSLLVV16HI:
   20140         2384 :     case IX86_BUILTIN_PSLLVV16SI:
   20141         2384 :     case IX86_BUILTIN_PSLLVV2DI:
   20142         2384 :     case IX86_BUILTIN_PSLLVV2DI_MASK:
   20143         2384 :     case IX86_BUILTIN_PSLLVV32HI:
   20144         2384 :     case IX86_BUILTIN_PSLLVV4DI:
   20145         2384 :     case IX86_BUILTIN_PSLLVV4DI_MASK:
   20146         2384 :     case IX86_BUILTIN_PSLLVV4SI:
   20147         2384 :     case IX86_BUILTIN_PSLLVV4SI_MASK:
   20148         2384 :     case IX86_BUILTIN_PSLLVV8DI:
   20149         2384 :     case IX86_BUILTIN_PSLLVV8HI:
   20150         2384 :     case IX86_BUILTIN_PSLLVV8SI:
   20151         2384 :     case IX86_BUILTIN_PSLLVV8SI_MASK:
   20152         2384 :       rcode = ASHIFT;
   20153         2384 :       is_vshift = true;
   20154         2384 :       goto do_shift;
   20155         2341 :     case IX86_BUILTIN_PSRAVQ128:
   20156         2341 :     case IX86_BUILTIN_PSRAVQ256:
   20157         2341 :     case IX86_BUILTIN_PSRAVV16HI:
   20158         2341 :     case IX86_BUILTIN_PSRAVV16SI:
   20159         2341 :     case IX86_BUILTIN_PSRAVV32HI:
   20160         2341 :     case IX86_BUILTIN_PSRAVV4SI:
   20161         2341 :     case IX86_BUILTIN_PSRAVV4SI_MASK:
   20162         2341 :     case IX86_BUILTIN_PSRAVV8DI:
   20163         2341 :     case IX86_BUILTIN_PSRAVV8HI:
   20164         2341 :     case IX86_BUILTIN_PSRAVV8SI:
   20165         2341 :     case IX86_BUILTIN_PSRAVV8SI_MASK:
   20166         2341 :       rcode = ASHIFTRT;
   20167         2341 :       is_vshift = true;
   20168         2341 :       goto do_shift;
   20169         2380 :     case IX86_BUILTIN_PSRLVV16HI:
   20170         2380 :     case IX86_BUILTIN_PSRLVV16SI:
   20171         2380 :     case IX86_BUILTIN_PSRLVV2DI:
   20172         2380 :     case IX86_BUILTIN_PSRLVV2DI_MASK:
   20173         2380 :     case IX86_BUILTIN_PSRLVV32HI:
   20174         2380 :     case IX86_BUILTIN_PSRLVV4DI:
   20175         2380 :     case IX86_BUILTIN_PSRLVV4DI_MASK:
   20176         2380 :     case IX86_BUILTIN_PSRLVV4SI:
   20177         2380 :     case IX86_BUILTIN_PSRLVV4SI_MASK:
   20178         2380 :     case IX86_BUILTIN_PSRLVV8DI:
   20179         2380 :     case IX86_BUILTIN_PSRLVV8HI:
   20180         2380 :     case IX86_BUILTIN_PSRLVV8SI:
   20181         2380 :     case IX86_BUILTIN_PSRLVV8SI_MASK:
   20182         2380 :       rcode = LSHIFTRT;
   20183         2380 :       is_vshift = true;
   20184         2380 :       goto do_shift;
   20185              : 
   20186        30857 :     do_shift:
   20187        30857 :       gcc_assert (n_args >= 2);
   20188        30857 :       if (!gimple_call_lhs (stmt))
   20189              :         {
   20190            1 :           gsi_replace (gsi, gimple_build_nop (), false);
   20191            1 :           return true;
   20192              :         }
   20193        30856 :       arg0 = gimple_call_arg (stmt, 0);
   20194        30856 :       arg1 = gimple_call_arg (stmt, 1);
   20195        30856 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20196              :       /* For masked shift, only optimize if the mask is all ones.  */
   20197        30856 :       if (n_args > 2
   20198        30856 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   20199              :         break;
   20200        16081 :       if (is_vshift)
   20201              :         {
   20202         2640 :           if (TREE_CODE (arg1) != VECTOR_CST)
   20203              :             break;
   20204           69 :           count = TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0)));
   20205           69 :           if (integer_zerop (arg1))
   20206           27 :             count = 0;
   20207           42 :           else if (rcode == ASHIFTRT)
   20208              :             break;
   20209              :           else
   20210          230 :             for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg1); ++i)
   20211              :               {
   20212          212 :                 tree elt = VECTOR_CST_ELT (arg1, i);
   20213          212 :                 if (!wi::neg_p (wi::to_wide (elt))
   20214          375 :                     && wi::to_widest (elt) < count)
   20215           16 :                   return false;
   20216              :               }
   20217              :         }
   20218              :       else
   20219              :         {
   20220        13441 :           arg1 = ix86_vector_shift_count (arg1);
   20221        13441 :           if (!arg1)
   20222              :             break;
   20223         5608 :           count = tree_to_uhwi (arg1);
   20224              :         }
   20225         5653 :       if (count == 0)
   20226              :         {
   20227              :           /* Just return the first argument for shift by 0.  */
   20228           93 :           loc = gimple_location (stmt);
   20229           93 :           g = gimple_build_assign (gimple_call_lhs (stmt), arg0);
   20230           93 :           gimple_set_location (g, loc);
   20231           93 :           gsi_replace (gsi, g, false);
   20232           93 :           return true;
   20233              :         }
   20234         5560 :       if (rcode != ASHIFTRT
   20235         5560 :           && count >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (arg0))))
   20236              :         {
   20237              :           /* For shift counts equal or greater than precision, except for
   20238              :              arithmetic right shift the result is zero.  */
   20239           78 :           loc = gimple_location (stmt);
   20240           78 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   20241           78 :                                    build_zero_cst (TREE_TYPE (arg0)));
   20242           78 :           gimple_set_location (g, loc);
   20243           78 :           gsi_replace (gsi, g, false);
   20244           78 :           return true;
   20245              :         }
   20246              :       break;
   20247              : 
   20248          531 :     case IX86_BUILTIN_SHUFPD512:
   20249          531 :     case IX86_BUILTIN_SHUFPS512:
   20250          531 :     case IX86_BUILTIN_SHUFPD:
   20251          531 :     case IX86_BUILTIN_SHUFPD256:
   20252          531 :     case IX86_BUILTIN_SHUFPS:
   20253          531 :     case IX86_BUILTIN_SHUFPS256:
   20254          531 :       arg0 = gimple_call_arg (stmt, 0);
   20255          531 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20256              :       /* This is masked shuffle.  Only optimize if the mask is all ones.  */
   20257          531 :       if (n_args > 3
   20258          895 :           && !ix86_masked_all_ones (elems,
   20259          364 :                                     gimple_call_arg (stmt, n_args - 1)))
   20260              :         break;
   20261          203 :       arg2 = gimple_call_arg (stmt, 2);
   20262          203 :       if (TREE_CODE (arg2) == INTEGER_CST && gimple_call_lhs (stmt))
   20263              :         {
   20264          146 :           unsigned HOST_WIDE_INT shuffle_mask = TREE_INT_CST_LOW (arg2);
   20265              :           /* Check valid imm, refer to gcc.target/i386/testimm-10.c.  */
   20266          146 :           if (shuffle_mask > 255)
   20267              :             return false;
   20268              : 
   20269          144 :           machine_mode imode = GET_MODE_INNER (TYPE_MODE (TREE_TYPE (arg0)));
   20270          144 :           loc = gimple_location (stmt);
   20271          144 :           tree itype = (imode == E_DFmode
   20272          144 :                         ? long_long_integer_type_node : integer_type_node);
   20273          144 :           tree vtype = build_vector_type (itype, elems);
   20274          144 :           tree_vector_builder elts (vtype, elems, 1);
   20275              : 
   20276              : 
   20277              :           /* Transform integer shuffle_mask to vector perm_mask which
   20278              :              is used by vec_perm_expr, refer to shuflp[sd]256/512 in sse.md.  */
   20279          984 :           for (unsigned i = 0; i != elems; i++)
   20280              :             {
   20281          696 :               unsigned sel_idx;
   20282              :               /* Imm[1:0](if VL > 128, then use Imm[3:2],Imm[5:4],Imm[7:6])
   20283              :                  provide 2 select controls for each element of the
   20284              :                  destination.  */
   20285          696 :               if (imode == E_DFmode)
   20286          240 :                 sel_idx = (i & 1) * elems + (i & ~1)
   20287          240 :                           + ((shuffle_mask >> i) & 1);
   20288              :               else
   20289              :                 {
   20290              :                   /* Imm[7:0](if VL > 128, also use Imm[7:0]) provide 4 select
   20291              :                      controls for each element of the destination.  */
   20292          456 :                   unsigned j = i % 4;
   20293          456 :                   sel_idx = ((i >> 1) & 1) * elems + (i & ~3)
   20294          456 :                             + ((shuffle_mask >> 2 * j) & 3);
   20295              :                 }
   20296          696 :               elts.quick_push (build_int_cst (itype, sel_idx));
   20297              :             }
   20298              : 
   20299          144 :           tree perm_mask = elts.build ();
   20300          144 :           arg1 = gimple_call_arg (stmt, 1);
   20301          144 :           g = gimple_build_assign (gimple_call_lhs (stmt),
   20302              :                                    VEC_PERM_EXPR,
   20303              :                                    arg0, arg1, perm_mask);
   20304          144 :           gimple_set_location (g, loc);
   20305          144 :           gsi_replace (gsi, g, false);
   20306          144 :           return true;
   20307          144 :         }
   20308              :       // Do not error yet, the constant could be propagated later?
   20309              :       break;
   20310              : 
   20311           48 :     case IX86_BUILTIN_PABSB:
   20312           48 :     case IX86_BUILTIN_PABSW:
   20313           48 :     case IX86_BUILTIN_PABSD:
   20314              :       /* 64-bit vector abs<mode>2 is only supported under TARGET_MMX_WITH_SSE.  */
   20315           48 :       if (!TARGET_MMX_WITH_SSE)
   20316              :         break;
   20317              :       /* FALLTHRU.  */
   20318         2190 :     case IX86_BUILTIN_PABSB128:
   20319         2190 :     case IX86_BUILTIN_PABSB256:
   20320         2190 :     case IX86_BUILTIN_PABSB512:
   20321         2190 :     case IX86_BUILTIN_PABSW128:
   20322         2190 :     case IX86_BUILTIN_PABSW256:
   20323         2190 :     case IX86_BUILTIN_PABSW512:
   20324         2190 :     case IX86_BUILTIN_PABSD128:
   20325         2190 :     case IX86_BUILTIN_PABSD256:
   20326         2190 :     case IX86_BUILTIN_PABSD512:
   20327         2190 :     case IX86_BUILTIN_PABSQ128:
   20328         2190 :     case IX86_BUILTIN_PABSQ256:
   20329         2190 :     case IX86_BUILTIN_PABSQ512:
   20330         2190 :     case IX86_BUILTIN_PABSB128_MASK:
   20331         2190 :     case IX86_BUILTIN_PABSB256_MASK:
   20332         2190 :     case IX86_BUILTIN_PABSW128_MASK:
   20333         2190 :     case IX86_BUILTIN_PABSW256_MASK:
   20334         2190 :     case IX86_BUILTIN_PABSD128_MASK:
   20335         2190 :     case IX86_BUILTIN_PABSD256_MASK:
   20336         2190 :       gcc_assert (n_args >= 1);
   20337         2190 :       if (!gimple_call_lhs (stmt))
   20338              :         {
   20339            1 :           gsi_replace (gsi, gimple_build_nop (), false);
   20340            1 :           return true;
   20341              :         }
   20342         2189 :       arg0 = gimple_call_arg (stmt, 0);
   20343         2189 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20344              :       /* For masked ABS, only optimize if the mask is all ones.  */
   20345         2189 :       if (n_args > 1
   20346         2189 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, n_args - 1)))
   20347              :         break;
   20348          229 :       {
   20349          229 :         tree utype, ures, vce;
   20350          229 :         utype = unsigned_type_for (TREE_TYPE (arg0));
   20351              :         /* PABSB/W/D/Q store the unsigned result in dst, use ABSU_EXPR
   20352              :            instead of ABS_EXPR to handle overflow case(TYPE_MIN).  */
   20353          229 :         ures = gimple_build (&stmts, ABSU_EXPR, utype, arg0);
   20354          229 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   20355          229 :         loc = gimple_location (stmt);
   20356          229 :         vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg0), ures);
   20357          229 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   20358              :                                  VIEW_CONVERT_EXPR, vce);
   20359          229 :         gsi_replace (gsi, g, false);
   20360              :       }
   20361          229 :       return true;
   20362              : 
   20363         2225 :     case IX86_BUILTIN_MINPS:
   20364         2225 :     case IX86_BUILTIN_MINPD:
   20365         2225 :     case IX86_BUILTIN_MINPS256:
   20366         2225 :     case IX86_BUILTIN_MINPD256:
   20367         2225 :     case IX86_BUILTIN_MINPS512:
   20368         2225 :     case IX86_BUILTIN_MINPD512:
   20369         2225 :     case IX86_BUILTIN_MINPS128_MASK:
   20370         2225 :     case IX86_BUILTIN_MINPD128_MASK:
   20371         2225 :     case IX86_BUILTIN_MINPS256_MASK:
   20372         2225 :     case IX86_BUILTIN_MINPD256_MASK:
   20373         2225 :     case IX86_BUILTIN_MINPH128_MASK:
   20374         2225 :     case IX86_BUILTIN_MINPH256_MASK:
   20375         2225 :     case IX86_BUILTIN_MINPH512_MASK:
   20376         2225 :       tcode = LT_EXPR;
   20377         2225 :       goto do_minmax;
   20378              : 
   20379              :     case IX86_BUILTIN_MAXPS:
   20380              :     case IX86_BUILTIN_MAXPD:
   20381              :     case IX86_BUILTIN_MAXPS256:
   20382              :     case IX86_BUILTIN_MAXPD256:
   20383              :     case IX86_BUILTIN_MAXPS512:
   20384              :     case IX86_BUILTIN_MAXPD512:
   20385              :     case IX86_BUILTIN_MAXPS128_MASK:
   20386              :     case IX86_BUILTIN_MAXPD128_MASK:
   20387              :     case IX86_BUILTIN_MAXPS256_MASK:
   20388              :     case IX86_BUILTIN_MAXPD256_MASK:
   20389              :     case IX86_BUILTIN_MAXPH128_MASK:
   20390              :     case IX86_BUILTIN_MAXPH256_MASK:
   20391              :     case IX86_BUILTIN_MAXPH512_MASK:
   20392              :       tcode = GT_EXPR;
   20393         4435 :     do_minmax:
   20394         4435 :       gcc_assert (n_args >= 2);
   20395              :       /* Without SSE4.1 we often aren't able to pattern match it back to the
   20396              :          desired instruction.  */
   20397         4435 :       if (!gimple_call_lhs (stmt) || !optimize || !TARGET_SSE4_1)
   20398              :         break;
   20399         3865 :       arg0 = gimple_call_arg (stmt, 0);
   20400         3865 :       arg1 = gimple_call_arg (stmt, 1);
   20401         3865 :       elems = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
   20402              :       /* For masked minmax, only optimize if the mask is all ones.  */
   20403         3865 :       if (n_args > 2
   20404         3865 :           && !ix86_masked_all_ones (elems, gimple_call_arg (stmt, 3)))
   20405              :         break;
   20406          647 :       if (n_args >= 5)
   20407              :         {
   20408          436 :           tree arg4 = gimple_call_arg (stmt, 4);
   20409          436 :           if (!tree_fits_uhwi_p (arg4))
   20410              :             break;
   20411          424 :           if (tree_to_uhwi (arg4) == 4)
   20412              :             /* Ok.  */;
   20413          416 :           else if (tree_to_uhwi (arg4) != 8)
   20414              :             /* Invalid round argument.  */
   20415              :             break;
   20416          416 :           else if (HONOR_NANS (arg0))
   20417              :             /* Lowering to comparison would raise exceptions which
   20418              :                shouldn't be raised.  */
   20419              :             break;
   20420              :         }
   20421          219 :       {
   20422          219 :         tree type = truth_type_for (TREE_TYPE (arg0));
   20423          219 :         tree cmpres = gimple_build (&stmts, tcode, type, arg0, arg1);
   20424          219 :         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
   20425          219 :         g = gimple_build_assign (gimple_call_lhs (stmt),
   20426              :                                  VEC_COND_EXPR, cmpres, arg0, arg1);
   20427          219 :         gsi_replace (gsi, g, false);
   20428              :       }
   20429          219 :       return true;
   20430              : 
   20431              :     default:
   20432              :       break;
   20433              :     }
   20434              : 
   20435              :   return false;
   20436              : }
   20437              : 
   20438              : /* Handler for an SVML-style interface to
   20439              :    a library with vectorized intrinsics.  */
   20440              : 
   20441              : tree
   20442           10 : ix86_veclibabi_svml (combined_fn fn, tree type_out, tree type_in)
   20443              : {
   20444           10 :   char name[20];
   20445           10 :   tree fntype, new_fndecl, args;
   20446           10 :   unsigned arity;
   20447           10 :   const char *bname;
   20448           10 :   machine_mode el_mode, in_mode;
   20449           10 :   int n, in_n;
   20450              : 
   20451              :   /* The SVML is suitable for unsafe math only.  */
   20452           10 :   if (!flag_unsafe_math_optimizations)
   20453              :     return NULL_TREE;
   20454              : 
   20455           10 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   20456           10 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   20457           10 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   20458           10 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   20459           10 :   if (el_mode != in_mode
   20460           10 :       || n != in_n)
   20461              :     return NULL_TREE;
   20462              : 
   20463           10 :   switch (fn)
   20464              :     {
   20465           10 :     CASE_CFN_EXP:
   20466           10 :     CASE_CFN_LOG:
   20467           10 :     CASE_CFN_LOG10:
   20468           10 :     CASE_CFN_POW:
   20469           10 :     CASE_CFN_TANH:
   20470           10 :     CASE_CFN_TAN:
   20471           10 :     CASE_CFN_ATAN:
   20472           10 :     CASE_CFN_ATAN2:
   20473           10 :     CASE_CFN_ATANH:
   20474           10 :     CASE_CFN_CBRT:
   20475           10 :     CASE_CFN_SINH:
   20476           10 :     CASE_CFN_SIN:
   20477           10 :     CASE_CFN_ASINH:
   20478           10 :     CASE_CFN_ASIN:
   20479           10 :     CASE_CFN_COSH:
   20480           10 :     CASE_CFN_COS:
   20481           10 :     CASE_CFN_ACOSH:
   20482           10 :     CASE_CFN_ACOS:
   20483           10 :       if ((el_mode != DFmode || n != 2)
   20484            8 :           && (el_mode != SFmode || n != 4))
   20485              :         return NULL_TREE;
   20486            6 :       break;
   20487              : 
   20488              :     default:
   20489              :       return NULL_TREE;
   20490              :     }
   20491              : 
   20492            6 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20493              :                                  ? double_type_node : float_type_node, fn);
   20494            6 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20495              : 
   20496            6 :   if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
   20497            2 :     strcpy (name, "vmlsLn4");
   20498            4 :   else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOG)
   20499            0 :     strcpy (name, "vmldLn2");
   20500            4 :   else if (n == 4)
   20501              :     {
   20502            2 :       sprintf (name, "vmls%s", bname+10);
   20503            2 :       name[strlen (name)-1] = '4';
   20504              :     }
   20505              :   else
   20506            2 :     sprintf (name, "vmld%s2", bname+10);
   20507              : 
   20508              :   /* Convert to uppercase. */
   20509            6 :   name[4] &= ~0x20;
   20510              : 
   20511            6 :   arity = 0;
   20512            6 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20513            0 :     arity++;
   20514              : 
   20515            6 :   if (arity == 1)
   20516            0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20517              :   else
   20518            6 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20519              : 
   20520              :   /* Build a function declaration for the vectorized function.  */
   20521            6 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20522              :                            FUNCTION_DECL, get_identifier (name), fntype);
   20523            6 :   TREE_PUBLIC (new_fndecl) = 1;
   20524            6 :   DECL_EXTERNAL (new_fndecl) = 1;
   20525            6 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   20526            6 :   TREE_READONLY (new_fndecl) = 1;
   20527              : 
   20528            6 :   return new_fndecl;
   20529              : }
   20530              : 
   20531              : /* Handler for an ACML-style interface to
   20532              :    a library with vectorized intrinsics.  */
   20533              : 
   20534              : tree
   20535            3 : ix86_veclibabi_acml (combined_fn fn, tree type_out, tree type_in)
   20536              : {
   20537            3 :   char name[20] = "__vr.._";
   20538            3 :   tree fntype, new_fndecl, args;
   20539            3 :   unsigned arity;
   20540            3 :   const char *bname;
   20541            3 :   machine_mode el_mode, in_mode;
   20542            3 :   int n, in_n;
   20543              : 
   20544              :   /* The ACML is 64bits only and suitable for unsafe math only as
   20545              :      it does not correctly support parts of IEEE with the required
   20546              :      precision such as denormals.  */
   20547            3 :   if (!TARGET_64BIT
   20548            3 :       || !flag_unsafe_math_optimizations)
   20549              :     return NULL_TREE;
   20550              : 
   20551            3 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   20552            3 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   20553            3 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   20554            3 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   20555            3 :   if (el_mode != in_mode
   20556            3 :       || n != in_n)
   20557              :     return NULL_TREE;
   20558              : 
   20559            3 :   switch (fn)
   20560              :     {
   20561            3 :     CASE_CFN_SIN:
   20562            3 :     CASE_CFN_COS:
   20563            3 :     CASE_CFN_EXP:
   20564            3 :     CASE_CFN_LOG:
   20565            3 :     CASE_CFN_LOG2:
   20566            3 :     CASE_CFN_LOG10:
   20567            3 :       if (el_mode == DFmode && n == 2)
   20568              :         {
   20569            3 :           name[4] = 'd';
   20570            3 :           name[5] = '2';
   20571              :         }
   20572            0 :       else if (el_mode == SFmode && n == 4)
   20573              :         {
   20574            0 :           name[4] = 's';
   20575            0 :           name[5] = '4';
   20576              :         }
   20577              :       else
   20578              :         return NULL_TREE;
   20579            3 :       break;
   20580              : 
   20581              :     default:
   20582              :       return NULL_TREE;
   20583              :     }
   20584              : 
   20585            3 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20586              :                                  ? double_type_node : float_type_node, fn);
   20587            3 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20588            3 :   sprintf (name + 7, "%s", bname+10);
   20589              : 
   20590            3 :   arity = 0;
   20591            3 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20592            0 :     arity++;
   20593              : 
   20594            3 :   if (arity == 1)
   20595            0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20596              :   else
   20597            3 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20598              : 
   20599              :   /* Build a function declaration for the vectorized function.  */
   20600            3 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20601              :                            FUNCTION_DECL, get_identifier (name), fntype);
   20602            3 :   TREE_PUBLIC (new_fndecl) = 1;
   20603            3 :   DECL_EXTERNAL (new_fndecl) = 1;
   20604            3 :   DECL_IS_NOVOPS (new_fndecl) = 1;
   20605            3 :   TREE_READONLY (new_fndecl) = 1;
   20606              : 
   20607            3 :   return new_fndecl;
   20608              : }
   20609              : 
   20610              : /* Handler for an AOCL-LibM-style interface to
   20611              :    a library with vectorized intrinsics.  */
   20612              : 
   20613              : tree
   20614          386 : ix86_veclibabi_aocl (combined_fn fn, tree type_out, tree type_in)
   20615              : {
   20616          386 :   char name[20] = "amd_vr";
   20617          386 :   int name_len = 6;
   20618          386 :   tree fntype, new_fndecl, args;
   20619          386 :   unsigned arity;
   20620          386 :   const char *bname;
   20621          386 :   machine_mode el_mode, in_mode;
   20622          386 :   int n, in_n;
   20623              : 
   20624              :   /* AOCL-LibM is 64bits only.  It is also only suitable for unsafe math only
   20625              :      as it trades off some accuracy for increased performance.  */
   20626          386 :   if (!TARGET_64BIT
   20627          386 :       || !flag_unsafe_math_optimizations)
   20628              :     return NULL_TREE;
   20629              : 
   20630          386 :   el_mode = TYPE_MODE (TREE_TYPE (type_out));
   20631          386 :   n = TYPE_VECTOR_SUBPARTS (type_out);
   20632          386 :   in_mode = TYPE_MODE (TREE_TYPE (type_in));
   20633          386 :   in_n = TYPE_VECTOR_SUBPARTS (type_in);
   20634          386 :   if (el_mode != in_mode
   20635          386 :       || n != in_n)
   20636              :     return NULL_TREE;
   20637              : 
   20638          386 :   gcc_checking_assert (n > 0);
   20639              : 
   20640              :   /* Decide whether there exists a function for the combination of FN, the mode
   20641              :      and the vector width.  Return early if it doesn't.  */
   20642              : 
   20643          386 :   if (el_mode != DFmode && el_mode != SFmode)
   20644              :     return NULL_TREE;
   20645              : 
   20646              :   /* Supported vector widths for given FN and single/double precision.  Zeros
   20647              :      are used to fill out unused positions in the arrays.  */
   20648          386 :   static const int supported_n[][2][3] = {
   20649              :   /*   Single prec. ,  Double prec.  */
   20650              :     { { 16,  0,  0 }, {  2,  4,  8 } }, /* TAN.  */
   20651              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* EXP.  */
   20652              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* EXP2.  */
   20653              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* LOG.  */
   20654              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* LOG2.  */
   20655              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* COS.  */
   20656              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* SIN.  */
   20657              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* POW.  */
   20658              :     { {  4,  8, 16 }, {  2,  4,  8 } }, /* ERF.  */
   20659              :     { {  4,  8, 16 }, {  2,  8,  0 } }, /* ATAN.  */
   20660              :     { {  4,  8, 16 }, {  2,  0,  0 } }, /* LOG10.  */
   20661              :     { {  4,  0,  0 }, {  2,  0,  0 } }, /* EXP10.  */
   20662              :     { {  4,  0,  0 }, {  2,  0,  0 } }, /* LOG1P.  */
   20663              :     { {  4,  8, 16 }, {  8,  0,  0 } }, /* ASIN.  */
   20664              :     { {  4, 16,  0 }, {  0,  0,  0 } }, /* ACOS.  */
   20665              :     { {  4,  8, 16 }, {  0,  0,  0 } }, /* TANH.  */
   20666              :     { {  4,  0,  0 }, {  0,  0,  0 } }, /* EXPM1.  */
   20667              :     { {  4,  8,  0 }, {  0,  0,  0 } }, /* COSH.  */
   20668              :   };
   20669              : 
   20670              :   /* We cannot simply index the supported_n array with FN since multiple FNs
   20671              :      may correspond to a single operation (see the definitions of these
   20672              :      CASE_CFN_* macros).  */
   20673          386 :   int i;
   20674          386 :   switch (fn)
   20675              :     {
   20676              :     CASE_CFN_TAN   :  i = 0; break;
   20677           28 :     CASE_CFN_EXP   :  i = 1; break;
   20678           28 :     CASE_CFN_EXP2  :  i = 2; break;
   20679           28 :     CASE_CFN_LOG   :  i = 3; break;
   20680           28 :     CASE_CFN_LOG2  :  i = 4; break;
   20681           28 :     CASE_CFN_COS   :  i = 5; break;
   20682           28 :     CASE_CFN_SIN   :  i = 6; break;
   20683           28 :     CASE_CFN_POW   :  i = 7; break;
   20684           28 :     CASE_CFN_ERF   :  i = 8; break;
   20685           25 :     CASE_CFN_ATAN  :  i = 9; break;
   20686           20 :     CASE_CFN_LOG10 : i = 10; break;
   20687           10 :     CASE_CFN_EXP10 : i = 11; break;
   20688           10 :     CASE_CFN_LOG1P : i = 12; break;
   20689           24 :     CASE_CFN_ASIN  : i = 13; break;
   20690           14 :     CASE_CFN_ACOS  : i = 14; break;
   20691           18 :     CASE_CFN_TANH  : i = 15; break;
   20692            9 :     CASE_CFN_EXPM1 : i = 16; break;
   20693           14 :     CASE_CFN_COSH  : i = 17; break;
   20694              :     default: return NULL_TREE;
   20695              :     }
   20696              : 
   20697          386 :   int j = el_mode == DFmode;
   20698          386 :   bool n_is_supported = false;
   20699          976 :   for (unsigned k = 0; k < 3; k++)
   20700          857 :     if (supported_n[i][j][k] == n)
   20701              :       {
   20702              :         n_is_supported = true;
   20703              :         break;
   20704              :       }
   20705          386 :   if (!n_is_supported)
   20706              :     return NULL_TREE;
   20707              : 
   20708              :   /* Append the precision and the vector width to the function name we are
   20709              :      constructing.  */
   20710          267 :   name[name_len++] = el_mode == DFmode ? 'd' : 's';
   20711          267 :   switch (n)
   20712              :     {
   20713          214 :       case 2:
   20714          214 :       case 4:
   20715          214 :       case 8:
   20716          214 :         name[name_len++] = '0' + n;
   20717          214 :         break;
   20718           53 :       case 16:
   20719           53 :         name[name_len++] = '1';
   20720           53 :         name[name_len++] = '6';
   20721           53 :         break;
   20722            0 :       default:
   20723            0 :         gcc_unreachable ();
   20724              :     }
   20725          267 :   name[name_len++] = '_';
   20726              : 
   20727              :   /* Append the operation name (steal it from the name of a builtin).  */
   20728          267 :   tree fndecl = mathfn_built_in (el_mode == DFmode
   20729              :                                  ? double_type_node : float_type_node, fn);
   20730          267 :   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   20731          267 :   sprintf (name + name_len, "%s", bname + 10);
   20732              : 
   20733          267 :   arity = 0;
   20734          267 :   for (args = DECL_ARGUMENTS (fndecl); args; args = TREE_CHAIN (args))
   20735            0 :     arity++;
   20736              : 
   20737          267 :   if (arity == 1)
   20738            0 :     fntype = build_function_type_list (type_out, type_in, NULL);
   20739              :   else
   20740          267 :     fntype = build_function_type_list (type_out, type_in, type_in, NULL);
   20741              : 
   20742              :   /* Build a function declaration for the vectorized function.  */
   20743          267 :   new_fndecl = build_decl (BUILTINS_LOCATION,
   20744              :                            FUNCTION_DECL, get_identifier (name), fntype);
   20745          267 :   TREE_PUBLIC (new_fndecl) = 1;
   20746          267 :   DECL_EXTERNAL (new_fndecl) = 1;
   20747          267 :   TREE_READONLY (new_fndecl) = 1;
   20748              : 
   20749          267 :   return new_fndecl;
   20750              : }
   20751              : 
   20752              : /* Returns a decl of a function that implements scatter store with
   20753              :    register type VECTYPE and index type INDEX_TYPE and SCALE.
   20754              :    Return NULL_TREE if it is not available.  */
   20755              : 
   20756              : static tree
   20757       142198 : ix86_vectorize_builtin_scatter (const_tree vectype,
   20758              :                                 const_tree index_type, int scale)
   20759              : {
   20760       142198 :   bool si;
   20761       142198 :   enum ix86_builtins code;
   20762              : 
   20763       142198 :   if (!TARGET_AVX512F)
   20764              :     return NULL_TREE;
   20765              : 
   20766         4222 :   if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 2u)
   20767         7425 :       ? !TARGET_USE_SCATTER_2PARTS
   20768         7425 :       : (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 4u)
   20769         3203 :          ? !TARGET_USE_SCATTER_4PARTS
   20770         2076 :          : !TARGET_USE_SCATTER_8PARTS))
   20771              :     return NULL_TREE;
   20772              : 
   20773         4222 :   if ((TREE_CODE (index_type) != INTEGER_TYPE
   20774          465 :        && !POINTER_TYPE_P (index_type))
   20775         4687 :       || (TYPE_MODE (index_type) != SImode
   20776         1779 :           && TYPE_MODE (index_type) != DImode))
   20777              :     return NULL_TREE;
   20778              : 
   20779         4452 :   if (TYPE_PRECISION (index_type) > POINTER_SIZE)
   20780              :     return NULL_TREE;
   20781              : 
   20782              :   /* v*scatter* insn sign extends index to pointer mode.  */
   20783         4222 :   if (TYPE_PRECISION (index_type) < POINTER_SIZE
   20784         4222 :       && TYPE_UNSIGNED (index_type))
   20785              :     return NULL_TREE;
   20786              : 
   20787              :   /* Scale can be 1, 2, 4 or 8.  */
   20788         4222 :   if (scale <= 0
   20789         4222 :       || scale > 8
   20790         4206 :       || (scale & (scale - 1)) != 0)
   20791              :     return NULL_TREE;
   20792              : 
   20793         4206 :   si = TYPE_MODE (index_type) == SImode;
   20794         4206 :   switch (TYPE_MODE (vectype))
   20795              :     {
   20796          170 :     case E_V8DFmode:
   20797          170 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DF : IX86_BUILTIN_SCATTERDIV8DF;
   20798              :       break;
   20799          104 :     case E_V8DImode:
   20800          104 :       code = si ? IX86_BUILTIN_SCATTERALTSIV8DI : IX86_BUILTIN_SCATTERDIV8DI;
   20801              :       break;
   20802          177 :     case E_V16SFmode:
   20803          177 :       code = si ? IX86_BUILTIN_SCATTERSIV16SF : IX86_BUILTIN_SCATTERALTDIV16SF;
   20804              :       break;
   20805          266 :     case E_V16SImode:
   20806          266 :       code = si ? IX86_BUILTIN_SCATTERSIV16SI : IX86_BUILTIN_SCATTERALTDIV16SI;
   20807              :       break;
   20808          207 :     case E_V4DFmode:
   20809          207 :       if (TARGET_AVX512VL)
   20810           34 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DF : IX86_BUILTIN_SCATTERDIV4DF;
   20811              :       else
   20812              :         return NULL_TREE;
   20813              :       break;
   20814          142 :     case E_V4DImode:
   20815          142 :       if (TARGET_AVX512VL)
   20816           34 :         code = si ? IX86_BUILTIN_SCATTERALTSIV4DI : IX86_BUILTIN_SCATTERDIV4DI;
   20817              :       else
   20818              :         return NULL_TREE;
   20819              :       break;
   20820          248 :     case E_V8SFmode:
   20821          248 :       if (TARGET_AVX512VL)
   20822           40 :         code = si ? IX86_BUILTIN_SCATTERSIV8SF : IX86_BUILTIN_SCATTERALTDIV8SF;
   20823              :       else
   20824              :         return NULL_TREE;
   20825              :       break;
   20826          277 :     case E_V8SImode:
   20827          277 :       if (TARGET_AVX512VL)
   20828           82 :         code = si ? IX86_BUILTIN_SCATTERSIV8SI : IX86_BUILTIN_SCATTERALTDIV8SI;
   20829              :       else
   20830              :         return NULL_TREE;
   20831              :       break;
   20832          251 :     case E_V2DFmode:
   20833          251 :       if (TARGET_AVX512VL)
   20834           94 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DF : IX86_BUILTIN_SCATTERDIV2DF;
   20835              :       else
   20836              :         return NULL_TREE;
   20837              :       break;
   20838          196 :     case E_V2DImode:
   20839          196 :       if (TARGET_AVX512VL)
   20840           94 :         code = si ? IX86_BUILTIN_SCATTERALTSIV2DI : IX86_BUILTIN_SCATTERDIV2DI;
   20841              :       else
   20842              :         return NULL_TREE;
   20843              :       break;
   20844          301 :     case E_V4SFmode:
   20845          301 :       if (TARGET_AVX512VL)
   20846           96 :         code = si ? IX86_BUILTIN_SCATTERSIV4SF : IX86_BUILTIN_SCATTERALTDIV4SF;
   20847              :       else
   20848              :         return NULL_TREE;
   20849              :       break;
   20850          333 :     case E_V4SImode:
   20851          333 :       if (TARGET_AVX512VL)
   20852          138 :         code = si ? IX86_BUILTIN_SCATTERSIV4SI : IX86_BUILTIN_SCATTERALTDIV4SI;
   20853              :       else
   20854              :         return NULL_TREE;
   20855              :       break;
   20856              :     default:
   20857              :       return NULL_TREE;
   20858              :     }
   20859              : 
   20860         1329 :   return get_ix86_builtin (code);
   20861              : }
   20862              : 
   20863              : /* Return true if it is safe to use the rsqrt optabs to optimize
   20864              :    1.0/sqrt.  */
   20865              : 
   20866              : static bool
   20867           66 : use_rsqrt_p (machine_mode mode)
   20868              : {
   20869           66 :   return ((mode == HFmode
   20870           42 :            || (TARGET_SSE && TARGET_SSE_MATH))
   20871           66 :           && flag_finite_math_only
   20872           65 :           && !flag_trapping_math
   20873          119 :           && flag_unsafe_math_optimizations);
   20874              : }
   20875              : 
   20876              : /* Helper for avx_vpermilps256_operand et al.  This is also used by
   20877              :    the expansion functions to turn the parallel back into a mask.
   20878              :    The return value is 0 for no match and the imm8+1 for a match.  */
   20879              : 
   20880              : int
   20881        65476 : avx_vpermilp_parallel (rtx par, machine_mode mode)
   20882              : {
   20883        65476 :   unsigned i, nelt = GET_MODE_NUNITS (mode);
   20884        65476 :   unsigned mask = 0;
   20885        65476 :   unsigned char ipar[16] = {};  /* Silence -Wuninitialized warning.  */
   20886              : 
   20887        65476 :   if (XVECLEN (par, 0) != (int) nelt)
   20888              :     return 0;
   20889              : 
   20890              :   /* Validate that all of the elements are constants, and not totally
   20891              :      out of range.  Copy the data into an integral array to make the
   20892              :      subsequent checks easier.  */
   20893       316886 :   for (i = 0; i < nelt; ++i)
   20894              :     {
   20895       251410 :       rtx er = XVECEXP (par, 0, i);
   20896       251410 :       unsigned HOST_WIDE_INT ei;
   20897              : 
   20898       251410 :       if (!CONST_INT_P (er))
   20899              :         return 0;
   20900       251410 :       ei = INTVAL (er);
   20901       251410 :       if (ei >= nelt)
   20902              :         return 0;
   20903       251410 :       ipar[i] = ei;
   20904              :     }
   20905              : 
   20906        65476 :   switch (mode)
   20907              :     {
   20908              :     case E_V8DFmode:
   20909              :     case E_V8DImode:
   20910              :       /* In the 512-bit DFmode case, we can only move elements within
   20911              :          a 128-bit lane.  First fill the second part of the mask,
   20912              :          then fallthru.  */
   20913         4735 :       for (i = 4; i < 6; ++i)
   20914              :         {
   20915         3287 :           if (!IN_RANGE (ipar[i], 4, 5))
   20916              :             return 0;
   20917         3062 :           mask |= (ipar[i] - 4) << i;
   20918              :         }
   20919         3492 :       for (i = 6; i < 8; ++i)
   20920              :         {
   20921         2470 :           if (!IN_RANGE (ipar[i], 6, 7))
   20922              :             return 0;
   20923         2044 :           mask |= (ipar[i] - 6) << i;
   20924              :         }
   20925              :       /* FALLTHRU */
   20926              : 
   20927        20303 :     case E_V4DFmode:
   20928        20303 :     case E_V4DImode:
   20929              :       /* In the 256-bit DFmode case, we can only move elements within
   20930              :          a 128-bit lane.  */
   20931        46224 :       for (i = 0; i < 2; ++i)
   20932              :         {
   20933        38851 :           if (!IN_RANGE (ipar[i], 0, 1))
   20934              :             return 0;
   20935        25921 :           mask |= ipar[i] << i;
   20936              :         }
   20937        19421 :       for (i = 2; i < 4; ++i)
   20938              :         {
   20939        13402 :           if (!IN_RANGE (ipar[i], 2, 3))
   20940              :             return 0;
   20941        12048 :           mask |= (ipar[i] - 2) << i;
   20942              :         }
   20943              :       break;
   20944              : 
   20945              :     case E_V16SFmode:
   20946              :     case E_V16SImode:
   20947              :       /* In 512 bit SFmode case, permutation in the upper 256 bits
   20948              :          must mirror the permutation in the lower 256-bits.  */
   20949         3652 :       for (i = 0; i < 8; ++i)
   20950         3256 :         if (ipar[i] + 8 != ipar[i + 8])
   20951              :           return 0;
   20952              :       /* FALLTHRU */
   20953              : 
   20954              :     case E_V8SFmode:
   20955              :     case E_V8SImode:
   20956              :       /* In 256 bit SFmode case, we have full freedom of
   20957              :          movement within the low 128-bit lane, but the high 128-bit
   20958              :          lane must mirror the exact same pattern.  */
   20959        34080 :       for (i = 0; i < 4; ++i)
   20960        28881 :         if (ipar[i] + 4 != ipar[i + 4])
   20961              :           return 0;
   20962              :       nelt = 4;
   20963              :       /* FALLTHRU */
   20964              : 
   20965        39881 :     case E_V2DFmode:
   20966        39881 :     case E_V2DImode:
   20967        39881 :     case E_V4SFmode:
   20968        39881 :     case E_V4SImode:
   20969              :       /* In the 128-bit case, we've full freedom in the placement of
   20970              :          the elements from the source operand.  */
   20971       139003 :       for (i = 0; i < nelt; ++i)
   20972        99122 :         mask |= ipar[i] << (i * (nelt / 2));
   20973              :       break;
   20974              : 
   20975            0 :     default:
   20976            0 :       gcc_unreachable ();
   20977              :     }
   20978              : 
   20979              :   /* Make sure success has a non-zero value by adding one.  */
   20980        45900 :   return mask + 1;
   20981              : }
   20982              : 
   20983              : /* Helper for avx_vperm2f128_v4df_operand et al.  This is also used by
   20984              :    the expansion functions to turn the parallel back into a mask.
   20985              :    The return value is 0 for no match and the imm8+1 for a match.  */
   20986              : 
   20987              : int
   20988        42800 : avx_vperm2f128_parallel (rtx par, machine_mode mode)
   20989              : {
   20990        42800 :   unsigned i, nelt = GET_MODE_NUNITS (mode), nelt2 = nelt / 2;
   20991        42800 :   unsigned mask = 0;
   20992        42800 :   unsigned char ipar[8] = {};  /* Silence -Wuninitialized warning.  */
   20993              : 
   20994        42800 :   if (XVECLEN (par, 0) != (int) nelt)
   20995              :     return 0;
   20996              : 
   20997              :   /* Validate that all of the elements are constants, and not totally
   20998              :      out of range.  Copy the data into an integral array to make the
   20999              :      subsequent checks easier.  */
   21000       344520 :   for (i = 0; i < nelt; ++i)
   21001              :     {
   21002       301720 :       rtx er = XVECEXP (par, 0, i);
   21003       301720 :       unsigned HOST_WIDE_INT ei;
   21004              : 
   21005       301720 :       if (!CONST_INT_P (er))
   21006              :         return 0;
   21007       301720 :       ei = INTVAL (er);
   21008       301720 :       if (ei >= 2 * nelt)
   21009              :         return 0;
   21010       301720 :       ipar[i] = ei;
   21011              :     }
   21012              : 
   21013              :   /* Validate that the halves of the permute are halves.  */
   21014        82747 :   for (i = 0; i < nelt2 - 1; ++i)
   21015        66596 :     if (ipar[i] + 1 != ipar[i + 1])
   21016              :       return 0;
   21017        51160 :   for (i = nelt2; i < nelt - 1; ++i)
   21018        35661 :     if (ipar[i] + 1 != ipar[i + 1])
   21019              :       return 0;
   21020              : 
   21021              :   /* Reconstruct the mask.  */
   21022        46401 :   for (i = 0; i < 2; ++i)
   21023              :     {
   21024        30952 :       unsigned e = ipar[i * nelt2];
   21025        30952 :       if (e % nelt2)
   21026              :         return 0;
   21027        30902 :       e /= nelt2;
   21028        30902 :       mask |= e << (i * 4);
   21029              :     }
   21030              : 
   21031              :   /* Make sure success has a non-zero value by adding one.  */
   21032        15449 :   return mask + 1;
   21033              : }
   21034              : 
   21035              : /* Return a mask of VPTERNLOG operands that do not affect output.  */
   21036              : 
   21037              : int
   21038         2434 : vpternlog_redundant_operand_mask (rtx pternlog_imm)
   21039              : {
   21040         2434 :   int mask = 0;
   21041         2434 :   int imm8 = INTVAL (pternlog_imm);
   21042              : 
   21043         2434 :   if (((imm8 >> 4) & 0x0F) == (imm8 & 0x0F))
   21044            6 :     mask |= 1;
   21045         2434 :   if (((imm8 >> 2) & 0x33) == (imm8 & 0x33))
   21046            6 :     mask |= 2;
   21047         2434 :   if (((imm8 >> 1) & 0x55) == (imm8 & 0x55))
   21048          151 :     mask |= 4;
   21049              : 
   21050         2434 :   return mask;
   21051              : }
   21052              : 
   21053              : /* Eliminate false dependencies on operands that do not affect output
   21054              :    by substituting other operands of a VPTERNLOG.  */
   21055              : 
   21056              : void
   21057           79 : substitute_vpternlog_operands (rtx *operands)
   21058              : {
   21059           79 :   int mask = vpternlog_redundant_operand_mask (operands[4]);
   21060              : 
   21061           79 :   if (mask & 1) /* The first operand is redundant.  */
   21062            2 :     operands[1] = operands[2];
   21063              : 
   21064           79 :   if (mask & 2) /* The second operand is redundant.  */
   21065            2 :     operands[2] = operands[1];
   21066              : 
   21067           79 :   if (mask & 4) /* The third operand is redundant.  */
   21068           75 :     operands[3] = operands[1];
   21069            4 :   else if (REG_P (operands[3]))
   21070              :     {
   21071            0 :       if (mask & 1)
   21072            0 :         operands[1] = operands[3];
   21073            0 :       if (mask & 2)
   21074            0 :         operands[2] = operands[3];
   21075              :     }
   21076           79 : }
   21077              : 
   21078              : /* Return a register priority for hard reg REGNO.  */
   21079              : static int
   21080     60199083 : ix86_register_priority (int hard_regno)
   21081              : {
   21082              :   /* ebp and r13 as the base always wants a displacement, r12 as the
   21083              :      base always wants an index.  So discourage their usage in an
   21084              :      address.  */
   21085     60199083 :   if (hard_regno == R12_REG || hard_regno == R13_REG)
   21086              :     return 0;
   21087     55670076 :   if (hard_regno == BP_REG)
   21088              :     return 1;
   21089              :   /* New x86-64 int registers result in bigger code size.  Discourage them.  */
   21090     53680501 :   if (REX_INT_REGNO_P (hard_regno))
   21091              :     return 2;
   21092     36387440 :   if (REX2_INT_REGNO_P (hard_regno))
   21093              :     return 2;
   21094              :   /* New x86-64 SSE registers result in bigger code size.  Discourage them.  */
   21095     36384918 :   if (REX_SSE_REGNO_P (hard_regno))
   21096              :     return 2;
   21097     30330180 :   if (EXT_REX_SSE_REGNO_P (hard_regno))
   21098              :     return 1;
   21099              :   /* Usage of AX register results in smaller code.  Prefer it.  */
   21100     30050779 :   if (hard_regno == AX_REG)
   21101      4076297 :     return 4;
   21102              :   return 3;
   21103              : }
   21104              : 
   21105              : /* Implement TARGET_PREFERRED_RELOAD_CLASS.
   21106              : 
   21107              :    Put float CONST_DOUBLE in the constant pool instead of fp regs.
   21108              :    QImode must go into class Q_REGS.
   21109              :    Narrow ALL_REGS to GENERAL_REGS.  This supports allowing movsf and
   21110              :    movdf to do mem-to-mem moves through integer regs.  */
   21111              : 
   21112              : static reg_class_t
   21113    565768905 : ix86_preferred_reload_class (rtx x, reg_class_t regclass)
   21114              : {
   21115    565768905 :   machine_mode mode = GET_MODE (x);
   21116              : 
   21117              :   /* We're only allowed to return a subclass of CLASS.  Many of the
   21118              :      following checks fail for NO_REGS, so eliminate that early.  */
   21119    565768905 :   if (regclass == NO_REGS)
   21120              :     return NO_REGS;
   21121              : 
   21122              :   /* All classes can load zeros.  */
   21123    564858146 :   if (x == CONST0_RTX (mode))
   21124              :     return regclass;
   21125              : 
   21126              :   /* Force constants into memory if we are loading a non-zero constant
   21127              :      into an MMX, SSE or MASK register.  This is because there are no
   21128              :      MMX/SSE/MASK instructions to load from a constant.  Exceptions are
   21129              :      minus ones for MASK register and standard SSE constants for SSE
   21130              :      register.  */
   21131    539194277 :   if (CONSTANT_P (x))
   21132              :     {
   21133    157973174 :       if (MAYBE_MMX_CLASS_P (regclass))
   21134              :         return NO_REGS;
   21135    157849107 :        if (MAYBE_MASK_CLASS_P (regclass))
   21136        18947 :          return x == constm1_rtx ? regclass : NO_REGS;
   21137    157830160 :        if (MAYBE_SSE_CLASS_P (regclass))
   21138     13310360 :          return (mode != VOIDmode && standard_sse_constant_p (x, mode)
   21139     31354146 :                  ? regclass : NO_REGS);
   21140              :     }
   21141              : 
   21142              :   /* Floating-point constants need more complex checks.  */
   21143    507697117 :   if (CONST_DOUBLE_P (x))
   21144              :     {
   21145              :       /* General regs can load everything.  */
   21146       313858 :       if (INTEGER_CLASS_P (regclass))
   21147              :         return regclass;
   21148              : 
   21149              :       /* Floats can load 0 and 1 plus some others.  Note that we eliminated
   21150              :          zero above.  We only want to wind up preferring 80387 registers if
   21151              :          we plan on doing computation with them.  */
   21152       184204 :       if (IS_STACK_MODE (mode)
   21153       242707 :           && standard_80387_constant_p (x) > 0)
   21154              :         {
   21155              :           /* Limit class to FP regs.  */
   21156        40511 :           if (FLOAT_CLASS_P (regclass))
   21157              :             return FLOAT_REGS;
   21158              :         }
   21159              : 
   21160       143693 :       return NO_REGS;
   21161              :     }
   21162              : 
   21163              :   /* Prefer SSE if we can use them for math.  Also allow integer regs
   21164              :      when moves between register units are cheap.  */
   21165    507383259 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   21166              :     {
   21167     31518560 :       if (TARGET_INTER_UNIT_MOVES_FROM_VEC
   21168     31505077 :           && TARGET_INTER_UNIT_MOVES_TO_VEC
   21169     94519486 :           && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (word_mode))
   21170     31363162 :         return INT_SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   21171              :       else
   21172       155398 :         return SSE_CLASS_P (regclass) ? regclass : NO_REGS;
   21173              :     }
   21174              : 
   21175              :   /* Generally when we see PLUS here, it's the function invariant
   21176              :      (plus soft-fp const_int).  Which can only be computed into general
   21177              :      regs.  */
   21178    475864699 :   if (GET_CODE (x) == PLUS)
   21179      2121144 :     return INTEGER_CLASS_P (regclass) ? regclass : NO_REGS;
   21180              : 
   21181              :   /* QImode constants are easy to load, but non-constant QImode data
   21182              :      must go into Q_REGS or ALL_MASK_REGS.  */
   21183    473743555 :   if (GET_MODE (x) == QImode && !CONSTANT_P (x))
   21184              :     {
   21185     25463699 :       if (Q_CLASS_P (regclass))
   21186              :         return regclass;
   21187     20583853 :       else if (reg_class_subset_p (Q_REGS, regclass))
   21188              :         return Q_REGS;
   21189        55038 :       else if (MASK_CLASS_P (regclass))
   21190              :         return regclass;
   21191              :       else
   21192              :         return NO_REGS;
   21193              :     }
   21194              : 
   21195              :   return regclass;
   21196              : }
   21197              : 
   21198              : /* Discourage putting floating-point values in SSE registers unless
   21199              :    SSE math is being used, and likewise for the 387 registers.  */
   21200              : static reg_class_t
   21201     76784406 : ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
   21202              : {
   21203              :   /* Restrict the output reload class to the register bank that we are doing
   21204              :      math on.  If we would like not to return a subset of CLASS, reject this
   21205              :      alternative: if reload cannot do this, it will still use its choice.  */
   21206     76784406 :   machine_mode mode = GET_MODE (x);
   21207     76784406 :   if (SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH)
   21208      7357099 :     return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
   21209              : 
   21210     69427307 :   if (IS_STACK_MODE (mode))
   21211       211578 :     return FLOAT_CLASS_P (regclass) ? regclass : NO_REGS;
   21212              : 
   21213              :   return regclass;
   21214              : }
   21215              : 
   21216              : static reg_class_t
   21217    399077844 : ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
   21218              :                        machine_mode mode, secondary_reload_info *sri)
   21219              : {
   21220              :   /* Double-word spills from general registers to non-offsettable memory
   21221              :      references (zero-extended addresses) require special handling.  */
   21222    399077844 :   if (TARGET_64BIT
   21223    345994093 :       && MEM_P (x)
   21224    187313656 :       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
   21225     19329181 :       && INTEGER_CLASS_P (rclass)
   21226    401796204 :       && !offsettable_memref_p (x))
   21227              :     {
   21228      2467678 :       sri->icode = (in_p
   21229      1233839 :                     ? CODE_FOR_reload_noff_load
   21230              :                     : CODE_FOR_reload_noff_store);
   21231              :       /* Add the cost of moving address to a temporary.  */
   21232      1233839 :       sri->extra_cost = 1;
   21233              : 
   21234      1233839 :       return NO_REGS;
   21235              :     }
   21236              : 
   21237              :   /* QImode spills from non-QI registers require
   21238              :      intermediate register on 32bit targets.  */
   21239    397844005 :   if (mode == QImode
   21240    397844005 :       && ((!TARGET_64BIT && !in_p
   21241       589653 :            && INTEGER_CLASS_P (rclass)
   21242       589605 :            && MAYBE_NON_Q_CLASS_P (rclass))
   21243     23122987 :           || (!TARGET_AVX512DQ
   21244     22908963 :               && MAYBE_MASK_CLASS_P (rclass))))
   21245              :     {
   21246         6640 :       int regno = true_regnum (x);
   21247              : 
   21248              :       /* Return Q_REGS if the operand is in memory.  */
   21249         6640 :       if (regno == -1)
   21250              :         return Q_REGS;
   21251              : 
   21252         5142 :       return NO_REGS;
   21253              :     }
   21254              : 
   21255              :   /* Require movement to gpr, and then store to memory.  */
   21256    397837365 :   if ((mode == HFmode || mode == HImode || mode == V2QImode
   21257              :        || mode == BFmode)
   21258      4210891 :       && !TARGET_SSE4_1
   21259      3616138 :       && SSE_CLASS_P (rclass)
   21260       294887 :       && !in_p && MEM_P (x))
   21261              :     {
   21262       178844 :       sri->extra_cost = 1;
   21263       178844 :       return GENERAL_REGS;
   21264              :     }
   21265              : 
   21266              :   /* This condition handles corner case where an expression involving
   21267              :      pointers gets vectorized.  We're trying to use the address of a
   21268              :      stack slot as a vector initializer.
   21269              : 
   21270              :      (set (reg:V2DI 74 [ vect_cst_.2 ])
   21271              :           (vec_duplicate:V2DI (reg/f:DI 20 frame)))
   21272              : 
   21273              :      Eventually frame gets turned into sp+offset like this:
   21274              : 
   21275              :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21276              :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   21277              :                                        (const_int 392 [0x188]))))
   21278              : 
   21279              :      That later gets turned into:
   21280              : 
   21281              :      (set (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21282              :           (vec_duplicate:V2DI (plus:DI (reg/f:DI 7 sp)
   21283              :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))))
   21284              : 
   21285              :      We'll have the following reload recorded:
   21286              : 
   21287              :      Reload 0: reload_in (DI) =
   21288              :            (plus:DI (reg/f:DI 7 sp)
   21289              :             (mem/u/c/i:DI (symbol_ref/u:DI ("*.LC0") [flags 0x2]) [0 S8 A64]))
   21290              :      reload_out (V2DI) = (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21291              :      SSE_REGS, RELOAD_OTHER (opnum = 0), can't combine
   21292              :      reload_in_reg: (plus:DI (reg/f:DI 7 sp) (const_int 392 [0x188]))
   21293              :      reload_out_reg: (reg:V2DI 21 xmm0 [orig:74 vect_cst_.2 ] [74])
   21294              :      reload_reg_rtx: (reg:V2DI 22 xmm1)
   21295              : 
   21296              :      Which isn't going to work since SSE instructions can't handle scalar
   21297              :      additions.  Returning GENERAL_REGS forces the addition into integer
   21298              :      register and reload can handle subsequent reloads without problems.  */
   21299              : 
   21300    229813810 :   if (in_p && GET_CODE (x) == PLUS
   21301            2 :       && SSE_CLASS_P (rclass)
   21302    397658521 :       && SCALAR_INT_MODE_P (mode))
   21303            0 :     return GENERAL_REGS;
   21304              : 
   21305              :   return NO_REGS;
   21306              : }
   21307              : 
   21308              : /* Implement TARGET_CLASS_LIKELY_SPILLED_P.  */
   21309              : 
   21310              : static bool
   21311    740578787 : ix86_class_likely_spilled_p (reg_class_t rclass)
   21312              : {
   21313    729606327 :   switch (rclass)
   21314              :     {
   21315              :       case AREG:
   21316              :       case DREG:
   21317              :       case CREG:
   21318              :       case BREG:
   21319              :       case AD_REGS:
   21320              :       case SIREG:
   21321              :       case DIREG:
   21322              :       case SSE_FIRST_REG:
   21323              :       case FP_TOP_REG:
   21324              :       case FP_SECOND_REG:
   21325              :         return true;
   21326              : 
   21327    706408455 :       default:
   21328    706408455 :         break;
   21329              :     }
   21330              : 
   21331    706408455 :   return false;
   21332              : }
   21333              : 
   21334              : /* Implement TARGET_CALLEE_SAVE_COST.  */
   21335              : 
   21336              : static int
   21337     83264120 : ix86_callee_save_cost (spill_cost_type, unsigned int hard_regno, machine_mode,
   21338              :                        unsigned int, int mem_cost, const HARD_REG_SET &, bool)
   21339              : {
   21340              :   /* Account for the fact that push and pop are shorter and do their
   21341              :      own allocation and deallocation.  */
   21342     83264120 :   if (GENERAL_REGNO_P (hard_regno))
   21343              :     {
   21344              :       /* push is 1 byte while typical spill is 4-5 bytes.
   21345              :          ??? We probably should adjust size costs accordingly.
   21346              :          Costs are relative to reg-reg move that has 2 bytes for 32bit
   21347              :          and 3 bytes otherwise.  Be sure that no cost table sets cost
   21348              :          to 2, so we end up with 0.  */
   21349     83253930 :       if (mem_cost <= 2 || optimize_function_for_size_p (cfun))
   21350              :         return 1;
   21351     79640634 :       return mem_cost - 2;
   21352              :     }
   21353              :   return mem_cost;
   21354              : }
   21355              : 
   21356              : /* Return true if a set of DST by the expression SRC should be allowed.
   21357              :    This prevents complex sets of likely_spilled hard regs before split1.  */
   21358              : 
   21359              : bool
   21360    626794732 : ix86_hardreg_mov_ok (rtx dst, rtx src)
   21361              : {
   21362              :   /* Avoid complex sets of likely_spilled hard registers before reload.  */
   21363    519630584 :   if (REG_P (dst) && HARD_REGISTER_P (dst)
   21364    302690397 :       && !REG_P (src) && !MEM_P (src)
   21365     99223874 :       && !(VECTOR_MODE_P (GET_MODE (dst))
   21366     99223874 :            ? standard_sse_constant_p (src, GET_MODE (dst))
   21367     49369501 :            : x86_64_immediate_operand (src, GET_MODE (dst)))
   21368     10972460 :       && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst)))
   21369    636471026 :       && ix86_pre_reload_split ())
   21370      3306889 :     return false;
   21371              :   return true;
   21372              : }
   21373              : 
   21374              : /* If we are copying between registers from different register sets
   21375              :    (e.g. FP and integer), we may need a memory location.
   21376              : 
   21377              :    The function can't work reliably when one of the CLASSES is a class
   21378              :    containing registers from multiple sets.  We avoid this by never combining
   21379              :    different sets in a single alternative in the machine description.
   21380              :    Ensure that this constraint holds to avoid unexpected surprises.
   21381              : 
   21382              :    When STRICT is false, we are being called from REGISTER_MOVE_COST,
   21383              :    so do not enforce these sanity checks.
   21384              : 
   21385              :    To optimize register_move_cost performance, define inline variant.  */
   21386              : 
   21387              : static inline bool
   21388   5786112263 : inline_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   21389              :                                 reg_class_t class2, int strict)
   21390              : {
   21391   5786112263 :   if (lra_in_progress && (class1 == NO_REGS || class2 == NO_REGS))
   21392              :     return false;
   21393              : 
   21394   5753099311 :   if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
   21395   4902818225 :       || MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
   21396   4186920514 :       || MAYBE_SSE_CLASS_P (class1) != SSE_CLASS_P (class1)
   21397   3994798190 :       || MAYBE_SSE_CLASS_P (class2) != SSE_CLASS_P (class2)
   21398   3812982733 :       || MAYBE_MMX_CLASS_P (class1) != MMX_CLASS_P (class1)
   21399   3812982733 :       || MAYBE_MMX_CLASS_P (class2) != MMX_CLASS_P (class2)
   21400   3812982733 :       || MAYBE_MASK_CLASS_P (class1) != MASK_CLASS_P (class1)
   21401   9392825000 :       || MAYBE_MASK_CLASS_P (class2) != MASK_CLASS_P (class2))
   21402              :     {
   21403   2278467812 :       gcc_assert (!strict || lra_in_progress);
   21404              :       return true;
   21405              :     }
   21406              : 
   21407   3474631499 :   if (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2))
   21408              :     return true;
   21409              : 
   21410              :   /* ??? This is a lie.  We do have moves between mmx/general, and for
   21411              :      mmx/sse2.  But by saying we need secondary memory we discourage the
   21412              :      register allocator from using the mmx registers unless needed.  */
   21413   3322762369 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   21414              :     return true;
   21415              : 
   21416              :   /* Between mask and general, we have moves no larger than word size.  */
   21417   3224596779 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   21418              :     {
   21419      2642893 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2))
   21420      3456984 :           || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   21421              :         return true;
   21422              :     }
   21423              : 
   21424   3224401209 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   21425              :     {
   21426              :       /* SSE1 doesn't have any direct moves from other classes.  */
   21427    700156373 :       if (!TARGET_SSE2)
   21428              :         return true;
   21429              : 
   21430    698320309 :       if (!(INTEGER_CLASS_P (class1) || INTEGER_CLASS_P (class2)))
   21431              :         return true;
   21432              : 
   21433              :       /* If the target says that inter-unit moves are more expensive
   21434              :          than moving through memory, then don't generate them.  */
   21435   1047157317 :       if ((SSE_CLASS_P (class1) && !TARGET_INTER_UNIT_MOVES_FROM_VEC)
   21436   1046665208 :           || (SSE_CLASS_P (class2) && !TARGET_INTER_UNIT_MOVES_TO_VEC))
   21437              :         return true;
   21438              : 
   21439              :       /* With SSE4.1, *mov{ti,di}_internal supports moves between
   21440              :          SSE_REGS and GENERAL_REGS using pinsr{q,d} or pextr{q,d}.  */
   21441    696988595 :       if (TARGET_SSE4_1
   21442     37061515 :           && (TARGET_64BIT ? mode == TImode : mode == DImode))
   21443              :         return false;
   21444              : 
   21445              :       /* Moves from SSE_REGS to GENERAL_REGS need only SSE2:
   21446              :          *movti_internal splits them into movq + shufpd + movq.  */
   21447    695382260 :       if (TARGET_64BIT && mode == TImode && SSE_CLASS_P (class1))
   21448              :         return false;
   21449              : 
   21450    681492340 :       int msize = GET_MODE_SIZE (mode);
   21451              : 
   21452              :       /* Between SSE and general, we have moves no larger than word size.  */
   21453    697807510 :       if (msize > UNITS_PER_WORD)
   21454              :         return true;
   21455              : 
   21456              :       /* In addition to SImode moves, HImode moves are supported for SSE2 and above,
   21457              :          Use vmovw with AVX512FP16, or pinsrw/pextrw without AVX512FP16.  */
   21458    601641180 :       int minsize = GET_MODE_SIZE (TARGET_SSE2 ? HImode : SImode);
   21459              : 
   21460    601641180 :       if (msize < minsize)
   21461           30 :         return true;
   21462              :     }
   21463              : 
   21464              :   return false;
   21465              : }
   21466              : 
   21467              : /* Implement TARGET_SECONDARY_MEMORY_NEEDED.  */
   21468              : 
   21469              : static bool
   21470     73192061 : ix86_secondary_memory_needed (machine_mode mode, reg_class_t class1,
   21471              :                               reg_class_t class2)
   21472              : {
   21473     73192061 :   return inline_secondary_memory_needed (mode, class1, class2, true);
   21474              : }
   21475              : 
   21476              : /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.
   21477              : 
   21478              :    get_secondary_mem widens integral modes to BITS_PER_WORD.
   21479              :    There is no need to emit full 64 bit move on 64 bit targets
   21480              :    for integral modes that can be moved using 32 bit move.  */
   21481              : 
   21482              : static machine_mode
   21483        12742 : ix86_secondary_memory_needed_mode (machine_mode mode)
   21484              : {
   21485        25484 :   if (GET_MODE_BITSIZE (mode) < 32 && INTEGRAL_MODE_P (mode))
   21486           17 :     return mode_for_size (32, GET_MODE_CLASS (mode), 0).require ();
   21487              :   return mode;
   21488              : }
   21489              : 
   21490              : /* Implement the TARGET_CLASS_MAX_NREGS hook.
   21491              : 
   21492              :    On the 80386, this is the size of MODE in words,
   21493              :    except in the FP regs, where a single reg is always enough.  */
   21494              : 
   21495              : static unsigned char
   21496   5814599306 : ix86_class_max_nregs (reg_class_t rclass, machine_mode mode)
   21497              : {
   21498   5814599306 :   if (MAYBE_INTEGER_CLASS_P (rclass))
   21499              :     {
   21500   3921933688 :       if (mode == XFmode)
   21501    147420851 :         return (TARGET_64BIT ? 2 : 3);
   21502   3774512837 :       else if (mode == XCmode)
   21503    147420494 :         return (TARGET_64BIT ? 4 : 6);
   21504              :       else
   21505   7360433205 :         return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21506              :     }
   21507              :   else
   21508              :     {
   21509   1892665618 :       if (COMPLEX_MODE_P (mode))
   21510              :         return 2;
   21511              :       else
   21512   1613139261 :         return 1;
   21513              :     }
   21514              : }
   21515              : 
   21516              : /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
   21517              : 
   21518              : static bool
   21519     42082193 : ix86_can_change_mode_class (machine_mode from, machine_mode to,
   21520              :                             reg_class_t regclass)
   21521              : {
   21522     42082193 :   if (from == to)
   21523              :     return true;
   21524              : 
   21525              :   /* x87 registers can't do subreg at all, as all values are reformatted
   21526              :      to extended precision.
   21527              : 
   21528              :      ??? middle-end queries mode changes for ALL_REGS and this makes
   21529              :      vec_series_lowpart_p to always return false.  We probably should
   21530              :      restrict this to modes supported by i387 and check if it is enabled.  */
   21531     40564046 :   if (MAYBE_FLOAT_CLASS_P (regclass))
   21532              :     return false;
   21533              : 
   21534     35399183 :   if (MAYBE_SSE_CLASS_P (regclass) || MAYBE_MMX_CLASS_P (regclass))
   21535              :     {
   21536              :       /* Vector registers do not support QI or HImode loads.  If we don't
   21537              :          disallow a change to these modes, reload will assume it's ok to
   21538              :          drop the subreg from (subreg:SI (reg:HI 100) 0).  This affects
   21539              :          the vec_dupv4hi pattern.
   21540              :          NB: SSE2 can load 16bit data to sse register via pinsrw.  */
   21541     16581651 :       int mov_size = MAYBE_SSE_CLASS_P (regclass) && TARGET_SSE2 ? 2 : 4;
   21542     16581651 :       if (GET_MODE_SIZE (from) < mov_size
   21543     33163272 :           || GET_MODE_SIZE (to) < mov_size)
   21544      2090263 :         return false;
   21545              :     }
   21546              : 
   21547              :   return true;
   21548              : }
   21549              : 
   21550              : /* Return index of MODE in the sse load/store tables.  */
   21551              : 
   21552              : static inline int
   21553    773070146 : sse_store_index (machine_mode mode)
   21554              : {
   21555              :   /* NB: Use SFmode cost for HFmode instead of adding HFmode load/store
   21556              :      costs to processor_costs, which requires changes to all entries in
   21557              :      processor cost table.  */
   21558    773070146 :   if (mode == E_HFmode)
   21559    139259684 :     mode = E_SFmode;
   21560              : 
   21561   1546140292 :   switch (GET_MODE_SIZE (mode))
   21562              :     {
   21563              :     case 4:
   21564              :       return 0;
   21565              :     case 8:
   21566              :       return 1;
   21567              :     case 16:
   21568              :       return 2;
   21569              :     case 32:
   21570              :       return 3;
   21571              :     case 64:
   21572              :       return 4;
   21573              :     default:
   21574              :       return -1;
   21575              :     }
   21576              : }
   21577              : 
   21578              : /* Return the cost of moving data of mode M between a
   21579              :    register and memory.  A value of 2 is the default; this cost is
   21580              :    relative to those in `REGISTER_MOVE_COST'.
   21581              : 
   21582              :    This function is used extensively by register_move_cost that is used to
   21583              :    build tables at startup.  Make it inline in this case.
   21584              :    When IN is 2, return maximum of in and out move cost.
   21585              : 
   21586              :    If moving between registers and memory is more expensive than
   21587              :    between two registers, you should define this macro to express the
   21588              :    relative cost.
   21589              : 
   21590              :    Model also increased moving costs of QImode registers in non
   21591              :    Q_REGS classes.
   21592              :  */
   21593              : static inline int
   21594   7011510301 : inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
   21595              : {
   21596   7011510301 :   int cost;
   21597              : 
   21598   7011510301 :   if (FLOAT_CLASS_P (regclass))
   21599              :     {
   21600    359593417 :       int index;
   21601    359593417 :       switch (mode)
   21602              :         {
   21603              :           case E_SFmode:
   21604              :             index = 0;
   21605              :             break;
   21606              :           case E_DFmode:
   21607              :             index = 1;
   21608              :             break;
   21609              :           case E_XFmode:
   21610              :             index = 2;
   21611              :             break;
   21612              :           default:
   21613              :             return 100;
   21614              :         }
   21615    107491433 :       if (in == 2)
   21616    103476054 :         return MAX (ix86_cost->hard_register.fp_load [index],
   21617              :                     ix86_cost->hard_register.fp_store [index]);
   21618      4015379 :       return in ? ix86_cost->hard_register.fp_load [index]
   21619      4015379 :                 : ix86_cost->hard_register.fp_store [index];
   21620              :     }
   21621   6651916884 :   if (SSE_CLASS_P (regclass))
   21622              :     {
   21623    641787289 :       int index = sse_store_index (mode);
   21624    641787289 :       if (index == -1)
   21625              :         return 100;
   21626    556666507 :       if (in == 2)
   21627    390306241 :         return MAX (ix86_cost->hard_register.sse_load [index],
   21628              :                     ix86_cost->hard_register.sse_store [index]);
   21629    166360266 :       return in ? ix86_cost->hard_register.sse_load [index]
   21630    166360266 :                 : ix86_cost->hard_register.sse_store [index];
   21631              :     }
   21632   6010129595 :   if (MASK_CLASS_P (regclass))
   21633              :     {
   21634    110257063 :       int index;
   21635    220514126 :       switch (GET_MODE_SIZE (mode))
   21636              :         {
   21637              :         case 1:
   21638              :           index = 0;
   21639              :           break;
   21640      9094277 :         case 2:
   21641      9094277 :           index = 1;
   21642      9094277 :           break;
   21643              :         /* DImode loads and stores assumed to cost the same as SImode.  */
   21644     40919830 :         case 4:
   21645     40919830 :         case 8:
   21646     40919830 :           index = 2;
   21647     40919830 :           break;
   21648              :         default:
   21649              :           return 100;
   21650              :         }
   21651              : 
   21652     53655975 :       if (in == 2)
   21653       592407 :         return MAX (ix86_cost->hard_register.mask_load[index],
   21654              :                     ix86_cost->hard_register.mask_store[index]);
   21655     53063568 :       return in ? ix86_cost->hard_register.mask_load[2]
   21656     53063568 :                 : ix86_cost->hard_register.mask_store[2];
   21657              :     }
   21658   5899872532 :   if (MMX_CLASS_P (regclass))
   21659              :     {
   21660    175569796 :       int index;
   21661    351139592 :       switch (GET_MODE_SIZE (mode))
   21662              :         {
   21663              :           case 4:
   21664              :             index = 0;
   21665              :             break;
   21666    103040740 :           case 8:
   21667    103040740 :             index = 1;
   21668    103040740 :             break;
   21669              :           default:
   21670              :             return 100;
   21671              :         }
   21672    141078508 :       if (in == 2)
   21673    120737470 :         return MAX (ix86_cost->hard_register.mmx_load [index],
   21674              :                     ix86_cost->hard_register.mmx_store [index]);
   21675     20341038 :       return in ? ix86_cost->hard_register.mmx_load [index]
   21676     20341038 :                 : ix86_cost->hard_register.mmx_store [index];
   21677              :     }
   21678  11448605472 :   switch (GET_MODE_SIZE (mode))
   21679              :     {
   21680    127039297 :       case 1:
   21681    127039297 :         if (Q_CLASS_P (regclass) || TARGET_64BIT)
   21682              :           {
   21683    124408574 :             if (!in)
   21684     19957224 :               return ix86_cost->hard_register.int_store[0];
   21685    104451350 :             if (TARGET_PARTIAL_REG_DEPENDENCY
   21686    104451350 :                 && optimize_function_for_speed_p (cfun))
   21687     97423714 :               cost = ix86_cost->hard_register.movzbl_load;
   21688              :             else
   21689      7027636 :               cost = ix86_cost->hard_register.int_load[0];
   21690    104451350 :             if (in == 2)
   21691     84469500 :               return MAX (cost, ix86_cost->hard_register.int_store[0]);
   21692              :             return cost;
   21693              :           }
   21694              :         else
   21695              :           {
   21696      2630723 :            if (in == 2)
   21697      1863020 :              return MAX (ix86_cost->hard_register.movzbl_load,
   21698              :                          ix86_cost->hard_register.int_store[0] + 4);
   21699       767703 :            if (in)
   21700       383911 :              return ix86_cost->hard_register.movzbl_load;
   21701              :            else
   21702       383792 :              return ix86_cost->hard_register.int_store[0] + 4;
   21703              :           }
   21704    654925068 :         break;
   21705    654925068 :       case 2:
   21706    654925068 :         {
   21707    654925068 :           int cost;
   21708    654925068 :           if (in == 2)
   21709    553199180 :             cost = MAX (ix86_cost->hard_register.int_load[1],
   21710              :                         ix86_cost->hard_register.int_store[1]);
   21711              :           else
   21712    101725888 :             cost = in ? ix86_cost->hard_register.int_load[1]
   21713              :                       : ix86_cost->hard_register.int_store[1];
   21714              : 
   21715    654925068 :           if (mode == E_HFmode)
   21716              :             {
   21717              :               /* Prefer SSE over GPR for HFmode.  */
   21718    126861192 :               int sse_cost;
   21719    126861192 :               int index = sse_store_index (mode);
   21720    126861192 :               if (in == 2)
   21721    116690586 :                 sse_cost = MAX (ix86_cost->hard_register.sse_load[index],
   21722              :                                 ix86_cost->hard_register.sse_store[index]);
   21723              :               else
   21724     20341212 :                 sse_cost = (in
   21725     10170606 :                             ? ix86_cost->hard_register.sse_load [index]
   21726              :                             : ix86_cost->hard_register.sse_store [index]);
   21727    126861192 :               if (sse_cost >= cost)
   21728    126861192 :                 cost = sse_cost + 1;
   21729              :             }
   21730              :           return cost;
   21731              :         }
   21732   4942338371 :       default:
   21733   4942338371 :         if (in == 2)
   21734   3823208696 :           cost = MAX (ix86_cost->hard_register.int_load[2],
   21735              :                       ix86_cost->hard_register.int_store[2]);
   21736   1119129675 :         else if (in)
   21737    559751735 :           cost = ix86_cost->hard_register.int_load[2];
   21738              :         else
   21739    559377940 :           cost = ix86_cost->hard_register.int_store[2];
   21740              :         /* Multiply with the number of GPR moves needed.  */
   21741  10003730266 :         return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21742              :     }
   21743              : }
   21744              : 
   21745              : static int
   21746   1810106833 : ix86_memory_move_cost (machine_mode mode, reg_class_t regclass, bool in)
   21747              : {
   21748   2714839849 :   return inline_memory_move_cost (mode, (enum reg_class) regclass, in ? 1 : 0);
   21749              : }
   21750              : 
   21751              : 
   21752              : /* Return the cost of moving data from a register in class CLASS1 to
   21753              :    one in class CLASS2.
   21754              : 
   21755              :    It is not required that the cost always equal 2 when FROM is the same as TO;
   21756              :    on some machines it is expensive to move between registers if they are not
   21757              :    general registers.  */
   21758              : 
   21759              : static int
   21760   5712920202 : ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
   21761              :                          reg_class_t class2_i)
   21762              : {
   21763   5712920202 :   enum reg_class class1 = (enum reg_class) class1_i;
   21764   5712920202 :   enum reg_class class2 = (enum reg_class) class2_i;
   21765              : 
   21766              :   /* In case we require secondary memory, compute cost of the store followed
   21767              :      by load.  In order to avoid bad register allocation choices, we need
   21768              :      for this to be *at least* as high as the symmetric MEMORY_MOVE_COST.  */
   21769              : 
   21770   5712920202 :   if (inline_secondary_memory_needed (mode, class1, class2, false))
   21771              :     {
   21772   2600701734 :       int cost = 1;
   21773              : 
   21774   2600701734 :       cost += inline_memory_move_cost (mode, class1, 2);
   21775   2600701734 :       cost += inline_memory_move_cost (mode, class2, 2);
   21776              : 
   21777              :       /* In case of copying from general_purpose_register we may emit multiple
   21778              :          stores followed by single load causing memory size mismatch stall.
   21779              :          Count this as arbitrarily high cost of 20.  */
   21780   5201403468 :       if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD
   21781    768845363 :           && TARGET_MEMORY_MISMATCH_STALL
   21782   4138392460 :           && targetm.class_max_nregs (class1, mode)
   21783    768845363 :              > targetm.class_max_nregs (class2, mode))
   21784    148885528 :         cost += 20;
   21785              : 
   21786              :       /* In the case of FP/MMX moves, the registers actually overlap, and we
   21787              :          have to switch modes in order to treat them differently.  */
   21788     60368771 :       if ((MMX_CLASS_P (class1) && MAYBE_FLOAT_CLASS_P (class2))
   21789   2651563291 :           || (MMX_CLASS_P (class2) && MAYBE_FLOAT_CLASS_P (class1)))
   21790     19014428 :         cost += 20;
   21791              : 
   21792              :       return cost;
   21793              :     }
   21794              : 
   21795              :   /* Moves between MMX and non-MMX units require secondary memory.  */
   21796   3112218468 :   if (MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
   21797            0 :     gcc_unreachable ();
   21798              : 
   21799   3112218468 :   if (SSE_CLASS_P (class1) != SSE_CLASS_P (class2))
   21800    607228338 :     return (SSE_CLASS_P (class1)
   21801    607228338 :             ? ix86_cost->hard_register.sse_to_integer
   21802    607228338 :             : ix86_cost->hard_register.integer_to_sse);
   21803              : 
   21804              :   /* Moves between mask register and GPR.  */
   21805   2504990130 :   if (MASK_CLASS_P (class1) != MASK_CLASS_P (class2))
   21806              :     {
   21807      1069541 :       return (MASK_CLASS_P (class1)
   21808      1069541 :               ? ix86_cost->hard_register.mask_to_integer
   21809      1069541 :               : ix86_cost->hard_register.integer_to_mask);
   21810              :     }
   21811              :   /* Moving between mask registers.  */
   21812   2503920589 :   if (MASK_CLASS_P (class1) && MASK_CLASS_P (class2))
   21813       102447 :     return ix86_cost->hard_register.mask_move;
   21814              : 
   21815   2503818142 :   if (MAYBE_FLOAT_CLASS_P (class1))
   21816     12019900 :     return ix86_cost->hard_register.fp_move;
   21817   2491798242 :   if (MAYBE_SSE_CLASS_P (class1))
   21818              :     {
   21819    233742060 :       if (GET_MODE_BITSIZE (mode) <= 128)
   21820    114376578 :         return ix86_cost->hard_register.xmm_move;
   21821      4988904 :       if (GET_MODE_BITSIZE (mode) <= 256)
   21822      1585230 :         return ix86_cost->hard_register.ymm_move;
   21823       909222 :       return ix86_cost->hard_register.zmm_move;
   21824              :     }
   21825   2374927212 :   if (MAYBE_MMX_CLASS_P (class1))
   21826      2211035 :     return ix86_cost->hard_register.mmx_move;
   21827              :   return 2;
   21828              : }
   21829              : 
   21830              : /* Implement TARGET_HARD_REGNO_NREGS.  This is ordinarily the length in
   21831              :    words of a value of mode MODE but can be less for certain modes in
   21832              :    special long registers.
   21833              : 
   21834              :    Actually there are no two word move instructions for consecutive
   21835              :    registers.  And only registers 0-3 may have mov byte instructions
   21836              :    applied to them.  */
   21837              : 
   21838              : static unsigned int
   21839   9225863872 : ix86_hard_regno_nregs (unsigned int regno, machine_mode mode)
   21840              : {
   21841   9225863872 :   if (GENERAL_REGNO_P (regno))
   21842              :     {
   21843   3140719616 :       if (mode == XFmode)
   21844     25328384 :         return TARGET_64BIT ? 2 : 3;
   21845   3115391232 :       if (mode == XCmode)
   21846     25328384 :         return TARGET_64BIT ? 4 : 6;
   21847   6238849664 :       return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
   21848              :     }
   21849   6085144256 :   if (COMPLEX_MODE_P (mode))
   21850              :     return 2;
   21851              :   /* Register pair for mask registers.  */
   21852   5299964352 :   if (mode == P2QImode || mode == P2HImode)
   21853     98147488 :     return 2;
   21854              : 
   21855              :   return 1;
   21856              : }
   21857              : 
   21858              : /* Implement REGMODE_NATURAL_SIZE(MODE).  */
   21859              : unsigned int
   21860    238176920 : ix86_regmode_natural_size (machine_mode mode)
   21861              : {
   21862    238176920 :   if (mode == P2HImode || mode == P2QImode)
   21863      1771702 :     return GET_MODE_SIZE (mode) / 2;
   21864    237291069 :   return UNITS_PER_WORD;
   21865              : }
   21866              : 
   21867              : /* Implement TARGET_HARD_REGNO_MODE_OK.  */
   21868              : 
   21869              : static bool
   21870  54022302582 : ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   21871              : {
   21872              :   /* Flags and only flags can only hold CCmode values.  */
   21873  54022302582 :   if (CC_REGNO_P (regno))
   21874    420663901 :     return GET_MODE_CLASS (mode) == MODE_CC;
   21875  53601638681 :   if (GET_MODE_CLASS (mode) == MODE_CC
   21876              :       || GET_MODE_CLASS (mode) == MODE_RANDOM)
   21877              :     return false;
   21878  48115949386 :   if (STACK_REGNO_P (regno))
   21879   4611180220 :     return VALID_FP_MODE_P (mode);
   21880  43504769166 :   if (MASK_REGNO_P (regno))
   21881              :     {
   21882              :       /* Register pair only starts at even register number.  */
   21883   3598702775 :       if ((mode == P2QImode || mode == P2HImode))
   21884     49694822 :         return MASK_PAIR_REGNO_P(regno);
   21885              : 
   21886   1032084257 :       return ((TARGET_AVX512F && VALID_MASK_REG_MODE (mode))
   21887   4560101467 :               || (TARGET_AVX512BW && VALID_MASK_AVX512BW_MODE (mode)));
   21888              :     }
   21889              : 
   21890  39906066391 :   if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
   21891              :     return false;
   21892              : 
   21893  38932393332 :   if (SSE_REGNO_P (regno))
   21894              :     {
   21895              :       /* We implement the move patterns for all vector modes into and
   21896              :          out of SSE registers, even when no operation instructions
   21897              :          are available.  */
   21898              : 
   21899              :       /* For AVX-512 we allow, regardless of regno:
   21900              :           - XI mode
   21901              :           - any of 512-bit wide vector mode
   21902              :           - any scalar mode.  */
   21903  16537280835 :       if (TARGET_AVX512F
   21904              :           && ((VALID_AVX512F_REG_OR_XI_MODE (mode))
   21905              :               || VALID_AVX512F_SCALAR_MODE (mode)))
   21906              :         return true;
   21907              : 
   21908              :       /* TODO check for QI/HI scalars.  */
   21909              :       /* AVX512VL allows sse regs16+ for 128/256 bit modes.  */
   21910  15825931293 :       if (TARGET_AVX512VL
   21911   1882664568 :           && (VALID_AVX256_REG_OR_OI_MODE (mode)
   21912   1654467199 :               || VALID_AVX512VL_128_REG_MODE (mode)))
   21913              :         return true;
   21914              : 
   21915              :       /* xmm16-xmm31 are only available for AVX-512.  */
   21916  15345915300 :       if (EXT_REX_SSE_REGNO_P (regno))
   21917              :         return false;
   21918              : 
   21919              :       /* Without SSE2, 16-bit moves are not supported.  */
   21920  10080138342 :       if (!TARGET_SSE2 && GET_MODE_SIZE (mode) == GET_MODE_SIZE (HImode))
   21921              :         return false;
   21922              : 
   21923              :       /* OImode and AVX modes are available only when AVX is enabled.  */
   21924   8799108308 :       return ((TARGET_AVX
   21925   1948227581 :                && VALID_AVX256_REG_OR_OI_MODE (mode))
   21926              :               || VALID_SSE_REG_MODE (mode)
   21927              :               || VALID_SSE2_REG_MODE (mode)
   21928              :               || VALID_MMX_REG_MODE (mode)
   21929   8799108308 :               || VALID_MMX_REG_MODE_3DNOW (mode));
   21930              :     }
   21931  22395112497 :   if (MMX_REGNO_P (regno))
   21932              :     {
   21933              :       /* We implement the move patterns for 3DNOW modes even in MMX mode,
   21934              :          so if the register is available at all, then we can move data of
   21935              :          the given mode into or out of it.  */
   21936   3842629013 :       return (VALID_MMX_REG_MODE (mode)
   21937              :               || VALID_MMX_REG_MODE_3DNOW (mode));
   21938              :     }
   21939              : 
   21940  18552483484 :   if (mode == QImode)
   21941              :     {
   21942              :       /* Take care for QImode values - they can be in non-QI regs,
   21943              :          but then they do cause partial register stalls.  */
   21944    211308278 :       if (ANY_QI_REGNO_P (regno))
   21945              :         return true;
   21946     21584413 :       if (!TARGET_PARTIAL_REG_STALL)
   21947              :         return true;
   21948              :       /* LRA checks if the hard register is OK for the given mode.
   21949              :          QImode values can live in non-QI regs, so we allow all
   21950              :          registers here.  */
   21951           33 :       if (lra_in_progress)
   21952              :        return true;
   21953           33 :       return !can_create_pseudo_p ();
   21954              :     }
   21955              :   /* We handle both integer and floats in the general purpose registers.  */
   21956  18341175206 :   else if (VALID_INT_MODE_P (mode)
   21957  13407293577 :            || VALID_FP_MODE_P (mode))
   21958              :     return true;
   21959              :   /* Lots of MMX code casts 8 byte vector modes to DImode.  If we then go
   21960              :      on to use that value in smaller contexts, this can easily force a
   21961              :      pseudo to be allocated to GENERAL_REGS.  Since this is no worse than
   21962              :      supporting DImode, allow it.  */
   21963  12327437331 :   else if (VALID_MMX_REG_MODE_3DNOW (mode) || VALID_MMX_REG_MODE (mode))
   21964              :     return true;
   21965              : 
   21966              :   return false;
   21967              : }
   21968              : 
   21969              : /* Initialize function_abis[ABI_ID] with the set of register clobbers
   21970              :    in FULL_REG_CLOBBERS, adjusting for rules that apply to all ABIs.  */
   21971              : 
   21972              : static void
   21973          762 : ix86_initialize_abi (unsigned int abi_id, HARD_REG_SET full_reg_clobbers)
   21974              : {
   21975              :   /* The general rule is that fixed registers should be marked as
   21976              :      call-clobbered.  This includes global registers, inaccessible
   21977              :      registers, the flags register, and the FPSR.
   21978              : 
   21979              :      Handle the exceptions below.  */
   21980          762 :   full_reg_clobbers |= fixed_reg_set;
   21981              : 
   21982              :   /* Every ABI (even preserve_none) preserves EBP/RBP.  */
   21983          762 :   CLEAR_HARD_REG_BIT (full_reg_clobbers, HARD_FRAME_POINTER_REGNUM);
   21984              : 
   21985              :   /* Treat GCC's internal frame-related registers as call-preserved.  */
   21986          762 :   CLEAR_HARD_REG_BIT (full_reg_clobbers, FRAME_POINTER_REGNUM);
   21987          762 :   CLEAR_HARD_REG_BIT (full_reg_clobbers, ARG_POINTER_REGNUM);
   21988              : 
   21989              :   /* MMX registers aren't preserved.  */
   21990          762 :   if (TARGET_MMX)
   21991          762 :     full_reg_clobbers |= reg_class_contents[MMX_REGS];
   21992              : 
   21993              :   /* X87 registers aren't preserved.  */
   21994          762 :   if (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387)
   21995          762 :     full_reg_clobbers |= reg_class_contents[FLOAT_REGS];
   21996              : 
   21997          762 :   function_abis[abi_id].initialize (abi_id, full_reg_clobbers);
   21998          762 : }
   21999              : 
   22000              : /* Return the descriptor of no_callee_saved_registers function type.
   22001              :    None of the enabled registers are preserved, except for the common
   22002              :    rules applied by ix86_initialize_abi.  */
   22003              : 
   22004              : static const predefined_function_abi &
   22005         3088 : ix86_no_callee_saved_abi (void)
   22006              : {
   22007         3088 :   auto &no_callee_saved_abi = function_abis[ABI_NO_CALLEE_SAVED];
   22008         3088 :   if (!no_callee_saved_abi.initialized_p ())
   22009           98 :     ix86_initialize_abi (ABI_NO_CALLEE_SAVED, accessible_reg_set);
   22010         3088 :   return no_callee_saved_abi;
   22011              : }
   22012              : 
   22013              : /* Return the descriptor of the no_caller_saved_registers function type
   22014              :    with ABI identifier ABI_ID.  All registers are preserved, except for:
   22015              : 
   22016              :    - the return registers, which are enumerated in ABI_ID.
   22017              : 
   22018              :    - the common rules applied by ix86_initialize_abi.  */
   22019              : 
   22020              : static const predefined_function_abi &
   22021         3705 : ix86_no_caller_saved_abi (unsigned int abi_id)
   22022              : {
   22023         3705 :   auto &abi = function_abis[abi_id];
   22024         3705 :   if (!abi.initialized_p ())
   22025              :     {
   22026          172 :       HARD_REG_SET full_reg_clobbers = {};
   22027              : 
   22028          172 :       switch (abi_id)
   22029              :         {
   22030              :         case ABI_NO_CALLER_SAVED_RETURN_VOID:
   22031              :           break;
   22032              : 
   22033            1 :         case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
   22034            1 :           SET_HARD_REG_BIT (full_reg_clobbers, DX_REG);
   22035              :           /* Fall through.  */
   22036            9 :         case ABI_NO_CALLER_SAVED_RETURN_AX:
   22037            9 :           SET_HARD_REG_BIT (full_reg_clobbers, AX_REG);
   22038            9 :           break;
   22039              : 
   22040            2 :         case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
   22041            2 :           SET_HARD_REG_BIT (full_reg_clobbers, AX_REG);
   22042            2 :           SET_HARD_REG_BIT (full_reg_clobbers, XMM0_REG);
   22043            2 :           break;
   22044              : 
   22045            1 :         case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
   22046            1 :           SET_HARD_REG_BIT (full_reg_clobbers, XMM1_REG);
   22047              :           /* Fall through.  */
   22048            2 :         case ABI_NO_CALLER_SAVED_RETURN_XMM0:
   22049            2 :           SET_HARD_REG_BIT (full_reg_clobbers, XMM0_REG);
   22050            2 :           break;
   22051              : 
   22052            0 :         default:
   22053            0 :           gcc_unreachable ();
   22054              :         }
   22055              : 
   22056          172 :       ix86_initialize_abi (abi_id, full_reg_clobbers);
   22057              :     }
   22058         3705 :   return abi;
   22059              : }
   22060              : 
   22061              : /* Return the descriptor of the standard function ABI type.  If
   22062              :    ABI_TYPE == ABI_ALTERNATE, return the function alternate ABI type.  */
   22063              : 
   22064              : static const predefined_function_abi &
   22065      1596088 : ix86_standard_abi (int abi_type)
   22066              : {
   22067      1596088 :   static const char ix86_call_used_regs[] = CALL_USED_REGISTERS;
   22068      1596088 :   auto &standard_abi = function_abis[abi_type];
   22069      1596088 :   if (!standard_abi.initialized_p ())
   22070              :     {
   22071          492 :       HARD_REG_SET full_reg_clobbers = {};
   22072              : 
   22073              :       /* Add all registers that are clobbered by the call.  NB: If the
   22074              :          current ABI is SYSV_ABI, the alternate ABI is MS_ABI.   */
   22075         1007 :       bool is_64bit_ms_abi = (TARGET_64BIT
   22076          492 :                               && ix86_abi == (abi_type == ABI_ALTERNATE
   22077          492 :                                               ? SYSV_ABI : MS_ABI));
   22078           23 :       char c_mask = CALL_USED_REGISTERS_MASK (is_64bit_ms_abi);
   22079        46740 :       for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   22080        46248 :         if (ix86_call_used_regs[i] == 1
   22081         8856 :             || (ix86_call_used_regs[i] & c_mask))
   22082        37668 :           SET_HARD_REG_BIT (full_reg_clobbers, i);
   22083              : 
   22084          492 :       ix86_initialize_abi (abi_type, full_reg_clobbers);
   22085              :     }
   22086      1596088 :   return standard_abi;
   22087              : }
   22088              : 
   22089              : /* Return the descriptor of the function alternate ABI type.  */
   22090              : 
   22091              : static const predefined_function_abi &
   22092      1596088 : ix86_alternate_abi (void)
   22093              : {
   22094           12 :   return ix86_standard_abi (ABI_ALTERNATE);
   22095              : }
   22096              : 
   22097              : /* Return the function ABI ID based on FNTYPE.  */
   22098              : 
   22099              : static int
   22100    424237153 : ix86_function_abi_id (const_tree fntype)
   22101              : {
   22102    424237153 :   auto call_saved_registers = ix86_fntype_call_saved_registers (fntype);
   22103    424237153 :   if (call_saved_registers == TYPE_PRESERVE_NONE
   22104    424237153 :       || call_saved_registers == TYPE_NO_CALLEE_SAVED_REGISTERS)
   22105              :     return ABI_NO_CALLEE_SAVED;
   22106              : 
   22107    424234065 :   if (call_saved_registers == TYPE_NO_CALLER_SAVED_REGISTERS)
   22108              :     {
   22109         3705 :       tree type = TREE_TYPE (fntype);
   22110         3705 :       if (VOID_TYPE_P (type))
   22111              :         return ABI_NO_CALLER_SAVED_RETURN_VOID;
   22112              :       /* AX register contains the address of the return value location
   22113              :          passed in by the caller.  */
   22114         2256 :       else if (ix86_return_in_memory (type, fntype))
   22115              :         return ABI_NO_CALLER_SAVED_RETURN_AX;
   22116         2197 :       rtx ret = ix86_function_value (type, fntype, false);
   22117         2197 :       unsigned int nregs;
   22118         2197 :       if (REG_P (ret))
   22119              :         {
   22120         2016 :           unsigned int regno = REGNO (ret);
   22121         2016 :           if (STACK_REGNO_P (regno) || MMX_REGNO_P (regno))
   22122              :             return ABI_NO_CALLER_SAVED_RETURN_VOID;
   22123              :           else
   22124         2016 :             switch (regno)
   22125              :               {
   22126         1947 :               case AX_REG:
   22127         1947 :                 nregs = REG_NREGS (ret);
   22128         1947 :                 if (nregs == 1)
   22129              :                   return ABI_NO_CALLER_SAVED_RETURN_AX;
   22130           71 :                 else if (nregs == 2)
   22131              :                   return ABI_NO_CALLER_SAVED_RETURN_AX_DX;
   22132            0 :                 gcc_unreachable ();
   22133              :               case XMM0_REG:
   22134              :                 return ABI_NO_CALLER_SAVED_RETURN_XMM0;
   22135            0 :               default:
   22136            0 :                 gcc_unreachable ();
   22137              :               }
   22138              :         }
   22139          181 :       else if (GET_CODE (ret) == PARALLEL && XVECLEN (ret, 0) == 2)
   22140              :         {
   22141          181 :           rtx x0 = XVECEXP (ret, 0, 0);
   22142          181 :           rtx x1 = XVECEXP (ret, 0, 1);
   22143          181 :           if (GET_CODE (x0) == EXPR_LIST
   22144          181 :               && GET_CODE (x1) == EXPR_LIST)
   22145              :             {
   22146          181 :               x0 = XEXP (x0, 0);
   22147          181 :               x1 = XEXP (x1, 0);
   22148          181 :               if (REG_P (x0) && REGNO (x0) == AX_REG)
   22149              :                 {
   22150           59 :                   if (REG_P (x1) && REGNO (x1) == XMM0_REG)
   22151              :                     return ABI_NO_CALLER_SAVED_RETURN_AX_XMM0;
   22152              :                 }
   22153          122 :               if (REG_P (x0) && REGNO (x0) == XMM0_REG && REG_P (x1))
   22154              :                 {
   22155          122 :                   if (REGNO (x1) == AX_REG)
   22156              :                     return ABI_NO_CALLER_SAVED_RETURN_AX_XMM0;
   22157           64 :                   else if (REGNO (x1) == XMM1_REG)
   22158              :                     return ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1;
   22159              :                 }
   22160              :             }
   22161              : 
   22162            0 :           gcc_unreachable ();
   22163              :         }
   22164              :     }
   22165              : 
   22166              :   /* NB: This must be the last since other attributes change the
   22167              :      function ABI.  */
   22168    424230360 :   if (ix86_function_type_abi (fntype) != ix86_abi)
   22169      1596076 :     return ABI_ALTERNATE;
   22170              : 
   22171              :   return ABI_DEFAULT;
   22172              : }
   22173              : 
   22174              : /* Implement TARGET_FNTYPE_ABI.  */
   22175              : 
   22176              : static const predefined_function_abi &
   22177    424237153 : ix86_fntype_abi (const_tree fntype)
   22178              : {
   22179    424237153 :   unsigned int abi_id = ix86_function_abi_id (fntype);
   22180    424237153 :   switch (abi_id)
   22181              :     {
   22182    422634284 :     case ABI_DEFAULT:
   22183    422634284 :       return default_function_abi;
   22184              : 
   22185      1596076 :     case ABI_ALTERNATE:
   22186      1596076 :       return ix86_alternate_abi ();
   22187              : 
   22188         3088 :     case ABI_NO_CALLEE_SAVED:
   22189         3088 :       return ix86_no_callee_saved_abi ();
   22190              : 
   22191         3705 :     case ABI_NO_CALLER_SAVED_RETURN_VOID:
   22192         3705 :     case ABI_NO_CALLER_SAVED_RETURN_AX:
   22193         3705 :     case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
   22194         3705 :     case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
   22195         3705 :     case ABI_NO_CALLER_SAVED_RETURN_XMM0:
   22196         3705 :     case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
   22197         3705 :       return ix86_no_caller_saved_abi (abi_id);
   22198              : 
   22199              :     default:
   22200              :       gcc_unreachable ();
   22201              :     }
   22202              : 
   22203              :   return default_function_abi;
   22204              : }
   22205              : 
   22206              : /* Initialize function_abis with corresponding abi_id,
   22207              :    currently only handle vzeroupper.  */
   22208              : void
   22209        22375 : ix86_initialize_callee_abi (unsigned int abi_id)
   22210              : {
   22211        22375 :   gcc_assert (abi_id == ABI_VZEROUPPER);
   22212        22375 :   predefined_function_abi &vzeroupper_abi = function_abis[abi_id];
   22213        22375 :   if (!vzeroupper_abi.initialized_p ())
   22214              :     {
   22215              :       HARD_REG_SET full_reg_clobbers;
   22216         4347 :       CLEAR_HARD_REG_SET (full_reg_clobbers);
   22217         4347 :       vzeroupper_abi.initialize (ABI_VZEROUPPER, full_reg_clobbers);
   22218              :     }
   22219        22375 : }
   22220              : 
   22221              : void
   22222        22375 : ix86_expand_avx_vzeroupper (void)
   22223              : {
   22224              :   /* Initialize vzeroupper_abi here.  */
   22225        22375 :   ix86_initialize_callee_abi (ABI_VZEROUPPER);
   22226        22375 :   rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
   22227        22375 :   CALL_INSN_ABI_ID (insn) = ABI_VZEROUPPER;
   22228              :   /* Return false for non-local goto in can_nonlocal_goto.  */
   22229        22375 :   make_reg_eh_region_note (insn, 0, INT_MIN);
   22230              :   /* Flag used for call_insn indicates it's a fake call.  */
   22231        22375 :   RTX_FLAG (insn, used) = 1;
   22232        22375 : }
   22233              : 
   22234              : 
   22235              : /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED.  The only ABI that
   22236              :    saves SSE registers across calls is Win64 (thus no need to check the
   22237              :    current ABI here), and with AVX enabled Win64 only guarantees that
   22238              :    the low 16 bytes are saved.  */
   22239              : 
   22240              : static bool
   22241   1973086162 : ix86_hard_regno_call_part_clobbered (unsigned int abi_id, unsigned int regno,
   22242              :                                      machine_mode mode)
   22243              : {
   22244   1973086162 :   switch (abi_id)
   22245              :     {
   22246     32323101 :     case ABI_VZEROUPPER:
   22247              :       /* Special ABI for vzeroupper which only clobbers higher part of
   22248              :          SSE registers.  */
   22249     32323101 :       return (GET_MODE_SIZE (mode) > 16
   22250     32323101 :               && ((TARGET_64BIT && REX_SSE_REGNO_P (regno))
   22251      4868610 :                   || LEGACY_SSE_REGNO_P (regno)));
   22252              : 
   22253   1940258889 :     case ABI_DEFAULT:
   22254   1940258889 :     case ABI_ALTERNATE:
   22255   1940258889 :     case ABI_NO_CALLEE_SAVED:
   22256   1940258889 :       break;
   22257              : 
   22258              :     case ABI_NO_CALLER_SAVED_RETURN_VOID:
   22259              :     case ABI_NO_CALLER_SAVED_RETURN_AX:
   22260              :     case ABI_NO_CALLER_SAVED_RETURN_AX_DX:
   22261              :       /* These ABIs don't clobber SSE registers.  */
   22262              :       return false;
   22263              : 
   22264              :     case ABI_NO_CALLER_SAVED_RETURN_AX_XMM0:
   22265              :     case ABI_NO_CALLER_SAVED_RETURN_XMM0:
   22266              :     case ABI_NO_CALLER_SAVED_RETURN_XMM0_XMM1:
   22267              :       /* These ABIs return some values in SSE registers and preserve
   22268              :          the rest.  The return value registers (XMM0 and possibly XMM1)
   22269              :          are fully rather than partially call-clobbered.  */
   22270              :       return false;
   22271              : 
   22272            0 :     default:
   22273            0 :       gcc_unreachable ();
   22274              :     }
   22275              : 
   22276   2535530305 :   return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
   22277              : }
   22278              : 
   22279              : /* A subroutine of ix86_modes_tieable_p.  Return true if MODE is a
   22280              :    tieable integer mode.  */
   22281              : 
   22282              : static bool
   22283     54807634 : ix86_tieable_integer_mode_p (machine_mode mode)
   22284              : {
   22285     54807634 :   switch (mode)
   22286              :     {
   22287              :     case E_HImode:
   22288              :     case E_SImode:
   22289              :       return true;
   22290              : 
   22291      5442598 :     case E_QImode:
   22292      5442598 :       return TARGET_64BIT || !TARGET_PARTIAL_REG_STALL;
   22293              : 
   22294     10966715 :     case E_DImode:
   22295     10966715 :       return TARGET_64BIT;
   22296              : 
   22297              :     default:
   22298              :       return false;
   22299              :     }
   22300              : }
   22301              : 
   22302              : /* Implement TARGET_MODES_TIEABLE_P.
   22303              : 
   22304              :    Return true if MODE1 is accessible in a register that can hold MODE2
   22305              :    without copying.  That is, all register classes that can hold MODE2
   22306              :    can also hold MODE1.  */
   22307              : 
   22308              : static bool
   22309     35335184 : ix86_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   22310              : {
   22311     35335184 :   if (mode1 == mode2)
   22312              :     return true;
   22313              : 
   22314     35249366 :   if (ix86_tieable_integer_mode_p (mode1)
   22315     35249366 :       && ix86_tieable_integer_mode_p (mode2))
   22316              :     return true;
   22317              : 
   22318              :   /* MODE2 being XFmode implies fp stack or general regs, which means we
   22319              :      can tie any smaller floating point modes to it.  Note that we do not
   22320              :      tie this with TFmode.  */
   22321     25691944 :   if (mode2 == XFmode)
   22322         4315 :     return mode1 == SFmode || mode1 == DFmode;
   22323              : 
   22324              :   /* MODE2 being DFmode implies fp stack, general or sse regs, which means
   22325              :      that we can tie it with SFmode.  */
   22326     25687629 :   if (mode2 == DFmode)
   22327       250412 :     return mode1 == SFmode;
   22328              : 
   22329              :   /* If MODE2 is only appropriate for an SSE register, then tie with
   22330              :      any vector modes or scalar floating point modes acceptable to SSE
   22331              :      registers, excluding scalar integer modes with SUBREG:
   22332              :         (subreg:QI (reg:TI 99) 0))
   22333              :         (subreg:HI (reg:TI 99) 0))
   22334              :         (subreg:SI (reg:TI 99) 0))
   22335              :         (subreg:DI (reg:TI 99) 0))
   22336              :      to avoid unnecessary move from SSE register to integer register.
   22337              :    */
   22338     25437217 :   if (GET_MODE_SIZE (mode2) >= 16
   22339     39395382 :       && (GET_MODE_SIZE (mode1) == GET_MODE_SIZE (mode2)
   22340     13820525 :           || ((VECTOR_MODE_P (mode1) || SCALAR_FLOAT_MODE_P (mode1))
   22341       508018 :               && GET_MODE_SIZE (mode1) <= GET_MODE_SIZE (mode2)))
   22342     31567302 :       && ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode2))
   22343      5686404 :     return ix86_hard_regno_mode_ok (FIRST_SSE_REG, mode1);
   22344              : 
   22345              :   /* If MODE2 is appropriate for an MMX register, then tie
   22346              :      with any other mode acceptable to MMX registers.  */
   22347     19750813 :   if (GET_MODE_SIZE (mode2) == 8
   22348     19750813 :       && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode2))
   22349      3383654 :     return (GET_MODE_SIZE (mode1) == 8
   22350      3383654 :             && ix86_hard_regno_mode_ok (FIRST_MMX_REG, mode1));
   22351              : 
   22352              :   /* SCmode and DImode can be tied.  */
   22353     16367159 :   if ((mode1 == E_SCmode && mode2 == E_DImode)
   22354     16367159 :       || (mode1 == E_DImode && mode2 == E_SCmode))
   22355          108 :     return TARGET_64BIT;
   22356              : 
   22357              :   /* [SD]Cmode and V2[SD]Fmode modes can be tied.  */
   22358     16367051 :   if ((mode1 == E_SCmode && mode2 == E_V2SFmode)
   22359     16367051 :       || (mode1 == E_V2SFmode && mode2 == E_SCmode)
   22360     16367051 :       || (mode1 == E_DCmode && mode2 == E_V2DFmode)
   22361     16367051 :       || (mode1 == E_V2DFmode && mode2 == E_DCmode))
   22362            0 :     return true;
   22363              : 
   22364              :   return false;
   22365              : }
   22366              : 
   22367              : /* Return the cost of moving between two registers of mode MODE.  */
   22368              : 
   22369              : static int
   22370     30090342 : ix86_set_reg_reg_cost (machine_mode mode)
   22371              : {
   22372     30090342 :   unsigned int units = UNITS_PER_WORD;
   22373              : 
   22374     30090342 :   switch (GET_MODE_CLASS (mode))
   22375              :     {
   22376              :     default:
   22377              :       break;
   22378              : 
   22379              :     case MODE_CC:
   22380     30090342 :       units = GET_MODE_SIZE (CCmode);
   22381              :       break;
   22382              : 
   22383      1180146 :     case MODE_FLOAT:
   22384      1180146 :       if ((TARGET_SSE && mode == TFmode)
   22385       685591 :           || (TARGET_80387 && mode == XFmode)
   22386       219182 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
   22387       148381 :           || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
   22388      2325112 :         units = GET_MODE_SIZE (mode);
   22389              :       break;
   22390              : 
   22391      1337858 :     case MODE_COMPLEX_FLOAT:
   22392      1337858 :       if ((TARGET_SSE && mode == TCmode)
   22393       896856 :           || (TARGET_80387 && mode == XCmode)
   22394       455730 :           || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
   22395        14570 :           || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
   22396      2669152 :         units = GET_MODE_SIZE (mode);
   22397              :       break;
   22398              : 
   22399     19151589 :     case MODE_VECTOR_INT:
   22400     19151589 :     case MODE_VECTOR_FLOAT:
   22401     19151589 :       if ((TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
   22402     19054265 :           || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   22403     18880376 :           || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   22404     16189099 :           || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   22405     14850908 :           || ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   22406     14805060 :               && VALID_MMX_REG_MODE (mode)))
   22407      8710406 :         units = GET_MODE_SIZE (mode);
   22408              :     }
   22409              : 
   22410              :   /* Return the cost of moving between two registers of mode MODE,
   22411              :      assuming that the move will be in pieces of at most UNITS bytes.  */
   22412     30090342 :   return COSTS_N_INSNS (CEIL (GET_MODE_SIZE (mode), units));
   22413              : }
   22414              : 
   22415              : /* Return cost of vector operation in MODE given that scalar version has
   22416              :    COST.  */
   22417              : 
   22418              : static int
   22419   2899036211 : ix86_vec_cost (machine_mode mode, int cost)
   22420              : {
   22421   2899036211 :   if (!VECTOR_MODE_P (mode))
   22422              :     return cost;
   22423              : 
   22424   2898783079 :   if (GET_MODE_BITSIZE (mode) == 128
   22425   2898783079 :       && TARGET_SSE_SPLIT_REGS)
   22426      2882536 :     return cost * GET_MODE_BITSIZE (mode) / 64;
   22427   2897341811 :   else if (GET_MODE_BITSIZE (mode) > 128
   22428   2897341811 :       && TARGET_AVX256_SPLIT_REGS)
   22429      1720252 :     return cost * GET_MODE_BITSIZE (mode) / 128;
   22430   2896481685 :   else if (GET_MODE_BITSIZE (mode) > 256
   22431   2896481685 :       && TARGET_AVX512_SPLIT_REGS)
   22432       335640 :     return cost * GET_MODE_BITSIZE (mode) / 256;
   22433              :   return cost;
   22434              : }
   22435              : 
   22436              : /* Return cost of vec_widen_<s>mult_hi/lo_<mode>,
   22437              :    vec_widen_<s>mul_hi/lo_<mode> is only available for VI124_AVX2.  */
   22438              : static int
   22439         1217 : ix86_widen_mult_cost (const struct processor_costs *cost,
   22440              :                       enum machine_mode mode, bool uns_p)
   22441              : {
   22442         1217 :   gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
   22443         1217 :   int extra_cost = 0;
   22444         1217 :   int basic_cost = 0;
   22445         1217 :   switch (mode)
   22446              :     {
   22447          136 :     case V8HImode:
   22448          136 :     case V16HImode:
   22449          136 :       if (!uns_p || mode == V16HImode)
   22450           55 :         extra_cost = cost->sse_op * 2;
   22451          136 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   22452          136 :       break;
   22453          209 :     case V4SImode:
   22454          209 :     case V8SImode:
   22455              :       /* pmulhw/pmullw can be used.  */
   22456          209 :       basic_cost = cost->mulss * 2 + cost->sse_op * 2;
   22457          209 :       break;
   22458          804 :     case V2DImode:
   22459              :       /* pmuludq under sse2, pmuldq under sse4.1, for sign_extend,
   22460              :          require extra 4 mul, 4 add, 4 cmp and 2 shift.  */
   22461          804 :       if (!TARGET_SSE4_1 && !uns_p)
   22462          484 :         extra_cost = (cost->mulss + cost->sse_op + cost->sse_op) * 4
   22463          484 :                       + cost->sse_op * 2;
   22464              :       /* Fallthru.  */
   22465          860 :     case V4DImode:
   22466          860 :       basic_cost = cost->mulss * 2 + cost->sse_op * 4;
   22467          860 :       break;
   22468              :     default:
   22469              :       /* Not implemented.  */
   22470              :       return 100;
   22471              :     }
   22472         1205 :   return ix86_vec_cost (mode, basic_cost + extra_cost);
   22473              : }
   22474              : 
   22475              : /* Return cost of multiplication in MODE.  */
   22476              : 
   22477              : static int
   22478   1237032216 : ix86_multiplication_cost (const struct processor_costs *cost,
   22479              :                           enum machine_mode mode)
   22480              : {
   22481   1237032216 :   machine_mode inner_mode = mode;
   22482   1237032216 :   if (VECTOR_MODE_P (mode))
   22483   1235989393 :     inner_mode = GET_MODE_INNER (mode);
   22484              : 
   22485   1237032216 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22486       760785 :     return inner_mode == DFmode ? cost->mulsd : cost->mulss;
   22487   1236271431 :   else if (X87_FLOAT_MODE_P (mode))
   22488       166707 :     return cost->fmul;
   22489   1236104724 :   else if (FLOAT_MODE_P (mode))
   22490       241868 :     return  ix86_vec_cost (mode,
   22491       241868 :                            inner_mode == DFmode ? cost->mulsd : cost->mulss);
   22492   1235862856 :   else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22493              :     {
   22494   1235771687 :       int nmults, nops;
   22495              :       /* Cost of reading the memory.  */
   22496   1235771687 :       int extra;
   22497              : 
   22498   1235771687 :       switch (mode)
   22499              :         {
   22500     19460482 :         case V4QImode:
   22501     19460482 :         case V8QImode:
   22502              :           /* Partial V*QImode is emulated with 4-6 insns.  */
   22503     19460482 :           nmults = 1;
   22504     19460482 :           nops = 3;
   22505     19460482 :           extra = 0;
   22506              : 
   22507     19460482 :           if (TARGET_AVX512BW && TARGET_AVX512VL)
   22508              :             ;
   22509     19344312 :           else if (TARGET_AVX2)
   22510              :             nops += 2;
   22511     18836172 :           else if (TARGET_XOP)
   22512        10040 :             extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22513              :           else
   22514              :             {
   22515     18826132 :               nops += 1;
   22516     18826132 :               extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22517              :             }
   22518     19460482 :           goto do_qimode;
   22519              : 
   22520      9730726 :         case V16QImode:
   22521              :           /* V*QImode is emulated with 4-11 insns.  */
   22522      9730726 :           nmults = 1;
   22523      9730726 :           nops = 3;
   22524      9730726 :           extra = 0;
   22525              : 
   22526      9730726 :           if (TARGET_AVX2 && !TARGET_PREFER_AVX128)
   22527              :             {
   22528       309899 :               if (!(TARGET_AVX512BW && TARGET_AVX512VL))
   22529       252100 :                 nops += 3;
   22530              :             }
   22531      9420827 :           else if (TARGET_XOP)
   22532              :             {
   22533         5464 :               nmults += 1;
   22534         5464 :               nops += 2;
   22535         5464 :               extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22536              :             }
   22537              :           else
   22538              :             {
   22539      9415363 :               nmults += 1;
   22540      9415363 :               nops += 4;
   22541      9415363 :               extra += COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22542              :             }
   22543      9730726 :           goto do_qimode;
   22544              : 
   22545      9729092 :         case V32QImode:
   22546      9729092 :           nmults = 1;
   22547      9729092 :           nops = 3;
   22548      9729092 :           extra = 0;
   22549              : 
   22550      9729092 :           if (!TARGET_AVX512BW || TARGET_PREFER_AVX256)
   22551              :             {
   22552      9643940 :               nmults += 1;
   22553      9643940 :               nops += 4;
   22554              :               /* 2 loads, so no division by 2.  */
   22555      9643940 :               extra += COSTS_N_INSNS (cost->sse_load[3]);
   22556              :             }
   22557      9729092 :           goto do_qimode;
   22558              : 
   22559      9728613 :         case V64QImode:
   22560      9728613 :           nmults = 2;
   22561      9728613 :           nops = 9;
   22562              :           /* 2 loads of each size, so no division by 2.  */
   22563      9728613 :           extra = COSTS_N_INSNS (cost->sse_load[3] + cost->sse_load[4]);
   22564              : 
   22565     48648913 :         do_qimode:
   22566     48648913 :           return ix86_vec_cost (mode, cost->mulss * nmults
   22567     48648913 :                                 + cost->sse_op * nops) + extra;
   22568              : 
   22569     41606634 :         case V4SImode:
   22570              :           /* pmulld is used in this case. No emulation is needed.  */
   22571     41606634 :           if (TARGET_SSE4_1)
   22572      2268645 :             goto do_native;
   22573              :           /* V4SImode is emulated with 7 insns.  */
   22574              :           else
   22575     39337989 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 5);
   22576              : 
   22577    168171263 :         case V2DImode:
   22578    168171263 :         case V4DImode:
   22579              :           /* vpmullq is used in this case. No emulation is needed.  */
   22580    168171263 :           if (TARGET_AVX512DQ && TARGET_AVX512VL)
   22581       650747 :             goto do_native;
   22582              :           /* V*DImode is emulated with 6-8 insns.  */
   22583    167520516 :           else if (TARGET_XOP && mode == V2DImode)
   22584        55164 :             return ix86_vec_cost (mode, cost->mulss * 2 + cost->sse_op * 4);
   22585              :           /* FALLTHRU */
   22586    251486032 :         case V8DImode:
   22587              :           /* vpmullq is used in this case. No emulation is needed.  */
   22588    251486032 :           if (TARGET_AVX512DQ && mode == V8DImode)
   22589       417628 :             goto do_native;
   22590              :           else
   22591    251068404 :             return ix86_vec_cost (mode, cost->mulss * 3 + cost->sse_op * 5);
   22592              : 
   22593    896661217 :         default:
   22594    896661217 :         do_native:
   22595    896661217 :           return ix86_vec_cost (mode, cost->mulss);
   22596              :         }
   22597              :     }
   22598              :   else
   22599       182262 :     return (cost->mult_init[MODE_INDEX (mode)] + cost->mult_bit * 7);
   22600              : }
   22601              : 
   22602              : /* Return cost of multiplication in MODE.  */
   22603              : 
   22604              : static int
   22605     74843840 : ix86_division_cost (const struct processor_costs *cost,
   22606              :                           enum machine_mode mode)
   22607              : {
   22608     74843840 :   machine_mode inner_mode = mode;
   22609     74843840 :   if (VECTOR_MODE_P (mode))
   22610     54852312 :     inner_mode = GET_MODE_INNER (mode);
   22611              : 
   22612     74843840 :   if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   22613       256392 :     return inner_mode == DFmode ? cost->divsd : cost->divss;
   22614     74587448 :   else if (X87_FLOAT_MODE_P (mode))
   22615        46863 :     return cost->fdiv;
   22616     74540585 :   else if (FLOAT_MODE_P (mode))
   22617        22361 :     return ix86_vec_cost (mode,
   22618        22361 :                           inner_mode == DFmode ? cost->divsd : cost->divss);
   22619              :   else
   22620     83592294 :     return cost->divide[MODE_INDEX (mode)];
   22621              : }
   22622              : 
   22623              : /* Return cost of shift in MODE.
   22624              :    If CONSTANT_OP1 is true, the op1 value is known and set in OP1_VAL.
   22625              :    AND_IN_OP1 specify in op1 is result of AND and SHIFT_AND_TRUNCATE
   22626              :    if op1 is a result of subreg.
   22627              : 
   22628              :    SKIP_OP0/1 is set to true if cost of OP0/1 should be ignored.  */
   22629              : 
   22630              : static int
   22631    794436966 : ix86_shift_rotate_cost (const struct processor_costs *cost,
   22632              :                         enum rtx_code code,
   22633              :                         enum machine_mode mode, bool constant_op1,
   22634              :                         HOST_WIDE_INT op1_val,
   22635              :                         bool and_in_op1,
   22636              :                         bool shift_and_truncate,
   22637              :                         bool *skip_op0, bool *skip_op1)
   22638              : {
   22639    794436966 :   if (skip_op0)
   22640    794352945 :     *skip_op0 = *skip_op1 = false;
   22641              : 
   22642    794436966 :   if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   22643              :     {
   22644    407988114 :       int count;
   22645              :       /* Cost of reading the memory.  */
   22646    407988114 :       int extra;
   22647              : 
   22648    407988114 :       switch (mode)
   22649              :         {
   22650      6192129 :         case V4QImode:
   22651      6192129 :         case V8QImode:
   22652      6192129 :           if (TARGET_AVX2)
   22653              :             /* Use vpbroadcast.  */
   22654       199007 :             extra = cost->sse_op;
   22655              :           else
   22656      5993122 :             extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22657              : 
   22658      6192129 :           if (constant_op1)
   22659              :             {
   22660      6192099 :               if (code == ASHIFTRT)
   22661              :                 {
   22662          308 :                   count = 4;
   22663          308 :                   extra *= 2;
   22664              :                 }
   22665              :               else
   22666              :                 count = 2;
   22667              :             }
   22668           30 :           else if (TARGET_AVX512BW && TARGET_AVX512VL)
   22669           30 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   22670            0 :           else if (TARGET_SSE4_1)
   22671              :             count = 5;
   22672            0 :           else if (code == ASHIFTRT)
   22673              :             count = 6;
   22674              :           else
   22675            0 :             count = 5;
   22676      6192099 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   22677              : 
   22678      3099146 :         case V16QImode:
   22679      3099146 :           if (TARGET_XOP)
   22680              :             {
   22681              :               /* For XOP we use vpshab, which requires a broadcast of the
   22682              :                  value to the variable shift insn.  For constants this
   22683              :                  means a V16Q const in mem; even when we can perform the
   22684              :                  shift with one insn set the cost to prefer paddb.  */
   22685         3573 :               if (constant_op1)
   22686              :                 {
   22687         2614 :                   extra = COSTS_N_INSNS (cost->sse_load[2]) / 2;
   22688         2614 :                   return ix86_vec_cost (mode, cost->sse_op) + extra;
   22689              :                 }
   22690              :               else
   22691              :                 {
   22692          959 :                   count = (code == ASHIFT) ? 3 : 4;
   22693          959 :                   return ix86_vec_cost (mode, cost->sse_op * count);
   22694              :                 }
   22695              :             }
   22696              :           /* FALLTHRU */
   22697      6191378 :         case V32QImode:
   22698      6191378 :           if (TARGET_GFNI && constant_op1)
   22699              :             {
   22700              :               /* Use vgf2p8affine.  One extra load for the mask, but in a loop
   22701              :                  with enough registers it will be moved out.  So for now don't
   22702              :                  account the constant mask load.  This is not quite right
   22703              :                  for non loop vectorization.  */
   22704        12368 :               extra = 0;
   22705        12368 :               return ix86_vec_cost (mode, cost->sse_op) + extra;
   22706              :             }
   22707      6179010 :           if (TARGET_AVX2)
   22708              :             /* Use vpbroadcast.  */
   22709       191318 :             extra = cost->sse_op;
   22710              :           else
   22711      5987692 :             extra = COSTS_N_INSNS (mode == V16QImode
   22712              :                                    ? cost->sse_load[2]
   22713      5987692 :                                    : cost->sse_load[3]) / 2;
   22714              : 
   22715      6179010 :           if (constant_op1)
   22716              :             {
   22717      6178778 :               if (code == ASHIFTRT)
   22718              :                 {
   22719          381 :                   count = 4;
   22720          381 :                   extra *= 2;
   22721              :                 }
   22722              :               else
   22723              :                 count = 2;
   22724              :             }
   22725          232 :           else if (TARGET_AVX512BW
   22726           76 :                    && ((mode == V32QImode && !TARGET_PREFER_AVX256)
   22727           38 :                        || (mode == V16QImode && TARGET_AVX512VL
   22728           38 :                            && !TARGET_PREFER_AVX128)))
   22729           76 :             return ix86_vec_cost (mode, cost->sse_op * 4);
   22730          156 :           else if (TARGET_AVX2
   22731            0 :                    && mode == V16QImode && !TARGET_PREFER_AVX128)
   22732              :             count = 6;
   22733          156 :           else if (TARGET_SSE4_1)
   22734              :             count = 9;
   22735          148 :           else if (code == ASHIFTRT)
   22736              :             count = 10;
   22737              :           else
   22738           84 :             count = 9;
   22739      6178934 :           return ix86_vec_cost (mode, cost->sse_op * count) + extra;
   22740              : 
   22741      3095932 :         case V64QImode:
   22742              :           /* Ignore the mask load for GF2P8AFFINEQB.  */
   22743      3095932 :           extra = 0;
   22744      3095932 :           return ix86_vec_cost (mode, cost->sse_op) + extra;
   22745              : 
   22746     55822937 :         case V2DImode:
   22747     55822937 :         case V4DImode:
   22748              :           /* V*DImode arithmetic right shift is emulated.  */
   22749     55822937 :           if (code == ASHIFTRT && !TARGET_AVX512VL)
   22750              :             {
   22751         1522 :               if (constant_op1)
   22752              :                 {
   22753          761 :                   if (op1_val == 63)
   22754          490 :                     count = TARGET_SSE4_2 ? 1 : 2;
   22755          570 :                   else if (TARGET_XOP)
   22756              :                     count = 2;
   22757          271 :                   else if (TARGET_SSE4_1)
   22758              :                     count = 3;
   22759              :                   else
   22760          291 :                     count = 4;
   22761              :                 }
   22762          761 :               else if (TARGET_XOP)
   22763              :                 count = 3;
   22764           96 :               else if (TARGET_SSE4_2)
   22765              :                 count = 4;
   22766              :               else
   22767         1522 :                 count = 5;
   22768              : 
   22769         1522 :               return ix86_vec_cost (mode, cost->sse_op * count);
   22770              :             }
   22771              :           /* FALLTHRU */
   22772    392503580 :         default:
   22773    392503580 :           return ix86_vec_cost (mode, cost->sse_op);
   22774              :         }
   22775              :     }
   22776              : 
   22777    781628900 :   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   22778              :     {
   22779    197654266 :       if (constant_op1)
   22780              :         {
   22781    197619325 :           if (op1_val > 32)
   22782    140407473 :             return cost->shift_const + COSTS_N_INSNS (2);
   22783              :           else
   22784     57211852 :             return cost->shift_const * 2;
   22785              :         }
   22786              :       else
   22787              :         {
   22788        34941 :           if (and_in_op1)
   22789           63 :             return cost->shift_var * 2;
   22790              :           else
   22791        34878 :             return cost->shift_var * 6 + COSTS_N_INSNS (2);
   22792              :         }
   22793              :     }
   22794              :   else
   22795              :     {
   22796    188794586 :       if (constant_op1)
   22797    188019804 :         return cost->shift_const;
   22798       774782 :       else if (shift_and_truncate)
   22799              :         {
   22800        24056 :           if (skip_op0)
   22801        24056 :             *skip_op0 = *skip_op1 = true;
   22802              :           /* Return the cost after shift-and truncation.  */
   22803        24056 :           return cost->shift_var;
   22804              :         }
   22805              :       else
   22806       750726 :         return cost->shift_var;
   22807              :     }
   22808              : }
   22809              : 
   22810              : static int
   22811    157985231 : ix86_insn_cost (rtx_insn *insn, bool speed)
   22812              : {
   22813    157985231 :   int insn_cost = 0;
   22814              :   /* Add extra cost to avoid post_reload late_combine revert
   22815              :      the optimization did in pass_rpad.  */
   22816    157985231 :   if (reload_completed
   22817      4613156 :       && ix86_rpad_gate ()
   22818       249350 :       && recog_memoized (insn) >= 0
   22819    158234260 :       && get_attr_avx_partial_xmm_update (insn)
   22820              :       == AVX_PARTIAL_XMM_UPDATE_TRUE)
   22821              :     insn_cost += COSTS_N_INSNS (3);
   22822              : 
   22823    157985231 :   rtx pat = PATTERN (insn);
   22824              :   /* A USE of a memory is more expensive than a use of a REG.
   22825              :      For example *<absneg>mode2_1's use of a signbit mask.  */
   22826    157985231 :   if (GET_CODE (pat) == PARALLEL)
   22827              :     {
   22828     48645382 :       for (int i = 0; i < XVECLEN (pat, 0); i++)
   22829              :         {
   22830     32673351 :           rtx x = XVECEXP (pat, 0, i);
   22831     32673351 :           if (GET_CODE (x) == USE && MEM_P (XEXP (x, 0)))
   22832        63529 :             insn_cost += !speed ? COSTS_N_BYTES (4)
   22833        29796 :                                 : TARGET_64BIT ? COSTS_N_INSNS (1) + 1
   22834              :                                                : COSTS_N_INSNS (3) + 1;
   22835              :         }
   22836              :     }
   22837              :   /* Cost *h{add,sub}<mode>[_low] directly as pattern cost for the
   22838              :      variants with outer vec_concat are artificially low.  */
   22839    157985231 :   if (INSN_CODE (insn) >= 0
   22840    157985231 :       && get_attr_cost_special (insn) == COST_SPECIAL_HADDSUB)
   22841          632 :     return insn_cost + ix86_vec_cost (GET_MODE (pat),
   22842          316 :                                       (speed ? ix86_tune_cost
   22843          316 :                                        : &ix86_size_cost)->addss);
   22844              : 
   22845    157984915 :   return insn_cost + pattern_cost (pat, speed);
   22846              : }
   22847              : 
   22848              : /* Return cost of SSE/AVX FP->FP conversion (extensions and truncates).  */
   22849              : 
   22850              : static int
   22851       778880 : vec_fp_conversion_cost (const struct processor_costs *cost, int size)
   22852              : {
   22853       778880 :   if (size < 128)
   22854       773650 :     return cost->cvtss2sd;
   22855         5230 :   else if (size < 256)
   22856              :     {
   22857         2445 :       if (TARGET_SSE_SPLIT_REGS)
   22858            0 :         return cost->cvtss2sd * size / 64;
   22859         2445 :       return cost->cvtss2sd;
   22860              :     }
   22861         2785 :   if (size < 512)
   22862         1483 :     return cost->vcvtps2pd256;
   22863              :   else
   22864         1302 :     return cost->vcvtps2pd512;
   22865              : }
   22866              : 
   22867              : /* Return true of X is UNSPEC with UNSPEC_PCMP or UNSPEC_UNSIGNED_PCMP.  */
   22868              : 
   22869              : static bool
   22870       299971 : unspec_pcmp_p (rtx x)
   22871              : {
   22872       299971 :   return GET_CODE (x) == UNSPEC
   22873       299971 :          && (XINT (x, 1) == UNSPEC_PCMP || XINT (x, 1) == UNSPEC_UNSIGNED_PCMP);
   22874              : }
   22875              : 
   22876              : /* Compute a (partial) cost for rtx X.  Return true if the complete
   22877              :    cost has been computed, and false if subexpressions should be
   22878              :    scanned.  In either case, *TOTAL contains the cost result.  */
   22879              : 
   22880              : static bool
   22881   7896605739 : ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
   22882              :                 int *total, bool speed)
   22883              : {
   22884   7896605739 :   rtx mask;
   22885   7896605739 :   enum rtx_code code = GET_CODE (x);
   22886   7896605739 :   enum rtx_code outer_code = (enum rtx_code) outer_code_i;
   22887   4230429591 :   const struct processor_costs *cost
   22888   7896605739 :     = speed ? ix86_tune_cost : &ix86_size_cost;
   22889   7896605739 :   int src_cost;
   22890              : 
   22891              :   /* Handling different vternlog variants.  */
   22892   7896605739 :   if ((GET_MODE_SIZE (mode) == 64
   22893   7896605739 :        ? TARGET_AVX512F
   22894   6683801830 :        : (TARGET_AVX512VL
   22895   6619761916 :           || (TARGET_AVX512F && !TARGET_PREFER_AVX256)))
   22896    179572817 :       && GET_MODE_SIZE (mode) >= 16
   22897    121993840 :       && outer_code_i == SET
   22898   7943734178 :       && ternlog_operand (x, mode))
   22899              :     {
   22900        33622 :       rtx args[3];
   22901              : 
   22902        33622 :       args[0] = NULL_RTX;
   22903        33622 :       args[1] = NULL_RTX;
   22904        33622 :       args[2] = NULL_RTX;
   22905        33622 :       int idx = ix86_ternlog_idx (x, args);
   22906        33622 :       gcc_assert (idx >= 0);
   22907              : 
   22908        33622 :       *total = cost->sse_op;
   22909       134488 :       for (int i = 0; i != 3; i++)
   22910       100866 :         if (args[i])
   22911        71132 :           *total += rtx_cost (args[i], GET_MODE (args[i]), UNSPEC, i, speed);
   22912        33622 :       return true;
   22913              :     }
   22914              : 
   22915              : 
   22916   7896572117 :   switch (code)
   22917              :     {
   22918     49696740 :     case SET:
   22919     49696740 :       if (register_operand (SET_DEST (x), VOIDmode)
   22920     49696740 :           && register_operand (SET_SRC (x), VOIDmode))
   22921              :         {
   22922     30090342 :           *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
   22923     30090342 :           return true;
   22924              :         }
   22925              : 
   22926     19606398 :       if (register_operand (SET_SRC (x), VOIDmode))
   22927              :         /* Avoid potentially incorrect high cost from rtx_costs
   22928              :            for non-tieable SUBREGs.  */
   22929              :         src_cost = 0;
   22930              :       else
   22931              :         {
   22932     16740735 :           src_cost = rtx_cost (SET_SRC (x), mode, SET, 1, speed);
   22933              : 
   22934     16740735 :           if (CONSTANT_P (SET_SRC (x)))
   22935              :             /* Constant costs assume a base value of COSTS_N_INSNS (1) and add
   22936              :                a small value, possibly zero for cheap constants.  */
   22937      7368155 :             src_cost += COSTS_N_INSNS (1);
   22938              :         }
   22939              : 
   22940     19606398 :       *total = src_cost + rtx_cost (SET_DEST (x), mode, SET, 0, speed);
   22941     19606398 :       return true;
   22942              : 
   22943   2908097480 :     case CONST_INT:
   22944   2908097480 :     case CONST:
   22945   2908097480 :     case LABEL_REF:
   22946   2908097480 :     case SYMBOL_REF:
   22947   2908097480 :       if (x86_64_immediate_operand (x, VOIDmode))
   22948   2286251538 :         *total = 0;
   22949    621845942 :       else if (TARGET_64BIT && x86_64_zext_immediate_operand (x, VOIDmode))
   22950              :         /* Consider the zext constants slightly more expensive, as they
   22951              :            can't appear in most instructions.  */
   22952     28720679 :         *total = 1;
   22953              :       else
   22954              :         /* movabsq is slightly more expensive than a simple instruction. */
   22955    593125263 :         *total = COSTS_N_INSNS (1) + 1;
   22956              :       return true;
   22957              : 
   22958      7700238 :     case CONST_DOUBLE:
   22959      7700238 :       if (IS_STACK_MODE (mode))
   22960      1295768 :         switch (standard_80387_constant_p (x))
   22961              :           {
   22962              :           case -1:
   22963              :           case 0:
   22964              :             break;
   22965       274842 :           case 1: /* 0.0 */
   22966       274842 :             *total = 1;
   22967       274842 :             return true;
   22968       469112 :           default: /* Other constants */
   22969       469112 :             *total = 2;
   22970       469112 :             return true;
   22971              :           }
   22972              :       /* FALLTHRU */
   22973              : 
   22974     15196511 :     case CONST_VECTOR:
   22975     15196511 :       switch (standard_sse_constant_p (x, mode))
   22976              :         {
   22977              :         case 0:
   22978              :           break;
   22979      4504137 :         case 1:  /* 0: xor eliminates false dependency */
   22980      4504137 :           *total = 0;
   22981      4504137 :           return true;
   22982       211476 :         default: /* -1: cmp contains false dependency */
   22983       211476 :           *total = 1;
   22984       211476 :           return true;
   22985              :         }
   22986              :       /* FALLTHRU */
   22987              : 
   22988     11513622 :     case CONST_WIDE_INT:
   22989              :       /* Fall back to (MEM (SYMBOL_REF)), since that's where
   22990              :          it'll probably end up.  Add a penalty for size.  */
   22991     23027244 :       *total = (COSTS_N_INSNS (1)
   22992     22798371 :                 + (!TARGET_64BIT && flag_pic)
   22993     23027244 :                 + (GET_MODE_SIZE (mode) <= 4
   22994     20170227 :                    ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
   22995     11513622 :       return true;
   22996              : 
   22997     23175366 :     case ZERO_EXTEND:
   22998              :       /* The zero extensions is often completely free on x86_64, so make
   22999              :          it as cheap as possible.  */
   23000     23175366 :       if (TARGET_64BIT && mode == DImode
   23001      5040292 :           && GET_MODE (XEXP (x, 0)) == SImode)
   23002      3081017 :         *total = 1;
   23003     20094349 :       else if (TARGET_ZERO_EXTEND_WITH_AND)
   23004            0 :         *total = cost->add;
   23005              :       else
   23006     20094349 :         *total = cost->movzx;
   23007              :       return false;
   23008              : 
   23009      2872517 :     case SIGN_EXTEND:
   23010      2872517 :       *total = cost->movsx;
   23011      2872517 :       return false;
   23012              : 
   23013    653479454 :     case ASHIFT:
   23014    653479454 :       if (SCALAR_INT_MODE_P (mode)
   23015    252445898 :           && GET_MODE_SIZE (mode) < UNITS_PER_WORD
   23016    697674857 :           && CONST_INT_P (XEXP (x, 1)))
   23017              :         {
   23018     44006556 :           HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   23019     44006556 :           if (value == 1)
   23020              :             {
   23021      2540211 :               *total = cost->add;
   23022      2540211 :               return false;
   23023              :             }
   23024     41466345 :           if ((value == 2 || value == 3)
   23025      4657776 :               && cost->lea <= cost->shift_const)
   23026              :             {
   23027      2200039 :               *total = cost->lea;
   23028      2200039 :               return false;
   23029              :             }
   23030              :         }
   23031              :       /* FALLTHRU */
   23032              : 
   23033    794352945 :     case ROTATE:
   23034    794352945 :     case ASHIFTRT:
   23035    794352945 :     case LSHIFTRT:
   23036    794352945 :     case ROTATERT:
   23037    794352945 :       bool skip_op0, skip_op1;
   23038    794352945 :       *total = ix86_shift_rotate_cost (cost, code, mode,
   23039    794352945 :                                        CONSTANT_P (XEXP (x, 1)),
   23040              :                                        CONST_INT_P (XEXP (x, 1))
   23041              :                                          ? INTVAL (XEXP (x, 1)) : -1,
   23042              :                                        GET_CODE (XEXP (x, 1)) == AND,
   23043    794352945 :                                        SUBREG_P (XEXP (x, 1))
   23044       675351 :                                        && GET_CODE (XEXP (XEXP (x, 1),
   23045              :                                                           0)) == AND,
   23046              :                                        &skip_op0, &skip_op1);
   23047    794352945 :       if (skip_op0 || skip_op1)
   23048              :         {
   23049        24056 :           if (!skip_op0)
   23050            0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23051        24056 :           if (!skip_op1)
   23052            0 :             *total += rtx_cost (XEXP (x, 1), mode, code, 0, speed);
   23053              :           return true;
   23054              :         }
   23055              :       return false;
   23056              : 
   23057       228384 :     case FMA:
   23058       228384 :       {
   23059       228384 :         rtx sub;
   23060              : 
   23061       228384 :         gcc_assert (FLOAT_MODE_P (mode));
   23062       228384 :         gcc_assert (TARGET_FMA || TARGET_FMA4 || TARGET_AVX512F);
   23063              : 
   23064       456768 :         *total = ix86_vec_cost (mode,
   23065       228384 :                                 GET_MODE_INNER (mode) == SFmode
   23066              :                                 ? cost->fmass : cost->fmasd);
   23067       228384 :         *total += rtx_cost (XEXP (x, 1), mode, FMA, 1, speed);
   23068              : 
   23069              :         /* Negate in op0 or op2 is free: FMS, FNMA, FNMS.  */
   23070       228384 :         sub = XEXP (x, 0);
   23071       228384 :         if (GET_CODE (sub) == NEG)
   23072        51259 :           sub = XEXP (sub, 0);
   23073       228384 :         *total += rtx_cost (sub, mode, FMA, 0, speed);
   23074              : 
   23075       228384 :         sub = XEXP (x, 2);
   23076       228384 :         if (GET_CODE (sub) == NEG)
   23077        40590 :           sub = XEXP (sub, 0);
   23078       228384 :         *total += rtx_cost (sub, mode, FMA, 2, speed);
   23079       228384 :         return true;
   23080              :       }
   23081              : 
   23082   1801843990 :     case MULT:
   23083   1801843990 :       if (!FLOAT_MODE_P (mode) && !VECTOR_MODE_P (mode))
   23084              :         {
   23085    565079678 :           rtx op0 = XEXP (x, 0);
   23086    565079678 :           rtx op1 = XEXP (x, 1);
   23087    565079678 :           int nbits;
   23088    565079678 :           if (CONST_INT_P (XEXP (x, 1)))
   23089              :             {
   23090    546393877 :               unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
   23091   1108588077 :               for (nbits = 0; value != 0; value &= value - 1)
   23092    562194200 :                 nbits++;
   23093              :             }
   23094              :           else
   23095              :             /* This is arbitrary.  */
   23096              :             nbits = 7;
   23097              : 
   23098              :           /* Compute costs correctly for widening multiplication.  */
   23099    565079678 :           if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
   23100    570787639 :               && GET_MODE_SIZE (GET_MODE (XEXP (op0, 0))) * 2
   23101      5707961 :                  == GET_MODE_SIZE (mode))
   23102              :             {
   23103      5692553 :               int is_mulwiden = 0;
   23104      5692553 :               machine_mode inner_mode = GET_MODE (op0);
   23105              : 
   23106      5692553 :               if (GET_CODE (op0) == GET_CODE (op1))
   23107      5589191 :                 is_mulwiden = 1, op1 = XEXP (op1, 0);
   23108       103362 :               else if (CONST_INT_P (op1))
   23109              :                 {
   23110        93224 :                   if (GET_CODE (op0) == SIGN_EXTEND)
   23111        40115 :                     is_mulwiden = trunc_int_for_mode (INTVAL (op1), inner_mode)
   23112        40115 :                                   == INTVAL (op1);
   23113              :                   else
   23114        53109 :                     is_mulwiden = !(INTVAL (op1) & ~GET_MODE_MASK (inner_mode));
   23115              :                 }
   23116              : 
   23117      5682415 :               if (is_mulwiden)
   23118      5682415 :                 op0 = XEXP (op0, 0), mode = GET_MODE (op0);
   23119              :             }
   23120              : 
   23121    565079678 :           int mult_init;
   23122              :           // Double word multiplication requires 3 mults and 2 adds.
   23123   1145895947 :           if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23124              :             {
   23125    340041769 :               mult_init = 3 * cost->mult_init[MODE_INDEX (word_mode)]
   23126    340041769 :                           + 2 * cost->add;
   23127    340041769 :               nbits *= 3;
   23128              :             }
   23129    388169218 :           else mult_init = cost->mult_init[MODE_INDEX (mode)];
   23130              : 
   23131   1130159356 :           *total = (mult_init
   23132    565079678 :                     + nbits * cost->mult_bit
   23133    565079678 :                     + rtx_cost (op0, mode, outer_code, opno, speed)
   23134    565079678 :                     + rtx_cost (op1, mode, outer_code, opno, speed));
   23135              : 
   23136    565079678 :           return true;
   23137              :         }
   23138   1236764312 :       *total = ix86_multiplication_cost (cost, mode);
   23139   1236764312 :       return false;
   23140              : 
   23141     74828408 :     case DIV:
   23142     74828408 :     case UDIV:
   23143     74828408 :     case MOD:
   23144     74828408 :     case UMOD:
   23145     74828408 :       *total = ix86_division_cost (cost, mode);
   23146     74828408 :       return false;
   23147              : 
   23148    706008760 :     case PLUS:
   23149    706008760 :       if (GET_MODE_CLASS (mode) == MODE_INT
   23150    967626473 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   23151              :         {
   23152    145806871 :           if (GET_CODE (XEXP (x, 0)) == PLUS
   23153      3483464 :               && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
   23154       811484 :               && CONST_INT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))
   23155       811475 :               && CONSTANT_P (XEXP (x, 1)))
   23156              :             {
   23157       811443 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
   23158       811443 :               if (val == 2 || val == 4 || val == 8)
   23159              :                 {
   23160       811341 :                   *total = cost->lea;
   23161       811341 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   23162              :                                       outer_code, opno, speed);
   23163       811341 :                   *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0), mode,
   23164              :                                       outer_code, opno, speed);
   23165       811341 :                   *total += rtx_cost (XEXP (x, 1), mode,
   23166              :                                       outer_code, opno, speed);
   23167       811341 :                   return true;
   23168              :                 }
   23169              :             }
   23170    144995428 :           else if (GET_CODE (XEXP (x, 0)) == MULT
   23171     53561103 :                    && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   23172              :             {
   23173     53497945 :               HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
   23174     53497945 :               if (val == 2 || val == 4 || val == 8)
   23175              :                 {
   23176      8088438 :                   *total = cost->lea;
   23177      8088438 :                   *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23178              :                                       outer_code, opno, speed);
   23179      8088438 :                   *total += rtx_cost (XEXP (x, 1), mode,
   23180              :                                       outer_code, opno, speed);
   23181      8088438 :                   return true;
   23182              :                 }
   23183              :             }
   23184     91497483 :           else if (GET_CODE (XEXP (x, 0)) == PLUS)
   23185              :             {
   23186      2672021 :               rtx op = XEXP (XEXP (x, 0), 0);
   23187              : 
   23188              :               /* Add with carry, ignore the cost of adding a carry flag.  */
   23189      2672021 :               if (ix86_carry_flag_operator (op, mode)
   23190      2672021 :                   || ix86_carry_flag_unset_operator (op, mode))
   23191        69046 :                 *total = cost->add;
   23192              :               else
   23193              :                 {
   23194      2602975 :                   *total = cost->lea;
   23195      2602975 :                   *total += rtx_cost (op, mode,
   23196              :                                       outer_code, opno, speed);
   23197              :                 }
   23198              : 
   23199      2672021 :               *total += rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   23200              :                                   outer_code, opno, speed);
   23201      2672021 :               *total += rtx_cost (XEXP (x, 1), mode,
   23202              :                                   outer_code, opno, speed);
   23203      2672021 :               return true;
   23204              :             }
   23205              :         }
   23206              :       /* FALLTHRU */
   23207              : 
   23208   1881625043 :     case MINUS:
   23209              :       /* Subtract with borrow, ignore the cost of subtracting a carry flag.  */
   23210   1881625043 :       if (GET_MODE_CLASS (mode) == MODE_INT
   23211    531807722 :           && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
   23212    240989937 :           && GET_CODE (XEXP (x, 0)) == MINUS
   23213   1881664151 :           && (ix86_carry_flag_operator (XEXP (XEXP (x, 0), 1), mode)
   23214        15447 :               || ix86_carry_flag_unset_operator (XEXP (XEXP (x, 0), 1), mode)))
   23215              :         {
   23216        23661 :           *total = cost->add;
   23217        23661 :           *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23218              :                               outer_code, opno, speed);
   23219        23661 :           *total += rtx_cost (XEXP (x, 1), mode,
   23220              :                               outer_code, opno, speed);
   23221        23661 :           return true;
   23222              :         }
   23223              : 
   23224   1881601382 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23225      2434936 :         *total = cost->addss;
   23226   1879166446 :       else if (X87_FLOAT_MODE_P (mode))
   23227       224016 :         *total = cost->fadd;
   23228   1878942430 :       else if (FLOAT_MODE_P (mode))
   23229       455148 :         *total = ix86_vec_cost (mode, cost->addss);
   23230   1878487282 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23231   1236542768 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23232   1323394375 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23233    339071638 :         *total = cost->add * 2;
   23234              :       else
   23235    302872876 :         *total = cost->add;
   23236              :       return false;
   23237              : 
   23238      3933007 :     case IOR:
   23239      3933007 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23240      3680338 :           || SSE_FLOAT_MODE_P (mode))
   23241              :         {
   23242              :           /* (ior (not ...) ...) can be a single insn in AVX512.  */
   23243         3091 :           if (GET_CODE (XEXP (x, 0)) == NOT && TARGET_AVX512F
   23244       266632 :               && (GET_MODE_SIZE (mode) == 64
   23245            0 :                   || (TARGET_AVX512VL
   23246            0 :                       && (GET_MODE_SIZE (mode) == 32
   23247            0 :                           || GET_MODE_SIZE (mode) == 16))))
   23248              :             {
   23249            0 :               rtx right = GET_CODE (XEXP (x, 1)) != NOT
   23250            0 :                           ? XEXP (x, 1) : XEXP (XEXP (x, 1), 0);
   23251              : 
   23252            0 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23253            0 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23254              :                                    outer_code, opno, speed)
   23255            0 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   23256            0 :               return true;
   23257              :             }
   23258       266632 :           *total = ix86_vec_cost (mode, cost->sse_op);
   23259       266632 :         }
   23260      3666375 :       else if (TARGET_64BIT
   23261      3367020 :                && mode == TImode
   23262      1755784 :                && GET_CODE (XEXP (x, 0)) == ASHIFT
   23263       262157 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
   23264       260144 :                && GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == DImode
   23265       260144 :                && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   23266       260144 :                && INTVAL (XEXP (XEXP (x, 0), 1)) == 64
   23267       260144 :                && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND
   23268       236779 :                && GET_MODE (XEXP (XEXP (x, 1), 0)) == DImode)
   23269              :         {
   23270              :           /* *concatditi3 is cheap.  */
   23271       236779 :           rtx op0 = XEXP (XEXP (XEXP (x, 0), 0), 0);
   23272       236779 :           rtx op1 = XEXP (XEXP (x, 1), 0);
   23273         1574 :           *total = (SUBREG_P (op0) && GET_MODE (SUBREG_REG (op0)) == DFmode)
   23274       236779 :                    ? COSTS_N_INSNS (1)    /* movq.  */
   23275       235205 :                    : set_src_cost (op0, DImode, speed);
   23276         2506 :           *total += (SUBREG_P (op1) && GET_MODE (SUBREG_REG (op1)) == DFmode)
   23277       236779 :                     ? COSTS_N_INSNS (1)    /* movq.  */
   23278       234286 :                     : set_src_cost (op1, DImode, speed);
   23279       236779 :           return true;
   23280              :         }
   23281      3429596 :       else if (TARGET_64BIT
   23282      3130241 :                && mode == TImode
   23283      1519005 :                && GET_CODE (XEXP (x, 0)) == AND
   23284      1457030 :                && REG_P (XEXP (XEXP (x, 0), 0))
   23285      1451703 :                && CONST_WIDE_INT_P (XEXP (XEXP (x, 0), 1))
   23286      1448960 :                && CONST_WIDE_INT_NUNITS (XEXP (XEXP (x, 0), 1)) == 2
   23287      1448960 :                && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 0) == -1
   23288       941449 :                && CONST_WIDE_INT_ELT (XEXP (XEXP (x, 0), 1), 1) == 0
   23289       941449 :                && GET_CODE (XEXP (x, 1)) == ASHIFT
   23290       938991 :                && GET_CODE (XEXP (XEXP (x, 1), 0)) == ZERO_EXTEND
   23291       938991 :                && GET_MODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == DImode
   23292       938991 :                && CONST_INT_P (XEXP (XEXP (x, 1), 1))
   23293      4368587 :                && INTVAL (XEXP (XEXP (x, 1), 1)) == 64)
   23294              :         {
   23295              :           /* *insvti_highpart is cheap.  */
   23296       938991 :           rtx op = XEXP (XEXP (XEXP (x, 1), 0), 0);
   23297       938991 :           *total = COSTS_N_INSNS (1) + 1;
   23298         1564 :           *total += (SUBREG_P (op) && GET_MODE (SUBREG_REG (op)) == DFmode)
   23299       938991 :                     ? COSTS_N_INSNS (1)    /* movq.  */
   23300       937951 :                     : set_src_cost (op, DImode, speed);
   23301       938991 :           return true;
   23302              :         }
   23303      5280565 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23304       778627 :         *total = cost->add * 2;
   23305              :       else
   23306      1711978 :         *total = cost->add;
   23307              :       return false;
   23308              : 
   23309       618940 :     case XOR:
   23310       618940 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23311       461686 :           || SSE_FLOAT_MODE_P (mode))
   23312       157254 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23313       984789 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23314        17837 :         *total = cost->add * 2;
   23315              :       else
   23316       443849 :         *total = cost->add;
   23317              :       return false;
   23318              : 
   23319      6741839 :     case AND:
   23320      6741839 :       if (address_no_seg_operand (x, mode))
   23321              :         {
   23322        13895 :           *total = cost->lea;
   23323        13895 :           return true;
   23324              :         }
   23325      6727944 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23326      6277858 :                || SSE_FLOAT_MODE_P (mode))
   23327              :         {
   23328              :           /* pandn is a single instruction.  */
   23329       492820 :           if (GET_CODE (XEXP (x, 0)) == NOT)
   23330              :             {
   23331        64666 :               rtx right = XEXP (x, 1);
   23332              : 
   23333              :               /* (and (not ...) (not ...)) can be a single insn in AVX512.  */
   23334          180 :               if (GET_CODE (right) == NOT && TARGET_AVX512F
   23335        64666 :                   && (GET_MODE_SIZE (mode) == 64
   23336            0 :                       || (TARGET_AVX512VL
   23337            0 :                           && (GET_MODE_SIZE (mode) == 32
   23338            0 :                               || GET_MODE_SIZE (mode) == 16))))
   23339            0 :                 right = XEXP (right, 0);
   23340              : 
   23341        64666 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23342        64666 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23343              :                                    outer_code, opno, speed)
   23344        64666 :                        + rtx_cost (right, mode, outer_code, opno, speed);
   23345        64666 :               return true;
   23346              :             }
   23347       428154 :           else if (GET_CODE (XEXP (x, 1)) == NOT)
   23348              :             {
   23349         2770 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23350         2770 :                        + rtx_cost (XEXP (x, 0), mode,
   23351              :                                    outer_code, opno, speed)
   23352         2770 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   23353              :                                    outer_code, opno, speed);
   23354         2770 :               return true;
   23355              :             }
   23356       425384 :           *total = ix86_vec_cost (mode, cost->sse_op);
   23357       425384 :         }
   23358     13205845 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23359              :         {
   23360      1178334 :           if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   23361              :             {
   23362         1670 :               *total = cost->add * 2
   23363          835 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23364              :                                    outer_code, opno, speed)
   23365          835 :                        + rtx_cost (XEXP (x, 1), mode,
   23366              :                                    outer_code, opno, speed);
   23367          835 :               return true;
   23368              :             }
   23369      1177499 :           else if (TARGET_BMI && GET_CODE (XEXP (x, 1)) == NOT)
   23370              :             {
   23371            0 :               *total = cost->add * 2
   23372            0 :                        + rtx_cost (XEXP (x, 0), mode,
   23373              :                                    outer_code, opno, speed)
   23374            0 :                        + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   23375              :                                    outer_code, opno, speed);
   23376            0 :               return true;
   23377              :             }
   23378      1177499 :           *total = cost->add * 2;
   23379              :         }
   23380      5056790 :       else if (TARGET_BMI && GET_CODE (XEXP (x,0)) == NOT)
   23381              :         {
   23382         7410 :           *total = cost->add
   23383         3705 :                    + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23384              :                                outer_code, opno, speed)
   23385         3705 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23386         3705 :           return true;
   23387              :         }
   23388      5053085 :       else if (TARGET_BMI && GET_CODE (XEXP (x,1)) == NOT)
   23389              :         {
   23390          112 :           *total = cost->add
   23391           56 :                    + rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   23392           56 :                    + rtx_cost (XEXP (XEXP (x, 1), 0), mode,
   23393              :                                outer_code, opno, speed);
   23394           56 :           return true;
   23395              :         }
   23396              :       else
   23397      5053029 :         *total = cost->add;
   23398              :       return false;
   23399              : 
   23400       575413 :     case NOT:
   23401       575413 :       if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23402              :         {
   23403              :           /* (not (xor ...)) can be a single insn in AVX512.  */
   23404            0 :           if (GET_CODE (XEXP (x, 0)) == XOR && TARGET_AVX512F
   23405        21796 :               && (GET_MODE_SIZE (mode) == 64
   23406            0 :                   || (TARGET_AVX512VL
   23407            0 :                       && (GET_MODE_SIZE (mode) == 32
   23408            0 :                           || GET_MODE_SIZE (mode) == 16))))
   23409              :             {
   23410            0 :               *total = ix86_vec_cost (mode, cost->sse_op)
   23411            0 :                        + rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23412              :                                    outer_code, opno, speed)
   23413            0 :                        + rtx_cost (XEXP (XEXP (x, 0), 1), mode,
   23414              :                                    outer_code, opno, speed);
   23415            0 :               return true;
   23416              :             }
   23417              : 
   23418              :           // vnot is pxor -1.
   23419        21796 :           *total = ix86_vec_cost (mode, cost->sse_op) + 1;
   23420              :         }
   23421      1257396 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23422        50237 :         *total = cost->add * 2;
   23423              :       else
   23424       503380 :         *total = cost->add;
   23425              :       return false;
   23426              : 
   23427     18729076 :     case NEG:
   23428     18729076 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23429        54089 :         *total = cost->sse_op;
   23430     18674987 :       else if (X87_FLOAT_MODE_P (mode))
   23431        15497 :         *total = cost->fchs;
   23432     18659490 :       else if (FLOAT_MODE_P (mode))
   23433        27409 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23434     18632081 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23435     13721816 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23436      9972221 :       else if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
   23437      1806966 :         *total = cost->add * 3;
   23438              :       else
   23439      3103299 :         *total = cost->add;
   23440              :       return false;
   23441              : 
   23442     55826699 :     case COMPARE:
   23443     55826699 :       rtx op0, op1;
   23444     55826699 :       op0 = XEXP (x, 0);
   23445     55826699 :       op1 = XEXP (x, 1);
   23446     55826699 :       if (GET_CODE (op0) == ZERO_EXTRACT
   23447        99488 :           && XEXP (op0, 1) == const1_rtx
   23448        88319 :           && CONST_INT_P (XEXP (op0, 2))
   23449        88287 :           && op1 == const0_rtx)
   23450              :         {
   23451              :           /* This kind of construct is implemented using test[bwl].
   23452              :              Treat it as if we had an AND.  */
   23453        88287 :           mode = GET_MODE (XEXP (op0, 0));
   23454       176574 :           *total = (cost->add
   23455        88287 :                     + rtx_cost (XEXP (op0, 0), mode, outer_code,
   23456              :                                 opno, speed)
   23457        88287 :                     + rtx_cost (const1_rtx, mode, outer_code, opno, speed));
   23458        88287 :           return true;
   23459              :         }
   23460              : 
   23461     55738412 :       if (GET_CODE (op0) == PLUS && rtx_equal_p (XEXP (op0, 0), op1))
   23462              :         {
   23463              :           /* This is an overflow detection, count it as a normal compare.  */
   23464       146291 :           *total = rtx_cost (op0, GET_MODE (op0), COMPARE, 0, speed);
   23465       146291 :           return true;
   23466              :         }
   23467              : 
   23468     55592121 :       rtx geu;
   23469              :       /* Match x
   23470              :          (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
   23471              :                       (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))  */
   23472     55592121 :       if (mode == CCCmode
   23473       312913 :           && GET_CODE (op0) == NEG
   23474         8174 :           && GET_CODE (geu = XEXP (op0, 0)) == GEU
   23475         8171 :           && REG_P (XEXP (geu, 0))
   23476         8171 :           && (GET_MODE (XEXP (geu, 0)) == CCCmode
   23477          769 :               || GET_MODE (XEXP (geu, 0)) == CCmode)
   23478         8171 :           && REGNO (XEXP (geu, 0)) == FLAGS_REG
   23479         8171 :           && XEXP (geu, 1) == const0_rtx
   23480         8171 :           && GET_CODE (op1) == LTU
   23481         8171 :           && REG_P (XEXP (op1, 0))
   23482         8171 :           && GET_MODE (XEXP (op1, 0)) == GET_MODE (XEXP (geu, 0))
   23483         8171 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   23484     55600292 :           && XEXP (op1, 1) == const0_rtx)
   23485              :         {
   23486              :           /* This is *setcc_qi_addqi3_cconly_overflow_1_* patterns, a nop.  */
   23487         8171 :           *total = 0;
   23488         8171 :           return true;
   23489              :         }
   23490              :       /* Match x
   23491              :          (compare:CCC (neg:QI (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
   23492              :                       (geu:QI (reg:CCC FLAGS_REG) (const_int 0)))  */
   23493     55583950 :       if (mode == CCCmode
   23494       304742 :           && GET_CODE (op0) == NEG
   23495            3 :           && GET_CODE (XEXP (op0, 0)) == LTU
   23496            3 :           && REG_P (XEXP (XEXP (op0, 0), 0))
   23497            3 :           && GET_MODE (XEXP (XEXP (op0, 0), 0)) == CCCmode
   23498            3 :           && REGNO (XEXP (XEXP (op0, 0), 0)) == FLAGS_REG
   23499            3 :           && XEXP (XEXP (op0, 0), 1) == const0_rtx
   23500            3 :           && GET_CODE (op1) == GEU
   23501            3 :           && REG_P (XEXP (op1, 0))
   23502            3 :           && GET_MODE (XEXP (op1, 0)) == CCCmode
   23503            3 :           && REGNO (XEXP (op1, 0)) == FLAGS_REG
   23504     55583953 :           && XEXP (op1, 1) == const0_rtx)
   23505              :         {
   23506              :           /* This is *x86_cmc.  */
   23507            3 :           if (!speed)
   23508            0 :             *total = COSTS_N_BYTES (1);
   23509            3 :           else if (TARGET_SLOW_STC)
   23510            0 :             *total = COSTS_N_INSNS (2);
   23511              :           else
   23512            3 :             *total = COSTS_N_INSNS (1);
   23513              :           return true;
   23514              :         }
   23515              : 
   23516     55583947 :       if (SCALAR_INT_MODE_P (GET_MODE (op0))
   23517    115629152 :           && GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
   23518              :         {
   23519       782969 :           if (op1 == const0_rtx)
   23520       109654 :             *total = cost->add
   23521       109654 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed);
   23522              :           else
   23523       673315 :             *total = 3*cost->add
   23524       673315 :                      + rtx_cost (op0, GET_MODE (op0), outer_code, opno, speed)
   23525       673315 :                      + rtx_cost (op1, GET_MODE (op0), outer_code, opno, speed);
   23526       782969 :           return true;
   23527              :         }
   23528              : 
   23529              :       /* The embedded comparison operand is completely free.  */
   23530     54800978 :       if (!general_operand (op0, GET_MODE (op0)) && op1 == const0_rtx)
   23531       379283 :         *total = 0;
   23532              : 
   23533              :       return false;
   23534              : 
   23535      1392289 :     case FLOAT_EXTEND:
   23536              :       /* x87 represents all values extended to 80bit.  */
   23537      1392289 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23538       667824 :         *total = 0;
   23539              :       else
   23540      1448930 :         *total = vec_fp_conversion_cost (cost, GET_MODE_BITSIZE (mode));
   23541              :       return false;
   23542              : 
   23543        85765 :     case FLOAT_TRUNCATE:
   23544        85765 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23545        58691 :         *total = cost->fadd;
   23546              :       else
   23547        54148 :         *total = vec_fp_conversion_cost (cost, GET_MODE_BITSIZE (mode));
   23548              :       return false;
   23549       703456 :     case FLOAT:
   23550       703456 :     case UNSIGNED_FLOAT:
   23551       703456 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23552              :         /* TODO: We do not have cost tables for x87.  */
   23553        95760 :         *total = cost->fadd;
   23554       607696 :       else if (VECTOR_MODE_P (mode))
   23555            0 :         *total = ix86_vec_cost (mode, cost->cvtpi2ps);
   23556              :       else
   23557       607696 :         *total = cost->cvtsi2ss;
   23558              :       return false;
   23559              : 
   23560       290251 :     case FIX:
   23561       290251 :     case UNSIGNED_FIX:
   23562       290251 :       if (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23563              :         /* TODO: We do not have cost tables for x87.  */
   23564       290251 :         *total = cost->fadd;
   23565            0 :       else if (VECTOR_MODE_P (mode))
   23566            0 :         *total = ix86_vec_cost (mode, cost->cvtps2pi);
   23567              :       else
   23568            0 :         *total = cost->cvtss2si;
   23569              :       return false;
   23570              : 
   23571       417450 :     case ABS:
   23572              :       /* SSE requires memory load for the constant operand. It may make
   23573              :          sense to account for this.  Of course the constant operand may or
   23574              :          may not be reused. */
   23575       417450 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23576       296741 :         *total = cost->sse_op;
   23577       120709 :       else if (X87_FLOAT_MODE_P (mode))
   23578        36906 :         *total = cost->fabs;
   23579        83803 :       else if (FLOAT_MODE_P (mode))
   23580        33864 :         *total = ix86_vec_cost (mode, cost->sse_op);
   23581        49939 :       else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
   23582         6657 :         *total = cost->sse_op;
   23583              :       return false;
   23584              : 
   23585        29325 :     case SQRT:
   23586        29325 :       if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   23587        18880 :         *total = mode == SFmode ? cost->sqrtss : cost->sqrtsd;
   23588        10445 :       else if (X87_FLOAT_MODE_P (mode))
   23589         4402 :         *total = cost->fsqrt;
   23590         6043 :       else if (FLOAT_MODE_P (mode))
   23591         6043 :         *total = ix86_vec_cost (mode,
   23592              :                                 mode == SFmode ? cost->sqrtss : cost->sqrtsd);
   23593              :       return false;
   23594              : 
   23595      4068946 :     case UNSPEC:
   23596      4068946 :       switch (XINT (x, 1))
   23597              :         {
   23598       126637 :         case UNSPEC_TP:
   23599       126637 :           *total = 0;
   23600       126637 :           break;
   23601              : 
   23602         5210 :         case UNSPEC_VTERNLOG:
   23603         5210 :           *total = cost->sse_op;
   23604         5210 :           if (!REG_P (XVECEXP (x, 0, 0)))
   23605          720 :             *total += rtx_cost (XVECEXP (x, 0, 0), mode, code, 0, speed);
   23606         5210 :           if (!REG_P (XVECEXP (x, 0, 1)))
   23607          694 :             *total += rtx_cost (XVECEXP (x, 0, 1), mode, code, 1, speed);
   23608         5210 :           if (!REG_P (XVECEXP (x, 0, 2)))
   23609          733 :             *total += rtx_cost (XVECEXP (x, 0, 2), mode, code, 2, speed);
   23610              :           return true;
   23611              : 
   23612        94907 :         case UNSPEC_PTEST:
   23613        94907 :           {
   23614        94907 :             *total = cost->sse_op;
   23615        94907 :             rtx test_op0 = XVECEXP (x, 0, 0);
   23616        94907 :             if (!rtx_equal_p (test_op0, XVECEXP (x, 0, 1)))
   23617              :               return false;
   23618        94259 :             if (GET_CODE (test_op0) == AND)
   23619              :               {
   23620           23 :                 rtx and_op0 = XEXP (test_op0, 0);
   23621           23 :                 if (GET_CODE (and_op0) == NOT)
   23622            0 :                   and_op0 = XEXP (and_op0, 0);
   23623           23 :                 *total += rtx_cost (and_op0, GET_MODE (and_op0),
   23624              :                                     AND, 0, speed)
   23625           23 :                           + rtx_cost (XEXP (test_op0, 1), GET_MODE (and_op0),
   23626              :                                       AND, 1, speed);
   23627              :              }
   23628              :             else
   23629        94236 :               *total = rtx_cost (test_op0, GET_MODE (test_op0),
   23630              :                                  UNSPEC, 0, speed);
   23631              :           }
   23632              :           return true;
   23633              : 
   23634        20388 :         case UNSPEC_BLENDV:
   23635        20388 :           *total = cost->sse_op;
   23636        20388 :           if (!REG_P (XVECEXP (x, 0, 0)))
   23637         8517 :             *total += rtx_cost (XVECEXP (x, 0, 0), mode, code, 0, speed);
   23638        20388 :           if (!REG_P (XVECEXP (x, 0, 1)))
   23639         9982 :             *total += rtx_cost (XVECEXP (x, 0, 1), mode, code, 1, speed);
   23640        20388 :           if (!REG_P (XVECEXP (x, 0, 2)))
   23641              :             {
   23642        12933 :               rtx cond = XVECEXP (x, 0, 2);
   23643        12933 :               if ((GET_CODE (cond) == LT || GET_CODE (cond) == GT)
   23644          773 :                   && CONST_VECTOR_P (XEXP (cond, 1)))
   23645              :                 {
   23646              :                   /* avx2_blendvpd256_gt and friends.  */
   23647          153 :                   if (!REG_P (XEXP (cond, 0)))
   23648           70 :                     *total += rtx_cost (XEXP (cond, 0), mode, code, 2, speed);
   23649              :                 }
   23650              :               else
   23651        12780 :                 *total += rtx_cost (cond, mode, code, 2, speed);
   23652              :             }
   23653              :           return true;
   23654              : 
   23655        57469 :         case UNSPEC_MOVMSK:
   23656        57469 :           *total = cost->sse_op;
   23657        57469 :           return true;
   23658              : 
   23659              :         default:
   23660              :           break;
   23661              :         }
   23662              :       return false;
   23663              : 
   23664      1824608 :     case VEC_CONCAT:
   23665              :       /* ??? Assume all of these vector manipulation patterns are
   23666              :          recognizable.  In which case they all pretty much have the
   23667              :          same cost.
   23668              :          ??? We should still recruse when computing cost.  */
   23669      1824608 :      *total = cost->sse_op;
   23670      1824608 :      return true;
   23671              : 
   23672      2495160 :     case VEC_SELECT:
   23673              :      /* Special case extracting lower part from the vector.
   23674              :         This by itself needs to code and most of SSE/AVX instructions have
   23675              :         packed and single forms where the single form may be represented
   23676              :         by such VEC_SELECT.
   23677              : 
   23678              :         Use cost 1 (despite the fact that functionally equivalent SUBREG has
   23679              :         cost 0).  Making VEC_SELECT completely free, for example instructs CSE
   23680              :         to forward propagate VEC_SELECT into
   23681              : 
   23682              :            (set (reg eax) (reg src))
   23683              : 
   23684              :         which then prevents fwprop and combining. See i.e.
   23685              :         gcc.target/i386/pr91103-1.c.
   23686              : 
   23687              :         ??? rtvec_series_p test should be, for valid patterns, equivalent to
   23688              :         vec_series_lowpart_p but is not, since the latter calls
   23689              :         can_cange_mode_class on ALL_REGS and this return false since x87 does
   23690              :         not support subregs at all.  */
   23691      2495160 :      if (rtvec_series_p (XVEC (XEXP (x, 1), 0), 0))
   23692       685173 :        *total = rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
   23693       685173 :                           outer_code, opno, speed) + 1;
   23694              :      else
   23695              :        /* ??? We should still recruse when computing cost.  */
   23696      1809987 :        *total = cost->sse_op;
   23697              :      return true;
   23698              : 
   23699      1287656 :     case VEC_DUPLICATE:
   23700      2575312 :       *total = rtx_cost (XEXP (x, 0),
   23701      1287656 :                          GET_MODE (XEXP (x, 0)),
   23702              :                          VEC_DUPLICATE, 0, speed);
   23703              :       /* It's broadcast instruction, not embedded broadcasting.  */
   23704      1287656 :       if (outer_code == SET)
   23705      1213172 :         *total += cost->sse_op;
   23706              : 
   23707              :      return true;
   23708              : 
   23709       935035 :     case VEC_MERGE:
   23710       935035 :       mask = XEXP (x, 2);
   23711              :       /* Scalar versions of SSE instructions may be represented as:
   23712              : 
   23713              :          (vec_merge (vec_duplicate (operation ....))
   23714              :                      (register or memory)
   23715              :                      (const_int 1))
   23716              : 
   23717              :          In this case vec_merge and vec_duplicate is for free.
   23718              :          Just recurse into operation and second operand.  */
   23719       935035 :       if (mask == const1_rtx
   23720       394512 :           && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)
   23721              :         {
   23722       254462 :           *total = rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   23723              :                              outer_code, opno, speed)
   23724       254462 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23725       254462 :           return true;
   23726              :         }
   23727              :       /* This is masked instruction, assume the same cost,
   23728              :          as nonmasked variant.  */
   23729       680573 :       else if (TARGET_AVX512F
   23730       680573 :                && (register_operand (mask, GET_MODE (mask))
   23731              :                    /* Redunduant clean up of high bits for kmask with VL=2/4
   23732              :                       .i.e (vec_merge op0, op1, (and op3 15)).  */
   23733       124633 :                    || (GET_CODE (mask) == AND
   23734          403 :                        && register_operand (XEXP (mask, 0), GET_MODE (mask))
   23735          403 :                        && CONST_INT_P (XEXP (mask, 1))
   23736          403 :                        && ((INTVAL (XEXP (mask, 1)) == 3
   23737          131 :                             && GET_MODE_NUNITS (mode) == 2)
   23738          272 :                            || (INTVAL (XEXP (mask, 1)) == 15
   23739          272 :                                && GET_MODE_NUNITS (mode) == 4)))))
   23740              :         {
   23741       378352 :           *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   23742       378352 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23743       378352 :           return true;
   23744              :         }
   23745              :       /* Combination of the two above:
   23746              : 
   23747              :          (vec_merge (vec_merge (vec_duplicate (operation ...))
   23748              :                        (register or memory)
   23749              :                        (reg:QI mask))
   23750              :                     (register or memory)
   23751              :                     (const_int 1))
   23752              : 
   23753              :          i.e. avx512fp16_vcvtss2sh_mask.  */
   23754       302221 :       else if (TARGET_AVX512F
   23755       124230 :                && mask == const1_rtx
   23756        46033 :                && GET_CODE (XEXP (x, 0)) == VEC_MERGE
   23757        27126 :                && GET_CODE (XEXP (XEXP (x, 0), 0)) == VEC_DUPLICATE
   23758       304483 :                && register_operand (XEXP (XEXP (x, 0), 2),
   23759         2262 :                                     GET_MODE (XEXP (XEXP (x, 0), 2))))
   23760              :         {
   23761         2250 :           *total = rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
   23762              :                              mode, outer_code, opno, speed)
   23763         2250 :                    + rtx_cost (XEXP (XEXP (x, 0), 1),
   23764              :                                mode, outer_code, opno, speed)
   23765         2250 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed);
   23766         2250 :           return true;
   23767              :         }
   23768              :       /* vcmp.  */
   23769       299971 :       else if (unspec_pcmp_p (mask)
   23770       299971 :                || (GET_CODE (mask) == NOT
   23771            0 :                    && unspec_pcmp_p (XEXP (mask, 0))))
   23772              :         {
   23773         1950 :           rtx uns = GET_CODE (mask) == NOT ? XEXP (mask, 0) : mask;
   23774         1950 :           rtx unsop0 = XVECEXP (uns, 0, 0);
   23775              :           /* Make (subreg:V4SI (not:V16QI (reg:V16QI ..)) 0)
   23776              :              cost the same as register.
   23777              :              This is used by avx_cmp<mode>3_ltint_not.  */
   23778         1950 :           if (SUBREG_P (unsop0))
   23779          417 :             unsop0 = XEXP (unsop0, 0);
   23780         1950 :           if (GET_CODE (unsop0) == NOT)
   23781           18 :             unsop0 = XEXP (unsop0, 0);
   23782         1950 :           *total = rtx_cost (XEXP (x, 0), mode, outer_code, opno, speed)
   23783         1950 :                    + rtx_cost (XEXP (x, 1), mode, outer_code, opno, speed)
   23784         1950 :                    + rtx_cost (unsop0, mode, UNSPEC, opno, speed)
   23785         1950 :                    + rtx_cost (XVECEXP (uns, 0, 1), mode, UNSPEC, opno, speed)
   23786         1950 :                    + cost->sse_op;
   23787         1950 :           return true;
   23788              :         }
   23789              :       else
   23790       298021 :         *total = cost->sse_op;
   23791       298021 :       return false;
   23792              : 
   23793    110391589 :     case MEM:
   23794              :       /* CONST_VECTOR_DUPLICATE_P in constant_pool is just broadcast.
   23795              :          or variants in ix86_vector_duplicate_simode_const.  */
   23796              : 
   23797    110391589 :       if (GET_MODE_SIZE (mode) >= 16
   23798     17715761 :           && VECTOR_MODE_P (mode)
   23799     11568076 :           && SYMBOL_REF_P (XEXP (x, 0))
   23800      2324656 :           && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))
   23801    112486597 :           && ix86_broadcast_from_constant (mode, x))
   23802              :         {
   23803       535723 :           *total = COSTS_N_INSNS (2) + speed;
   23804       535723 :           return true;
   23805              :         }
   23806              : 
   23807              :       /* An insn that accesses memory is slightly more expensive
   23808              :          than one that does not.  */
   23809    109855866 :       if (speed)
   23810              :         {
   23811     98344098 :           *total += 1;
   23812     98344098 :           rtx addr = XEXP (x, 0);
   23813              :           /* For MEM, rtx_cost iterates each subrtx, and adds up the costs,
   23814              :              so for MEM (reg) and MEM (reg + 4), the former costs 5,
   23815              :              the latter costs 9, it is not accurate for x86. Ideally
   23816              :              address_cost should be used, but it reduce cost too much.
   23817              :              So current solution is make constant disp as cheap as possible.  */
   23818     98344098 :           if (GET_CODE (addr) == PLUS
   23819     79725246 :               && x86_64_immediate_operand (XEXP (addr, 1), Pmode)
   23820              :               /* Only handle (reg + disp) since other forms of addr are mostly LEA,
   23821              :                  there's no additional cost for the plus of disp.  */
   23822    172622703 :               && register_operand (XEXP (addr, 0), Pmode))
   23823              :             {
   23824     58412274 :               *total += 1;
   23825     71214481 :               *total += rtx_cost (XEXP (addr, 0), Pmode, PLUS, 0, speed);
   23826     58412274 :               return true;
   23827              :             }
   23828              :         }
   23829              : 
   23830              :       return false;
   23831              : 
   23832        46558 :     case ZERO_EXTRACT:
   23833        46558 :       if (XEXP (x, 1) == const1_rtx
   23834        11440 :           && GET_CODE (XEXP (x, 2)) == ZERO_EXTEND
   23835            0 :           && GET_MODE (XEXP (x, 2)) == SImode
   23836            0 :           && GET_MODE (XEXP (XEXP (x, 2), 0)) == QImode)
   23837              :         {
   23838              :           /* Ignore cost of zero extension and masking of last argument.  */
   23839            0 :           *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23840            0 :           *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23841            0 :           *total += rtx_cost (XEXP (XEXP (x, 2), 0), mode, code, 2, speed);
   23842            0 :           return true;
   23843              :         }
   23844              :       return false;
   23845              : 
   23846     30328786 :     case IF_THEN_ELSE:
   23847     30328786 :       if (TARGET_XOP
   23848        25149 :           && VECTOR_MODE_P (mode)
   23849     30334177 :           && (GET_MODE_SIZE (mode) == 16 || GET_MODE_SIZE (mode) == 32))
   23850              :         {
   23851              :           /* vpcmov.  */
   23852         4823 :           *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (6);
   23853         4823 :           if (!REG_P (XEXP (x, 0)))
   23854         4663 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23855         4823 :           if (!REG_P (XEXP (x, 1)))
   23856         4630 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23857         4823 :           if (!REG_P (XEXP (x, 2)))
   23858         4632 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   23859              :           return true;
   23860              :         }
   23861            0 :       else if (TARGET_CMOVE
   23862     30323963 :                && SCALAR_INT_MODE_P (mode)
   23863     33130813 :                && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
   23864              :         {
   23865              :           /* cmov.  */
   23866      2577564 :           *total = COSTS_N_INSNS (1);
   23867      2577564 :           if (!COMPARISON_P (XEXP (x, 0)) && !REG_P (XEXP (x, 0)))
   23868            0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23869      2577564 :           if (!REG_P (XEXP (x, 1)))
   23870       145681 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23871      2577564 :           if (!REG_P (XEXP (x, 2)))
   23872       747040 :             *total += rtx_cost (XEXP (x, 2), mode, code, 2, speed);
   23873              :           return true;
   23874              :         }
   23875              :       return false;
   23876              : 
   23877     18677954 :     case EQ:
   23878     18677954 :     case GT:
   23879     18677954 :     case GTU:
   23880     18677954 :     case LT:
   23881     18677954 :     case LTU:
   23882     18677954 :       if (TARGET_SSE2
   23883     18674754 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23884     19053858 :           && GET_MODE_SIZE (mode) >= 8)
   23885              :         {
   23886              :           /* vpcmpeq */
   23887       368200 :           *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
   23888       368200 :           if (!REG_P (XEXP (x, 0)))
   23889        71340 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23890       368200 :           if (!REG_P (XEXP (x, 1)))
   23891       139713 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23892              :           return true;
   23893              :         }
   23894     18309754 :       if (TARGET_XOP
   23895        12236 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23896     18309862 :           && GET_MODE_SIZE (mode) <= 16)
   23897              :         {
   23898              :           /* vpcomeq */
   23899          108 :           *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (6);
   23900          108 :           if (!REG_P (XEXP (x, 0)))
   23901            0 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23902          108 :           if (!REG_P (XEXP (x, 1)))
   23903            0 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23904              :           return true;
   23905              :         }
   23906              :       return false;
   23907              : 
   23908     16621386 :     case NE:
   23909     16621386 :     case GE:
   23910     16621386 :     case GEU:
   23911     16621386 :       if (TARGET_XOP
   23912        21827 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23913     16628053 :           && GET_MODE_SIZE (mode) <= 16)
   23914              :         {
   23915              :           /* vpcomneq */
   23916         6667 :           *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (6);
   23917         6667 :           if (!REG_P (XEXP (x, 0)))
   23918         1405 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23919         6667 :           if (!REG_P (XEXP (x, 1)))
   23920         5683 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23921              :           return true;
   23922              :         }
   23923     16614719 :       if (TARGET_SSE2
   23924     16612567 :           && GET_MODE_CLASS (mode) == MODE_VECTOR_INT
   23925     16618027 :           && GET_MODE_SIZE (mode) >= 8)
   23926              :         {
   23927         3343 :           if (TARGET_AVX512F && GET_MODE_SIZE (mode) >= 16)
   23928              :             /* vpcmpeq + vpternlog */
   23929           51 :             *total = speed ? COSTS_N_INSNS (2) : COSTS_N_BYTES (11);
   23930              :           else
   23931              :             /* vpcmpeq + pxor + vpcmpeq */
   23932         3394 :             *total = speed ? COSTS_N_INSNS (3) : COSTS_N_BYTES (12);
   23933         3284 :           if (!REG_P (XEXP (x, 0)))
   23934          342 :             *total += rtx_cost (XEXP (x, 0), mode, code, 0, speed);
   23935         3284 :           if (!REG_P (XEXP (x, 1)))
   23936           45 :             *total += rtx_cost (XEXP (x, 1), mode, code, 1, speed);
   23937              :           return true;
   23938              :         }
   23939              :       return false;
   23940              : 
   23941              :     default:
   23942              :       return false;
   23943              :     }
   23944              : }
   23945              : 
   23946              : #if TARGET_MACHO
   23947              : 
   23948              : static int current_machopic_label_num;
   23949              : 
   23950              : /* Given a symbol name and its associated stub, write out the
   23951              :    definition of the stub.  */
   23952              : 
   23953              : void
   23954              : machopic_output_stub (FILE *file, const char *symb, const char *stub)
   23955              : {
   23956              :   unsigned int length;
   23957              :   char *binder_name, *symbol_name, lazy_ptr_name[32];
   23958              :   int label = ++current_machopic_label_num;
   23959              : 
   23960              :   /* For 64-bit we shouldn't get here.  */
   23961              :   gcc_assert (!TARGET_64BIT);
   23962              : 
   23963              :   /* Lose our funky encoding stuff so it doesn't contaminate the stub.  */
   23964              :   symb = targetm.strip_name_encoding (symb);
   23965              : 
   23966              :   length = strlen (stub);
   23967              :   binder_name = XALLOCAVEC (char, length + 32);
   23968              :   GEN_BINDER_NAME_FOR_STUB (binder_name, stub, length);
   23969              : 
   23970              :   length = strlen (symb);
   23971              :   symbol_name = XALLOCAVEC (char, length + 32);
   23972              :   GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
   23973              : 
   23974              :   sprintf (lazy_ptr_name, "L%d$lz", label);
   23975              : 
   23976              :   if (MACHOPIC_ATT_STUB)
   23977              :     switch_to_section (darwin_sections[machopic_picsymbol_stub3_section]);
   23978              :   else if (MACHOPIC_PURE)
   23979              :     switch_to_section (darwin_sections[machopic_picsymbol_stub2_section]);
   23980              :   else
   23981              :     switch_to_section (darwin_sections[machopic_symbol_stub_section]);
   23982              : 
   23983              :   fprintf (file, "%s:\n", stub);
   23984              :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   23985              : 
   23986              :   if (MACHOPIC_ATT_STUB)
   23987              :     {
   23988              :       fprintf (file, "\thlt ; hlt ; hlt ; hlt ; hlt\n");
   23989              :     }
   23990              :   else if (MACHOPIC_PURE)
   23991              :     {
   23992              :       /* PIC stub.  */
   23993              :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   23994              :       rtx tmp = gen_rtx_REG (SImode, 2 /* ECX */);
   23995              :       output_set_got (tmp, NULL_RTX);   /* "CALL ___<cpu>.get_pc_thunk.cx".  */
   23996              :       fprintf (file, "LPC$%d:\tmovl\t%s-LPC$%d(%%ecx),%%ecx\n",
   23997              :                label, lazy_ptr_name, label);
   23998              :       fprintf (file, "\tjmp\t*%%ecx\n");
   23999              :     }
   24000              :   else
   24001              :     fprintf (file, "\tjmp\t*%s\n", lazy_ptr_name);
   24002              : 
   24003              :   /* The AT&T-style ("self-modifying") stub is not lazily bound, thus
   24004              :      it needs no stub-binding-helper.  */
   24005              :   if (MACHOPIC_ATT_STUB)
   24006              :     return;
   24007              : 
   24008              :   fprintf (file, "%s:\n", binder_name);
   24009              : 
   24010              :   if (MACHOPIC_PURE)
   24011              :     {
   24012              :       fprintf (file, "\tlea\t%s-%s(%%ecx),%%ecx\n", lazy_ptr_name, binder_name);
   24013              :       fprintf (file, "\tpushl\t%%ecx\n");
   24014              :     }
   24015              :   else
   24016              :     fprintf (file, "\tpushl\t$%s\n", lazy_ptr_name);
   24017              : 
   24018              :   fputs ("\tjmp\tdyld_stub_binding_helper\n", file);
   24019              : 
   24020              :   /* N.B. Keep the correspondence of these
   24021              :      'symbol_ptr/symbol_ptr2/symbol_ptr3' sections consistent with the
   24022              :      old-pic/new-pic/non-pic stubs; altering this will break
   24023              :      compatibility with existing dylibs.  */
   24024              :   if (MACHOPIC_PURE)
   24025              :     {
   24026              :       /* 25-byte PIC stub using "CALL get_pc_thunk".  */
   24027              :       switch_to_section (darwin_sections[machopic_lazy_symbol_ptr2_section]);
   24028              :     }
   24029              :   else
   24030              :     /* 16-byte -mdynamic-no-pic stub.  */
   24031              :     switch_to_section(darwin_sections[machopic_lazy_symbol_ptr3_section]);
   24032              : 
   24033              :   fprintf (file, "%s:\n", lazy_ptr_name);
   24034              :   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
   24035              :   fprintf (file, ASM_LONG "%s\n", binder_name);
   24036              : }
   24037              : #endif /* TARGET_MACHO */
   24038              : 
   24039              : /* Order the registers for register allocator.  */
   24040              : 
   24041              : void
   24042       221098 : x86_order_regs_for_local_alloc (void)
   24043              : {
   24044       221098 :    int pos = 0;
   24045       221098 :    int i;
   24046              : 
   24047              :    /* First allocate the local general purpose registers.  */
   24048     21004310 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   24049     20783212 :      if (GENERAL_REGNO_P (i) && default_function_abi.clobbers_full_reg_p (i))
   24050      5538692 :        reg_alloc_order [pos++] = i;
   24051              : 
   24052              :    /* Global general purpose registers.  */
   24053     21004310 :    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   24054     20783212 :      if (GENERAL_REGNO_P (i) && !default_function_abi.clobbers_full_reg_p (i))
   24055      1536444 :        reg_alloc_order [pos++] = i;
   24056              : 
   24057              :    /* x87 registers come first in case we are doing FP math
   24058              :       using them.  */
   24059       221098 :    if (!TARGET_SSE_MATH)
   24060        56385 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   24061        50120 :        reg_alloc_order [pos++] = i;
   24062              : 
   24063              :    /* SSE registers.  */
   24064      1989882 :    for (i = FIRST_SSE_REG; i <= LAST_SSE_REG; i++)
   24065      1768784 :      reg_alloc_order [pos++] = i;
   24066      1989882 :    for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
   24067      1768784 :      reg_alloc_order [pos++] = i;
   24068              : 
   24069              :    /* Extended REX SSE registers.  */
   24070      3758666 :    for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
   24071      3537568 :      reg_alloc_order [pos++] = i;
   24072              : 
   24073              :    /* Mask register.  */
   24074      1989882 :    for (i = FIRST_MASK_REG; i <= LAST_MASK_REG; i++)
   24075      1768784 :      reg_alloc_order [pos++] = i;
   24076              : 
   24077              :    /* x87 registers.  */
   24078       221098 :    if (TARGET_SSE_MATH)
   24079      1933497 :      for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
   24080      1718664 :        reg_alloc_order [pos++] = i;
   24081              : 
   24082      1989882 :    for (i = FIRST_MMX_REG; i <= LAST_MMX_REG; i++)
   24083      1768784 :      reg_alloc_order [pos++] = i;
   24084              : 
   24085              :    /* Initialize the rest of array as we do not allocate some registers
   24086              :       at all.  */
   24087      1547686 :    while (pos < FIRST_PSEUDO_REGISTER)
   24088      1326588 :      reg_alloc_order [pos++] = 0;
   24089       221098 : }
   24090              : 
   24091              : static bool
   24092    258497266 : ix86_ms_bitfield_layout_p (const_tree record_type)
   24093              : {
   24094    258497266 :   return ((TARGET_MS_BITFIELD_LAYOUT
   24095          215 :            && !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
   24096    258497266 :           || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type)));
   24097              : }
   24098              : 
   24099              : /* Returns an expression indicating where the this parameter is
   24100              :    located on entry to the FUNCTION.  */
   24101              : 
   24102              : static rtx
   24103         1896 : x86_this_parameter (tree function)
   24104              : {
   24105         1896 :   tree type = TREE_TYPE (function);
   24106         1896 :   bool aggr = aggregate_value_p (TREE_TYPE (type), type) != 0;
   24107         1896 :   int nregs;
   24108              : 
   24109         1896 :   if (TARGET_64BIT)
   24110              :     {
   24111         1894 :       const int *parm_regs;
   24112              : 
   24113         1894 :       if (lookup_attribute ("preserve_none", TYPE_ATTRIBUTES (type)))
   24114              :         parm_regs = x86_64_preserve_none_int_parameter_registers;
   24115         1894 :       else if (ix86_function_type_abi (type) == MS_ABI)
   24116              :         parm_regs = x86_64_ms_abi_int_parameter_registers;
   24117              :       else
   24118         1894 :         parm_regs = x86_64_int_parameter_registers;
   24119         1894 :       return gen_rtx_REG (Pmode, parm_regs[aggr]);
   24120              :     }
   24121              : 
   24122            2 :   nregs = ix86_function_regparm (type, function);
   24123              : 
   24124            2 :   if (nregs > 0 && !stdarg_p (type))
   24125              :     {
   24126            0 :       int regno;
   24127            0 :       unsigned int ccvt = ix86_get_callcvt (type);
   24128              : 
   24129            0 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   24130            0 :         regno = aggr ? DX_REG : CX_REG;
   24131            0 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   24132              :         {
   24133            0 :           regno = CX_REG;
   24134            0 :           if (aggr)
   24135            0 :             return gen_rtx_MEM (SImode,
   24136            0 :                                 plus_constant (Pmode, stack_pointer_rtx, 4));
   24137              :         }
   24138              :       else
   24139              :         {
   24140            0 :           regno = AX_REG;
   24141            0 :           if (aggr)
   24142              :             {
   24143            0 :               regno = DX_REG;
   24144            0 :               if (nregs == 1)
   24145            0 :                 return gen_rtx_MEM (SImode,
   24146            0 :                                     plus_constant (Pmode,
   24147              :                                                    stack_pointer_rtx, 4));
   24148              :             }
   24149              :         }
   24150            0 :       return gen_rtx_REG (SImode, regno);
   24151              :     }
   24152              : 
   24153            4 :   return gen_rtx_MEM (SImode, plus_constant (Pmode, stack_pointer_rtx,
   24154            4 :                                              aggr ? 8 : 4));
   24155              : }
   24156              : 
   24157              : /* Determine whether x86_output_mi_thunk can succeed.  */
   24158              : 
   24159              : static bool
   24160         5186 : x86_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
   24161              :                          const_tree function)
   24162              : {
   24163              :   /* 64-bit can handle anything.  */
   24164         5186 :   if (TARGET_64BIT)
   24165              :     return true;
   24166              : 
   24167              :   /* For 32-bit, everything's fine if we have one free register.  */
   24168           76 :   if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
   24169              :     return true;
   24170              : 
   24171              :   /* Need a free register for vcall_offset.  */
   24172            0 :   if (vcall_offset)
   24173              :     return false;
   24174              : 
   24175              :   /* Need a free register for GOT references.  */
   24176            0 :   if (flag_pic && !targetm.binds_local_p (function))
   24177              :     return false;
   24178              : 
   24179              :   /* Otherwise ok.  */
   24180              :   return true;
   24181              : }
   24182              : 
   24183              : /* Output the assembler code for a thunk function.  THUNK_DECL is the
   24184              :    declaration for the thunk function itself, FUNCTION is the decl for
   24185              :    the target function.  DELTA is an immediate constant offset to be
   24186              :    added to THIS.  If VCALL_OFFSET is nonzero, the word at
   24187              :    *(*this + vcall_offset) should be added to THIS.  */
   24188              : 
   24189              : static void
   24190         1896 : x86_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
   24191              :                      HOST_WIDE_INT vcall_offset, tree function)
   24192              : {
   24193         1896 :   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   24194         1896 :   rtx this_param = x86_this_parameter (function);
   24195         1896 :   rtx this_reg, tmp, fnaddr;
   24196         1896 :   unsigned int tmp_regno;
   24197         1896 :   rtx_insn *insn;
   24198         1896 :   int saved_flag_force_indirect_call = flag_force_indirect_call;
   24199              : 
   24200         1896 :   if (TARGET_64BIT)
   24201              :     tmp_regno = R10_REG;
   24202              :   else
   24203              :     {
   24204            2 :       unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (function));
   24205            2 :       if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
   24206              :         tmp_regno = AX_REG;
   24207            2 :       else if ((ccvt & IX86_CALLCVT_THISCALL) != 0)
   24208              :         tmp_regno = DX_REG;
   24209              :       else
   24210            2 :         tmp_regno = CX_REG;
   24211              : 
   24212            2 :       if (flag_pic)
   24213            2 :   flag_force_indirect_call = 0;
   24214              :     }
   24215              : 
   24216         1896 :   emit_note (NOTE_INSN_PROLOGUE_END);
   24217              : 
   24218              :   /* CET is enabled, insert EB instruction.  */
   24219         1896 :   if ((flag_cf_protection & CF_BRANCH))
   24220           20 :     emit_insn (gen_nop_endbr ());
   24221              : 
   24222              :   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
   24223              :      pull it in now and let DELTA benefit.  */
   24224         1896 :   if (REG_P (this_param))
   24225              :     this_reg = this_param;
   24226            2 :   else if (vcall_offset)
   24227              :     {
   24228              :       /* Put the this parameter into %eax.  */
   24229            2 :       this_reg = gen_rtx_REG (Pmode, AX_REG);
   24230            1 :       emit_move_insn (this_reg, this_param);
   24231              :     }
   24232              :   else
   24233              :     this_reg = NULL_RTX;
   24234              : 
   24235              :   /* Adjust the this parameter by a fixed constant.  */
   24236         1896 :   if (delta)
   24237              :     {
   24238          921 :       rtx delta_rtx = GEN_INT (delta);
   24239          921 :       rtx delta_dst = this_reg ? this_reg : this_param;
   24240              : 
   24241          921 :       if (TARGET_64BIT)
   24242              :         {
   24243          920 :           if (!x86_64_general_operand (delta_rtx, Pmode))
   24244              :             {
   24245            0 :               tmp = gen_rtx_REG (Pmode, tmp_regno);
   24246            0 :               emit_move_insn (tmp, delta_rtx);
   24247            0 :               delta_rtx = tmp;
   24248              :             }
   24249              :         }
   24250              : 
   24251          922 :       ix86_emit_binop (PLUS, Pmode, delta_dst, delta_rtx);
   24252              :     }
   24253              : 
   24254              :   /* Adjust the this parameter by a value stored in the vtable.  */
   24255         1896 :   if (vcall_offset)
   24256              :     {
   24257         1026 :       rtx vcall_addr, vcall_mem, this_mem;
   24258              : 
   24259         1027 :       tmp = gen_rtx_REG (Pmode, tmp_regno);
   24260              : 
   24261         1026 :       this_mem = gen_rtx_MEM (ptr_mode, this_reg);
   24262         1027 :       if (Pmode != ptr_mode)
   24263            0 :         this_mem = gen_rtx_ZERO_EXTEND (Pmode, this_mem);
   24264         1026 :       emit_move_insn (tmp, this_mem);
   24265              : 
   24266              :       /* Adjust the this parameter.  */
   24267         1027 :       vcall_addr = plus_constant (Pmode, tmp, vcall_offset);
   24268         1026 :       if (TARGET_64BIT
   24269         1026 :           && !ix86_legitimate_address_p (ptr_mode, vcall_addr, true))
   24270              :         {
   24271            0 :           rtx tmp2 = gen_rtx_REG (Pmode, R11_REG);
   24272            0 :           emit_move_insn (tmp2, GEN_INT (vcall_offset));
   24273            0 :           vcall_addr = gen_rtx_PLUS (Pmode, tmp, tmp2);
   24274              :         }
   24275              : 
   24276         1026 :       vcall_mem = gen_rtx_MEM (ptr_mode, vcall_addr);
   24277         1027 :       if (Pmode != ptr_mode)
   24278            0 :         emit_insn (gen_addsi_1_zext (this_reg,
   24279              :                                      gen_rtx_REG (ptr_mode,
   24280              :                                                   REGNO (this_reg)),
   24281              :                                      vcall_mem));
   24282              :       else
   24283         1026 :         ix86_emit_binop (PLUS, Pmode, this_reg, vcall_mem);
   24284              :     }
   24285              : 
   24286              :   /* If necessary, drop THIS back to its stack slot.  */
   24287         1896 :   if (this_reg && this_reg != this_param)
   24288            1 :     emit_move_insn (this_param, this_reg);
   24289              : 
   24290         1896 :   fnaddr = XEXP (DECL_RTL (function), 0);
   24291         1896 :   if (TARGET_64BIT)
   24292              :     {
   24293           25 :       if (!flag_pic || targetm.binds_local_p (function)
   24294         1919 :           || TARGET_PECOFF)
   24295              :         ;
   24296              :       else
   24297              :         {
   24298            0 :           tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOTPCREL);
   24299            0 :           tmp = gen_rtx_CONST (Pmode, tmp);
   24300            0 :           fnaddr = gen_const_mem (Pmode, tmp);
   24301              :         }
   24302              :     }
   24303              :   else
   24304              :     {
   24305            2 :       if (!flag_pic || targetm.binds_local_p (function))
   24306              :         ;
   24307              : #if TARGET_MACHO
   24308              :       else if (TARGET_MACHO)
   24309              :         {
   24310              :           fnaddr = machopic_indirect_call_target (DECL_RTL (function));
   24311              :           fnaddr = XEXP (fnaddr, 0);
   24312              :         }
   24313              : #endif /* TARGET_MACHO */
   24314              :       else
   24315              :         {
   24316            0 :           tmp = gen_rtx_REG (Pmode, CX_REG);
   24317            0 :           output_set_got (tmp, NULL_RTX);
   24318              : 
   24319            0 :           fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, fnaddr), UNSPEC_GOT);
   24320            0 :           fnaddr = gen_rtx_CONST (Pmode, fnaddr);
   24321            0 :           fnaddr = gen_rtx_PLUS (Pmode, tmp, fnaddr);
   24322            0 :           fnaddr = gen_const_mem (Pmode, fnaddr);
   24323              :         }
   24324              :     }
   24325              : 
   24326              :   /* Our sibling call patterns do not allow memories, because we have no
   24327              :      predicate that can distinguish between frame and non-frame memory.
   24328              :      For our purposes here, we can get away with (ab)using a jump pattern,
   24329              :      because we're going to do no optimization.  */
   24330         1896 :   if (MEM_P (fnaddr))
   24331              :     {
   24332            0 :       if (sibcall_insn_operand (fnaddr, word_mode))
   24333              :         {
   24334            0 :           fnaddr = XEXP (DECL_RTL (function), 0);
   24335            0 :           tmp = gen_rtx_MEM (QImode, fnaddr);
   24336            0 :           tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   24337            0 :           tmp = emit_call_insn (tmp);
   24338            0 :           SIBLING_CALL_P (tmp) = 1;
   24339              :         }
   24340              :       else
   24341            0 :         emit_jump_insn (gen_indirect_jump (fnaddr));
   24342              :     }
   24343              :   else
   24344              :     {
   24345         1896 :       if (ix86_cmodel == CM_LARGE_PIC && SYMBOLIC_CONST (fnaddr))
   24346              :         {
   24347              :           // CM_LARGE_PIC always uses pseudo PIC register which is
   24348              :           // uninitialized.  Since FUNCTION is local and calling it
   24349              :           // doesn't go through PLT, we use scratch register %r11 as
   24350              :           // PIC register and initialize it here.
   24351            3 :           pic_offset_table_rtx = gen_rtx_REG (Pmode, R11_REG);
   24352            3 :           ix86_init_large_pic_reg (tmp_regno);
   24353            3 :           fnaddr = legitimize_pic_address (fnaddr,
   24354            3 :                                            gen_rtx_REG (Pmode, tmp_regno));
   24355              :         }
   24356              : 
   24357         1896 :       if (!sibcall_insn_operand (fnaddr, word_mode))
   24358              :         {
   24359            9 :           tmp = gen_rtx_REG (word_mode, tmp_regno);
   24360            9 :           if (GET_MODE (fnaddr) != word_mode)
   24361            0 :             fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr);
   24362            9 :           emit_move_insn (tmp, fnaddr);
   24363            9 :           fnaddr = tmp;
   24364              :         }
   24365              : 
   24366         1896 :       tmp = gen_rtx_MEM (QImode, fnaddr);
   24367         1896 :       tmp = gen_rtx_CALL (VOIDmode, tmp, const0_rtx);
   24368         1896 :       tmp = emit_call_insn (tmp);
   24369         1896 :       SIBLING_CALL_P (tmp) = 1;
   24370              :     }
   24371         1896 :   emit_barrier ();
   24372              : 
   24373              :   /* Emit just enough of rest_of_compilation to get the insns emitted.  */
   24374         1896 :   insn = get_insns ();
   24375         1896 :   shorten_branches (insn);
   24376         1896 :   assemble_start_function (thunk_fndecl, fnname);
   24377         1896 :   final_start_function (insn, file, 1);
   24378         1896 :   final (insn, file, 1);
   24379         1896 :   final_end_function ();
   24380         1896 :   assemble_end_function (thunk_fndecl, fnname);
   24381              : 
   24382         1896 :   flag_force_indirect_call = saved_flag_force_indirect_call;
   24383         1896 : }
   24384              : 
   24385              : static void
   24386       279576 : x86_file_start (void)
   24387              : {
   24388       279576 :   default_file_start ();
   24389       279576 :   if (TARGET_16BIT)
   24390            6 :     fputs ("\t.code16gcc\n", asm_out_file);
   24391              : #if TARGET_MACHO
   24392              :   darwin_file_start ();
   24393              : #endif
   24394       279576 :   if (X86_FILE_START_VERSION_DIRECTIVE)
   24395              :     fputs ("\t.version\t\"01.01\"\n", asm_out_file);
   24396       279576 :   if (X86_FILE_START_FLTUSED)
   24397              :     fputs ("\t.global\t__fltused\n", asm_out_file);
   24398       279576 :   if (ix86_asm_dialect == ASM_INTEL)
   24399           65 :     fputs ("\t.intel_syntax noprefix\n", asm_out_file);
   24400       279576 : }
   24401              : 
   24402              : int
   24403    107874814 : x86_field_alignment (tree type, int computed)
   24404              : {
   24405    107874814 :   machine_mode mode;
   24406              : 
   24407    107874814 :   if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
   24408              :     return computed;
   24409      9135488 :   if (TARGET_IAMCU)
   24410            0 :     return iamcu_alignment (type, computed);
   24411      9135488 :   type = strip_array_types (type);
   24412      9135488 :   mode = TYPE_MODE (type);
   24413      9135488 :   if (mode == DFmode || mode == DCmode
   24414      9029707 :       || GET_MODE_CLASS (mode) == MODE_INT
   24415      3024154 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
   24416              :     {
   24417      6111334 :       if (TYPE_ATOMIC (type) && computed > 32)
   24418              :         {
   24419            0 :           static bool warned;
   24420              : 
   24421            0 :           if (!warned && warn_psabi)
   24422              :             {
   24423            0 :               const char *url
   24424              :                 = CHANGES_ROOT_URL "gcc-11/changes.html#ia32_atomic";
   24425              : 
   24426            0 :               warned = true;
   24427            0 :               inform (input_location, "the alignment of %<_Atomic %T%> "
   24428              :                                       "fields changed in %{GCC 11.1%}",
   24429            0 :                       TYPE_MAIN_VARIANT (type), url);
   24430              :             }
   24431              :         }
   24432              :       else
   24433      6111334 :       return MIN (32, computed);
   24434              :     }
   24435              :   return computed;
   24436              : }
   24437              : 
   24438              : /* Print call to TARGET to FILE.  */
   24439              : 
   24440              : static void
   24441          293 : x86_print_call_or_nop (FILE *file, const char *target,
   24442              :                        const char *label)
   24443              : {
   24444          293 :   if (flag_nop_mcount || !strcmp (target, "nop"))
   24445              :     {
   24446            9 :       if (TARGET_16BIT)
   24447              :         /* 3 byte no-op: lea 0(%si), %si */
   24448            1 :         fprintf (file, "%s" ASM_BYTE "0x8d, 0x74, 0x00\n", label);
   24449              :       else
   24450              :         /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
   24451            8 :         fprintf (file, "%s" ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n",
   24452              :                  label);
   24453              :     }
   24454          284 :   else if (!TARGET_PECOFF && flag_pic)
   24455              :     {
   24456            8 :       gcc_assert (flag_plt);
   24457              : 
   24458            8 :       fprintf (file, "%s\tcall\t%s@PLT\n", label, target);
   24459              :     }
   24460              :   else
   24461          276 :     fprintf (file, "%s\tcall\t%s\n", label, target);
   24462          293 : }
   24463              : 
   24464              : static bool
   24465          313 : current_fentry_name (const char **name)
   24466              : {
   24467          313 :   tree attr = lookup_attribute ("fentry_name",
   24468          313 :                                 DECL_ATTRIBUTES (current_function_decl));
   24469          313 :   if (!attr)
   24470              :     return false;
   24471            2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   24472            2 :   return true;
   24473              : }
   24474              : 
   24475              : static bool
   24476           16 : current_fentry_section (const char **name)
   24477              : {
   24478           16 :   tree attr = lookup_attribute ("fentry_section",
   24479           16 :                                 DECL_ATTRIBUTES (current_function_decl));
   24480           16 :   if (!attr)
   24481              :     return false;
   24482            2 :   *name = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
   24483            2 :   return true;
   24484              : }
   24485              : 
   24486              : /* Return a caller-saved register which isn't live or a callee-saved
   24487              :    register which has been saved on stack in the prologue at entry for
   24488              :    profile.  */
   24489              : 
   24490              : static int
   24491           17 : x86_64_select_profile_regnum (bool r11_ok ATTRIBUTE_UNUSED)
   24492              : {
   24493              :   /* Use %r10 if the profiler is emitted before the prologue or it isn't
   24494              :      used by DRAP.  */
   24495           17 :   if (ix86_profile_before_prologue ()
   24496            4 :       || !crtl->drap_reg
   24497           17 :       || REGNO (crtl->drap_reg) != R10_REG)
   24498              :     return R10_REG;
   24499              : 
   24500              :   /* The profiler is emitted after the prologue.  If there is a
   24501              :      caller-saved register which isn't live or a callee-saved
   24502              :      register saved on stack in the prologue, use it.  */
   24503              : 
   24504            0 :   bitmap reg_live = df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun));
   24505              : 
   24506            0 :   int i;
   24507            0 :   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   24508            0 :     if (GENERAL_REGNO_P (i)
   24509            0 :         && i != R10_REG
   24510              : #ifdef NO_PROFILE_COUNTERS
   24511            0 :         && (r11_ok || i != R11_REG)
   24512              : #else
   24513              :         && i != R11_REG
   24514              : #endif
   24515            0 :         && TEST_HARD_REG_BIT (accessible_reg_set, i)
   24516            0 :         && (ix86_save_reg (i, true, true)
   24517            0 :             || (crtl->abi->clobbers_full_reg_p (i)
   24518            0 :                 && !fixed_regs[i]
   24519            0 :                 && !REGNO_REG_SET_P (reg_live, i))))
   24520              :       return i;
   24521              : 
   24522            0 :   sorry ("no register available for profiling %<-mcmodel=large%s%>",
   24523            0 :          ix86_cmodel == CM_LARGE_PIC ? " -fPIC" : "");
   24524              : 
   24525            0 :   return R10_REG;
   24526              : }
   24527              : 
   24528              : /* Output assembler code to FILE to increment profiler label # LABELNO
   24529              :    for profiling a function entry.  */
   24530              : void
   24531          313 : x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
   24532              : {
   24533          313 :   if (cfun->machine->insn_queued_at_entrance)
   24534              :     {
   24535            7 :       if (cfun->machine->insn_queued_at_entrance == TYPE_ENDBR)
   24536            6 :         fprintf (file, "\t%s\n", TARGET_64BIT ? "endbr64" : "endbr32");
   24537            7 :       unsigned int patch_area_size
   24538            7 :         = crtl->patch_area_size - crtl->patch_area_entry;
   24539            7 :       if (patch_area_size)
   24540            2 :         ix86_output_patchable_area (patch_area_size,
   24541              :                                     crtl->patch_area_entry == 0);
   24542              :     }
   24543              : 
   24544          313 :   const char *mcount_name = MCOUNT_NAME;
   24545              : 
   24546          313 :   bool fentry_section_p
   24547          313 :     = (flag_record_mcount
   24548          611 :        || lookup_attribute ("fentry_section",
   24549          298 :                             DECL_ATTRIBUTES (current_function_decl)));
   24550              : 
   24551              :   const char *label = fentry_section_p ? "1:" : "";
   24552              : 
   24553          313 :   if (current_fentry_name (&mcount_name))
   24554              :     ;
   24555          311 :   else if (fentry_name)
   24556            1 :     mcount_name = fentry_name;
   24557          310 :   else if (flag_fentry)
   24558          298 :     mcount_name = MCOUNT_NAME_BEFORE_PROLOGUE;
   24559              : 
   24560          313 :   if (TARGET_64BIT)
   24561              :     {
   24562              : #ifndef NO_PROFILE_COUNTERS
   24563              :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   24564              :         fprintf (file, "\tlea\tr11, %sP%d[rip]\n", LPREFIX, labelno);
   24565              :       else
   24566              :         fprintf (file, "\tleaq\t%sP%d(%%rip), %%r11\n", LPREFIX, labelno);
   24567              : #endif
   24568              : 
   24569          312 :       int scratch;
   24570          312 :       const char *reg;
   24571          312 :       char legacy_reg[4] = { 0 };
   24572              : 
   24573          312 :       if (!TARGET_PECOFF)
   24574              :         {
   24575          312 :           switch (ix86_cmodel)
   24576              :             {
   24577            7 :             case CM_LARGE:
   24578            7 :               scratch = x86_64_select_profile_regnum (true);
   24579            7 :               reg = hi_reg_name[scratch];
   24580            7 :               if (LEGACY_INT_REGNO_P (scratch))
   24581              :                 {
   24582            0 :                   legacy_reg[0] = 'r';
   24583            0 :                   legacy_reg[1] = reg[0];
   24584            0 :                   legacy_reg[2] = reg[1];
   24585            0 :                   reg = legacy_reg;
   24586              :                 }
   24587            7 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   24588            1 :                 fprintf (file, "%s\tmovabs\t%s, OFFSET FLAT:%s\n"
   24589              :                                "\tcall\t%s\n", label, reg, mcount_name,
   24590              :                                reg);
   24591              :               else
   24592            6 :                 fprintf (file, "%s\tmovabsq\t$%s, %%%s\n\tcall\t*%%%s\n",
   24593              :                          label, mcount_name, reg, reg);
   24594              :               break;
   24595           10 :             case CM_LARGE_PIC:
   24596              : #ifdef NO_PROFILE_COUNTERS
   24597           10 :               scratch = x86_64_select_profile_regnum (false);
   24598           10 :               reg = hi_reg_name[scratch];
   24599           10 :               if (LEGACY_INT_REGNO_P (scratch))
   24600              :                 {
   24601            0 :                   legacy_reg[0] = 'r';
   24602            0 :                   legacy_reg[1] = reg[0];
   24603            0 :                   legacy_reg[2] = reg[1];
   24604            0 :                   reg = legacy_reg;
   24605              :                 }
   24606           10 :               if (ASSEMBLER_DIALECT == ASM_INTEL)
   24607              :                 {
   24608            1 :                   fprintf (file, "1:movabs\tr11, "
   24609              :                                  "OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-1b\n");
   24610            1 :                   fprintf (file, "\tlea\t%s, 1b[rip]\n", reg);
   24611            1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   24612            1 :                   fprintf (file, "\tmovabs\tr11, OFFSET FLAT:%s@PLTOFF\n",
   24613              :                            mcount_name);
   24614            1 :                   fprintf (file, "\tadd\t%s, r11\n", reg);
   24615            1 :                   fprintf (file, "\tcall\t%s\n", reg);
   24616            1 :                   break;
   24617              :                 }
   24618            9 :               fprintf (file,
   24619              :                        "1:\tmovabsq\t$_GLOBAL_OFFSET_TABLE_-1b, %%r11\n");
   24620            9 :               fprintf (file, "\tleaq\t1b(%%rip), %%%s\n", reg);
   24621            9 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   24622            9 :               fprintf (file, "\tmovabsq\t$%s@PLTOFF, %%r11\n", mcount_name);
   24623            9 :               fprintf (file, "\taddq\t%%r11, %%%s\n", reg);
   24624            9 :               fprintf (file, "\tcall\t*%%%s\n", reg);
   24625              : #else
   24626              :               sorry ("profiling %<-mcmodel=large%> with PIC is not supported");
   24627              : #endif
   24628            9 :               break;
   24629           12 :             case CM_SMALL_PIC:
   24630           12 :             case CM_MEDIUM_PIC:
   24631           12 :               if (!flag_plt)
   24632              :                 {
   24633            3 :                   if (ASSEMBLER_DIALECT == ASM_INTEL)
   24634            0 :                     fprintf (file, "%s\tcall\t[QWORD PTR %s@GOTPCREL[rip]]\n",
   24635              :                              label, mcount_name);
   24636              :                   else
   24637            3 :                     fprintf (file, "%s\tcall\t*%s@GOTPCREL(%%rip)\n",
   24638              :                              label, mcount_name);
   24639              :                   break;
   24640              :                 }
   24641              :               /* fall through */
   24642          292 :             default:
   24643          292 :               x86_print_call_or_nop (file, mcount_name, label);
   24644          292 :               break;
   24645              :             }
   24646              :         }
   24647              :       else
   24648              :         x86_print_call_or_nop (file, mcount_name, label);
   24649              :     }
   24650            1 :   else if (flag_pic)
   24651              :     {
   24652              : #ifndef NO_PROFILE_COUNTERS
   24653              :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   24654              :         fprintf (file,
   24655              :                  "\tlea\t" PROFILE_COUNT_REGISTER ", %sP%d@GOTOFF[ebx]\n",
   24656              :                  LPREFIX, labelno);
   24657              :       else
   24658              :         fprintf (file,
   24659              :                  "\tleal\t%sP%d@GOTOFF(%%ebx), %%" PROFILE_COUNT_REGISTER "\n",
   24660              :                  LPREFIX, labelno);
   24661              : #endif
   24662            0 :       if (flag_plt)
   24663            0 :         x86_print_call_or_nop (file, mcount_name, label);
   24664            0 :       else if (ASSEMBLER_DIALECT == ASM_INTEL)
   24665            0 :         fprintf (file, "%s\tcall\t[DWORD PTR %s@GOT[ebx]]\n",
   24666              :                  label, mcount_name);
   24667              :       else
   24668            0 :         fprintf (file, "%s\tcall\t*%s@GOT(%%ebx)\n",
   24669              :                  label, mcount_name);
   24670              :     }
   24671              :   else
   24672              :     {
   24673              : #ifndef NO_PROFILE_COUNTERS
   24674              :       if (ASSEMBLER_DIALECT == ASM_INTEL)
   24675              :         fprintf (file,
   24676              :                  "\tmov\t" PROFILE_COUNT_REGISTER ", OFFSET FLAT:%sP%d\n",
   24677              :                  LPREFIX, labelno);
   24678              :       else
   24679              :         fprintf (file, "\tmovl\t$%sP%d, %%" PROFILE_COUNT_REGISTER "\n",
   24680              :                  LPREFIX, labelno);
   24681              : #endif
   24682            1 :       x86_print_call_or_nop (file, mcount_name, label);
   24683              :     }
   24684              : 
   24685          313 :   if (fentry_section_p)
   24686              :     {
   24687           16 :       const char *sname = "__mcount_loc";
   24688              : 
   24689           16 :       if (current_fentry_section (&sname))
   24690              :         ;
   24691           14 :       else if (fentry_section)
   24692            1 :         sname = fentry_section;
   24693              : 
   24694           16 :       fprintf (file, "\t.section %s, \"a\",@progbits\n", sname);
   24695           16 :       fprintf (file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
   24696           16 :       fprintf (file, "\t.previous\n");
   24697              :     }
   24698          313 : }
   24699              : 
   24700              : /* We don't have exact information about the insn sizes, but we may assume
   24701              :    quite safely that we are informed about all 1 byte insns and memory
   24702              :    address sizes.  This is enough to eliminate unnecessary padding in
   24703              :    99% of cases.  */
   24704              : 
   24705              : int
   24706    399254295 : ix86_min_insn_size (rtx_insn *insn)
   24707              : {
   24708    399254295 :   int l = 0, len;
   24709              : 
   24710    399254295 :   if (!INSN_P (insn) || !active_insn_p (insn))
   24711              :     return 0;
   24712              : 
   24713              :   /* Discard alignments we've emit and jump instructions.  */
   24714    398741849 :   if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
   24715    398741849 :       && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
   24716              :     return 0;
   24717              : 
   24718              :   /* Important case - calls are always 5 bytes.
   24719              :      It is common to have many calls in the row.  */
   24720    398741845 :   if (CALL_P (insn)
   24721      9525810 :       && symbolic_reference_mentioned_p (PATTERN (insn))
   24722    407926585 :       && !SIBLING_CALL_P (insn))
   24723              :     return 5;
   24724    389801266 :   len = get_attr_length (insn);
   24725    389801266 :   if (len <= 1)
   24726              :     return 1;
   24727              : 
   24728              :   /* For normal instructions we rely on get_attr_length being exact,
   24729              :      with a few exceptions.  */
   24730    381061494 :   if (!JUMP_P (insn))
   24731              :     {
   24732    375492137 :       enum attr_type type = get_attr_type (insn);
   24733              : 
   24734    375492137 :       switch (type)
   24735              :         {
   24736        96117 :         case TYPE_MULTI:
   24737        96117 :           if (GET_CODE (PATTERN (insn)) == ASM_INPUT
   24738        96117 :               || asm_noperands (PATTERN (insn)) >= 0)
   24739              :             return 0;
   24740              :           break;
   24741              :         case TYPE_OTHER:
   24742              :         case TYPE_FCMP:
   24743              :           break;
   24744              :         default:
   24745              :           /* Otherwise trust get_attr_length.  */
   24746              :           return len;
   24747              :         }
   24748              : 
   24749       478197 :       l = get_attr_length_address (insn);
   24750       478197 :       if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
   24751              :         l = 4;
   24752              :     }
   24753       387673 :   if (l)
   24754        90524 :     return 1+l;
   24755              :   else
   24756              :     return 2;
   24757              : }
   24758              : 
   24759              : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   24760              : 
   24761              : /* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
   24762              :    window.  */
   24763              : 
   24764              : static void
   24765        46636 : ix86_avoid_jump_mispredicts (void)
   24766              : {
   24767        46636 :   rtx_insn *insn, *start = get_insns ();
   24768        46636 :   int nbytes = 0, njumps = 0;
   24769        46636 :   bool isjump = false;
   24770              : 
   24771              :   /* Look for all minimal intervals of instructions containing 4 jumps.
   24772              :      The intervals are bounded by START and INSN.  NBYTES is the total
   24773              :      size of instructions in the interval including INSN and not including
   24774              :      START.  When the NBYTES is smaller than 16 bytes, it is possible
   24775              :      that the end of START and INSN ends up in the same 16byte page.
   24776              : 
   24777              :      The smallest offset in the page INSN can start is the case where START
   24778              :      ends on the offset 0.  Offset of INSN is then NBYTES - sizeof (INSN).
   24779              :      We add p2align to 16byte window with maxskip 15 - NBYTES + sizeof (INSN).
   24780              : 
   24781              :      Don't consider asm goto as jump, while it can contain a jump, it doesn't
   24782              :      have to, control transfer to label(s) can be performed through other
   24783              :      means, and also we estimate minimum length of all asm stmts as 0.  */
   24784       716076 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   24785              :     {
   24786       669440 :       int min_size;
   24787              : 
   24788       669440 :       if (LABEL_P (insn))
   24789              :         {
   24790          942 :           align_flags alignment = label_to_alignment (insn);
   24791          942 :           int align = alignment.levels[0].log;
   24792          942 :           int max_skip = alignment.levels[0].maxskip;
   24793              : 
   24794          942 :           if (max_skip > 15)
   24795              :             max_skip = 15;
   24796              :           /* If align > 3, only up to 16 - max_skip - 1 bytes can be
   24797              :              already in the current 16 byte page, because otherwise
   24798              :              ASM_OUTPUT_MAX_SKIP_ALIGN could skip max_skip or fewer
   24799              :              bytes to reach 16 byte boundary.  */
   24800          942 :           if (align <= 0
   24801          307 :               || (align <= 3 && max_skip != (1 << align) - 1))
   24802          942 :             max_skip = 0;
   24803          942 :           if (dump_file)
   24804            0 :             fprintf (dump_file, "Label %i with max_skip %i\n",
   24805            0 :                      INSN_UID (insn), max_skip);
   24806          942 :           if (max_skip)
   24807              :             {
   24808         6098 :               while (nbytes + max_skip >= 16)
   24809              :                 {
   24810         5791 :                   start = NEXT_INSN (start);
   24811          295 :                   if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   24812         5808 :                       || CALL_P (start))
   24813          335 :                     njumps--, isjump = true;
   24814              :                   else
   24815              :                     isjump = false;
   24816         5791 :                   nbytes -= ix86_min_insn_size (start);
   24817              :                 }
   24818              :             }
   24819          942 :           continue;
   24820          942 :         }
   24821              : 
   24822       668498 :       min_size = ix86_min_insn_size (insn);
   24823       668498 :       nbytes += min_size;
   24824       668498 :       if (dump_file)
   24825            0 :         fprintf (dump_file, "Insn %i estimated to %i bytes\n",
   24826            0 :                  INSN_UID (insn), min_size);
   24827        47741 :       if ((JUMP_P (insn) && asm_noperands (PATTERN (insn)) < 0)
   24828       668518 :           || CALL_P (insn))
   24829        48754 :         njumps++;
   24830              :       else
   24831       619744 :         continue;
   24832              : 
   24833        57011 :       while (njumps > 3)
   24834              :         {
   24835         8257 :           start = NEXT_INSN (start);
   24836          508 :           if ((JUMP_P (start) && asm_noperands (PATTERN (start)) < 0)
   24837         8257 :               || CALL_P (start))
   24838         1208 :             njumps--, isjump = true;
   24839              :           else
   24840              :             isjump = false;
   24841         8257 :           nbytes -= ix86_min_insn_size (start);
   24842              :         }
   24843        48754 :       gcc_assert (njumps >= 0);
   24844        48754 :       if (dump_file)
   24845            0 :         fprintf (dump_file, "Interval %i to %i has %i bytes\n",
   24846            0 :                  INSN_UID (start), INSN_UID (insn), nbytes);
   24847              : 
   24848        48754 :       if (njumps == 3 && isjump && nbytes < 16)
   24849              :         {
   24850           30 :           int padsize = 15 - nbytes + ix86_min_insn_size (insn);
   24851              : 
   24852           30 :           if (dump_file)
   24853            0 :             fprintf (dump_file, "Padding insn %i by %i bytes!\n",
   24854            0 :                      INSN_UID (insn), padsize);
   24855           30 :           emit_insn_before (gen_max_skip_align (GEN_INT (4), GEN_INT (padsize)), insn);
   24856              :         }
   24857              :     }
   24858        46636 : }
   24859              : #endif
   24860              : 
   24861              : /* AMD Athlon works faster
   24862              :    when RET is not destination of conditional jump or directly preceded
   24863              :    by other jump instruction.  We avoid the penalty by inserting NOP just
   24864              :    before the RET instructions in such cases.  */
   24865              : static void
   24866        46356 : ix86_pad_returns (void)
   24867              : {
   24868        46356 :   edge e;
   24869        46356 :   edge_iterator ei;
   24870              : 
   24871        92737 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   24872              :     {
   24873        46381 :       basic_block bb = e->src;
   24874        46381 :       rtx_insn *ret = BB_END (bb);
   24875        46381 :       rtx_insn *prev;
   24876        46381 :       bool replace = false;
   24877              : 
   24878        46371 :       if (!JUMP_P (ret) || !ANY_RETURN_P (PATTERN (ret))
   24879        92752 :           || optimize_bb_for_size_p (bb))
   24880           23 :         continue;
   24881       184525 :       for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
   24882       137749 :         if (active_insn_p (prev) || LABEL_P (prev))
   24883              :           break;
   24884        46358 :       if (prev && LABEL_P (prev))
   24885              :         {
   24886           42 :           edge e;
   24887           42 :           edge_iterator ei;
   24888              : 
   24889           55 :           FOR_EACH_EDGE (e, ei, bb->preds)
   24890          143 :             if (EDGE_FREQUENCY (e) && e->src->index >= 0
   24891           95 :                 && !(e->flags & EDGE_FALLTHRU))
   24892              :               {
   24893              :                 replace = true;
   24894              :                 break;
   24895              :               }
   24896              :         }
   24897           42 :       if (!replace)
   24898              :         {
   24899        46323 :           prev = prev_active_insn (ret);
   24900        46323 :           if (prev
   24901        46323 :               && ((JUMP_P (prev) && any_condjump_p (prev))
   24902        45887 :                   || CALL_P (prev)))
   24903              :             replace = true;
   24904              :           /* Empty functions get branch mispredict even when
   24905              :              the jump destination is not visible to us.  */
   24906        46323 :           if (!prev && !optimize_function_for_size_p (cfun))
   24907              :             replace = true;
   24908              :         }
   24909        45905 :       if (replace)
   24910              :         {
   24911          488 :           emit_jump_insn_before (gen_simple_return_internal_long (), ret);
   24912          488 :           delete_insn (ret);
   24913              :         }
   24914              :     }
   24915        46356 : }
   24916              : 
   24917              : /* Count the minimum number of instructions in BB.  Return 4 if the
   24918              :    number of instructions >= 4.  */
   24919              : 
   24920              : static int
   24921           41 : ix86_count_insn_bb (basic_block bb)
   24922              : {
   24923           41 :   rtx_insn *insn;
   24924           41 :   int insn_count = 0;
   24925              : 
   24926              :   /* Count number of instructions in this block.  Return 4 if the number
   24927              :      of instructions >= 4.  */
   24928          295 :   FOR_BB_INSNS (bb, insn)
   24929              :     {
   24930              :       /* Only happen in exit blocks.  */
   24931          290 :       if (JUMP_P (insn)
   24932          290 :           && ANY_RETURN_P (PATTERN (insn)))
   24933              :         break;
   24934              : 
   24935          267 :       if (NONDEBUG_INSN_P (insn)
   24936          104 :           && GET_CODE (PATTERN (insn)) != USE
   24937          353 :           && GET_CODE (PATTERN (insn)) != CLOBBER)
   24938              :         {
   24939           86 :           insn_count++;
   24940           86 :           if (insn_count >= 4)
   24941              :             return insn_count;
   24942              :         }
   24943              :     }
   24944              : 
   24945              :   return insn_count;
   24946              : }
   24947              : 
   24948              : 
   24949              : /* Count the minimum number of instructions in code path in BB.
   24950              :    Return 4 if the number of instructions >= 4.  */
   24951              : 
   24952              : static int
   24953           61 : ix86_count_insn (basic_block bb)
   24954              : {
   24955           61 :   edge e;
   24956           61 :   edge_iterator ei;
   24957           61 :   int min_prev_count;
   24958              : 
   24959              :   /* Only bother counting instructions along paths with no
   24960              :      more than 2 basic blocks between entry and exit.  Given
   24961              :      that BB has an edge to exit, determine if a predecessor
   24962              :      of BB has an edge from entry.  If so, compute the number
   24963              :      of instructions in the predecessor block.  If there
   24964              :      happen to be multiple such blocks, compute the minimum.  */
   24965           61 :   min_prev_count = 4;
   24966          144 :   FOR_EACH_EDGE (e, ei, bb->preds)
   24967              :     {
   24968          109 :       edge prev_e;
   24969          109 :       edge_iterator prev_ei;
   24970              : 
   24971          109 :       if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   24972              :         {
   24973           26 :           min_prev_count = 0;
   24974           26 :           break;
   24975              :         }
   24976          182 :       FOR_EACH_EDGE (prev_e, prev_ei, e->src->preds)
   24977              :         {
   24978          109 :           if (prev_e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun))
   24979              :             {
   24980           10 :               int count = ix86_count_insn_bb (e->src);
   24981           10 :               if (count < min_prev_count)
   24982           83 :                 min_prev_count = count;
   24983              :               break;
   24984              :             }
   24985              :         }
   24986              :     }
   24987              : 
   24988           61 :   if (min_prev_count < 4)
   24989           31 :     min_prev_count += ix86_count_insn_bb (bb);
   24990              : 
   24991           61 :   return min_prev_count;
   24992              : }
   24993              : 
   24994              : /* Pad short function to 4 instructions.   */
   24995              : 
   24996              : static void
   24997           63 : ix86_pad_short_function (void)
   24998              : {
   24999           63 :   edge e;
   25000           63 :   edge_iterator ei;
   25001              : 
   25002          127 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   25003              :     {
   25004           64 :       rtx_insn *ret = BB_END (e->src);
   25005           64 :       if (JUMP_P (ret) && ANY_RETURN_P (PATTERN (ret)))
   25006              :         {
   25007           61 :           int insn_count = ix86_count_insn (e->src);
   25008              : 
   25009              :           /* Pad short function.  */
   25010           61 :           if (insn_count < 4)
   25011              :             {
   25012              :               rtx_insn *insn = ret;
   25013              : 
   25014              :               /* Find epilogue.  */
   25015              :               while (insn
   25016           50 :                      && (!NOTE_P (insn)
   25017           23 :                          || NOTE_KIND (insn) != NOTE_INSN_EPILOGUE_BEG))
   25018           28 :                 insn = PREV_INSN (insn);
   25019              : 
   25020           22 :               if (!insn)
   25021            0 :                 insn = ret;
   25022              : 
   25023              :               /* Two NOPs count as one instruction.  */
   25024           22 :               insn_count = 2 * (4 - insn_count);
   25025           22 :               emit_insn_before (gen_nops (GEN_INT (insn_count)), insn);
   25026              :             }
   25027              :         }
   25028              :     }
   25029           63 : }
   25030              : 
   25031              : /* Fix up a Windows system unwinder issue.  If an EH region falls through into
   25032              :    the epilogue, the Windows system unwinder will apply epilogue logic and
   25033              :    produce incorrect offsets.  This can be avoided by adding a nop between
   25034              :    the last insn that can throw and the first insn of the epilogue.  */
   25035              : 
   25036              : static void
   25037            0 : ix86_seh_fixup_eh_fallthru (void)
   25038              : {
   25039            0 :   edge e;
   25040            0 :   edge_iterator ei;
   25041              : 
   25042            0 :   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
   25043              :     {
   25044            0 :       rtx_insn *insn, *next;
   25045              : 
   25046              :       /* Find the beginning of the epilogue.  */
   25047            0 :       for (insn = BB_END (e->src); insn != NULL; insn = PREV_INSN (insn))
   25048            0 :         if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
   25049              :           break;
   25050            0 :       if (insn == NULL)
   25051            0 :         continue;
   25052              : 
   25053              :       /* We only care about preceding insns that can throw.  */
   25054            0 :       insn = prev_active_insn (insn);
   25055            0 :       if (insn == NULL || !can_throw_internal (insn))
   25056            0 :         continue;
   25057              : 
   25058              :       /* Do not separate calls from their debug information.  */
   25059            0 :       for (next = NEXT_INSN (insn); next != NULL; next = NEXT_INSN (next))
   25060            0 :         if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_VAR_LOCATION)
   25061            0 :           insn = next;
   25062              :         else
   25063              :           break;
   25064              : 
   25065            0 :       emit_insn_after (gen_nops (const1_rtx), insn);
   25066              :     }
   25067            0 : }
   25068              : /* Split vector load from parm_decl to elemental loads to avoid STLF
   25069              :    stalls.  */
   25070              : static void
   25071       999980 : ix86_split_stlf_stall_load ()
   25072              : {
   25073       999980 :   rtx_insn* insn, *start = get_insns ();
   25074       999980 :   unsigned window = 0;
   25075              : 
   25076     27661095 :   for (insn = start; insn; insn = NEXT_INSN (insn))
   25077              :     {
   25078     27660245 :       if (!NONDEBUG_INSN_P (insn))
   25079     15720438 :         continue;
   25080     11939807 :       window++;
   25081              :       /* Insert 64 vaddps %xmm18, %xmm19, %xmm20(no dependence between each
   25082              :          other, just emulate for pipeline) before stalled load, stlf stall
   25083              :          case is as fast as no stall cases on CLX.
   25084              :          Since CFG is freed before machine_reorg, just do a rough
   25085              :          calculation of the window according to the layout.  */
   25086     11939807 :       if (window > (unsigned) x86_stlf_window_ninsns)
   25087              :         return;
   25088              : 
   25089     11921407 :       if (any_uncondjump_p (insn)
   25090     11885752 :           || ANY_RETURN_P (PATTERN (insn))
   25091     23421448 :           || CALL_P (insn))
   25092              :         return;
   25093              : 
   25094     10940677 :       rtx set = single_set (insn);
   25095     10940677 :       if (!set)
   25096       446600 :         continue;
   25097     10494077 :       rtx src = SET_SRC (set);
   25098     20987796 :       if (!MEM_P (src)
   25099              :           /* Only handle V2DFmode load since it doesn't need any scratch
   25100              :              register.  */
   25101      1492383 :           || GET_MODE (src) != E_V2DFmode
   25102         5748 :           || !MEM_EXPR (src)
   25103         4184 :           || TREE_CODE (get_base_address (MEM_EXPR (src))) != PARM_DECL
   25104              :           /* Avoid invalid memory address.
   25105              :              i.e.
   25106              :              (mem/c:V2DF (plus:DI (reg/f:DI 7 sp)
   25107              :                                   (const_int 2147483640 [0x7ffffff8])))
   25108              :              Adjusting it by 8 puts the displacement at 0x80000000, out of
   25109              :              range for the signed 32-bit field an x86 address can encode.  */
   25110     10494795 :           || !memory_address_addr_space_p (DFmode,
   25111     10493719 :                                            XEXP (adjust_address_nv (src, DFmode,
   25112              :                                                                     8), 0),
   25113          359 :                                            MEM_ADDR_SPACE (src)))
   25114     10493719 :         continue;
   25115              : 
   25116          358 :       rtx zero = CONST0_RTX (V2DFmode);
   25117          358 :       rtx dest = SET_DEST (set);
   25118          358 :       rtx m = adjust_address (src, DFmode, 0);
   25119          358 :       rtx loadlpd = gen_sse2_loadlpd (dest, zero, m);
   25120          358 :       emit_insn_before (loadlpd, insn);
   25121          358 :       m = adjust_address (src, DFmode, 8);
   25122          358 :       rtx loadhpd = gen_sse2_loadhpd (dest, dest, m);
   25123          358 :       if (dump_file && (dump_flags & TDF_DETAILS))
   25124              :         {
   25125            0 :           fputs ("Due to potential STLF stall, split instruction:\n",
   25126              :                  dump_file);
   25127            0 :           print_rtl_single (dump_file, insn);
   25128            0 :           fputs ("To:\n", dump_file);
   25129            0 :           print_rtl_single (dump_file, loadlpd);
   25130            0 :           print_rtl_single (dump_file, loadhpd);
   25131              :         }
   25132          358 :       PATTERN (insn) = loadhpd;
   25133          358 :       INSN_CODE (insn) = -1;
   25134          358 :       gcc_assert (recog_memoized (insn) != -1);
   25135              :     }
   25136              : }
   25137              : 
   25138              : /* Implement machine specific optimizations.  We implement padding of returns
   25139              :    for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window.  */
   25140              : static void
   25141      1520562 : ix86_reorg (void)
   25142              : {
   25143              :   /* We are freeing block_for_insn in the toplev to keep compatibility
   25144              :      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   25145      1520562 :   compute_bb_for_insn ();
   25146              : 
   25147      1520562 :   if (TARGET_SEH && current_function_has_exception_handlers ())
   25148              :     ix86_seh_fixup_eh_fallthru ();
   25149              : 
   25150      1520562 :   if (optimize && optimize_function_for_speed_p (cfun))
   25151              :     {
   25152      1002377 :       if (TARGET_SSE2)
   25153       999980 :         ix86_split_stlf_stall_load ();
   25154      1002377 :       if (TARGET_PAD_SHORT_FUNCTION)
   25155           63 :         ix86_pad_short_function ();
   25156      1002314 :       else if (TARGET_PAD_RETURNS)
   25157        46356 :         ix86_pad_returns ();
   25158              : #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
   25159      1002377 :       if (TARGET_FOUR_JUMP_LIMIT)
   25160        46636 :         ix86_avoid_jump_mispredicts ();
   25161              : #endif
   25162              :     }
   25163      1520562 : }
   25164              : 
   25165              : /* Return nonzero when QImode register that must be represented via REX prefix
   25166              :    is used.  */
   25167              : bool
   25168      9035951 : x86_extended_QIreg_mentioned_p (rtx_insn *insn)
   25169              : {
   25170      9035951 :   int i;
   25171      9035951 :   extract_insn_cached (insn);
   25172     34293370 :   for (i = 0; i < recog_data.n_operands; i++)
   25173      4758339 :     if (GENERAL_REG_P (recog_data.operand[i])
   25174     22535591 :         && !QI_REGNO_P (REGNO (recog_data.operand[i])))
   25175              :        return true;
   25176              :   return false;
   25177              : }
   25178              : 
   25179              : /* Return true when INSN mentions register that must be encoded using REX
   25180              :    prefix.  */
   25181              : bool
   25182    200571650 : x86_extended_reg_mentioned_p (rtx insn)
   25183              : {
   25184    200571650 :   subrtx_iterator::array_type array;
   25185   1054408171 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   25186              :     {
   25187    903378686 :       const_rtx x = *iter;
   25188    903378686 :       if (REG_P (x)
   25189    903378686 :           && (REX_INT_REGNO_P (REGNO (x)) || REX_SSE_REGNO_P (REGNO (x))
   25190    259168888 :               || REX2_INT_REGNO_P (REGNO (x))))
   25191     49542165 :         return true;
   25192              :     }
   25193    151029485 :   return false;
   25194    200571650 : }
   25195              : 
   25196              : /* Return true when INSN mentions register that must be encoded using REX2
   25197              :    prefix.  */
   25198              : bool
   25199      2048997 : x86_extended_rex2reg_mentioned_p (rtx insn)
   25200              : {
   25201      2048997 :   subrtx_iterator::array_type array;
   25202      9486667 :   FOR_EACH_SUBRTX (iter, array, INSN_P (insn) ? PATTERN (insn) : insn, NONCONST)
   25203              :     {
   25204      7438291 :       const_rtx x = *iter;
   25205      7438291 :       if (REG_P (x) && REX2_INT_REGNO_P (REGNO (x)))
   25206          621 :         return true;
   25207              :     }
   25208      2048376 :   return false;
   25209      2048997 : }
   25210              : 
   25211              : /* Return true when rtx operands mentions register that must be encoded using
   25212              :    evex prefix.  */
   25213              : bool
   25214           11 : x86_evex_reg_mentioned_p (rtx operands[], int nops)
   25215              : {
   25216           11 :   int i;
   25217           32 :   for (i = 0; i < nops; i++)
   25218           25 :     if (EXT_REX_SSE_REG_P (operands[i])
   25219           46 :         || x86_extended_rex2reg_mentioned_p (operands[i]))
   25220              :       return true;
   25221              :   return false;
   25222              : }
   25223              : 
   25224              : /* If profitable, negate (without causing overflow) integer constant
   25225              :    of mode MODE at location LOC.  Return true in this case.  */
   25226              : bool
   25227      6052933 : x86_maybe_negate_const_int (rtx *loc, machine_mode mode)
   25228              : {
   25229      6052933 :   HOST_WIDE_INT val;
   25230              : 
   25231      6052933 :   if (!CONST_INT_P (*loc))
   25232              :     return false;
   25233              : 
   25234      5079138 :   switch (mode)
   25235              :     {
   25236      2922501 :     case E_DImode:
   25237              :       /* DImode x86_64 constants must fit in 32 bits.  */
   25238      2922501 :       gcc_assert (x86_64_immediate_operand (*loc, mode));
   25239              : 
   25240              :       mode = SImode;
   25241              :       break;
   25242              : 
   25243              :     case E_SImode:
   25244              :     case E_HImode:
   25245              :     case E_QImode:
   25246              :       break;
   25247              : 
   25248            0 :     default:
   25249            0 :       gcc_unreachable ();
   25250              :     }
   25251              : 
   25252              :   /* Avoid overflows.  */
   25253      5079138 :   if (mode_signbit_p (mode, *loc))
   25254              :     return false;
   25255              : 
   25256      5078391 :   val = INTVAL (*loc);
   25257              : 
   25258              :   /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
   25259              :      Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
   25260      5078391 :   if ((val < 0 && val != -128)
   25261      3348842 :       || val == 128)
   25262              :     {
   25263      1741497 :       *loc = GEN_INT (-val);
   25264      1741497 :       return true;
   25265              :     }
   25266              : 
   25267              :   return false;
   25268              : }
   25269              : 
   25270              : /* Generate an unsigned DImode/SImode to FP conversion.  This is the same code
   25271              :    optabs would emit if we didn't have TFmode patterns.  */
   25272              : 
   25273              : void
   25274         5546 : x86_emit_floatuns (rtx operands[2])
   25275              : {
   25276         5546 :   rtx_code_label *neglab, *donelab;
   25277         5546 :   rtx i0, i1, f0, in, out;
   25278         5546 :   machine_mode mode, inmode;
   25279              : 
   25280         5546 :   inmode = GET_MODE (operands[1]);
   25281         5546 :   gcc_assert (inmode == SImode || inmode == DImode);
   25282              : 
   25283         5546 :   out = operands[0];
   25284         5546 :   in = force_reg (inmode, operands[1]);
   25285         5546 :   mode = GET_MODE (out);
   25286         5546 :   neglab = gen_label_rtx ();
   25287         5546 :   donelab = gen_label_rtx ();
   25288         5546 :   f0 = gen_reg_rtx (mode);
   25289              : 
   25290         5546 :   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, inmode, 0, neglab);
   25291              : 
   25292         5546 :   expand_float (out, in, 0);
   25293              : 
   25294         5546 :   emit_jump_insn (gen_jump (donelab));
   25295         5546 :   emit_barrier ();
   25296              : 
   25297         5546 :   emit_label (neglab);
   25298              : 
   25299         5546 :   i0 = expand_simple_binop (inmode, LSHIFTRT, in, const1_rtx, NULL,
   25300              :                             1, OPTAB_DIRECT);
   25301         5546 :   i1 = expand_simple_binop (inmode, AND, in, const1_rtx, NULL,
   25302              :                             1, OPTAB_DIRECT);
   25303         5546 :   i0 = expand_simple_binop (inmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
   25304              : 
   25305         5546 :   expand_float (f0, i0, 0);
   25306              : 
   25307         5546 :   emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
   25308              : 
   25309         5546 :   emit_label (donelab);
   25310         5546 : }
   25311              : 
   25312              : /* Return the diagnostic message string if conversion from FROMTYPE to
   25313              :    TOTYPE is not allowed, NULL otherwise.  */
   25314              : 
   25315              : static const char *
   25316   1138633486 : ix86_invalid_conversion (const_tree fromtype, const_tree totype)
   25317              : {
   25318   1138633486 :   machine_mode from_mode = element_mode (fromtype);
   25319   1138633486 :   machine_mode to_mode = element_mode (totype);
   25320              : 
   25321   1138633486 :   if (!TARGET_SSE2 && from_mode != to_mode)
   25322              :     {
   25323              :       /* Do no allow conversions to/from BFmode/HFmode scalar types
   25324              :          when TARGET_SSE2 is not available.  */
   25325       470309 :       if (from_mode == BFmode)
   25326              :         return N_("invalid conversion from type %<__bf16%> "
   25327              :                   "without option %<-msse2%>");
   25328       470308 :       if (from_mode == HFmode)
   25329              :         return N_("invalid conversion from type %<_Float16%> "
   25330              :                   "without option %<-msse2%>");
   25331       470308 :       if (to_mode == BFmode)
   25332              :         return N_("invalid conversion to type %<__bf16%> "
   25333              :                   "without option %<-msse2%>");
   25334       470308 :       if (to_mode == HFmode)
   25335              :         return N_("invalid conversion to type %<_Float16%> "
   25336              :                   "without option %<-msse2%>");
   25337              :     }
   25338              : 
   25339              :   /* Warn for silent implicit conversion between __bf16 and short,
   25340              :      since __bfloat16 is refined as real __bf16 instead of short
   25341              :      since GCC13.  */
   25342   1138633484 :   if (element_mode (fromtype) != element_mode (totype)
   25343   1138633484 :       && (TARGET_AVX512BF16 || TARGET_AVXNECONVERT))
   25344              :     {
   25345              :       /* Warn for silent implicit conversion where user may expect
   25346              :          a bitcast.  */
   25347     10462012 :       if ((TYPE_MODE (fromtype) == BFmode
   25348          279 :            && TYPE_MODE (totype) == HImode)
   25349     10462290 :           || (TYPE_MODE (totype) == BFmode
   25350          427 :               && TYPE_MODE (fromtype) == HImode))
   25351            1 :         warning (0, "%<__bfloat16%> is redefined from typedef %<short%> "
   25352              :                 "to real %<__bf16%> since GCC 13.1, be careful of "
   25353              :                  "implicit conversion between %<__bf16%> and %<short%>; "
   25354              :                  "an explicit bitcast may be needed here");
   25355              :     }
   25356              : 
   25357              :   /* Conversion allowed.  */
   25358              :   return NULL;
   25359              : }
   25360              : 
   25361              : /* Return the diagnostic message string if the unary operation OP is
   25362              :    not permitted on TYPE, NULL otherwise.  */
   25363              : 
   25364              : static const char *
   25365     94982360 : ix86_invalid_unary_op (int op, const_tree type)
   25366              : {
   25367     94982360 :   machine_mode mmode = element_mode (type);
   25368              :   /* Reject all single-operand operations on BFmode/HFmode except for &
   25369              :      when TARGET_SSE2 is not available.  */
   25370     94982360 :   if (!TARGET_SSE2 && op != ADDR_EXPR)
   25371              :     {
   25372       111586 :       if (mmode == BFmode)
   25373              :         return N_("operation not permitted on type %<__bf16%> "
   25374              :                   "without option %<-msse2%>");
   25375       111586 :       if (mmode == HFmode)
   25376            0 :         return N_("operation not permitted on type %<_Float16%> "
   25377              :                   "without option %<-msse2%>");
   25378              :     }
   25379              : 
   25380              :   /* Operation allowed.  */
   25381              :   return NULL;
   25382              : }
   25383              : 
   25384              : /* Return the diagnostic message string if the binary operation OP is
   25385              :    not permitted on TYPE1 and TYPE2, NULL otherwise.  */
   25386              : 
   25387              : static const char *
   25388    172348286 : ix86_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
   25389              :                         const_tree type2)
   25390              : {
   25391    172348286 :   machine_mode type1_mode = element_mode (type1);
   25392    172348286 :   machine_mode type2_mode = element_mode (type2);
   25393              :   /* Reject all 2-operand operations on BFmode or HFmode
   25394              :      when TARGET_SSE2 is not available.  */
   25395    172348286 :   if (!TARGET_SSE2)
   25396              :     {
   25397      1013344 :       if (type1_mode == BFmode || type2_mode == BFmode)
   25398              :         return N_("operation not permitted on type %<__bf16%> "
   25399              :                   "without option %<-msse2%>");
   25400              : 
   25401      1013344 :       if (type1_mode == HFmode || type2_mode == HFmode)
   25402            0 :         return N_("operation not permitted on type %<_Float16%> "
   25403              :                   "without option %<-msse2%>");
   25404              :     }
   25405              : 
   25406              :   /* Operation allowed.  */
   25407              :   return NULL;
   25408              : }
   25409              : 
   25410              : 
   25411              : /* Target hook for scalar_mode_supported_p.  */
   25412              : static bool
   25413      5593113 : ix86_scalar_mode_supported_p (scalar_mode mode)
   25414              : {
   25415      5593113 :   if (DECIMAL_FLOAT_MODE_P (mode))
   25416       643974 :     return default_decimal_float_supported_p ();
   25417      4949139 :   else if (mode == TFmode)
   25418              :     return true;
   25419      4619317 :   else if (mode == HFmode || mode == BFmode)
   25420              :     return true;
   25421              :   else
   25422      3961656 :     return default_scalar_mode_supported_p (mode);
   25423              : }
   25424              : 
   25425              : /* Implement TARGET_LIBGCC_FLOATING_POINT_MODE_SUPPORTED_P - return TRUE
   25426              :    if MODE is HFmode, and punt to the generic implementation otherwise.  */
   25427              : 
   25428              : static bool
   25429      2265188 : ix86_libgcc_floating_mode_supported_p (scalar_float_mode mode)
   25430              : {
   25431              :   /* NB: Always return TRUE for HFmode so that the _Float16 type will
   25432              :      be defined by the C front-end for AVX512FP16 intrinsics.  We will
   25433              :      issue an error in ix86_expand_move for HFmode if AVX512FP16 isn't
   25434              :      enabled.  */
   25435      1936833 :   return ((mode == HFmode || mode == BFmode)
   25436      3873666 :           ? true
   25437      1608478 :           : default_libgcc_floating_mode_supported_p (mode));
   25438              : }
   25439              : 
   25440              : /* Implements target hook vector_mode_supported_p.  */
   25441              : static bool
   25442   1371658039 : ix86_vector_mode_supported_p (machine_mode mode)
   25443              : {
   25444              :   /* For ia32, scalar TImode isn't supported and so V1TImode shouldn't be
   25445              :      either.  */
   25446   1502641970 :   if (!TARGET_64BIT && GET_MODE_INNER (mode) == TImode)
   25447              :     return false;
   25448   1371551859 :   if (TARGET_SSE && VALID_SSE_REG_MODE (mode))
   25449              :     return true;
   25450   1156480454 :   if (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
   25451              :     return true;
   25452    520254064 :   if (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
   25453              :     return true;
   25454    376294256 :   if (TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
   25455              :     return true;
   25456    238104169 :   if ((TARGET_MMX || TARGET_MMX_WITH_SSE)
   25457    238046612 :       && VALID_MMX_REG_MODE (mode))
   25458              :     return true;
   25459     37085880 :   if ((TARGET_3DNOW || TARGET_MMX_WITH_SSE)
   25460     36436505 :       && VALID_MMX_REG_MODE_3DNOW (mode))
   25461              :     return true;
   25462     23775022 :   if (mode == V2QImode)
   25463        24813 :     return true;
   25464              :   return false;
   25465              : }
   25466              : 
   25467              : /* Target hook for c_mode_for_suffix.  */
   25468              : static machine_mode
   25469       203917 : ix86_c_mode_for_suffix (char suffix)
   25470              : {
   25471       203917 :   if (suffix == 'q')
   25472              :     return TFmode;
   25473           37 :   if (suffix == 'w')
   25474              :     return XFmode;
   25475              : 
   25476            0 :   return VOIDmode;
   25477              : }
   25478              : 
   25479              : /* Helper function to map common constraints to non-EGPR ones.
   25480              :    All related constraints have h prefix, and h plus Upper letter
   25481              :    means the constraint is strictly EGPR enabled, while h plus
   25482              :    lower letter indicates the constraint is strictly gpr16 only.
   25483              : 
   25484              :    Specially for "g" constraint, split it to rmi as there is
   25485              :    no corresponding general constraint define for backend.
   25486              : 
   25487              :    Here is the full list to map constraints that may involve
   25488              :    gpr to h prefixed.
   25489              : 
   25490              :    "g" -> "jrjmi"
   25491              :    "r" -> "jr"
   25492              :    "m" -> "jm"
   25493              :    "<" -> "j<"
   25494              :    ">" -> "j>"
   25495              :    "o" -> "jo"
   25496              :    "V" -> "jV"
   25497              :    "p" -> "jp"
   25498              :    "Bm" -> "ja"
   25499              : */
   25500              : 
   25501           64 : static void map_egpr_constraints (vec<const char *> &constraints)
   25502              : {
   25503           74 :   for (size_t i = 0; i < constraints.length(); i++)
   25504              :     {
   25505           10 :       const char *cur = constraints[i];
   25506              : 
   25507           10 :       if (startswith (cur, "=@cc"))
   25508            0 :         continue;
   25509              : 
   25510           10 :       int len = strlen (cur);
   25511           10 :       auto_vec<char> buf;
   25512              : 
   25513           24 :       for (int j = 0; j < len; j++)
   25514              :         {
   25515           14 :           switch (cur[j])
   25516              :             {
   25517            2 :             case 'g':
   25518            2 :               buf.safe_push ('j');
   25519            2 :               buf.safe_push ('r');
   25520            2 :               buf.safe_push ('j');
   25521            2 :               buf.safe_push ('m');
   25522            2 :               buf.safe_push ('i');
   25523            2 :               break;
   25524            8 :             case 'r':
   25525            8 :             case 'm':
   25526            8 :             case '<':
   25527            8 :             case '>':
   25528            8 :             case 'o':
   25529            8 :             case 'V':
   25530            8 :             case 'p':
   25531            8 :               buf.safe_push ('j');
   25532            8 :               buf.safe_push (cur[j]);
   25533            8 :               break;
   25534            0 :             case 'B':
   25535            0 :               if (cur[j + 1] == 'm')
   25536              :                 {
   25537            0 :                   buf.safe_push ('j');
   25538            0 :                   buf.safe_push ('a');
   25539            0 :                   j++;
   25540              :                 }
   25541              :               else
   25542              :                 {
   25543            0 :                   buf.safe_push (cur[j]);
   25544            0 :                   buf.safe_push (cur[j + 1]);
   25545            0 :                   j++;
   25546              :                 }
   25547              :               break;
   25548            0 :             case 'T':
   25549            0 :             case 'Y':
   25550            0 :             case 'W':
   25551            0 :             case 'j':
   25552            0 :               buf.safe_push (cur[j]);
   25553            0 :               buf.safe_push (cur[j + 1]);
   25554            0 :               j++;
   25555            0 :               break;
   25556            0 :             case '{':
   25557            0 :               do
   25558              :                 {
   25559            0 :                   buf.safe_push (cur[j]);
   25560            0 :                 } while (cur[j++] != '}');
   25561              :               break;
   25562            4 :             default:
   25563            4 :               buf.safe_push (cur[j]);
   25564            4 :               break;
   25565              :             }
   25566              :         }
   25567           10 :       buf.safe_push ('\0');
   25568           20 :       constraints[i] = xstrdup (buf.address ());
   25569           10 :     }
   25570           64 : }
   25571              : 
   25572              : /* Worker function for TARGET_MD_ASM_ADJUST.
   25573              : 
   25574              :    We implement asm flag outputs, and maintain source compatibility
   25575              :    with the old cc0-based compiler.  */
   25576              : 
   25577              : static rtx_insn *
   25578        94293 : ix86_md_asm_adjust (vec<rtx> &outputs, vec<rtx> & /*inputs*/,
   25579              :                     vec<machine_mode> & /*input_modes*/,
   25580              :                     vec<const char *> &constraints, vec<rtx> &/*uses*/,
   25581              :                     vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
   25582              :                     location_t loc)
   25583              : {
   25584        94293 :   bool saw_asm_flag = false;
   25585              : 
   25586        94293 :   start_sequence ();
   25587              : 
   25588        94293 :   if (TARGET_APX_EGPR && !ix86_apx_inline_asm_use_gpr32)
   25589           64 :     map_egpr_constraints (constraints);
   25590              : 
   25591       267148 :   for (unsigned i = 0, n = outputs.length (); i < n; ++i)
   25592              :     {
   25593        79380 :       const char *con = constraints[i];
   25594        79380 :       if (!startswith (con, "=@cc"))
   25595        79292 :         continue;
   25596           88 :       con += 4;
   25597           88 :       if (strchr (con, ',') != NULL)
   25598              :         {
   25599            1 :           error_at (loc, "alternatives not allowed in %<asm%> flag output");
   25600            1 :           continue;
   25601              :         }
   25602              : 
   25603           87 :       bool invert = false;
   25604           87 :       if (con[0] == 'n')
   25605           19 :         invert = true, con++;
   25606              : 
   25607           87 :       machine_mode mode = CCmode;
   25608           87 :       rtx_code code = UNKNOWN;
   25609              : 
   25610           87 :       switch (con[0])
   25611              :         {
   25612           15 :         case 'a':
   25613           15 :           if (con[1] == 0)
   25614              :             mode = CCAmode, code = EQ;
   25615            4 :           else if (con[1] == 'e' && con[2] == 0)
   25616              :             mode = CCCmode, code = NE;
   25617              :           break;
   25618           11 :         case 'b':
   25619           11 :           if (con[1] == 0)
   25620              :             mode = CCCmode, code = EQ;
   25621            6 :           else if (con[1] == 'e' && con[2] == 0)
   25622              :             mode = CCAmode, code = NE;
   25623              :           break;
   25624           14 :         case 'c':
   25625           14 :           if (con[1] == 0)
   25626              :             mode = CCCmode, code = EQ;
   25627              :           break;
   25628            8 :         case 'e':
   25629            8 :           if (con[1] == 0)
   25630              :             mode = CCZmode, code = EQ;
   25631              :           break;
   25632           11 :         case 'g':
   25633           11 :           if (con[1] == 0)
   25634              :             mode = CCGCmode, code = GT;
   25635            5 :           else if (con[1] == 'e' && con[2] == 0)
   25636              :             mode = CCGCmode, code = GE;
   25637              :           break;
   25638           10 :         case 'l':
   25639           10 :           if (con[1] == 0)
   25640              :             mode = CCGCmode, code = LT;
   25641            5 :           else if (con[1] == 'e' && con[2] == 0)
   25642              :             mode = CCGCmode, code = LE;
   25643              :           break;
   25644            4 :         case 'o':
   25645            4 :           if (con[1] == 0)
   25646              :             mode = CCOmode, code = EQ;
   25647              :           break;
   25648            4 :         case 'p':
   25649            4 :           if (con[1] == 0)
   25650              :             mode = CCPmode, code = EQ;
   25651              :           break;
   25652            4 :         case 's':
   25653            4 :           if (con[1] == 0)
   25654              :             mode = CCSmode, code = EQ;
   25655              :           break;
   25656            6 :         case 'z':
   25657            6 :           if (con[1] == 0)
   25658              :             mode = CCZmode, code = EQ;
   25659              :           break;
   25660              :         }
   25661            1 :       if (code == UNKNOWN)
   25662              :         {
   25663            1 :           error_at (loc, "unknown %<asm%> flag output %qs", constraints[i]);
   25664            1 :           continue;
   25665              :         }
   25666           86 :       if (invert)
   25667           19 :         code = reverse_condition (code);
   25668              : 
   25669           86 :       rtx dest = outputs[i];
   25670           86 :       if (!saw_asm_flag)
   25671              :         {
   25672              :           /* This is the first asm flag output.  Here we put the flags
   25673              :              register in as the real output and adjust the condition to
   25674              :              allow it.  */
   25675           75 :           constraints[i] = "=Bf";
   25676           75 :           outputs[i] = gen_rtx_REG (CCmode, FLAGS_REG);
   25677           75 :           saw_asm_flag = true;
   25678              :         }
   25679              :       else
   25680              :         {
   25681              :           /* We don't need the flags register as output twice.  */
   25682           11 :           constraints[i] = "=X";
   25683           11 :           outputs[i] = gen_rtx_SCRATCH (SImode);
   25684              :         }
   25685              : 
   25686           86 :       rtx x = gen_rtx_REG (mode, FLAGS_REG);
   25687           86 :       x = gen_rtx_fmt_ee (code, QImode, x, const0_rtx);
   25688              : 
   25689           86 :       machine_mode dest_mode = GET_MODE (dest);
   25690           86 :       if (!SCALAR_INT_MODE_P (dest_mode))
   25691              :         {
   25692            3 :           error_at (loc, "invalid type for %<asm%> flag output");
   25693            3 :           continue;
   25694              :         }
   25695              : 
   25696           83 :       if (dest_mode == QImode)
   25697           73 :         emit_insn (gen_rtx_SET (dest, x));
   25698              :       else
   25699              :         {
   25700           10 :           rtx reg = gen_reg_rtx (QImode);
   25701           10 :           emit_insn (gen_rtx_SET (reg, x));
   25702              : 
   25703           10 :           reg = convert_to_mode (dest_mode, reg, 1);
   25704           10 :           emit_move_insn (dest, reg);
   25705              :         }
   25706              :     }
   25707              : 
   25708        94293 :   rtx_insn *seq = end_sequence ();
   25709              : 
   25710        94293 :   if (saw_asm_flag)
   25711              :     return seq;
   25712              :   else
   25713              :     {
   25714              :       /* If we had no asm flag outputs, clobber the flags.  */
   25715        94218 :       clobbers.safe_push (gen_rtx_REG (CCmode, FLAGS_REG));
   25716        94218 :       SET_HARD_REG_BIT (clobbered_regs, FLAGS_REG);
   25717        94218 :       return NULL;
   25718              :     }
   25719              : }
   25720              : 
   25721              : /* Implements target vector targetm.asm.encode_section_info.  */
   25722              : 
   25723              : static void ATTRIBUTE_UNUSED
   25724     10090114 : ix86_encode_section_info (tree decl, rtx rtl, int first)
   25725              : {
   25726     10090114 :   default_encode_section_info (decl, rtl, first);
   25727              : 
   25728     10090114 :   if (ix86_in_large_data_p (decl))
   25729           32 :     SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_FAR_ADDR;
   25730     10090114 : }
   25731              : 
   25732              : /* Worker function for REVERSE_CONDITION.  */
   25733              : 
   25734              : enum rtx_code
   25735     32820279 : ix86_reverse_condition (enum rtx_code code, machine_mode mode)
   25736              : {
   25737     32820279 :   return (mode == CCFPmode
   25738     32820279 :           ? reverse_condition_maybe_unordered (code)
   25739     28353851 :           : reverse_condition (code));
   25740              : }
   25741              : 
   25742              : /* Output code to perform an x87 FP register move, from OPERANDS[1]
   25743              :    to OPERANDS[0].  */
   25744              : 
   25745              : const char *
   25746       653236 : output_387_reg_move (rtx_insn *insn, rtx *operands)
   25747              : {
   25748       653236 :   if (REG_P (operands[0]))
   25749              :     {
   25750       547752 :       if (REG_P (operands[1])
   25751       547752 :           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   25752              :         {
   25753       292637 :           if (REGNO (operands[0]) == FIRST_STACK_REG)
   25754       274718 :             return output_387_ffreep (operands, 0);
   25755              :           return "fstp\t%y0";
   25756              :         }
   25757       255115 :       if (STACK_TOP_P (operands[0]))
   25758       255115 :         return "fld%Z1\t%y1";
   25759              :       return "fst\t%y0";
   25760              :     }
   25761       105484 :   else if (MEM_P (operands[0]))
   25762              :     {
   25763       105484 :       gcc_assert (REG_P (operands[1]));
   25764       105484 :       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
   25765              :         return "fstp%Z0\t%y0";
   25766              :       else
   25767              :         {
   25768              :           /* There is no non-popping store to memory for XFmode.
   25769              :              So if we need one, follow the store with a load.  */
   25770         5593 :           if (GET_MODE (operands[0]) == XFmode)
   25771              :             return "fstp%Z0\t%y0\n\tfld%Z0\t%y0";
   25772              :           else
   25773         1935 :             return "fst%Z0\t%y0";
   25774              :         }
   25775              :     }
   25776              :   else
   25777            0 :     gcc_unreachable();
   25778              : }
   25779              : #ifdef TARGET_SOLARIS
   25780              : /* Solaris implementation of TARGET_ASM_NAMED_SECTION.  */
   25781              : 
   25782              : static void
   25783              : i386_solaris_elf_named_section (const char *name, unsigned int flags,
   25784              :                                 tree decl)
   25785              : {
   25786              :   /* With Binutils 2.15, the "@unwind" marker must be specified on
   25787              :      every occurrence of the ".eh_frame" section, not just the first
   25788              :      one.  */
   25789              :   if (TARGET_64BIT
   25790              :       && strcmp (name, ".eh_frame") == 0)
   25791              :     {
   25792              :       fprintf (asm_out_file, "\t.section\t%s,\"%s\",@unwind\n", name,
   25793              :                flags & SECTION_WRITE ? "aw" : "a");
   25794              :       return;
   25795              :     }
   25796              : 
   25797              : #if HAVE_SOLARIS_AS
   25798              :   if (HAVE_COMDAT_GROUP && flags & SECTION_LINKONCE)
   25799              :     {
   25800              :       solaris_elf_asm_comdat_section (name, flags, decl);
   25801              :       return;
   25802              :     }
   25803              : 
   25804              :   /* Solaris/x86 as uses the same syntax for the SHF_EXCLUDE flags as the
   25805              :      SPARC assembler.  One cannot mix single-letter flags and #exclude, so
   25806              :      only emit the latter here.  */
   25807              :   if (flags & SECTION_EXCLUDE)
   25808              :     {
   25809              :       fprintf (asm_out_file, "\t.section\t%s,#exclude\n", name);
   25810              :       return;
   25811              :     }
   25812              : #endif
   25813              : 
   25814              :   default_elf_asm_named_section (name, flags, decl);
   25815              : }
   25816              : #endif /* TARGET_SOLARIS */
   25817              : 
   25818              : /* Return the mangling of TYPE if it is an extended fundamental type.  */
   25819              : 
   25820              : static const char *
   25821   1108305373 : ix86_mangle_type (const_tree type)
   25822              : {
   25823   1108305373 :   type = TYPE_MAIN_VARIANT (type);
   25824              : 
   25825   1108305373 :   if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
   25826              :       && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
   25827              :     return NULL;
   25828              : 
   25829    601137702 :   if (type == float128_type_node || type == float64x_type_node)
   25830              :     return NULL;
   25831              : 
   25832    600333058 :   switch (TYPE_MODE (type))
   25833              :     {
   25834              :     case E_BFmode:
   25835              :       return "DF16b";
   25836       504824 :     case E_HFmode:
   25837              :       /* _Float16 is "DF16_".
   25838              :          Align with clang's decision in https://reviews.llvm.org/D33719. */
   25839       504824 :       return "DF16_";
   25840       700248 :     case E_TFmode:
   25841              :       /* __float128 is "g".  */
   25842       700248 :       return "g";
   25843      8210639 :     case E_XFmode:
   25844              :       /* "long double" or __float80 is "e".  */
   25845      8210639 :       return "e";
   25846              :     default:
   25847              :       return NULL;
   25848              :     }
   25849              : }
   25850              : 
   25851              : /* Create C++ tinfo symbols for only conditionally available fundamental
   25852              :    types.  */
   25853              : 
   25854              : static void
   25855            5 : ix86_emit_support_tinfos (emit_support_tinfos_callback callback)
   25856              : {
   25857            5 :   extern tree ix86_float16_type_node;
   25858            5 :   extern tree ix86_bf16_type_node;
   25859              : 
   25860            5 :   if (!TARGET_SSE2)
   25861              :     {
   25862            0 :       if (!float16_type_node)
   25863            0 :         float16_type_node = ix86_float16_type_node;
   25864            0 :       if (!bfloat16_type_node)
   25865            0 :         bfloat16_type_node = ix86_bf16_type_node;
   25866            0 :       callback (float16_type_node);
   25867            0 :       callback (bfloat16_type_node);
   25868            0 :       float16_type_node = NULL_TREE;
   25869            0 :       bfloat16_type_node = NULL_TREE;
   25870              :     }
   25871            5 : }
   25872              : 
   25873              : static GTY(()) tree ix86_tls_stack_chk_guard_decl;
   25874              : 
   25875              : static tree
   25876          336 : ix86_stack_protect_guard (void)
   25877              : {
   25878          336 :   if (TARGET_SSP_TLS_GUARD)
   25879              :     {
   25880          261 :       tree type_node = lang_hooks.types.type_for_mode (ptr_mode, 1);
   25881          261 :       int qual = ENCODE_QUAL_ADDR_SPACE (ix86_stack_protector_guard_reg);
   25882          261 :       tree type = build_qualified_type (type_node, qual);
   25883          261 :       tree t;
   25884              : 
   25885          261 :       if (OPTION_SET_P (ix86_stack_protector_guard_symbol_str))
   25886              :         {
   25887            1 :           t = ix86_tls_stack_chk_guard_decl;
   25888              : 
   25889            1 :           if (t == NULL)
   25890              :             {
   25891            1 :               rtx x;
   25892              : 
   25893            1 :               t = build_decl
   25894            1 :                 (UNKNOWN_LOCATION, VAR_DECL,
   25895              :                  get_identifier (ix86_stack_protector_guard_symbol_str),
   25896              :                  type);
   25897            1 :               TREE_STATIC (t) = 1;
   25898            1 :               TREE_PUBLIC (t) = 1;
   25899            1 :               DECL_EXTERNAL (t) = 1;
   25900            1 :               TREE_USED (t) = 1;
   25901            1 :               TREE_THIS_VOLATILE (t) = 1;
   25902            1 :               DECL_ARTIFICIAL (t) = 1;
   25903            1 :               DECL_IGNORED_P (t) = 1;
   25904              : 
   25905              :               /* Do not share RTL as the declaration is visible outside of
   25906              :                  current function.  */
   25907            1 :               x = DECL_RTL (t);
   25908            1 :               RTX_FLAG (x, used) = 1;
   25909              : 
   25910            1 :               ix86_tls_stack_chk_guard_decl = t;
   25911              :             }
   25912              :         }
   25913              :       else
   25914              :         {
   25915          260 :           tree asptrtype = build_pointer_type (type);
   25916              : 
   25917          260 :           t = build_int_cst (asptrtype, ix86_stack_protector_guard_offset);
   25918          260 :           t = build2 (MEM_REF, asptrtype, t,
   25919              :                       build_int_cst (asptrtype, 0));
   25920          260 :           TREE_THIS_VOLATILE (t) = 1;
   25921              :         }
   25922              : 
   25923              :       return t;
   25924              :     }
   25925              : 
   25926           75 :   return default_stack_protect_guard ();
   25927              : }
   25928              : 
   25929              : /* Implement TARGET_STACK_PROTECT_GUARD_SYMBOL_P.  */
   25930              : 
   25931              : static bool
   25932       208511 : ix86_stack_protect_guard_symbol_p (void)
   25933              : {
   25934       208511 :   return TARGET_SSP_GLOBAL_GUARD;
   25935              : }
   25936              : 
   25937              : static bool
   25938          924 : ix86_stack_protect_runtime_enabled_p (void)
   25939              : {
   25940              :   /* Naked functions should not enable stack protector.  */
   25941          924 :   return !ix86_function_naked (current_function_decl);
   25942              : }
   25943              : 
   25944              : /* For 32-bit code we can save PIC register setup by using
   25945              :    __stack_chk_fail_local hidden function instead of calling
   25946              :    __stack_chk_fail directly.  64-bit code doesn't need to setup any PIC
   25947              :    register, so it is better to call __stack_chk_fail directly.  */
   25948              : 
   25949              : static tree ATTRIBUTE_UNUSED
   25950          329 : ix86_stack_protect_fail (void)
   25951              : {
   25952          329 :   return TARGET_64BIT
   25953          329 :          ? default_external_stack_protect_fail ()
   25954            1 :          : default_hidden_stack_protect_fail ();
   25955              : }
   25956              : 
   25957              : /* Select a format to encode pointers in exception handling data.  CODE
   25958              :    is 0 for data, 1 for code labels, 2 for function pointers.  GLOBAL is
   25959              :    true if the symbol may be affected by dynamic relocations.
   25960              : 
   25961              :    ??? All x86 object file formats are capable of representing this.
   25962              :    After all, the relocation needed is the same as for the call insn.
   25963              :    Whether or not a particular assembler allows us to enter such, I
   25964              :    guess we'll have to see.  */
   25965              : 
   25966              : int
   25967       815679 : asm_preferred_eh_data_format (int code, int global)
   25968              : {
   25969              :   /* PE-COFF is effectively always -fPIC because of the .reloc section.  */
   25970       815679 :   if (flag_pic || TARGET_PECOFF || !ix86_direct_extern_access)
   25971              :     {
   25972        85479 :       int type = DW_EH_PE_sdata8;
   25973        85479 :       if (ptr_mode == SImode
   25974        71494 :           || ix86_cmodel == CM_SMALL_PIC
   25975        85565 :           || (ix86_cmodel == CM_MEDIUM_PIC && (global || code)))
   25976              :         type = DW_EH_PE_sdata4;
   25977       121396 :       return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type;
   25978              :     }
   25979              : 
   25980       730200 :   if (ix86_cmodel == CM_SMALL
   25981        18670 :       || (ix86_cmodel == CM_MEDIUM && code))
   25982       711543 :     return DW_EH_PE_udata4;
   25983              : 
   25984              :   return DW_EH_PE_absptr;
   25985              : }
   25986              : 
   25987              : /* Cost of constructing or destructing a vector in VECMODE from/to elements
   25988              :    of ELMODE.  */
   25989              : static int
   25990       789445 : ix86_vector_cd_cost (machine_mode vecmode, machine_mode elmode)
   25991              : {
   25992      1578890 :   if (GET_MODE_BITSIZE (vecmode) < 128)
   25993       545928 :     return ((GET_MODE_BITSIZE (vecmode) / GET_MODE_BITSIZE (elmode) - 1)
   25994       272964 :             * ix86_cost->sse_op);
   25995              : 
   25996       516481 :   int n = GET_MODE_BITSIZE (vecmode) / 128;
   25997       516481 :   int cost = 0;
   25998              :   /* Element inserts/extracts into/from N SSE vectors, the possible
   25999              :      GPR <-> XMM moves have to be accounted for elsewhere.  */
   26000      1032962 :   if (GET_MODE_BITSIZE (elmode) < 128)
   26001      1031716 :     cost += n * (128 / GET_MODE_BITSIZE (elmode) - 1) * ix86_cost->sse_op;
   26002       516481 :   if (GET_MODE_BITSIZE (vecmode) >= 256
   26003       526436 :       && GET_MODE_BITSIZE (elmode) < 256)
   26004              :     /* N/2 vinserti128/vextracti128 for SSE <-> AVX256.  */
   26005         9955 :     cost += n * ix86_vec_cost (V32QImode, ix86_cost->sse_op) / 2;
   26006      1032962 :   if (GET_MODE_BITSIZE (vecmode) == 512)
   26007              :     /* One vinserti64x4/vextracti64x4 for AVX256 <-> AVX512.  */
   26008         2048 :     cost += ix86_vec_cost (vecmode, ix86_cost->sse_op);
   26009              :   return cost;
   26010              : }
   26011              : 
   26012              : /* Worker for ix86_builtin_vectorization_cost and the fallback calls
   26013              :    from ix86_vector_costs::add_stmt_cost.  */
   26014              : static int
   26015     15968454 : ix86_default_vector_cost (enum vect_cost_for_stmt type_of_cost,
   26016              :                           machine_mode mode)
   26017              : {
   26018     15968454 :   bool fp = FLOAT_MODE_P (mode);
   26019     15968454 :   int index;
   26020     15968454 :   switch (type_of_cost)
   26021              :     {
   26022      1889240 :       case scalar_stmt:
   26023      1889240 :         return fp ? ix86_cost->addss : COSTS_N_INSNS (1);
   26024              : 
   26025      1897571 :       case scalar_load:
   26026              :         /* load/store costs are relative to register move which is 2. Recompute
   26027              :            it to COSTS_N_INSNS so everything have same base.  */
   26028      3795142 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_load[0]
   26029      1897571 :                               : ix86_cost->int_load [2]) / 2;
   26030              : 
   26031      4048918 :       case scalar_store:
   26032      8097836 :         return COSTS_N_INSNS (fp ? ix86_cost->sse_store[0]
   26033      4048918 :                               : ix86_cost->int_store [2]) / 2;
   26034              : 
   26035      1129063 :       case vector_stmt:
   26036      2258126 :         return ix86_vec_cost (mode,
   26037      2258126 :                               fp ? ix86_cost->addss : ix86_cost->sse_op);
   26038              : 
   26039      2020521 :       case vector_load:
   26040      2020521 :         index = sse_store_index (mode);
   26041              :         /* See PR82713 - we may end up being called on non-vector type.  */
   26042      2020521 :         if (index < 0)
   26043       104414 :           index = 2;
   26044      2020521 :         return COSTS_N_INSNS (ix86_cost->sse_load[index]) / 2;
   26045              : 
   26046      1007217 :       case vector_store:
   26047      1007217 :         index = sse_store_index (mode);
   26048              :         /* See PR82713 - we may end up being called on non-vector type.  */
   26049      1007217 :         if (index < 0)
   26050        94765 :           index = 2;
   26051      1007217 :         return COSTS_N_INSNS (ix86_cost->sse_store[index]) / 2;
   26052              : 
   26053       564892 :       case vec_to_scalar:
   26054              :         /* This is a lane extraction, possibly from lane zero.  */
   26055       564892 :         return (ix86_vec_cost (mode, ix86_cost->sse_op)
   26056       564892 :                 + (fp ? 0 : COSTS_N_INSNS (ix86_cost->sse_to_integer) / 2));
   26057              : 
   26058       490324 :       case scalar_to_vec:
   26059              :         /* This is always a full splat from scalar, not a lane insertion.  */
   26060       490324 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   26061              : 
   26062              :       /* We should have separate costs for unaligned loads and gather/scatter.
   26063              :          Do that incrementally.  */
   26064       534834 :       case unaligned_load:
   26065       534834 :         index = sse_store_index (mode);
   26066              :         /* See PR82713 - we may end up being called on non-vector type.  */
   26067       534834 :         if (index < 0)
   26068         3652 :           index = 2;
   26069       534834 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_load[index]) / 2;
   26070              : 
   26071       858066 :       case unaligned_store:
   26072       858066 :         index = sse_store_index (mode);
   26073              :         /* See PR82713 - we may end up being called on non-vector type.  */
   26074       858066 :         if (index < 0)
   26075        17343 :           index = 2;
   26076       858066 :         return COSTS_N_INSNS (ix86_cost->sse_unaligned_store[index]) / 2;
   26077              : 
   26078            0 :       case vector_gather_load:
   26079            0 :         return ix86_vec_cost (mode,
   26080            0 :                               COSTS_N_INSNS
   26081              :                                  (ix86_cost->gather_static
   26082              :                                   + ix86_cost->gather_per_elt
   26083            0 :                                     * GET_MODE_NUNITS (mode)) / 2);
   26084              : 
   26085            0 :       case vector_scatter_store:
   26086            0 :         return ix86_vec_cost (mode,
   26087            0 :                               COSTS_N_INSNS
   26088              :                                  (ix86_cost->scatter_static
   26089              :                                   + ix86_cost->scatter_per_elt
   26090            0 :                                     * GET_MODE_NUNITS (mode)) / 2);
   26091              : 
   26092       369962 :       case cond_branch_taken:
   26093       369962 :         return ix86_cost->cond_taken_branch_cost;
   26094              : 
   26095         8696 :       case cond_branch_not_taken:
   26096         8696 :         return ix86_cost->cond_not_taken_branch_cost;
   26097              : 
   26098       302881 :       case vec_perm:
   26099       302881 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   26100              : 
   26101        89894 :       case vec_promote_demote:
   26102        89894 :         if (fp)
   26103        11734 :           return vec_fp_conversion_cost (ix86_tune_cost, mode);
   26104        78160 :         return ix86_vec_cost (mode, ix86_cost->sse_op);
   26105              : 
   26106       756375 :       case vec_construct:
   26107       756375 :       case vec_deconstruct:
   26108      1512750 :         return ix86_vector_cd_cost (mode, GET_MODE_INNER (mode));
   26109              : 
   26110            0 :       default:
   26111            0 :         gcc_unreachable ();
   26112              :     }
   26113              : }
   26114              : 
   26115              : /* Implement targetm.vectorize.builtin_vectorization_cost.  */
   26116              : static int
   26117      9511836 : ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
   26118              :                                  tree vectype, int)
   26119              : {
   26120      9511836 :   machine_mode mode = TImode;
   26121      9511836 :   if (vectype != NULL)
   26122      5992692 :     mode = TYPE_MODE (vectype);
   26123      9511836 :   return ix86_default_vector_cost (type_of_cost, mode);
   26124              : }
   26125              : 
   26126              : 
   26127              : /* This function returns the calling abi specific va_list type node.
   26128              :    It returns  the FNDECL specific va_list type.  */
   26129              : 
   26130              : static tree
   26131        47669 : ix86_fn_abi_va_list (tree fndecl)
   26132              : {
   26133        47669 :   if (!TARGET_64BIT)
   26134          726 :     return va_list_type_node;
   26135        46943 :   gcc_assert (fndecl != NULL_TREE);
   26136              : 
   26137        46943 :   if (ix86_function_abi ((const_tree) fndecl) == MS_ABI)
   26138        12880 :     return ms_va_list_type_node;
   26139              :   else
   26140        34063 :     return sysv_va_list_type_node;
   26141              : }
   26142              : 
   26143              : /* Returns the canonical va_list type specified by TYPE. If there
   26144              :    is no valid TYPE provided, it return NULL_TREE.  */
   26145              : 
   26146              : static tree
   26147       247575 : ix86_canonical_va_list_type (tree type)
   26148              : {
   26149       247575 :   if (TARGET_64BIT)
   26150              :     {
   26151       247073 :       if (lookup_attribute ("ms_abi va_list", TYPE_ATTRIBUTES (type)))
   26152         5948 :         return ms_va_list_type_node;
   26153              : 
   26154       241125 :       if ((TREE_CODE (type) == ARRAY_TYPE
   26155        50159 :            && integer_zerop (array_type_nelts_minus_one (type)))
   26156       241125 :           || POINTER_TYPE_P (type))
   26157              :         {
   26158       189063 :           tree elem_type = TREE_TYPE (type);
   26159       189063 :           if (TREE_CODE (elem_type) == RECORD_TYPE
   26160       341158 :               && lookup_attribute ("sysv_abi va_list",
   26161       152095 :                                    TYPE_ATTRIBUTES (elem_type)))
   26162       152095 :             return sysv_va_list_type_node;
   26163              :         }
   26164              : 
   26165              :       return NULL_TREE;
   26166              :     }
   26167              : 
   26168          502 :   return std_canonical_va_list_type (type);
   26169              : }
   26170              : 
   26171              : /* Iterate through the target-specific builtin types for va_list.
   26172              :    IDX denotes the iterator, *PTREE is set to the result type of
   26173              :    the va_list builtin, and *PNAME to its internal type.
   26174              :    Returns zero if there is no element for this index, otherwise
   26175              :    IDX should be increased upon the next call.
   26176              :    Note, do not iterate a base builtin's name like __builtin_va_list.
   26177              :    Used from c_common_nodes_and_builtins.  */
   26178              : 
   26179              : static int
   26180       632184 : ix86_enum_va_list (int idx, const char **pname, tree *ptree)
   26181              : {
   26182       632184 :   if (TARGET_64BIT)
   26183              :     {
   26184       626808 :       switch (idx)
   26185              :         {
   26186              :         default:
   26187              :           break;
   26188              : 
   26189       208936 :         case 0:
   26190       208936 :           *ptree = ms_va_list_type_node;
   26191       208936 :           *pname = "__builtin_ms_va_list";
   26192       208936 :           return 1;
   26193              : 
   26194       208936 :         case 1:
   26195       208936 :           *ptree = sysv_va_list_type_node;
   26196       208936 :           *pname = "__builtin_sysv_va_list";
   26197       208936 :           return 1;
   26198              :         }
   26199              :     }
   26200              : 
   26201              :   return 0;
   26202              : }
   26203              : 
   26204              : #undef TARGET_SCHED_DISPATCH
   26205              : #define TARGET_SCHED_DISPATCH ix86_bd_has_dispatch
   26206              : #undef TARGET_SCHED_DISPATCH_DO
   26207              : #define TARGET_SCHED_DISPATCH_DO ix86_bd_do_dispatch
   26208              : #undef TARGET_SCHED_REASSOCIATION_WIDTH
   26209              : #define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
   26210              : #undef TARGET_SCHED_REORDER
   26211              : #define TARGET_SCHED_REORDER ix86_atom_sched_reorder
   26212              : #undef TARGET_SCHED_ADJUST_PRIORITY
   26213              : #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
   26214              : #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
   26215              : #define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
   26216              :   ix86_dependencies_evaluation_hook
   26217              : 
   26218              : 
   26219              : /* Implementation of reassociation_width target hook used by
   26220              :    reassoc phase to identify parallelism level in reassociated
   26221              :    tree.  Statements tree_code is passed in OPC.  Arguments type
   26222              :    is passed in MODE.  */
   26223              : 
   26224              : static int
   26225        25994 : ix86_reassociation_width (tree_code op, machine_mode mode)
   26226              : {
   26227        25994 :   int width = 1;
   26228              :   /* Vector part.  */
   26229        25994 :   if (VECTOR_MODE_P (mode))
   26230              :     {
   26231         8735 :       int div = 1;
   26232         8735 :       if (INTEGRAL_MODE_P (mode))
   26233         2814 :         width = ix86_cost->reassoc_vec_int;
   26234         5921 :       else if (FLOAT_MODE_P (mode))
   26235         5921 :         width = ix86_cost->reassoc_vec_fp;
   26236              : 
   26237         8735 :       if (width == 1)
   26238              :         return 1;
   26239              : 
   26240              :       /* Znver1-4 Integer vector instructions execute in FP unit
   26241              :          and can execute 3 additions and one multiplication per cycle.  */
   26242         8730 :       if ((ix86_tune == PROCESSOR_ZNVER1 || ix86_tune == PROCESSOR_ZNVER2
   26243         8730 :            || ix86_tune == PROCESSOR_ZNVER3 || ix86_tune == PROCESSOR_ZNVER4
   26244         8730 :            || ix86_tune == PROCESSOR_C86_4G_M4
   26245         8730 :            || ix86_tune == PROCESSOR_C86_4G_M6
   26246         8730 :            || ix86_tune == PROCESSOR_C86_4G_M7
   26247         8728 :            || ix86_tune == PROCESSOR_C86_4G_M8)
   26248            2 :           && INTEGRAL_MODE_P (mode) && op != PLUS_EXPR && op != MINUS_EXPR)
   26249              :         return 1;
   26250              :       /* Znver5 can do 2 integer multiplications per cycle with latency
   26251              :          of 3.  */
   26252         8730 :       if ((ix86_tune == PROCESSOR_ZNVER5 || ix86_tune == PROCESSOR_ZNVER6)
   26253            0 :           && INTEGRAL_MODE_P (mode) && op != PLUS_EXPR && op != MINUS_EXPR)
   26254         8730 :         width = 6;
   26255              : 
   26256              :       /* Account for targets that splits wide vectors into multiple parts.  */
   26257         8732 :       if (TARGET_AVX512_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 256)
   26258            0 :         div = GET_MODE_BITSIZE (mode) / 256;
   26259         8730 :       else if (TARGET_AVX256_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 128)
   26260            0 :         div = GET_MODE_BITSIZE (mode) / 128;
   26261         8730 :       else if (TARGET_SSE_SPLIT_REGS && GET_MODE_BITSIZE (mode) > 64)
   26262            0 :         div = GET_MODE_BITSIZE (mode) / 64;
   26263         8730 :       width = (width + div - 1) / div;
   26264         8730 :     }
   26265              :   /* Scalar part.  */
   26266              :   else if (INTEGRAL_MODE_P (mode))
   26267        11651 :     width = ix86_cost->reassoc_int;
   26268              :   else if (FLOAT_MODE_P (mode))
   26269         5608 :     width = ix86_cost->reassoc_fp;
   26270              : 
   26271              :   /* Avoid using too many registers in 32bit mode.  */
   26272        25989 :   if (!TARGET_64BIT && width > 2)
   26273        25994 :     width = 2;
   26274              :   return width;
   26275              : }
   26276              : 
   26277              : /* ??? No autovectorization into MMX or 3DNOW until we can reliably
   26278              :    place emms and femms instructions.  */
   26279              : 
   26280              : static machine_mode
   26281      5502013 : ix86_preferred_simd_mode (scalar_mode mode)
   26282              : {
   26283      5502013 :   if (!TARGET_SSE)
   26284          873 :     return word_mode;
   26285              : 
   26286      5501140 :   switch (mode)
   26287              :     {
   26288       463525 :     case E_QImode:
   26289       463525 :       if (TARGET_AVX512BW && !TARGET_PREFER_AVX256)
   26290              :         return V64QImode;
   26291       450121 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26292              :         return V32QImode;
   26293              :       else
   26294       428068 :         return V16QImode;
   26295              : 
   26296       223178 :     case E_HImode:
   26297       223178 :       if (TARGET_AVX512BW && !TARGET_PREFER_AVX256)
   26298              :         return V32HImode;
   26299       211927 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26300              :         return V16HImode;
   26301              :       else
   26302       193105 :         return V8HImode;
   26303              : 
   26304      1641229 :     case E_SImode:
   26305      1641229 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26306              :         return V16SImode;
   26307      1571831 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26308              :         return V8SImode;
   26309              :       else
   26310      1417470 :         return V4SImode;
   26311              : 
   26312      1936381 :     case E_DImode:
   26313      1936381 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26314              :         return V8DImode;
   26315      1521528 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26316              :         return V4DImode;
   26317              :       else
   26318      1453744 :         return V2DImode;
   26319              : 
   26320       144983 :     case E_HFmode:
   26321       144983 :       if (TARGET_AVX512FP16)
   26322              :         {
   26323       142753 :           if (TARGET_AVX512VL)
   26324              :             {
   26325        69581 :               if (TARGET_PREFER_AVX128)
   26326              :                 return V8HFmode;
   26327        69351 :               else if (TARGET_PREFER_AVX256)
   26328              :                 return V16HFmode;
   26329              :             }
   26330       139971 :           return V32HFmode;
   26331              :         }
   26332         2230 :       return word_mode;
   26333              : 
   26334        63439 :     case E_BFmode:
   26335        63439 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26336              :         return V32BFmode;
   26337        26748 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26338              :         return V16BFmode;
   26339              :       else
   26340        13617 :         return V8BFmode;
   26341              : 
   26342       669242 :     case E_SFmode:
   26343       669242 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26344              :         return V16SFmode;
   26345       464662 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26346              :         return V8SFmode;
   26347              :       else
   26348       393143 :         return V4SFmode;
   26349              : 
   26350       319895 :     case E_DFmode:
   26351       319895 :       if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26352              :         return V8DFmode;
   26353       198159 :       else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26354              :         return V4DFmode;
   26355       139589 :       else if (TARGET_SSE2)
   26356              :         return V2DFmode;
   26357              :       /* FALLTHRU */
   26358              : 
   26359        39330 :     default:
   26360        39330 :       return word_mode;
   26361              :     }
   26362              : }
   26363              : 
   26364              : /* If AVX is enabled then try vectorizing with both 256bit and 128bit
   26365              :    vectors.  If AVX512F is enabled then try vectorizing with 512bit,
   26366              :    256bit and 128bit vectors.  */
   26367              : 
   26368              : static unsigned int
   26369      2300391 : ix86_autovectorize_vector_modes (vector_modes *modes, bool all)
   26370              : {
   26371      2300391 :   if (TARGET_AVX512F && !TARGET_PREFER_AVX256)
   26372              :     {
   26373        76295 :       modes->safe_push (V64QImode);
   26374        76295 :       modes->safe_push (V32QImode);
   26375        76295 :       modes->safe_push (V16QImode);
   26376              :     }
   26377      2224096 :   else if (TARGET_AVX512F && all)
   26378              :     {
   26379          574 :       modes->safe_push (V32QImode);
   26380          574 :       modes->safe_push (V16QImode);
   26381          574 :       modes->safe_push (V64QImode);
   26382              :     }
   26383      2223522 :   else if (TARGET_AVX && !TARGET_PREFER_AVX128)
   26384              :     {
   26385        28741 :       modes->safe_push (V32QImode);
   26386        28741 :       modes->safe_push (V16QImode);
   26387              :     }
   26388      2194781 :   else if (TARGET_AVX && all)
   26389              :     {
   26390           24 :       modes->safe_push (V16QImode);
   26391           24 :       modes->safe_push (V32QImode);
   26392              :     }
   26393      2194757 :   else if (TARGET_SSE2)
   26394      2192395 :     modes->safe_push (V16QImode);
   26395              : 
   26396      2300391 :   if (TARGET_MMX_WITH_SSE)
   26397      1905908 :     modes->safe_push (V8QImode);
   26398              : 
   26399      2300391 :   if (TARGET_SSE2)
   26400      2298029 :     modes->safe_push (V4QImode);
   26401              : 
   26402      2300391 :   return ix86_vect_compare_costs ? VECT_COMPARE_COSTS : 0;
   26403              : }
   26404              : 
   26405              : /* Implementation of targetm.vectorize.get_mask_mode.  */
   26406              : 
   26407              : static opt_machine_mode
   26408      3583726 : ix86_get_mask_mode (machine_mode data_mode)
   26409              : {
   26410      3583726 :   unsigned vector_size = GET_MODE_SIZE (data_mode);
   26411      3583726 :   unsigned nunits = GET_MODE_NUNITS (data_mode);
   26412      3583726 :   unsigned elem_size = vector_size / nunits;
   26413              : 
   26414              :   /* Scalar mask case.  */
   26415       483208 :   if ((TARGET_AVX512F && vector_size == 64)
   26416      3467557 :       || (TARGET_AVX512VL && (vector_size == 32 || vector_size == 16))
   26417              :       /* AVX512FP16 only supports vector comparison
   26418              :          to kmask for _Float16.  */
   26419      3291471 :       || (TARGET_AVX512VL && TARGET_AVX512FP16
   26420        18413 :           && GET_MODE_INNER (data_mode) == E_HFmode)
   26421      6879928 :       || (TARGET_AVX10_2 && GET_MODE_INNER (data_mode) == E_BFmode))
   26422              :     {
   26423       295283 :       if (elem_size == 4
   26424       295283 :           || elem_size == 8
   26425       136103 :           || (TARGET_AVX512BW && (elem_size == 1 || elem_size == 2)))
   26426       264006 :         return smallest_int_mode_for_size (nunits).require ();
   26427              :     }
   26428              : 
   26429      3319720 :   scalar_int_mode elem_mode
   26430      3319720 :     = smallest_int_mode_for_size (elem_size * BITS_PER_UNIT).require ();
   26431              : 
   26432      3319720 :   gcc_assert (elem_size * nunits == vector_size);
   26433              : 
   26434      3319720 :   return mode_for_vector (elem_mode, nunits);
   26435              : }
   26436              : 
   26437              : 
   26438              : 
   26439              : /* Return class of registers which could be used for pseudo of MODE
   26440              :    and of class RCLASS for spilling instead of memory.  Return NO_REGS
   26441              :    if it is not possible or non-profitable.  */
   26442              : 
   26443              : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   26444              : 
   26445              : static reg_class_t
   26446   6411135578 : ix86_spill_class (reg_class_t rclass, machine_mode mode)
   26447              : {
   26448   6411135578 :   if (0 && TARGET_GENERAL_REGS_SSE_SPILL
   26449              :       && TARGET_SSE2
   26450              :       && TARGET_INTER_UNIT_MOVES_TO_VEC
   26451              :       && TARGET_INTER_UNIT_MOVES_FROM_VEC
   26452              :       && (mode == SImode || (TARGET_64BIT && mode == DImode))
   26453              :       && INTEGER_CLASS_P (rclass))
   26454              :     return ALL_SSE_REGS;
   26455   6411135578 :   return NO_REGS;
   26456              : }
   26457              : 
   26458              : /* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  Like the default implementation,
   26459              :    but returns a lower bound.  */
   26460              : 
   26461              : static unsigned int
   26462      1930139 : ix86_max_noce_ifcvt_seq_cost (edge e)
   26463              : {
   26464      1930139 :   bool predictable_p = predictable_edge_p (e);
   26465      1930139 :   if (predictable_p)
   26466              :     {
   26467       146340 :       if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
   26468            8 :         return param_max_rtl_if_conversion_predictable_cost;
   26469              :     }
   26470              :   else
   26471              :     {
   26472      1783799 :       if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
   26473           69 :         return param_max_rtl_if_conversion_unpredictable_cost;
   26474              :     }
   26475              : 
   26476              :   /* For modern machines with deeper pipeline, the penalty for branch
   26477              :      misprediction could be higher than before to reset the pipeline
   26478              :      slots. Add parameter br_mispredict_scale as a factor to describe
   26479              :      the impact of resetting the pipeline.  */
   26480              : 
   26481      1930062 :   return BRANCH_COST (true, predictable_p)
   26482      1930062 :          * ix86_tune_cost->br_mispredict_scale;
   26483              : }
   26484              : 
   26485              : /* Return true if SEQ is a good candidate as a replacement for the
   26486              :    if-convertible sequence described in IF_INFO.  */
   26487              : 
   26488              : static bool
   26489       199062 : ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
   26490              : {
   26491       199062 :   if (TARGET_ONE_IF_CONV_INSN && if_info->speed_p)
   26492              :     {
   26493              :       int cmov_cnt = 0;
   26494              :       /* Punt if SEQ contains more than one CMOV or FCMOV instruction.
   26495              :          Maybe we should allow even more conditional moves as long as they
   26496              :          are used far enough not to stall the CPU, or also consider
   26497              :          IF_INFO->TEST_BB succ edge probabilities.  */
   26498          411 :       for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
   26499              :         {
   26500          342 :           rtx set = single_set (insn);
   26501          342 :           if (!set)
   26502            0 :             continue;
   26503          342 :           if (GET_CODE (SET_SRC (set)) != IF_THEN_ELSE)
   26504          299 :             continue;
   26505           43 :           rtx src = SET_SRC (set);
   26506           43 :           machine_mode mode = GET_MODE (src);
   26507           43 :           if (GET_MODE_CLASS (mode) != MODE_INT
   26508            0 :               && GET_MODE_CLASS (mode) != MODE_FLOAT)
   26509            0 :             continue;
   26510           43 :           if ((!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
   26511           42 :               || (!REG_P (XEXP (src, 2)) && !MEM_P (XEXP (src, 2))))
   26512            1 :             continue;
   26513              :           /* insn is CMOV or FCMOV.  */
   26514           42 :           if (++cmov_cnt > 1)
   26515              :             return false;
   26516              :         }
   26517              :     }
   26518              : 
   26519              :   /* W/o TARGET_SSE4_1, it takes 3 instructions (pand, pandn and por)
   26520              :      for movdfcc/movsfcc, and could possibly fail cost comparison.
   26521              :      Increase branch cost will hurt performance for other modes, so
   26522              :      specially add some preference for floating point ifcvt.  */
   26523       199053 :   if (!TARGET_SSE4_1 && if_info->x
   26524       143296 :       && GET_MODE_CLASS (GET_MODE (if_info->x)) == MODE_FLOAT
   26525        17958 :       && if_info->speed_p)
   26526              :     {
   26527        11002 :       unsigned cost = seq_cost (seq, true);
   26528              : 
   26529        11002 :       if (cost <= if_info->original_cost)
   26530              :         return true;
   26531              : 
   26532         9742 :       return cost <= (if_info->max_seq_cost + COSTS_N_INSNS (2));
   26533              :     }
   26534              : 
   26535       188051 :   return default_noce_conversion_profitable_p (seq, if_info);
   26536              : }
   26537              : 
   26538              : /* x86-specific vector costs.  */
   26539              : class ix86_vector_costs : public vector_costs
   26540              : {
   26541              : public:
   26542              :   ix86_vector_costs (vec_info *, bool);
   26543              : 
   26544              :   unsigned int add_stmt_cost (int count, vect_cost_for_stmt kind,
   26545              :                               stmt_vec_info stmt_info, slp_tree node,
   26546              :                               tree vectype, int misalign,
   26547              :                               vect_cost_model_location where) override;
   26548              :   unsigned int add_slp_cost (slp_tree, const array_slice<stmt_info_for_cost> &);
   26549              :   void finish_cost (const vector_costs *) override;
   26550              :   bool better_main_loop_than_p (const vector_costs *) const override;
   26551              :   bool better_epilogue_loop_than_p (const vector_costs *other,
   26552              :                                     loop_vec_info main_loop) const override;
   26553              : 
   26554              : private:
   26555              : 
   26556              :   bool better_fold_left_reduc_than_p (const vector_costs *) const;
   26557              :   /* Estimate register pressure of the vectorized code.  */
   26558              :   void ix86_vect_estimate_reg_pressure ();
   26559              :   /* Number of GENERAL_REGS/SSE_REGS used in the vectorizer, it's used for
   26560              :      estimation of register pressure.
   26561              :      ??? Currently it's only used by vec_construct/scalar_to_vec
   26562              :      where we know it's not loaded from memory.  */
   26563              :   unsigned m_num_gpr_needed[3];
   26564              :   unsigned m_num_sse_needed[3];
   26565              :   /* Number of 256-bit vector permutation.  */
   26566              :   unsigned m_num_avx256_vec_perm[3];
   26567              :   /* Number of 512-bit vector permutation.  */
   26568              :   unsigned m_num_avx512_vec_perm[3];
   26569              :   /* Number of reductions for FMA/DOT_PROD_EXPR/SAD_EXPR  */
   26570              :   unsigned m_num_reduc[X86_REDUC_LAST];
   26571              :   /* Don't do unroll if m_prefer_unroll is false, default is true.  */
   26572              :   bool m_prefer_unroll;
   26573              :   /* Scalar lanes in fold-left reductions.  */
   26574              :   unsigned int m_num_fold_left_reduc_lanes;
   26575              : };
   26576              : 
   26577      2269476 : ix86_vector_costs::ix86_vector_costs (vec_info* vinfo, bool costing_for_scalar)
   26578              :   : vector_costs (vinfo, costing_for_scalar),
   26579      2269476 :     m_num_gpr_needed (),
   26580      2269476 :     m_num_sse_needed (),
   26581      2269476 :     m_num_avx256_vec_perm (),
   26582      2269476 :     m_num_avx512_vec_perm (),
   26583      2269476 :     m_num_reduc (),
   26584      2269476 :     m_prefer_unroll (true),
   26585      2269476 :     m_num_fold_left_reduc_lanes (0)
   26586      2269476 : {}
   26587              : 
   26588              : /* Implement targetm.vectorize.create_costs.  */
   26589              : 
   26590              : static vector_costs *
   26591      2269476 : ix86_vectorize_create_costs (vec_info *vinfo, bool costing_for_scalar)
   26592              : {
   26593      2269476 :   return new ix86_vector_costs (vinfo, costing_for_scalar);
   26594              : }
   26595              : 
   26596              : /* Return true if a vec_perm should be counted as a cross-lane vector
   26597              :    permutation for a vector with NUNITS elements.  */
   26598              : static bool
   26599         5356 : ix86_count_cross_lane_perm_p (vec_info *vinfo, slp_tree node, unsigned nunits)
   26600              : {
   26601              :   /* TODO: For loop vectorization with no SLP load-permutation
   26602              :      information, conservatively treat these perms as cross-lane.
   26603              :      Repeated-index cases such as {0, 0, 0, 0} are emitted as
   26604              :      separate vec_perm_exprs for each index, so we cannot reliably
   26605              :      separate false positives from real cross-lane shuffles yet.  */
   26606         5356 :   if (!node
   26607         5329 :       || !SLP_TREE_LOAD_PERMUTATION (node).exists ()
   26608         9636 :       || !is_a<bb_vec_info> (vinfo))
   26609              :     return true;
   26610              : 
   26611           41 :   unsigned half = nunits / 2;
   26612           41 :   bool allsame = true;
   26613           41 :   unsigned first = SLP_TREE_LOAD_PERMUTATION (node)[0];
   26614           41 :   bool cross_lane_p = false;
   26615              : 
   26616          217 :   for (unsigned i = 0; i != SLP_TREE_LANES (node); i++)
   26617              :     {
   26618          215 :       unsigned tmp = SLP_TREE_LOAD_PERMUTATION (node)[i];
   26619              :       /* allsame is just a broadcast.  */
   26620          215 :       if (tmp != first)
   26621          106 :         allsame = false;
   26622              : 
   26623              :       /* The load permutation can cover multiple vectors, so compare
   26624              :          source and destination lanes modulo NUNITS.  */
   26625          215 :       tmp = tmp & (nunits - 1);
   26626          215 :       unsigned index = i & (nunits - 1);
   26627          215 :       if ((index < half && tmp >= half) || (index >= half && tmp < half))
   26628           67 :         cross_lane_p = true;
   26629              : 
   26630          215 :       if (!allsame && cross_lane_p)
   26631              :         return true;
   26632              :     }
   26633              : 
   26634              :   return false;
   26635              : }
   26636              : 
   26637              : unsigned
   26638      8023840 : ix86_vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
   26639              :                                   stmt_vec_info stmt_info, slp_tree node,
   26640              :                                   tree vectype, int,
   26641              :                                   vect_cost_model_location where)
   26642              : {
   26643      8023840 :   unsigned retval = 0;
   26644      8023840 :   bool scalar_p
   26645              :     = (kind == scalar_stmt || kind == scalar_load || kind == scalar_store);
   26646      8023840 :   int stmt_cost = - 1;
   26647              : 
   26648      8023840 :   bool fp = false;
   26649      8023840 :   machine_mode mode = scalar_p ? SImode : TImode;
   26650              : 
   26651      8023840 :   if (vectype != NULL)
   26652              :     {
   26653      3694527 :       fp = FLOAT_TYPE_P (vectype);
   26654      3694527 :       mode = TYPE_MODE (vectype);
   26655      3694527 :       if (scalar_p)
   26656       287154 :         mode = TYPE_MODE (TREE_TYPE (vectype));
   26657              :     }
   26658              :   /* When we are costing a scalar stmt use the scalar stmt to get at the
   26659              :      type of the operation.  */
   26660      4329313 :   else if (scalar_p && stmt_info)
   26661      4245114 :     if (tree lhs = gimple_get_lhs (stmt_info->stmt))
   26662              :       {
   26663      4059036 :         fp = FLOAT_TYPE_P (TREE_TYPE (lhs));
   26664      4059036 :         mode = TYPE_MODE (TREE_TYPE (lhs));
   26665              :       }
   26666              : 
   26667      8023840 :   if ((kind == vector_stmt || kind == scalar_stmt)
   26668      2166211 :       && stmt_info
   26669     10180723 :       && stmt_info->stmt && gimple_code (stmt_info->stmt) == GIMPLE_ASSIGN)
   26670              :     {
   26671      1724639 :       tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
   26672              :       /*machine_mode inner_mode = mode;
   26673              :       if (VECTOR_MODE_P (mode))
   26674              :         inner_mode = GET_MODE_INNER (mode);*/
   26675              : 
   26676      1724639 :       switch (subcode)
   26677              :         {
   26678       688301 :         case PLUS_EXPR:
   26679       688301 :         case POINTER_PLUS_EXPR:
   26680       688301 :         case MINUS_EXPR:
   26681       688301 :           if (kind == scalar_stmt)
   26682              :             {
   26683       430163 :               if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26684        99806 :                 stmt_cost = ix86_cost->addss;
   26685       330357 :               else if (X87_FLOAT_MODE_P (mode))
   26686          155 :                 stmt_cost = ix86_cost->fadd;
   26687              :               else
   26688       330202 :                 stmt_cost = ix86_cost->add;
   26689              :             }
   26690              :           else
   26691       258138 :             stmt_cost = ix86_vec_cost (mode, fp ? ix86_cost->addss
   26692              :                                        : ix86_cost->sse_op);
   26693              :           break;
   26694              : 
   26695       267842 :         case MULT_EXPR:
   26696              :           /* For MULT_HIGHPART_EXPR, x86 only supports pmulhw,
   26697              :              take it as MULT_EXPR.  */
   26698       267842 :         case MULT_HIGHPART_EXPR:
   26699       267842 :           stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   26700       267842 :           break;
   26701              :           /* There's no direct instruction for WIDEN_MULT_EXPR,
   26702              :              take emulation into account.  */
   26703         1217 :         case WIDEN_MULT_EXPR:
   26704         2434 :           stmt_cost = ix86_widen_mult_cost (ix86_cost, mode,
   26705         1217 :                                             TYPE_UNSIGNED (vectype));
   26706         1217 :           break;
   26707              : 
   26708        11370 :         case NEGATE_EXPR:
   26709        11370 :           if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26710         3563 :             stmt_cost = ix86_cost->sse_op;
   26711         7807 :           else if (X87_FLOAT_MODE_P (mode))
   26712            0 :             stmt_cost = ix86_cost->fchs;
   26713         7807 :           else if (VECTOR_MODE_P (mode))
   26714         3866 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26715              :           else
   26716         3941 :             stmt_cost = ix86_cost->add;
   26717              :           break;
   26718        15432 :         case TRUNC_DIV_EXPR:
   26719        15432 :         case CEIL_DIV_EXPR:
   26720        15432 :         case FLOOR_DIV_EXPR:
   26721        15432 :         case ROUND_DIV_EXPR:
   26722        15432 :         case TRUNC_MOD_EXPR:
   26723        15432 :         case CEIL_MOD_EXPR:
   26724        15432 :         case FLOOR_MOD_EXPR:
   26725        15432 :         case RDIV_EXPR:
   26726        15432 :         case ROUND_MOD_EXPR:
   26727        15432 :         case EXACT_DIV_EXPR:
   26728        15432 :           stmt_cost = ix86_division_cost (ix86_cost, mode);
   26729        15432 :           break;
   26730              : 
   26731        84021 :         case RSHIFT_EXPR:
   26732        84021 :         case LSHIFT_EXPR:
   26733        84021 :         case LROTATE_EXPR:
   26734        84021 :         case RROTATE_EXPR:
   26735        84021 :           {
   26736        84021 :             tree op1 = gimple_assign_rhs1 (stmt_info->stmt);
   26737        84021 :             tree op2 = gimple_assign_rhs2 (stmt_info->stmt);
   26738        84021 :             stmt_cost = ix86_shift_rotate_cost
   26739        84021 :                            (ix86_cost,
   26740              :                             (subcode == RSHIFT_EXPR
   26741        42753 :                              && !TYPE_UNSIGNED (TREE_TYPE (op1)))
   26742              :                             ? ASHIFTRT : LSHIFTRT, mode,
   26743        84021 :                             TREE_CODE (op2) == INTEGER_CST,
   26744        84021 :                             cst_and_fits_in_hwi (op2)
   26745        52565 :                             ? int_cst_value (op2) : -1,
   26746              :                             false, false, NULL, NULL);
   26747              :           }
   26748        84021 :           break;
   26749       105722 :         case NOP_EXPR:
   26750              :           /* Only sign-conversions are free.  */
   26751       105722 :           if (tree_nop_conversion_p
   26752       105722 :                 (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt)),
   26753       105722 :                  TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))))
   26754              :             stmt_cost = 0;
   26755       105722 :           else if (fp)
   26756        10479 :             stmt_cost = vec_fp_conversion_cost
   26757        10479 :                           (ix86_tune_cost, GET_MODE_BITSIZE (mode));
   26758              :           break;
   26759              : 
   26760        23657 :         case FLOAT_EXPR:
   26761        23657 :             if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26762        17724 :               stmt_cost = ix86_cost->cvtsi2ss;
   26763         5933 :             else if (X87_FLOAT_MODE_P (mode))
   26764              :               /* TODO: We do not have cost tables for x87.  */
   26765           50 :               stmt_cost = ix86_cost->fadd;
   26766              :             else
   26767         5883 :               stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtpi2ps);
   26768              :             break;
   26769              : 
   26770         2459 :         case FIX_TRUNC_EXPR:
   26771         2459 :             if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26772            0 :               stmt_cost = ix86_cost->cvtss2si;
   26773         2459 :             else if (X87_FLOAT_MODE_P (mode))
   26774              :               /* TODO: We do not have cost tables for x87.  */
   26775            0 :               stmt_cost = ix86_cost->fadd;
   26776              :             else
   26777         2459 :               stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtps2pi);
   26778              :             break;
   26779              : 
   26780        56788 :         case COND_EXPR:
   26781        56788 :           {
   26782              :             /* SSE2 conditinal move sequence is:
   26783              :                  pcmpgtd %xmm5, %xmm0 (accounted separately)
   26784              :                  pand    %xmm0, %xmm2
   26785              :                  pandn   %xmm1, %xmm0
   26786              :                  por     %xmm2, %xmm0
   26787              :                while SSE4 uses cmp + blend
   26788              :                and AVX512 masked moves.
   26789              : 
   26790              :                The condition is accounted separately since we usually have
   26791              :                  p = a < b
   26792              :                  c = p ? x : y
   26793              :                and we will account first statement as setcc.  Exception is when
   26794              :                p is loaded from memory as bool and then we will not account
   26795              :                the compare, but there is no way to check for this.  */
   26796              : 
   26797        56788 :             int ninsns = TARGET_SSE4_1 ? 1 : 3;
   26798              : 
   26799              :             /* If one of parameters is 0 or -1 the sequence will be simplified:
   26800              :                (if_true & mask) | (if_false & ~mask) -> if_true & mask  */
   26801        24070 :             if (ninsns > 1
   26802        24070 :                 && (zerop (gimple_assign_rhs2 (stmt_info->stmt))
   26803        23734 :                     || zerop (gimple_assign_rhs3 (stmt_info->stmt))
   26804        13577 :                     || integer_minus_onep
   26805        13577 :                         (gimple_assign_rhs2 (stmt_info->stmt))
   26806        13290 :                     || integer_minus_onep
   26807        13290 :                         (gimple_assign_rhs3 (stmt_info->stmt))))
   26808              :               ninsns = 1;
   26809              : 
   26810        56788 :             if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26811         5072 :               stmt_cost = ninsns * ix86_cost->sse_op;
   26812        51716 :             else if (X87_FLOAT_MODE_P (mode))
   26813              :               /* x87 requires conditional branch.  We don't have cost for
   26814              :                  that.  */
   26815              :               ;
   26816        51707 :             else if (VECTOR_MODE_P (mode))
   26817        21728 :               stmt_cost = ix86_vec_cost (mode, ninsns * ix86_cost->sse_op);
   26818              :             else
   26819              :               /* compare (accounted separately) + cmov.  */
   26820        29979 :               stmt_cost = ix86_cost->add;
   26821              :           }
   26822              :           break;
   26823              : 
   26824        37436 :         case MIN_EXPR:
   26825        37436 :         case MAX_EXPR:
   26826        37436 :           if (fp)
   26827              :             {
   26828         1507 :               if (X87_FLOAT_MODE_P (mode)
   26829          533 :                   && !SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26830              :                 /* x87 requires conditional branch.  We don't have cost for
   26831              :                    that.  */
   26832              :                 ;
   26833              :               else
   26834              :                 /* minss  */
   26835         1507 :                 stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26836              :             }
   26837              :           else
   26838              :             {
   26839        35929 :               if (VECTOR_MODE_P (mode))
   26840              :                 {
   26841        10453 :                   stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26842              :                   /* vpmin was introduced in SSE3.
   26843              :                      SSE2 needs pcmpgtd + pand + pandn + pxor.
   26844              :                      If one of parameters is 0 or -1 the sequence is simplified
   26845              :                      to pcmpgtd + pand.  */
   26846        10453 :                   if (!TARGET_SSSE3)
   26847              :                     {
   26848         8597 :                       if (zerop (gimple_assign_rhs2 (stmt_info->stmt))
   26849        15420 :                           || integer_minus_onep
   26850         6823 :                                 (gimple_assign_rhs2 (stmt_info->stmt)))
   26851         1774 :                         stmt_cost *= 2;
   26852              :                       else
   26853         6823 :                         stmt_cost *= 4;
   26854              :                     }
   26855              :                 }
   26856              :               else
   26857              :                 /* cmp + cmov.  */
   26858        25476 :                 stmt_cost = ix86_cost->add * 2;
   26859              :             }
   26860              :           break;
   26861              : 
   26862         1839 :         case ABS_EXPR:
   26863         1839 :         case ABSU_EXPR:
   26864         1839 :           if (fp)
   26865              :             {
   26866         1116 :               if (X87_FLOAT_MODE_P (mode)
   26867          601 :                   && !SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26868              :                 /* fabs.  */
   26869            0 :                 stmt_cost = ix86_cost->fabs;
   26870              :               else
   26871              :                 /* andss of sign bit.  */
   26872         1116 :                 stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26873              :             }
   26874              :           else
   26875              :             {
   26876          723 :               if (VECTOR_MODE_P (mode))
   26877              :                 {
   26878          116 :                   stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26879              :                   /* vabs was introduced in SSE3.
   26880              :                      SSE3 uses psrat + pxor + psub.  */
   26881          116 :                   if (!TARGET_SSSE3)
   26882           86 :                     stmt_cost *= 3;
   26883              :                 }
   26884              :               else
   26885              :                 /* neg + cmov.  */
   26886          607 :                 stmt_cost = ix86_cost->add * 2;
   26887              :             }
   26888              :           break;
   26889              : 
   26890       169093 :         case BIT_IOR_EXPR:
   26891       169093 :         case BIT_XOR_EXPR:
   26892       169093 :         case BIT_AND_EXPR:
   26893       169093 :         case BIT_NOT_EXPR:
   26894       169093 :           gcc_assert (!SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode)
   26895              :                       && !X87_FLOAT_MODE_P (mode));
   26896       169093 :           if (VECTOR_MODE_P (mode))
   26897        59140 :             stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26898              :           else
   26899       109953 :             stmt_cost = ix86_cost->add;
   26900              :           break;
   26901              : 
   26902       259462 :         default:
   26903       259462 :           if (TREE_CODE_CLASS (subcode) == tcc_comparison)
   26904              :             {
   26905       100637 :               tree op_type;
   26906       100637 :               if (kind == vector_stmt)
   26907        32841 :                 op_type = SLP_TREE_VECTYPE (SLP_TREE_CHILDREN (node)[0]);
   26908              :               else
   26909        67796 :                 op_type = vect_comparison_type (stmt_info);
   26910       100637 :               mode = TYPE_MODE (op_type);
   26911              : 
   26912       100637 :               if (SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (mode))
   26913              :                 /* CMPccS? insructions are cheap, so use sse_op.  While they
   26914              :                    produce a mask which may need to be turned to 0/1 by and,
   26915              :                    expect that this will be optimized away in a common case.  */
   26916         8494 :                 stmt_cost = ix86_cost->sse_op;
   26917        92143 :               else if (X87_FLOAT_MODE_P (mode))
   26918              :                 /* fcmp + setcc.  */
   26919           32 :                 stmt_cost = ix86_cost->fadd + ix86_cost->add;
   26920        92111 :               else if (VECTOR_MODE_P (mode))
   26921        32784 :                 stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   26922              :               else
   26923              :                 /* setcc.  */
   26924        59327 :                 stmt_cost = ix86_cost->add;
   26925              :               break;
   26926              :             }
   26927              :           break;
   26928              :         }
   26929              :     }
   26930              : 
   26931              :   /* Record number of load/store/gather/scatter in vectorized body.  */
   26932      8023840 :   if (where == vect_body && !m_costing_for_scalar)
   26933              :     {
   26934      2213610 :       int scale = 1;
   26935      2213610 :       if (vectype
   26936      4413269 :           && ((GET_MODE_SIZE (TYPE_MODE (vectype)) == 64
   26937        60076 :               && TARGET_AVX512_SPLIT_REGS)
   26938      4399016 :               || (GET_MODE_SIZE (TYPE_MODE (vectype)) == 32
   26939       119168 :                   && TARGET_AVX256_SPLIT_REGS)))
   26940              :         scale = 2;
   26941              : 
   26942      2213610 :       switch (kind)
   26943              :         {
   26944              :           /* Emulated gather/scatter or any scalarization.  */
   26945       118315 :         case scalar_load:
   26946       118315 :         case scalar_stmt:
   26947       118315 :         case scalar_store:
   26948       118315 :         case vector_gather_load:
   26949       118315 :         case vector_scatter_store:
   26950       118315 :           m_prefer_unroll = false;
   26951       118315 :           break;
   26952              : 
   26953       765018 :         case vector_stmt:
   26954       765018 :         case vec_to_scalar:
   26955              :           /* Count number of reduction FMA and "real" DOT_PROD_EXPR,
   26956              :              unroll in the vectorizer will enable partial sum.  */
   26957       765018 :           if (stmt_info
   26958       763056 :               && vect_is_reduction (stmt_info)
   26959       834765 :               && stmt_info->stmt)
   26960              :             {
   26961              :               /* Handle __builtin_fma.  */
   26962        69747 :               if (gimple_call_combined_fn (stmt_info->stmt) == CFN_FMA)
   26963              :                 {
   26964           11 :                   m_num_reduc[X86_REDUC_FMA] += count * scale;
   26965           11 :                   break;
   26966              :                 }
   26967              : 
   26968        69736 :               if (!is_gimple_assign (stmt_info->stmt))
   26969              :                 break;
   26970              : 
   26971        66970 :               tree_code subcode = gimple_assign_rhs_code (stmt_info->stmt);
   26972        66970 :               machine_mode inner_mode = GET_MODE_INNER (mode);
   26973        66970 :               tree rhs1, rhs2;
   26974        66970 :               bool native_vnni_p = true;
   26975        66970 :               gimple* def;
   26976        66970 :               machine_mode mode_rhs;
   26977        66970 :               switch (subcode)
   26978              :                 {
   26979        50091 :                 case PLUS_EXPR:
   26980        50091 :                 case MINUS_EXPR:
   26981        50091 :                   if (!fp || !flag_associative_math
   26982        26428 :                       || flag_fp_contract_mode != FP_CONTRACT_FAST)
   26983              :                     break;
   26984              : 
   26985              :                   /* FMA condition for different modes.  */
   26986        26428 :                   if (((inner_mode == DFmode || inner_mode == SFmode)
   26987        26398 :                        && !TARGET_FMA && !TARGET_AVX512VL)
   26988         8622 :                       || (inner_mode == HFmode && !TARGET_AVX512FP16)
   26989         8622 :                       || (inner_mode == BFmode && !TARGET_AVX10_2))
   26990              :                     break;
   26991              : 
   26992              :                   /* MULT_EXPR + PLUS_EXPR/MINUS_EXPR is transformed
   26993              :                      to FMA/FNMA after vectorization.  */
   26994         8622 :                   rhs1 = gimple_assign_rhs1 (stmt_info->stmt);
   26995         8622 :                   rhs2 = gimple_assign_rhs2 (stmt_info->stmt);
   26996         8622 :                   if (subcode == PLUS_EXPR
   26997         6769 :                       && TREE_CODE (rhs1) == SSA_NAME
   26998         6769 :                       && (def = SSA_NAME_DEF_STMT (rhs1), true)
   26999         6769 :                       && is_gimple_assign (def)
   27000        12025 :                       && gimple_assign_rhs_code (def) == MULT_EXPR)
   27001         1992 :                     m_num_reduc[X86_REDUC_FMA] += count * scale;
   27002         6630 :                   else if (TREE_CODE (rhs2) == SSA_NAME
   27003         6630 :                            && (def = SSA_NAME_DEF_STMT (rhs2), true)
   27004         6630 :                            && is_gimple_assign (def)
   27005        13173 :                            && gimple_assign_rhs_code (def) == MULT_EXPR)
   27006         6537 :                     m_num_reduc[X86_REDUC_FMA] += count * scale;
   27007              :                   break;
   27008              : 
   27009              :                   /* Vectorizer lane_reducing_op_p supports DOT_PROX_EXPR,
   27010              :                      WIDEN_SUM_EXPR and SAD_EXPR, x86 backend only supports
   27011              :                      SAD_EXPR (usad{v16qi,v32qi,v64qi}) and DOT_PROD_EXPR.  */
   27012          628 :                 case DOT_PROD_EXPR:
   27013          628 :                   rhs1 = gimple_assign_rhs1 (stmt_info->stmt);
   27014          628 :                   mode_rhs = TYPE_MODE (TREE_TYPE (rhs1));
   27015          628 :                   if (mode_rhs == QImode)
   27016              :                     {
   27017          355 :                       rhs2 = gimple_assign_rhs2 (stmt_info->stmt);
   27018          355 :                       signop signop1_p = TYPE_SIGN (TREE_TYPE (rhs1));
   27019          355 :                       signop signop2_p = TYPE_SIGN (TREE_TYPE (rhs2));
   27020              : 
   27021              :                       /* vpdpbusd.  */
   27022          355 :                       if (signop1_p != signop2_p)
   27023           88 :                         native_vnni_p
   27024           88 :                           = (GET_MODE_SIZE (mode) == 64
   27025           88 :                              ? TARGET_AVX512VNNI
   27026           28 :                              : ((TARGET_AVX512VNNI && TARGET_AVX512VL)
   27027           88 :                                 || TARGET_AVXVNNI));
   27028              :                       else
   27029              :                         /* vpdpbssd.  */
   27030          267 :                         native_vnni_p
   27031          283 :                           = (GET_MODE_SIZE (mode) == 64
   27032          267 :                              ? TARGET_AVX10_2
   27033          251 :                              : (TARGET_AVXVNNIINT8 || TARGET_AVX10_2));
   27034              :                     }
   27035          628 :                   m_num_reduc[X86_REDUC_DOT_PROD] += count * scale;
   27036              : 
   27037              :                   /* Dislike to do unroll and partial sum for
   27038              :                      emulated DOT_PROD_EXPR.  */
   27039          628 :                   if (!native_vnni_p)
   27040          171 :                     m_num_reduc[X86_REDUC_DOT_PROD] += 3 * count;
   27041              :                   break;
   27042              : 
   27043          112 :                 case SAD_EXPR:
   27044          112 :                   m_num_reduc[X86_REDUC_SAD] += count * scale;
   27045          112 :                   break;
   27046              : 
   27047              :                 default:
   27048              :                   break;
   27049              :                 }
   27050              :             }
   27051              : 
   27052              :         default:
   27053              :           break;
   27054              :         }
   27055              :     }
   27056              : 
   27057              : 
   27058      8023840 :   combined_fn cfn;
   27059      8023840 :   if ((kind == vector_stmt || kind == scalar_stmt)
   27060      2166211 :       && stmt_info
   27061      2156883 :       && stmt_info->stmt
   27062     10180723 :       && is_gimple_call (stmt_info->stmt))
   27063              :     {
   27064        26928 :       tree fndecl = gimple_call_fndecl (stmt_info->stmt);
   27065        26928 :       cgraph_node *node;
   27066        26928 :       if ((fndecl
   27067         5595 :            && (node = cgraph_node::get (fndecl))
   27068         5566 :            && node->simd_clones)
   27069        31518 :           || gimple_call_internal_p (stmt_info->stmt, IFN_MASK_CALL))
   27070         2460 :         stmt_cost = 10 * ix86_vec_cost (mode,
   27071         1230 :                                         mode == SFmode ? ix86_cost->fmass
   27072              :                                         : ix86_cost->fmasd);
   27073        25698 :       else if ((cfn = gimple_call_combined_fn (stmt_info->stmt)) != CFN_LAST)
   27074        24318 :         switch (cfn)
   27075              :           {
   27076          107 :           case CFN_FMA:
   27077          107 :             stmt_cost = ix86_vec_cost (mode,
   27078          107 :                                        mode == SFmode ? ix86_cost->fmass
   27079              :                                        : ix86_cost->fmasd);
   27080          107 :             break;
   27081           62 :           case CFN_MULH:
   27082           62 :             stmt_cost = ix86_multiplication_cost (ix86_cost, mode);
   27083           62 :             break;
   27084              :           default:
   27085              :             break;
   27086              :           }
   27087              :     }
   27088              : 
   27089      8023840 :   if (kind == vec_promote_demote)
   27090              :     {
   27091        62191 :       int outer_size
   27092              :         = tree_to_uhwi
   27093        62191 :             (TYPE_SIZE
   27094        62191 :                 (TREE_TYPE (gimple_assign_lhs (stmt_info->stmt))));
   27095        62191 :       int inner_size
   27096              :         = tree_to_uhwi
   27097        62191 :             (TYPE_SIZE
   27098        62191 :                 (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt))));
   27099        62191 :       bool inner_fp = FLOAT_TYPE_P
   27100              :                         (TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt)));
   27101              : 
   27102         5638 :       if (fp && inner_fp)
   27103         5128 :         stmt_cost = vec_fp_conversion_cost
   27104         5128 :                           (ix86_tune_cost, GET_MODE_BITSIZE (mode));
   27105        57063 :       else if (fp && !inner_fp)
   27106         6151 :         stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtpi2ps);
   27107        50912 :       else if (!fp && inner_fp)
   27108          510 :         stmt_cost = ix86_vec_cost (mode, ix86_cost->cvtps2pi);
   27109              :       else
   27110        50402 :         stmt_cost = ix86_vec_cost (mode, ix86_cost->sse_op);
   27111              :       /* VEC_PACK_TRUNC_EXPR and similar demote operations: If outer size is
   27112              :          greater than inner size we will end up doing two conversions and
   27113              :          packing them.  We always pack pairs; if the size difference is greater
   27114              :          it is split into multiple demote operations.  */
   27115        62191 :       if (inner_size > outer_size)
   27116        23813 :         stmt_cost = stmt_cost * 2
   27117        23813 :                     + ix86_vec_cost (mode, ix86_cost->sse_op);
   27118              :     }
   27119              : 
   27120              :   /* If we do elementwise loads into a vector then we are bound by
   27121              :      latency and execution resources for the many scalar loads
   27122              :      (AGU and load ports).  Try to account for this by scaling the
   27123              :      construction cost by the number of elements involved.  */
   27124      8023840 :   if ((kind == vec_construct || kind == vec_deconstruct)
   27125      8023840 :       && ((node
   27126       368110 :            && (((SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_ELEMENTWISE
   27127       379446 :                  || SLP_TREE_MEMORY_ACCESS_TYPE (node) == VMAT_STRIDED_SLP)
   27128        43062 :                 && (TREE_CODE (DR_STEP (STMT_VINFO_DATA_REF
   27129              :                                         (SLP_TREE_REPRESENTATIVE (node))))
   27130              :                     != INTEGER_CST))
   27131        23139 :                || mat_gather_scatter_p (SLP_TREE_MEMORY_ACCESS_TYPE (node))))))
   27132              :     {
   27133        33070 :       auto lsdata = static_cast<vect_load_store_data *> (node->data);
   27134        33070 :       tree ls_type = lsdata->ls_type ? lsdata->ls_type : vectype;
   27135        33070 :       tree ls_eltype
   27136        33070 :         = lsdata->ls_eltype ? lsdata->ls_eltype : TREE_TYPE (ls_type);
   27137        33070 :       stmt_cost = ix86_vector_cd_cost (TYPE_MODE (ls_type),
   27138        33070 :                                        TYPE_MODE (ls_eltype));
   27139        33070 :       stmt_cost *= (GET_MODE_BITSIZE (TYPE_MODE (ls_type))
   27140        66140 :                     / GET_MODE_BITSIZE (TYPE_MODE (ls_eltype)) + 1);
   27141              :     }
   27142      8023840 :   if (stmt_cost == -1)
   27143      6456618 :     stmt_cost = ix86_default_vector_cost (kind, mode);
   27144              : 
   27145              :   /* BIT_FIELD_REF <vect_**, 64, 0> with count 0 costs 0 in body.  */
   27146      8023840 :   if (kind == vec_perm && vectype && count != 0)
   27147              :     {
   27148       125253 :       unsigned vec_size = GET_MODE_SIZE (TYPE_MODE (vectype));
   27149       125253 :       unsigned nunits = TYPE_VECTOR_SUBPARTS (vectype);
   27150       125253 :       unsigned *num_vec_perm = NULL;
   27151              : 
   27152       125253 :       if (vec_size == 32)
   27153         4157 :         num_vec_perm = m_num_avx256_vec_perm;
   27154       121096 :       else if (vec_size == 64)
   27155         1199 :         num_vec_perm = m_num_avx512_vec_perm;
   27156              : 
   27157         5356 :       if (num_vec_perm && ix86_count_cross_lane_perm_p (m_vinfo, node, nunits))
   27158              :         {
   27159         5354 :           num_vec_perm[where] += count;
   27160         5354 :           if (dump_file && (dump_flags & TDF_DETAILS))
   27161              :             {
   27162          349 :               fprintf (dump_file,
   27163              :                        "Detected avx%u cross-lane permutation: ", vec_size * 8);
   27164          349 :               if (stmt_info)
   27165          126 :                 print_gimple_expr (dump_file, stmt_info->stmt, 0, TDF_SLIM);
   27166          349 :               fprintf (dump_file, " \n");
   27167              :             }
   27168              :         }
   27169              :     }
   27170              : 
   27171              :   /* Penalize DFmode vector operations for Bonnell.  */
   27172      8023840 :   if (TARGET_CPU_P (BONNELL) && kind == vector_stmt
   27173      8023925 :       && vectype && GET_MODE_INNER (TYPE_MODE (vectype)) == DFmode)
   27174           12 :     stmt_cost *= 5;  /* FIXME: The value here is arbitrary.  */
   27175              : 
   27176              :   /* Statements in an inner loop relative to the loop being
   27177              :      vectorized are weighted more heavily.  The value here is
   27178              :      arbitrary and could potentially be improved with analysis.  */
   27179      8023840 :   retval = adjust_cost_for_freq (stmt_info, where, count * stmt_cost);
   27180              : 
   27181              :   /* We need to multiply all vector stmt cost by 1.7 (estimated cost)
   27182              :      for Silvermont as it has out of order integer pipeline and can execute
   27183              :      2 scalar instruction per tick, but has in order SIMD pipeline.  */
   27184      8023840 :   if ((TARGET_CPU_P (SILVERMONT) || TARGET_CPU_P (GOLDMONT)
   27185      8023840 :        || TARGET_CPU_P (GOLDMONT_PLUS) || TARGET_CPU_P (INTEL))
   27186         2551 :       && stmt_info && stmt_info->stmt)
   27187              :     {
   27188         2144 :       tree lhs_op = gimple_get_lhs (stmt_info->stmt);
   27189         2144 :       if (lhs_op && TREE_CODE (TREE_TYPE (lhs_op)) == INTEGER_TYPE)
   27190         1612 :         retval = (retval * 17) / 10;
   27191              :     }
   27192              : 
   27193      8023840 :   m_costs[where] += retval;
   27194              : 
   27195      8023840 :   return retval;
   27196              : }
   27197              : 
   27198              : unsigned
   27199      2771642 : ix86_vector_costs::add_slp_cost (slp_tree node,
   27200              :                                  const array_slice<stmt_info_for_cost> &parts)
   27201              : {
   27202      2771642 :   int stmt_cost = 0;
   27203              : 
   27204              :   /* For vector construction account for the cost of moving data between
   27205              :      GRP and XMM.  As we are looking at the SLP nodes elements, avoid
   27206              :      duplicate costs by doing this in add_slp_cost, leaving the actual
   27207              :      splat/ctor cost to add_stmt_cost.  */
   27208      2771642 :   if (SLP_TREE_DEF_TYPE (node) == vect_external_def)
   27209              :     {
   27210              :       unsigned i;
   27211              :       tree op;
   27212      1118894 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   27213       775476 :         if (TREE_CODE (op) == SSA_NAME)
   27214       546021 :           TREE_VISITED (op) = 0;
   27215      1118894 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   27216              :         {
   27217       775476 :           if (TREE_CODE (op) != SSA_NAME
   27218       546021 :               || TREE_VISITED (op))
   27219       268567 :             continue;
   27220       506909 :           TREE_VISITED (op) = 1;
   27221       506909 :           gimple *def = SSA_NAME_DEF_STMT (op);
   27222       506909 :           tree tem;
   27223              :           /* Look through a conversion.  */
   27224       506909 :           if (is_gimple_assign (def)
   27225       282869 :               && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
   27226        32187 :               && ((tem = gimple_assign_rhs1 (def)), true)
   27227       539096 :               && TREE_CODE (tem) == SSA_NAME)
   27228        31974 :             def = SSA_NAME_DEF_STMT (tem);
   27229              :           /* When the component is loaded from memory without sign-
   27230              :              or zero-extension we can move it to a vector register and/or
   27231              :              insert it via vpinsr with a memory operand.  */
   27232       506909 :           if (gimple_assign_load_p (def)
   27233       145831 :               && tree_nop_conversion_p (TREE_TYPE (op),
   27234       145831 :                                         TREE_TYPE (gimple_assign_lhs (def)))
   27235       788087 :               && (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op))) > 1
   27236         6393 :                   || TARGET_SSE4_1))
   27237              :             ;
   27238              :           /* When the component is extracted from a vector it is already
   27239              :              in a vector register.  */
   27240       371616 :           else if (is_gimple_assign (def)
   27241       142132 :                    && gimple_assign_rhs_code (def) == BIT_FIELD_REF
   27242       372990 :                    && VECTOR_TYPE_P (TREE_TYPE
   27243              :                                 (TREE_OPERAND (gimple_assign_rhs1 (def), 0))))
   27244              :             ;
   27245              :           else
   27246              :             {
   27247       370658 :               if (FLOAT_TYPE_P (TREE_TYPE (op)))
   27248              :                 {
   27249              :                   /* Scalar FP values residing in x87 registers need to be
   27250              :                      spilled and reloaded.  */
   27251        17144 :                   auto mode2 = TYPE_MODE (TREE_TYPE (op));
   27252        17144 :                   if (IS_STACK_MODE (mode2))
   27253              :                     {
   27254         1027 :                       int cost
   27255              :                         = (ix86_cost->hard_register.fp_store[mode2 == SFmode
   27256         1027 :                                                              ? 0 : 1]
   27257         1027 :                            + ix86_cost->sse_load[sse_store_index (mode2)]);
   27258         1027 :                       stmt_cost += COSTS_N_INSNS (cost) / 2;
   27259              :                     }
   27260        17144 :                   m_num_sse_needed[vect_prologue]++;
   27261              :                 }
   27262              :               else
   27263              :                 {
   27264       353514 :                   m_num_gpr_needed[vect_prologue]++;
   27265              : 
   27266       353514 :                   stmt_cost += COSTS_N_INSNS (ix86_cost->integer_to_sse) / 2;
   27267              :                 }
   27268              :             }
   27269              :         }
   27270      1118894 :       FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_OPS (node), i, op)
   27271       775476 :         if (TREE_CODE (op) == SSA_NAME)
   27272       546021 :           TREE_VISITED (op) = 0;
   27273              : 
   27274       343418 :       if (stmt_cost > 0
   27275       343418 :           && dump_file && (dump_flags & TDF_DETAILS))
   27276         2057 :         fprintf (dump_file, "node %p gpr->xmm moves costs %d in prologue\n",
   27277              :                  (void *)node, stmt_cost);
   27278       343418 :       m_costs[vect_prologue] += stmt_cost;
   27279              :     }
   27280              : 
   27281      2771642 :   return stmt_cost + vector_costs::add_slp_cost (node, parts);
   27282              : }
   27283              : 
   27284              : void
   27285      1958021 : ix86_vector_costs::ix86_vect_estimate_reg_pressure ()
   27286              : {
   27287      1958021 :   unsigned gpr_spill_cost = COSTS_N_INSNS (ix86_cost->int_store [2]) / 2;
   27288      1958021 :   unsigned sse_spill_cost = COSTS_N_INSNS (ix86_cost->sse_store[0]) / 2;
   27289              : 
   27290              :   /* Any better way to have target available fp registers, currently use SSE_REGS.  */
   27291      1958021 :   unsigned target_avail_sse = TARGET_64BIT ? (TARGET_AVX512F ? 32 : 16) : 8;
   27292      7832084 :   for (unsigned i = 0; i != 3; i++)
   27293              :     {
   27294      5874063 :       if (m_num_gpr_needed[i] > target_avail_regs)
   27295          865 :         m_costs[i] += gpr_spill_cost * (m_num_gpr_needed[i] - target_avail_regs);
   27296              :       /* Only measure sse registers pressure.  */
   27297      5874063 :       if (TARGET_SSE && (m_num_sse_needed[i] > target_avail_sse))
   27298          100 :         m_costs[i] += sse_spill_cost * (m_num_sse_needed[i] - target_avail_sse);
   27299              :     }
   27300      1958021 : }
   27301              : 
   27302              : void
   27303      1958021 : ix86_vector_costs::finish_cost (const vector_costs *scalar_costs)
   27304              : {
   27305      1958021 :   loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo);
   27306       503755 :   if (loop_vinfo && !m_costing_for_scalar)
   27307              :     {
   27308       126474 :       unsigned int vf = vect_vf_for_cost (loop_vinfo);
   27309       551655 :       for (auto inst : LOOP_VINFO_SLP_INSTANCES (loop_vinfo))
   27310       172233 :         if ((SLP_INSTANCE_KIND (inst) == slp_inst_kind_reduc_group
   27311       172233 :              || SLP_INSTANCE_KIND (inst) == slp_inst_kind_reduc_chain)
   27312       172233 :             && (vect_reduc_type (loop_vinfo, SLP_INSTANCE_TREE (inst))
   27313              :                 == FOLD_LEFT_REDUCTION))
   27314         3980 :           m_num_fold_left_reduc_lanes
   27315         3980 :             += vf * SLP_TREE_LANES (SLP_INSTANCE_TREE (inst));
   27316              : 
   27317       126474 :       if (m_num_fold_left_reduc_lanes && dump_enabled_p ())
   27318           19 :         dump_printf_loc (MSG_NOTE, vect_location,
   27319              :                          "in-order FP reduction lanes: %u\n",
   27320              :                          m_num_fold_left_reduc_lanes);
   27321              : 
   27322              :       /* We are currently not asking the vectorizer to compare costs
   27323              :          between different vector mode sizes.  When using predication
   27324              :          that will end up always choosing the preferred mode size even
   27325              :          if there's a smaller mode covering all lanes.  Test for this
   27326              :          situation and artificially reject the larger mode attempt.
   27327              :          ???  We currently lack masked ops for sub-SSE sized modes,
   27328              :          so we could restrict this rejection to AVX and AVX512 modes
   27329              :          but error on the safe side for now.  */
   27330       126474 :       if (LOOP_VINFO_USING_PARTIAL_VECTORS_P (loop_vinfo)
   27331           29 :           && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27332           17 :           && LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   27333       126485 :           && (exact_log2 (LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ())
   27334           22 :               > ceil_log2 (LOOP_VINFO_INT_NITERS (loop_vinfo))))
   27335            8 :         m_costs[vect_body] = INT_MAX;
   27336              : 
   27337              :       /* We'd like to avoid using masking if there's an in-order reduction
   27338              :          to vectorize because that will also perform in-order adds of
   27339              :          masked elements (as neutral value, of course) here, but there
   27340              :          is currently no way to indicate to try un-masked with the same
   27341              :          mode.  */
   27342              : 
   27343       126474 :       bool any_reduc_p = false;
   27344       502429 :       for (int i = 0; i != X86_REDUC_LAST; i++)
   27345       377256 :         if (m_num_reduc[i])
   27346              :           {
   27347              :             any_reduc_p = true;
   27348              :             break;
   27349              :           }
   27350              : 
   27351       126474 :       if (any_reduc_p
   27352              :           /* Not much gain for loop with gather and scatter.  */
   27353         1301 :           && m_prefer_unroll
   27354         1144 :           && !LOOP_VINFO_EPILOGUE_P (loop_vinfo))
   27355              :         {
   27356         1826 :           unsigned unroll_factor
   27357          913 :             = OPTION_SET_P (ix86_vect_unroll_limit)
   27358          913 :             ? ix86_vect_unroll_limit
   27359          913 :             : ix86_cost->vect_unroll_limit;
   27360              : 
   27361          913 :           if (unroll_factor > 1)
   27362              :             {
   27363         3652 :               for (int i = 0 ; i != X86_REDUC_LAST; i++)
   27364              :                 {
   27365         2739 :                   if (m_num_reduc[i])
   27366              :                     {
   27367          913 :                       unsigned tmp = CEIL (ix86_cost->reduc_lat_mult_thr[i],
   27368              :                                            m_num_reduc[i]);
   27369         2739 :                       unroll_factor = MIN (unroll_factor, tmp);
   27370              :                     }
   27371              :                 }
   27372              : 
   27373         1826 :               m_suggested_unroll_factor  = 1 << ceil_log2 (unroll_factor);
   27374              :             }
   27375              :         }
   27376              : 
   27377              :     }
   27378              : 
   27379      1958021 :   ix86_vect_estimate_reg_pressure ();
   27380              : 
   27381      9790105 :   for (int i = 0; i != 3; i++)
   27382      5874063 :     if (m_num_avx256_vec_perm[i]
   27383          539 :         && TARGET_AVX256_AVOID_VEC_PERM)
   27384            7 :       m_costs[i] = INT_MAX;
   27385              : 
   27386      7832084 :   for (int i = 0; i != 3; i++)
   27387      5874063 :     if (m_num_avx512_vec_perm[i] && TARGET_AVX512_AVOID_VEC_PERM)
   27388            5 :       m_costs[i] = INT_MAX;
   27389              : 
   27390              :   /* When X86_TUNE_AVX512_TWO_EPILOGUES is enabled arrange for both
   27391              :      a AVX2 and a SSE epilogue for AVX512 vectorized loops.  */
   27392      1958021 :   if (loop_vinfo
   27393       503755 :       && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27394        44400 :       && GET_MODE_SIZE (loop_vinfo->vector_mode) == 32
   27395      1958788 :       && ix86_tune_features[X86_TUNE_AVX512_TWO_EPILOGUES])
   27396           25 :     m_suggested_epilogue_mode = V16QImode;
   27397              :   /* When a 128bit SSE vectorized epilogue still has a VF of 16 or larger
   27398              :      enable a 64bit SSE epilogue.  */
   27399      1958021 :   if (loop_vinfo
   27400       503755 :       && LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27401        44400 :       && GET_MODE_SIZE (loop_vinfo->vector_mode) == 16
   27402      1960575 :       && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () >= 16)
   27403          110 :     m_suggested_epilogue_mode = V8QImode;
   27404              : 
   27405              :   /* When X86_TUNE_AVX512_MASKED_EPILOGUES is enabled try to use
   27406              :      a masked epilogue if that doesn't seem detrimental.  */
   27407      1958021 :   if (loop_vinfo
   27408       503755 :       && !LOOP_VINFO_EPILOGUE_P (loop_vinfo)
   27409       481555 :       && LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () > 2
   27410              :       /* Avoid a masked epilog if cascaded epilogues eventually get us
   27411              :          to one with VF 1 as that means no scalar epilog at all.  */
   27412        76750 :       && !((GET_MODE_SIZE (loop_vinfo->vector_mode)
   27413        76750 :             / LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant () == 16)
   27414           34 :            && ix86_tune_features[X86_TUNE_AVX512_TWO_EPILOGUES])
   27415        76749 :       && ix86_tune_features[X86_TUNE_AVX512_MASKED_EPILOGUES]
   27416      1958205 :       && !OPTION_SET_P (param_vect_partial_vector_usage))
   27417              :     {
   27418          166 :       bool avoid = false;
   27419          166 :       if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
   27420          129 :           && LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo) >= 0)
   27421              :         {
   27422          129 :           unsigned int peel_niter
   27423              :             = LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo);
   27424          129 :           if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
   27425            0 :             peel_niter += 1;
   27426              :           /* When we know the number of scalar iterations of the epilogue,
   27427              :              avoid masking when a single vector epilog iteration handles
   27428              :              it in full.  */
   27429          129 :           if (pow2p_hwi ((LOOP_VINFO_INT_NITERS (loop_vinfo) - peel_niter)
   27430          129 :                          % LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ()))
   27431              :             avoid = true;
   27432              :         }
   27433          164 :       if (!avoid && loop_outer (loop_outer (LOOP_VINFO_LOOP (loop_vinfo))))
   27434           14 :         for (auto ddr : LOOP_VINFO_DDRS (loop_vinfo))
   27435              :           {
   27436            4 :             if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
   27437              :               ;
   27438            4 :             else if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
   27439              :               ;
   27440              :             else
   27441              :               {
   27442            2 :                 int loop_depth
   27443            4 :                     = index_in_loop_nest (LOOP_VINFO_LOOP (loop_vinfo)->num,
   27444            2 :                                           DDR_LOOP_NEST (ddr));
   27445            4 :                 if (DDR_NUM_DIST_VECTS (ddr) == 1
   27446            2 :                     && DDR_DIST_VECTS (ddr)[0][loop_depth] == 0)
   27447              :                   {
   27448              :                     /* Avoid the case when there's an outer loop that might
   27449              :                        traverse a multi-dimensional array with the inner
   27450              :                        loop just executing the masked epilogue with a
   27451              :                        read-write where the next outer iteration might
   27452              :                        read from the masked part of the previous write,
   27453              :                        'n' filling half a vector.
   27454              :                          for (j = 0; j < m; ++j)
   27455              :                            for (i = 0; i < n; ++i)
   27456              :                              a[j][i] = c * a[j][i];  */
   27457              :                     avoid = true;
   27458              :                     break;
   27459              :                   }
   27460              :               }
   27461              :           }
   27462              :       /* Avoid using masking if there's an in-order reduction
   27463              :          to vectorize because that will also perform in-order adds of
   27464              :          masked elements (as neutral value, of course).  */
   27465          166 :       if (!avoid)
   27466              :         {
   27467          655 :           for (auto inst : LOOP_VINFO_SLP_INSTANCES (loop_vinfo))
   27468          173 :             if (SLP_INSTANCE_KIND (inst) == slp_inst_kind_reduc_group
   27469          173 :                 && (vect_reduc_type (loop_vinfo, SLP_INSTANCE_TREE (inst))
   27470              :                     == FOLD_LEFT_REDUCTION))
   27471              :               {
   27472              :                 avoid = true;
   27473              :                 break;
   27474              :               }
   27475              :         }
   27476          162 :       if (!avoid)
   27477              :         {
   27478          158 :           m_suggested_epilogue_mode = loop_vinfo->vector_mode;
   27479          158 :           m_masked_epilogue = 1;
   27480              :         }
   27481              :     }
   27482              : 
   27483      1958021 :   vector_costs::finish_cost (scalar_costs);
   27484      1958021 : }
   27485              : 
   27486              : /* Return true if THIS has a shorter fold-left reduction chain than OTHER.  */
   27487              : 
   27488              : bool
   27489        35522 : ix86_vector_costs::better_fold_left_reduc_than_p
   27490              :   (const vector_costs *other) const
   27491              : {
   27492        35522 :   auto other_costs = static_cast<const ix86_vector_costs *> (other);
   27493        35522 :   if (m_num_fold_left_reduc_lanes >= other_costs->m_num_fold_left_reduc_lanes)
   27494              :     return false;
   27495              : 
   27496              :   /* Do not let emulated sub-SSE modes win on this alone.  */
   27497          328 :   loop_vec_info loop_vinfo = as_a<loop_vec_info> (m_vinfo);
   27498          656 :   return known_ge (GET_MODE_SIZE (loop_vinfo->vector_mode), 16);
   27499              : }
   27500              : 
   27501              : /* Return true if THIS should be preferred over OTHER as main vector loop.  */
   27502              : 
   27503              : bool
   27504        33975 : ix86_vector_costs::better_main_loop_than_p (const vector_costs *other) const
   27505              : {
   27506        33975 :   loop_vec_info this_loop_vinfo = as_a<loop_vec_info> (this->vinfo ());
   27507        33975 :   loop_vec_info other_loop_vinfo = as_a<loop_vec_info> (other->vinfo ());
   27508              : 
   27509        33975 :   if (better_fold_left_reduc_than_p (other))
   27510              :     return true;
   27511              : 
   27512              :   /* If the other loop is masked it does not need an epilog.  Prefer that
   27513              :      if the current loop cannot be vectorized fully with a vector
   27514              :      epilogs with at most one scalar iteration left.  */
   27515        25682 :   if (LOOP_VINFO_NITERS_KNOWN_P (this_loop_vinfo)
   27516        25682 :       && LOOP_VINFO_USING_PARTIAL_VECTORS_P (other_loop_vinfo)
   27517            4 :       && known_gt (LOOP_VINFO_VECT_FACTOR (other_loop_vinfo),
   27518              :                    LOOP_VINFO_INT_NITERS (this_loop_vinfo))
   27519        33942 :       && (popcount_hwi (LOOP_VINFO_INT_NITERS (this_loop_vinfo) & ~1)
   27520            4 :           > (param_vect_epilogues_nomask != 0)))
   27521              :     return false;
   27522              : 
   27523        33934 :   return vector_costs::better_main_loop_than_p (other);
   27524              : }
   27525              : 
   27526              : /* Return true if THIS should be preferred over OTHER as epilog vector
   27527              :    loop when vectorizing MAIN_LOOP.  */
   27528              : 
   27529              : bool
   27530         1547 : ix86_vector_costs::better_epilogue_loop_than_p (const vector_costs *other,
   27531              :                                                 loop_vec_info main_loop) const
   27532              : {
   27533         1547 :   loop_vec_info this_loop_info = as_a <loop_vec_info> (this->vinfo ());
   27534              : 
   27535         1547 :   if (better_fold_left_reduc_than_p (other))
   27536              :     return true;
   27537              : 
   27538              :   /* The x86 target allows for multiple vector epilogues, if THIS is
   27539              :      the suggested epilog mode of OTHER then keep the latter unless
   27540              :      THIS has a VF of one which means no further epilog needed.  */
   27541         1547 :   int tem;
   27542         1547 :   if (known_gt (LOOP_VINFO_VECT_FACTOR (this_loop_info), 1U)
   27543         1547 :       && (GET_MODE_SIZE (other->suggested_epilogue_mode (tem))
   27544         3070 :           == GET_MODE_SIZE (this_loop_info->vector_mode)))
   27545              :     return false;
   27546         1459 :   return vector_costs::better_epilogue_loop_than_p (other, main_loop);
   27547              : }
   27548              : 
   27549              : /* Validate target specific memory model bits in VAL. */
   27550              : 
   27551              : static unsigned HOST_WIDE_INT
   27552       413746 : ix86_memmodel_check (unsigned HOST_WIDE_INT val)
   27553              : {
   27554       413746 :   enum memmodel model = memmodel_from_int (val);
   27555       413746 :   bool strong;
   27556              : 
   27557       413746 :   if (val & ~(unsigned HOST_WIDE_INT)(IX86_HLE_ACQUIRE|IX86_HLE_RELEASE
   27558              :                                       |MEMMODEL_MASK)
   27559       413742 :       || ((val & IX86_HLE_ACQUIRE) && (val & IX86_HLE_RELEASE)))
   27560              :     {
   27561            4 :       warning (OPT_Winvalid_memory_model,
   27562              :                "unknown architecture specific memory model");
   27563            4 :       return MEMMODEL_SEQ_CST;
   27564              :     }
   27565       413742 :   strong = (is_mm_acq_rel (model) || is_mm_seq_cst (model));
   27566       413742 :   if (val & IX86_HLE_ACQUIRE && !(is_mm_acquire (model) || strong))
   27567              :     {
   27568            0 :       warning (OPT_Winvalid_memory_model,
   27569              :               "%<HLE_ACQUIRE%> not used with %<ACQUIRE%> or stronger "
   27570              :                "memory model");
   27571            0 :       return MEMMODEL_SEQ_CST | IX86_HLE_ACQUIRE;
   27572              :     }
   27573       413742 :   if (val & IX86_HLE_RELEASE && !(is_mm_release (model) || strong))
   27574              :     {
   27575            0 :       warning (OPT_Winvalid_memory_model,
   27576              :               "%<HLE_RELEASE%> not used with %<RELEASE%> or stronger "
   27577              :                "memory model");
   27578            0 :       return MEMMODEL_SEQ_CST | IX86_HLE_RELEASE;
   27579              :     }
   27580              :   return val;
   27581              : }
   27582              : 
   27583              : /* Set CLONEI->vecsize_mangle, CLONEI->mask_mode, CLONEI->vecsize_int,
   27584              :    CLONEI->vecsize_float and if CLONEI->simdlen is 0, also
   27585              :    CLONEI->simdlen.  Return 0 if SIMD clones shouldn't be emitted,
   27586              :    or number of vecsize_mangle variants that should be emitted.  */
   27587              : 
   27588              : static int
   27589         7725 : ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
   27590              :                                              struct cgraph_simd_clone *clonei,
   27591              :                                              tree base_type, int num,
   27592              :                                              bool explicit_p)
   27593              : {
   27594         7725 :   int ret = 1;
   27595              : 
   27596         7725 :   if (clonei->simdlen
   27597         7725 :       && (clonei->simdlen < 2
   27598         1325 :           || clonei->simdlen > 1024
   27599         1325 :           || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
   27600              :     {
   27601            0 :       if (explicit_p)
   27602            0 :         warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27603              :                     "unsupported simdlen %wd", clonei->simdlen.to_constant ());
   27604              :       return 0;
   27605              :     }
   27606              : 
   27607         7725 :   tree ret_type = TREE_TYPE (TREE_TYPE (node->decl));
   27608         7725 :   if (TREE_CODE (ret_type) != VOID_TYPE)
   27609         6905 :     switch (TYPE_MODE (ret_type))
   27610              :       {
   27611         6905 :       case E_QImode:
   27612         6905 :       case E_HImode:
   27613         6905 :       case E_SImode:
   27614         6905 :       case E_DImode:
   27615         6905 :       case E_SFmode:
   27616         6905 :       case E_DFmode:
   27617              :       /* case E_SCmode: */
   27618              :       /* case E_DCmode: */
   27619         6905 :         if (!AGGREGATE_TYPE_P (ret_type))
   27620              :           break;
   27621              :         /* FALLTHRU */
   27622            2 :       default:
   27623            2 :         if (explicit_p)
   27624            2 :           warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27625              :                       "unsupported return type %qT for simd", ret_type);
   27626              :         return 0;
   27627              :       }
   27628              : 
   27629         7723 :   tree t;
   27630         7723 :   int i;
   27631         7723 :   tree type_arg_types = TYPE_ARG_TYPES (TREE_TYPE (node->decl));
   27632         7723 :   bool decl_arg_p = (node->definition || type_arg_types == NULL_TREE);
   27633              : 
   27634         7723 :   for (t = (decl_arg_p ? DECL_ARGUMENTS (node->decl) : type_arg_types), i = 0;
   27635        20710 :        t && t != void_list_node; t = TREE_CHAIN (t), i++)
   27636              :     {
   27637        16938 :       tree arg_type = decl_arg_p ? TREE_TYPE (t) : TREE_VALUE (t);
   27638        12992 :       switch (TYPE_MODE (arg_type))
   27639              :         {
   27640        12973 :         case E_QImode:
   27641        12973 :         case E_HImode:
   27642        12973 :         case E_SImode:
   27643        12973 :         case E_DImode:
   27644        12973 :         case E_SFmode:
   27645        12973 :         case E_DFmode:
   27646              :         /* case E_SCmode: */
   27647              :         /* case E_DCmode: */
   27648        12973 :           if (!AGGREGATE_TYPE_P (arg_type))
   27649              :             break;
   27650              :           /* FALLTHRU */
   27651           41 :         default:
   27652           41 :           if (clonei->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM)
   27653              :             break;
   27654            5 :           if (explicit_p)
   27655            5 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27656              :                         "unsupported argument type %qT for simd", arg_type);
   27657              :           return 0;
   27658              :         }
   27659              :     }
   27660              : 
   27661         7718 :   if (!TREE_PUBLIC (node->decl) || !explicit_p)
   27662              :     {
   27663              :       /* If the function isn't exported, we can pick up just one ISA
   27664              :          for the clones.  */
   27665          114 :       if (TARGET_AVX512F)
   27666            0 :         clonei->vecsize_mangle = 'e';
   27667          114 :       else if (TARGET_AVX2)
   27668            1 :         clonei->vecsize_mangle = 'd';
   27669          113 :       else if (TARGET_AVX)
   27670           88 :         clonei->vecsize_mangle = 'c';
   27671              :       else
   27672           25 :         clonei->vecsize_mangle = 'b';
   27673              :       ret = 1;
   27674              :     }
   27675              :   else
   27676              :     {
   27677         7604 :       clonei->vecsize_mangle = "bcde"[num];
   27678         7604 :       ret = 4;
   27679              :     }
   27680         7718 :   clonei->mask_mode = VOIDmode;
   27681         7718 :   switch (clonei->vecsize_mangle)
   27682              :     {
   27683         1926 :     case 'b':
   27684         1926 :       clonei->vecsize_int = 128;
   27685         1926 :       clonei->vecsize_float = 128;
   27686         1926 :       break;
   27687         1989 :     case 'c':
   27688         1989 :       clonei->vecsize_int = 128;
   27689         1989 :       clonei->vecsize_float = 256;
   27690         1989 :       break;
   27691         1902 :     case 'd':
   27692         1902 :       clonei->vecsize_int = 256;
   27693         1902 :       clonei->vecsize_float = 256;
   27694         1902 :       break;
   27695         1901 :     case 'e':
   27696         1901 :       clonei->vecsize_int = 512;
   27697         1901 :       clonei->vecsize_float = 512;
   27698         1901 :       if (TYPE_MODE (base_type) == QImode)
   27699           19 :         clonei->mask_mode = DImode;
   27700              :       else
   27701         1882 :         clonei->mask_mode = SImode;
   27702              :       break;
   27703              :     }
   27704         7718 :   if (clonei->simdlen == 0)
   27705              :     {
   27706         6393 :       if (SCALAR_INT_MODE_P (TYPE_MODE (base_type)))
   27707         3329 :         clonei->simdlen = clonei->vecsize_int;
   27708              :       else
   27709         3064 :         clonei->simdlen = clonei->vecsize_float;
   27710         6393 :       clonei->simdlen = clonei->simdlen
   27711        12786 :                         / GET_MODE_BITSIZE (TYPE_MODE (base_type));
   27712              :     }
   27713         1325 :   else if (clonei->simdlen > 16)
   27714              :     {
   27715              :       /* For compatibility with ICC, use the same upper bounds
   27716              :          for simdlen.  In particular, for CTYPE below, use the return type,
   27717              :          unless the function returns void, in that case use the characteristic
   27718              :          type.  If it is possible for given SIMDLEN to pass CTYPE value
   27719              :          in registers (8 [XYZ]MM* regs for 32-bit code, 16 [XYZ]MM* regs
   27720              :          for 64-bit code), accept that SIMDLEN, otherwise warn and don't
   27721              :          emit corresponding clone.  */
   27722           12 :       tree ctype = ret_type;
   27723           12 :       if (VOID_TYPE_P (ret_type))
   27724            0 :         ctype = base_type;
   27725           24 :       int cnt = GET_MODE_BITSIZE (TYPE_MODE (ctype)) * clonei->simdlen;
   27726           12 :       if (SCALAR_INT_MODE_P (TYPE_MODE (ctype)))
   27727            8 :         cnt /= clonei->vecsize_int;
   27728              :       else
   27729            4 :         cnt /= clonei->vecsize_float;
   27730           12 :       if (cnt > (TARGET_64BIT ? 16 : 8))
   27731              :         {
   27732            0 :           if (explicit_p)
   27733            0 :             warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
   27734              :                         "unsupported simdlen %wd",
   27735              :                         clonei->simdlen.to_constant ());
   27736              :           return 0;
   27737              :         }
   27738              :       }
   27739              :   return ret;
   27740              : }
   27741              : 
   27742              : /* If SIMD clone NODE can't be used in a vectorized loop
   27743              :    in current function, return -1, otherwise return a badness of using it
   27744              :    (0 if it is most desirable from vecsize_mangle point of view, 1
   27745              :    slightly less desirable, etc.).  */
   27746              : 
   27747              : static int
   27748         1764 : ix86_simd_clone_usable (struct cgraph_node *node, machine_mode)
   27749              : {
   27750         1764 :   switch (node->simdclone->vecsize_mangle)
   27751              :     {
   27752          626 :     case 'b':
   27753          626 :       if (!TARGET_SSE2)
   27754              :         return -1;
   27755          626 :       if (!TARGET_AVX)
   27756              :         return 0;
   27757          525 :       return TARGET_AVX512F ? 3 : TARGET_AVX2 ? 2 : 1;
   27758          628 :     case 'c':
   27759          628 :       if (!TARGET_AVX)
   27760              :         return -1;
   27761          583 :       return TARGET_AVX512F ? 2 : TARGET_AVX2 ? 1 : 0;
   27762          322 :     case 'd':
   27763          322 :       if (!TARGET_AVX2)
   27764              :         return -1;
   27765          117 :       return TARGET_AVX512F ? 1 : 0;
   27766          188 :     case 'e':
   27767          188 :       if (!TARGET_AVX512F)
   27768          130 :         return -1;
   27769              :       return 0;
   27770            0 :     default:
   27771            0 :       gcc_unreachable ();
   27772              :     }
   27773              : }
   27774              : 
   27775              : /* This function adjusts the unroll factor based on
   27776              :    the hardware capabilities. For ex, bdver3 has
   27777              :    a loop buffer which makes unrolling of smaller
   27778              :    loops less important. This function decides the
   27779              :    unroll factor using number of memory references
   27780              :    (value 32 is used) as a heuristic. */
   27781              : 
   27782              : static unsigned
   27783       811195 : ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
   27784              : {
   27785       811195 :   basic_block *bbs;
   27786       811195 :   rtx_insn *insn;
   27787       811195 :   unsigned i;
   27788       811195 :   unsigned mem_count = 0;
   27789              : 
   27790              :   /* Unroll small size loop when unroll factor is not explicitly
   27791              :      specified.  */
   27792       811195 :   if (ix86_unroll_only_small_loops && !loop->unroll)
   27793              :     {
   27794       767348 :       if (loop->ninsns <= ix86_cost->small_unroll_ninsns)
   27795        73792 :         return MIN (nunroll, ix86_cost->small_unroll_factor);
   27796              :       else
   27797              :         return 1;
   27798              :     }
   27799              : 
   27800        43847 :   if (!TARGET_ADJUST_UNROLL)
   27801              :      return nunroll;
   27802              : 
   27803              :   /* Count the number of memory references within the loop body.
   27804              :      This value determines the unrolling factor for bdver3 and bdver4
   27805              :      architectures. */
   27806            8 :   subrtx_iterator::array_type array;
   27807            8 :   bbs = get_loop_body (loop);
   27808           32 :   for (i = 0; i < loop->num_nodes; i++)
   27809          120 :     FOR_BB_INSNS (bbs[i], insn)
   27810          104 :       if (NONDEBUG_INSN_P (insn))
   27811          588 :         FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   27812          516 :           if (const_rtx x = *iter)
   27813          516 :             if (MEM_P (x))
   27814              :               {
   27815           28 :                 machine_mode mode = GET_MODE (x);
   27816           56 :                 unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
   27817           28 :                 if (n_words > 4)
   27818            0 :                   mem_count += 2;
   27819              :                 else
   27820           28 :                   mem_count += 1;
   27821              :               }
   27822            8 :   free (bbs);
   27823              : 
   27824            8 :   if (mem_count && mem_count <=32)
   27825            8 :     return MIN (nunroll, 32 / mem_count);
   27826              : 
   27827              :   return nunroll;
   27828            8 : }
   27829              : 
   27830              : 
   27831              : /* Implement TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P.  */
   27832              : 
   27833              : static bool
   27834       427528 : ix86_float_exceptions_rounding_supported_p (void)
   27835              : {
   27836              :   /* For x87 floating point with standard excess precision handling,
   27837              :      there is no adddf3 pattern (since x87 floating point only has
   27838              :      XFmode operations) so the default hook implementation gets this
   27839              :      wrong.  */
   27840       427528 :   return TARGET_80387 || (TARGET_SSE && TARGET_SSE_MATH);
   27841              : }
   27842              : 
   27843              : /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
   27844              : 
   27845              : static void
   27846         7054 : ix86_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   27847              : {
   27848         7054 :   if (!TARGET_80387 && !(TARGET_SSE && TARGET_SSE_MATH))
   27849              :     return;
   27850         7054 :   tree exceptions_var = create_tmp_var_raw (integer_type_node);
   27851         7054 :   if (TARGET_80387)
   27852              :     {
   27853         7054 :       tree fenv_index_type = build_index_type (size_int (6));
   27854         7054 :       tree fenv_type = build_array_type (unsigned_type_node, fenv_index_type);
   27855         7054 :       tree fenv_var = create_tmp_var_raw (fenv_type);
   27856         7054 :       TREE_ADDRESSABLE (fenv_var) = 1;
   27857         7054 :       tree fenv_ptr = build_pointer_type (fenv_type);
   27858         7054 :       tree fenv_addr = build1 (ADDR_EXPR, fenv_ptr, fenv_var);
   27859         7054 :       fenv_addr = fold_convert (ptr_type_node, fenv_addr);
   27860         7054 :       tree fnstenv = get_ix86_builtin (IX86_BUILTIN_FNSTENV);
   27861         7054 :       tree fldenv = get_ix86_builtin (IX86_BUILTIN_FLDENV);
   27862         7054 :       tree fnstsw = get_ix86_builtin (IX86_BUILTIN_FNSTSW);
   27863         7054 :       tree fnclex = get_ix86_builtin (IX86_BUILTIN_FNCLEX);
   27864         7054 :       tree hold_fnstenv = build_call_expr (fnstenv, 1, fenv_addr);
   27865         7054 :       tree hold_fnclex = build_call_expr (fnclex, 0);
   27866         7054 :       fenv_var = build4 (TARGET_EXPR, fenv_type, fenv_var, hold_fnstenv,
   27867              :                          NULL_TREE, NULL_TREE);
   27868         7054 :       *hold = build2 (COMPOUND_EXPR, void_type_node, fenv_var,
   27869              :                       hold_fnclex);
   27870         7054 :       *clear = build_call_expr (fnclex, 0);
   27871         7054 :       tree sw_var = create_tmp_var_raw (short_unsigned_type_node);
   27872         7054 :       tree fnstsw_call = build_call_expr (fnstsw, 0);
   27873         7054 :       tree sw_mod = build4 (TARGET_EXPR, short_unsigned_type_node, sw_var,
   27874              :                             fnstsw_call, NULL_TREE, NULL_TREE);
   27875         7054 :       tree exceptions_x87 = fold_convert (integer_type_node, sw_var);
   27876         7054 :       tree update_mod = build4 (TARGET_EXPR, integer_type_node,
   27877              :                                 exceptions_var, exceptions_x87,
   27878              :                                 NULL_TREE, NULL_TREE);
   27879         7054 :       *update = build2 (COMPOUND_EXPR, integer_type_node,
   27880              :                         sw_mod, update_mod);
   27881         7054 :       tree update_fldenv = build_call_expr (fldenv, 1, fenv_addr);
   27882         7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update, update_fldenv);
   27883              :     }
   27884         7054 :   if (TARGET_SSE && TARGET_SSE_MATH)
   27885              :     {
   27886         7054 :       tree mxcsr_orig_var = create_tmp_var_raw (unsigned_type_node);
   27887         7054 :       tree mxcsr_mod_var = create_tmp_var_raw (unsigned_type_node);
   27888         7054 :       tree stmxcsr = get_ix86_builtin (IX86_BUILTIN_STMXCSR);
   27889         7054 :       tree ldmxcsr = get_ix86_builtin (IX86_BUILTIN_LDMXCSR);
   27890         7054 :       tree stmxcsr_hold_call = build_call_expr (stmxcsr, 0);
   27891         7054 :       tree hold_assign_orig = build4 (TARGET_EXPR, unsigned_type_node,
   27892              :                                       mxcsr_orig_var, stmxcsr_hold_call,
   27893              :                                       NULL_TREE, NULL_TREE);
   27894         7054 :       tree hold_mod_val = build2 (BIT_IOR_EXPR, unsigned_type_node,
   27895              :                                   mxcsr_orig_var,
   27896              :                                   build_int_cst (unsigned_type_node, 0x1f80));
   27897         7054 :       hold_mod_val = build2 (BIT_AND_EXPR, unsigned_type_node, hold_mod_val,
   27898              :                              build_int_cst (unsigned_type_node, 0xffffffc0));
   27899         7054 :       tree hold_assign_mod = build4 (TARGET_EXPR, unsigned_type_node,
   27900              :                                      mxcsr_mod_var, hold_mod_val,
   27901              :                                      NULL_TREE, NULL_TREE);
   27902         7054 :       tree ldmxcsr_hold_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   27903         7054 :       tree hold_all = build2 (COMPOUND_EXPR, unsigned_type_node,
   27904              :                               hold_assign_orig, hold_assign_mod);
   27905         7054 :       hold_all = build2 (COMPOUND_EXPR, void_type_node, hold_all,
   27906              :                          ldmxcsr_hold_call);
   27907         7054 :       if (*hold)
   27908         7054 :         *hold = build2 (COMPOUND_EXPR, void_type_node, *hold, hold_all);
   27909              :       else
   27910              :         *hold = hold_all;
   27911         7054 :       tree ldmxcsr_clear_call = build_call_expr (ldmxcsr, 1, mxcsr_mod_var);
   27912         7054 :       if (*clear)
   27913         7054 :         *clear = build2 (COMPOUND_EXPR, void_type_node, *clear,
   27914              :                          ldmxcsr_clear_call);
   27915              :       else
   27916              :         *clear = ldmxcsr_clear_call;
   27917         7054 :       tree stxmcsr_update_call = build_call_expr (stmxcsr, 0);
   27918         7054 :       tree exceptions_sse = fold_convert (integer_type_node,
   27919              :                                           stxmcsr_update_call);
   27920         7054 :       if (*update)
   27921              :         {
   27922         7054 :           tree exceptions_mod = build2 (BIT_IOR_EXPR, integer_type_node,
   27923              :                                         exceptions_var, exceptions_sse);
   27924         7054 :           tree exceptions_assign = build2 (MODIFY_EXPR, integer_type_node,
   27925              :                                            exceptions_var, exceptions_mod);
   27926         7054 :           *update = build2 (COMPOUND_EXPR, integer_type_node, *update,
   27927              :                             exceptions_assign);
   27928              :         }
   27929              :       else
   27930            0 :         *update = build4 (TARGET_EXPR, integer_type_node, exceptions_var,
   27931              :                           exceptions_sse, NULL_TREE, NULL_TREE);
   27932         7054 :       tree ldmxcsr_update_call = build_call_expr (ldmxcsr, 1, mxcsr_orig_var);
   27933         7054 :       *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   27934              :                         ldmxcsr_update_call);
   27935              :     }
   27936         7054 :   tree atomic_feraiseexcept
   27937         7054 :     = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
   27938         7054 :   tree atomic_feraiseexcept_call = build_call_expr (atomic_feraiseexcept,
   27939              :                                                     1, exceptions_var);
   27940         7054 :   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
   27941              :                     atomic_feraiseexcept_call);
   27942              : }
   27943              : 
   27944              : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   27945              : /* For i386, common symbol is local only for non-PIE binaries.  For
   27946              :    x86-64, common symbol is local only for non-PIE binaries or linker
   27947              :    supports copy reloc in PIE binaries.   */
   27948              : 
   27949              : static bool
   27950    807363893 : ix86_binds_local_p (const_tree exp)
   27951              : {
   27952    807363893 :   bool direct_extern_access
   27953    807363893 :     = (ix86_direct_extern_access
   27954   1611182529 :        && !(VAR_OR_FUNCTION_DECL_P (exp)
   27955    803818636 :             && lookup_attribute ("nodirect_extern_access",
   27956    803818636 :                                  DECL_ATTRIBUTES (exp))));
   27957         1233 :   if (!direct_extern_access)
   27958         1233 :     ix86_has_no_direct_extern_access = true;
   27959    807363893 :   return default_binds_local_p_3 (exp, flag_shlib != 0, true,
   27960              :                                   direct_extern_access,
   27961              :                                   (direct_extern_access
   27962    807362660 :                                    && (!flag_pic
   27963    145802733 :                                        || (TARGET_64BIT
   27964    807363893 :                                            && HAVE_LD_PIE_COPYRELOC != 0))));
   27965              : }
   27966              : 
   27967              : /* If flag_pic or ix86_direct_extern_access is false, then neither
   27968              :    local nor global relocs should be placed in readonly memory.  */
   27969              : 
   27970              : static int
   27971      5173563 : ix86_reloc_rw_mask (void)
   27972              : {
   27973      5173563 :   return (flag_pic || !ix86_direct_extern_access) ? 3 : 0;
   27974              : }
   27975              : #endif
   27976              : 
   27977              : /* Return true iff ADDR can be used as a symbolic base address.  */
   27978              : 
   27979              : static bool
   27980         3155 : symbolic_base_address_p (rtx addr)
   27981              : {
   27982            0 :   if (SYMBOL_REF_P (addr))
   27983              :     return true;
   27984              : 
   27985         3120 :   if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_GOTOFF)
   27986            0 :     return true;
   27987              : 
   27988              :   return false;
   27989              : }
   27990              : 
   27991              : /* Return true iff ADDR can be used as a base address.  */
   27992              : 
   27993              : static bool
   27994         4879 : base_address_p (rtx addr)
   27995              : {
   27996            0 :   if (REG_P (addr))
   27997              :     return true;
   27998              : 
   27999         2998 :   if (symbolic_base_address_p (addr))
   28000            0 :     return true;
   28001              : 
   28002              :   return false;
   28003              : }
   28004              : 
   28005              : /* If MEM is in the form of [(base+symbase)+offset], extract the three
   28006              :    parts of address and set to BASE, SYMBASE and OFFSET, otherwise
   28007              :    return false.  */
   28008              : 
   28009              : static bool
   28010         3129 : extract_base_offset_in_addr (rtx mem, rtx *base, rtx *symbase, rtx *offset)
   28011              : {
   28012         3129 :   rtx addr;
   28013              : 
   28014         3129 :   gcc_assert (MEM_P (mem));
   28015              : 
   28016         3129 :   addr = XEXP (mem, 0);
   28017              : 
   28018         3129 :   if (GET_CODE (addr) == CONST)
   28019           10 :     addr = XEXP (addr, 0);
   28020              : 
   28021         3129 :   if (base_address_p (addr))
   28022              :     {
   28023         1379 :       *base = addr;
   28024         1379 :       *symbase = const0_rtx;
   28025         1379 :       *offset = const0_rtx;
   28026         1379 :       return true;
   28027              :     }
   28028              : 
   28029         1750 :   if (GET_CODE (addr) == PLUS
   28030         1750 :       && base_address_p (XEXP (addr, 0)))
   28031              :     {
   28032          537 :       rtx addend = XEXP (addr, 1);
   28033              : 
   28034          537 :       if (GET_CODE (addend) == CONST)
   28035            0 :         addend = XEXP (addend, 0);
   28036              : 
   28037          537 :       if (CONST_INT_P (addend))
   28038              :         {
   28039          380 :           *base = XEXP (addr, 0);
   28040          380 :           *symbase = const0_rtx;
   28041          380 :           *offset = addend;
   28042          380 :           return true;
   28043              :         }
   28044              : 
   28045              :       /* Also accept REG + symbolic ref, with or without a CONST_INT
   28046              :          offset.  */
   28047          157 :       if (REG_P (XEXP (addr, 0)))
   28048              :         {
   28049          157 :           if (symbolic_base_address_p (addend))
   28050              :             {
   28051            0 :               *base = XEXP (addr, 0);
   28052            0 :               *symbase = addend;
   28053            0 :               *offset = const0_rtx;
   28054            0 :               return true;
   28055              :             }
   28056              : 
   28057          157 :           if (GET_CODE (addend) == PLUS
   28058            0 :               && symbolic_base_address_p (XEXP (addend, 0))
   28059          157 :               && CONST_INT_P (XEXP (addend, 1)))
   28060              :             {
   28061            0 :               *base = XEXP (addr, 0);
   28062            0 :               *symbase = XEXP (addend, 0);
   28063            0 :               *offset = XEXP (addend, 1);
   28064            0 :               return true;
   28065              :             }
   28066              :         }
   28067              :     }
   28068              : 
   28069              :   return false;
   28070              : }
   28071              : 
   28072              : /* Given OPERANDS of consecutive load/store, check if we can merge
   28073              :    them into move multiple.  LOAD is true if they are load instructions.
   28074              :    MODE is the mode of memory operands.  */
   28075              : 
   28076              : bool
   28077         1715 : ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
   28078              :                                     machine_mode mode)
   28079              : {
   28080         1715 :   HOST_WIDE_INT offval_1, offval_2, msize;
   28081         1715 :   rtx mem_1, mem_2, reg_1, reg_2, base_1, base_2,
   28082              :     symbase_1, symbase_2, offset_1, offset_2;
   28083              : 
   28084         1715 :   if (load)
   28085              :     {
   28086         1354 :       mem_1 = operands[1];
   28087         1354 :       mem_2 = operands[3];
   28088              :       /* Avoid fusing two loads from distinct parameters as that might
   28089              :          cause STLF failure.  */
   28090         1354 :       tree base_1;
   28091         1354 :       if (MEM_EXPR (mem_1)
   28092         1346 :           && MEM_EXPR (mem_2)
   28093         1343 :           && (TREE_CODE (base_1 = get_base_address (MEM_EXPR (mem_1)))
   28094              :               == PARM_DECL)
   28095         1354 :           && get_base_address (MEM_EXPR (mem_2)) != base_1)
   28096              :         return false;
   28097         1354 :       reg_1 = operands[0];
   28098         1354 :       reg_2 = operands[2];
   28099              :     }
   28100              :   else
   28101              :     {
   28102          361 :       mem_1 = operands[0];
   28103          361 :       mem_2 = operands[2];
   28104          361 :       reg_1 = operands[1];
   28105          361 :       reg_2 = operands[3];
   28106              :     }
   28107              : 
   28108         1715 :   gcc_assert (REG_P (reg_1) && REG_P (reg_2));
   28109              : 
   28110         1715 :   if (REGNO (reg_1) != REGNO (reg_2))
   28111              :     return false;
   28112              : 
   28113              :   /* Check if the addresses are in the form of [base+offset].  */
   28114         1710 :   if (!extract_base_offset_in_addr (mem_1, &base_1, &symbase_1, &offset_1))
   28115              :     return false;
   28116         1419 :   if (!extract_base_offset_in_addr (mem_2, &base_2, &symbase_2, &offset_2))
   28117              :     return false;
   28118              : 
   28119              :   /* Check if the bases are the same.  */
   28120          340 :   if (!rtx_equal_p (base_1, base_2) || !rtx_equal_p (symbase_1, symbase_2))
   28121              :     return false;
   28122              : 
   28123          211 :   offval_1 = INTVAL (offset_1);
   28124          211 :   offval_2 = INTVAL (offset_2);
   28125          211 :   msize = GET_MODE_SIZE (mode);
   28126              :   /* Check if mem_1 is adjacent to mem_2 and mem_1 has lower address.  */
   28127          211 :   if (offval_1 + msize != offval_2)
   28128          164 :     return false;
   28129              : 
   28130              :   return true;
   28131              : }
   28132              : 
   28133              : /* Implement the TARGET_OPTAB_SUPPORTED_P hook.  */
   28134              : 
   28135              : static bool
   28136       349230 : ix86_optab_supported_p (int op, machine_mode mode1, machine_mode,
   28137              :                         optimization_type opt_type)
   28138              : {
   28139       349230 :   switch (op)
   28140              :     {
   28141          158 :     case asin_optab:
   28142          158 :     case acos_optab:
   28143          158 :     case log1p_optab:
   28144          158 :     case exp_optab:
   28145          158 :     case exp10_optab:
   28146          158 :     case exp2_optab:
   28147          158 :     case expm1_optab:
   28148          158 :     case ldexp_optab:
   28149          158 :     case scalb_optab:
   28150          158 :     case lround_optab:
   28151          158 :       return opt_type == OPTIMIZE_FOR_SPEED;
   28152              : 
   28153           82 :     case round_optab:
   28154              :       /* Inlined sequence for round may takes 2 more insns
   28155              :          than current -Os path. */
   28156           82 :       if (mode1 == HFmode)
   28157              :         return true;
   28158           78 :       return opt_type == OPTIMIZE_FOR_SPEED;
   28159              : 
   28160          286 :     case rint_optab:
   28161          286 :       if (SSE_FLOAT_MODE_P (mode1)
   28162          139 :           && TARGET_SSE_MATH
   28163          127 :           && !flag_trapping_math
   28164           21 :           && !TARGET_SSE4_1
   28165              :           && mode1 != HFmode)
   28166           21 :         return opt_type == OPTIMIZE_FOR_SPEED;
   28167              :       return true;
   28168              : 
   28169         2058 :     case floor_optab:
   28170         2058 :     case ceil_optab:
   28171         2058 :     case btrunc_optab:
   28172         2058 :       if ((SSE_FLOAT_MODE_P (mode1)
   28173         1597 :            && TARGET_SSE_MATH
   28174         1530 :            && TARGET_SSE4_1)
   28175         1991 :           || mode1 == HFmode)
   28176              :         return true;
   28177         1913 :       return opt_type == OPTIMIZE_FOR_SPEED;
   28178              : 
   28179           66 :     case rsqrt_optab:
   28180           66 :       return opt_type == OPTIMIZE_FOR_SPEED && use_rsqrt_p (mode1);
   28181              : 
   28182              :     default:
   28183              :       return true;
   28184              :     }
   28185              : }
   28186              : 
   28187              : /* Address space support.
   28188              : 
   28189              :    This is not "far pointers" in the 16-bit sense, but an easy way
   28190              :    to use %fs and %gs segment prefixes.  Therefore:
   28191              : 
   28192              :     (a) All address spaces have the same modes,
   28193              :     (b) All address spaces have the same address forms,
   28194              :     (c) While %fs and %gs are technically subsets of the generic
   28195              :         address space, they are probably not subsets of each other.
   28196              :     (d) Since we have no access to the segment base register values
   28197              :         without resorting to a system call, we cannot convert a
   28198              :         non-default address space to a default address space.
   28199              :         Therefore we do not claim %fs or %gs are subsets of generic.
   28200              : 
   28201              :    Therefore we can (mostly) use the default hooks.  */
   28202              : 
   28203              : /* All use of segmentation is assumed to make address 0 valid.  */
   28204              : 
   28205              : static bool
   28206     70078986 : ix86_addr_space_zero_address_valid (addr_space_t as)
   28207              : {
   28208     70078986 :   return as != ADDR_SPACE_GENERIC;
   28209              : }
   28210              : 
   28211              : static void
   28212       791509 : ix86_init_libfuncs (void)
   28213              : {
   28214       791509 :   if (TARGET_64BIT)
   28215              :     {
   28216       776467 :       set_optab_libfunc (sdivmod_optab, TImode, "__divmodti4");
   28217       776467 :       set_optab_libfunc (udivmod_optab, TImode, "__udivmodti4");
   28218              :     }
   28219              :   else
   28220              :     {
   28221        15042 :       set_optab_libfunc (sdivmod_optab, DImode, "__divmoddi4");
   28222        15042 :       set_optab_libfunc (udivmod_optab, DImode, "__udivmoddi4");
   28223              :     }
   28224              : 
   28225              : #if TARGET_MACHO
   28226              :   darwin_rename_builtins ();
   28227              : #endif
   28228       791509 : }
   28229              : 
   28230              : /* Set the value of FLT_EVAL_METHOD in float.h.  When using only the
   28231              :    FPU, assume that the fpcw is set to extended precision; when using
   28232              :    only SSE, rounding is correct; when using both SSE and the FPU,
   28233              :    the rounding precision is indeterminate, since either may be chosen
   28234              :    apparently at random.  */
   28235              : 
   28236              : static enum flt_eval_method
   28237     92106789 : ix86_get_excess_precision (enum excess_precision_type type)
   28238              : {
   28239     92106789 :   switch (type)
   28240              :     {
   28241     87974471 :       case EXCESS_PRECISION_TYPE_FAST:
   28242              :         /* The fastest type to promote to will always be the native type,
   28243              :            whether that occurs with implicit excess precision or
   28244              :            otherwise.  */
   28245     87974471 :         return TARGET_AVX512FP16
   28246     87974471 :                ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16
   28247     87974471 :                : FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   28248      4131574 :       case EXCESS_PRECISION_TYPE_STANDARD:
   28249      4131574 :       case EXCESS_PRECISION_TYPE_IMPLICIT:
   28250              :         /* Otherwise, the excess precision we want when we are
   28251              :            in a standards compliant mode, and the implicit precision we
   28252              :            provide would be identical were it not for the unpredictable
   28253              :            cases.  */
   28254      4131574 :         if (TARGET_AVX512FP16 && TARGET_SSE_MATH)
   28255              :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   28256      4125647 :         else if (!TARGET_80387)
   28257              :           return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   28258      4119229 :         else if (!TARGET_MIX_SSE_I387)
   28259              :           {
   28260      4119057 :             if (!(TARGET_SSE && TARGET_SSE_MATH))
   28261              :               return FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE;
   28262      3130435 :             else if (TARGET_SSE2)
   28263              :               return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT;
   28264              :           }
   28265              : 
   28266              :         /* If we are in standards compliant mode, but we know we will
   28267              :            calculate in unpredictable precision, return
   28268              :            FLT_EVAL_METHOD_FLOAT.  There is no reason to introduce explicit
   28269              :            excess precision if the target can't guarantee it will honor
   28270              :            it.  */
   28271          336 :         return (type == EXCESS_PRECISION_TYPE_STANDARD
   28272          336 :                 ? FLT_EVAL_METHOD_PROMOTE_TO_FLOAT
   28273              :                 : FLT_EVAL_METHOD_UNPREDICTABLE);
   28274          744 :       case EXCESS_PRECISION_TYPE_FLOAT16:
   28275          744 :         if (TARGET_80387
   28276          738 :             && !(TARGET_SSE_MATH && TARGET_SSE))
   28277            4 :           error ("%<-fexcess-precision=16%> is not compatible with %<-mfpmath=387%>");
   28278              :         return FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16;
   28279            0 :       default:
   28280            0 :         gcc_unreachable ();
   28281              :     }
   28282              : 
   28283              :   return FLT_EVAL_METHOD_UNPREDICTABLE;
   28284              : }
   28285              : 
   28286              : /* Return true if _BitInt(N) is supported and fill its details into *INFO.  */
   28287              : bool
   28288       366772 : ix86_bitint_type_info (int n, struct bitint_info *info)
   28289              : {
   28290       366772 :   if (n <= 8)
   28291        12003 :     info->limb_mode = QImode;
   28292       354769 :   else if (n <= 16)
   28293         3722 :     info->limb_mode = HImode;
   28294       351047 :   else if (n <= 32 || (!TARGET_64BIT && n > 64))
   28295        47515 :     info->limb_mode = SImode;
   28296              :   else
   28297       303532 :     info->limb_mode = DImode;
   28298       366772 :   info->abi_limb_mode = info->limb_mode;
   28299       366772 :   info->big_endian = false;
   28300       366772 :   info->extended = bitint_ext_undef;
   28301       366772 :   return true;
   28302              : }
   28303              : 
   28304              : /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE.  Return DFmode, TFmode
   28305              :    or XFmode for TI_LONG_DOUBLE_TYPE which is for long double type,
   28306              :    based on long double bits, go with the default one for the others.  */
   28307              : 
   28308              : static machine_mode
   28309      3743243 : ix86_c_mode_for_floating_type (enum tree_index ti)
   28310              : {
   28311      3743243 :   if (ti == TI_LONG_DOUBLE_TYPE)
   28312       624378 :     return (TARGET_LONG_DOUBLE_64 ? DFmode
   28313       624346 :                                   : (TARGET_LONG_DOUBLE_128 ? TFmode : XFmode));
   28314      3118865 :   return default_mode_for_floating_type (ti);
   28315              : }
   28316              : 
   28317              : /* Returns modified FUNCTION_TYPE for cdtor callabi.  */
   28318              : tree
   28319        14894 : ix86_cxx_adjust_cdtor_callabi_fntype (tree fntype)
   28320              : {
   28321        14894 :   if (TARGET_64BIT
   28322           71 :       || TARGET_RTD
   28323        14965 :       || ix86_function_type_abi (fntype) != MS_ABI)
   28324              :     return fntype;
   28325              :   /* For 32-bit MS ABI add thiscall attribute.  */
   28326            0 :   tree attribs = tree_cons (get_identifier ("thiscall"), NULL_TREE,
   28327            0 :                             TYPE_ATTRIBUTES (fntype));
   28328            0 :   return build_type_attribute_variant (fntype, attribs);
   28329              : }
   28330              : 
   28331              : /* Implement PUSH_ROUNDING.  On 386, we have pushw instruction that
   28332              :    decrements by exactly 2 no matter what the position was, there is no pushb.
   28333              : 
   28334              :    But as CIE data alignment factor on this arch is -4 for 32bit targets
   28335              :    and -8 for 64bit targets, we need to make sure all stack pointer adjustments
   28336              :    are in multiple of 4 for 32bit targets and 8 for 64bit targets.  */
   28337              : 
   28338              : poly_int64
   28339    266453041 : ix86_push_rounding (poly_int64 bytes)
   28340              : {
   28341    342133456 :   return ROUND_UP (bytes, UNITS_PER_WORD);
   28342              : }
   28343              : 
   28344              : /* Use 8 bits metadata start from bit48 for LAM_U48,
   28345              :    6 bits metadata start from bit57 for LAM_U57.  */
   28346              : #define IX86_HWASAN_SHIFT (ix86_lam_type == lam_u48             \
   28347              :                            ? 48                                 \
   28348              :                            : (ix86_lam_type == lam_u57 ? 57 : 0))
   28349              : #define IX86_HWASAN_TAG_SIZE (ix86_lam_type == lam_u48          \
   28350              :                               ? 8                               \
   28351              :                               : (ix86_lam_type == lam_u57 ? 6 : 0))
   28352              : 
   28353              : /* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES.  */
   28354              : bool
   28355      6470718 : ix86_memtag_can_tag_addresses ()
   28356              : {
   28357      6470718 :   return ix86_lam_type != lam_none && TARGET_LP64;
   28358              : }
   28359              : 
   28360              : /* Implement TARGET_MEMTAG_TAG_BITSIZE.  */
   28361              : unsigned char
   28362          445 : ix86_memtag_tag_bitsize ()
   28363              : {
   28364          445 :   return IX86_HWASAN_TAG_SIZE;
   28365              : }
   28366              : 
   28367              : /* Implement TARGET_MEMTAG_SET_TAG.  */
   28368              : rtx
   28369          105 : ix86_memtag_set_tag (rtx untagged, rtx tag, rtx target)
   28370              : {
   28371              :   /* default_memtag_insert_random_tag may
   28372              :      generate tag with value more than 6 bits.  */
   28373          105 :   if (ix86_lam_type == lam_u57)
   28374              :     {
   28375          105 :       unsigned HOST_WIDE_INT and_imm
   28376              :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   28377              : 
   28378          105 :       emit_insn (gen_andqi3 (tag, tag, GEN_INT (and_imm)));
   28379              :     }
   28380          105 :   tag = expand_simple_binop (Pmode, ASHIFT, tag,
   28381          105 :                              GEN_INT (IX86_HWASAN_SHIFT), NULL_RTX,
   28382              :                              /* unsignedp = */1, OPTAB_WIDEN);
   28383          105 :   rtx ret = expand_simple_binop (Pmode, IOR, untagged, tag, target,
   28384              :                                  /* unsignedp = */1, OPTAB_DIRECT);
   28385          105 :   return ret;
   28386              : }
   28387              : 
   28388              : /* Implement TARGET_MEMTAG_EXTRACT_TAG.  */
   28389              : rtx
   28390          178 : ix86_memtag_extract_tag (rtx tagged_pointer, rtx target)
   28391              : {
   28392          178 :   rtx tag = expand_simple_binop (Pmode, LSHIFTRT, tagged_pointer,
   28393          178 :                                  GEN_INT (IX86_HWASAN_SHIFT), target,
   28394              :                                  /* unsignedp = */0,
   28395              :                                  OPTAB_DIRECT);
   28396          178 :   rtx ret = gen_reg_rtx (QImode);
   28397              :   /* Mask off bit63 when LAM_U57.  */
   28398          178 :   if (ix86_lam_type == lam_u57)
   28399              :     {
   28400          178 :       unsigned HOST_WIDE_INT and_imm
   28401              :         = (HOST_WIDE_INT_1U << IX86_HWASAN_TAG_SIZE) - 1;
   28402          178 :       emit_insn (gen_andqi3 (ret, gen_lowpart (QImode, tag),
   28403          178 :                              gen_int_mode (and_imm, QImode)));
   28404              :     }
   28405              :   else
   28406            0 :     emit_move_insn (ret, gen_lowpart (QImode, tag));
   28407          178 :   return ret;
   28408              : }
   28409              : 
   28410              : /* The default implementation of TARGET_MEMTAG_UNTAGGED_POINTER.  */
   28411              : rtx
   28412          113 : ix86_memtag_untagged_pointer (rtx tagged_pointer, rtx target)
   28413              : {
   28414              :   /* Leave bit63 alone.  */
   28415          113 :   rtx tag_mask = gen_int_mode (((HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT)
   28416          113 :                                 + (HOST_WIDE_INT_1U << 63) - 1),
   28417          113 :                                Pmode);
   28418          113 :   rtx untagged_base = expand_simple_binop (Pmode, AND, tagged_pointer,
   28419              :                                            tag_mask, target, true,
   28420              :                                            OPTAB_DIRECT);
   28421          113 :   gcc_assert (untagged_base);
   28422          113 :   return untagged_base;
   28423              : }
   28424              : 
   28425              : /* Implement TARGET_MEMTAG_ADD_TAG.  */
   28426              : rtx
   28427           89 : ix86_memtag_add_tag (rtx base, poly_int64 offset, unsigned char tag_offset)
   28428              : {
   28429           89 :   rtx base_tag = gen_reg_rtx (QImode);
   28430           89 :   rtx base_addr = gen_reg_rtx (Pmode);
   28431           89 :   rtx tagged_addr = gen_reg_rtx (Pmode);
   28432           89 :   rtx new_tag = gen_reg_rtx (QImode);
   28433          178 :   unsigned HOST_WIDE_INT and_imm
   28434           89 :     = (HOST_WIDE_INT_1U << IX86_HWASAN_SHIFT) - 1;
   28435              : 
   28436              :   /* When there's "overflow" in tag adding,
   28437              :      need to mask the most significant bit off.  */
   28438           89 :   emit_move_insn (base_tag, ix86_memtag_extract_tag (base, NULL_RTX));
   28439           89 :   emit_move_insn (base_addr,
   28440              :                   ix86_memtag_untagged_pointer (base, NULL_RTX));
   28441           89 :   emit_insn (gen_add2_insn (base_tag, gen_int_mode (tag_offset, QImode)));
   28442           89 :   emit_move_insn (new_tag, base_tag);
   28443           89 :   emit_insn (gen_andqi3 (new_tag, new_tag, gen_int_mode (and_imm, QImode)));
   28444           89 :   emit_move_insn (tagged_addr,
   28445              :                   ix86_memtag_set_tag (base_addr, new_tag, NULL_RTX));
   28446           89 :   return plus_constant (Pmode, tagged_addr, offset);
   28447              : }
   28448              : 
   28449              : /* Implement TARGET_HAVE_CCMP.  */
   28450              : static bool
   28451      8414576 : ix86_have_ccmp ()
   28452              : {
   28453      8414576 :   return (bool) TARGET_APX_CCMP;
   28454              : }
   28455              : 
   28456              : /* Implement TARGET_MODE_CAN_TRANSFER_BITS.  */
   28457              : static bool
   28458      4834480 : ix86_mode_can_transfer_bits (machine_mode mode)
   28459              : {
   28460      4834480 :   if (GET_MODE_CLASS (mode) == MODE_FLOAT
   28461      4783070 :       || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
   28462       124474 :     switch (GET_MODE_INNER (mode))
   28463              :       {
   28464        56558 :       case E_SFmode:
   28465        56558 :       case E_DFmode:
   28466              :         /* These suffer from normalization upon load when not using SSE.  */
   28467        56558 :         return !(ix86_fpmath & FPMATH_387);
   28468              :       default:
   28469              :         return true;
   28470              :       }
   28471              : 
   28472              :   return true;
   28473              : }
   28474              : 
   28475              : /* Implement TARGET_REDZONE_CLOBBER.  */
   28476              : static rtx
   28477            2 : ix86_redzone_clobber ()
   28478              : {
   28479            2 :   cfun->machine->asm_redzone_clobber_seen = true;
   28480            2 :   if (ix86_using_red_zone ())
   28481              :     {
   28482            2 :       rtx base = plus_constant (Pmode, stack_pointer_rtx, -RED_ZONE_SIZE);
   28483            2 :       rtx mem = gen_rtx_MEM (BLKmode, base);
   28484            2 :       set_mem_size (mem, RED_ZONE_SIZE);
   28485            2 :       return mem;
   28486              :     }
   28487              :   return NULL_RTX;
   28488              : }
   28489              : 
   28490              : /* Target-specific selftests.  */
   28491              : 
   28492              : #if CHECKING_P
   28493              : 
   28494              : namespace selftest {
   28495              : 
   28496              : /* Verify that hard regs are dumped as expected (in compact mode).  */
   28497              : 
   28498              : static void
   28499            4 : ix86_test_dumping_hard_regs ()
   28500              : {
   28501            4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI ax)", gen_raw_REG (SImode, 0));
   28502            4 :   ASSERT_RTL_DUMP_EQ ("(reg:SI dx)", gen_raw_REG (SImode, 1));
   28503            4 : }
   28504              : 
   28505              : /* Test dumping an insn with repeated references to the same SCRATCH,
   28506              :    to verify the rtx_reuse code.  */
   28507              : 
   28508              : static void
   28509            4 : ix86_test_dumping_memory_blockage ()
   28510              : {
   28511            4 :   set_new_first_and_last_insn (NULL, NULL);
   28512              : 
   28513            4 :   rtx pat = gen_memory_blockage ();
   28514            4 :   rtx_reuse_manager r;
   28515            4 :   r.preprocess (pat);
   28516              : 
   28517              :   /* Verify that the repeated references to the SCRATCH show use
   28518              :      reuse IDS.  The first should be prefixed with a reuse ID,
   28519              :      and the second should be dumped as a "reuse_rtx" of that ID.
   28520              :      The expected string assumes Pmode == DImode.  */
   28521            4 :   if (Pmode == DImode)
   28522            4 :     ASSERT_RTL_DUMP_EQ_WITH_REUSE
   28523              :       ("(cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0  A8])\n"
   28524              :        "        (unspec:BLK [\n"
   28525              :        "                (mem/v:BLK (reuse_rtx 0) [0  A8])\n"
   28526              :        "            ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r);
   28527            4 : }
   28528              : 
   28529              : /* Verify loading an RTL dump; specifically a dump of copying
   28530              :    a param on x86_64 from a hard reg into the frame.
   28531              :    This test is target-specific since the dump contains target-specific
   28532              :    hard reg names.  */
   28533              : 
   28534              : static void
   28535            4 : ix86_test_loading_dump_fragment_1 ()
   28536              : {
   28537            4 :   rtl_dump_test t (SELFTEST_LOCATION,
   28538            4 :                    locate_file ("x86_64/copy-hard-reg-into-frame.rtl"));
   28539              : 
   28540            4 :   rtx_insn *insn = get_insn_by_uid (1);
   28541              : 
   28542              :   /* The block structure and indentation here is purely for
   28543              :      readability; it mirrors the structure of the rtx.  */
   28544            4 :   tree mem_expr;
   28545            4 :   {
   28546            4 :     rtx pat = PATTERN (insn);
   28547            4 :     ASSERT_EQ (SET, GET_CODE (pat));
   28548            4 :     {
   28549            4 :       rtx dest = SET_DEST (pat);
   28550            4 :       ASSERT_EQ (MEM, GET_CODE (dest));
   28551              :       /* Verify the "/c" was parsed.  */
   28552            4 :       ASSERT_TRUE (RTX_FLAG (dest, call));
   28553            4 :       ASSERT_EQ (SImode, GET_MODE (dest));
   28554            4 :       {
   28555            4 :         rtx addr = XEXP (dest, 0);
   28556            4 :         ASSERT_EQ (PLUS, GET_CODE (addr));
   28557            4 :         ASSERT_EQ (DImode, GET_MODE (addr));
   28558            4 :         {
   28559            4 :           rtx lhs = XEXP (addr, 0);
   28560              :           /* Verify that the "frame" REG was consolidated.  */
   28561            4 :           ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs);
   28562              :         }
   28563            4 :         {
   28564            4 :           rtx rhs = XEXP (addr, 1);
   28565            4 :           ASSERT_EQ (CONST_INT, GET_CODE (rhs));
   28566            4 :           ASSERT_EQ (-4, INTVAL (rhs));
   28567              :         }
   28568              :       }
   28569              :       /* Verify the "[1 i+0 S4 A32]" was parsed.  */
   28570            4 :       ASSERT_EQ (1, MEM_ALIAS_SET (dest));
   28571              :       /* "i" should have been handled by synthesizing a global int
   28572              :          variable named "i".  */
   28573            4 :       mem_expr = MEM_EXPR (dest);
   28574            4 :       ASSERT_NE (mem_expr, NULL);
   28575            4 :       ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr));
   28576            4 :       ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr));
   28577            4 :       ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr)));
   28578            4 :       ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr)));
   28579              :       /* "+0".  */
   28580            4 :       ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest));
   28581            4 :       ASSERT_EQ (0, MEM_OFFSET (dest));
   28582              :       /* "S4".  */
   28583            4 :       ASSERT_EQ (4, MEM_SIZE (dest));
   28584              :       /* "A32.  */
   28585            4 :       ASSERT_EQ (32, MEM_ALIGN (dest));
   28586              :     }
   28587            4 :     {
   28588            4 :       rtx src = SET_SRC (pat);
   28589            4 :       ASSERT_EQ (REG, GET_CODE (src));
   28590            4 :       ASSERT_EQ (SImode, GET_MODE (src));
   28591            4 :       ASSERT_EQ (5, REGNO (src));
   28592            4 :       tree reg_expr = REG_EXPR (src);
   28593              :       /* "i" here should point to the same var as for the MEM_EXPR.  */
   28594            4 :       ASSERT_EQ (reg_expr, mem_expr);
   28595              :     }
   28596              :   }
   28597            4 : }
   28598              : 
   28599              : /* Verify that the RTL loader copes with a call_insn dump.
   28600              :    This test is target-specific since the dump contains a target-specific
   28601              :    hard reg name.  */
   28602              : 
   28603              : static void
   28604            4 : ix86_test_loading_call_insn ()
   28605              : {
   28606              :   /* The test dump includes register "xmm0", where requires TARGET_SSE
   28607              :      to exist.  */
   28608            4 :   if (!TARGET_SSE)
   28609            0 :     return;
   28610              : 
   28611            4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl"));
   28612              : 
   28613            4 :   rtx_insn *insn = get_insns ();
   28614            4 :   ASSERT_EQ (CALL_INSN, GET_CODE (insn));
   28615              : 
   28616              :   /* "/j".  */
   28617            4 :   ASSERT_TRUE (RTX_FLAG (insn, jump));
   28618              : 
   28619            4 :   rtx pat = PATTERN (insn);
   28620            4 :   ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat)));
   28621              : 
   28622              :   /* Verify REG_NOTES.  */
   28623            4 :   {
   28624              :     /* "(expr_list:REG_CALL_DECL".   */
   28625            4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn)));
   28626            4 :     rtx_expr_list *note0 = as_a <rtx_expr_list *> (REG_NOTES (insn));
   28627            4 :     ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0));
   28628              : 
   28629              :     /* "(expr_list:REG_EH_REGION (const_int 0 [0])".  */
   28630            4 :     rtx_expr_list *note1 = note0->next ();
   28631            4 :     ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1));
   28632              : 
   28633            4 :     ASSERT_EQ (NULL, note1->next ());
   28634              :   }
   28635              : 
   28636              :   /* Verify CALL_INSN_FUNCTION_USAGE.  */
   28637            4 :   {
   28638              :     /* "(expr_list:DF (use (reg:DF 21 xmm0))".  */
   28639            4 :     rtx_expr_list *usage
   28640            4 :       = as_a <rtx_expr_list *> (CALL_INSN_FUNCTION_USAGE (insn));
   28641            4 :     ASSERT_EQ (EXPR_LIST, GET_CODE (usage));
   28642            4 :     ASSERT_EQ (DFmode, GET_MODE (usage));
   28643            4 :     ASSERT_EQ (USE, GET_CODE (usage->element ()));
   28644            4 :     ASSERT_EQ (NULL, usage->next ());
   28645              :   }
   28646            4 : }
   28647              : 
   28648              : /* Verify that the RTL loader copes a dump from print_rtx_function.
   28649              :    This test is target-specific since the dump contains target-specific
   28650              :    hard reg names.  */
   28651              : 
   28652              : static void
   28653            4 : ix86_test_loading_full_dump ()
   28654              : {
   28655            4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl"));
   28656              : 
   28657            4 :   ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   28658              : 
   28659            4 :   rtx_insn *insn_1 = get_insn_by_uid (1);
   28660            4 :   ASSERT_EQ (NOTE, GET_CODE (insn_1));
   28661              : 
   28662            4 :   rtx_insn *insn_7 = get_insn_by_uid (7);
   28663            4 :   ASSERT_EQ (INSN, GET_CODE (insn_7));
   28664            4 :   ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7)));
   28665              : 
   28666            4 :   rtx_insn *insn_15 = get_insn_by_uid (15);
   28667            4 :   ASSERT_EQ (INSN, GET_CODE (insn_15));
   28668            4 :   ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15)));
   28669              : 
   28670              :   /* Verify crtl->return_rtx.  */
   28671            4 :   ASSERT_EQ (REG, GET_CODE (crtl->return_rtx));
   28672            4 :   ASSERT_EQ (0, REGNO (crtl->return_rtx));
   28673            4 :   ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx));
   28674            4 : }
   28675              : 
   28676              : /* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns.
   28677              :    In particular, verify that it correctly loads the 2nd operand.
   28678              :    This test is target-specific since these are machine-specific
   28679              :    operands (and enums).  */
   28680              : 
   28681              : static void
   28682            4 : ix86_test_loading_unspec ()
   28683              : {
   28684            4 :   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl"));
   28685              : 
   28686            4 :   ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
   28687              : 
   28688            4 :   ASSERT_TRUE (cfun);
   28689              : 
   28690              :   /* Test of an UNSPEC.  */
   28691            4 :    rtx_insn *insn = get_insns ();
   28692            4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   28693            4 :   rtx set = single_set (insn);
   28694            4 :   ASSERT_NE (NULL, set);
   28695            4 :   rtx dst = SET_DEST (set);
   28696            4 :   ASSERT_EQ (MEM, GET_CODE (dst));
   28697            4 :   rtx src = SET_SRC (set);
   28698            4 :   ASSERT_EQ (UNSPEC, GET_CODE (src));
   28699            4 :   ASSERT_EQ (BLKmode, GET_MODE (src));
   28700            4 :   ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1));
   28701              : 
   28702            4 :   rtx v0 = XVECEXP (src, 0, 0);
   28703              : 
   28704              :   /* Verify that the two uses of the first SCRATCH have pointer
   28705              :      equality.  */
   28706            4 :   rtx scratch_a = XEXP (dst, 0);
   28707            4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_a));
   28708              : 
   28709            4 :   rtx scratch_b = XEXP (v0, 0);
   28710            4 :   ASSERT_EQ (SCRATCH, GET_CODE (scratch_b));
   28711              : 
   28712            4 :   ASSERT_EQ (scratch_a, scratch_b);
   28713              : 
   28714              :   /* Verify that the two mems are thus treated as equal.  */
   28715            4 :   ASSERT_TRUE (rtx_equal_p (dst, v0));
   28716              : 
   28717              :   /* Verify that the insn is recognized.  */
   28718            4 :   ASSERT_NE(-1, recog_memoized (insn));
   28719              : 
   28720              :   /* Test of an UNSPEC_VOLATILE, which has its own enum values.  */
   28721            4 :   insn = NEXT_INSN (insn);
   28722            4 :   ASSERT_EQ (INSN, GET_CODE (insn));
   28723              : 
   28724            4 :   set = single_set (insn);
   28725            4 :   ASSERT_NE (NULL, set);
   28726              : 
   28727            4 :   src = SET_SRC (set);
   28728            4 :   ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src));
   28729            4 :   ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1));
   28730            4 : }
   28731              : 
   28732              : /* Run all target-specific selftests.  */
   28733              : 
   28734              : static void
   28735            4 : ix86_run_selftests (void)
   28736              : {
   28737            4 :   ix86_test_dumping_hard_regs ();
   28738            4 :   ix86_test_dumping_memory_blockage ();
   28739              : 
   28740              :   /* Various tests of loading RTL dumps, here because they contain
   28741              :      ix86-isms (e.g. names of hard regs).  */
   28742            4 :   ix86_test_loading_dump_fragment_1 ();
   28743            4 :   ix86_test_loading_call_insn ();
   28744            4 :   ix86_test_loading_full_dump ();
   28745            4 :   ix86_test_loading_unspec ();
   28746            4 : }
   28747              : 
   28748              : } // namespace selftest
   28749              : 
   28750              : #endif /* CHECKING_P */
   28751              : 
   28752              : static const scoped_attribute_specs *const ix86_attribute_table[] =
   28753              : {
   28754              :   &ix86_gnu_attribute_table
   28755              : };
   28756              : 
   28757              : /* Initialize the GCC target structure.  */
   28758              : #undef TARGET_RETURN_IN_MEMORY
   28759              : #define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
   28760              : 
   28761              : #undef TARGET_LEGITIMIZE_ADDRESS
   28762              : #define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
   28763              : 
   28764              : #undef TARGET_ATTRIBUTE_TABLE
   28765              : #define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
   28766              : #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
   28767              : #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
   28768              : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   28769              : #  undef TARGET_MERGE_DECL_ATTRIBUTES
   28770              : #  define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
   28771              : #endif
   28772              : 
   28773              : #undef TARGET_INVALID_CONVERSION
   28774              : #define TARGET_INVALID_CONVERSION ix86_invalid_conversion
   28775              : 
   28776              : #undef TARGET_INVALID_UNARY_OP
   28777              : #define TARGET_INVALID_UNARY_OP ix86_invalid_unary_op
   28778              : 
   28779              : #undef TARGET_INVALID_BINARY_OP
   28780              : #define TARGET_INVALID_BINARY_OP ix86_invalid_binary_op
   28781              : 
   28782              : #undef TARGET_COMP_TYPE_ATTRIBUTES
   28783              : #define TARGET_COMP_TYPE_ATTRIBUTES ix86_comp_type_attributes
   28784              : 
   28785              : #undef TARGET_INIT_BUILTINS
   28786              : #define TARGET_INIT_BUILTINS ix86_init_builtins
   28787              : #undef TARGET_BUILTIN_DECL
   28788              : #define TARGET_BUILTIN_DECL ix86_builtin_decl
   28789              : #undef TARGET_EXPAND_BUILTIN
   28790              : #define TARGET_EXPAND_BUILTIN ix86_expand_builtin
   28791              : 
   28792              : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
   28793              : #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
   28794              :   ix86_builtin_vectorized_function
   28795              : 
   28796              : #undef TARGET_VECTORIZE_BUILTIN_GATHER
   28797              : #define TARGET_VECTORIZE_BUILTIN_GATHER ix86_vectorize_builtin_gather
   28798              : 
   28799              : #undef TARGET_VECTORIZE_BUILTIN_SCATTER
   28800              : #define TARGET_VECTORIZE_BUILTIN_SCATTER ix86_vectorize_builtin_scatter
   28801              : 
   28802              : #undef TARGET_BUILTIN_RECIPROCAL
   28803              : #define TARGET_BUILTIN_RECIPROCAL ix86_builtin_reciprocal
   28804              : 
   28805              : #undef TARGET_ASM_FUNCTION_EPILOGUE
   28806              : #define TARGET_ASM_FUNCTION_EPILOGUE ix86_output_function_epilogue
   28807              : 
   28808              : #undef TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY
   28809              : #define TARGET_ASM_PRINT_PATCHABLE_FUNCTION_ENTRY \
   28810              :   ix86_print_patchable_function_entry
   28811              : 
   28812              : #undef TARGET_ENCODE_SECTION_INFO
   28813              : #ifndef SUBTARGET_ENCODE_SECTION_INFO
   28814              : #define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
   28815              : #else
   28816              : #define TARGET_ENCODE_SECTION_INFO SUBTARGET_ENCODE_SECTION_INFO
   28817              : #endif
   28818              : 
   28819              : #undef TARGET_ASM_OPEN_PAREN
   28820              : #define TARGET_ASM_OPEN_PAREN ""
   28821              : #undef TARGET_ASM_CLOSE_PAREN
   28822              : #define TARGET_ASM_CLOSE_PAREN ""
   28823              : 
   28824              : #undef TARGET_ASM_BYTE_OP
   28825              : #define TARGET_ASM_BYTE_OP ASM_BYTE
   28826              : 
   28827              : #undef TARGET_ASM_ALIGNED_HI_OP
   28828              : #define TARGET_ASM_ALIGNED_HI_OP ASM_SHORT
   28829              : #undef TARGET_ASM_ALIGNED_SI_OP
   28830              : #define TARGET_ASM_ALIGNED_SI_OP ASM_LONG
   28831              : #ifdef ASM_QUAD
   28832              : #undef TARGET_ASM_ALIGNED_DI_OP
   28833              : #define TARGET_ASM_ALIGNED_DI_OP ASM_QUAD
   28834              : #endif
   28835              : 
   28836              : #undef TARGET_PROFILE_BEFORE_PROLOGUE
   28837              : #define TARGET_PROFILE_BEFORE_PROLOGUE ix86_profile_before_prologue
   28838              : 
   28839              : #undef TARGET_MANGLE_DECL_ASSEMBLER_NAME
   28840              : #define TARGET_MANGLE_DECL_ASSEMBLER_NAME ix86_mangle_decl_assembler_name
   28841              : 
   28842              : #undef TARGET_ASM_UNALIGNED_HI_OP
   28843              : #define TARGET_ASM_UNALIGNED_HI_OP TARGET_ASM_ALIGNED_HI_OP
   28844              : #undef TARGET_ASM_UNALIGNED_SI_OP
   28845              : #define TARGET_ASM_UNALIGNED_SI_OP TARGET_ASM_ALIGNED_SI_OP
   28846              : #undef TARGET_ASM_UNALIGNED_DI_OP
   28847              : #define TARGET_ASM_UNALIGNED_DI_OP TARGET_ASM_ALIGNED_DI_OP
   28848              : 
   28849              : #undef TARGET_PRINT_OPERAND
   28850              : #define TARGET_PRINT_OPERAND ix86_print_operand
   28851              : #undef TARGET_PRINT_OPERAND_ADDRESS
   28852              : #define TARGET_PRINT_OPERAND_ADDRESS ix86_print_operand_address
   28853              : #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   28854              : #define TARGET_PRINT_OPERAND_PUNCT_VALID_P ix86_print_operand_punct_valid_p
   28855              : #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
   28856              : #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA i386_asm_output_addr_const_extra
   28857              : 
   28858              : #undef TARGET_SCHED_INIT_GLOBAL
   28859              : #define TARGET_SCHED_INIT_GLOBAL ix86_sched_init_global
   28860              : #undef TARGET_SCHED_ADJUST_COST
   28861              : #define TARGET_SCHED_ADJUST_COST ix86_adjust_cost
   28862              : #undef TARGET_SCHED_ISSUE_RATE
   28863              : #define TARGET_SCHED_ISSUE_RATE ix86_issue_rate
   28864              : #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
   28865              : #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   28866              :   ia32_multipass_dfa_lookahead
   28867              : #undef TARGET_SCHED_MACRO_FUSION_P
   28868              : #define TARGET_SCHED_MACRO_FUSION_P ix86_macro_fusion_p
   28869              : #undef TARGET_SCHED_MACRO_FUSION_PAIR_P
   28870              : #define TARGET_SCHED_MACRO_FUSION_PAIR_P ix86_macro_fusion_pair_p
   28871              : 
   28872              : #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   28873              : #define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
   28874              : 
   28875              : #undef TARGET_MEMMODEL_CHECK
   28876              : #define TARGET_MEMMODEL_CHECK ix86_memmodel_check
   28877              : 
   28878              : #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
   28879              : #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV ix86_atomic_assign_expand_fenv
   28880              : 
   28881              : #ifdef HAVE_AS_TLS
   28882              : #undef TARGET_HAVE_TLS
   28883              : #define TARGET_HAVE_TLS true
   28884              : #endif
   28885              : #undef TARGET_CANNOT_FORCE_CONST_MEM
   28886              : #define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
   28887              : #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
   28888              : #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
   28889              : 
   28890              : #undef TARGET_DELEGITIMIZE_ADDRESS
   28891              : #define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
   28892              : 
   28893              : #undef TARGET_CONST_NOT_OK_FOR_DEBUG_P
   28894              : #define TARGET_CONST_NOT_OK_FOR_DEBUG_P ix86_const_not_ok_for_debug_p
   28895              : 
   28896              : #undef TARGET_MS_BITFIELD_LAYOUT_P
   28897              : #define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
   28898              : 
   28899              : #if TARGET_MACHO
   28900              : #undef TARGET_BINDS_LOCAL_P
   28901              : #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
   28902              : #else
   28903              : #undef TARGET_BINDS_LOCAL_P
   28904              : #define TARGET_BINDS_LOCAL_P ix86_binds_local_p
   28905              : #endif
   28906              : #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   28907              : #undef TARGET_BINDS_LOCAL_P
   28908              : #define TARGET_BINDS_LOCAL_P i386_pe_binds_local_p
   28909              : #endif
   28910              : 
   28911              : #undef TARGET_ASM_OUTPUT_MI_THUNK
   28912              : #define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
   28913              : #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   28914              : #define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
   28915              : 
   28916              : #undef TARGET_ASM_FILE_START
   28917              : #define TARGET_ASM_FILE_START x86_file_start
   28918              : 
   28919              : #undef TARGET_OPTION_OVERRIDE
   28920              : #define TARGET_OPTION_OVERRIDE ix86_option_override
   28921              : 
   28922              : #undef TARGET_REGISTER_MOVE_COST
   28923              : #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
   28924              : #undef TARGET_MEMORY_MOVE_COST
   28925              : #define TARGET_MEMORY_MOVE_COST ix86_memory_move_cost
   28926              : #undef TARGET_RTX_COSTS
   28927              : #define TARGET_RTX_COSTS ix86_rtx_costs
   28928              : #undef TARGET_INSN_COST
   28929              : #define TARGET_INSN_COST ix86_insn_cost
   28930              : #undef TARGET_ADDRESS_COST
   28931              : #define TARGET_ADDRESS_COST ix86_address_cost
   28932              : 
   28933              : #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
   28934              : #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
   28935              :   ix86_use_by_pieces_infrastructure_p
   28936              : 
   28937              : #undef TARGET_OVERLAP_OP_BY_PIECES_P
   28938              : #define TARGET_OVERLAP_OP_BY_PIECES_P hook_bool_void_true
   28939              : 
   28940              : #undef TARGET_FLAGS_REGNUM
   28941              : #define TARGET_FLAGS_REGNUM FLAGS_REG
   28942              : #undef TARGET_FIXED_CONDITION_CODE_REGS
   28943              : #define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
   28944              : #undef TARGET_CC_MODES_COMPATIBLE
   28945              : #define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
   28946              : 
   28947              : #undef TARGET_MACHINE_DEPENDENT_REORG
   28948              : #define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
   28949              : 
   28950              : #undef TARGET_BUILD_BUILTIN_VA_LIST
   28951              : #define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
   28952              : 
   28953              : #undef TARGET_FOLD_BUILTIN
   28954              : #define TARGET_FOLD_BUILTIN ix86_fold_builtin
   28955              : 
   28956              : #undef TARGET_GIMPLE_FOLD_BUILTIN
   28957              : #define TARGET_GIMPLE_FOLD_BUILTIN ix86_gimple_fold_builtin
   28958              : 
   28959              : #undef TARGET_COMPARE_VERSION_PRIORITY
   28960              : #define TARGET_COMPARE_VERSION_PRIORITY ix86_compare_version_priority
   28961              : 
   28962              : #undef TARGET_GENERATE_VERSION_DISPATCHER_BODY
   28963              : #define TARGET_GENERATE_VERSION_DISPATCHER_BODY \
   28964              :   ix86_generate_version_dispatcher_body
   28965              : 
   28966              : #undef TARGET_GET_FUNCTION_VERSIONS_DISPATCHER
   28967              : #define TARGET_GET_FUNCTION_VERSIONS_DISPATCHER \
   28968              :   ix86_get_function_versions_dispatcher
   28969              : 
   28970              : #undef TARGET_ENUM_VA_LIST_P
   28971              : #define TARGET_ENUM_VA_LIST_P ix86_enum_va_list
   28972              : 
   28973              : #undef TARGET_FN_ABI_VA_LIST
   28974              : #define TARGET_FN_ABI_VA_LIST ix86_fn_abi_va_list
   28975              : 
   28976              : #undef TARGET_CANONICAL_VA_LIST_TYPE
   28977              : #define TARGET_CANONICAL_VA_LIST_TYPE ix86_canonical_va_list_type
   28978              : 
   28979              : #undef TARGET_EXPAND_BUILTIN_VA_START
   28980              : #define TARGET_EXPAND_BUILTIN_VA_START ix86_va_start
   28981              : 
   28982              : #undef TARGET_MD_ASM_ADJUST
   28983              : #define TARGET_MD_ASM_ADJUST ix86_md_asm_adjust
   28984              : 
   28985              : #undef TARGET_C_EXCESS_PRECISION
   28986              : #define TARGET_C_EXCESS_PRECISION ix86_get_excess_precision
   28987              : #undef TARGET_C_BITINT_TYPE_INFO
   28988              : #define TARGET_C_BITINT_TYPE_INFO ix86_bitint_type_info
   28989              : #undef TARGET_C_MODE_FOR_FLOATING_TYPE
   28990              : #define TARGET_C_MODE_FOR_FLOATING_TYPE ix86_c_mode_for_floating_type
   28991              : #undef TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE
   28992              : #define TARGET_CXX_ADJUST_CDTOR_CALLABI_FNTYPE ix86_cxx_adjust_cdtor_callabi_fntype
   28993              : #undef TARGET_PROMOTE_PROTOTYPES
   28994              : #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
   28995              : #undef TARGET_PUSH_ARGUMENT
   28996              : #define TARGET_PUSH_ARGUMENT ix86_push_argument
   28997              : #undef TARGET_SETUP_INCOMING_VARARGS
   28998              : #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
   28999              : #undef TARGET_MUST_PASS_IN_STACK
   29000              : #define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
   29001              : #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
   29002              : #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ix86_allocate_stack_slots_for_args
   29003              : #undef TARGET_FUNCTION_ARG_ADVANCE
   29004              : #define TARGET_FUNCTION_ARG_ADVANCE ix86_function_arg_advance
   29005              : #undef TARGET_FUNCTION_ARG
   29006              : #define TARGET_FUNCTION_ARG ix86_function_arg
   29007              : #undef TARGET_INIT_PIC_REG
   29008              : #define TARGET_INIT_PIC_REG ix86_init_pic_reg
   29009              : #undef TARGET_USE_PSEUDO_PIC_REG
   29010              : #define TARGET_USE_PSEUDO_PIC_REG ix86_use_pseudo_pic_reg
   29011              : #undef TARGET_FUNCTION_ARG_BOUNDARY
   29012              : #define TARGET_FUNCTION_ARG_BOUNDARY ix86_function_arg_boundary
   29013              : #undef TARGET_PASS_BY_REFERENCE
   29014              : #define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
   29015              : #undef TARGET_INTERNAL_ARG_POINTER
   29016              : #define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
   29017              : #undef TARGET_UPDATE_STACK_BOUNDARY
   29018              : #define TARGET_UPDATE_STACK_BOUNDARY ix86_update_stack_boundary
   29019              : #undef TARGET_GET_DRAP_RTX
   29020              : #define TARGET_GET_DRAP_RTX ix86_get_drap_rtx
   29021              : #undef TARGET_STRICT_ARGUMENT_NAMING
   29022              : #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   29023              : #undef TARGET_STATIC_CHAIN
   29024              : #define TARGET_STATIC_CHAIN ix86_static_chain
   29025              : #undef TARGET_TRAMPOLINE_INIT
   29026              : #define TARGET_TRAMPOLINE_INIT ix86_trampoline_init
   29027              : #undef TARGET_RETURN_POPS_ARGS
   29028              : #define TARGET_RETURN_POPS_ARGS ix86_return_pops_args
   29029              : 
   29030              : #undef TARGET_WARN_FUNC_RETURN
   29031              : #define TARGET_WARN_FUNC_RETURN ix86_warn_func_return
   29032              : 
   29033              : #undef TARGET_LEGITIMATE_COMBINED_INSN
   29034              : #define TARGET_LEGITIMATE_COMBINED_INSN ix86_legitimate_combined_insn
   29035              : 
   29036              : #undef TARGET_ASAN_SHADOW_OFFSET
   29037              : #define TARGET_ASAN_SHADOW_OFFSET ix86_asan_shadow_offset
   29038              : 
   29039              : #undef TARGET_GIMPLIFY_VA_ARG_EXPR
   29040              : #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
   29041              : 
   29042              : #undef TARGET_SCALAR_MODE_SUPPORTED_P
   29043              : #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p
   29044              : 
   29045              : #undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
   29046              : #define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
   29047              : ix86_libgcc_floating_mode_supported_p
   29048              : 
   29049              : #undef TARGET_VECTOR_MODE_SUPPORTED_P
   29050              : #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p
   29051              : 
   29052              : #undef TARGET_C_MODE_FOR_SUFFIX
   29053              : #define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix
   29054              : 
   29055              : #ifdef HAVE_AS_TLS
   29056              : #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
   29057              : #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel
   29058              : #endif
   29059              : 
   29060              : #ifdef SUBTARGET_INSERT_ATTRIBUTES
   29061              : #undef TARGET_INSERT_ATTRIBUTES
   29062              : #define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
   29063              : #endif
   29064              : 
   29065              : #undef TARGET_MANGLE_TYPE
   29066              : #define TARGET_MANGLE_TYPE ix86_mangle_type
   29067              : 
   29068              : #undef TARGET_EMIT_SUPPORT_TINFOS
   29069              : #define TARGET_EMIT_SUPPORT_TINFOS ix86_emit_support_tinfos
   29070              : 
   29071              : #undef TARGET_STACK_PROTECT_GUARD
   29072              : #define TARGET_STACK_PROTECT_GUARD ix86_stack_protect_guard
   29073              : 
   29074              : #undef TARGET_STACK_PROTECT_GUARD_SYMBOL_P
   29075              : #define TARGET_STACK_PROTECT_GUARD_SYMBOL_P \
   29076              :   ix86_stack_protect_guard_symbol_p
   29077              : 
   29078              : #undef TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
   29079              : #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P \
   29080              :   ix86_stack_protect_runtime_enabled_p
   29081              : 
   29082              : #if !TARGET_MACHO
   29083              : #undef TARGET_STACK_PROTECT_FAIL
   29084              : #define TARGET_STACK_PROTECT_FAIL ix86_stack_protect_fail
   29085              : #endif
   29086              : 
   29087              : #undef TARGET_FUNCTION_VALUE
   29088              : #define TARGET_FUNCTION_VALUE ix86_function_value
   29089              : 
   29090              : #undef TARGET_FUNCTION_VALUE_REGNO_P
   29091              : #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
   29092              : 
   29093              : #undef TARGET_ZERO_CALL_USED_REGS
   29094              : #define TARGET_ZERO_CALL_USED_REGS ix86_zero_call_used_regs
   29095              : 
   29096              : #undef TARGET_PROMOTE_FUNCTION_MODE
   29097              : #define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
   29098              : 
   29099              : #undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
   29100              : #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
   29101              : 
   29102              : #undef TARGET_MEMBER_TYPE_FORCES_BLK
   29103              : #define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
   29104              : 
   29105              : #undef TARGET_INSTANTIATE_DECLS
   29106              : #define TARGET_INSTANTIATE_DECLS ix86_instantiate_decls
   29107              : 
   29108              : #undef TARGET_SECONDARY_RELOAD
   29109              : #define TARGET_SECONDARY_RELOAD ix86_secondary_reload
   29110              : #undef TARGET_SECONDARY_MEMORY_NEEDED
   29111              : #define TARGET_SECONDARY_MEMORY_NEEDED ix86_secondary_memory_needed
   29112              : #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
   29113              : #define TARGET_SECONDARY_MEMORY_NEEDED_MODE ix86_secondary_memory_needed_mode
   29114              : 
   29115              : #undef TARGET_CLASS_MAX_NREGS
   29116              : #define TARGET_CLASS_MAX_NREGS ix86_class_max_nregs
   29117              : 
   29118              : #undef TARGET_BASE_REG_CLASS
   29119              : #define TARGET_BASE_REG_CLASS ix86_base_reg_class
   29120              : 
   29121              : #undef TARGET_PREFERRED_RELOAD_CLASS
   29122              : #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class
   29123              : #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
   29124              : #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class
   29125              : /* When this hook returns true for MODE, the compiler allows
   29126              :    registers explicitly used in the rtl to be used as spill registers
   29127              :    but prevents the compiler from extending the lifetime of these
   29128              :    registers.  */
   29129              : #undef TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
   29130              : #define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true
   29131              : #undef TARGET_CLASS_LIKELY_SPILLED_P
   29132              : #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p
   29133              : #undef TARGET_CALLEE_SAVE_COST
   29134              : #define TARGET_CALLEE_SAVE_COST ix86_callee_save_cost
   29135              : 
   29136              : #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
   29137              : #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
   29138              :   ix86_builtin_vectorization_cost
   29139              : #undef TARGET_VECTORIZE_VEC_PERM_CONST
   29140              : #define TARGET_VECTORIZE_VEC_PERM_CONST ix86_vectorize_vec_perm_const
   29141              : #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
   29142              : #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
   29143              :   ix86_preferred_simd_mode
   29144              : #undef TARGET_VECTORIZE_SPLIT_REDUCTION
   29145              : #define TARGET_VECTORIZE_SPLIT_REDUCTION \
   29146              :   ix86_split_reduction
   29147              : #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
   29148              : #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES \
   29149              :   ix86_autovectorize_vector_modes
   29150              : #undef TARGET_VECTORIZE_GET_MASK_MODE
   29151              : #define TARGET_VECTORIZE_GET_MASK_MODE ix86_get_mask_mode
   29152              : #undef TARGET_VECTORIZE_CREATE_COSTS
   29153              : #define TARGET_VECTORIZE_CREATE_COSTS ix86_vectorize_create_costs
   29154              : 
   29155              : #undef TARGET_SET_CURRENT_FUNCTION
   29156              : #define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
   29157              : 
   29158              : #undef TARGET_OPTION_VALID_ATTRIBUTE_P
   29159              : #define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
   29160              : 
   29161              : #undef TARGET_OPTION_SAVE
   29162              : #define TARGET_OPTION_SAVE ix86_function_specific_save
   29163              : 
   29164              : #undef TARGET_OPTION_RESTORE
   29165              : #define TARGET_OPTION_RESTORE ix86_function_specific_restore
   29166              : 
   29167              : #undef TARGET_OPTION_POST_STREAM_IN
   29168              : #define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in
   29169              : 
   29170              : #undef TARGET_OPTION_PRINT
   29171              : #define TARGET_OPTION_PRINT ix86_function_specific_print
   29172              : 
   29173              : #undef TARGET_CAN_INLINE_P
   29174              : #define TARGET_CAN_INLINE_P ix86_can_inline_p
   29175              : 
   29176              : #undef TARGET_LEGITIMATE_ADDRESS_P
   29177              : #define TARGET_LEGITIMATE_ADDRESS_P ix86_legitimate_address_p
   29178              : 
   29179              : #undef TARGET_REGISTER_PRIORITY
   29180              : #define TARGET_REGISTER_PRIORITY ix86_register_priority
   29181              : 
   29182              : #undef TARGET_REGISTER_USAGE_LEVELING_P
   29183              : #define TARGET_REGISTER_USAGE_LEVELING_P hook_bool_void_true
   29184              : 
   29185              : #undef TARGET_LEGITIMATE_CONSTANT_P
   29186              : #define TARGET_LEGITIMATE_CONSTANT_P ix86_legitimate_constant_p
   29187              : 
   29188              : #undef TARGET_COMPUTE_FRAME_LAYOUT
   29189              : #define TARGET_COMPUTE_FRAME_LAYOUT ix86_compute_frame_layout
   29190              : 
   29191              : #undef TARGET_FRAME_POINTER_REQUIRED
   29192              : #define TARGET_FRAME_POINTER_REQUIRED ix86_frame_pointer_required
   29193              : 
   29194              : #undef TARGET_CAN_ELIMINATE
   29195              : #define TARGET_CAN_ELIMINATE ix86_can_eliminate
   29196              : 
   29197              : #undef TARGET_EXTRA_LIVE_ON_ENTRY
   29198              : #define TARGET_EXTRA_LIVE_ON_ENTRY ix86_live_on_entry
   29199              : 
   29200              : #undef TARGET_ASM_CODE_END
   29201              : #define TARGET_ASM_CODE_END ix86_code_end
   29202              : 
   29203              : #undef TARGET_CONDITIONAL_REGISTER_USAGE
   29204              : #define TARGET_CONDITIONAL_REGISTER_USAGE ix86_conditional_register_usage
   29205              : 
   29206              : #undef TARGET_CANONICALIZE_COMPARISON
   29207              : #define TARGET_CANONICALIZE_COMPARISON ix86_canonicalize_comparison
   29208              : 
   29209              : #undef TARGET_LOOP_UNROLL_ADJUST
   29210              : #define TARGET_LOOP_UNROLL_ADJUST ix86_loop_unroll_adjust
   29211              : 
   29212              : /* Disabled due to PRs 70902, 71453, 71555, 71596 and 71657.  */
   29213              : #undef TARGET_SPILL_CLASS
   29214              : #define TARGET_SPILL_CLASS ix86_spill_class
   29215              : 
   29216              : #undef TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN
   29217              : #define TARGET_SIMD_CLONE_COMPUTE_VECSIZE_AND_SIMDLEN \
   29218              :   ix86_simd_clone_compute_vecsize_and_simdlen
   29219              : 
   29220              : #undef TARGET_SIMD_CLONE_ADJUST
   29221              : #define TARGET_SIMD_CLONE_ADJUST ix86_simd_clone_adjust
   29222              : 
   29223              : #undef TARGET_SIMD_CLONE_USABLE
   29224              : #define TARGET_SIMD_CLONE_USABLE ix86_simd_clone_usable
   29225              : 
   29226              : #undef TARGET_OMP_DEVICE_KIND_ARCH_ISA
   29227              : #define TARGET_OMP_DEVICE_KIND_ARCH_ISA ix86_omp_device_kind_arch_isa
   29228              : 
   29229              : #undef TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P
   29230              : #define TARGET_FLOAT_EXCEPTIONS_ROUNDING_SUPPORTED_P \
   29231              :   ix86_float_exceptions_rounding_supported_p
   29232              : 
   29233              : #undef TARGET_MODE_EMIT
   29234              : #define TARGET_MODE_EMIT ix86_emit_mode_set
   29235              : 
   29236              : #undef TARGET_MODE_NEEDED
   29237              : #define TARGET_MODE_NEEDED ix86_mode_needed
   29238              : 
   29239              : #undef TARGET_MODE_AFTER
   29240              : #define TARGET_MODE_AFTER ix86_mode_after
   29241              : 
   29242              : #undef TARGET_MODE_ENTRY
   29243              : #define TARGET_MODE_ENTRY ix86_mode_entry
   29244              : 
   29245              : #undef TARGET_MODE_EXIT
   29246              : #define TARGET_MODE_EXIT ix86_mode_exit
   29247              : 
   29248              : #undef TARGET_MODE_PRIORITY
   29249              : #define TARGET_MODE_PRIORITY ix86_mode_priority
   29250              : 
   29251              : #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
   29252              : #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
   29253              : 
   29254              : #undef TARGET_OFFLOAD_OPTIONS
   29255              : #define TARGET_OFFLOAD_OPTIONS \
   29256              :   ix86_offload_options
   29257              : 
   29258              : #undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT
   29259              : #define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512
   29260              : 
   29261              : #undef TARGET_OPTAB_SUPPORTED_P
   29262              : #define TARGET_OPTAB_SUPPORTED_P ix86_optab_supported_p
   29263              : 
   29264              : #undef TARGET_HARD_REGNO_SCRATCH_OK
   29265              : #define TARGET_HARD_REGNO_SCRATCH_OK ix86_hard_regno_scratch_ok
   29266              : 
   29267              : #undef TARGET_CUSTOM_FUNCTION_DESCRIPTORS
   29268              : #define TARGET_CUSTOM_FUNCTION_DESCRIPTORS X86_CUSTOM_FUNCTION_TEST
   29269              : 
   29270              : #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
   29271              : #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID ix86_addr_space_zero_address_valid
   29272              : 
   29273              : #undef TARGET_INIT_LIBFUNCS
   29274              : #define TARGET_INIT_LIBFUNCS ix86_init_libfuncs
   29275              : 
   29276              : #undef TARGET_EXPAND_DIVMOD_LIBFUNC
   29277              : #define TARGET_EXPAND_DIVMOD_LIBFUNC ix86_expand_divmod_libfunc
   29278              : 
   29279              : #undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
   29280              : #define TARGET_MAX_NOCE_IFCVT_SEQ_COST ix86_max_noce_ifcvt_seq_cost
   29281              : 
   29282              : #undef TARGET_NOCE_CONVERSION_PROFITABLE_P
   29283              : #define TARGET_NOCE_CONVERSION_PROFITABLE_P ix86_noce_conversion_profitable_p
   29284              : 
   29285              : #undef TARGET_HARD_REGNO_NREGS
   29286              : #define TARGET_HARD_REGNO_NREGS ix86_hard_regno_nregs
   29287              : #undef TARGET_HARD_REGNO_MODE_OK
   29288              : #define TARGET_HARD_REGNO_MODE_OK ix86_hard_regno_mode_ok
   29289              : 
   29290              : #undef TARGET_MODES_TIEABLE_P
   29291              : #define TARGET_MODES_TIEABLE_P ix86_modes_tieable_p
   29292              : 
   29293              : #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
   29294              : #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
   29295              :   ix86_hard_regno_call_part_clobbered
   29296              : 
   29297              : #undef TARGET_FNTYPE_ABI
   29298              : #define TARGET_FNTYPE_ABI ix86_fntype_abi
   29299              : 
   29300              : #undef TARGET_CAN_CHANGE_MODE_CLASS
   29301              : #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
   29302              : 
   29303              : #undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT
   29304              : #define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment
   29305              : 
   29306              : #undef TARGET_STATIC_RTX_ALIGNMENT
   29307              : #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
   29308              : #undef TARGET_CONSTANT_ALIGNMENT
   29309              : #define TARGET_CONSTANT_ALIGNMENT ix86_constant_alignment
   29310              : 
   29311              : #undef TARGET_EMPTY_RECORD_P
   29312              : #define TARGET_EMPTY_RECORD_P ix86_is_empty_record
   29313              : 
   29314              : #undef TARGET_WARN_PARAMETER_PASSING_ABI
   29315              : #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
   29316              : 
   29317              : #undef TARGET_GET_MULTILIB_ABI_NAME
   29318              : #define TARGET_GET_MULTILIB_ABI_NAME \
   29319              :   ix86_get_multilib_abi_name
   29320              : 
   29321              : #undef TARGET_IFUNC_REF_LOCAL_OK
   29322              : #define TARGET_IFUNC_REF_LOCAL_OK ix86_ifunc_ref_local_ok
   29323              : 
   29324              : #if !TARGET_MACHO && !TARGET_DLLIMPORT_DECL_ATTRIBUTES
   29325              : # undef TARGET_ASM_RELOC_RW_MASK
   29326              : # define TARGET_ASM_RELOC_RW_MASK ix86_reloc_rw_mask
   29327              : #endif
   29328              : 
   29329              : #undef TARGET_MEMTAG_CAN_TAG_ADDRESSES
   29330              : #define TARGET_MEMTAG_CAN_TAG_ADDRESSES ix86_memtag_can_tag_addresses
   29331              : 
   29332              : #undef TARGET_MEMTAG_ADD_TAG
   29333              : #define TARGET_MEMTAG_ADD_TAG ix86_memtag_add_tag
   29334              : 
   29335              : #undef TARGET_MEMTAG_SET_TAG
   29336              : #define TARGET_MEMTAG_SET_TAG ix86_memtag_set_tag
   29337              : 
   29338              : #undef TARGET_MEMTAG_EXTRACT_TAG
   29339              : #define TARGET_MEMTAG_EXTRACT_TAG ix86_memtag_extract_tag
   29340              : 
   29341              : #undef TARGET_MEMTAG_UNTAGGED_POINTER
   29342              : #define TARGET_MEMTAG_UNTAGGED_POINTER ix86_memtag_untagged_pointer
   29343              : 
   29344              : #undef TARGET_MEMTAG_TAG_BITSIZE
   29345              : #define TARGET_MEMTAG_TAG_BITSIZE ix86_memtag_tag_bitsize
   29346              : 
   29347              : #undef TARGET_GEN_CCMP_FIRST
   29348              : #define TARGET_GEN_CCMP_FIRST ix86_gen_ccmp_first
   29349              : 
   29350              : #undef TARGET_GEN_CCMP_NEXT
   29351              : #define TARGET_GEN_CCMP_NEXT ix86_gen_ccmp_next
   29352              : 
   29353              : #undef TARGET_HAVE_CCMP
   29354              : #define TARGET_HAVE_CCMP ix86_have_ccmp
   29355              : 
   29356              : #undef TARGET_MODE_CAN_TRANSFER_BITS
   29357              : #define TARGET_MODE_CAN_TRANSFER_BITS ix86_mode_can_transfer_bits
   29358              : 
   29359              : #undef TARGET_REDZONE_CLOBBER
   29360              : #define TARGET_REDZONE_CLOBBER ix86_redzone_clobber
   29361              : 
   29362              : static bool
   29363        99968 : ix86_libc_has_fast_function (int fcode ATTRIBUTE_UNUSED)
   29364              : {
   29365              : #ifdef OPTION_GLIBC
   29366        99968 :   if (OPTION_GLIBC)
   29367        99968 :     return (built_in_function)fcode == BUILT_IN_MEMPCPY;
   29368              :   else
   29369              :     return false;
   29370              : #else
   29371              :   return false;
   29372              : #endif
   29373              : }
   29374              : 
   29375              : #undef TARGET_LIBC_HAS_FAST_FUNCTION
   29376              : #define TARGET_LIBC_HAS_FAST_FUNCTION ix86_libc_has_fast_function
   29377              : 
   29378              : static unsigned
   29379        80763 : ix86_libm_function_max_error (unsigned cfn, machine_mode mode,
   29380              :                               bool boundary_p)
   29381              : {
   29382              : #ifdef OPTION_GLIBC
   29383        80763 :   bool glibc_p = OPTION_GLIBC;
   29384              : #else
   29385              :   bool glibc_p = false;
   29386              : #endif
   29387        80763 :   if (glibc_p)
   29388              :     {
   29389              :       /* If __FAST_MATH__ is defined, glibc provides libmvec.  */
   29390        80763 :       unsigned int libmvec_ret = 0;
   29391        80763 :       if (!flag_trapping_math
   29392         8518 :           && flag_unsafe_math_optimizations
   29393         3552 :           && flag_finite_math_only
   29394         3340 :           && !flag_signed_zeros
   29395         3340 :           && !flag_errno_math)
   29396         3340 :         switch (cfn)
   29397              :           {
   29398         1388 :           CASE_CFN_COS:
   29399         1388 :           CASE_CFN_COS_FN:
   29400         1388 :           CASE_CFN_SIN:
   29401         1388 :           CASE_CFN_SIN_FN:
   29402         1388 :             if (!boundary_p)
   29403              :               {
   29404              :                 /* With non-default rounding modes, libmvec provides
   29405              :                    complete garbage in results.  E.g.
   29406              :                    _ZGVcN8v_sinf for 1.40129846e-45f in FE_UPWARD
   29407              :                    returns 0.00333309174f rather than 1.40129846e-45f.  */
   29408          583 :                 if (flag_rounding_math)
   29409              :                   return ~0U;
   29410              :                 /* https://www.gnu.org/software/libc/manual/html_node/Errors-in-Math-Functions.html
   29411              :                    claims libmvec maximum error is 4ulps.
   29412              :                    My own random testing indicates 2ulps for SFmode and
   29413              :                    0.5ulps for DFmode, but let's go with the 4ulps.  */
   29414              :                 libmvec_ret = 4;
   29415              :               }
   29416              :             break;
   29417              :           default:
   29418              :             break;
   29419              :           }
   29420        80763 :       unsigned int ret = glibc_linux_libm_function_max_error (cfn, mode,
   29421              :                                                               boundary_p);
   29422        80763 :       return MAX (ret, libmvec_ret);
   29423              :     }
   29424            0 :   return default_libm_function_max_error (cfn, mode, boundary_p);
   29425              : }
   29426              : 
   29427              : #undef TARGET_LIBM_FUNCTION_MAX_ERROR
   29428              : #define TARGET_LIBM_FUNCTION_MAX_ERROR ix86_libm_function_max_error
   29429              : 
   29430              : #if TARGET_MACHO
   29431              : static bool
   29432              : ix86_cannot_copy_insn_p (rtx_insn *insn)
   29433              : {
   29434              :   if (TARGET_64BIT)
   29435              :     return false;
   29436              : 
   29437              :   rtx set = single_set (insn);
   29438              :   if (set)
   29439              :     {
   29440              :       rtx src = SET_SRC (set);
   29441              :       if (GET_CODE (src) == UNSPEC
   29442              :           && XINT (src, 1) == UNSPEC_SET_GOT)
   29443              :         return true;
   29444              :     }
   29445              :   return false;
   29446              : }
   29447              : 
   29448              : #undef TARGET_CANNOT_COPY_INSN_P
   29449              : #define TARGET_CANNOT_COPY_INSN_P ix86_cannot_copy_insn_p
   29450              : 
   29451              : #endif
   29452              : 
   29453              : #if CHECKING_P
   29454              : #undef TARGET_RUN_TARGET_SELFTESTS
   29455              : #define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
   29456              : #endif /* #if CHECKING_P */
   29457              : 
   29458              : #undef TARGET_DOCUMENTATION_NAME
   29459              : #define TARGET_DOCUMENTATION_NAME "x86"
   29460              : 
   29461              : /* Implement TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS.  */
   29462              : sbitmap
   29463       759033 : ix86_get_separate_components (void)
   29464              : {
   29465       759033 :   HOST_WIDE_INT offset, to_allocate;
   29466       759033 :   sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
   29467       759033 :   bitmap_clear (components);
   29468       759033 :   struct machine_function *m = cfun->machine;
   29469              : 
   29470       759033 :   offset = m->frame.stack_pointer_offset;
   29471       759033 :   to_allocate = offset - m->frame.sse_reg_save_offset;
   29472              : 
   29473              :   /* Shrink wrap separate uses MOV, which means APX PPX cannot be used.
   29474              :      Experiments show that APX PPX can speed up the prologue.  If the function
   29475              :      does not exit early during actual execution, then using APX PPX is faster.
   29476              :      If the function always exits early during actual execution, then shrink
   29477              :      wrap separate reduces the number of MOV (PUSH/POP) instructions actually
   29478              :      executed, thus speeding up execution.
   29479              :      foo:
   29480              :           movl    $1, %eax
   29481              :           testq   %rdi, %rdi
   29482              :           jne.L60
   29483              :           ret   ---> early return.
   29484              :     .L60:
   29485              :           subq    $88, %rsp     ---> belong to prologue.
   29486              :           xorl    %eax, %eax
   29487              :           movq    %rbx, 40 (%rsp) ---> belong to prologue.
   29488              :           movq    8 (%rdi), %rbx
   29489              :           movq    %rbp, 48 (%rsp) ---> belong to prologue.
   29490              :           movq    %rdi, %rbp
   29491              :           testq   %rbx, %rbx
   29492              :           jne.L61
   29493              :           movq    40 (%rsp), %rbx
   29494              :           movq    48 (%rsp), %rbp
   29495              :           addq    $88, %rsp
   29496              :           ret
   29497              :      .L61:
   29498              :           movq    %r12, 56 (%rsp) ---> belong to prologue.
   29499              :           movq    %r13, 64 (%rsp) ---> belong to prologue.
   29500              :           movq    %r14, 72 (%rsp) ---> belong to prologue.
   29501              :      ... ...
   29502              : 
   29503              :      Disable shrink wrap separate when PPX is enabled.  */
   29504       759033 :   if ((TARGET_APX_PPX && !crtl->calls_eh_return)
   29505       758554 :       || cfun->machine->func_type != TYPE_NORMAL
   29506              :       || TARGET_SEH
   29507       758456 :       || crtl->stack_realign_needed
   29508       749263 :       || m->call_ms2sysv)
   29509              :     return components;
   29510              : 
   29511              :   /* Since shrink wrapping separate uses MOV instead of PUSH/POP.
   29512              :      Disable shrink wrap separate when MOV is prohibited.  */
   29513       747341 :   if (save_regs_using_push_pop (to_allocate))
   29514              :     return components;
   29515              : 
   29516     34377270 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29517     34015404 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
   29518              :       {
   29519              :         /* Skip registers with large offsets, where a pseudo may be needed.  */
   29520       633343 :         if (IN_RANGE (offset, -0x8000, 0x7fff))
   29521       632202 :           bitmap_set_bit (components, regno);
   29522       679467 :         offset += UNITS_PER_WORD;
   29523              :       }
   29524              : 
   29525              :   /* Don't mess with the following registers.  */
   29526       361866 :   if (frame_pointer_needed)
   29527         6422 :     bitmap_clear_bit (components, HARD_FRAME_POINTER_REGNUM);
   29528              : 
   29529       361866 :   if (crtl->drap_reg)
   29530          138 :     bitmap_clear_bit (components, REGNO (crtl->drap_reg));
   29531              : 
   29532       361866 :   if (pic_offset_table_rtx)
   29533        29998 :     bitmap_clear_bit (components, REAL_PIC_OFFSET_TABLE_REGNUM);
   29534              : 
   29535              :   return components;
   29536              : }
   29537              : 
   29538              : /* Implement TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB.  */
   29539              : sbitmap
   29540      9797297 : ix86_components_for_bb (basic_block bb)
   29541              : {
   29542      9797297 :   bitmap in = DF_LIVE_IN (bb);
   29543      9797297 :   bitmap gen = &DF_LIVE_BB_INFO (bb)->gen;
   29544      9797297 :   bitmap kill = &DF_LIVE_BB_INFO (bb)->kill;
   29545              : 
   29546      9797297 :   sbitmap components = sbitmap_alloc (FIRST_PSEUDO_REGISTER);
   29547      9797297 :   bitmap_clear (components);
   29548              : 
   29549      9797297 :   function_abi_aggregator callee_abis;
   29550      9797297 :   rtx_insn *insn;
   29551    118754359 :   FOR_BB_INSNS (bb, insn)
   29552    108957062 :     if (CALL_P (insn))
   29553      3269518 :       callee_abis.note_callee_abi (insn_callee_abi (insn));
   29554      9797297 :   HARD_REG_SET extra_caller_saves = callee_abis.caller_save_regs (*crtl->abi);
   29555              : 
   29556              :   /* GPRs are used in a bb if they are in the IN, GEN, or KILL sets.  */
   29557    930743215 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29558    920945918 :     if (!fixed_regs[regno]
   29559    920945918 :         && (TEST_HARD_REG_BIT (extra_caller_saves, regno)
   29560    458063248 :             || bitmap_bit_p (in, regno)
   29561    431342751 :             || bitmap_bit_p (gen, regno)
   29562    418112619 :             || bitmap_bit_p (kill, regno)))
   29563     40267137 :       bitmap_set_bit (components, regno);
   29564              : 
   29565      9797297 :   return components;
   29566              : }
   29567              : 
   29568              : /* Implement TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS.  */
   29569              : void
   29570       484749 : ix86_disqualify_components (sbitmap, edge, sbitmap, bool)
   29571              : {
   29572              :   /* Nothing to do for x86.  */
   29573       484749 : }
   29574              : 
   29575              : /* Implement TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS.  */
   29576              : void
   29577       163505 : ix86_emit_prologue_components (sbitmap components)
   29578              : {
   29579       163505 :   HOST_WIDE_INT cfa_offset;
   29580       163505 :   struct machine_function *m = cfun->machine;
   29581              : 
   29582       163505 :   cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
   29583       163505 :                - m->frame.stack_pointer_offset;
   29584     15532975 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29585     15369470 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
   29586              :       {
   29587       735253 :         if (bitmap_bit_p (components, regno))
   29588       199189 :           ix86_emit_save_reg_using_mov (word_mode, regno, cfa_offset);
   29589       784913 :         cfa_offset -= UNITS_PER_WORD;
   29590              :       }
   29591       163505 : }
   29592              : 
   29593              : /* Implement TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS.  */
   29594              : void
   29595       145912 : ix86_emit_epilogue_components (sbitmap components)
   29596              : {
   29597       145912 :   HOST_WIDE_INT cfa_offset;
   29598       145912 :   struct machine_function *m = cfun->machine;
   29599       145912 :   cfa_offset = m->frame.reg_save_offset + m->fs.sp_offset
   29600       145912 :                - m->frame.stack_pointer_offset;
   29601              : 
   29602     13861640 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29603     13715728 :     if (GENERAL_REGNO_P (regno) && ix86_save_reg (regno, true, true))
   29604              :       {
   29605       657434 :         if (bitmap_bit_p (components, regno))
   29606              :           {
   29607       236581 :             rtx reg = gen_rtx_REG (word_mode, regno);
   29608       236581 :             rtx mem;
   29609       236581 :             rtx_insn *insn;
   29610              : 
   29611       236581 :             mem = choose_baseaddr (cfa_offset, NULL);
   29612       236581 :             mem = gen_frame_mem (word_mode, mem);
   29613       236581 :             insn = emit_move_insn (reg, mem);
   29614              : 
   29615       236581 :             RTX_FRAME_RELATED_P (insn) = 1;
   29616       236581 :             add_reg_note (insn, REG_CFA_RESTORE, reg);
   29617              :           }
   29618       713982 :         cfa_offset -= UNITS_PER_WORD;
   29619              :       }
   29620       145912 : }
   29621              : 
   29622              : /* Implement TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS.  */
   29623              : void
   29624        45833 : ix86_set_handled_components (sbitmap components)
   29625              : {
   29626      4354135 :   for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
   29627      4308302 :     if (bitmap_bit_p (components, regno))
   29628              :       {
   29629       108743 :         cfun->machine->reg_is_wrapped_separately[regno] = true;
   29630       108743 :         cfun->machine->use_fast_prologue_epilogue = true;
   29631       108743 :         cfun->machine->frame.save_regs_using_mov = true;
   29632              :       }
   29633        45833 : }
   29634              : 
   29635              : #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
   29636              : #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS ix86_get_separate_components
   29637              : #undef TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB
   29638              : #define TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB ix86_components_for_bb
   29639              : #undef TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS
   29640              : #define TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS ix86_disqualify_components
   29641              : #undef TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS
   29642              : #define TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS \
   29643              :   ix86_emit_prologue_components
   29644              : #undef TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS
   29645              : #define TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS \
   29646              :   ix86_emit_epilogue_components
   29647              : #undef TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS
   29648              : #define TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS ix86_set_handled_components
   29649              : 
   29650              : struct gcc_target targetm = TARGET_INITIALIZER;
   29651              : 
   29652              : #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.